Is there a way to implement a "font stack" with co...
# compose-desktop
r
Is there a way to implement a "font stack" with compose where "FontA" is used, but it it's not found, "FontB" is used as a fallback etc..? I see that this is done internally within compose, but I don't see much other than in `FontFamily.kt`: "TODO(b/214587299): Add large ktdoc comment here about how it all works, including fallback and optional"!
Bumping this in case anyone has any ideas?
I don't see any opportunity to properly write this functionality either, since
FontFamily
and
FontFamily.Resolver
are sealed. I have a hacky workaround, but I can only use font paths and can't look up fonts by identity:
Copy code
@OptIn(ExperimentalTextApi::class)
fun fontStack(vararg fonts: Font): Font {
    require(!fonts.any { it is SystemFont }) { "SystemFont implements its own fallback stack and cannot be used here"}

    // Return the first resolvable font in the stack. Exceptions can be caught here, unlike if you were to try
    // and use a missing font in a composition.
    for (font in fonts) {
        try {
            fontResolver.resolve(fontFamily = font.toFontFamily(), fontWeight = font.weight, fontStyle = font.style)
            return font
        } catch (_: Exception) {}
    }

    // As a last resort, an invalid SystemFont will fall back internally to the platform default font.
    return SystemFont(identity = "")
}

private val fontResolver by lazy { createFontFamilyResolver() }
👍 1