diff --git a/.idea/workspace.xml b/.idea/workspace.xml index 3a2729c..1fa7fff 100644 --- a/.idea/workspace.xml +++ b/.idea/workspace.xml @@ -7,18 +7,12 @@ - - - - + - - - - Unexpected Unexp fun getSh codeRange @@ -195,6 +183,7 @@ demo.PNG joiner va- + ' .141 @@ -513,34 +502,34 @@ - + - - + - + + - - + - + + @@ -549,7 +538,7 @@ - + @@ -568,6 +557,18 @@ + + + + + + + + + + + + @@ -857,7 +858,7 @@ - + @@ -866,6 +867,35 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + @@ -880,28 +910,6 @@ - - - - - - - - - - - - - - - - - - - - - - @@ -909,30 +917,20 @@ - - - - - - - - - - - - - - - - - + + + + + + + - - + + diff --git a/FontTestGDX/lib/TerrarumSansBitmap.jar b/FontTestGDX/lib/TerrarumSansBitmap.jar index d8a30a6..b0c3f86 100644 Binary files a/FontTestGDX/lib/TerrarumSansBitmap.jar and b/FontTestGDX/lib/TerrarumSansBitmap.jar differ diff --git a/FontTestGDX/src/FontTestGDX.kt b/FontTestGDX/src/FontTestGDX.kt index c055cdf..e59a676 100644 --- a/FontTestGDX/src/FontTestGDX.kt +++ b/FontTestGDX/src/FontTestGDX.kt @@ -23,8 +23,8 @@ class FontTestGDX : Game() { lateinit var camera: OrthographicCamera - private val demotextName = "demotext.txt" - private val outimageName = "demo.png" + private val demotextName = "testtext.txt" + private val outimageName = "testing.png" override fun create() { font = GameFontBase("./assets", flipY = false, errorOnUnknownChar = true) // must test for two flipY cases diff --git a/assets/ascii_variable.tga b/assets/ascii_variable.tga index 24a6bff..312a0bd 100644 Binary files a/assets/ascii_variable.tga and b/assets/ascii_variable.tga differ diff --git a/assets/unipunct_variable.tga b/assets/unipunct_variable.tga index c3ab5f8..16c2c7a 100644 Binary files a/assets/unipunct_variable.tga and b/assets/unipunct_variable.tga differ diff --git a/demo.PNG b/demo.PNG index a9b715a..a19052d 100644 Binary files a/demo.PNG and b/demo.PNG differ diff --git a/demotext.txt b/demotext.txt index f2c8ad6..25ee118 100644 --- a/demotext.txt +++ b/demotext.txt @@ -10,7 +10,7 @@ You somehow found a multilingual one, and it makes your game look like an old co “Well, better than nothing… no, it’s ugly.” You speak japanese and you wish to support it, but then このクソなfont only goot for displaying -Japanese, it's not even multilingual, and their English look uncanny and inconsistent as hell. +Japanese, it’s not even multilingual, and their English look uncanny and inconsistent as hell. Eventually you just mix different fonts together, and the results were always infuriating. @@ -91,13 +91,20 @@ How multilingual? Real multilingual! 􎳌For all those dash-pedants, we have en-dash, em-dash, and even horizontal bars!􀀀 + 􏿿5¹⁹⁄₃₂ inch is 142.1 mm · (C₂F₄)ₙ is godly · Error = MoreCode²􀀀 + 􏿿NOTE: we don’t do fractions. 142¹⁄₁₀ mm is illegal!􀀀 + +􎳌Did you know Unicode supports arbitrary fractions? Actually I didn’t… as they abused super/subscripts!􀀀 + 􏃯Unicode References:􀀀 Basic Latin Latin-1 Latin Extension A Latin Extionsion B IPA Extension Greek Cyrillic Cyrillic Supplement Armenian Devanagari Bengali Thai Georgian Runic Cherokee Georgian Extended - General Punctuations CJK Symbols Kana Kana Phonetic Extension CJK Unihan Extension A CJK Unihan - Hangul Syllables Fullwidth Forms Kana Supplement + General Punctuations Superscripts and Subscripts CJK Symbols Kana Kana Phonetic Extension + CJK Unihan Extension A CJK Unihan Hangul Syllables Fullwidth Forms Kana Supplement GitHub’s issue page is open! You can report any 􏽕errors􀀀, or leave 􏽕suggestions􀀀. You can help this font to be more versatile. (for more languages, more frameworks) 􏽕Clone􀀀 this repo, make -changes, and make a 􏽕pull request􀀀! I appreciate any and all supports. \ No newline at end of file +changes, and make a 􏽕pull request􀀀! I appreciate any and all supports. + +� 􎳌文字化け!􀀀 � \ No newline at end of file diff --git a/src/net/torvald/terrarumsansbitmap/gdx/GameFontBase.kt b/src/net/torvald/terrarumsansbitmap/gdx/GameFontBase.kt index be50b2d..c2c36b3 100644 --- a/src/net/torvald/terrarumsansbitmap/gdx/GameFontBase.kt +++ b/src/net/torvald/terrarumsansbitmap/gdx/GameFontBase.kt @@ -309,7 +309,7 @@ class GameFontBase(fontDir: String, val noShadow: Boolean = false, val flipY: Bo 0x3400..0x9FFF, 0x400..0x52F, 0xFF00..0xFF1F, - 0x2000..0x205F, + 0x2000..0x209F, 0x370..0x3CE, 0xE00..0xE5F, 0x530..0x58F, @@ -471,123 +471,13 @@ class GameFontBase(fontDir: String, val noShadow: Boolean = false, val flipY: Bo if (charSeq.isNotBlank()) { if (oldCharSequence != charSeq || firstRun) { textBuffer = charSeq.toCodePoints() - val str = textBuffer - val widths = getWidthOfCharSeq(str) - val texWidth = widths.sum() + //val texWidth = widths.sum() //if (!firstRun) textTexture.dispose() //textTexture = FrameBuffer(Pixmap.Format.RGBA8888, texWidth, H, true) - glyphWidthBuffer = widths - - posXbuffer = IntArray(str.size, { 0 }) - posYbuffer = IntArray(str.size, { 0 }) - - - var nonDiacriticCounter = 0 // index of last instance of non-diacritic char - var stackUpwardCounter = 0 - var stackDownwardCounter = 0 - for (charIndex in 0 until posXbuffer.size) { - if (charIndex > 0) { - // nonDiacriticCounter allows multiple diacritics - - val thisChar = str[charIndex] - if (glyphProps[thisChar] == null && errorOnUnknownChar) { - val errorGlyphSB = StringBuilder() - Character.toChars(thisChar).forEach { errorGlyphSB.append(it) } - - throw InternalError("No GlyphProps for char '$errorGlyphSB' " + - "(${thisChar.charInfo()})") - } - val thisProp = glyphProps[thisChar] ?: nullProp - val lastNonDiacriticChar = str[nonDiacriticCounter] - val itsProp = glyphProps[lastNonDiacriticChar] ?: nullProp - - - //println("char: ${thisChar.charInfo()}\nproperties: $thisProp") - - - val alignmentOffset = when (thisProp.alignWhere) { - GlyphProps.ALIGN_LEFT -> 0 - GlyphProps.ALIGN_RIGHT -> thisProp.width - W_VAR_INIT - GlyphProps.ALIGN_CENTRE -> Math.ceil((thisProp.width - W_VAR_INIT) / 2.0).toInt() - else -> 0 // implies "diacriticsBeforeGlyph = true" - } - - if (!thisProp.writeOnTop) { - posXbuffer[charIndex] = - if (itsProp.alignWhere == GlyphProps.ALIGN_RIGHT) - posXbuffer[nonDiacriticCounter] + W_VAR_INIT + alignmentOffset + interchar - else - posXbuffer[nonDiacriticCounter] + itsProp.width + alignmentOffset + interchar - - nonDiacriticCounter = charIndex - - stackUpwardCounter = 0 - stackDownwardCounter = 0 - } - else if (thisProp.writeOnTop && thisProp.alignXPos == GlyphProps.DIA_JOINER) { - posXbuffer[charIndex] = - if (itsProp.alignWhere == GlyphProps.ALIGN_RIGHT) - posXbuffer[nonDiacriticCounter] + W_VAR_INIT + alignmentOffset - else - posXbuffer[nonDiacriticCounter] + itsProp.width + alignmentOffset - } - else { - // set X pos according to alignment information - posXbuffer[charIndex] = when (thisProp.alignWhere) { - GlyphProps.ALIGN_LEFT, GlyphProps.ALIGN_BEFORE -> posXbuffer[nonDiacriticCounter] - GlyphProps.ALIGN_RIGHT -> { - posXbuffer[nonDiacriticCounter] - (W_VAR_INIT - itsProp.width) - } - GlyphProps.ALIGN_CENTRE -> { - val alignXPos = if (itsProp.alignXPos == 0) itsProp.width.div(2) else itsProp.alignXPos - - if (itsProp.alignWhere == GlyphProps.ALIGN_RIGHT) { - posXbuffer[nonDiacriticCounter] + alignXPos + (itsProp.width + 1).div(2) - } - else { - posXbuffer[nonDiacriticCounter] + alignXPos - (W_VAR_INIT - 1).div(2) - } - } - else -> throw InternalError("Unsupported alignment: ${thisProp.alignWhere}") - } - - - // set Y pos according to diacritics position - if (thisProp.alignWhere == GlyphProps.ALIGN_CENTRE) { - when (thisProp.stackWhere) { - GlyphProps.STACK_DOWN -> { - posYbuffer[charIndex] = H_DIACRITICS * stackDownwardCounter - stackDownwardCounter++ - } - GlyphProps.STACK_UP -> { - posYbuffer[charIndex] = -H_DIACRITICS * stackUpwardCounter - - // shift down on lowercase if applicable - if (getSheetType(thisChar) in autoShiftDownOnLowercase && - lastNonDiacriticChar.isLowHeight()) { - if (thisProp.alignXPos == GlyphProps.DIA_OVERLAY) - posYbuffer[charIndex] += H_OVERLAY_LOWERCASE_SHIFTDOWN - else - posYbuffer[charIndex] += H_STACKUP_LOWERCASE_SHIFTDOWN - } - - stackUpwardCounter++ - } - GlyphProps.STACK_UP_N_DOWN -> { - posYbuffer[charIndex] = H_DIACRITICS * stackDownwardCounter - stackDownwardCounter++ - posYbuffer[charIndex] = -H_DIACRITICS * stackUpwardCounter - stackUpwardCounter++ - } - // for BEFORE_N_AFTER, do nothing in here - } - } - } - } - } + buildWidthAndPosBuffers() //print("[TerrarumSansBitmap] widthTable for $textBuffer: ") @@ -1037,6 +927,133 @@ class GameFontBase(fontDir: String, val noShadow: Boolean = false, val flipY: Bo } + private fun buildWidthAndPosBuffers() { + val str = textBuffer + val widths = getWidthOfCharSeq(str) + + glyphWidthBuffer = widths + + posXbuffer = IntArray(str.size, { 0 }) + posYbuffer = IntArray(str.size, { 0 }) + + + var nonDiacriticCounter = 0 // index of last instance of non-diacritic char + var stackUpwardCounter = 0 + var stackDownwardCounter = 0 + + val HALF_VAR_INIT = W_VAR_INIT.minus(1).div(2) + + for (charIndex in 0 until posXbuffer.size) { + if (charIndex > 0) { + // nonDiacriticCounter allows multiple diacritics + + val thisChar = str[charIndex] + if (glyphProps[thisChar] == null && errorOnUnknownChar) { + val errorGlyphSB = StringBuilder() + Character.toChars(thisChar).forEach { errorGlyphSB.append(it) } + + throw InternalError("No GlyphProps for char '$errorGlyphSB' " + + "(${thisChar.charInfo()})") + } + val thisProp = glyphProps[thisChar] ?: nullProp + val lastNonDiacriticChar = str[nonDiacriticCounter] + val itsProp = glyphProps[lastNonDiacriticChar] ?: nullProp + + + //println("char: ${thisChar.charInfo()}\nproperties: $thisProp") + + + val alignmentOffset = when (thisProp.alignWhere) { + GlyphProps.ALIGN_LEFT -> 0 + GlyphProps.ALIGN_RIGHT -> thisProp.width - W_VAR_INIT + GlyphProps.ALIGN_CENTRE -> Math.ceil((thisProp.width - W_VAR_INIT) / 2.0).toInt() + else -> 0 // implies "diacriticsBeforeGlyph = true" + } + + if (!thisProp.writeOnTop) { + posXbuffer[charIndex] = when (itsProp.alignWhere) { + GlyphProps.ALIGN_RIGHT -> + posXbuffer[nonDiacriticCounter] + W_VAR_INIT + alignmentOffset + interchar + GlyphProps.ALIGN_CENTRE -> + posXbuffer[nonDiacriticCounter] + HALF_VAR_INIT + itsProp.width + alignmentOffset + interchar + else -> + posXbuffer[nonDiacriticCounter] + itsProp.width + alignmentOffset + interchar + + } + + nonDiacriticCounter = charIndex + + stackUpwardCounter = 0 + stackDownwardCounter = 0 + } + else if (thisProp.writeOnTop && thisProp.alignXPos == GlyphProps.DIA_JOINER) { + posXbuffer[charIndex] = when (itsProp.alignWhere) { + GlyphProps.ALIGN_RIGHT -> + posXbuffer[nonDiacriticCounter] + W_VAR_INIT + alignmentOffset + //GlyphProps.ALIGN_CENTRE -> + // posXbuffer[nonDiacriticCounter] + HALF_VAR_INIT + itsProp.width + alignmentOffset + else -> + posXbuffer[nonDiacriticCounter] + itsProp.width + alignmentOffset + + } + } + else { + // set X pos according to alignment information + posXbuffer[charIndex] = when (thisProp.alignWhere) { + GlyphProps.ALIGN_LEFT, GlyphProps.ALIGN_BEFORE -> posXbuffer[nonDiacriticCounter] + GlyphProps.ALIGN_RIGHT -> { + posXbuffer[nonDiacriticCounter] - (W_VAR_INIT - itsProp.width) + } + GlyphProps.ALIGN_CENTRE -> { + val alignXPos = if (itsProp.alignXPos == 0) itsProp.width.div(2) else itsProp.alignXPos + + if (itsProp.alignWhere == GlyphProps.ALIGN_RIGHT) { + posXbuffer[nonDiacriticCounter] + alignXPos + (itsProp.width + 1).div(2) + } + else { + posXbuffer[nonDiacriticCounter] + alignXPos - HALF_VAR_INIT + } + } + else -> throw InternalError("Unsupported alignment: ${thisProp.alignWhere}") + } + + + // set Y pos according to diacritics position + if (thisProp.alignWhere == GlyphProps.ALIGN_CENTRE) { + when (thisProp.stackWhere) { + GlyphProps.STACK_DOWN -> { + posYbuffer[charIndex] = H_DIACRITICS * stackDownwardCounter + stackDownwardCounter++ + } + GlyphProps.STACK_UP -> { + posYbuffer[charIndex] = -H_DIACRITICS * stackUpwardCounter + + // shift down on lowercase if applicable + if (getSheetType(thisChar) in autoShiftDownOnLowercase && + lastNonDiacriticChar.isLowHeight()) { + if (thisProp.alignXPos == GlyphProps.DIA_OVERLAY) + posYbuffer[charIndex] += H_OVERLAY_LOWERCASE_SHIFTDOWN + else + posYbuffer[charIndex] += H_STACKUP_LOWERCASE_SHIFTDOWN + } + + stackUpwardCounter++ + } + GlyphProps.STACK_UP_N_DOWN -> { + posYbuffer[charIndex] = H_DIACRITICS * stackDownwardCounter + stackDownwardCounter++ + posYbuffer[charIndex] = -H_DIACRITICS * stackUpwardCounter + stackUpwardCounter++ + } + // for BEFORE_N_AFTER, do nothing in here + } + } + } + } + } + } + + /** UTF-16 to ArrayList of Int. UTF-16 is because of Java * Note: CharSequence IS a String. java.lang.String implements CharSequence. */ diff --git a/testing.PNG b/testing.PNG index 841c0c0..190ca14 100644 Binary files a/testing.PNG and b/testing.PNG differ diff --git a/testtext.txt b/testtext.txt index a6d3739..652d2ce 100644 --- a/testtext.txt +++ b/testtext.txt @@ -2,4 +2,27 @@ কাঁ (correct order, ??? rendering) हैहैहै সিওল কোরিয়া রাজধানী -सियोल कोरिया की राजधानी है \ No newline at end of file +सियोल कोरिया की राजधानी है + +O̸ +o̸ + +Received Pronunciation IPA: /ˌɪntəˈnæʃənəl/, [ˌɪntəˈnæʃənəɫ] +General American IPA: /ˌɪntɚˈnæʃənəl/, [ˌɪntɚˈnæʃənəɫ], [ˌɪɾ̃ɚˈnæʃənəɫ] +Rhymes: -ɛntəl (wtf wiktionary ??) + +ˈkʰomɐ gɛts ɐ ˈkʰjuɚ wɛl çiəz ə ˈstʌɹi fɔ ˈju ˈsɐɾə ˈpɛɾi wɔz ə bɛtʰəˈna˞li ˈnʌɚs hu hæd bin ˈwʌ˞kɪŋ deɪli æt æn +ˈɔʊl̴də d͡zʉ in ə dɪˈzʌɚtɪdə dɪsˈtɹʷɪkt ɔv zə tʰ ˈtʰɛɹɪtəɹi soʊ ʃi wʌz ˈvɛɹi ˈhæpi s tʉ stat ə njʉ d͡ʒɔb æt ə +ˈsʌbʌb˺ ˈpɹaɪbɛt pɹaktis in noʊsə ˈskweɚ niə zə ˈdjʉk ˈstoʊi ˈtaʊɚ ðæt ˈeɾiə wəz mʌt͡ʃ ˈniɾə fɔ hɐ ænd mɔə +tʉ laɪk˺ hɐ ˈlaɪkiŋgə ˈibn̩ so ɔ̃ ha fa˞st ˈmɔnɪŋ ʃi fɛlt͡s s t͡stɹɛst ʃi eɪt ə bɔl̴ ɔb˺ ˈpɔɹʷɪd͡ʒ t͡ʃɛkt hɐ˞sɛlf ɪn ðə +ˈmiɹəɚ ænd wɑʃt hɐ˞ ɸeɪs ɪn ə ˈhʌ˞li zɛn ʃi pʊt ɑn ə pɹeɪn bə ˈjɛloʊ dɹɛs ænd ə ɸʊlɪɸʊlis ˈd͡ʒækɛt pikt ap +hɐ˞ kʰit ænd ˈhɛdɪdə fɔ ˈwʌ˞kʰ + +ˈkʊmɐ gɛts ə ˈkjɚ wɛl̴ ˈɸ͜hi˞ɹɪzə ˈstʌɾi fɔ ʔəju saɹəʔ ˈpɛɹi wɑzə bə ˈbɛtənəɹi bɛt˺ ˈbɛtəˌɹɪnəɹi ənʌs f f hu havə bin +ˈw̰ʌ˞kɪŋ deɹi ʔat˺ ʔan ʔat an ol̴d͜zʉ in zə diˈzɑɹɛd d ˈdistɹɪkt ɔb ðəʔ ˈtɛɹɪtəɹʷi soʊ çi wʌz ˈbɛɹɪ ˈhɑpi tʉ stɑ˞t˺ +njʉ ə ˈnjʉ d͡ʒoʊb̥ ɐʔ to s̩ˈpɚb pɹaɪvɛt ˈpɹaktɪs ɪn nɔsˈkwɛɚ niə ðə ˈdʌk sɹit˺ t ˈtɔʌ˞ zat˺ ˈeɹiə wɑz mat͡ʃ ˈniɹɪ ˈniɹə fɔ +hʌ̥ɕʉ̥ fɔ hɚ ændə mɔ̰ mɔə tu ˈħə ˈɹaɪkɪŋ ˈivn̩ zoʊ ɔn ɸ hɐ fɐst mɔɹɪŋ ʃi fɛlt ˈsɹɛɾɛ ɛ̰ ʃi eɪt˺ ʌ boʊl̴ ɔb ˈpɹis æ̃ ˈt͡ʃɛkʰt +ˈhɑsɛlf ɪnə ˈmiɹə and wɔʃt hɐ fʷeɪs ɪn ˈhʌ˞ɹi ʌ ˈðɛn si pʊt ɔn ðə pɹeɪnə ˈjɛɹoʊ ˈdɹɛsɪz an fɹis ˈd͡ʒækɛt n̩ pik ʌpt +ˈhɑ kɪt an ˈhɛdɪd fɔ ə fɔ wɔk fɔ ˈwʌ˞kʰ æ̰̃ + +acegijmnopqrsuvwxyzɱɳʙɾɽʒʂʐʋɹɻɥɟɡɢʛȵɲŋɴʀɕʑçʝxɣχʁʜʍɰʟɨʉɯuʊøɘɵɤəɛœɜɞʌɔæɐɶɑɒɚɝɩɪʅʈʏʞ \ No newline at end of file