Using fonts in a Compose Multiplatform project
Asked Answered
B

3

5

I am looking for a way to easily use custom fonts in a Compose Multiplatform project.

I found that we need to use Font from the androidx.compose.ui.text.platform.Font package. But this object takes in parameter data: ByteArray.

Until now, I haven't found a way to use Font to import a font file from the commonMain resource directory.

How to use custom fonts in the commonMain part of a Compose Multiplatform project?

Thank you for your help!

Beneath answered 17/4, 2023 at 12:31 Comment(1)
You need to set font from resources, check this answer https://mcmap.net/q/2030241/-can-39-t-use-a-font-in-kotlin-multiplatformSetser
C
5

There is a easy way to use common resources directory for both android and desktop.

create src/commonMain/resources/ directory inside :shared module. then set the android source sets of android and jvm as follows:

kotlin {
    targetHierarchy.default()

    android {
        compilations.all {
            kotlinOptions {
                jvmTarget = "1.8"
            }
        }
    }

    jvm {
        sourceSets {
            named("jvmMain") {
                resources.srcDir("src/commonMain/resources") // <============= here
            }
        }
    }

    sourceSets {
        val commonMain by getting {
            dependencies {
                // compose libraries
                implementation(compose.runtime)
                implementation(compose.foundation)
                @OptIn(org.jetbrains.compose.ExperimentalComposeLibrary::class)
                implementation(compose.components.resources)
            }
        }
        
        val jvmMain by getting {
            dependencies {
                implementation(compose.desktop.currentOs)
            }
        }
    }
}

android {
    namespace = "a.b.c"
    compileSdk = 33
    defaultConfig {
        minSdk = 21
    }
    sourceSets {
        named("main") {
            manifest.srcFile("src/androidMain/AndroidManifest.xml")
            res.srcDirs("src/commonMain/resources") // <============= here
        }
    }
}

To get the fonts create a provider file inside :shared:commonMain/ as:

expect val acmeTypography: Typography

Now implement it inside both :shared:androidMain and :shared:jvmMain as:

// shared:jvmMain/

import androidx.compose.ui.text.platform.Font

actual val acmeTypography = Typography(
    defaultFontFamily = FontFamily(
        Font(resource = "font/acme_regular.ttf", FontWeight.Normal)
    ),
)

// shared:androidMain
import androidx.compose.ui.text.font.Font

actual val acmeTypography = Typography(
    defaultFontFamily = FontFamily(
        Font(R.font.acme_regular, FontWeight.Normal)
    ),
)
Catechol answered 7/7, 2023 at 18:14 Comment(1)
Does this work for iOS as well?Rodger
L
3

The easiest way is to use moko resources : https://github.com/icerockdev/moko-resources

Add the font in commonMain/resources/MR/fonts

for example: PlayfairDisplay-Bold.ttf file

Then load the FontFamily :

val fontFamilyExtraBold: FontFamily = fontFamilyResource(SharedRes.fonts.PlayfairDisplay.extraBold)

And finaly use it in your Typography in your theme. More infos on Moko resources docs.

Lentha answered 21/5, 2023 at 12:11 Comment(0)
O
2

This is other way to link and use custom Compose fonts in Compose Multiplatform

https://jassielcastro.medium.com/custom-fonts-in-android-and-ios-applications-using-kotlin-multiplatform-and-jetpack-compose-c88d2d519e77

Oreilly answered 12/6, 2023 at 4:41 Comment(1)
Please share the content of the link as part of your answer. That way if the link goes down the answer is still useful for other users.Muddler

© 2022 - 2024 — McMap. All rights reserved.