diff --git a/.idea/libraries/GdxLib.xml b/.idea/libraries/GdxLib.xml
index 09fa810..d597db0 100644
--- a/.idea/libraries/GdxLib.xml
+++ b/.idea/libraries/GdxLib.xml
@@ -9,6 +9,7 @@
+
diff --git a/.idea/workspace.xml b/.idea/workspace.xml
index 932e925..43c4a58 100644
--- a/.idea/workspace.xml
+++ b/.idea/workspace.xml
@@ -7,9 +7,11 @@
+
+
-
+
@@ -30,8 +32,8 @@
-
-
+
+
@@ -79,16 +81,16 @@
-
+
-
+
-
-
+
+
@@ -115,8 +117,8 @@
-
-
+
+
@@ -161,7 +163,6 @@
- buildWidthTable
lastNonDiacriticChar
c.toInt()
har.toInt()
@@ -191,6 +192,7 @@
xySw
getWidth
getWidthOfCharSeq
+ makeShadow
.141
@@ -216,19 +218,19 @@
-
+
-
-
+
+
-
+
@@ -282,7 +284,7 @@
-
+
@@ -501,11 +503,11 @@
-
+
-
+
@@ -513,11 +515,11 @@
-
+
-
+
@@ -564,25 +566,6 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
@@ -876,18 +859,6 @@
-
-
-
-
-
-
-
-
-
-
-
-
@@ -912,6 +883,43 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
@@ -922,13 +930,10 @@
-
-
-
-
-
+
+
diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md
index ec31684..11bacee 100644
--- a/CONTRIBUTING.md
+++ b/CONTRIBUTING.md
@@ -93,6 +93,7 @@ Also note that the font compiler will not "stack" these diacritics.
- Each spritesheet is 4096x4096 maximum, which is a size of 4K Texture. However it is recommended to be smaller or equal to 1024x1024.
- Glyphs exceeding 15px of width needs to be broken down with 2 or more characters. Wider sheets WILL NOT BE IMPLEMENTED, can't waste much pixels just for few superwide glyphs.
+- Due to how the compiler is coded, actual glyph must have alpha value of 255, the tags must have alpha values LESS THAN 255 (and obviously greater than zero). RGB plane of the TGA image doesn't do anything, keep it as #FFFFFF white.
### Implementing the Korean writing system
diff --git a/FontTestGDX/lib/TerrarumSansBitmap.jar b/FontTestGDX/lib/TerrarumSansBitmap.jar
index 38021e1..608f546 100644
Binary files a/FontTestGDX/lib/TerrarumSansBitmap.jar and b/FontTestGDX/lib/TerrarumSansBitmap.jar differ
diff --git a/demo.PNG b/demo.PNG
index a58b490..bb6b76a 100644
Binary files a/demo.PNG and b/demo.PNG differ
diff --git a/src/net/torvald/terrarumsansbitmap/gdx/GameFontBase.kt b/src/net/torvald/terrarumsansbitmap/gdx/GameFontBase.kt
index 652cea6..8a0a75e 100644
--- a/src/net/torvald/terrarumsansbitmap/gdx/GameFontBase.kt
+++ b/src/net/torvald/terrarumsansbitmap/gdx/GameFontBase.kt
@@ -460,11 +460,15 @@ class GameFontBase(fontDir: String, val noShadow: Boolean = false, val flipY: Bo
}
}
-
if (isVariable) buildWidthTable(pixmap, codeRange[index], 16)
buildWidthTableFixed()
+ if (!noShadow) {
+ makeShadow(pixmap)
+ }
+
+
val texture = Texture(pixmap)
val texRegPack = if (isVariable) {
TextureRegionPack(texture, W_VAR_INIT, H, HGAP_VAR, 0, xySwapped = isXYSwapped)
@@ -576,7 +580,6 @@ class GameFontBase(fontDir: String, val noShadow: Boolean = false, val flipY: Bo
originalColour = batch.color.cpy()
var mainCol = originalColour
- var shadowCol = mainCol.cpy().mul(0.5f, 0.5f, 0.5f, 1f)
//textTexture.begin()
@@ -586,136 +589,81 @@ class GameFontBase(fontDir: String, val noShadow: Boolean = false, val flipY: Bo
//println()
- val runs = if (noShadow) 0..0 else 3 downTo 0
- for (run in runs) { // 0: Main, 1..3: Shadows
- resetHash()
- var index = 0
- while (index <= textBuffer.lastIndex) {
- val c = textBuffer[index]
- val sheetID = getSheetType(c)
- val (sheetX, sheetY) =
- if (index == 0) getSheetwisePosition(0, c)
- else getSheetwisePosition(textBuffer[index - 1], c)
- val hash = getHash(c)
-
- if (run == 0) {
- //println("[TerrarumSansBitmap] sprite: $sheetID:${sheetX}x${sheetY}")
- }
-
-
- if (isColourCode(c)) {
- if (c == 0x100000) {
- mainCol = originalColour
- shadowCol = mainCol.cpy().mul(0.5f, 0.5f, 0.5f, 1f)
- }
- else {
- mainCol = getColour(c)
- shadowCol = mainCol.cpy().mul(0.5f, 0.5f, 0.5f, 1f)
- }
- }
- else if (isCharsetOverride(c)) {
- charsetOverride = c - CHARSET_OVERRIDE_DEFAULT
- }
- else if (sheetID == SHEET_HANGUL) {
- // Flookahead for {I, P, F}
-
- val cNext = if (index + 1 < textBuffer.size) textBuffer[index + 1] else 0
- val cNextNext = if (index + 2 < textBuffer.size) textBuffer[index + 2] else 0
-
- val hangulLength = if (isHangulJongseong(cNextNext) && isHangulJungseong(cNext))
- 3
- else if (isHangulJungseong(cNext))
- 2
- else
- 1
-
- val (indices, rows) = toHangulIndexAndRow(c, cNext, cNextNext)
-
- val (indexCho, indexJung, indexJong) = indices
- val (choRow, jungRow, jongRow) = rows
- val hangulSheet = sheets[SHEET_HANGUL]
-
-
- //println("${c.toHex()} ${cNext.toHex()} ${cNextNext.toHex()}")
- //println("I: $indexCho,\t$choRow")
- //println("P: $indexJung,\t$jungRow")
- //println("F: $indexJong,\t$jongRow")
- //println("skip: $hangulLength")
- //println("====")
-
-
- when (run) {
- 0 -> {
- 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)
- }
- 1 -> {
- batch.color = shadowCol
- batch.draw(hangulSheet.get(indexCho, choRow), x + posXbuffer[index] + 1, y)
- batch.draw(hangulSheet.get(indexJung, jungRow), x + posXbuffer[index] + 1, y)
- batch.draw(hangulSheet.get(indexJong, jongRow), x + posXbuffer[index] + 1, y)
- }
- 2 -> {
- batch.color = shadowCol
- batch.draw(hangulSheet.get(indexCho, choRow), x + posXbuffer[index], y + 1.flipY())
- batch.draw(hangulSheet.get(indexJung, jungRow), x + posXbuffer[index], y + 1.flipY())
- batch.draw(hangulSheet.get(indexJong, jongRow), x + posXbuffer[index], y + 1.flipY())
- }
- 3 -> {
- batch.color = shadowCol
- batch.draw(hangulSheet.get(indexCho, choRow), x + posXbuffer[index] + 1, y + 1.flipY())
- batch.draw(hangulSheet.get(indexJung, jungRow), x + posXbuffer[index] + 1, y + 1.flipY())
- batch.draw(hangulSheet.get(indexJong, jongRow), x + posXbuffer[index] + 1, y + 1.flipY())
-
- }
- }
-
-
- index += hangulLength - 1
+ resetHash()
+ var index = 0
+ while (index <= textBuffer.lastIndex) {
+ val c = textBuffer[index]
+ val sheetID = getSheetType(c)
+ val (sheetX, sheetY) =
+ if (index == 0) getSheetwisePosition(0, c)
+ else getSheetwisePosition(textBuffer[index - 1], c)
+ val hash = getHash(c)
+ if (isColourCode(c)) {
+ if (c == 0x100000) {
+ mainCol = originalColour
}
else {
- try {
-
- val posY = y + 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 texture = sheets[sheetID].get(sheetX, sheetY)
-
- when (run) {
- 0 -> {
- batch.color = mainCol
- batch.draw(texture, posX, posY)
- }
- 1 -> {
- batch.color = shadowCol
- batch.draw(texture, posX + 1, posY)
- }
- 2 -> {
- batch.color = shadowCol
- batch.draw(texture, posX, posY + 1.flipY())
- }
- 3 -> {
- batch.color = shadowCol
- batch.draw(texture, posX + 1, posY + 1.flipY())
- }
- }
- }
- catch (noSuchGlyph: ArrayIndexOutOfBoundsException) {
- batch.color = mainCol
- }
+ mainCol = getColour(c)
}
-
-
- index++
}
+ else if (isCharsetOverride(c)) {
+ charsetOverride = c - CHARSET_OVERRIDE_DEFAULT
+ }
+ else if (sheetID == SHEET_HANGUL) {
+ // Flookahead for {I, P, F}
+
+ val cNext = if (index + 1 < textBuffer.size) textBuffer[index + 1] else 0
+ val cNextNext = if (index + 2 < textBuffer.size) textBuffer[index + 2] else 0
+
+ val hangulLength = if (isHangulJongseong(cNextNext) && isHangulJungseong(cNext))
+ 3
+ else if (isHangulJungseong(cNext))
+ 2
+ else
+ 1
+
+ val (indices, rows) = toHangulIndexAndRow(c, cNext, cNextNext)
+
+ val (indexCho, indexJung, indexJong) = indices
+ val (choRow, jungRow, jongRow) = rows
+ val hangulSheet = sheets[SHEET_HANGUL]
+
+
+
+ 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)
+
+
+ index += hangulLength - 1
+
+ }
+ else {
+ try {
+
+ val posY = y + 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 texture = sheets[sheetID].get(sheetX, sheetY)
+
+ batch.color = mainCol
+ batch.draw(texture, posX, posY)
+
+ }
+ catch (noSuchGlyph: ArrayIndexOutOfBoundsException) {
+ batch.color = mainCol
+ }
+ }
+
+
+ index++
}
/*textTexture.end()
@@ -1321,6 +1269,46 @@ class GameFontBase(fontDir: String, val noShadow: Boolean = false, val flipY: Bo
}
+ /**
+ * Edits the given pixmap so that it would have a shadow on it.
+ *
+ * This function must be called `AFTER buildWidthTable()`
+ *
+ * The pixmap must be mutable (beware of concurrentmodificationexception).
+ */
+ private fun makeShadow(pixmap: Pixmap) {
+
+
+ for (y in 0..pixmap.height - 2) {
+ for (x in 0..pixmap.width - 2) {
+ val pxNow = pixmap.getPixel(x, y) // RGBA8888
+
+ // if you have read CONTRIBUTING.md, it says the actual glyph part MUST HAVE alpha of 255.
+ // but some of the older spritesheets still have width tag drawn as alpha of 255.
+ // therefore we still skip every x+15th pixels
+
+ if (x % 16 != 15) {
+ 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) */