Cannot use desktop system fonts in Theme or as a Compose Font
It is currently not possible to use any user-selected font in a Jetpack Compose Desktop app, as there is no way to load a system font at runtime.
I'm trying to implement a font-picker but while I can choose a font, I cannot use it to display text.
Given:
val graphicsEnvironment = GraphicsEnvironment.getLocalGraphicsEnvironment()
val allFonts: List<Font> = graphicsEnvironment.allFonts.toList()
It is possible to choose any font available to the system. For instance:
val segoeScript: Font? = allFonts.toList().find { it.name == "Segoe Script" }?.deriveFont(24f)
println(segoeScript)
But you cannot use this java.awt.Font as a Jetpack FontFamily - e.g. val segoeFontFamily = FontFamily(androidx.compose.ui.text.platform.Font(file = __??????__ ,weight = FontWeight.Normal,style = FontStyle.Normal)) is not possible, because I have only a java.awt.Font and not a file handle to the font.
It is not possible, without reflection, to get a File handle for a system font - see https://stackoverflow.com/questions/2019249/get-font-file-as-a-file-object-or-get-its-path for more.
The closest I've come to getting the actual file name is via some protected methods:
val ttf = FontAccess.getFontAccess().getFont2D(segoeScript) as TrueTypeFont
println(ttf.getPublicFileName()) ///////// getPublicFileName() is a protected function
Though how's this for a creatively dangerous solution?
val ttf = FontAccess.getFontAccess().getFont2D(segoeScript) as TrueTypeFont
val ttfString = ttf.toString() // the toString() method uses getPublicFileName() internally...
println(ttfString) // ** TrueType Font: Family=Segoe Script Name=Segoe Script style=0 fileName=C:\Windows\Fonts\segoesc.ttf
val fileName = ttfString.substringAfter("fileName=")
println(fileName) // C:\Windows\Fonts\segoesc.ttf
val segoeFont = androidx.compose.ui.text.platform.Font(File(fileName))
println(segoeFont) // FileFont(file=C:\Windows\Fonts\segoesc.ttf, weight=FontWeight(weight=400), style=Normal)
Probably safer approach would be not rely on AWT fonts in Compose apps at all. Why it is needd?
Because I am hoping to build an app (similar to https://github.com/pavius/the-dot-factory ) for a Rasperry Pi project I have. I need access to the system fonts. Surely that's not an unreasonable request for a desktop development framework? Right now, I don't think Jetpack Compose Desktop could support the simplest of text-editing apps if it doesn't have access to system fonts.
Just an idea, why not find the font files in the filesystem? If you're only targeting Raspberry pi, you can look in /usr/share/fonts and ~/.fonts.