Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Using fonts in a Compose Multiplatform project

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?

like image 565
Vince Avatar asked Jul 21 '26 06:07

Vince


1 Answers

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)
    ),
)
like image 121
Shahriar Zaman Avatar answered Jul 22 '26 18:07

Shahriar Zaman



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!