///|
/// App-registered embedded font: the family it was registered under plus the
/// Skia typeface created from the font data.
priv struct SkiaEmbeddedFont {
family : @core.FontFamily
typeface : @skia_native.Typeface
}
///|
/// Registry of fonts registered via `@core.TextSystem::register_font_data`.
/// Renderer-global so multiple text systems share one registry; later
/// registrations of the same family replace earlier ones.
let embedded_fonts : Ref[Array[SkiaEmbeddedFont]] = Ref([])
///|
/// Registers in-memory font data under a family. The typeface is created
/// eagerly so invalid data fails at registration time, and it is registered
/// with the native side so paragraph layout can resolve the family by name.
fn skia_register_font_data(family : @core.FontFamily, data : Bytes) -> Unit {
let family_alias = skia_embedded_font_alias(family)
match @skia_native.Typeface::register_data(family_alias, data) {
Some(typeface) => {
embedded_fonts.val = embedded_fonts.val.filter(fn(existing) {
existing.family != family
})
embedded_fonts.val.push({ family, typeface })
}
None => ()
}
}
///|
/// Returns the registered typeface for `font` when any family in the font
/// spec's family stack matches a registered embedded font. The font spec's
/// own order wins: the first matching registered family is used.
fn skia_typeface_from_embedded(font : @core.FontSpec) -> @skia_native.Typeface? {
for family in font.families.families {
for embedded in embedded_fonts.val {
if embedded.family == family {
return Some(embedded.typeface)
}
}
}
None
}
///|
/// Converts a font spec's variation axes into native (tag, value) pairs.
fn skia_variation_pairs(font : @core.FontSpec) -> Array[(Bytes, Float)] {
font.variations.map(fn(variation) {
(
@utf8.encode(variation.axis[:], bom=false),
Float::from_double(variation.value),
)
})
}
///|
/// Family alias used for native registration: `Name(name)` registers the
/// literal name; generic families register their first concrete candidate
/// so a `FontSpec` using the same generic family resolves the embedded font.
fn skia_embedded_font_alias(family : @core.FontFamily) -> Bytes {
let candidates = skia_font_family_candidates(family)
if candidates.is_empty() {
b""
} else {
@utf8.encode(candidates[0][:], bom=false)
}
}