First working version of the Keming Machine
@@ -38,19 +38,29 @@ Width is encoded in binary bits, on pixels. On the font spritesheet, every glyph
|
||||
|
||||
### Glyph Tags
|
||||
|
||||
Green-tinted area (should be 10 px tall) contains the tags. Tags are defined as following:
|
||||
Rightmost vertical column (should be 20 px tall) contains the tags. Tags are defined as following:
|
||||
|
||||
```
|
||||
(LSB) 0 == Use Compiler Directive (Undefined right now, keep it as 0)
|
||||
1 -, 1 = Align to this X pos of prev char,
|
||||
1 | 2 = only valid if write-on-top is 1
|
||||
1 | 4 = and is centre-aligned and non-zero
|
||||
1 -' 8 = (if this is zero, floorOf(width/2) will be used instead)
|
||||
0 -, 0 Align 1 Align 0 Align 1 Align before
|
||||
1 -' 0 left 0 right 1 centre 1 the glyph
|
||||
1 == write-on-top, usually it's diatritics but not always (e.g. devanagari vowel sign O)
|
||||
1 -, 0 Stack 1 Stack 0 Before 1 Up &
|
||||
(MSB) 0 -' 0 up 0 down 1 &After 1 Down (e.g. U+0C48)
|
||||
(LSB) W -,
|
||||
W |
|
||||
W |= Width of the character
|
||||
W |
|
||||
W -'
|
||||
m --Is this character lowheight?
|
||||
K -,
|
||||
K |= Tags used by the "Keming Machine"
|
||||
K |
|
||||
K -' ,-Unused
|
||||
· --'
|
||||
X -, Align to this X pos of prev char, only valid if write-on-top is 1
|
||||
X |= and is centre-aligned and non-zero
|
||||
X | (if this is zero, floorOf(width/2) will be used instead)
|
||||
X -'
|
||||
A -,_ 0 Align 1 Align 0 Align 1 Align before
|
||||
A -' 0 left 0 right 1 centre 1 the glyph
|
||||
D --write-on-top, usually it's diatritics but not always (e.g. devanagari vowel sign O)
|
||||
S -,_ 0 Stack 1 Stack 0 Before 1 Up &
|
||||
(MSB) S -' 0 up 0 down 1 &After 1 Down (e.g. U+0C48)
|
||||
```
|
||||
|
||||
#### Stack Up/Down
|
||||
|
||||
|
Before Width: | Height: | Size: 320 KiB After Width: | Height: | Size: 320 KiB |
|
Before Width: | Height: | Size: 1.8 KiB After Width: | Height: | Size: 5.0 KiB |
|
Before Width: | Height: | Size: 280 KiB After Width: | Height: | Size: 280 KiB |
BIN
demo.PNG
|
Before Width: | Height: | Size: 142 KiB After Width: | Height: | Size: 142 KiB |
@@ -5,7 +5,8 @@ There are many bitmap fonts on the internet. You care for the multilingual suppo
|
||||
most of them do not support your language, vector fonts take too much time to load, and even
|
||||
then their legibility suffers because screw built-in antialias.
|
||||
|
||||
You somehow found a multilingual one, and it makes your game look like an old computer, and you say:
|
||||
You somehow found a multilingual one, and it makes your text as if they came straight from an old
|
||||
computer terminal, and you say:
|
||||
|
||||
“Well, better than nothing… no, it’s ugly.”
|
||||
|
||||
|
||||
|
Before Width: | Height: | Size: 18 KiB After Width: | Height: | Size: 1.1 KiB |
115
keming_machine.txt
Normal file
@@ -0,0 +1,115 @@
|
||||
--- Pixel 0
|
||||
- Lowheight bit
|
||||
- encoding: has pixel - it's low height
|
||||
- used by the diacritics system to quickly look up if the character is low height without parsing the Pixel 1
|
||||
|
||||
### Legends
|
||||
#
|
||||
# ͞ A·B < unset for lowheight miniscules, as in e
|
||||
# |·| < space we don't care
|
||||
#――C·D < middle hole for majuscules, as in C
|
||||
# E·F < middle hole for miniscules, as in c
|
||||
# ͟ G·H
|
||||
# ――― < baseline
|
||||
# |·|
|
||||
# J·K
|
||||
|
||||
--- Pixel 1
|
||||
- A..K Occupied (1024)
|
||||
- Is ABGH are all Ys instead of Bars? (2)
|
||||
- Say, A is Bar but E is wye (e.g. Ꮨ), this condition is false; this character must be encoded as ABDFGH(B).
|
||||
- encoding:
|
||||
- <MSB> Y0000000 JK000000 ABCDEFGH <LSB>
|
||||
- Y: Bar/Wye Mode
|
||||
- A..K: arguments
|
||||
- B-type will contract the space by 2 pixels, while Y-type will do it by 1
|
||||
|
||||
# Capital/lower itself is given using the pixel 0 due to the diacritics processing
|
||||
|
||||
--- Examples
|
||||
- AB(B): T
|
||||
- ABCEGH(B): C
|
||||
- ABCEFGH(Y): K
|
||||
- ABCDEG: Ꮅ
|
||||
- ABCDEFGH: B,D,O
|
||||
- ABCDFH: Ч
|
||||
- ABCEG: Г
|
||||
- ABGH: Ꮖ
|
||||
- ACDEG: Ꮀ
|
||||
- ACDEFGH: h,Ƅ
|
||||
- ACDFH: ߆
|
||||
- ACEGH: L
|
||||
- AH(Y): \
|
||||
- BDEFGH: J
|
||||
- BDFGH: ɺ,ป
|
||||
- BG(Y): /
|
||||
- CD: Ⴕ
|
||||
- CDEF(Y): Φ
|
||||
- CDEFGH: a,c,e,i,o,φ,ϕ
|
||||
- CDEFGHJK: g
|
||||
- CDEFGHK: ƞ
|
||||
|
||||
- AB(Y): Y
|
||||
- ABCD(Y): V
|
||||
- CDEF(Y): v
|
||||
- EFGH(Y): ʌ
|
||||
- CDGH(Y): A
|
||||
|
||||
--- Rules
|
||||
# Legend: _ dont care
|
||||
# @ must have a bit set
|
||||
# ` must have a bit unset
|
||||
- ͟A͟B͟C͟D͟E͟F͟G͟H͟J͟K͟ ͟ ͟ ͟A͟B͟C͟D͟E͟F͟G͟H͟J͟K͟
|
||||
- _@_`___`__ — `_________ # Γe,TJ ; Ye,YJ,Ve,VJ,TA,ΓA,VA,Vʌ,YA,Yʌ,yA,yʌ,/a,/d
|
||||
- _@_@___`__ — `___`_@___ # Pɺ but NOT PJ
|
||||
- ___`_`____ — `___@_`___ # Cꟶ,Kꟶ,Lꟶ,Γꟶ
|
||||
- ___`_`____ — `_@___`___ # CꟵ,KꟵ,LꟵ,ΓꟵ
|
||||
-----------------------------------------------------
|
||||
- _`________ — @_`___`___ # eꞀ,LT ; eY,LY,eV,LV,AT,AꞀ,AY,Ay,λY,λy,a\,b\
|
||||
- _`___`_@__ — @_@___`___ # Lꟼ but NOT bꟼ
|
||||
- _`___@_`__ — __`_`_____ # ⱶƆ,ⱶJ
|
||||
- _`_@___`__ — __`_`_____ # ⱵƆ,ⱵJ
|
||||
|
||||
|
||||
--- Implementation
|
||||
code: |
|
||||
val posTable = intArrayOf(7,6,5,4,3,2,1,0,9,8)
|
||||
|
||||
class RuleMask(s: String) {
|
||||
|
||||
private var careBits = 0
|
||||
private var ruleBits = 0
|
||||
|
||||
init {
|
||||
s.forEachIndexed { index, char ->
|
||||
when (char) {
|
||||
'@' -> {
|
||||
careBits = careBits or (1 shl posTable[index])
|
||||
ruleBits = ruleBits or (1 shl posTable[index])
|
||||
}
|
||||
'`' -> {
|
||||
careBits = careBits or (1 shl posTable[index])
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fun matches(shapeBits: Int) = ((shapeBits and careBits) and ruleBits) == 0
|
||||
|
||||
}
|
||||
|
||||
--- Pixel 2
|
||||
Glyph pos for up/down diacritics
|
||||
- U: X-position for stack-up diacritics
|
||||
- D: X-position for stack-down diacritics
|
||||
- encoding:
|
||||
- <MSB> 00000000 100DDDDD 100UUUUU <LSB>
|
||||
- If either U/D is unused, centre position will be used.
|
||||
- Diacritics will be centred on the x-position this parameter points to
|
||||
|
||||
--- Pixel 3
|
||||
dot removal for diacritics:
|
||||
- All 24 bits are used to put replacement character
|
||||
- encoding:
|
||||
- <MSB> RRRRRRRR GGGGGGGG BBBBBBBB <LSB>
|
||||
|
||||
@@ -10,7 +10,12 @@ data class GlyphProps(
|
||||
val alignXPos: Int,
|
||||
val rtl: Boolean = false,
|
||||
val stackWhere: Int = 0,
|
||||
var extInfo: IntArray? = null
|
||||
var extInfo: IntArray? = null,
|
||||
|
||||
val hasKernData: Boolean = false,
|
||||
val isLowheight: Boolean = false,
|
||||
val isKernYtype: Boolean = false,
|
||||
val kerningMask: Int = 255
|
||||
) {
|
||||
companion object {
|
||||
const val ALIGN_LEFT = 0
|
||||
@@ -38,6 +43,21 @@ data class GlyphProps(
|
||||
tags.ushr(8).and(3)
|
||||
)
|
||||
|
||||
constructor(width: Int, tags: Int, isLowheight: Boolean, isKernYtype: Boolean, kerningMask: Int) : this(
|
||||
width,
|
||||
tags.ushr(7).and(1) == 1,
|
||||
tags.ushr(5).and(3),
|
||||
tags.ushr(1).and(15),
|
||||
tags.and(1) == 1,
|
||||
tags.ushr(8).and(3),
|
||||
null,
|
||||
|
||||
true,
|
||||
isLowheight,
|
||||
isKernYtype,
|
||||
kerningMask
|
||||
)
|
||||
|
||||
fun isOverlay() = writeOnTop && alignXPos == 1
|
||||
|
||||
override fun hashCode(): Int {
|
||||
|
||||
@@ -726,13 +726,28 @@ class TerrarumSansBitmap(
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// lowheight bit
|
||||
val isLowHeight = (pixmap.getPixel(codeStartX, codeStartY + 5).and(0xFF) != 0)
|
||||
|
||||
// Keming machine parameters
|
||||
val kerningBit1 = pixmap.getPixel(codeStartX, codeStartY + 6)
|
||||
val kerningBit2 = pixmap.getPixel(codeStartX, codeStartY + 7)
|
||||
val kerningBit3 = pixmap.getPixel(codeStartX, codeStartY + 8)
|
||||
val isKerningYtype = ((kerningBit1 and 0x80000000.toInt()) != 0)
|
||||
val kerningMask = kerningBit1.ushr(8).and(0xFFFFFF)
|
||||
val hasKerningBit = kerningBit1 and 255 != 0//(kerningBit1 and 255 != 0 && kerningMask != 0xFFFF)
|
||||
|
||||
|
||||
//println("$code: Width $width, tags $tags")
|
||||
if (hasKerningBit)
|
||||
println("$code: W $width, tags $tags, low? $isLowHeight, kern ${kerningMask.toString(16).padStart(6,'0')} (raw: ${kerningBit1.toLong().and(4294967295).toString(16).padStart(8,'0')})")
|
||||
|
||||
/*val isDiacritics = pixmap.getPixel(codeStartX, codeStartY + H - 1).and(0xFF) != 0
|
||||
if (isDiacritics)
|
||||
glyphWidth = -glyphWidth*/
|
||||
|
||||
glyphProps[code] = GlyphProps(width, tags)
|
||||
glyphProps[code] = if (hasKerningBit) GlyphProps(width, tags, isLowHeight, isKerningYtype, kerningMask) else GlyphProps(width, tags)
|
||||
|
||||
// extra info
|
||||
val extCount = glyphProps[code]?.requiredExtInfoCount() ?: 0
|
||||
@@ -752,6 +767,7 @@ class TerrarumSansBitmap(
|
||||
glyphProps[code]!!.extInfo!![x] = info
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1337,6 +1353,90 @@ class TerrarumSansBitmap(
|
||||
return crc.value.toInt()
|
||||
}
|
||||
|
||||
fun CodePoint.isLowHeight() = glyphProps[this]?.isLowheight == true || this in lowHeightLetters
|
||||
|
||||
private fun getKerning(prevChar: CodePoint, thisChar: CodePoint): Int {
|
||||
val maskL = glyphProps[prevChar]?.kerningMask
|
||||
val maskR = glyphProps[thisChar]?.kerningMask
|
||||
return if (glyphProps[prevChar]?.hasKernData == true && glyphProps[thisChar]?.hasKernData == true) {
|
||||
val contraction = if (glyphProps[prevChar]?.isKernYtype == true || glyphProps[thisChar]?.isKernYtype == true) -1 else -2
|
||||
kerningRules.forEachIndexed { index, it ->
|
||||
if (it.first.matches(maskL!!) && it.second.matches(maskR!!)) {
|
||||
println("Kerning rule match #${index+1}: ${prevChar.toChar()}${thisChar.toChar()}, Rule:${it.first} ${it.second}; Contraction: ${-contraction}")
|
||||
|
||||
return contraction
|
||||
}
|
||||
}
|
||||
return 0
|
||||
}
|
||||
else 0
|
||||
/*else if (prevChar in lowHeightLetters) {
|
||||
return if (thisChar in kernTees) kernTee // lh - T
|
||||
else if (thisChar in kernYees) kernYee // lh - Y
|
||||
else 0
|
||||
}
|
||||
else if (prevChar in kernElls) {
|
||||
return if (thisChar in kernTees) kernTee // L - T
|
||||
else if (thisChar in kernVees) kernYee // L - V
|
||||
else if (thisChar in kernYees) kernYee // L - Y
|
||||
else 0
|
||||
}
|
||||
else if (prevChar in kernTees) {
|
||||
return if (thisChar in lowHeightLetters) kernTee // T - lh
|
||||
else if (thisChar in kernJays) kernTee // T - J
|
||||
else if (thisChar in kernAyes) kernYee // T - A
|
||||
else if (thisChar in kernDees) kernTee // T - d
|
||||
else 0
|
||||
}
|
||||
else if (prevChar in kernYees) {
|
||||
return if (thisChar in lowHeightLetters) kernYee // Y - lh
|
||||
else if (thisChar in kernAyes) kernYee // Y - A
|
||||
else if (thisChar in kernJays) kernYee // Y - J
|
||||
else if (thisChar in kernDees) kernYee // Y - d
|
||||
else 0
|
||||
}
|
||||
else if (prevChar in kernAyes) {
|
||||
return if (thisChar in kernVees) kernAV // A - V
|
||||
else if (thisChar in kernTees) kernAV // A - T
|
||||
else if (thisChar in kernYees) kernYee // A - Y
|
||||
else 0
|
||||
}
|
||||
else if (prevChar in kernVees) {
|
||||
return if (thisChar in kernAyes) kernAV // V - A
|
||||
else if (thisChar in kernJays) kernAV // V - J
|
||||
else if (thisChar in kernDees) kernAV // V - d
|
||||
else 0
|
||||
}
|
||||
else if (prevChar in kernGammas) {
|
||||
return if (thisChar in kernAyes) kernYee // Γ - Α
|
||||
else if (thisChar in lowHeightLetters) kernTee // Γ - lh
|
||||
else if (thisChar in kernJays) kernTee // Γ - J
|
||||
else if (thisChar in kernDees) kernTee // Γ - d
|
||||
else 0
|
||||
}
|
||||
else if (prevChar in kernBees) {
|
||||
return if (thisChar in kernTees) kernTee // b - T
|
||||
else if (thisChar in kernYees) kernYee // b - Y
|
||||
else 0
|
||||
}
|
||||
else if (prevChar in kernLowVees) {
|
||||
return if (thisChar in kernTees) kernTee
|
||||
else if (thisChar in kernLowLambdas) kernAVlow
|
||||
else 0
|
||||
}
|
||||
else if (prevChar in kernLowLambdas) {
|
||||
return if (thisChar in kernTees) kernTee
|
||||
else if (thisChar in kernLowVees) kernAVlow
|
||||
else 0
|
||||
}
|
||||
else if (prevChar in slashes) {
|
||||
return if (thisChar in kernDees || thisChar in lowHeightLetters) kernSlash // / - d
|
||||
else if (thisChar in slashes) kernDoubleSlash
|
||||
else 0
|
||||
}
|
||||
else 0*/
|
||||
}
|
||||
|
||||
companion object {
|
||||
|
||||
private fun Boolean.toSign() = if (this) 1 else -1
|
||||
@@ -1344,7 +1444,6 @@ class TerrarumSansBitmap(
|
||||
/**
|
||||
* lowercase AND the height is equal to x-height (e.g. lowercase B, D, F, H, K, L, ... does not count
|
||||
*/
|
||||
fun CodePoint.isLowHeight() = this in lowHeightLetters
|
||||
|
||||
data class ShittyGlyphLayout(val textBuffer: CodepointSequence, val linotype: Texture, val width: Int)
|
||||
data class TextCacheObj(val hash: Long, val glyphLayout: ShittyGlyphLayout?): Comparable<TextCacheObj> {
|
||||
@@ -1358,7 +1457,6 @@ class TerrarumSansBitmap(
|
||||
}
|
||||
|
||||
|
||||
|
||||
private val HCF = 0x115F
|
||||
private val HJF = 0x1160
|
||||
|
||||
@@ -1813,74 +1911,6 @@ print(','.join(a))
|
||||
private val kernSlash = -1
|
||||
private val kernDoubleSlash = -2
|
||||
|
||||
private fun getKerning(prevChar: CodePoint, thisChar: CodePoint): Int {
|
||||
return if (prevChar in lowHeightLetters) {
|
||||
return if (thisChar in kernTees) kernTee // lh - T
|
||||
else if (thisChar in kernYees) kernYee // lh - Y
|
||||
else 0
|
||||
}
|
||||
else if (prevChar in kernElls) {
|
||||
return if (thisChar in kernTees) kernTee // L - T
|
||||
else if (thisChar in kernVees) kernYee // L - V
|
||||
else if (thisChar in kernYees) kernYee // L - Y
|
||||
else 0
|
||||
}
|
||||
else if (prevChar in kernTees) {
|
||||
return if (thisChar in lowHeightLetters) kernTee // T - lh
|
||||
else if (thisChar in kernJays) kernTee // T - J
|
||||
else if (thisChar in kernAyes) kernYee // T - A
|
||||
else if (thisChar in kernDees) kernTee // T - d
|
||||
else 0
|
||||
}
|
||||
else if (prevChar in kernYees) {
|
||||
return if (thisChar in lowHeightLetters) kernYee // Y - lh
|
||||
else if (thisChar in kernAyes) kernYee // Y - A
|
||||
else if (thisChar in kernJays) kernYee // Y - J
|
||||
else if (thisChar in kernDees) kernYee // Y - d
|
||||
else 0
|
||||
}
|
||||
else if (prevChar in kernAyes) {
|
||||
return if (thisChar in kernVees) kernAV // A - V
|
||||
else if (thisChar in kernTees) kernAV // A - T
|
||||
else if (thisChar in kernYees) kernYee // A - Y
|
||||
else 0
|
||||
}
|
||||
else if (prevChar in kernVees) {
|
||||
return if (thisChar in kernAyes) kernAV // V - A
|
||||
else if (thisChar in kernJays) kernAV // V - J
|
||||
else if (thisChar in kernDees) kernAV // V - d
|
||||
else 0
|
||||
}
|
||||
else if (prevChar in kernGammas) {
|
||||
return if (thisChar in kernAyes) kernYee // Γ - Α
|
||||
else if (thisChar in lowHeightLetters) kernTee // Γ - lh
|
||||
else if (thisChar in kernJays) kernTee // Γ - J
|
||||
else if (thisChar in kernDees) kernTee // Γ - d
|
||||
else 0
|
||||
}
|
||||
else if (prevChar in kernBees) {
|
||||
return if (thisChar in kernTees) kernTee // b - T
|
||||
else if (thisChar in kernYees) kernYee // b - Y
|
||||
else 0
|
||||
}
|
||||
else if (prevChar in kernLowVees) {
|
||||
return if (thisChar in kernTees) kernTee
|
||||
else if (thisChar in kernLowLambdas) kernAVlow
|
||||
else 0
|
||||
}
|
||||
else if (prevChar in kernLowLambdas) {
|
||||
return if (thisChar in kernTees) kernTee
|
||||
else if (thisChar in kernLowVees) kernAVlow
|
||||
else 0
|
||||
}
|
||||
else if (prevChar in slashes) {
|
||||
return if (thisChar in kernDees || thisChar in lowHeightLetters) kernSlash // / - d
|
||||
else if (thisChar in slashes) kernDoubleSlash
|
||||
else 0
|
||||
}
|
||||
else 0
|
||||
}
|
||||
|
||||
|
||||
val charsetOverrideDefault = Character.toChars(CHARSET_OVERRIDE_DEFAULT).toSurrogatedString()
|
||||
val charsetOverrideBulgarian = Character.toChars(CHARSET_OVERRIDE_BG_BG).toSurrogatedString()
|
||||
@@ -1890,6 +1920,65 @@ print(','.join(a))
|
||||
private fun CharArray.toSurrogatedString(): String = "${this[0]}${this[1]}"
|
||||
|
||||
val noColorCode = toColorCode(0x0000)
|
||||
|
||||
|
||||
|
||||
// The "Keming" Machine //
|
||||
|
||||
private val kemingBitMask: IntArray = intArrayOf(7,6,5,4,3,2,1,0,15,14).map { 1 shl it }.toIntArray()
|
||||
|
||||
private class RuleMask(s: String) {
|
||||
|
||||
private var careBits = 0
|
||||
private var ruleBits = 0
|
||||
|
||||
init {
|
||||
s.forEachIndexed { index, char ->
|
||||
when (char) {
|
||||
'@' -> {
|
||||
careBits = careBits or kemingBitMask[index]
|
||||
ruleBits = ruleBits or kemingBitMask[index]
|
||||
}
|
||||
'`' -> {
|
||||
careBits = careBits or kemingBitMask[index]
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fun matches(shapeBits: Int) = ((shapeBits and careBits) == ruleBits)
|
||||
|
||||
override fun toString() = "C:${careBits.toString(2).padStart(16,'0')}-R:${ruleBits.toString(2).padStart(16,'0')}"
|
||||
}
|
||||
|
||||
/**
|
||||
* Legend: _ dont care
|
||||
* @ must have a bit set
|
||||
* ` must have a bit unset
|
||||
* Order: ABCDEFGHJK, where
|
||||
*
|
||||
* A·B < unset for lowheight miniscules, as in e
|
||||
* |·| < space we don't care
|
||||
* C·D < middle hole for majuscules, as in C
|
||||
* E·F < middle hole for miniscules, as in c
|
||||
* G·H
|
||||
*――― < baseline
|
||||
* |·|
|
||||
* J·K
|
||||
*/
|
||||
private val kerningRules = arrayOf(
|
||||
RuleMask("_@_`___`__") to RuleMask("`_________"),
|
||||
RuleMask("_@_@___`__") to RuleMask("`___`_@___"),
|
||||
RuleMask("___`_`____") to RuleMask("`___@_`___"),
|
||||
RuleMask("___`_`____") to RuleMask("`_@___`___"),
|
||||
|
||||
RuleMask("_`________") to RuleMask("@_`___`___"),
|
||||
RuleMask("_`___`_@__") to RuleMask("@_@___`___"),
|
||||
RuleMask("_`___@_`__") to RuleMask("__`_`_____"),
|
||||
RuleMask("_`_@___`__") to RuleMask("__`_`_____"),
|
||||
)
|
||||
|
||||
// End of the Keming Machine
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -6,14 +6,12 @@ import com.badlogic.gdx.graphics.Texture
|
||||
import com.badlogic.gdx.graphics.g2d.Batch
|
||||
import com.badlogic.gdx.graphics.g2d.BitmapFont
|
||||
import com.badlogic.gdx.graphics.g2d.GlyphLayout
|
||||
import com.badlogic.gdx.graphics.g2d.SpriteBatch
|
||||
import com.badlogic.gdx.utils.GdxRuntimeException
|
||||
import net.torvald.terrarumsansbitmap.GlyphProps
|
||||
import net.torvald.terrarumsansbitmap.gdx.*
|
||||
import net.torvald.terrarumsansbitmap.gdx.CodePoint
|
||||
import net.torvald.terrarumsansbitmap.gdx.TerrarumSansBitmap.Companion.TextCacheObj
|
||||
import net.torvald.terrarumsansbitmap.gdx.TerrarumSansBitmap.Companion.ShittyGlyphLayout
|
||||
import net.torvald.terrarumsansbitmap.gdx.TerrarumSansBitmap.Companion.isLowHeight
|
||||
import java.io.BufferedOutputStream
|
||||
import java.io.FileOutputStream
|
||||
import java.io.Reader
|
||||
|
||||