mirror of
https://github.com/storytold/designcraft.git
synced 2026-10-24 10:16:59 -06:00
fonts: Georgian UI text from craft-fonts' Noto Sans Georgian (#1270)
* fonts: Georgian UI text from craft-fonts' Noto Sans Georgian font_definitions registers the Geor face and appends it to every family, like Arabic (and to the Arabic families after the CJK faces); the wasm filter in crates/fonts/build.rs keeps the face. The installed-font probe for Geor stays skipped whenever craft-fonts covers the script. Bump craft-fonts-ref to a71c20e (storytold/craft-fonts#27). Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01YMTAbGNRxnMEzRvYnQGphF * Release: build the web version with craft-fonts too (web-craft-fonts) The shared release workflow builds the web release without CRAFT_FONTS_DIR unless web-craft-fonts is set, so the web version would still have no Georgian face (CodeRabbit on vectorcraft#2934). Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01YMTAbGNRxnMEzRvYnQGphF * test: the Arabic New Document test scrolls to Height like the other fields With craft-fonts' Noto Sans Arabic (from a71c20e3) the rows above Height are taller, so at 392x271 the field starts partly below the dialog body's clip and the test's unscrolled visible_label check failed (FreeBSD jobs). It stays reachable: scroll to it as the test already does for Gutter and the margins. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01YMTAbGNRxnMEzRvYnQGphF * CI: same craft-fonts pin as release (a71c20e3), so the gate checks the Georgian face Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01YMTAbGNRxnMEzRvYnQGphF --------- Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Opus 5.5
parent
348a8a4dc9
commit
80d13911b2
@@ -22,7 +22,7 @@ jobs:
|
||||
uses: storytold/craft-common-actions/.github/workflows/gate.yml@main
|
||||
with:
|
||||
# Same craft-fonts commit as release.yml.
|
||||
craft-fonts-ref: abb83316d96aa59c1cf64784289e378fe9fa5695
|
||||
craft-fonts-ref: a71c20e30af613287c504f7e685ca8fad77752bc
|
||||
timeout-minutes: 90
|
||||
packages: >-
|
||||
pkg-config libxkbcommon-dev libwayland-dev libx11-dev libxcb1-dev libxcursor-dev
|
||||
|
||||
@@ -27,4 +27,4 @@ jobs:
|
||||
# Intentionally tracked at @main (not SHA-pinned) so org-wide CI improvements, security fixes, and build optimizations propagate without PR churn across all craftapp repos.
|
||||
uses: storytold/craft-common-actions/.github/workflows/freebsd.yml@main
|
||||
with:
|
||||
craft-fonts-ref: abb83316d96aa59c1cf64784289e378fe9fa5695
|
||||
craft-fonts-ref: a71c20e30af613287c504f7e685ca8fad77752bc
|
||||
|
||||
@@ -24,7 +24,8 @@ jobs:
|
||||
with:
|
||||
app-name: designcraft
|
||||
app-title: DesignCraft
|
||||
craft-fonts-ref: abb83316d96aa59c1cf64784289e378fe9fa5695
|
||||
craft-fonts-ref: a71c20e30af613287c504f7e685ca8fad77752bc
|
||||
web-craft-fonts: true
|
||||
version: ${{ inputs.version }}
|
||||
secrets:
|
||||
APPLE_CERTIFICATE: ${{ secrets.APPLE_CERTIFICATE }}
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
//! Optional craft-fonts build input (https://github.com/storytold/craft-fonts, recipe from its
|
||||
//! `docs/integration.md`). With `CRAFT_FONTS_DIR=<checkout>` the fonts in its
|
||||
//! `fonts/manifest.txt` are embedded as `CRAFT_FONTS`; unset, `CRAFT_FONTS` is empty. Web
|
||||
//! (wasm32) builds embed only the UI face, BIZ UDPGothic Regular, to stay within the web size
|
||||
//! (wasm32) builds embed only the UI faces, BIZ UDPGothic Regular and Noto Sans Georgian Regular, to stay within the web size
|
||||
//! budget. It only reads the local checkout: no network.
|
||||
use std::fmt::Write as _;
|
||||
use std::path::PathBuf;
|
||||
@@ -38,7 +38,7 @@ fn craft_fonts(dir: &std::path::Path) -> Result<String, String> {
|
||||
let [family, style, file, scripts, ..] = f.as_slice() else {
|
||||
return Err(format!("malformed manifest line: {line}"));
|
||||
};
|
||||
if wasm && !(*family == "BIZ UDPGothic" && *style == "Regular") {
|
||||
if wasm && !matches!((*family, *style), ("BIZ UDPGothic" | "Noto Sans Georgian", "Regular")) {
|
||||
continue;
|
||||
}
|
||||
let path = dir.join(file).canonicalize().map_err(|e| format!("{file}: {e}"))?;
|
||||
|
||||
@@ -9149,7 +9149,11 @@ mod tests {
|
||||
for _ in 0..3 {
|
||||
dialog_frame(&mut app, &ctx, screen, vec![]);
|
||||
}
|
||||
let height = visible_label(&dialog_frame(&mut app, &ctx, screen, vec![]), screen, "66p1");
|
||||
// With craft-fonts' Noto Sans Arabic the rows above are taller, so at the smallest size the
|
||||
// Height field starts partly below the body's clip: scroll to it like the other fields.
|
||||
let labels = dialog_frame(&mut app, &ctx, screen, vec![]);
|
||||
let (_, _, body) = labels.iter().find(|(text, _, _)| text.trim() == "66p1").expect("66p1 is painted");
|
||||
let height = scroll_to_label(&mut app, &ctx, screen, body.center(), "66p1");
|
||||
click_dialog(&mut app, &ctx, screen, height.center());
|
||||
dialog_frame(
|
||||
&mut app,
|
||||
|
||||
@@ -446,9 +446,9 @@ pub(crate) fn add_system_fallbacks(fonts: &mut FontDefinitions, system: &[System
|
||||
|
||||
/// The UI fonts: the app's own, then the craft-fonts faces from `craft` (empty without
|
||||
/// `CRAFT_FONTS_DIR`) as fallbacks at the end of every family: Japanese (BIZ UDPGothic first) and
|
||||
/// Simplified Chinese, in the interface language's order, then Arabic. The `arabic` families
|
||||
/// Simplified Chinese, in the interface language's order, then Arabic and Georgian. The `arabic` families
|
||||
/// put the Arabic face first for right-to-left runs. egui has no system-font discovery, so
|
||||
/// without craft-fonts CJK and Arabic UI text has no glyphs.
|
||||
/// without craft-fonts CJK, Arabic and Georgian UI text has no glyphs.
|
||||
pub(crate) fn font_definitions(craft: &'static [designcraft_fonts::CraftFont], lang: &str) -> FontDefinitions {
|
||||
let mut fonts = FontDefinitions::default();
|
||||
let add = |fonts: &mut FontDefinitions, name: &str, data: &'static [u8]| {
|
||||
@@ -466,12 +466,13 @@ pub(crate) fn font_definitions(craft: &'static [designcraft_fonts::CraftFont], l
|
||||
japanese.sort_by_key(|f| (f.family != "BIZ UDPGothic", f.style != "Regular"));
|
||||
let chinese = pick("Hans");
|
||||
let arabic = pick("Arab");
|
||||
let georgian = pick("Geor");
|
||||
let name = |f: &designcraft_fonts::CraftFont| format!("craft-{}-{}", f.family, f.style);
|
||||
for f in japanese.iter().chain(&chinese) {
|
||||
// CJK faces sit on the Latin baseline (see `baseline_tweak`).
|
||||
fonts.font_data.insert(name(f), Arc::new(FontData { tweak: baseline_tweak(f.bytes, 0), ..FontData::from_static(f.bytes) }));
|
||||
}
|
||||
for f in &arabic {
|
||||
for f in arabic.iter().chain(&georgian) {
|
||||
add(&mut fonts, &name(f), f.bytes);
|
||||
}
|
||||
// Han characters take the forms of the interface language: Chinese faces first for Chinese.
|
||||
@@ -483,12 +484,16 @@ pub(crate) fn font_definitions(craft: &'static [designcraft_fonts::CraftFont], l
|
||||
ja.sort_by_key(|f| (f.family != "BIZ UDPGothic", f.style != "Bold"));
|
||||
}
|
||||
let (first, second) = if zh { (&chinese, &ja) } else { (&ja, &chinese) };
|
||||
stack.extend(first.iter().chain(second).chain(&arabic).map(|f| name(f)));
|
||||
stack.extend(first.iter().chain(second).chain(&arabic).chain(&georgian).map(|f| name(f)));
|
||||
}
|
||||
// Arabic runs (rtl.rs): the Arabic face first, so letters and spaces shape as one run.
|
||||
for family in ["arabic", "arabic-semibold"] {
|
||||
let ui = if family == "arabic" { "ui" } else { "ui-semibold" };
|
||||
let stack = arabic.iter().map(|f| name(f)).chain([ui.to_string(), "ui".to_string()]).chain(japanese.iter().chain(&chinese).map(|f| name(f)));
|
||||
let stack = arabic
|
||||
.iter()
|
||||
.map(|f| name(f))
|
||||
.chain([ui.to_string(), "ui".to_string()])
|
||||
.chain(japanese.iter().chain(&chinese).chain(&georgian).map(|f| name(f)));
|
||||
let mut seen = std::collections::HashSet::new();
|
||||
fonts.families.insert(FontFamily::Name(family.into()), stack.filter(|n| seen.insert(n.clone())).collect());
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user