Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions crates/ui-egui/src/i18n.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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.
Expand Down
7 changes: 7 additions & 0 deletions crates/ui-egui/src/i18n/ui.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand Down
12 changes: 10 additions & 2 deletions crates/ui-egui/src/theme.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand All @@ -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());
}
Expand Down