UI-FONT: cover the Chinese interface catalog with system fallback faces

This commit is contained in:
Yura Izmailov
2026-10-20 20:43:14 +02:00
parent 9db7f3b217
commit d4f06b5a9d
3 changed files with 19 additions and 2 deletions
+2
View File
@@ -10,6 +10,8 @@ pub(crate) mod effects;
/// Translations for the panels, tooltips and dialogs below the menu bar (see the module docs).
mod ui;
use effectcraft_engine::menus::{MenuEntry, MenuNode};
#[cfg(not(target_arch = "wasm32"))]
pub(crate) use ui::catalog_characters;
pub(crate) use ui::{set_current, tr, tr_args};
/// Every language with a catalog, in the order Settings ▸ General ▸ Language lists them.
+7
View File
@@ -60,6 +60,13 @@ fn catalog(language: &str) -> Option<&'static Index> {
Some(index.get_or_init(|| rows.iter().copied().collect()))
}
/// Characters required by the fixed panel catalog, for system-font coverage selection.
/// Sorted and deduplicated so fallback registration is deterministic.
#[cfg(not(target_arch = "wasm32"))]
pub(crate) fn catalog_characters(language: &str) -> Vec<char> {
catalog(language).into_iter().flat_map(|c| c.values()).flat_map(|s| s.chars()).collect::<std::collections::BTreeSet<_>>().into_iter().collect()
}
/// Translate one interface string: the current language's row for `text`, or `text` itself.
pub(crate) fn tr(text: &str) -> &str {
catalog(current()).and_then(|c| c.get(text)).copied().unwrap_or(text)
+10 -2
View File
@@ -408,7 +408,14 @@ fn install_script_fallbacks(family_fonts: &mut FontDefinitions, language: &str)
let cjk = if is_chinese(language) { [han, KANA] } else { [KANA, han] };
let mut names = Vec::new();
let mut seen = Vec::new();
for &(probe, name) in cjk.iter().chain(SCRIPT_PROBES).chain(std::iter::once(&HANGUL)) {
// A font covering one Han probe may be a sparse subset. Register additional faces
// needed by the actual interface catalog instead of assuming whole-script coverage.
let extra = if is_chinese(language) { crate::i18n::catalog_characters(language) } else { Vec::new() };
let extra: Vec<_> = extra.into_iter().filter(|ch| *ch >= '\u{2e80}').map(|ch| (ch, "catalog-system")).collect();
for &(probe, name) in cjk.iter().chain(SCRIPT_PROBES).chain(std::iter::once(&HANGUL)).chain(&extra) {
if name == "catalog-system" && seen.iter().any(|&id| fonts::face(id).has_char(probe)) {
continue;
}
let id = fonts::fallback_for(probe, base);
if seen.contains(&id) {
continue;
@@ -422,7 +429,8 @@ fn install_script_fallbacks(family_fonts: &mut FontDefinitions, language: &str)
// Use the already-read, parsed bytes rather than reading a font file twice.
let mut data = FontData::from_owned(font.data().as_bytes().to_vec());
data.index = face.info.index;
family_fonts.font_data.insert(name.to_string(), Arc::new(data));
let name = if name == "catalog-system" { format!("{name}-{:x}", probe as u32) } else { name.to_string() };
family_fonts.font_data.insert(name.clone(), Arc::new(data));
for family in family_fonts.families.values_mut() {
family.push(name.to_string());
}