Move fonts outside jar file
authorLanius Trolling <lanius@laniustrolling.dev>
Thu, 8 Feb 2024 15:45:05 +0000 (10:45 -0500)
committerLanius Trolling <lanius@laniustrolling.dev>
Thu, 8 Feb 2024 15:45:05 +0000 (10:45 -0500)
src/jvmMain/kotlin/info/mechyrdia/lore/fonts.kt
src/jvmMain/resources/fonts/mechyrdia-sans-bold-italic.ttf [deleted file]
src/jvmMain/resources/fonts/mechyrdia-sans-bold.ttf [deleted file]
src/jvmMain/resources/fonts/mechyrdia-sans-italic.ttf [deleted file]
src/jvmMain/resources/fonts/mechyrdia-sans.ttf [deleted file]

index d858f52d23ff780d53999424649ab36417c14ac5..74207fc701279089ad9c176a6f8e3be3ffd74242 100644 (file)
@@ -1,6 +1,8 @@
 package info.mechyrdia.lore
 
+import info.mechyrdia.Configuration
 import info.mechyrdia.yieldThread
+import io.ktor.util.*
 import java.awt.Font
 import java.awt.RenderingHints
 import java.awt.Shape
@@ -8,6 +10,10 @@ import java.awt.geom.AffineTransform
 import java.awt.geom.GeneralPath
 import java.awt.geom.PathIterator
 import java.awt.image.BufferedImage
+import java.io.File
+import kotlin.properties.ReadOnlyProperty
+import kotlin.reflect.KProperty
+import kotlin.text.toCharArray
 
 object MechyrdiaSansFont {
        enum class Alignment(val amount: Double) {
@@ -20,20 +26,45 @@ object MechyrdiaSansFont {
        
        private const val DEFAULT_FONT_SIZE = 48f
        
-       private fun loadFont(font: String): Font {
-               return Font
-                       .createFont(Font.TRUETYPE_FONT, javaClass.getResourceAsStream("/fonts/$font.ttf")!!)
-                       .deriveFont(DEFAULT_FONT_SIZE)
+       private val fontsRoot = File(Configuration.CurrentConfiguration.rootDir, "fonts")
+       
+       private fun loadedFont(fontName: String): ReadOnlyProperty<Any?, Font> {
+               return object : ReadOnlyProperty<Any?, Font> {
+                       private var loadedFont: Font? = null
+                       private var lastLoaded = Long.MIN_VALUE
+                       
+                       private val fontFile = fontsRoot.combineSafe("$fontName.ttf")
+                       
+                       private fun loadFont(): Font = fontFile.inputStream().use { inStream ->
+                               Font
+                                       .createFont(Font.TRUETYPE_FONT, inStream)
+                                       .deriveFont(DEFAULT_FONT_SIZE)
+                       }
+                       
+                       @Synchronized
+                       override fun getValue(thisRef: Any?, property: KProperty<*>): Font {
+                               val font = loadedFont
+                               val lastMod = fontFile.lastModified()
+                               
+                               if (font == null || lastLoaded < lastMod)
+                                       return loadFont().also {
+                                               loadedFont = it
+                                               lastLoaded = lastMod
+                                       }
+                               
+                               return font
+                       }
+               }
        }
        
-       private val mechyrdiaSans = loadFont("mechyrdia-sans")
-       private val mechyrdiaSansB = loadFont("mechyrdia-sans-bold")
-       private val mechyrdiaSansI = loadFont("mechyrdia-sans-italic")
-       private val mechyrdiaSansBI = loadFont("mechyrdia-sans-bold-italic")
+       private val mechyrdiaSans by loadedFont("mechyrdia-sans")
+       private val mechyrdiaSansB by loadedFont("mechyrdia-sans-bold")
+       private val mechyrdiaSansI by loadedFont("mechyrdia-sans-italic")
+       private val mechyrdiaSansBI by loadedFont("mechyrdia-sans-bold-italic")
        
-       private val mechyrdiaSansFonts = listOf(mechyrdiaSans, mechyrdiaSansI, mechyrdiaSansB, mechyrdiaSansBI)
+       private val mechyrdiaSansFonts = listOf(::mechyrdiaSans, ::mechyrdiaSansI, ::mechyrdiaSansB, ::mechyrdiaSansBI)
        private fun getFont(bold: Boolean, italic: Boolean): Font {
-               return mechyrdiaSansFonts[(if (bold) 2 else 0) + (if (italic) 1 else 0)]
+               return mechyrdiaSansFonts[(if (bold) 2 else 0) + (if (italic) 1 else 0)].get()
        }
        
        private fun layoutText(text: String, font: Font, alignAmount: Double): Shape {
@@ -56,7 +87,7 @@ object MechyrdiaSansFont {
                                if (line.isNotBlank()) {
                                        val x = (width - fontMetrics.stringWidth(line)) * alignAmount
                                        
-                                       // Mechyrdia Sans only supports the Latin alphabet, so we can ignore bidirectional text
+                                       // Mechyrdia Sans only supports the Latin and Cyrillic alphabets, so we can ignore bidirectional text
                                        val glyphs = font.layoutGlyphVector(g2d.fontRenderContext, line.toCharArray(), 0, line.length, Font.LAYOUT_LEFT_TO_RIGHT)
                                        val textShape = glyphs.outline as GeneralPath
                                        
diff --git a/src/jvmMain/resources/fonts/mechyrdia-sans-bold-italic.ttf b/src/jvmMain/resources/fonts/mechyrdia-sans-bold-italic.ttf
deleted file mode 100644 (file)
index ab8cd68..0000000
Binary files a/src/jvmMain/resources/fonts/mechyrdia-sans-bold-italic.ttf and /dev/null differ
diff --git a/src/jvmMain/resources/fonts/mechyrdia-sans-bold.ttf b/src/jvmMain/resources/fonts/mechyrdia-sans-bold.ttf
deleted file mode 100644 (file)
index fb678ed..0000000
Binary files a/src/jvmMain/resources/fonts/mechyrdia-sans-bold.ttf and /dev/null differ
diff --git a/src/jvmMain/resources/fonts/mechyrdia-sans-italic.ttf b/src/jvmMain/resources/fonts/mechyrdia-sans-italic.ttf
deleted file mode 100644 (file)
index 372b806..0000000
Binary files a/src/jvmMain/resources/fonts/mechyrdia-sans-italic.ttf and /dev/null differ
diff --git a/src/jvmMain/resources/fonts/mechyrdia-sans.ttf b/src/jvmMain/resources/fonts/mechyrdia-sans.ttf
deleted file mode 100644 (file)
index f9de875..0000000
Binary files a/src/jvmMain/resources/fonts/mechyrdia-sans.ttf and /dev/null differ