mirror of
https://github.com/storytold/lightcraft.git
synced 2026-10-26 19:17:02 -06:00
The Japanese fonts (BIZ UDPGothic Regular/Bold for the UI, BIZ UDMincho for text watermarks; #110, #114) now come from storytold/craft-fonts instead of assets/fonts/. - crates/engine/build.rs: the craft-fonts recipe. With CRAFT_FONTS_DIR set it embeds the manifest's fonts as lightcraft_engine::CRAFT_FONTS (wasm32: BIZ UDPGothic Regular only, for the web size budget); unset, CRAFT_FONTS is empty. Local files only, no network; craft-fonts is not in any Cargo.toml. - UI: theme::font_definitions adds the Japanese faces after Inter and egui's defaults in every family (BIZ UDPGothic first, Bold first for semibold). About box lists the embedded families. - Watermarks: Inter, then the craft-fonts Japanese faces (Mincho first). - Removed BIZUDPGothic-Regular/Bold.ttf, BIZUDMincho-Regular.ttf and their OFL files, and their ATTRIBUTION rows; added an attribution row for craft-fonts as an optional build input; NOTICE updated. - Tests: Japanese glyph tests use CRAFT_FONTS and skip without it; new tests for Japanese in the UI with craft-fonts and for the UI and watermarks without it. - CI: the FreeBSD job builds/tests with craft-fonts. Releases check out craft-fonts at a pinned commit, build with CRAFT_FONTS_DIR + CRAFT_FONTS_REQUIRED=1, and ship the fonts' OFL licences (plus NOTICE) in every package. - Docs: AGENTS.md, CLAUDE.md, README, docs/web.md, docs/localization-ja.md, ROADMAP, parity. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
53 lines
1.9 KiB
Rust
53 lines
1.9 KiB
Rust
//! Fonts from the optional craft-fonts build input (storytold/craft-fonts).
|
|
//!
|
|
//! Built with `CRAFT_FONTS_DIR=<craft-fonts checkout>`, [`CRAFT_FONTS`] holds every font in its
|
|
//! manifest (today: the Japanese UI and document fonts); otherwise it is empty and LightCraft uses
|
|
//! only its own bundled fonts (Inter). Both the egui UI and the export watermark renderer read it
|
|
//! from here. See craftrules `standards/fonts.md`.
|
|
|
|
/// A font from the optional craft-fonts build input (empty unless built with `CRAFT_FONTS_DIR`).
|
|
pub struct CraftFont {
|
|
pub family: &'static str,
|
|
pub style: &'static str,
|
|
/// ISO 15924 scripts the font is for, e.g. `"Jpan"`.
|
|
pub scripts: &'static [&'static str],
|
|
pub bytes: &'static [u8],
|
|
}
|
|
|
|
include!(concat!(env!("OUT_DIR"), "/craft_fonts.rs"));
|
|
|
|
impl CraftFont {
|
|
/// Whether the font is meant for `script` (ISO 15924, e.g. `"Jpan"`).
|
|
pub fn covers(&self, script: &str) -> bool {
|
|
self.scripts.contains(&script)
|
|
}
|
|
|
|
/// Mincho (serif) faces, the preferred Japanese faces for document-like text.
|
|
pub fn is_mincho(&self) -> bool {
|
|
self.family.contains("Mincho")
|
|
}
|
|
}
|
|
|
|
/// The craft-fonts faces for Japanese, in `fonts`' order (empty without craft-fonts).
|
|
pub fn japanese(fonts: &'static [CraftFont]) -> impl Iterator<Item = &'static CraftFont> {
|
|
fonts.iter().filter(|f| f.covers("Jpan"))
|
|
}
|
|
|
|
#[cfg(test)]
|
|
mod tests {
|
|
use super::*;
|
|
|
|
#[test]
|
|
fn craft_fonts_are_well_formed_or_absent() {
|
|
if CRAFT_FONTS.is_empty() {
|
|
eprintln!("built without CRAFT_FONTS_DIR: no craft-fonts to check");
|
|
return;
|
|
}
|
|
for f in CRAFT_FONTS {
|
|
assert!(!f.family.is_empty() && !f.style.is_empty() && !f.scripts.is_empty(), "{}", f.family);
|
|
assert!(ab_glyph::FontRef::try_from_slice(f.bytes).is_ok(), "{} {} parses", f.family, f.style);
|
|
}
|
|
assert!(japanese(CRAFT_FONTS).next().is_some(), "craft-fonts carries Japanese faces");
|
|
}
|
|
}
|