WIP, at least it draws something

This commit is contained in:
Minjae Song
2018-09-17 16:26:25 +09:00
parent d8dd88c6a7
commit 920b11e3e9
4 changed files with 171 additions and 34 deletions

BIN
demo.PNG

Binary file not shown.

Before

Width:  |  Height:  |  Size: 145 KiB

After

Width:  |  Height:  |  Size: 14 KiB

View File

@@ -394,12 +394,12 @@ class GameFontBase(fontDir: String, val noShadow: Boolean = false, val flipY: Bo
0x2C60..0x2C7F
)
private val glyphProps: HashMap<Int, GlyphProps> = HashMap()
private val sheets: Array<TextureRegionPack>
private val sheets: Array<PixmapRegionPack>
private var charsetOverride = 0
init {
val sheetsPack = ArrayList<TextureRegionPack>()
val sheetsPack = ArrayList<PixmapRegionPack>()
// first we create pixmap to read pixels, then make texture using pixmap
fileList.forEachIndexed { index, it ->
@@ -470,44 +470,46 @@ class GameFontBase(fontDir: String, val noShadow: Boolean = false, val flipY: Bo
buildWidthTableFixed()
if (!noShadow) {
makeShadow(pixmap)
}
/*if (!noShadow) {
makeShadowForSheet(pixmap)
}*/
val texture = Texture(pixmap)
//val texture = Texture(pixmap)
val texRegPack = if (isVariable) {
TextureRegionPack(texture, W_VAR_INIT, H, HGAP_VAR, 0, xySwapped = isXYSwapped)
PixmapRegionPack(pixmap, W_VAR_INIT, H, HGAP_VAR, 0, xySwapped = isXYSwapped)
}
else if (index == SHEET_UNIHAN) {
TextureRegionPack(texture, W_UNIHAN, H_UNIHAN) // the only exception that is height is 16
PixmapRegionPack(pixmap, 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)
PixmapRegionPack(pixmap, W_UNIHAN, H)
}
else if (index == SHEET_CJK_PUNCT) {
TextureRegionPack(texture, W_ASIAN_PUNCT, H)
PixmapRegionPack(pixmap, W_ASIAN_PUNCT, H)
}
else if (index == SHEET_KANA) {
TextureRegionPack(texture, W_KANA, H)
PixmapRegionPack(pixmap, W_KANA, H)
}
else if (index == SHEET_HANGUL) {
TextureRegionPack(texture, W_HANGUL, H)
PixmapRegionPack(pixmap, W_HANGUL, H)
}
else if (index == SHEET_CUSTOM_SYM) {
TextureRegionPack(texture, SIZE_CUSTOM_SYM, SIZE_CUSTOM_SYM) // TODO variable
PixmapRegionPack(pixmap, SIZE_CUSTOM_SYM, SIZE_CUSTOM_SYM) // TODO variable
}
else if (index == SHEET_RUNIC) {
TextureRegionPack(texture, W_LATIN_WIDE, H)
PixmapRegionPack(pixmap, W_LATIN_WIDE, H)
}
else throw IllegalArgumentException("[TerrarumSansBitmap] Unknown sheet index: $index")
texRegPack.texture.setFilter(minFilter, magFilter)
//texRegPack.texture.setFilter(minFilter, magFilter)
sheetsPack.add(texRegPack)
pixmap.dispose() // you are terminated
//pixmap.dispose() // you are terminated
}
sheets = sheetsPack.toTypedArray()
@@ -545,6 +547,10 @@ class GameFontBase(fontDir: String, val noShadow: Boolean = false, val flipY: Bo
private var nullProp = GlyphProps(15, 0)
private var pixmapTextureHolder: Texture? = null
private var pixmapHolder: Pixmap? = null
private val pixmapOffsetY = -10
override fun draw(batch: Batch, charSeq: CharSequence, x: Float, y: Float): GlyphLayout? {
val oldProjectionMatrix = batch.projectionMatrix
@@ -553,13 +559,12 @@ class GameFontBase(fontDir: String, val noShadow: Boolean = false, val flipY: Bo
// always draw at integer position; this is bitmap font after all
val x = Math.round(x).toFloat()
val y = Math.round(y).toFloat()
val x = Math.round(x).toInt()//.toFloat()
val y = Math.round(y).toInt()//.toFloat()
if (charSeq.isNotBlank()) {
if (!textCache.containsKey(charSeq) || firstRun) {
textBuffer = charSeq.toCodePoints()
@@ -612,7 +617,13 @@ class GameFontBase(fontDir: String, val noShadow: Boolean = false, val flipY: Bo
//println()
resetHash(charSeq, x, y)
resetHash(charSeq, x.toFloat(), y.toFloat())
pixmapHolder?.dispose() /* you can do this one */
//pixmapTextureHolder?.dispose() /* you CAN'T do this however */
pixmapHolder = Pixmap(getWidth(textBuffer), H + -(pixmapOffsetY * 2), Pixmap.Format.RGBA8888)
var index = 0
while (index <= textBuffer.lastIndex) {
val c = textBuffer[index]
@@ -654,10 +665,18 @@ class GameFontBase(fontDir: String, val noShadow: Boolean = false, val flipY: Bo
batch.color = mainCol
batch.draw(hangulSheet.get(indexCho, choRow), x + posXbuffer[index].toFloat(), y)
batch.draw(hangulSheet.get(indexJung, jungRow), x + posXbuffer[index].toFloat(), y)
batch.draw(hangulSheet.get(indexJong, jongRow), x + posXbuffer[index].toFloat(), y)
//batch.color = mainCol
val choTex = hangulSheet.get(indexCho, choRow)
val jungTex = hangulSheet.get(indexJung, jungRow)
val jongTex = hangulSheet.get(indexJong, jongRow)
pixmapHolder?.drawPixmap(choTex, posXbuffer[index], pixmapOffsetY)
pixmapHolder?.drawPixmap(jungTex, posXbuffer[index], pixmapOffsetY)
pixmapHolder?.drawPixmap(jongTex, posXbuffer[index], pixmapOffsetY)
//batch.draw(choTex, x + posXbuffer[index].toFloat(), y)
//batch.draw(jungTex, x + posXbuffer[index].toFloat(), y)
//batch.draw(hangulSheet.get(indexJong, jongRow), x + posXbuffer[index].toFloat(), y)
index += hangulLength - 1
@@ -665,22 +684,24 @@ class GameFontBase(fontDir: String, val noShadow: Boolean = false, val flipY: Bo
}
else {
try {
val posY = y + posYbuffer[index].flipY() +
val posY = posYbuffer[index].flipY() +
if (sheetID == SHEET_UNIHAN) // evil exceptions
offsetUnihan
else if (sheetID == SHEET_CUSTOM_SYM)
offsetCustomSym
else 0
val posX = x + posXbuffer[index]
val posX = posXbuffer[index]
val texture = sheets[sheetID].get(sheetX, sheetY)
batch.color = mainCol
batch.draw(texture, posX, posY)
//batch.color = mainCol
pixmapHolder?.drawPixmap(texture, posX, posY + pixmapOffsetY)
//batch.draw(texture, posX, posY)
}
catch (noSuchGlyph: ArrayIndexOutOfBoundsException) {
batch.color = mainCol
//batch.color = mainCol
}
}
@@ -688,6 +709,11 @@ class GameFontBase(fontDir: String, val noShadow: Boolean = false, val flipY: Bo
index++
}
batch.color = mainCol
makeShadow(pixmapHolder)
pixmapTextureHolder = Texture(pixmapHolder)
batch.draw(pixmapTextureHolder, x.toFloat(), y.toFloat())
/*textTexture.end()
@@ -713,6 +739,11 @@ class GameFontBase(fontDir: String, val noShadow: Boolean = false, val flipY: Bo
sheets.forEach { it.dispose() }
}
/**
* Used for positioning letters, NOT for the actual width.
*
* For actual width, use `getWidth()`
*/
private fun getWidthOfCharSeq(s: CodepointSequence): IntArray {
val len = IntArray(s.size)
for (i in 0..s.lastIndex) {
@@ -1007,8 +1038,9 @@ class GameFontBase(fontDir: String, val noShadow: Boolean = false, val flipY: Bo
private val glyphLayout = GlyphLayout()
fun getWidth(text: String): Int {
var s = text.toCodePoints()
fun getWidth(text: String) = getWidth(text.toCodePoints())
fun getWidth(s: CodepointSequence): Int {
var len = 0
var i = 0
@@ -1296,9 +1328,7 @@ class GameFontBase(fontDir: String, val noShadow: Boolean = false, val flipY: Bo
*
* The pixmap must be mutable (beware of concurrentmodificationexception).
*/
private fun makeShadow(pixmap: Pixmap) {
private fun makeShadowForSheet(pixmap: Pixmap) {
for (y in 0..pixmap.height - 2) {
for (x in 0..pixmap.width - 2) {
val pxNow = pixmap.getPixel(x, y) // RGBA8888
@@ -1329,6 +1359,40 @@ class GameFontBase(fontDir: String, val noShadow: Boolean = false, val flipY: Bo
}
/**
* Edits the given pixmap so that it would have a shadow on it.
*
* Meant to be used to give shadow to a linotype (typeset-finished line of pixmap)
*
* The pixmap must be mutable (beware of concurrentmodificationexception).
*/
private fun makeShadow(pixmap: Pixmap?) {
if (pixmap == null) return
for (y in 0..pixmap.height - 2) {
for (x in 0..pixmap.width - 2) {
val pxNow = pixmap.getPixel(x, y) // RGBA8888
if (pxNow and 0xFF == 255) {
val pxRight = (x + 1) to y
val pxBottom = x to (y + 1)
val pxBottomRight = (x + 1) to (y + 1)
val opCue = listOf(pxRight, pxBottom, pxBottomRight)
opCue.forEach {
if (pixmap.getPixel(it.first, it.second) and 0xFF == 0) {
pixmap.drawPixel(it.first, it.second,
// the shadow has the same colour, but alpha halved
pxNow.and(0xFFFFFF00.toInt()).or(0x7F)
)
}
}
}
}
}
}
/** High surrogate comes before the low. */
private fun Char.isHighSurrogate() = (this.toInt() in 0xD800..0xDBFF)
/** CodePoint = 0x10000 + (H - 0xD800) * 0x400 + (L - 0xDC00) */

View File

@@ -0,0 +1,73 @@
package net.torvald.terrarumsansbitmap.gdx
import com.badlogic.gdx.files.FileHandle
import com.badlogic.gdx.graphics.Pixmap
/**
* Created by minjaesong on 2018-09-17.
*/
class PixmapRegionPack(
pixmap: Pixmap,
val tileW: Int,
val tileH: Int,
val hGap: Int = 0,
val vGap: Int = 0,
val hFrame: Int = 0,
val vFrame: Int = 0,
val xySwapped: Boolean = false // because Unicode chart does, duh
) {
//constructor(ref: String, tileW: Int, tileH: Int, hGap: Int = 0, vGap: Int = 0, hFrame: Int = 0, vFrame: Int = 0, xySwapped: Boolean = false) :
// this(Pixmap(ref), tileW, tileH, hGap, vGap, hFrame, vFrame, xySwapped)
constructor(fileHandle: FileHandle, tileW: Int, tileH: Int, hGap: Int = 0, vGap: Int = 0, hFrame: Int = 0, vFrame: Int = 0, xySwapped: Boolean = false) :
this(Pixmap(fileHandle), tileW, tileH, hGap, vGap, hFrame, vFrame, xySwapped)
val horizontalCount = (pixmap.width - 2 * hFrame + hGap) / (tileW + hGap)
val verticalCount = (pixmap.height - 2 * vFrame + vGap) / (tileH + vGap)
val regions: Array<Pixmap>
init {
if (!xySwapped) {
regions = Array<Pixmap>(horizontalCount * verticalCount, {
val region = Pixmap(tileW, tileH, Pixmap.Format.RGBA8888)
val rx = (it % horizontalCount * (tileW + hGap)) + hFrame
val ry = (it / horizontalCount * (tileH + vGap)) + vFrame
region.drawPixmap(pixmap, 0, 0,
rx * (tileW + hGap),
ry * (tileH + vGap),
tileW, tileH
)
// todo globalFlipY ?
/*return*/region
})
}
else {
regions = Array<Pixmap>(horizontalCount * verticalCount, {
val region = Pixmap(tileW, tileH, Pixmap.Format.RGBA8888)
val rx = (it / verticalCount * (tileW + hGap)) + hFrame
val ry = (it % verticalCount * (tileH + vGap)) + vFrame
region.drawPixmap(pixmap, 0, 0,
rx * (tileW + hGap),
ry * (tileH + vGap),
tileW, tileH
)
// todo globalFlipY ?
/*return*/region
})
}
}
fun get(x: Int, y: Int) = regions[y * horizontalCount + x]
fun dispose() {
regions.forEach { it.dispose() }
}
}