Does compose web support variable fonts? I am tryi...
# compose-web
a
Does compose web support variable fonts? I am trying to use Inter, works great on desktop but shows squares on web
f
I was not familiar with the term Variable Fonts; But it sounds really cool! Would be great if supported 😉 https://fonts.google.com/knowledge/introducing_type/introducing_variable_fonts
a
Go +1 the issue if u havent
1
o
I see someone has already contributed its support - https://github.com/JetBrains/compose-multiplatform-core/pull/1623 🙂 And if you want to use them via Compose resources - https://github.com/JetBrains/compose-multiplatform/pull/5183
a
@Oleksandr Karpovich [JB] do i have to use the
variationSettings = FontVariation.Settings(FontVariation.weight(400))
parameter to make it work? right now i am getting squares without it
I am also getting squares for non variable fonts
o
do i have to use the
variationSettings = FontVariation.Settings(FontVariation.weight(400))
yes, it looks correct. Here is a code of the example in our demo project: https://github.com/JetBrains/compose-multiplatform-core/blob/367bb867d66f0f1d2ce7d[…]tlin/androidx/compose/mpp/demo/components/text/VariableFonts.kt
I am also getting squares for non variable fonts
How do you set a font? Do you use Compose Resources?
a
yes. same code works on desktop, doesnt work on wasm
let me share a snippet
it is not about fonts after all, but i might have found a bug. will report when i get to the bottom of it
@Oleksandr Karpovich [JB] do you know if you folks rely on recomposition to load the font on web, while other platforms don't need that?
o
yes, that's true. Since web loads all the resources asynchronously, there is an internal state which is updated when a font is ready.
a
then the squares is a result of not being able to recompose (which is a bug on my code) do you show squares if the font is not yet loaded?
o
usually it's better to wait until the font is ready before showing any content. https://www.jetbrains.com/help/kotlin-multiplatform-dev/compose-multiplatform-resources-usage.html#preloading-of-resources-for-web-targets there is an expandable snippet
a
i see. thanks for the tip
👍 1
w
hi folks! would you mind sharing a snippet how variable font should be configured for web target (wasmJsMain), after compiling the font is not loaded at all in web target (only non text composables are rendered) I have this in my common code (pretty sure I do it wrong) :
Copy code
@Composable
fun AppTheme(
    darkTheme: Boolean = isSystemInDarkTheme(),
    content: @Composable() () -> Unit
) {
    val colorScheme = when {
        darkTheme -> darkScheme
        else -> lightScheme
    }
    val interFontFamily = FontFamily(
        Font(
            Res.font.inter_var,
            variationSettings = FontVariation.Settings(FontVariation.weight(400))
        )
    )


    val typography = Typography(
        bodyLarge = TextStyle(fontFamily = interFontFamily),
        bodyMedium = TextStyle(fontFamily = interFontFamily),
        bodySmall = TextStyle(fontFamily = interFontFamily),
        titleLarge = TextStyle(fontFamily = interFontFamily),
        titleMedium = TextStyle(fontFamily = interFontFamily),
        titleSmall = TextStyle(fontFamily = interFontFamily),
        labelLarge = TextStyle(fontFamily = interFontFamily),
        labelMedium = TextStyle(fontFamily = interFontFamily),
        labelSmall = TextStyle(fontFamily = interFontFamily),
        displayLarge = TextStyle(fontFamily = interFontFamily),
        displayMedium = TextStyle(fontFamily = interFontFamily),
        displaySmall = TextStyle(fontFamily = interFontFamily)
    )

    MaterialTheme(
        colorScheme = colorScheme,
        typography = typography,
        content = content
    )
}
o
@wiktor Since on web the resources are loaded asynchronously, I expect that
AppTheme
would recompose after the font file has been loaded. And I expect that
Typography
instance would be recreated too. But maybe it doesn't happen. I think it's worth trying to preload the font on web: https://github.com/JetBrains/compose-multiplatform/blob/master/components/resources/demo/shared/src/wasmJsMain/kotlin/main.wasm.kt#L31 and proceed to the rest of the app only after the font is ready. _ In your case:
Copy code
// somewhere in your web main.kt

if (font1 != null && font2 != null && emojiFont != null && fontsFallbackInitialiazed) {
            AppTheme(..., content)
}
I think you don't need
fontFamilyResolver.preload
in this case. Only
val font1 by preloadFont(Res.font.Workbench_Regular)
, use the overload with variationSettings - https://github.com/JetBrains/compose-multiplatform/blob/master/components/resource[…]/webMain/kotlin/org/jetbrains/compose/resources/Resource.web.kt
w
thank you for the response! I tried to preload the font:
Copy code
@OptIn(ExperimentalComposeUiApi::class, ExperimentalResourceApi::class)
fun main() {
    ComposeViewport(document.body!!) {
        val font by preloadFont(Res.font.inter_var)
        if (font != null) {
            App()
        } else {
            println("Font not loaded")
        }
    }
}
but still no luck, I see this in logs:
ignore me, this is not font loading problem, but something with the layout 🤦 weirdly when I use custom font layout is cut on height (it used to fill max parent)