@ -2,37 +2,31 @@ package org.jetbrains.compose.resources
@@ -2,37 +2,31 @@ package org.jetbrains.compose.resources
import androidx.compose.runtime.Composable
import androidx.compose.runtime.getValue
import androidx.compose.ui.text.ExperimentalTextApi
import androidx.compose.ui.text.font.*
import androidx.compose.ui.text.platform.Font
import androidx.compose.ui.text.platform.SystemFont
import androidx.compose.ui.unit.Density
import kotlin.io.encoding.Base64
import kotlin.io.encoding.ExperimentalEncodingApi
private val emptyFontBase64 =
" T1RUTwAJAIAAAwAQQ0ZGIML7MfIAAAQIAAAA2U9TLzJmMV8PAAABAAAAAGBjbWFwANUAVwAAA6QAAABEaGVhZCMuU7 " +
" IAAACcAAAANmhoZWECvgAmAAAA1AAAACRobXR4Az4AAAAABOQAAAAQbWF4cAAEUAAAAAD4AAAABm5hbWUpw3nbAAABYAAAAkNwb3N0AAMA " +
" AAAAA+gAAAAgAAEAAAABAADs7nftXw889QADA+gAAAAA4WWJaQAAAADhZYlpAAAAAAFNAAAAAAADAAIAAAAAAAAAAQAAArz+1AAAAU0AAA " +
" AAAAAAAQAAAAAAAAAAAAAAAAAAAAQAAFAAAAQAAAADAHwB9AAFAAACigK7AAAAjAKKArsAAAHfADEBAgAAAAAAAAAAAAAAAAAAAAEAAAAA " +
" AAAAAAAAAABYWFhYAEAAIABfArz+1AAAAAAAAAAAAAEAAAAAAV4AAAAgACAAAAAAACIBngABAAAAAAAAAAIAbwABAAAAAAABAAUAAAABAA " +
" AAAAACAAcADwABAAAAAAADABAAdQABAAAAAAAEAA0AJAABAAAAAAAFAAIAbwABAAAAAAAGAAwASwABAAAAAAAHAAIAbwABAAAAAAAIAAIA " +
" bwABAAAAAAAJAAIAbwABAAAAAAAKAAIAbwABAAAAAAALAAIAbwABAAAAAAAMAAIAbwABAAAAAAANAAIAbwABAAAAAAAOAAIAbwABAAAAAA " +
" AQAAUAAAABAAAAAAARAAcADwADAAEECQAAAAQAcQADAAEECQABAAoABQADAAEECQACAA4AFgADAAEECQADACAAhQADAAEECQAEABoAMQAD " +
" AAEECQAFAAQAcQADAAEECQAGABgAVwADAAEECQAHAAQAcQADAAEECQAIAAQAcQADAAEECQAJAAQAcQADAAEECQAKAAQAcQADAAEECQALAA " +
" QAcQADAAEECQAMAAQAcQADAAEECQANAAQAcQADAAEECQAOAAQAcQADAAEECQAQAAoABQADAAEECQARAA4AFmVtcHR5AGUAbQBwAHQAeVJl " +
" Z3VsYXIAUgBlAGcAdQBsAGEAcmVtcHR5IFJlZ3VsYXIAZQBtAHAAdAB5ACAAUgBlAGcAdQBsAGEAcmVtcHR5UmVndWxhcgBlAG0AcAB0AH " +
" kAUgBlAGcAdQBsAGEAciIiACIAIiIiOmVtcHR5IFJlZ3VsYXIAIgAiADoAZQBtAHAAdAB5ACAAUgBlAGcAdQBsAGEAcgAAAAABAAMAAQAA " +
" AAwABAA4AAAACgAIAAIAAgAAACAAQQBf//8AAAAAACAAQQBf//8AAP/h/8H/pAABAAAAAAAAAAAAAAADAAAAAAAAAAAAAAAAAAAAAAAAAA " +
" AAAAAAAAAAAAAAAQAEAQABAQENZW1wdHlSZWd1bGFyAAEBASf4GwD4HAL4HQP4HgSLi/lQ9+EFHQAAAHgPHQAAAH8Rix0AAADZEgAHAQED " +
" EBUcISIsIiJlbXB0eSBSZWd1bGFyZW1wdHlSZWd1bGFyc3BhY2VBdW5kZXJzY29yZQAAAAGLAYwBjQAEAQFMT1FT+F2f+TcVi4uL/TeLiw " +
" iLi/g1i4uLCIuLi/k3i4sIi4v8NYuLiwi7/QcVi4uL+NeLiwiLi/fUi4uLCIuLi/zXi4sIi4v71IuLiwgO9+EOnw6fDgAAAAHJAAABTQAA " +
" ABQAAAAUAAA= "
private const val defaultFontIdentity = " org.jetbrains.compose.resources.defaultFont "
@OptIn ( ExperimentalEncodingApi :: class )
private val defaultEmptyFont by lazy { Font ( " org.jetbrains.compose.emptyFont " , Base64 . decode ( emptyFontBase64 ) ) }
// It's mainly necessary for the web.
// A meaningful default font is used while a requested font is being loaded asynchronously.
// Check out skiko for the default font details - it's bundled into skiko.wasm
// https://github.com/JetBrains/skiko/blob/master/skiko/src/webMain/cpp/Roboto-Regular.ttf.cc
//
// Notes:
// - On the web, the default font provided by skiko has limited glyph coverage.
// When encountering unknown glyphs, it will display '<EFBFBD> ' or tofu (empty box) characters (for example, for emojis).
// - the default font doesn't support font styles and weights customization.
@OptIn ( ExperimentalTextApi :: class )
private val defaultFont : Font = SystemFont ( defaultFontIdentity )
private val fontCache = AsyncCache < String , Font > ( )
internal val Font . isEmptyPlaceholder : Boolean
get ( ) = this == defaultEmptyFont
internal val Font . isDefault : Boolean
@OptIn ( ExperimentalTextApi :: class )
get ( ) = ( this as ? SystemFont ) ?. identity == defaultFontIdentity
private fun ByteArray . footprint ( ) = " [ $size : ${lastOrNull()?.toInt()} ] "
@ -44,7 +38,7 @@ private fun ByteArray.footprint() = "[$size:${lastOrNull()?.toInt()}]"
@@ -44,7 +38,7 @@ private fun ByteArray.footprint() = "[$size:${lastOrNull()?.toInt()}]"
@Composable
actual fun Font ( resource : FontResource , weight : FontWeight , style : FontStyle ) : Font {
val resourceReader = LocalResourceReader . currentOrPreview
val fontFile by rememberResourceState ( resource , weight , style , { defaultEmpty Font } ) { env ->
val fontFile by rememberResourceState ( resource , weight , style , { defaultFont } ) { env ->
val path = resource . getResourceItemByEnvironment ( env ) . path
val key = " $path : $weight : $style "
fontCache . getOrLoad ( key ) {
@ -54,7 +48,6 @@ actual fun Font(resource: FontResource, weight: FontWeight, style: FontStyle): F
@@ -54,7 +48,6 @@ actual fun Font(resource: FontResource, weight: FontWeight, style: FontStyle): F
}
return fontFile
}
@Composable
actual fun Font (
resource : FontResource ,
@ -63,7 +56,7 @@ actual fun Font(
@@ -63,7 +56,7 @@ actual fun Font(
variationSettings : FontVariation . Settings ,
) : Font {
val resourceReader = LocalResourceReader . currentOrPreview
val fontFile by rememberResourceState ( resource , weight , style , variationSettings , { defaultEmpty Font } ) { env ->
val fontFile by rememberResourceState ( resource , weight , style , variationSettings , { defaultFont } ) { env ->
val path = resource . getResourceItemByEnvironment ( env ) . path
val key = " $path : $weight : $style : ${variationSettings.getCacheKey()} "
fontCache . getOrLoad ( key ) {