My final goal is to load fonts from a Variable Font Collection file. Most phones sold in China enable users to use custom fonts system-wide(ideally), but most of those fonts don't have full support for Unicode CJK ideographs, thus causing inconsistency, so I decided to embed Noto font into my app from the very beginning of development. I'm trying to utilize VFC to reduce the APK size.
In Compose there isn't a Font() function that takes a TTC index, so I tried defining a font family in XML file(which supports android:ttcIndex attribute), reading it as Typeface and finally turning it into a Compose FontFamily. I tried with a regular variable font at first, and when all that was done, I found that Text() didn't display text in the font weight I specified, instead falling back to FontWeight.Normal if present in font XML, or the font weight closest to that.
I put a regular variable font(Noto Sans CJK JP variable font) in /res/font directory, created a <font-name.xml> file, and the content is below:
<font-family xmlns:android="http://schemas.android.com/apk/res/android">
<font android:font="@font/noto_sans_variable_jp"
android:fontVariationSettings="'wght' 100"
android:fontWeight="100"/>
<!-- ... -->
<font android:font="@font/noto_sans_variable_jp"
android:fontVariationSettings="'wght' 900"
android:fontWeight="900"/>
</font-family>
in the Activity, that XML font file is converted as Typeface:
val jp = resources.getFont(R.font.sans_jp)
and finally I set that Typeface as the fontFamily of my Text:
import androidx.compose.ui.text.font.FontFamily as ComposeFontFamily
Text(
text = "測試文本",
fontFamily = ComposeFontFamily(jp),
fontWeight = FontWeight(900)
)
I expected the text to be displayed in the font weight I specified(900), but in the Preview the font weight fell back to 100(smallest weight in that file), code below:
@Preview
@Composable
private fun TypefacePreview() {
MaterialTheme {
Text(
"測試文本",
fontFamily = ComposeFontFamily(
LocalContext.current.resources.getFont(R.font.sans_jp)
),
fontWeight = FontWeight(900)
)
}
}
and in the app running on a physical device, the font weight 400.
By the way, when a Typeface has a fallback chain comprised of different fonts in the same font weight, there is no problem.
So [EDIT: even though I know such attempt is currently totally meaningless because that variable OTC file is ~30MB and loading it will cause OOM,] I wonder if there's something to do with how Compose treats Android Native Typeface internally.
EDIT: Some time ago I ended up implementing custom Font class and AndroidFont.TypefaceLoader object. Now the problem is that the Variable Font Collection is 30+MB for sans-serif and 50+MB for serif, causing my app to randomly crash in OOM.