Reputation: 3084
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!
Upvotes: 5
Views: 6020
Reputation: 451
They adopted font for compose resource feature, you can add your font to font resources folder
and then apply font to your text style like so
val Typography1
@Composable // Composable is required for loading font from compose resources
get() = Typography(
displayLarge = TextStyle(
fontFamily = FontFamily(Font(Res.font.itim_regular))
)
)
// Or you can also apply font to all styles
val Typography
@Composable
get() = Typography().let {
val itimFont = FontFamily(Font(Res.font.itim_regular))
it.copy(
displayLarge = it.displayLarge.copy(fontFamily = itimFont),
displayMedium = it.displayMedium.copy(fontFamily = itimFont),
displaySmall = it.displaySmall.copy(fontFamily = itimFont),
headlineLarge = it.headlineLarge.copy(fontFamily = itimFont),
headlineMedium = it.headlineMedium.copy(fontFamily = itimFont),
headlineSmall = it.headlineSmall.copy(fontFamily = itimFont),
titleLarge = it.titleLarge.copy(fontFamily = itimFont),
titleMedium = it.titleMedium.copy(fontFamily = itimFont),
titleSmall = it.titleSmall.copy(fontFamily = itimFont),
bodyLarge = it.bodyLarge.copy(fontFamily = itimFont),
bodyMedium = it.bodyMedium.copy(fontFamily = itimFont),
bodySmall = it.bodySmall.copy(fontFamily = itimFont),
labelLarge = it.labelLarge.copy(fontFamily = itimFont),
labelMedium = it.labelMedium.copy(fontFamily = itimFont),
labelSmall = it.labelSmall.copy(fontFamily = itimFont)
)
}
Upvotes: 1
Reputation: 938
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)
),
)
Upvotes: 5
Reputation: 21
This is other way to link and use custom Compose fonts in Compose Multiplatform
Upvotes: 2
Reputation: 497
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.
Upvotes: 3