potential memory leak fixed (unbound cache size)

This commit is contained in:
Minjae Song
2018-11-03 16:35:26 +09:00
parent 048b683cb2
commit b623727b1a
3 changed files with 310 additions and 178 deletions

166
.idea/workspace.xml generated
View File

@@ -29,8 +29,8 @@
<file leaf-file-name="GameFontBase.kt" pinned="false" current-in-tab="true"> <file leaf-file-name="GameFontBase.kt" pinned="false" current-in-tab="true">
<entry file="file://$PROJECT_DIR$/src/net/torvald/terrarumsansbitmap/gdx/GameFontBase.kt"> <entry file="file://$PROJECT_DIR$/src/net/torvald/terrarumsansbitmap/gdx/GameFontBase.kt">
<provider selected="true" editor-type-id="text-editor"> <provider selected="true" editor-type-id="text-editor">
<state relative-caret-position="293"> <state relative-caret-position="372">
<caret line="567" selection-start-line="567" selection-end-line="567" /> <caret line="372" lean-forward="true" selection-start-line="372" selection-end-line="372" />
<folding> <folding>
<element signature="e#1207#1689#0" expanded="true" /> <element signature="e#1207#1689#0" expanded="true" />
</folding> </folding>
@@ -72,7 +72,7 @@
<file leaf-file-name="FontTestGDX.kt" pinned="false" current-in-tab="false"> <file leaf-file-name="FontTestGDX.kt" pinned="false" current-in-tab="false">
<entry file="file://$PROJECT_DIR$/FontTestGDX/src/FontTestGDX.kt"> <entry file="file://$PROJECT_DIR$/FontTestGDX/src/FontTestGDX.kt">
<provider selected="true" editor-type-id="text-editor"> <provider selected="true" editor-type-id="text-editor">
<state relative-caret-position="-195"> <state relative-caret-position="338">
<caret line="33" column="38" selection-start-line="33" selection-start-column="38" selection-end-line="33" selection-end-column="38" /> <caret line="33" column="38" selection-start-line="33" selection-start-column="38" selection-end-line="33" selection-end-column="38" />
<folding> <folding>
<element signature="e#0#384#0" expanded="true" /> <element signature="e#0#384#0" expanded="true" />
@@ -84,8 +84,8 @@
<file leaf-file-name="GameFontBase.kt" pinned="false" current-in-tab="true"> <file leaf-file-name="GameFontBase.kt" pinned="false" current-in-tab="true">
<entry file="file://$PROJECT_DIR$/src/net/torvald/terrarumsansbitmap/gdx/GameFontBase.kt"> <entry file="file://$PROJECT_DIR$/src/net/torvald/terrarumsansbitmap/gdx/GameFontBase.kt">
<provider selected="true" editor-type-id="text-editor"> <provider selected="true" editor-type-id="text-editor">
<state relative-caret-position="537"> <state relative-caret-position="421">
<caret line="727" column="36" lean-forward="true" selection-start-line="727" selection-start-column="36" selection-end-line="727" selection-end-column="36" /> <caret line="90" column="332" selection-start-line="90" selection-start-column="332" selection-end-line="90" selection-end-column="332" />
<folding> <folding>
<element signature="e#1207#1689#0" expanded="true" /> <element signature="e#1207#1689#0" expanded="true" />
</folding> </folding>
@@ -120,11 +120,6 @@
</provider> </provider>
</entry> </entry>
</file> </file>
<file leaf-file-name="demo.PNG" pinned="false" current-in-tab="false">
<entry file="file://$PROJECT_DIR$/demo.PNG">
<provider selected="true" editor-type-id="images" />
</entry>
</file>
<file leaf-file-name="CONTRIBUTING.md" pinned="false" current-in-tab="false"> <file leaf-file-name="CONTRIBUTING.md" pinned="false" current-in-tab="false">
<entry file="file://$PROJECT_DIR$/CONTRIBUTING.md"> <entry file="file://$PROJECT_DIR$/CONTRIBUTING.md">
<provider selected="true" editor-type-id="split-provider[text-editor;MarkdownPreviewEditor]"> <provider selected="true" editor-type-id="split-provider[text-editor;MarkdownPreviewEditor]">
@@ -170,29 +165,22 @@
<option name="RECENT_TEMPLATES"> <option name="RECENT_TEMPLATES">
<list> <list>
<option value="Kotlin Class" /> <option value="Kotlin Class" />
<option value="Interface" />
<option value="Class" />
</list> </list>
</option> </option>
</component> </component>
<component name="FindInProjectRecents"> <component name="FindInProjectRecents">
<findStrings> <findStrings>
<find>pro</find>
<find>system</find>
<find>posXbuffer</find>
<find>U+</find>
<find>variable</find>
<find>TextureRe</find>
<find>xyswap</find>
<find>isXYSwapped</find> <find>isXYSwapped</find>
<find>xySw</find> <find>xySw</find>
<find>getWidth</find> <find>getWidth</find>
<find>getWidthOfCharSeq</find> <find>getWidthOfCharSeq</find>
<find>makeShadow</find> <find>makeShadow</find>
<find>fun draw</find>
<find>glyphWidthBuffer</find> <find>glyphWidthBuffer</find>
<find>oldCharSequence</find> <find>oldCharSequence</find>
<find>charSeq.toCodeP</find> <find>charSeq.toCodeP</find>
<find>resetH</find> <find>resetH</find>
<find>println</find>
<find>HashMap</find> <find>HashMap</find>
<find>drawPixmap</find> <find>drawPixmap</find>
<find>RGBA</find> <find>RGBA</find>
@@ -205,12 +193,22 @@
<find>buildWidthAndPos</find> <find>buildWidthAndPos</find>
<find>flagMake</find> <find>flagMake</find>
<find>pixmapHolder?.dis</find> <find>pixmapHolder?.dis</find>
<find>glyphProps[</find>
<find>textCache</find>
<find>glyphProps</find>
<find>(c: Int)</find>
<find>hashC</find>
<find>TreeNode</find>
<find>sear</find>
<find>fun draw</find>
<find>println</find>
</findStrings> </findStrings>
<replaceStrings> <replaceStrings>
<replace>.141</replace> <replace>.141</replace>
<replace>c</replace> <replace>c</replace>
<replace>har</replace> <replace>har</replace>
<replace>TEXH</replace> <replace>TEXH</replace>
<replace>(c: CodePoint)</replace>
</replaceStrings> </replaceStrings>
</component> </component>
<component name="Git.Settings"> <component name="Git.Settings">
@@ -236,6 +234,9 @@
<option value="$PROJECT_DIR$/CONTRIBUTING.md" /> <option value="$PROJECT_DIR$/CONTRIBUTING.md" />
<option value="$PROJECT_DIR$/src/net/torvald/terrarumsansbitmap/gdx/PixmapRegionPack.kt" /> <option value="$PROJECT_DIR$/src/net/torvald/terrarumsansbitmap/gdx/PixmapRegionPack.kt" />
<option value="$PROJECT_DIR$/demotext.txt" /> <option value="$PROJECT_DIR$/demotext.txt" />
<option value="$PROJECT_DIR$/src/net/torvald/terrarumsansbitmap/AgedItem.java" />
<option value="$PROJECT_DIR$/src/net/torvald/terrarumsansbitmap/RedBlackNode.java" />
<option value="$PROJECT_DIR$/src/net/torvald/terrarumsansbitmap/RedBlackTree.java" />
<option value="$PROJECT_DIR$/src/net/torvald/terrarumsansbitmap/gdx/GameFontBase.kt" /> <option value="$PROJECT_DIR$/src/net/torvald/terrarumsansbitmap/gdx/GameFontBase.kt" />
</list> </list>
</option> </option>
@@ -251,8 +252,6 @@
<foldersAlwaysOnTop value="true" /> <foldersAlwaysOnTop value="true" />
</navigator> </navigator>
<panes> <panes>
<pane id="PackagesPane" />
<pane id="Scope" />
<pane id="ProjectPane"> <pane id="ProjectPane">
<subPane> <subPane>
<expand> <expand>
@@ -293,15 +292,17 @@
<select /> <select />
</subPane> </subPane>
</pane> </pane>
<pane id="PackagesPane" />
<pane id="Scope" />
</panes> </panes>
</component> </component>
<component name="PropertiesComponent"> <component name="PropertiesComponent">
<property name="SearchEverywhereHistoryKey" value="soft wr&#9;ACTION&#9;EditorToggleUseSoftWraps" /> <property name="SearchEverywhereHistoryKey" value="HashMap&#9;PSI&#9;JAVA://java.util.HashMap&#10;soft wr&#9;ACTION&#9;EditorToggleUseSoftWraps" />
<property name="last_opened_file_path" value="$PROJECT_DIR$/lib/gdx.jar!/" /> <property name="last_opened_file_path" value="$PROJECT_DIR$/lib/gdx.jar!/" />
<property name="project.structure.last.edited" value="Artifacts" /> <property name="project.structure.last.edited" value="Artifacts" />
<property name="project.structure.proportion" value="0.15" /> <property name="project.structure.proportion" value="0.15" />
<property name="project.structure.side.proportion" value="0.32068965" /> <property name="project.structure.side.proportion" value="0.32068965" />
<property name="settings.editor.selected.configurable" value="configurable.group.editor" /> <property name="settings.editor.selected.configurable" value="preferences.language.Kotlin" />
</component> </component>
<component name="RecentsManager"> <component name="RecentsManager">
<key name="MoveFile.RECENT_KEYS"> <key name="MoveFile.RECENT_KEYS">
@@ -361,6 +362,16 @@
<option name="Make" enabled="true" /> <option name="Make" enabled="true" />
</method> </method>
</configuration> </configuration>
<configuration default="true" type="JetRunConfigurationType" factoryName="Kotlin">
<module name="BuildJAR_TerrarumSansBitmap" />
<option name="VM_PARAMETERS" />
<option name="PROGRAM_PARAMETERS" />
<option name="ALTERNATIVE_JRE_PATH_ENABLED" value="false" />
<option name="ALTERNATIVE_JRE_PATH" />
<option name="PASS_PARENT_ENVS" value="true" />
<option name="MAIN_CLASS_NAME" />
<option name="WORKING_DIRECTORY" />
</configuration>
<configuration default="true" type="KotlinStandaloneScriptRunConfigurationType" factoryName="Kotlin script"> <configuration default="true" type="KotlinStandaloneScriptRunConfigurationType" factoryName="Kotlin script">
<option name="filePath" /> <option name="filePath" />
<option name="vmParameters" /> <option name="vmParameters" />
@@ -451,16 +462,6 @@
<envs /> <envs />
<method /> <method />
</configuration> </configuration>
<configuration default="true" type="JetRunConfigurationType" factoryName="Kotlin">
<module name="BuildJAR_TerrarumSansBitmap" />
<option name="VM_PARAMETERS" />
<option name="PROGRAM_PARAMETERS" />
<option name="ALTERNATIVE_JRE_PATH_ENABLED" value="false" />
<option name="ALTERNATIVE_JRE_PATH" />
<option name="PASS_PARENT_ENVS" value="true" />
<option name="MAIN_CLASS_NAME" />
<option name="WORKING_DIRECTORY" />
</configuration>
<configuration default="true" type="Remote" factoryName="Remote"> <configuration default="true" type="Remote" factoryName="Remote">
<option name="USE_SOCKET_TRANSPORT" value="true" /> <option name="USE_SOCKET_TRANSPORT" value="true" />
<option name="SERVER_MODE" value="false" /> <option name="SERVER_MODE" value="false" />
@@ -521,26 +522,26 @@
<layout> <layout>
<window_info anchor="right" id="Palette" order="3" /> <window_info anchor="right" id="Palette" order="3" />
<window_info anchor="bottom" id="TODO" order="6" /> <window_info anchor="bottom" id="TODO" order="6" />
<window_info anchor="bottom" id="Messages" order="9" weight="0.20779221" /> <window_info anchor="bottom" id="Messages" order="9" visible="true" weight="0.20779221" />
<window_info anchor="right" id="Palette&#9;" order="5" /> <window_info anchor="right" id="Palette&#9;" order="5" />
<window_info anchor="bottom" id="Event Log" order="10" side_tool="true" /> <window_info anchor="bottom" id="Event Log" order="10" side_tool="true" />
<window_info anchor="right" id="Maven Projects" order="4" /> <window_info anchor="right" id="Maven Projects" order="4" />
<window_info anchor="bottom" id="Version Control" order="8" />
<window_info anchor="bottom" id="Run" order="2" weight="0.2591522" /> <window_info anchor="bottom" id="Run" order="2" weight="0.2591522" />
<window_info anchor="bottom" id="Version Control" order="8" />
<window_info anchor="bottom" id="Terminal" order="7" /> <window_info anchor="bottom" id="Terminal" order="7" />
<window_info id="Designer" order="2" /> <window_info id="Designer" order="2" />
<window_info content_ui="combo" id="Project" order="0" visible="true" weight="0.08742005" /> <window_info active="true" content_ui="combo" id="Project" order="0" visible="true" weight="0.09008529" />
<window_info anchor="bottom" id="Find" order="1" weight="0.32931355" />
<window_info id="Structure" order="1" side_tool="true" weight="0.25" /> <window_info id="Structure" order="1" side_tool="true" weight="0.25" />
<window_info anchor="right" id="Ant Build" order="1" weight="0.25" /> <window_info anchor="right" id="Ant Build" order="1" weight="0.25" />
<window_info id="UI Designer" order="4" /> <window_info id="UI Designer" order="4" />
<window_info anchor="bottom" id="Debug" order="3" weight="0.24768089" />
<window_info id="Favorites" order="3" side_tool="true" /> <window_info id="Favorites" order="3" side_tool="true" />
<window_info active="true" anchor="bottom" id="Debug" order="3" visible="true" weight="0.24768089" />
<window_info anchor="right" content_ui="combo" id="Hierarchy" order="2" weight="0.25" /> <window_info anchor="right" content_ui="combo" id="Hierarchy" order="2" weight="0.25" />
<window_info anchor="bottom" id="Inspection" order="5" weight="0.4" /> <window_info anchor="bottom" id="Inspection" order="5" weight="0.4" />
<window_info anchor="right" id="Commander" order="0" weight="0.4" /> <window_info anchor="right" id="Commander" order="0" weight="0.4" />
<window_info anchor="bottom" id="Message" order="0" /> <window_info anchor="bottom" id="Message" order="0" />
<window_info anchor="bottom" id="Cvs" order="4" weight="0.25" /> <window_info anchor="bottom" id="Cvs" order="4" weight="0.25" />
<window_info anchor="bottom" id="Find" order="1" weight="0.32931355" />
</layout> </layout>
</component> </component>
<component name="VcsContentAnnotationSettings"> <component name="VcsContentAnnotationSettings">
@@ -556,35 +557,6 @@
<option name="FILTER_TARGETS" value="false" /> <option name="FILTER_TARGETS" value="false" />
</component> </component>
<component name="editorHistoryManager"> <component name="editorHistoryManager">
<entry file="file://$PROJECT_DIR$/src/net/torvald/terrarumsansbitmap/gdx/GameFontBase.kt">
<provider selected="true" editor-type-id="text-editor">
<state relative-caret-position="18122">
<caret line="1394" column="67" selection-start-line="1394" selection-start-column="67" selection-end-line="1394" selection-end-column="67" />
<folding>
<element signature="e#1207#1689#0" expanded="true" />
</folding>
</state>
</provider>
</entry>
<entry file="file://$PROJECT_DIR$/README.md">
<provider selected="true" editor-type-id="split-provider[text-editor;MarkdownPreviewEditor]">
<state split_layout="SECOND">
<first_editor relative-caret-position="143">
<caret line="11" column="153" selection-start-line="11" selection-start-column="153" selection-end-line="11" selection-end-column="153" />
</first_editor>
<second_editor>
<js_state />
</second_editor>
</state>
</provider>
</entry>
<entry file="file://$PROJECT_DIR$/src/net/torvald/terrarumsansbitmap/slick2d/GameFontBase.kt">
<provider selected="true" editor-type-id="text-editor">
<state relative-caret-position="8905">
<caret line="749" column="35" selection-start-line="749" selection-start-column="35" selection-end-line="749" selection-end-column="35" />
</state>
</provider>
</entry>
<entry file="file://$PROJECT_DIR$/src/net/torvald/terrarumsansbitmap/gdx/GameFontBase.kt"> <entry file="file://$PROJECT_DIR$/src/net/torvald/terrarumsansbitmap/gdx/GameFontBase.kt">
<provider selected="true" editor-type-id="text-editor"> <provider selected="true" editor-type-id="text-editor">
<state relative-caret-position="9594"> <state relative-caret-position="9594">
@@ -757,13 +729,7 @@
</state> </state>
</provider> </provider>
</entry> </entry>
<entry file="jar://$KOTLIN_BUNDLED$/lib/kotlin-runtime-sources.jar!/kotlin/CharSequence.kt"> <entry file="jar://$KOTLIN_BUNDLED$/lib/kotlin-runtime-sources.jar!/kotlin/CharSequence.kt" />
<provider selected="true" editor-type-id="text-editor">
<state relative-caret-position="91">
<caret line="21" column="17" selection-start-line="21" selection-start-column="17" selection-end-line="21" selection-end-column="17" />
</state>
</provider>
</entry>
<entry file="jar://$PROJECT_DIR$/lib/gdx.jar!/com/badlogic/gdx/graphics/glutils/GLFrameBuffer.class"> <entry file="jar://$PROJECT_DIR$/lib/gdx.jar!/com/badlogic/gdx/graphics/glutils/GLFrameBuffer.class">
<provider selected="true" editor-type-id="text-editor"> <provider selected="true" editor-type-id="text-editor">
<state relative-caret-position="2379"> <state relative-caret-position="2379">
@@ -894,7 +860,7 @@
</entry> </entry>
<entry file="file://$PROJECT_DIR$/FontTestGDX/src/FontTestGDX.kt"> <entry file="file://$PROJECT_DIR$/FontTestGDX/src/FontTestGDX.kt">
<provider selected="true" editor-type-id="text-editor"> <provider selected="true" editor-type-id="text-editor">
<state relative-caret-position="-195"> <state relative-caret-position="338">
<caret line="33" column="38" selection-start-line="33" selection-start-column="38" selection-end-line="33" selection-end-column="38" /> <caret line="33" column="38" selection-start-line="33" selection-start-column="38" selection-end-line="33" selection-end-column="38" />
<folding> <folding>
<element signature="e#0#384#0" expanded="true" /> <element signature="e#0#384#0" expanded="true" />
@@ -916,13 +882,49 @@
</state> </state>
</provider> </provider>
</entry> </entry>
<entry file="file://$PROJECT_DIR$/demo.PNG"> <entry file="jar://C:/Program Files/Java/jdk1.8.0_131/src.zip!/java/util/HashMap.java">
<provider selected="true" editor-type-id="images" /> <provider selected="true" editor-type-id="text-editor">
<state relative-caret-position="-5975">
<caret line="1798" column="23" selection-start-line="1798" selection-start-column="23" selection-end-line="1798" selection-end-column="23" />
</state>
</provider>
</entry>
<entry file="file://$PROJECT_DIR$/src/net/torvald/terrarumsansbitmap/AgedItem.java">
<provider selected="true" editor-type-id="text-editor">
<state relative-caret-position="325">
<caret line="25" column="1" selection-start-line="25" selection-start-column="1" selection-end-line="25" selection-end-column="1" />
<folding>
<element signature="e#309#310#0" expanded="true" />
<element signature="e#335#336#0" expanded="true" />
<element signature="e#462#463#0" expanded="true" />
<element signature="e#486#487#0" expanded="true" />
</folding>
</state>
</provider>
</entry>
<entry file="file://$PROJECT_DIR$/src/net/torvald/terrarumsansbitmap/RedBlackNode.java">
<provider selected="true" editor-type-id="text-editor">
<state relative-caret-position="351">
<caret line="27" column="14" selection-start-line="27" selection-start-column="14" selection-end-line="27" selection-end-column="14" />
</state>
</provider>
</entry>
<entry file="file://$PROJECT_DIR$/src/net/torvald/terrarumsansbitmap/RedBlackTree.java">
<provider selected="true" editor-type-id="text-editor">
<state relative-caret-position="-9212">
<caret line="69" column="67" selection-start-line="69" selection-start-column="67" selection-end-line="69" selection-end-column="67" />
<folding>
<element signature="imports" expanded="true" />
<element signature="e#22666#22667#0" expanded="true" />
<element signature="e#22707#22708#0" expanded="true" />
</folding>
</state>
</provider>
</entry> </entry>
<entry file="file://$PROJECT_DIR$/src/net/torvald/terrarumsansbitmap/gdx/GameFontBase.kt"> <entry file="file://$PROJECT_DIR$/src/net/torvald/terrarumsansbitmap/gdx/GameFontBase.kt">
<provider selected="true" editor-type-id="text-editor"> <provider selected="true" editor-type-id="text-editor">
<state relative-caret-position="537"> <state relative-caret-position="372">
<caret line="727" column="36" lean-forward="true" selection-start-line="727" selection-start-column="36" selection-end-line="727" selection-end-column="36" /> <caret line="372" lean-forward="true" selection-start-line="372" selection-end-line="372" />
<folding> <folding>
<element signature="e#1207#1689#0" expanded="true" /> <element signature="e#1207#1689#0" expanded="true" />
</folding> </folding>
@@ -963,7 +965,7 @@
<splitter-proportions> <splitter-proportions>
<option name="proportions"> <option name="proportions">
<list> <list>
<option value="0.2" /> <option value="0.32068965" />
</list> </list>
</option> </option>
</splitter-proportions> </splitter-proportions>
@@ -975,7 +977,7 @@
<splitter-proportions> <splitter-proportions>
<option name="proportions"> <option name="proportions">
<list> <list>
<option value="0.2" /> <option value="0.32068965" />
</list> </list>
</option> </option>
</splitter-proportions> </splitter-proportions>
@@ -996,7 +998,7 @@
</state> </state>
<state key="ProjectLibrariesConfigurable.UI"> <state key="ProjectLibrariesConfigurable.UI">
<settings> <settings>
<last-edited>TesterLib</last-edited> <last-edited>GdxLib</last-edited>
<splitter-proportions> <splitter-proportions>
<option name="proportions"> <option name="proportions">
<list> <list>

View File

@@ -33,12 +33,16 @@ import com.badlogic.gdx.utils.GdxRuntimeException
import net.torvald.terrarumsansbitmap.GlyphProps import net.torvald.terrarumsansbitmap.GlyphProps
import java.io.BufferedOutputStream import java.io.BufferedOutputStream
import java.io.FileOutputStream import java.io.FileOutputStream
import java.lang.NullPointerException
import java.security.MessageDigest import java.security.MessageDigest
import java.util.zip.CRC32 import java.util.zip.CRC32
import java.util.zip.GZIPInputStream import java.util.zip.GZIPInputStream
import kotlin.math.roundToInt import kotlin.math.roundToInt
typealias CodepointSequence = ArrayList<Int> typealias CodepointSequence = ArrayList<CodePoint>
internal typealias CodePoint = Int
internal typealias ARGB8888 = Int
internal typealias Hash = Long
/** /**
* LibGDX port of Terrarum Sans Bitmap implementation * LibGDX port of Terrarum Sans Bitmap implementation
@@ -84,7 +88,7 @@ typealias CodepointSequence = ArrayList<Int>
* *
* Created by minjaesong on 2017-06-15. * Created by minjaesong on 2017-06-15.
*/ */
class GameFontBase(fontDir: String, val noShadow: Boolean = false, val flipY: Boolean = false, val minFilter: Texture.TextureFilter = Texture.TextureFilter.Nearest, val magFilter: Texture.TextureFilter = Texture.TextureFilter.Nearest, var errorOnUnknownChar: Boolean = false) : BitmapFont() { class GameFontBase(fontDir: String, val noShadow: Boolean = false, val flipY: Boolean = false, val minFilter: Texture.TextureFilter = Texture.TextureFilter.Nearest, val magFilter: Texture.TextureFilter = Texture.TextureFilter.Nearest, var errorOnUnknownChar: Boolean = false, val textCacheSize: Int = 128, val debug: Boolean = false) : BitmapFont() {
// Hangul Implementation Specific // // Hangul Implementation Specific //
@@ -122,19 +126,19 @@ class GameFontBase(fontDir: String, val noShadow: Boolean = false, val flipY: Bo
9 9
} }
private fun isHangulChosung(c: Int) = c in (0x1100..0x115F) || c in (0xA960..0xA97F) private fun isHangulChosung(c: CodePoint) = c in (0x1100..0x115F) || c in (0xA960..0xA97F)
private fun isHangulJungseong(c: Int) = c in (0x1160..0x11A7) || c in (0xD7B0..0xD7C6) private fun isHangulJungseong(c: CodePoint) = c in (0x1160..0x11A7) || c in (0xD7B0..0xD7C6)
private fun isHangulJongseong(c: Int) = c in (0x11A8..0x11FF) || c in (0xD7CB..0xD7FB) private fun isHangulJongseong(c: CodePoint) = c in (0x11A8..0x11FF) || c in (0xD7CB..0xD7FB)
private fun toHangulChosungIndex(c: Int) = private fun toHangulChosungIndex(c: CodePoint) =
if (!isHangulChosung(c)) throw IllegalArgumentException("This Hangul sequence does not begin with Chosung (${c.toHex()})") if (!isHangulChosung(c)) throw IllegalArgumentException("This Hangul sequence does not begin with Chosung (${c.toHex()})")
else if (c in 0x1100..0x115F) c - 0x1100 else if (c in 0x1100..0x115F) c - 0x1100
else c - 0xA960 + 96 else c - 0xA960 + 96
private fun toHangulJungseongIndex(c: Int) = private fun toHangulJungseongIndex(c: CodePoint) =
if (!isHangulJungseong(c)) 0 if (!isHangulJungseong(c)) 0
else if (c in 0x1160..0x11A7) c - 0x1160 else if (c in 0x1160..0x11A7) c - 0x1160
else c - 0xD7B0 + 72 else c - 0xD7B0 + 72
private fun toHangulJongseongIndex(c: Int) = private fun toHangulJongseongIndex(c: CodePoint) =
if (!isHangulJongseong(c)) 0 if (!isHangulJongseong(c)) 0
else if (c in 0x11A8..0x11FF) c - 0x11A8 + 1 else if (c in 0x11A8..0x11FF) c - 0x11A8 + 1
else c - 0xD7CB + 88 + 1 else c - 0xD7CB + 88 + 1
@@ -146,7 +150,7 @@ class GameFontBase(fontDir: String, val noShadow: Boolean = false, val flipY: Bo
* @param pCP Code point for Peak (Jungseong) * @param pCP Code point for Peak (Jungseong)
* @param fCP Code point for Final (Jongseong * @param fCP Code point for Final (Jongseong
*/ */
private fun toHangulIndex(iCP: Int, pCP: Int, fCP: Int): IntArray { private fun toHangulIndex(iCP: CodePoint, pCP: CodePoint, fCP: CodePoint): IntArray {
val indexI = toHangulChosungIndex(iCP) val indexI = toHangulChosungIndex(iCP)
val indexP = toHangulJungseongIndex(pCP) val indexP = toHangulJungseongIndex(pCP)
val indexF = toHangulJongseongIndex(fCP) val indexF = toHangulJongseongIndex(fCP)
@@ -154,7 +158,7 @@ class GameFontBase(fontDir: String, val noShadow: Boolean = false, val flipY: Bo
return intArrayOf(indexI, indexP, indexF) return intArrayOf(indexI, indexP, indexF)
} }
private fun toHangulIndexAndRow(iCP: Int, pCP: Int, fCP: Int): Pair<IntArray, IntArray> { private fun toHangulIndexAndRow(iCP: CodePoint, pCP: CodePoint, fCP: CodePoint): Pair<IntArray, IntArray> {
val (indexI, indexP, indexF) = toHangulIndex(iCP, pCP, fCP) val (indexI, indexP, indexF) = toHangulIndex(iCP, pCP, fCP)
val rowI = getHanInitialRow(indexI, indexP, indexF) val rowI = getHanInitialRow(indexI, indexP, indexF)
@@ -167,114 +171,114 @@ class GameFontBase(fontDir: String, val noShadow: Boolean = false, val flipY: Bo
// END Hangul // // END Hangul //
private fun isHangul(c: Int) = c in codeRange[SHEET_HANGUL] private fun isHangul(c: CodePoint) = c in codeRange[SHEET_HANGUL]
private fun isAscii(c: Int) = c in codeRange[SHEET_ASCII_VARW] private fun isAscii(c: CodePoint) = c in codeRange[SHEET_ASCII_VARW]
private fun isRunic(c: Int) = c in codeRange[SHEET_RUNIC] private fun isRunic(c: CodePoint) = c in codeRange[SHEET_RUNIC]
private fun isExtA(c: Int) = c in codeRange[SHEET_EXTA_VARW] private fun isExtA(c: CodePoint) = c in codeRange[SHEET_EXTA_VARW]
private fun isExtB(c: Int) = c in codeRange[SHEET_EXTB_VARW] private fun isExtB(c: CodePoint) = c in codeRange[SHEET_EXTB_VARW]
private fun isKana(c: Int) = c in codeRange[SHEET_KANA] private fun isKana(c: CodePoint) = c in codeRange[SHEET_KANA]
private fun isCJKPunct(c: Int) = c in codeRange[SHEET_CJK_PUNCT] private fun isCJKPunct(c: CodePoint) = c in codeRange[SHEET_CJK_PUNCT]
private fun isUniHan(c: Int) = c in codeRange[SHEET_UNIHAN] private fun isUniHan(c: CodePoint) = c in codeRange[SHEET_UNIHAN]
private fun isCyrilic(c: Int) = c in codeRange[SHEET_CYRILIC_VARW] private fun isCyrilic(c: CodePoint) = c in codeRange[SHEET_CYRILIC_VARW]
private fun isFullwidthUni(c: Int) = c in codeRange[SHEET_FW_UNI] private fun isFullwidthUni(c: CodePoint) = c in codeRange[SHEET_FW_UNI]
private fun isUniPunct(c: Int) = c in codeRange[SHEET_UNI_PUNCT_VARW] private fun isUniPunct(c: CodePoint) = c in codeRange[SHEET_UNI_PUNCT_VARW]
private fun isGreek(c: Int) = c in codeRange[SHEET_GREEK_VARW] private fun isGreek(c: CodePoint) = c in codeRange[SHEET_GREEK_VARW]
private fun isThai(c: Int) = c in codeRange[SHEET_THAI_VARW] private fun isThai(c: CodePoint) = c in codeRange[SHEET_THAI_VARW]
/*private fun isDiacritics(c: Int) = c in 0xE34..0xE3A /*private fun isDiacritics(c: CodePoint) = c in 0xE34..0xE3A
|| c in 0xE47..0xE4E || c in 0xE47..0xE4E
|| c == 0xE31*/ || c == 0xE31*/
private fun isCustomSym(c: Int) = c in codeRange[SHEET_CUSTOM_SYM] private fun isCustomSym(c: CodePoint) = c in codeRange[SHEET_CUSTOM_SYM]
private fun isArmenian(c: Int) = c in codeRange[SHEET_HAYEREN_VARW] private fun isArmenian(c: CodePoint) = c in codeRange[SHEET_HAYEREN_VARW]
private fun isKartvelian(c: Int) = c in codeRange[SHEET_KARTULI_VARW] private fun isKartvelian(c: CodePoint) = c in codeRange[SHEET_KARTULI_VARW]
private fun isIPA(c: Int) = c in codeRange[SHEET_IPA_VARW] private fun isIPA(c: CodePoint) = c in codeRange[SHEET_IPA_VARW]
private fun isLatinExtAdd(c: Int) = c in 0x1E00..0x1EFF private fun isLatinExtAdd(c: CodePoint) = c in 0x1E00..0x1EFF
private fun isBulgarian(c: Int) = c in 0x400..0x45F private fun isBulgarian(c: CodePoint) = c in 0x400..0x45F
private fun isColourCode(c: Int) = c == 0x100000 || c in 0x10F000..0x10FFFF private fun isColourCode(c: CodePoint) = c == 0x100000 || c in 0x10F000..0x10FFFF
private fun isCharsetOverride(c: Int) = c in 0xFFFC0..0xFFFFF private fun isCharsetOverride(c: CodePoint) = c in 0xFFFC0..0xFFFFF
private fun isCherokee(c: Int) = c in codeRange[SHEET_TSALAGI_VARW] private fun isCherokee(c: CodePoint) = c in codeRange[SHEET_TSALAGI_VARW]
private fun isInsular(c: Int) = c == 0x1D79 || c in 0xA779..0xA787 private fun isInsular(c: CodePoint) = c == 0x1D79 || c in 0xA779..0xA787
private fun isNagariBengali(c: Int) = c in codeRange[SHEET_NAGARI_BENGALI_VARW] private fun isNagariBengali(c: CodePoint) = c in codeRange[SHEET_NAGARI_BENGALI_VARW]
private fun isKartvelianCaps(c: Int) = c in codeRange[SHEET_KARTULI_CAPS_VARW] private fun isKartvelianCaps(c: CodePoint) = c in codeRange[SHEET_KARTULI_CAPS_VARW]
private fun isDiacriticalMarks(c: Int) = c in codeRange[SHEET_DIACRITICAL_MARKS_VARW] private fun isDiacriticalMarks(c: CodePoint) = c in codeRange[SHEET_DIACRITICAL_MARKS_VARW]
private fun isPolytonicGreek(c: Int) = c in codeRange[SHEET_GREEK_POLY_VARW] private fun isPolytonicGreek(c: CodePoint) = c in codeRange[SHEET_GREEK_POLY_VARW]
private fun isExtC(c: Int) = c in codeRange[SHEET_EXTC_VARW] private fun isExtC(c: CodePoint) = c in codeRange[SHEET_EXTC_VARW]
private fun isCaps(c: Int) = Character.isUpperCase(c) || isKartvelianCaps(c) private fun isCaps(c: CodePoint) = Character.isUpperCase(c) || isKartvelianCaps(c)
private fun extAindexX(c: Int) = (c - 0x100) % 16 private fun extAindexX(c: CodePoint) = (c - 0x100) % 16
private fun extAindexY(c: Int) = (c - 0x100) / 16 private fun extAindexY(c: CodePoint) = (c - 0x100) / 16
private fun extBindexX(c: Int) = (c - 0x180) % 16 private fun extBindexX(c: CodePoint) = (c - 0x180) % 16
private fun extBindexY(c: Int) = (c - 0x180) / 16 private fun extBindexY(c: CodePoint) = (c - 0x180) / 16
private fun runicIndexX(c: Int) = (c - 0x16A0) % 16 private fun runicIndexX(c: CodePoint) = (c - 0x16A0) % 16
private fun runicIndexY(c: Int) = (c - 0x16A0) / 16 private fun runicIndexY(c: CodePoint) = (c - 0x16A0) / 16
private fun kanaIndexX(c: Int) = (c - 0x3040) % 16 private fun kanaIndexX(c: CodePoint) = (c - 0x3040) % 16
private fun kanaIndexY(c: Int) = private fun kanaIndexY(c: CodePoint) =
if (c in 0x31F0..0x31FF) 12 if (c in 0x31F0..0x31FF) 12
else if (c in 0x1B000..0x1B00F) 13 else if (c in 0x1B000..0x1B00F) 13
else (c - 0x3040) / 16 else (c - 0x3040) / 16
private fun cjkPunctIndexX(c: Int) = (c - 0x3000) % 16 private fun cjkPunctIndexX(c: CodePoint) = (c - 0x3000) % 16
private fun cjkPunctIndexY(c: Int) = (c - 0x3000) / 16 private fun cjkPunctIndexY(c: CodePoint) = (c - 0x3000) / 16
private fun cyrilicIndexX(c: Int) = (c - 0x400) % 16 private fun cyrilicIndexX(c: CodePoint) = (c - 0x400) % 16
private fun cyrilicIndexY(c: Int) = (c - 0x400) / 16 private fun cyrilicIndexY(c: CodePoint) = (c - 0x400) / 16
private fun fullwidthUniIndexX(c: Int) = (c - 0xFF00) % 16 private fun fullwidthUniIndexX(c: CodePoint) = (c - 0xFF00) % 16
private fun fullwidthUniIndexY(c: Int) = (c - 0xFF00) / 16 private fun fullwidthUniIndexY(c: CodePoint) = (c - 0xFF00) / 16
private fun uniPunctIndexX(c: Int) = (c - 0x2000) % 16 private fun uniPunctIndexX(c: CodePoint) = (c - 0x2000) % 16
private fun uniPunctIndexY(c: Int) = (c - 0x2000) / 16 private fun uniPunctIndexY(c: CodePoint) = (c - 0x2000) / 16
private fun unihanIndexX(c: Int) = (c - 0x3400) % 256 private fun unihanIndexX(c: CodePoint) = (c - 0x3400) % 256
private fun unihanIndexY(c: Int) = (c - 0x3400) / 256 private fun unihanIndexY(c: CodePoint) = (c - 0x3400) / 256
private fun greekIndexX(c: Int) = (c - 0x370) % 16 private fun greekIndexX(c: CodePoint) = (c - 0x370) % 16
private fun greekIndexY(c: Int) = (c - 0x370) / 16 private fun greekIndexY(c: CodePoint) = (c - 0x370) / 16
private fun thaiIndexX(c: Int) = (c - 0xE00) % 16 private fun thaiIndexX(c: CodePoint) = (c - 0xE00) % 16
private fun thaiIndexY(c: Int) = (c - 0xE00) / 16 private fun thaiIndexY(c: CodePoint) = (c - 0xE00) / 16
private fun symbolIndexX(c: Int) = (c - 0xE000) % 16 private fun symbolIndexX(c: CodePoint) = (c - 0xE000) % 16
private fun symbolIndexY(c: Int) = (c - 0xE000) / 16 private fun symbolIndexY(c: CodePoint) = (c - 0xE000) / 16
private fun armenianIndexX(c: Int) = (c - 0x530) % 16 private fun armenianIndexX(c: CodePoint) = (c - 0x530) % 16
private fun armenianIndexY(c: Int) = (c - 0x530) / 16 private fun armenianIndexY(c: CodePoint) = (c - 0x530) / 16
private fun kartvelianIndexX(c: Int) = (c - 0x10D0) % 16 private fun kartvelianIndexX(c: CodePoint) = (c - 0x10D0) % 16
private fun kartvelianIndexY(c: Int) = (c - 0x10D0) / 16 private fun kartvelianIndexY(c: CodePoint) = (c - 0x10D0) / 16
private fun ipaIndexX(c: Int) = (c - 0x250) % 16 private fun ipaIndexX(c: CodePoint) = (c - 0x250) % 16
private fun ipaIndexY(c: Int) = (c - 0x250) / 16 private fun ipaIndexY(c: CodePoint) = (c - 0x250) / 16
private fun latinExtAddX(c: Int) = (c - 0x1E00) % 16 private fun latinExtAddX(c: CodePoint) = (c - 0x1E00) % 16
private fun latinExtAddY(c: Int) = (c - 0x1E00) / 16 private fun latinExtAddY(c: CodePoint) = (c - 0x1E00) / 16
private fun cherokeeIndexX(c: Int) = (c - 0x13A0) % 16 private fun cherokeeIndexX(c: CodePoint) = (c - 0x13A0) % 16
private fun cherokeeIndexY(c: Int) = (c - 0x13A0) / 16 private fun cherokeeIndexY(c: CodePoint) = (c - 0x13A0) / 16
private fun insularIndexX(c: Int) = private fun insularIndexX(c: CodePoint) =
if (c == 0x1D79) 0 else (c - 0xA770) % 16 if (c == 0x1D79) 0 else (c - 0xA770) % 16
private fun insularIndexY(c: Int) = private fun insularIndexY(c: CodePoint) =
if (c == 0x1D79) 0 else (c - 0xA770) / 16 if (c == 0x1D79) 0 else (c - 0xA770) / 16
private fun nagariIndexX(c: Int) = (c - 0x900) % 16 private fun nagariIndexX(c: CodePoint) = (c - 0x900) % 16
private fun nagariIndexY(c: Int) = (c - 0x900) / 16 private fun nagariIndexY(c: CodePoint) = (c - 0x900) / 16
private fun kartvelianCapsIndexX(c: Int) = (c - 0x1C90) % 16 private fun kartvelianCapsIndexX(c: CodePoint) = (c - 0x1C90) % 16
private fun kartvelianCapsIndexY(c: Int) = (c - 0x1C90) / 16 private fun kartvelianCapsIndexY(c: CodePoint) = (c - 0x1C90) / 16
private fun diacriticalMarksIndexX(c: Int) = (c - 0x300) % 16 private fun diacriticalMarksIndexX(c: CodePoint) = (c - 0x300) % 16
private fun diacriticalMarksIndexY(c: Int) = (c - 0x300) / 16 private fun diacriticalMarksIndexY(c: CodePoint) = (c - 0x300) / 16
private fun polytonicGreekIndexX(c: Int) = (c - 0x1F00) % 16 private fun polytonicGreekIndexX(c: CodePoint) = (c - 0x1F00) % 16
private fun polytonicGreekIndexY(c: Int) = (c - 0x1F00) / 16 private fun polytonicGreekIndexY(c: CodePoint) = (c - 0x1F00) / 16
private fun extCIndexX(c: Int) = (c - 0x2C60) % 16 private fun extCIndexX(c: CodePoint) = (c - 0x2C60) % 16
private fun extCIndexY(c: Int) = (c - 0x2C60) / 16 private fun extCIndexY(c: CodePoint) = (c - 0x2C60) / 16
private val lowHeightLetters = "acegijmnopqrsuvwxyzɱɳʙɾɽʒʂʐʋɹɻɥɟɡɢʛȵɲŋɴʀɕʑçʝxɣχʁʜʍɰʟɨʉɯuʊøɘɵɤəɛœɜɞʌɔæɐɶɑɒɚɝɩɪʅʈʏʞⱥⱦⱱⱳⱴⱶⱷⱸⱺⱻ".toSortedSet() private val lowHeightLetters = "acegijmnopqrsuvwxyzɱɳʙɾɽʒʂʐʋɹɻɥɟɡɢʛȵɲŋɴʀɕʑçʝxɣχʁʜʍɰʟɨʉɯuʊøɘɵɤəɛœɜɞʌɔæɐɶɑɒɚɝɩɪʅʈʏʞⱥⱦⱱⱳⱴⱶⱷⱸⱺⱻ".toSortedSet()
/** /**
@@ -285,8 +289,111 @@ class GameFontBase(fontDir: String, val noShadow: Boolean = false, val flipY: Bo
// TODO (val posXbuffer: IntArray, val posYbuffer: IntArray) -> (val linotype: Pixmap) // TODO (val posXbuffer: IntArray, val posYbuffer: IntArray) -> (val linotype: Pixmap)
private data class ShittyGlyphLayout(val textBuffer: CodepointSequence, val linotype: Pixmap) private data class ShittyGlyphLayout(val textBuffer: CodepointSequence, val linotype: Pixmap)
private val textCache = HashMap<CharSequence, ShittyGlyphLayout>()
//private val textCache = HashMap<CharSequence, ShittyGlyphLayout>()
private data class TextCacheObj(var age: Int, val hash: Long, val glyphLayout: ShittyGlyphLayout?)
private var textCacheCap = 0
private val textCache = Array(textCacheSize) { TextCacheObj(-1, -1L, null) }
/**
* Insertion sorts the last element fo the textCache
*/
private fun addToCache(text: CodepointSequence, linotype: Pixmap) {
// make room first
if (textCacheCap == textCacheSize - 1) {
var c = 0
var mark = -1
while (c < textCacheSize - 1) {
if (textCache[c].age == 0 && mark == -1) // if unmarked and age == 0, mark it
mark = c
if (mark >= 0) { // if marked then ...
// shift left everyting by 1
textCache[c] = textCache[c + 1]
}
c += 1
}
}
// count down all the elements' age by 1
textCache.forEach { it.age -= 1 }
// put new element at the end
textCache[textCacheCap] = TextCacheObj(textCacheCap, text.getHash(), ShittyGlyphLayout(text, linotype))
// insertion sort last elem (sorted by hash)
if (textCacheCap >= 1) { // when there's two or more elem...
var j = textCacheCap - 1
val x = textCache[textCacheCap]
while (j >= 0 && textCache[j].hash > x.hash) {
textCache[j + 1] = textCache[j]
j -= 1
}
textCache[j + 1] = x
}
if (textCacheCap < textCacheSize - 1) {
textCacheCap++
}
}
private fun getCache(hash: Long): TextCacheObj {
var low = 0
var high = textCacheCap
var key = -1
while (low <= high) {
val mid = (low + high).ushr(1) // safe from overflows
val midVal = textCache[mid]
if (hash > midVal.hash)
low = mid + 1
else if (hash < midVal.hash)
high = mid - 1
else {
key = mid
break // the condition is not enough to break the loop
}
}
if (key < 0)
throw NullPointerException("No element found")
return textCache[key]
}
private fun cacheContains(hash: Long): Boolean {
var low = 0
var high = textCacheCap
var key = -1
while (low <= high) {
val mid = (low + high).ushr(1) // safe from overflows
val midVal = textCache[mid]
if (hash > midVal.hash)
low = mid + 1
else if (hash < midVal.hash)
high = mid - 1
else {
key = mid
break // the condition is not enough to break the loop
}
}
return (key >= 0)
}
private fun getColour(codePoint: Int): Int { // input: 0x10F_RGB, out: RGBA8888 private fun getColour(codePoint: Int): Int { // input: 0x10F_RGB, out: RGBA8888
if (colourBuffer.containsKey(codePoint)) if (colourBuffer.containsKey(codePoint))
@@ -306,7 +413,7 @@ class GameFontBase(fontDir: String, val noShadow: Boolean = false, val flipY: Bo
return col return col
} }
private val colourBuffer = HashMap<Int, Int>() private val colourBuffer = HashMap<CodePoint, ARGB8888>()
private val unihanWidthSheets = arrayOf( private val unihanWidthSheets = arrayOf(
SHEET_UNIHAN, SHEET_UNIHAN,
@@ -397,7 +504,8 @@ class GameFontBase(fontDir: String, val noShadow: Boolean = false, val flipY: Bo
0x1F00..0x1FFF, 0x1F00..0x1FFF,
0x2C60..0x2C7F 0x2C60..0x2C7F
) )
private val glyphProps: HashMap<Int, GlyphProps> = HashMap() /** Props of all printable Unicode points. */
private val glyphProps: HashMap<CodePoint, GlyphProps> = HashMap()
private val sheets: Array<PixmapRegionPack> private val sheets: Array<PixmapRegionPack>
private var charsetOverride = 0 private var charsetOverride = 0
@@ -567,6 +675,10 @@ class GameFontBase(fontDir: String, val noShadow: Boolean = false, val flipY: Bo
private val pixmapOffsetY = 10 private val pixmapOffsetY = 10
override fun draw(batch: Batch, charSeq: CharSequence, x: Float, y: Float): GlyphLayout? { override fun draw(batch: Batch, charSeq: CharSequence, x: Float, y: Float): GlyphLayout? {
if (debug)
println("[TerrarumSansBitmap] max age: $textCacheCap")
fun Int.flipY() = this * if (flipY) 1 else -1 fun Int.flipY() = this * if (flipY) 1 else -1
@@ -579,10 +691,11 @@ class GameFontBase(fontDir: String, val noShadow: Boolean = false, val flipY: Bo
val mainColObj = originalColour val mainColObj = originalColour
var mainCol: Int = originalColour.toRGBA8888().forceOpaque() var mainCol: Int = originalColour.toRGBA8888().forceOpaque()
val charSeqHash = charSeq.toCodePoints().getHash()
if (charSeq.isNotBlank()) { if (charSeq.isNotBlank()) {
if (!textCache.containsKey(charSeq) || flagFirstRun) { if (!cacheContains(charSeqHash) || flagFirstRun) {
textBuffer = charSeq.toCodePoints() textBuffer = charSeq.toCodePoints()
val (posXbuffer, posYbuffer) = buildWidthAndPosBuffers() val (posXbuffer, posYbuffer) = buildWidthAndPosBuffers()
@@ -704,13 +817,14 @@ class GameFontBase(fontDir: String, val noShadow: Boolean = false, val flipY: Bo
// put things into cache // put things into cache
textCache[charSeq] = ShittyGlyphLayout(textBuffer, linotype!!) //textCache[charSeq] = ShittyGlyphLayout(textBuffer, linotype!!)
addToCache(textBuffer, linotype!!)
} }
else { else {
val bufferObj = textCache[charSeq] val bufferObj = getCache(charSeqHash)
textBuffer = bufferObj!!.textBuffer textBuffer = bufferObj.glyphLayout!!.textBuffer
linotype = bufferObj!!.linotype linotype = bufferObj.glyphLayout!!.linotype
} }
@@ -788,7 +902,7 @@ class GameFontBase(fontDir: String, val noShadow: Boolean = false, val flipY: Bo
return len return len
} }
private fun getSheetType(c: Int): Int { private fun getSheetType(c: CodePoint): Int {
if (charsetOverride == 1 && isBulgarian(c)) if (charsetOverride == 1 && isBulgarian(c))
return SHEET_BULGARIAN_VARW return SHEET_BULGARIAN_VARW
else if (charsetOverride == 2 && isBulgarian(c)) else if (charsetOverride == 2 && isBulgarian(c))
@@ -1492,6 +1606,7 @@ class GameFontBase(fontDir: String, val noShadow: Boolean = false, val flipY: Bo
val charsetOverrideBulgarian = Character.toChars(CHARSET_OVERRIDE_BG_BG) val charsetOverrideBulgarian = Character.toChars(CHARSET_OVERRIDE_BG_BG)
val charsetOverrideSerbian = Character.toChars(CHARSET_OVERRIDE_SR_SR) val charsetOverrideSerbian = Character.toChars(CHARSET_OVERRIDE_SR_SR)
// randomiser effect hash ONLY
private val hashBasis = -3750763034362895579L private val hashBasis = -3750763034362895579L
private val hashPrime = 1099511628211L private val hashPrime = 1099511628211L
private var hashAccumulator = hashBasis private var hashAccumulator = hashBasis
@@ -1508,6 +1623,21 @@ class GameFontBase(fontDir: String, val noShadow: Boolean = false, val flipY: Bo
getHash(y.toRawBits()) getHash(y.toRawBits())
} }
fun CodepointSequence.getHash(): Long {
val hashBasis = -3750763034362895579L
val hashPrime = 1099511628211L
var hashAccumulator = hashBasis
this.forEach {
hashAccumulator = hashAccumulator xor it.toLong()
hashAccumulator *= hashPrime
}
return hashAccumulator
}
private fun Int.toHex() = "U+${this.toString(16).padStart(4, '0').toUpperCase()}" private fun Int.toHex() = "U+${this.toString(16).padStart(4, '0').toUpperCase()}"
private fun CharSequence.sha256(): ByteArray { private fun CharSequence.sha256(): ByteArray {
@@ -1614,4 +1744,4 @@ class GameFontBase(fontDir: String, val noShadow: Boolean = false, val flipY: Bo
val noColorCode = toColorCode(0x0000) val noColorCode = toColorCode(0x0000)
} }
} }