use crate::hbox::HorzStringInfo;
use crate::length::Length;
use std::collections::BTreeMap;
#[derive(Clone, Copy, Debug, PartialEq, Eq)]
pub enum MathKind {
Ord,
Bin,
Rel,
Op,
Punct,
Open,
Close,
Prefix,
Inner,
End,
}
#[derive(Clone, Debug, PartialEq)]
pub struct MathGlyph {
pub info: HorzStringInfo,
pub text: String,
pub gid: Option<u16>,
pub dx: Length,
pub dy: Length,
pub width: Length,
pub height: Length,
pub depth: Length,
}
#[derive(Clone, Copy, Debug, PartialEq, Eq, PartialOrd, Ord, Hash)]
pub enum MathCharClass {
Italic,
BoldItalic,
Roman,
BoldRoman,
Script,
BoldScript,
Fraktur,
BoldFraktur,
DoubleStruck,
SansSerif,
BoldSansSerif,
ItalicSansSerif,
BoldItalicSansSerif,
Typewriter,
}
pub(crate) fn default_math_class_map() -> BTreeMap<String, (String, MathKind)> {
[
("=", "=", MathKind::Rel),
("<", "<", MathKind::Rel),
(">", ">", MathKind::Rel),
(":", ":", MathKind::Rel),
("+", "+", MathKind::Bin),
("-", "\u{2212}", MathKind::Bin),
("|", "|", MathKind::Bin),
("/", "/", MathKind::Ord),
(",", ",", MathKind::Punct),
]
.into_iter()
.map(|(k, v, mk)| (k.to_string(), (v.to_string(), mk)))
.collect()
}
pub fn default_math_variant_char(class: MathCharClass, c: char) -> Option<char> {
let cap = c.is_ascii_uppercase().then(|| c as u32 - 'A' as u32);
let small = c.is_ascii_lowercase().then(|| c as u32 - 'a' as u32);
fn cp(base: u32, i: u32) -> Option<char> {
char::from_u32(base + i)
}
match class {
MathCharClass::Italic => match (cap, small) {
(Some(i), _) => cp(0x1D434, i),
(_, Some(7)) => Some('\u{210E}'),
(_, Some(i)) => cp(0x1D44E, i),
_ => None,
},
MathCharClass::BoldItalic => match (cap, small) {
(Some(i), _) => cp(0x1D468, i),
(_, Some(i)) => cp(0x1D482, i),
_ => None,
},
MathCharClass::Roman => (cap.is_some() || small.is_some()).then_some(c),
MathCharClass::BoldRoman => match (cap, small) {
(Some(i), _) => cp(0x1D400, i),
(_, Some(i)) => cp(0x1D41A, i),
_ => None,
},
MathCharClass::Script => match c {
'B' => Some('\u{212C}'),
'E' => Some('\u{2130}'),
'F' => Some('\u{2131}'),
'H' => Some('\u{210B}'),
'I' => Some('\u{2110}'),
'L' => Some('\u{2112}'),
'M' => Some('\u{2133}'),
'R' => Some('\u{211B}'),
'e' => Some('\u{212F}'),
'g' => Some('\u{210A}'),
'o' => Some('\u{2134}'),
_ => match (cap, small) {
(Some(i), _) => cp(0x1D49C, i),
(_, Some(i)) => cp(0x1D4B6, i),
_ => None,
},
},
MathCharClass::BoldScript => match (cap, small) {
(Some(i), _) => cp(0x1D4D0, i),
(_, Some(i)) => cp(0x1D4EA, i),
_ => None,
},
MathCharClass::Fraktur => match c {
'C' => Some('\u{212D}'),
'H' => Some('\u{210C}'),
'I' => Some('\u{2111}'),
'R' => Some('\u{211C}'),
'Z' => Some('\u{2128}'),
_ => match (cap, small) {
(Some(i), _) => cp(0x1D504, i),
(_, Some(i)) => cp(0x1D51E, i),
_ => None,
},
},
MathCharClass::BoldFraktur => match (cap, small) {
(Some(i), _) => cp(0x1D56C, i),
(_, Some(i)) => cp(0x1D586, i),
_ => None,
},
MathCharClass::DoubleStruck => match c {
'C' => Some('\u{2102}'),
'H' => Some('\u{210D}'),
'N' => Some('\u{2115}'),
'P' => Some('\u{2119}'),
'Q' => Some('\u{211A}'),
'R' => Some('\u{211D}'),
'Z' => Some('\u{2124}'),
_ => match (cap, small) {
(Some(i), _) => cp(0x1D538, i),
(_, Some(i)) => cp(0x1D552, i),
_ => None,
},
},
MathCharClass::SansSerif => match (cap, small) {
(Some(i), _) => cp(0x1D5A0, i),
(_, Some(i)) => cp(0x1D5BA, i),
_ => None,
},
MathCharClass::BoldSansSerif => match (cap, small) {
(Some(i), _) => cp(0x1D5D4, i),
(_, Some(i)) => cp(0x1D5EE, i),
_ => None,
},
MathCharClass::ItalicSansSerif => match (cap, small) {
(Some(i), _) => cp(0x1D608, i),
(_, Some(i)) => cp(0x1D622, i),
_ => None,
},
MathCharClass::BoldItalicSansSerif => match (cap, small) {
(Some(i), _) => cp(0x1D63C, i),
(_, Some(i)) => cp(0x1D656, i),
_ => None,
},
MathCharClass::Typewriter => match (cap, small) {
(Some(i), _) => cp(0x1D670, i),
(_, Some(i)) => cp(0x1D68A, i),
_ => None,
},
}
}