gdx font almost working

- TODO: bulgarian/serbian, shadow
This commit is contained in:
minjaesong
2017-06-16 18:52:03 +09:00
parent 6e403f97f8
commit e07e321ee3
4 changed files with 153 additions and 93 deletions

Binary file not shown.

View File

@@ -29,15 +29,50 @@ class TestTestTest : ApplicationAdapter() {
//gameFont = BitmapFont()
}
val text = arrayOf(
"x64またはx86-64とは、x86アーキテクチャを64ビットに拡張した命令セットアーキテクチャ。",
"実際には、AMDが発表したAMD64命令セット、続けてインテルが採用したIntel 64命令セット (かつてIA-32eまたはEM64Tと呼ばれていた)",
"などを含む、各社のAMD64互換命令セットの総称である。x86命令セットと互換性を持っていることから、広義にはx86にx64を含む場合がある。",
"",
"x86-64는 x86 명령어 집합 아키텍처의 64비트 모임이다. x86-64 명령어 집합은 에뮬레이션 없이 인텔의 x86를 지원하며 AMD64로 이름 붙인",
"AMD에 의해 고안되었다. 이 아키텍처는 인텔 64라는 이름으로 인텔에 의해 복제되기도 했다. (옘힐, 클래카마스 기술, CT, IA-32e, EM64T 등으로",
"불렸음) 이로써 x86-64 또는 x64의 이름을 일상적으로 사용하기에 이르렀다.",
"",
"x86-64 (также AMD64/Intel64/EM64T) — 64-битное расширение, набор команд для архитектуры x86, разработанное",
"компанией AMD, позволяющее выполнять программы в 64-разрядном режиме. Это расширение архитектуры x86 с",
"почти полной обратной совместимостью.",
"",
"Επίσης η x86-64 έχει καταχωρητές γενικής χρήσης 64-bit και πολλές άλλες βελτιώσεις. Η αρχική προδιαγραφή",
"δημιουργήθηκε από την AMD και έχει υλοποιηθεί από την AMD, την Intel, τη VIA και άλλες εταιρείες. Διατηρεί πλήρη",
"συμβατότητα προς τα πίσω με κώδικα 32-bit.",
"",
"x86-64 (簡稱x64) 是64位版本的x86指令集向后相容於16位及32位的x86架構。x64於1999年由AMD設計AMD首次公開",
"64位元集以擴充給x86稱為「AMD64」。其後也為英特爾所採用現時英特爾稱之為「Intel 64」在之前曾使用過「Clackamas",
"Technology」 (CT)、「IA-32e」及「EM64T」",
"",
"x86-64, ou x64, est une extension du jeu d'instructions x86 d'Intel, introduite par la société AMD avec la gamme",
"AMD64. Intel utilisera cette extension en l'appelant initialement EM64T renommé aujourd'hui en Intel 64.",
"",
"Amd64 (також x86-64/intel64/em64t/x64) — 64-бітова архітектура мікропроцесора і відповідний набір інструкцій,",
"розроблені компанією AMD. Це розширення архітектури x86 з повною зворотною сумісністю.",
"",
"x86-64 е наименованието на наборът от 64-битови разширения към x86 процесорната архитектура. Като синоним",
"на това наименование, се използват и съкращенията AMD64 (използвано от AMD), EM64T и IA-32e (използвани от",
"Intel) и x64 (използвано от Microsoft)."
)
override fun render() {
Gdx.gl.glClearColor(0f, 0f, 0f, 1f)
Gdx.gl.glClearColor(.157f, .157f, .157f, 0f)
Gdx.gl.glClear(GL20.GL_COLOR_BUFFER_BIT)
Gdx.graphics.setTitle("$GAME_NAME — F: ${Gdx.graphics.framesPerSecond}")
batch.inBatch {
gameFont.draw(batch, "Hello, world!", 10f, 30f)
text.forEachIndexed { index, s ->
gameFont.draw(batch, s, 10f, 10 + (20 * text.size) - 20f * index)
}
}
}
@@ -58,6 +93,9 @@ fun main(args: Array<String>) { // LWJGL 3 won't work? java.lang.VerifyError
val config = LwjglApplicationConfiguration()
config.useGL30 = true
config.vSyncEnabled = false
config.resizable = false
config.width = 1072
config.height = 742
//config.foregroundFPS = 9999
LwjglApplication(TestTestTest(), config)
}

