use std::sync::{Arc, OnceLock};
use parley::fontique::{Blob, FamilyId, FontInfoOverride, GenericFamily, Script};
use crate::FontContext;
pub type FamilyFallback = fn(&str) -> Option<&'static str>;
static FAMILY_FALLBACK: OnceLock<FamilyFallback> = OnceLock::new();
pub(crate) fn set(fallback: FamilyFallback) {
let _ = FAMILY_FALLBACK.set(fallback);
}
pub(crate) fn lookup(name: &str) -> Option<&'static str> {
let mapped = FAMILY_FALLBACK.get()?(name)?;
(!mapped.eq_ignore_ascii_case(name)).then_some(mapped)
}
pub fn register_face(ctx: &mut FontContext, bytes: &'static [u8]) {
ctx.collection
.register_fonts(Blob::new(Arc::new(bytes) as _), None);
}
pub fn register_family(
ctx: &mut FontContext,
family: &str,
bytes: &'static [u8],
) -> Option<FamilyId> {
let registered = ctx.collection.register_fonts(
Blob::new(Arc::new(bytes) as _),
Some(FontInfoOverride {
family_name: Some(family),
..FontInfoOverride::default()
}),
);
registered.into_iter().next().map(|(id, _)| id)
}
pub fn bind(
ctx: &mut FontContext,
sans: FamilyId,
serif: FamilyId,
mono: FamilyId,
extra: &[FamilyId],
scripts: &[[u8; 4]],
) {
let with_extra = |primary: FamilyId| std::iter::once(primary).chain(extra.iter().copied());
for generic in [
GenericFamily::SansSerif,
GenericFamily::SystemUi,
GenericFamily::UiSansSerif,
] {
ctx.collection
.set_generic_families(generic, with_extra(sans));
}
for generic in [GenericFamily::Serif, GenericFamily::UiSerif] {
ctx.collection
.set_generic_families(generic, with_extra(serif));
}
for generic in [GenericFamily::Monospace, GenericFamily::UiMonospace] {
ctx.collection
.set_generic_families(generic, with_extra(mono));
}
for script in scripts {
ctx.collection
.append_fallbacks(Script::from_bytes(*script), extra.iter().copied());
}
}