From 226ae77ab4fcd2273c883c4873136f6cdebc1f95 Mon Sep 17 00:00:00 2001 From: Song Minjae Date: Sat, 11 Feb 2017 23:57:42 +0900 Subject: [PATCH] cyrillic Former-commit-id: b5b4c8495b387dbc6516829f3ddf0124f87d8500 Former-commit-id: 2c78b2fb6112199bc7bf4d55b3df01da10f14958 --- src/net/torvald/imagefont/GameFontBase.kt | 126 +++++++------------- src/net/torvald/imagefont/GameFontWhite.kt | 6 +- src/net/torvald/terrarum/StateFontTester.kt | 19 +-- 3 files changed, 50 insertions(+), 101 deletions(-) diff --git a/src/net/torvald/imagefont/GameFontBase.kt b/src/net/torvald/imagefont/GameFontBase.kt index e52ad212f..0ddbe9714 100644 --- a/src/net/torvald/imagefont/GameFontBase.kt +++ b/src/net/torvald/imagefont/GameFontBase.kt @@ -63,7 +63,6 @@ open class GameFontBase : Font { private fun isCJKPunct(c: Char) = c.toInt() >= 0x3000 && c.toInt() < 0x3040 private fun isUniHan(c: Char) = c.toInt() >= 0x3400 && c.toInt() < 0xA000 private fun isCyrilic(c: Char) = c.toInt() >= 0x400 && c.toInt() < 0x460 - private fun isCyrilicEF(c: Char) = cyrilecEFList.contains(c) private fun isFullwidthUni(c: Char) = c.toInt() >= 0xFF00 && c.toInt() < 0xFF20 private fun isUniPunct(c: Char) = c.toInt() >= 0x2000 && c.toInt() < 0x2070 private fun isWenQuanYi1(c: Char) = c.toInt() >= 0x33F3 && c.toInt() <= 0x69FC @@ -99,9 +98,6 @@ open class GameFontBase : Font { private fun cyrilicIndexX(c: Char) = (c.toInt() - 0x400) % 16 private fun cyrilicIndexY(c: Char) = (c.toInt() - 0x400) / 16 - private fun cyrilicEFindexX(c: Char) = cyrilecEFList.indexOf(c) % 16 - private fun cyrilicEFindexY(c: Char) = cyrilecEFList.indexOf(c) / 16 - private fun fullwidthUniIndexX(c: Char) = (c.toInt() - 0xFF00) % 16 private fun fullwidthUniIndexY(c: Char) = (c.toInt() - 0xFF00) / 16 @@ -132,7 +128,6 @@ open class GameFontBase : Font { private fun keycapIndexY(c: Char) = (c.toInt() - 0xE000) / 16 private val narrowWidthSheets = arrayOf( - SHEET_CYRILIC_EF, SHEET_GREEK_EF, SHEET_EXTB_ROMANIAN_EF ) @@ -155,25 +150,13 @@ open class GameFontBase : Font { val chr = s[i] val ctype = getSheetType(s[i]) - /*if (i > 0 && s[i].toInt() > 0x20) { - // inter-Unihan-hangul Kerning - val cpre = getSheetType(s[i - 1]) - if ((unihanWidthSheets.contains(cpre) || cpre == SHEET_HANGUL) && !(unihanWidthSheets.contains(ctype) || ctype == SHEET_HANGUL) - - || (unihanWidthSheets.contains(ctype) || ctype == SHEET_HANGUL) && !(unihanWidthSheets.contains(cpre) || cpre == SHEET_HANGUL)) { - // margin after/before hangul/unihan - len += 2 - } - else if ((ctype == SHEET_HANGUL || ctype == SHEET_KANA) && (cpre == SHEET_HANGUL || cpre == SHEET_KANA)) { - // margin between hangul/kana - len += 1 - } - - }*/ - if (chr.toInt() == 0x21B) // HAX! len += 6 - else if (ctype == SHEET_ASCII_VARW || ctype == SHEET_EXTA_VARW) + else if ( + ctype == SHEET_ASCII_VARW || + ctype == SHEET_EXTA_VARW || + ctype == SHEET_CYRILIC_VARW + ) len += asciiWidths[chr.toInt()]!! else if (zeroWidthSheets.contains(ctype)) len += 0 @@ -236,25 +219,6 @@ open class GameFontBase : Font { val glyphW = getWidth(ch.toString()) - /*// initials - hangulSheet.renderInUse( - Math.round(x + getWidthSubstr(s, i + 1) - glyphW), - Math.round(((H - H_HANGUL) / 2).toFloat() + y + 1f), - indexCho, choRow - ) - // medials - hangulSheet.renderInUse( - Math.round(x + getWidthSubstr(s, i + 1) - glyphW), - Math.round(((H - H_HANGUL) / 2).toFloat() + y + 1f), - indexJung, jungRow - ) - // finals - hangulSheet.renderInUse( - Math.round(x + getWidthSubstr(s, i + 1) - glyphW), - Math.round(((H - H_HANGUL) / 2).toFloat() + y + 1f), - indexJong, jongRow - )*/ - hangulSheet.getSubImage(indexCho, choRow).drawWithShadow( Math.round(x + getWidthSubstr(s, i + 1) - glyphW).toFloat(), Math.round(((H - H_HANGUL) / 2).toFloat() + y + 1f).toFloat(), @@ -389,14 +353,10 @@ open class GameFontBase : Font { sheetX = cjkPunctIndexX(ch) sheetY = cjkPunctIndexY(ch) } - SHEET_CYRILIC_EM -> { + SHEET_CYRILIC_VARW -> { sheetX = cyrilicIndexX(ch) sheetY = cyrilicIndexY(ch) } - SHEET_CYRILIC_EF -> { - sheetX = cyrilicEFindexX(ch) - sheetY = cyrilicEFindexY(ch) - } SHEET_FW_UNI -> { sheetX = fullwidthUniIndexX(ch) sheetY = fullwidthUniIndexY(ch) @@ -437,14 +397,6 @@ open class GameFontBase : Font { val glyphW = getWidth("" + ch) try { - /*sheetKey[prevInstance].renderInUse( - Math.round(x + getWidthSubstr(s, i + 1) - glyphW) // Interchar: pull punct right next to hangul to the left - + if (i > 0 && isHangul(s[i - 1])) -3 else 0, - Math.round(y) + if (prevInstance == SHEET_CJK_PUNCT) -1 - else if (prevInstance == SHEET_FW_UNI) (H - H_HANGUL) / 2 - else 0, - sheetX, sheetY - )*/ sheetKey[prevInstance]!!.getSubImage(sheetX, sheetY).drawWithShadow( Math.round(x + getWidthSubstr(s, i + 1) - glyphW).toFloat(), @@ -476,9 +428,7 @@ open class GameFontBase : Font { private fun getSheetType(c: Char): Int { // EFs - if (isCyrilicEF(c)) - return SHEET_CYRILIC_EF - else if (isGreekEF(c)) + if (isGreekEF(c)) return SHEET_GREEK_EF else if (isRomanianEF(c)) return SHEET_EXTB_ROMANIAN_EF @@ -497,7 +447,7 @@ open class GameFontBase : Font { else if (isExtA(c)) return SHEET_EXTA_VARW else if (isCyrilic(c)) - return SHEET_CYRILIC_EM + return SHEET_CYRILIC_VARW else if (isUniPunct(c)) return SHEET_UNI_PUNCT else if (isCJKPunct(c)) @@ -609,6 +559,32 @@ open class GameFontBase : Font { } } + fun buildCyrillicWidthTable() { + val binaryCodeOffset = 15 + + val cellW = cyrilic.getSubImage(0, 0).width + 1 // should be 16 + val cellH = cyrilic.getSubImage(0, 0).height + 1 // should be 20 + + // control chars + for (ccode in 0..0x5F) { + val glyphX = ccode % 16 + val glyphY = ccode / 16 + + val codeStartX = (glyphX * cellW) + binaryCodeOffset + val codeStartY = (glyphY * cellH) + + var glyphWidth = 0 + for (downCtr in 0..3) { + // if alpha is not zero, assume it's 1 + if (cyrilic.texture.getPixel(codeStartX, codeStartY + downCtr)[3] == 255) { + glyphWidth = glyphWidth or (1 shl downCtr) + } + } + + asciiWidths[0x400 + ccode] = glyphWidth + } + } + companion object { lateinit internal var hangulSheet: SpriteSheet @@ -622,7 +598,6 @@ open class GameFontBase : Font { lateinit internal var cjkPunct: SpriteSheet // static SpriteSheet uniHan; lateinit internal var cyrilic: SpriteSheet - lateinit internal var cyrilicEF: SpriteSheet lateinit internal var fullwidthForms: SpriteSheet lateinit internal var uniPunct: SpriteSheet lateinit internal var wenQuanYi_1: SpriteSheet @@ -643,7 +618,6 @@ open class GameFontBase : Font { internal val W_UNIHAN = 16 internal val W_LATIN_WIDE = 9 // width of regular letters, including m internal val W_LATIN_NARROW = 5 // width of letter f, t, i, l - internal val W_FLAG_VARIABLE: Int = -0x4E0E // neue internal val H = 20 internal val H_HANGUL = 16 @@ -659,31 +633,23 @@ open class GameFontBase : Font { internal val SHEET_KANA = 4 internal val SHEET_CJK_PUNCT = 5 internal val SHEET_UNIHAN = 6 - internal val SHEET_CYRILIC_EM = 7 - internal val SHEET_CYRILIC_EF = 8 - internal val SHEET_FW_UNI = 9 - internal val SHEET_UNI_PUNCT = 10 - internal val SHEET_WENQUANYI_1 = 11 - internal val SHEET_WENQUANYI_2 = 12 - internal val SHEET_GREEK_EM = 13 - internal val SHEET_GREEK_EF = 14 - internal val SHEET_EXTB_ROMANIAN_EM = 15 - internal val SHEET_EXTB_ROMANIAN_EF = 16 - internal val SHEET_THAI_EM = 17 - internal val SHEET_THAI_EF = 18 - internal val SHEET_KEYCAP = 19 + internal val SHEET_CYRILIC_VARW = 7 + internal val SHEET_FW_UNI = 8 + internal val SHEET_UNI_PUNCT = 9 + internal val SHEET_WENQUANYI_1 = 10 + internal val SHEET_WENQUANYI_2 = 11 + internal val SHEET_GREEK_EM = 12 + internal val SHEET_GREEK_EF = 13 + internal val SHEET_EXTB_ROMANIAN_EM = 14 + internal val SHEET_EXTB_ROMANIAN_EF = 15 + internal val SHEET_THAI_EM = 16 + internal val SHEET_THAI_EF = 17 + internal val SHEET_KEYCAP = 18 internal val SHEET_UNKNOWN = 254 internal val SHEET_COLOURCODE = 255 lateinit internal var sheetKey: Array - internal val cyrilecEFList = arrayOf( - 0x406.toChar(), - 0x407.toChar(), - 0x456.toChar(), - 0x457.toChar(), - 0x458.toChar() - ) internal val greekEFList = arrayOf( 0x390.toChar(), 0x399.toChar(), diff --git a/src/net/torvald/imagefont/GameFontWhite.kt b/src/net/torvald/imagefont/GameFontWhite.kt index 57f266368..3ccfca489 100644 --- a/src/net/torvald/imagefont/GameFontWhite.kt +++ b/src/net/torvald/imagefont/GameFontWhite.kt @@ -29,9 +29,7 @@ class GameFontWhite : GameFontBase() { , W_UNIHAN, H_UNIHAN );*/ GameFontBase.cyrilic = SpriteSheet( - "./assets/graphics/fonts/cyrilic_fullwidth.tga", GameFontBase.W_LATIN_WIDE, GameFontBase.H) - GameFontBase.cyrilicEF = SpriteSheet( - "./assets/graphics/fonts/cyrilic_ef.tga", GameFontBase.W_LATIN_NARROW, GameFontBase.H) + "./assets/graphics/fonts/cyrilic_variable.tga", 15, 19, 1) GameFontBase.fullwidthForms = SpriteSheet( "./assets/graphics/fonts/fullwidth_forms.tga", GameFontBase.W_UNIHAN, GameFontBase.H_UNIHAN) GameFontBase.uniPunct = SpriteSheet( @@ -62,7 +60,6 @@ class GameFontWhite : GameFontBase() { GameFontBase.cjkPunct, null, // Full unihan, filler because we're using WenQuanYi GameFontBase.cyrilic, - GameFontBase.cyrilicEF, GameFontBase.fullwidthForms, GameFontBase.uniPunct, GameFontBase.wenQuanYi_1, @@ -80,5 +77,6 @@ class GameFontWhite : GameFontBase() { buildAsciiWidthTable() buildLatinExtAWidthTable() + buildCyrillicWidthTable() } } diff --git a/src/net/torvald/terrarum/StateFontTester.kt b/src/net/torvald/terrarum/StateFontTester.kt index d3822ad22..5b7f6c824 100644 --- a/src/net/torvald/terrarum/StateFontTester.kt +++ b/src/net/torvald/terrarum/StateFontTester.kt @@ -76,28 +76,13 @@ nopqrstuvwxyz g.drawString("NOPQRSTÜVWXYZ", 10f, 30f) g.drawString("abcdefghijklmno", 160f, 10f) - g.drawString("pqrstuvwxyzßœ", 160f, 30f) + g.drawString("pqrstuvwxyzߌ", 160f, 30f) g.drawString("1234567890", 320f, 10f) g.drawString("minimum kerning keming Nannu Namu", 320f, 30f) g.drawString("Syö salmiakkia perkele", 480f, 10f) - /*val text = arrayOf( - "Kedok Ketawa (The Laughing Mask) is a 1940 action film from the Dutch East Indies, in", - "present-day Indonesia. After a young couple falls in love, the title character, a", - "vigilante, helps them fight off criminals who have been sent to kidnap the woman by a", - "rich man who wants her as his wife. It was the first film of Union Films, one of four", - "new production houses established after the country's ailing film industry was revived", - "by the success of Albert Balink's Terang Boelan. Kedok Ketawa was directed by Jo An", - "Djan and stars Basoeki Resobowo, Fatimah, Oedjang (as the vigilante), S Poniman and", - "Eddy Kock. Featuring fighting, comedy, and singing, and advertised as an \"Indonesian", - "cocktail of violent actions ... and sweet romance\", the film received positive", - "reviews, particularly for its cinematography. Following the success of the film, Union", - "produced another six before being shut down in early 1942 during the Japanese", - "occupation. Screened until at least August 1944, the film may be lost." - )*/ - val text = arrayOf( "The Olympic marmot (Marmota olympus) is a rodent in the squirrel family, Sciuridae.", "It lives only in the U.S. state of Washington, at middle elevations on the Olympic Peninsula.", @@ -128,7 +113,7 @@ nopqrstuvwxyz "mála sem einkenndust af því að opinberir aðilar virtu ekki stjórnarskrárvarin réttindi einstaklingsins.", "", "Also supports:", - "키스의 고유조건은 입술끼리 만나야 하고 특별한 기술은 필요치 않다.", + "키스의 고유조건은 입술끼리 만나야 하고 특별한 기술은 필요치 않다. 대한민국 머한민국 대구 머구 명작 띵작 유식 윾싀", "とりなくこゑす ゆめさませ みよあけわたる ひんかしを そらいろはえて おきつへに ほふねむれゐぬ もやのうち", "鳥啼く声す 夢覚ませ 見よ明け渡る 東を 空色栄えて 沖つ辺に 帆船群れゐぬ 靄の中 (using WenQuanYi)", ""