View File

@@ -1,12 +1,9 @@
package net.torvald.terrarumsansbitmap.gdx
import com.badlogic.gdx.Gdx
import com.badlogic.gdx.graphics.Color
import com.badlogic.gdx.graphics.Pixmap
import com.badlogic.gdx.graphics.Texture
import com.badlogic.gdx.graphics.g2d.*
import com.badlogic.gdx.utils.Array
import net.torvald.spriteanimation.TextureRegionPack
import java.io.BufferedOutputStream
import java.io.File
import java.io.FileOutputStream
@@ -74,14 +71,14 @@ class GameFontBase(val noShadow: Boolean) : BitmapFont() {
}
private fun isHangul(c: Char) = c.toInt() in 0xAC00..0xD7A3
private fun isAscii(c: Char) = c.toInt() in 0x20..0xFF
private fun isAscii(c: Char) = c.toInt() in 0..0xFF
//private fun isRunic(c: Char) = runicList.contains(c)
private fun isExtA(c: Char) = c.toInt() in 0x100..0x17F
private fun isExtB(c: Char) = c.toInt() in 0x180..0x24F
private fun isKana(c: Char) = c.toInt() in 0x3040..0x30FF
private fun isCJKPunct(c: Char) = c.toInt() in 0x3000..0x303F
private fun isUniHan(c: Char) = c.toInt() in 0x3400..0x9FFF
private fun isCyrilic(c: Char) = c.toInt() in 0x400..0x45F
private fun isCyrilic(c: Char) = c.toInt() in 0x400..0x4FF // 4FF: futureproof; currently only up to 45F is supported
private fun isFullwidthUni(c: Char) = c.toInt() in 0xFF00..0xFF1F
private fun isUniPunct(c: Char) = c.toInt() in 0x2000..0x206F
private fun isGreek(c: Char) = c.toInt() in 0x370..0x3CE
@@ -131,15 +128,15 @@ class GameFontBase(val noShadow: Boolean) : BitmapFont() {
private val unihanWidthSheets = arrayOf(
SHEET_UNIHAN,
SHEET_FW_UNI,
SHEET_UNIHAN
SHEET_FW_UNI
)
private val variableWidthSheets = arrayOf(
SHEET_ASCII_VARW,
SHEET_CYRILIC_VARW,
SHEET_EXTA_VARW,
SHEET_GREEK_VARW,
SHEET_EXTB_VARW,
SHEET_CYRILIC_VARW,
SHEET_UNI_PUNCT,
SHEET_GREEK_VARW,
SHEET_THAI_VARW
)
@@ -161,42 +158,42 @@ class GameFontBase(val noShadow: Boolean) : BitmapFont() {
)
private val codeRange = arrayOf( // MUST BE MATCHING WITH SHEET INDICES!!
0..0xFF,
0xAC00..0xD7A4,
0xAC00..0xD7A3,
0x100..0x17F,
0x180..0x24F,
0x3040..0x30FF,
0x3000..0x303F,
0x3400..0x9FFF,
0x400..0x45F,
0x400..0x4FF,
0xFF00..0xFF1F,
0x2000..0x206F,
0x370..0x3CE,
0xE00..0xE7F,
0xE000..0xE0FF
)
private val sheets = arrayOf( // MUST BE MATCHING WITH SHEET INDICES!!
asciiSheet,
hangulSheet,
extASheet,
extBSheet,
kanaSheet,
cjkPunct,
uniHan,
cyrilic,
fullwidthForms,
uniPunct,
greekSheet,
thaiSheet,
customSheet
)
private val glyphWidths: HashMap<Int, Int> = HashMap()
private val sheets: Array<TextureRegionPack>
init {
val sheetsPack = ArrayList<TextureRegionPack>()
// first we create pixmap to read pixels, then make texture using pixmap
fileList.forEachIndexed { index, it ->
val isVariable = it.endsWith("_variable.tga")
val isVariable1 = it.endsWith("_variable.tga")
val isVariable2 = variableWidthSheets.contains(index)
val isVariable = isVariable1 && isVariable2
// idiocity check
if (isVariable1 && !isVariable2)
throw Error("[TerrarumSansBitmap] font is named as variable on the name but not enlisted as")
else if (!isVariable1 && isVariable2)
throw Error("[TerrarumSansBitmap] font is enlisted as variable on the name but not named as")
val pixmap: Pixmap
// unpack gz if applicable
if (it.endsWith(".gz")) {
val gzi = GZIPInputStream(Gdx.files.internal(fontParentDir + it).read(8192))
@@ -217,16 +214,23 @@ class GameFontBase(val noShadow: Boolean) : BitmapFont() {
if (isVariable) {
buildWidthTable(pixmap, codeRange[index].first, codeRange[index])
println("[TerrarumSansBitmap] loading texture $it [VARIABLE]")
buildWidthTable(pixmap, codeRange[index], 16)
}
else {
println("[TerrarumSansBitmap] loading texture $it")
}
val texture = Texture(pixmap)
val texRegPack = if (isVariable) {
TextureRegionPack(texture, W_VAR_INIT, H, HGAP_VAR, 0)
}
else if (index == SHEET_UNIHAN || index == SHEET_FW_UNI) {
TextureRegionPack(texture, W_UNIHAN, H_UNIHAN)
else if (index == SHEET_UNIHAN) {
TextureRegionPack(texture, W_UNIHAN, H_UNIHAN) // the only exception that is height is 16
}
// below they all have height of 20 'H'
else if (index == SHEET_FW_UNI) {
TextureRegionPack(texture, W_UNIHAN, H)
}
else if (index == SHEET_CJK_PUNCT) {
TextureRegionPack(texture, W_ASIAN_PUNCT, H)
@@ -240,13 +244,15 @@ class GameFontBase(val noShadow: Boolean) : BitmapFont() {
else if (index == SHEET_CUSTOM_SYM) {
TextureRegionPack(texture, SIZE_CUSTOM_SYM, SIZE_CUSTOM_SYM) // TODO variable
}
else throw IllegalArgumentException("Unknown sheet index: $index")
else throw IllegalArgumentException("[TerrarumSansBitmap] Unknown sheet index: $index")
sheets[index] = texRegPack
sheetsPack.add(texRegPack)
pixmap.dispose() // you are terminated
}
sheets = sheetsPack.toTypedArray()
}
@@ -259,7 +265,6 @@ class GameFontBase(val noShadow: Boolean) : BitmapFont() {
override fun isFlipped() = false
override fun setFixedWidthGlyphs(glyphs: CharSequence) {
throw UnsupportedOperationException("Nope, no monospace, and figures are already fixed width, bruv.")
}
@@ -270,15 +275,18 @@ class GameFontBase(val noShadow: Boolean) : BitmapFont() {
setOwnsTexture(true)
}
private var microBuffer: CharSequence = ""
private var microBWidth = intArrayOf() // absolute posX of glyphs from print-origin
private val offsetUnihan = (H - H_UNIHAN) / 2
private val offsetCustomSym = (H - SIZE_CUSTOM_SYM) / 2
private var textBuffer: CharSequence = ""
private var textBWidth = intArrayOf() // absolute posX of glyphs from print-origin
override fun draw(batch: Batch, str: CharSequence, x: Float, y: Float): GlyphLayout? {
if (microBuffer != str) {
microBuffer = str
if (textBuffer != str) {
textBuffer = str
val widths = getWidthOfCharSeq(str)
microBWidth = Array(str.length, { charIndex ->
textBWidth = Array(str.length, { charIndex ->
if (charIndex == 0)
0
else {
@@ -290,16 +298,43 @@ class GameFontBase(val noShadow: Boolean) : BitmapFont() {
}
//print("[gamefontbase] widthTable for $microBuffer: ")
//microBWidth.forEach { print("$it ") }; println()
//print("[TerrarumSansBitmap] widthTable for $textBuffer: ")
//textBWidth.forEach { print("$it ") }; println()
microBuffer.forEachIndexed { index, c ->
textBuffer.forEachIndexed { index, c ->
val sheetID = getSheetType(c)
val sheetXY = getSheetwisePosition(c)
batch.draw(
sheets[sheetID]!!.get(sheetXY[0], sheetXY[1]),
x + microBWidth[index], y
)
//println("[TerrarumSansBitmap] sprite: $sheetID:${sheetXY[0]}x${sheetXY[1]}")
if (sheetID != SHEET_HANGUL) {
batch.draw(
sheets[sheetID].get(sheetXY[0], sheetXY[1]),
x + textBWidth[index],
y +
if (sheetID == SHEET_UNIHAN) // evil exceptions
offsetUnihan
else if (sheetID == SHEET_CUSTOM_SYM)
offsetCustomSym
else 0
)
}
else { // JOHAB (assemble) HANGUL
val hangulSheet = sheets[1]
val hIndex = c.toInt() - 0xAC00
val indexCho = getHanChosung(hIndex)
val indexJung = getHanJungseong(hIndex)
val indexJong = getHanJongseong(hIndex)
val choRow = getHanInitialRow(hIndex)
val jungRow = getHanMedialRow(hIndex)
val jongRow = getHanFinalRow(hIndex)
batch.draw(hangulSheet.get(indexCho, choRow), x + textBWidth[index], y)
batch.draw(hangulSheet.get(indexJung, jungRow), x + textBWidth[index], y)
batch.draw(hangulSheet.get(indexJong, jongRow), x + textBWidth[index], y)
}
}
return null
@@ -309,7 +344,7 @@ class GameFontBase(val noShadow: Boolean) : BitmapFont() {
override fun dispose() {
super.dispose()
sheets.forEach { it!!.dispose() }
sheets.forEach { it.dispose() }
}
private fun getWidthOfCharSeq(s: CharSequence): IntArray {
@@ -323,7 +358,7 @@ class GameFontBase(val noShadow: Boolean) : BitmapFont() {
glyphWidths[chr.toInt()]!!
}
catch (e: kotlin.KotlinNullPointerException) {
println("KotlinNullPointerException on glyph number ${Integer.toHexString(chr.toInt()).toUpperCase()}")
println("[TerrarumSansBitmap] no width data for glyph number ${Integer.toHexString(chr.toInt()).toUpperCase()}")
//System.exit(1)
W_LATIN_WIDE // failsafe
}
@@ -378,7 +413,7 @@ class GameFontBase(val noShadow: Boolean) : BitmapFont() {
else if (isCustomSym(c))
return SHEET_CUSTOM_SYM
else
return SHEET_UNKNOWN// fixed width punctuations
return SHEET_UNKNOWN
// fixed width
// fallback
}
@@ -386,19 +421,23 @@ class GameFontBase(val noShadow: Boolean) : BitmapFont() {
private fun getSheetwisePosition(ch: Char): IntArray {
val sheetX: Int; val sheetY: Int
when (getSheetType(ch)) {
SHEET_EXTA_VARW -> {
SHEET_UNIHAN -> {
sheetX = unihanIndexX(ch)
sheetY = unihanIndexY(ch)
}
SHEET_EXTA_VARW -> {
sheetX = extAindexX(ch)
sheetY = extAindexY(ch)
}
SHEET_EXTB_VARW -> {
SHEET_EXTB_VARW -> {
sheetX = extBindexX(ch)
sheetY = extBindexY(ch)
}
SHEET_KANA -> {
SHEET_KANA -> {
sheetX = kanaIndexX(ch)
sheetY = kanaIndexY(ch)
}
SHEET_CJK_PUNCT -> {
SHEET_CJK_PUNCT -> {
sheetX = cjkPunctIndexX(ch)
sheetY = cjkPunctIndexY(ch)
}
@@ -406,27 +445,27 @@ class GameFontBase(val noShadow: Boolean) : BitmapFont() {
sheetX = cyrilicIndexX(ch)
sheetY = cyrilicIndexY(ch)
}
SHEET_FW_UNI -> {
SHEET_FW_UNI -> {
sheetX = fullwidthUniIndexX(ch)
sheetY = fullwidthUniIndexY(ch)
}
SHEET_UNI_PUNCT -> {
SHEET_UNI_PUNCT -> {
sheetX = uniPunctIndexX(ch)
sheetY = uniPunctIndexY(ch)
}
SHEET_GREEK_VARW -> {
SHEET_GREEK_VARW -> {
sheetX = greekIndexX(ch)
sheetY = greekIndexY(ch)
}
SHEET_THAI_VARW -> {
SHEET_THAI_VARW -> {
sheetX = thaiIndexX(ch)
sheetY = thaiIndexY(ch)
}
SHEET_CUSTOM_SYM -> {
SHEET_CUSTOM_SYM -> {
sheetX = symbolIndexX(ch)
sheetY = symbolIndexY(ch)
}
else -> {
else -> {
sheetX = ch.toInt() % 16
sheetY = ch.toInt() / 16
}
@@ -435,19 +474,19 @@ class GameFontBase(val noShadow: Boolean) : BitmapFont() {
return intArrayOf(sheetX, sheetY)
}
fun buildWidthTable(pixmap: Pixmap, codeOffset: Int, codeRange: IntRange, rows: Int = 16) {
val binaryCodeOffset = 15
fun buildWidthTable(pixmap: Pixmap, codeRange: IntRange, cols: Int = 16) {
val binaryCodeOffset = W_VAR_INIT
val cellW = 16
val cellH = 20
val cellW = W_VAR_INIT + 1
val cellH = H
// control chars
for (ccode in codeRange) {
val glyphX = ccode % rows
val glyphY = ccode / rows
for (code in codeRange) {
val codeStartX = (glyphX * cellW) + binaryCodeOffset
val codeStartY = (glyphY * cellH)
val cellX = ((code - codeRange.start) % cols) * cellW
val cellY = ((code - codeRange.start) / cols) * cellH
val codeStartX = cellX + binaryCodeOffset
val codeStartY = cellY
var glyphWidth = 0
for (downCtr in 0..3) {
@@ -457,30 +496,13 @@ class GameFontBase(val noShadow: Boolean) : BitmapFont() {
}
}
glyphWidths[codeOffset + ccode] = glyphWidth
glyphWidths[code] = glyphWidth
}
}
companion object {
internal val glyphWidths: HashMap<Int, Int> = HashMap()
internal var hangulSheet: TextureRegionPack? = null
internal var asciiSheet: TextureRegionPack? = null
internal var runicSheet: TextureRegionPack? = null
internal var extASheet: TextureRegionPack? = null
internal var extBSheet: TextureRegionPack? = null
internal var kanaSheet: TextureRegionPack? = null
internal var cjkPunct: TextureRegionPack? = null
internal var uniHan: TextureRegionPack? = null
internal var cyrilic: TextureRegionPack? = null
internal var fullwidthForms: TextureRegionPack? = null
internal var uniPunct: TextureRegionPack? = null
internal var greekSheet: TextureRegionPack? = null
internal var thaiSheet: TextureRegionPack? = null
internal var customSheet: TextureRegionPack? = null
internal val JUNG_COUNT = 21
internal val JONG_COUNT = 28