mirror of
https://github.com/storytold/vectorcraft.git
synced 2026-11-02 14:16:56 -06:00
Type: Noto Sans Thai from craft-fonts is the Thai fallback, on the web too
The web build has no installed fonts, so Thai there showed as empty boxes. With a craft-fonts checkout that has Noto Sans Thai, its Thai font joins the document font database after the Arabic ones (the fallback for Thai where no Thai font is installed) and the web build fetches it before the app starts, as it does Noto Sans Arabic. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Opus 5.5
parent
7a85f6050d
commit
70e99987e9
@@ -1,8 +1,8 @@
|
||||
//! Fonts from the optional craft-fonts build input (<https://github.com/storytold/craft-fonts>).
|
||||
//!
|
||||
//! Built with `CRAFT_FONTS_DIR=<craft-fonts checkout>`, [`CRAFT_FONTS`] holds every font in its
|
||||
//! manifest (Japanese UI and document fonts, and Arabic fonts); built without it, it is empty and Japanese
|
||||
//! text falls back to the installed system fonts. Release builds always set it. See `build.rs`
|
||||
//! manifest (Japanese UI and document fonts, Arabic fonts and Noto Sans Thai); built without it,
|
||||
//! it is empty and that text falls back to the installed system fonts. Release builds always set it. See `build.rs`
|
||||
//! and craftrules `standards/fonts.md`.
|
||||
|
||||
/// A font from the optional craft-fonts build input (empty unless built with `CRAFT_FONTS_DIR`).
|
||||
@@ -39,6 +39,10 @@ impl CraftFont {
|
||||
pub fn is_arabic(&self) -> bool {
|
||||
self.scripts.contains(&"Arab")
|
||||
}
|
||||
/// Is the font for Thai text?
|
||||
pub fn is_thai(&self) -> bool {
|
||||
self.scripts.contains(&"Thai")
|
||||
}
|
||||
/// A serif (Mincho) family, for document text.
|
||||
pub fn is_mincho(&self) -> bool {
|
||||
self.family.contains("Mincho")
|
||||
@@ -63,11 +67,13 @@ pub fn japanese_document_fonts() -> Vec<&'static CraftFont> {
|
||||
|
||||
/// The craft-fonts faces the document font database loads: the Japanese ones in
|
||||
/// [`japanese_document_fonts`] order, then the Arabic ones in manifest order (Noto Sans Arabic
|
||||
/// first: the fallback for Arabic text; the other families are picked by name). Empty when built
|
||||
/// without craft-fonts.
|
||||
/// first: the fallback for Arabic text; the other families are picked by name), then the Thai ones
|
||||
/// (Noto Sans Thai: the fallback for Thai text where no Thai font is installed, and on the web).
|
||||
/// Empty when built without craft-fonts.
|
||||
pub fn document_fonts() -> Vec<&'static CraftFont> {
|
||||
let mut v = japanese_document_fonts();
|
||||
v.extend(CRAFT_FONTS.iter().filter(|f| f.is_arabic() && !f.is_japanese()));
|
||||
v.extend(CRAFT_FONTS.iter().filter(|f| f.is_thai() && !f.is_japanese() && !f.is_arabic()));
|
||||
v
|
||||
}
|
||||
|
||||
@@ -104,8 +110,10 @@ mod tests {
|
||||
assert!(name.ends_with(".ttf") || name.ends_with(".otf"), "{}", w.url);
|
||||
assert!(w.integrity.starts_with("sha256-") && w.integrity.len() == "sha256-".len() + 44, "{}", w.integrity);
|
||||
}
|
||||
// The fallbacks the first frame may need: Noto Sans Arabic and Noto Sans Thai, where the
|
||||
// checkout has them.
|
||||
let startup: Vec<_> = WEB_FONTS.iter().filter(|w| w.startup).map(|w| w.family).collect();
|
||||
let noto = CRAFT_FONTS.iter().any(|f| f.family == "Noto Sans Arabic");
|
||||
assert_eq!(startup, if noto { vec!["Noto Sans Arabic"] } else { vec![] });
|
||||
let expected: Vec<_> = ["Noto Sans Arabic", "Noto Sans Thai"].into_iter().filter(|n| CRAFT_FONTS.iter().any(|f| f.family == *n)).collect();
|
||||
assert_eq!(startup, expected);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -729,6 +729,20 @@ fn burasagari_leaves_latin_commas_and_full_stops_inside_the_line() {
|
||||
}
|
||||
}
|
||||
|
||||
/// With craft-fonts and no installed fonts (the web), Thai is set in Noto Sans Thai, not as empty
|
||||
/// boxes. Skipped when built without craft-fonts or with a checkout that has no Thai font.
|
||||
#[test]
|
||||
fn thai_without_installed_fonts_takes_the_craft_fonts_thai_font() {
|
||||
if !crate::CRAFT_FONTS.iter().any(|f| f.is_thai()) {
|
||||
eprintln!("skipping: no Thai font in craft-fonts (set CRAFT_FONTS_DIR to a checkout that has one)");
|
||||
return;
|
||||
}
|
||||
let l = layout(db(), &point("ภาษาไทย", style(20.0)));
|
||||
assert!(!l.glyphs.is_empty() && l.glyphs.iter().all(|g| g.gid != 0), "no .notdef");
|
||||
let families: Vec<String> = l.glyphs.iter().filter_map(|g| db().face_by_id(g.font_id)).map(|f| f.family.clone()).collect();
|
||||
assert!(families.iter().all(|f| f == "Noto Sans Thai"), "{families:?}");
|
||||
}
|
||||
|
||||
/// Thai is written without spaces between words: area type breaks its lines between words (as a
|
||||
/// model of Thai words finds them), never inside a word nor before a vowel or tone mark.
|
||||
#[test]
|
||||
|
||||
Reference in New Issue
Block a user