fn strip_subset_prefix(base_font: &str) -> &str {
let bytes = base_font.as_bytes();
if bytes.len() > 7 && bytes[6] == b'+' && bytes[..6].iter().all(u8::is_ascii_uppercase) {
&base_font[7..]
} else {
base_font
}
}
#[derive(Clone, Copy, PartialEq, Eq, Debug)]
enum Family {
Helvetica,
Times,
Courier,
}
const FAMILY_STEMS: &[(&str, Family)] = &[
("timesnewromanps", Family::Times),
("timesnewroman", Family::Times),
("couriernew", Family::Courier),
("helvetica", Family::Helvetica),
("courier", Family::Courier),
("arial", Family::Helvetica),
("times", Family::Times),
];
const STYLE_TOKENS: &[&str] = &[
"oblique", "regular", "italic", "roman", "bold", "book", "psmt", "ps", "mt",
];
fn strip_style_tokens(mut rest: &str) -> Option<(bool, bool)> {
let mut bold = false;
let mut italic = false;
while !rest.is_empty() {
let tok = *STYLE_TOKENS.iter().find(|&&t| rest.starts_with(t))?;
match tok {
"bold" => bold = true,
"italic" | "oblique" => italic = true,
_ => {}
}
rest = &rest[tok.len()..];
}
Some((bold, italic))
}
fn classify(base_font: &str) -> Option<(Family, bool, bool)> {
let stripped = strip_subset_prefix(base_font);
let lower = stripped.to_lowercase();
let compact: String = lower
.chars()
.filter(|c| !matches!(c, '-' | ',' | ' '))
.collect();
let (family, rest) = FAMILY_STEMS
.iter()
.find_map(|&(stem, family)| compact.strip_prefix(stem).map(|rest| (family, rest)))?;
let (bold, italic) = strip_style_tokens(rest)?;
Some((family, bold, italic))
}
fn lookup(table: &[(&str, u16)], glyph_name: &str) -> Option<f32> {
table
.binary_search_by_key(&glyph_name, |&(name, _)| name)
.ok()
.map(|i| table[i].1 as f32)
}
pub fn standard_14_width(base_font: &str, glyph_name: &str) -> Option<f32> {
let (family, bold, italic) = classify(base_font)?;
match family {
Family::Courier => Some(600.0),
Family::Helvetica => {
let table = if bold { HELVETICA_BOLD } else { HELVETICA };
lookup(table, glyph_name)
}
Family::Times => {
let table = match (bold, italic) {
(true, true) => TIMES_BOLD_ITALIC,
(true, false) => TIMES_BOLD,
(false, true) => TIMES_ITALIC,
(false, false) => TIMES_ROMAN,
};
lookup(table, glyph_name)
}
}
}
pub fn is_standard_14(base_font: &str) -> bool {
classify(base_font).is_some()
}
#[rustfmt::skip]
const HELVETICA: &[(&str, u16)] = &[
("A", 667),
("AE", 1000),
("Aacute", 667),
("Acircumflex", 667),
("Adieresis", 667),
("Agrave", 667),
("Aring", 667),
("Atilde", 667),
("B", 667),
("C", 722),
("Ccedilla", 722),
("D", 722),
("E", 667),
("Eacute", 667),
("Ecircumflex", 667),
("Edieresis", 667),
("Egrave", 667),
("Eth", 722),
("F", 611),
("G", 778),
("H", 722),
("I", 278),
("Iacute", 278),
("Icircumflex", 278),
("Idieresis", 278),
("Igrave", 278),
("J", 500),
("K", 667),
("L", 556),
("Lslash", 556),
("M", 833),
("N", 722),
("Ntilde", 722),
("O", 778),
("OE", 1000),
("Oacute", 778),
("Ocircumflex", 778),
("Odieresis", 778),
("Ograve", 778),
("Oslash", 778),
("Otilde", 778),
("P", 667),
("Q", 778),
("R", 722),
("S", 667),
("Scaron", 667),
("T", 611),
("Thorn", 667),
("U", 722),
("Uacute", 722),
("Ucircumflex", 722),
("Udieresis", 722),
("Ugrave", 722),
("V", 667),
("W", 944),
("X", 667),
("Y", 667),
("Yacute", 667),
("Ydieresis", 667),
("Z", 611),
("Zcaron", 611),
("a", 556),
("aacute", 556),
("acircumflex", 556),
("acute", 333),
("adieresis", 556),
("ae", 889),
("agrave", 556),
("ampersand", 667),
("aring", 556),
("asciicircum", 469),
("asciitilde", 584),
("asterisk", 389),
("at", 1015),
("atilde", 556),
("b", 556),
("backslash", 278),
("bar", 260),
("braceleft", 334),
("braceright", 334),
("bracketleft", 278),
("bracketright", 278),
("breve", 333),
("brokenbar", 260),
("bullet", 350),
("c", 500),
("caron", 333),
("ccedilla", 500),
("cedilla", 333),
("cent", 556),
("circumflex", 333),
("colon", 278),
("comma", 278),
("copyright", 737),
("currency", 556),
("d", 556),
("dagger", 556),
("daggerdbl", 556),
("degree", 400),
("dieresis", 333),
("divide", 584),
("dollar", 556),
("dotaccent", 333),
("dotlessi", 278),
("e", 556),
("eacute", 556),
("ecircumflex", 556),
("edieresis", 556),
("egrave", 556),
("eight", 556),
("ellipsis", 1000),
("emdash", 1000),
("endash", 556),
("equal", 584),
("eth", 556),
("exclam", 278),
("exclamdown", 333),
("f", 278),
("fi", 500),
("five", 556),
("fl", 500),
("florin", 556),
("four", 556),
("fraction", 167),
("g", 556),
("germandbls", 611),
("grave", 333),
("greater", 584),
("guillemotleft", 556),
("guillemotright", 556),
("guilsinglleft", 333),
("guilsinglright", 333),
("h", 556),
("hungarumlaut", 333),
("hyphen", 333),
("i", 222),
("iacute", 278),
("icircumflex", 278),
("idieresis", 278),
("igrave", 278),
("j", 222),
("k", 500),
("l", 222),
("less", 584),
("logicalnot", 584),
("lslash", 222),
("m", 833),
("macron", 333),
("minus", 584),
("mu", 556),
("multiply", 584),
("n", 556),
("nine", 556),
("ntilde", 556),
("numbersign", 556),
("o", 556),
("oacute", 556),
("ocircumflex", 556),
("odieresis", 556),
("oe", 944),
("ogonek", 333),
("ograve", 556),
("one", 556),
("onehalf", 834),
("onequarter", 834),
("onesuperior", 333),
("ordfeminine", 370),
("ordmasculine", 365),
("oslash", 611),
("otilde", 556),
("p", 556),
("paragraph", 537),
("parenleft", 333),
("parenright", 333),
("percent", 889),
("period", 278),
("periodcentered", 278),
("perthousand", 1000),
("plus", 584),
("plusminus", 584),
("q", 556),
("question", 556),
("questiondown", 611),
("quotedbl", 355),
("quotedblbase", 333),
("quotedblleft", 333),
("quotedblright", 333),
("quoteleft", 222),
("quoteright", 222),
("quotesinglbase", 222),
("quotesingle", 191),
("r", 333),
("registered", 737),
("ring", 333),
("s", 500),
("scaron", 500),
("section", 556),
("semicolon", 278),
("seven", 556),
("six", 556),
("slash", 278),
("space", 278),
("sterling", 556),
("t", 278),
("thorn", 556),
("three", 556),
("threequarters", 834),
("threesuperior", 333),
("tilde", 333),
("trademark", 1000),
("two", 556),
("twosuperior", 333),
("u", 556),
("uacute", 556),
("ucircumflex", 556),
("udieresis", 556),
("ugrave", 556),
("underscore", 556),
("v", 500),
("w", 722),
("x", 500),
("y", 500),
("yacute", 500),
("ydieresis", 500),
("yen", 556),
("z", 500),
("zcaron", 500),
("zero", 556),
];
#[rustfmt::skip]
const HELVETICA_BOLD: &[(&str, u16)] = &[
("A", 722),
("AE", 1000),
("Aacute", 722),
("Acircumflex", 722),
("Adieresis", 722),
("Agrave", 722),
("Aring", 722),
("Atilde", 722),
("B", 722),
("C", 722),
("Ccedilla", 722),
("D", 722),
("E", 667),
("Eacute", 667),
("Ecircumflex", 667),
("Edieresis", 667),
("Egrave", 667),
("Eth", 722),
("F", 611),
("G", 778),
("H", 722),
("I", 278),
("Iacute", 278),
("Icircumflex", 278),
("Idieresis", 278),
("Igrave", 278),
("J", 556),
("K", 722),
("L", 611),
("Lslash", 611),
("M", 833),
("N", 722),
("Ntilde", 722),
("O", 778),
("OE", 1000),
("Oacute", 778),
("Ocircumflex", 778),
("Odieresis", 778),
("Ograve", 778),
("Oslash", 778),
("Otilde", 778),
("P", 667),
("Q", 778),
("R", 722),
("S", 667),
("Scaron", 667),
("T", 611),
("Thorn", 667),
("U", 722),
("Uacute", 722),
("Ucircumflex", 722),
("Udieresis", 722),
("Ugrave", 722),
("V", 667),
("W", 944),
("X", 667),
("Y", 667),
("Yacute", 667),
("Ydieresis", 667),
("Z", 611),
("Zcaron", 611),
("a", 556),
("aacute", 556),
("acircumflex", 556),
("acute", 333),
("adieresis", 556),
("ae", 889),
("agrave", 556),
("ampersand", 722),
("aring", 556),
("asciicircum", 584),
("asciitilde", 584),
("asterisk", 389),
("at", 975),
("atilde", 556),
("b", 611),
("backslash", 278),
("bar", 280),
("braceleft", 389),
("braceright", 389),
("bracketleft", 333),
("bracketright", 333),
("breve", 333),
("brokenbar", 280),
("bullet", 350),
("c", 556),
("caron", 333),
("ccedilla", 556),
("cedilla", 333),
("cent", 556),
("circumflex", 333),
("colon", 333),
("comma", 278),
("copyright", 737),
("currency", 556),
("d", 611),
("dagger", 556),
("daggerdbl", 556),
("degree", 400),
("dieresis", 333),
("divide", 584),
("dollar", 556),
("dotaccent", 333),
("dotlessi", 278),
("e", 556),
("eacute", 556),
("ecircumflex", 556),
("edieresis", 556),
("egrave", 556),
("eight", 556),
("ellipsis", 1000),
("emdash", 1000),
("endash", 556),
("equal", 584),
("eth", 611),
("exclam", 333),
("exclamdown", 333),
("f", 333),
("fi", 611),
("five", 556),
("fl", 611),
("florin", 556),
("four", 556),
("fraction", 167),
("g", 611),
("germandbls", 611),
("grave", 333),
("greater", 584),
("guillemotleft", 556),
("guillemotright", 556),
("guilsinglleft", 333),
("guilsinglright", 333),
("h", 611),
("hungarumlaut", 333),
("hyphen", 333),
("i", 278),
("iacute", 278),
("icircumflex", 278),
("idieresis", 278),
("igrave", 278),
("j", 278),
("k", 556),
("l", 278),
("less", 584),
("logicalnot", 584),
("lslash", 278),
("m", 889),
("macron", 333),
("minus", 584),
("mu", 611),
("multiply", 584),
("n", 611),
("nine", 556),
("ntilde", 611),
("numbersign", 556),
("o", 611),
("oacute", 611),
("ocircumflex", 611),
("odieresis", 611),
("oe", 944),
("ogonek", 333),
("ograve", 611),
("one", 556),
("onehalf", 834),
("onequarter", 834),
("onesuperior", 333),
("ordfeminine", 370),
("ordmasculine", 365),
("oslash", 611),
("otilde", 611),
("p", 611),
("paragraph", 556),
("parenleft", 333),
("parenright", 333),
("percent", 889),
("period", 278),
("periodcentered", 278),
("perthousand", 1000),
("plus", 584),
("plusminus", 584),
("q", 611),
("question", 611),
("questiondown", 611),
("quotedbl", 474),
("quotedblbase", 500),
("quotedblleft", 500),
("quotedblright", 500),
("quoteleft", 278),
("quoteright", 278),
("quotesinglbase", 278),
("quotesingle", 238),
("r", 389),
("registered", 737),
("ring", 333),
("s", 556),
("scaron", 556),
("section", 556),
("semicolon", 333),
("seven", 556),
("six", 556),
("slash", 278),
("space", 278),
("sterling", 556),
("t", 333),
("thorn", 611),
("three", 556),
("threequarters", 834),
("threesuperior", 333),
("tilde", 333),
("trademark", 1000),
("two", 556),
("twosuperior", 333),
("u", 611),
("uacute", 611),
("ucircumflex", 611),
("udieresis", 611),
("ugrave", 611),
("underscore", 556),
("v", 556),
("w", 778),
("x", 556),
("y", 556),
("yacute", 556),
("ydieresis", 556),
("yen", 556),
("z", 500),
("zcaron", 500),
("zero", 556),
];
#[rustfmt::skip]
const TIMES_ROMAN: &[(&str, u16)] = &[
("A", 722),
("AE", 889),
("Aacute", 722),
("Acircumflex", 722),
("Adieresis", 722),
("Agrave", 722),
("Aring", 722),
("Atilde", 722),
("B", 667),
("C", 667),
("Ccedilla", 667),
("D", 722),
("E", 611),
("Eacute", 611),
("Ecircumflex", 611),
("Edieresis", 611),
("Egrave", 611),
("Eth", 722),
("F", 556),
("G", 722),
("H", 722),
("I", 333),
("Iacute", 333),
("Icircumflex", 333),
("Idieresis", 333),
("Igrave", 333),
("J", 389),
("K", 722),
("L", 611),
("Lslash", 611),
("M", 889),
("N", 722),
("Ntilde", 722),
("O", 722),
("OE", 889),
("Oacute", 722),
("Ocircumflex", 722),
("Odieresis", 722),
("Ograve", 722),
("Oslash", 722),
("Otilde", 722),
("P", 556),
("Q", 722),
("R", 667),
("S", 556),
("Scaron", 556),
("T", 611),
("Thorn", 556),
("U", 722),
("Uacute", 722),
("Ucircumflex", 722),
("Udieresis", 722),
("Ugrave", 722),
("V", 722),
("W", 944),
("X", 722),
("Y", 722),
("Yacute", 722),
("Ydieresis", 722),
("Z", 611),
("Zcaron", 611),
("a", 444),
("aacute", 444),
("acircumflex", 444),
("acute", 333),
("adieresis", 444),
("ae", 667),
("agrave", 444),
("ampersand", 778),
("aring", 444),
("asciicircum", 469),
("asciitilde", 541),
("asterisk", 500),
("at", 921),
("atilde", 444),
("b", 500),
("backslash", 278),
("bar", 200),
("braceleft", 480),
("braceright", 480),
("bracketleft", 333),
("bracketright", 333),
("breve", 333),
("brokenbar", 200),
("bullet", 350),
("c", 444),
("caron", 333),
("ccedilla", 444),
("cedilla", 333),
("cent", 500),
("circumflex", 333),
("colon", 278),
("comma", 250),
("copyright", 760),
("currency", 500),
("d", 500),
("dagger", 500),
("daggerdbl", 500),
("degree", 400),
("dieresis", 333),
("divide", 564),
("dollar", 500),
("dotaccent", 333),
("dotlessi", 278),
("e", 444),
("eacute", 444),
("ecircumflex", 444),
("edieresis", 444),
("egrave", 444),
("eight", 500),
("ellipsis", 1000),
("emdash", 1000),
("endash", 500),
("equal", 564),
("eth", 500),
("exclam", 333),
("exclamdown", 333),
("f", 333),
("fi", 556),
("five", 500),
("fl", 556),
("florin", 500),
("four", 500),
("fraction", 167),
("g", 500),
("germandbls", 500),
("grave", 333),
("greater", 564),
("guillemotleft", 500),
("guillemotright", 500),
("guilsinglleft", 333),
("guilsinglright", 333),
("h", 500),
("hungarumlaut", 333),
("hyphen", 333),
("i", 278),
("iacute", 278),
("icircumflex", 278),
("idieresis", 278),
("igrave", 278),
("j", 278),
("k", 500),
("l", 278),
("less", 564),
("logicalnot", 564),
("lslash", 278),
("m", 778),
("macron", 333),
("minus", 564),
("mu", 500),
("multiply", 564),
("n", 500),
("nine", 500),
("ntilde", 500),
("numbersign", 500),
("o", 500),
("oacute", 500),
("ocircumflex", 500),
("odieresis", 500),
("oe", 722),
("ogonek", 333),
("ograve", 500),
("one", 500),
("onehalf", 750),
("onequarter", 750),
("onesuperior", 300),
("ordfeminine", 276),
("ordmasculine", 310),
("oslash", 500),
("otilde", 500),
("p", 500),
("paragraph", 453),
("parenleft", 333),
("parenright", 333),
("percent", 833),
("period", 250),
("periodcentered", 250),
("perthousand", 1000),
("plus", 564),
("plusminus", 564),
("q", 500),
("question", 444),
("questiondown", 444),
("quotedbl", 408),
("quotedblbase", 444),
("quotedblleft", 444),
("quotedblright", 444),
("quoteleft", 333),
("quoteright", 333),
("quotesinglbase", 333),
("quotesingle", 180),
("r", 333),
("registered", 760),
("ring", 333),
("s", 389),
("scaron", 389),
("section", 500),
("semicolon", 278),
("seven", 500),
("six", 500),
("slash", 278),
("space", 250),
("sterling", 500),
("t", 278),
("thorn", 500),
("three", 500),
("threequarters", 750),
("threesuperior", 300),
("tilde", 333),
("trademark", 980),
("two", 500),
("twosuperior", 300),
("u", 500),
("uacute", 500),
("ucircumflex", 500),
("udieresis", 500),
("ugrave", 500),
("underscore", 500),
("v", 500),
("w", 722),
("x", 500),
("y", 500),
("yacute", 500),
("ydieresis", 500),
("yen", 500),
("z", 444),
("zcaron", 444),
("zero", 500),
];
#[rustfmt::skip]
const TIMES_BOLD: &[(&str, u16)] = &[
("A", 722),
("AE", 1000),
("Aacute", 722),
("Acircumflex", 722),
("Adieresis", 722),
("Agrave", 722),
("Aring", 722),
("Atilde", 722),
("B", 667),
("C", 722),
("Ccedilla", 722),
("D", 722),
("E", 667),
("Eacute", 667),
("Ecircumflex", 667),
("Edieresis", 667),
("Egrave", 667),
("Eth", 722),
("F", 611),
("G", 778),
("H", 778),
("I", 389),
("Iacute", 389),
("Icircumflex", 389),
("Idieresis", 389),
("Igrave", 389),
("J", 500),
("K", 778),
("L", 667),
("Lslash", 667),
("M", 944),
("N", 722),
("Ntilde", 722),
("O", 778),
("OE", 1000),
("Oacute", 778),
("Ocircumflex", 778),
("Odieresis", 778),
("Ograve", 778),
("Oslash", 778),
("Otilde", 778),
("P", 611),
("Q", 778),
("R", 722),
("S", 556),
("Scaron", 556),
("T", 667),
("Thorn", 611),
("U", 722),
("Uacute", 722),
("Ucircumflex", 722),
("Udieresis", 722),
("Ugrave", 722),
("V", 722),
("W", 1000),
("X", 722),
("Y", 722),
("Yacute", 722),
("Ydieresis", 722),
("Z", 667),
("Zcaron", 667),
("a", 500),
("aacute", 500),
("acircumflex", 500),
("acute", 333),
("adieresis", 500),
("ae", 722),
("agrave", 500),
("ampersand", 833),
("aring", 500),
("asciicircum", 581),
("asciitilde", 520),
("asterisk", 500),
("at", 930),
("atilde", 500),
("b", 556),
("backslash", 278),
("bar", 220),
("braceleft", 394),
("braceright", 394),
("bracketleft", 333),
("bracketright", 333),
("breve", 333),
("brokenbar", 220),
("bullet", 350),
("c", 444),
("caron", 333),
("ccedilla", 444),
("cedilla", 333),
("cent", 500),
("circumflex", 333),
("colon", 333),
("comma", 250),
("copyright", 747),
("currency", 500),
("d", 556),
("dagger", 500),
("daggerdbl", 500),
("degree", 400),
("dieresis", 333),
("divide", 570),
("dollar", 500),
("dotaccent", 333),
("dotlessi", 278),
("e", 444),
("eacute", 444),
("ecircumflex", 444),
("edieresis", 444),
("egrave", 444),
("eight", 500),
("ellipsis", 1000),
("emdash", 1000),
("endash", 500),
("equal", 570),
("eth", 500),
("exclam", 333),
("exclamdown", 333),
("f", 333),
("fi", 556),
("five", 500),
("fl", 556),
("florin", 500),
("four", 500),
("fraction", 167),
("g", 500),
("germandbls", 556),
("grave", 333),
("greater", 570),
("guillemotleft", 500),
("guillemotright", 500),
("guilsinglleft", 333),
("guilsinglright", 333),
("h", 556),
("hungarumlaut", 333),
("hyphen", 333),
("i", 278),
("iacute", 278),
("icircumflex", 278),
("idieresis", 278),
("igrave", 278),
("j", 333),
("k", 556),
("l", 278),
("less", 570),
("logicalnot", 570),
("lslash", 278),
("m", 833),
("macron", 333),
("minus", 570),
("mu", 556),
("multiply", 570),
("n", 556),
("nine", 500),
("ntilde", 556),
("numbersign", 500),
("o", 500),
("oacute", 500),
("ocircumflex", 500),
("odieresis", 500),
("oe", 722),
("ogonek", 333),
("ograve", 500),
("one", 500),
("onehalf", 750),
("onequarter", 750),
("onesuperior", 300),
("ordfeminine", 300),
("ordmasculine", 330),
("oslash", 500),
("otilde", 500),
("p", 556),
("paragraph", 540),
("parenleft", 333),
("parenright", 333),
("percent", 1000),
("period", 250),
("periodcentered", 250),
("perthousand", 1000),
("plus", 570),
("plusminus", 570),
("q", 556),
("question", 500),
("questiondown", 500),
("quotedbl", 555),
("quotedblbase", 500),
("quotedblleft", 500),
("quotedblright", 500),
("quoteleft", 333),
("quoteright", 333),
("quotesinglbase", 333),
("quotesingle", 278),
("r", 444),
("registered", 747),
("ring", 333),
("s", 389),
("scaron", 389),
("section", 500),
("semicolon", 333),
("seven", 500),
("six", 500),
("slash", 278),
("space", 250),
("sterling", 500),
("t", 333),
("thorn", 556),
("three", 500),
("threequarters", 750),
("threesuperior", 300),
("tilde", 333),
("trademark", 1000),
("two", 500),
("twosuperior", 300),
("u", 556),
("uacute", 556),
("ucircumflex", 556),
("udieresis", 556),
("ugrave", 556),
("underscore", 500),
("v", 500),
("w", 722),
("x", 500),
("y", 500),
("yacute", 500),
("ydieresis", 500),
("yen", 500),
("z", 444),
("zcaron", 444),
("zero", 500),
];
#[rustfmt::skip]
const TIMES_ITALIC: &[(&str, u16)] = &[
("A", 611),
("AE", 889),
("Aacute", 611),
("Acircumflex", 611),
("Adieresis", 611),
("Agrave", 611),
("Aring", 611),
("Atilde", 611),
("B", 611),
("C", 667),
("Ccedilla", 667),
("D", 722),
("E", 611),
("Eacute", 611),
("Ecircumflex", 611),
("Edieresis", 611),
("Egrave", 611),
("Eth", 722),
("F", 611),
("G", 722),
("H", 722),
("I", 333),
("Iacute", 333),
("Icircumflex", 333),
("Idieresis", 333),
("Igrave", 333),
("J", 444),
("K", 667),
("L", 556),
("Lslash", 556),
("M", 833),
("N", 667),
("Ntilde", 667),
("O", 722),
("OE", 944),
("Oacute", 722),
("Ocircumflex", 722),
("Odieresis", 722),
("Ograve", 722),
("Oslash", 722),
("Otilde", 722),
("P", 611),
("Q", 722),
("R", 611),
("S", 500),
("Scaron", 500),
("T", 556),
("Thorn", 611),
("U", 722),
("Uacute", 722),
("Ucircumflex", 722),
("Udieresis", 722),
("Ugrave", 722),
("V", 611),
("W", 833),
("X", 611),
("Y", 556),
("Yacute", 556),
("Ydieresis", 556),
("Z", 556),
("Zcaron", 556),
("a", 500),
("aacute", 500),
("acircumflex", 500),
("acute", 333),
("adieresis", 500),
("ae", 667),
("agrave", 500),
("ampersand", 778),
("aring", 500),
("asciicircum", 422),
("asciitilde", 541),
("asterisk", 500),
("at", 920),
("atilde", 500),
("b", 500),
("backslash", 278),
("bar", 275),
("braceleft", 400),
("braceright", 400),
("bracketleft", 389),
("bracketright", 389),
("breve", 333),
("brokenbar", 275),
("bullet", 350),
("c", 444),
("caron", 333),
("ccedilla", 444),
("cedilla", 333),
("cent", 500),
("circumflex", 333),
("colon", 333),
("comma", 250),
("copyright", 760),
("currency", 500),
("d", 500),
("dagger", 500),
("daggerdbl", 500),
("degree", 400),
("dieresis", 333),
("divide", 675),
("dollar", 500),
("dotaccent", 333),
("dotlessi", 278),
("e", 444),
("eacute", 444),
("ecircumflex", 444),
("edieresis", 444),
("egrave", 444),
("eight", 500),
("ellipsis", 889),
("emdash", 889),
("endash", 500),
("equal", 675),
("eth", 500),
("exclam", 333),
("exclamdown", 389),
("f", 278),
("fi", 500),
("five", 500),
("fl", 500),
("florin", 500),
("four", 500),
("fraction", 167),
("g", 500),
("germandbls", 500),
("grave", 333),
("greater", 675),
("guillemotleft", 500),
("guillemotright", 500),
("guilsinglleft", 333),
("guilsinglright", 333),
("h", 500),
("hungarumlaut", 333),
("hyphen", 333),
("i", 278),
("iacute", 278),
("icircumflex", 278),
("idieresis", 278),
("igrave", 278),
("j", 278),
("k", 444),
("l", 278),
("less", 675),
("logicalnot", 675),
("lslash", 278),
("m", 722),
("macron", 333),
("minus", 675),
("mu", 500),
("multiply", 675),
("n", 500),
("nine", 500),
("ntilde", 500),
("numbersign", 500),
("o", 500),
("oacute", 500),
("ocircumflex", 500),
("odieresis", 500),
("oe", 667),
("ogonek", 333),
("ograve", 500),
("one", 500),
("onehalf", 750),
("onequarter", 750),
("onesuperior", 300),
("ordfeminine", 276),
("ordmasculine", 310),
("oslash", 500),
("otilde", 500),
("p", 500),
("paragraph", 523),
("parenleft", 333),
("parenright", 333),
("percent", 833),
("period", 250),
("periodcentered", 250),
("perthousand", 1000),
("plus", 675),
("plusminus", 675),
("q", 500),
("question", 500),
("questiondown", 500),
("quotedbl", 420),
("quotedblbase", 556),
("quotedblleft", 556),
("quotedblright", 556),
("quoteleft", 333),
("quoteright", 333),
("quotesinglbase", 333),
("quotesingle", 214),
("r", 389),
("registered", 760),
("ring", 333),
("s", 389),
("scaron", 389),
("section", 500),
("semicolon", 333),
("seven", 500),
("six", 500),
("slash", 278),
("space", 250),
("sterling", 500),
("t", 278),
("thorn", 500),
("three", 500),
("threequarters", 750),
("threesuperior", 300),
("tilde", 333),
("trademark", 980),
("two", 500),
("twosuperior", 300),
("u", 500),
("uacute", 500),
("ucircumflex", 500),
("udieresis", 500),
("ugrave", 500),
("underscore", 500),
("v", 444),
("w", 667),
("x", 444),
("y", 444),
("yacute", 444),
("ydieresis", 444),
("yen", 500),
("z", 389),
("zcaron", 389),
("zero", 500),
];
#[rustfmt::skip]
const TIMES_BOLD_ITALIC: &[(&str, u16)] = &[
("A", 667),
("AE", 944),
("Aacute", 667),
("Acircumflex", 667),
("Adieresis", 667),
("Agrave", 667),
("Aring", 667),
("Atilde", 667),
("B", 667),
("C", 667),
("Ccedilla", 667),
("D", 722),
("E", 667),
("Eacute", 667),
("Ecircumflex", 667),
("Edieresis", 667),
("Egrave", 667),
("Eth", 722),
("F", 667),
("G", 722),
("H", 778),
("I", 389),
("Iacute", 389),
("Icircumflex", 389),
("Idieresis", 389),
("Igrave", 389),
("J", 500),
("K", 667),
("L", 611),
("Lslash", 611),
("M", 889),
("N", 722),
("Ntilde", 722),
("O", 722),
("OE", 944),
("Oacute", 722),
("Ocircumflex", 722),
("Odieresis", 722),
("Ograve", 722),
("Oslash", 722),
("Otilde", 722),
("P", 611),
("Q", 722),
("R", 667),
("S", 556),
("Scaron", 556),
("T", 611),
("Thorn", 611),
("U", 722),
("Uacute", 722),
("Ucircumflex", 722),
("Udieresis", 722),
("Ugrave", 722),
("V", 667),
("W", 889),
("X", 667),
("Y", 611),
("Yacute", 611),
("Ydieresis", 611),
("Z", 611),
("Zcaron", 611),
("a", 500),
("aacute", 500),
("acircumflex", 500),
("acute", 333),
("adieresis", 500),
("ae", 722),
("agrave", 500),
("ampersand", 778),
("aring", 500),
("asciicircum", 570),
("asciitilde", 570),
("asterisk", 500),
("at", 832),
("atilde", 500),
("b", 500),
("backslash", 278),
("bar", 220),
("braceleft", 348),
("braceright", 348),
("bracketleft", 333),
("bracketright", 333),
("breve", 333),
("brokenbar", 220),
("bullet", 350),
("c", 444),
("caron", 333),
("ccedilla", 444),
("cedilla", 333),
("cent", 500),
("circumflex", 333),
("colon", 333),
("comma", 250),
("copyright", 747),
("currency", 500),
("d", 500),
("dagger", 500),
("daggerdbl", 500),
("degree", 400),
("dieresis", 333),
("divide", 570),
("dollar", 500),
("dotaccent", 333),
("dotlessi", 278),
("e", 444),
("eacute", 444),
("ecircumflex", 444),
("edieresis", 444),
("egrave", 444),
("eight", 500),
("ellipsis", 1000),
("emdash", 1000),
("endash", 500),
("equal", 570),
("eth", 500),
("exclam", 389),
("exclamdown", 389),
("f", 333),
("fi", 556),
("five", 500),
("fl", 556),
("florin", 500),
("four", 500),
("fraction", 167),
("g", 500),
("germandbls", 500),
("grave", 333),
("greater", 570),
("guillemotleft", 500),
("guillemotright", 500),
("guilsinglleft", 333),
("guilsinglright", 333),
("h", 556),
("hungarumlaut", 333),
("hyphen", 333),
("i", 278),
("iacute", 278),
("icircumflex", 278),
("idieresis", 278),
("igrave", 278),
("j", 278),
("k", 500),
("l", 278),
("less", 570),
("logicalnot", 606),
("lslash", 278),
("m", 778),
("macron", 333),
("minus", 606),
("mu", 576),
("multiply", 570),
("n", 556),
("nine", 500),
("ntilde", 556),
("numbersign", 500),
("o", 500),
("oacute", 500),
("ocircumflex", 500),
("odieresis", 500),
("oe", 722),
("ogonek", 333),
("ograve", 500),
("one", 500),
("onehalf", 750),
("onequarter", 750),
("onesuperior", 300),
("ordfeminine", 266),
("ordmasculine", 300),
("oslash", 500),
("otilde", 500),
("p", 500),
("paragraph", 500),
("parenleft", 333),
("parenright", 333),
("percent", 833),
("period", 250),
("periodcentered", 250),
("perthousand", 1000),
("plus", 570),
("plusminus", 570),
("q", 500),
("question", 500),
("questiondown", 500),
("quotedbl", 555),
("quotedblbase", 500),
("quotedblleft", 500),
("quotedblright", 500),
("quoteleft", 333),
("quoteright", 333),
("quotesinglbase", 333),
("quotesingle", 278),
("r", 389),
("registered", 747),
("ring", 333),
("s", 389),
("scaron", 389),
("section", 500),
("semicolon", 333),
("seven", 500),
("six", 500),
("slash", 278),
("space", 250),
("sterling", 500),
("t", 278),
("thorn", 500),
("three", 500),
("threequarters", 750),
("threesuperior", 300),
("tilde", 333),
("trademark", 1000),
("two", 500),
("twosuperior", 300),
("u", 556),
("uacute", 556),
("ucircumflex", 556),
("udieresis", 556),
("ugrave", 556),
("underscore", 500),
("v", 444),
("w", 667),
("x", 500),
("y", 444),
("yacute", 444),
("ydieresis", 444),
("yen", 500),
("z", 389),
("zcaron", 389),
("zero", 500),
];
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn standard_14_known_widths() {
assert_eq!(standard_14_width("Helvetica", "space"), Some(278.0));
assert_eq!(standard_14_width("Helvetica", "A"), Some(667.0));
assert_eq!(standard_14_width("Helvetica-Bold", "A"), Some(722.0));
assert_eq!(standard_14_width("Times-Roman", "A"), Some(722.0));
assert_eq!(standard_14_width("Times-Italic", "a"), Some(500.0));
assert_eq!(standard_14_width("Courier", "A"), Some(600.0));
assert_eq!(standard_14_width("Courier-BoldOblique", "m"), Some(600.0));
assert_eq!(
standard_14_width("Helvetica-Oblique", "A"),
standard_14_width("Helvetica", "A")
);
assert_eq!(
standard_14_width("Helvetica-BoldOblique", "A"),
standard_14_width("Helvetica-Bold", "A")
);
}
#[test]
fn standard_14_aliases_and_non_members() {
assert_eq!(standard_14_width("Arial", "space"), Some(278.0)); assert_eq!(standard_14_width("ABCDEF+Times-Bold", "A"), Some(722.0)); assert_eq!(standard_14_width("TimesNewRomanPSMT", "A"), Some(722.0)); assert_eq!(standard_14_width("CourierNewPS-BoldMT", "A"), Some(600.0)); assert!(standard_14_width("Symbol", "alpha").is_none()); assert!(standard_14_width("SomeEmbeddedFont", "A").is_none());
assert!(is_standard_14("Courier-Bold") && !is_standard_14("Comic Sans"));
assert!(is_standard_14("Arial-BoldMT"));
assert!(!is_standard_14("ZapfDingbats"));
}
#[test]
fn standard_14_review_fix_positive() {
assert_eq!(standard_14_width("Helvetica-Bold", "A"), Some(722.0));
assert_eq!(standard_14_width("Arial-BoldMT", "space"), Some(278.0));
assert!(standard_14_width("TimesNewRomanPS-BoldItalicMT", "A").is_some());
assert_eq!(standard_14_width("CourierNew-Bold", "x"), Some(600.0));
assert!(standard_14_width("TimesNewRoman", "A").is_some());
assert!(standard_14_width("Times New Roman", "A").is_some());
}
#[test]
fn standard_14_rejects_metrically_distinct_siblings() {
assert!(standard_14_width("Helvetica-Narrow", "A").is_none());
assert!(standard_14_width("HelveticaNeue-Bold", "A").is_none());
assert!(standard_14_width("Helvetica Neue", "A").is_none());
assert!(standard_14_width("TimesTen-Bold", "A").is_none());
assert!(standard_14_width("Helvetica-Light", "A").is_none());
assert!(standard_14_width("Times New Roman Condensed", "A").is_none());
}
#[test]
fn standard_14_classify_case_folds() {
assert_eq!(standard_14_width("arial-bold", "A"), Some(722.0));
}
}