new tagging system

This commit is contained in:
minjaesong
2021-11-25 16:46:22 +09:00
parent 4f6584ac27
commit 8641c95169
10 changed files with 194 additions and 113 deletions

View File

@@ -50,17 +50,53 @@ Rightmost vertical column (should be 20 px tall) contains the tags. Tags are def
K -,
K |= Tags used by the "Keming Machine"
K |
K -' ,-Nudging control bit (see below)
N --'
X -, write-on-top and centre-aligned: Align to this X pos of prev char
X | (if this is zero, floorOf(width/2) will be used instead)
X | NOT write-on-top: nudge the texture by this pixels to the
X -' left (if N is unset) or right (if N is set)
K -' ,- Nudging Bits (see below)
n --'
X -,
X |= Diacritics Anchor Points (see below)
X |
X -'
A -,_ 0 Align 1 Align 0 Align 1 Align before
A -' 0 left 0 right 1 centre 1 the glyph
D --write-on-top, usually it's diatritics but not always (e.g. devanagari vowel sign O)
S -,_ 0 Stack 1 Stack 0 Before 1 Up &
(MSB) S -' 0 up 0 down 1 &After 1 Down (e.g. U+0C48)
TODO:
c - Nudging
Y - Anchor point Y for undefined, undefined, undefined
X - Anchor point X for undefined, undefined, undefined
Y - Anchor point Y for centre-aligned diacritics, undefined, undefined
X - Anchor point X for centre-aligned diacritics, undefined, undefined
* Nudging Bits encoding:
<MSB,Red> SXXXXXXX SYYYYYYY 00000000 <LSB,Blue>
Each X and Y numbers are Signed 8-Bit Integer.
X-positive: nudges towards left
Y-positive: nudges towards up
* Diacritics Anchor Point Encoding:
<MSB,Red> 1Y1Y1Y1Y 1Y2Y2Y2Y 1Y3Y3Y3Y <LSB,Blue>
<MSB,Red> 1X1X1X1X 1X2X2X2X 1X3X3X3X <LSB,Blue>
where Red is first, Green is second, Blue is the third diacritics.
MSB for each word must be set to indicate the value is being used.
-= NOTE =-
This encoding involves one HACK: using 0th diacritics' X-anchor pos as a type selector
This hack applies only when write-on-top bit is set.
Interpretation:
DIA_OVERLAY = 1
DIA_JOINER = 2
Right now, only the type-0 diacritics anchor point is used by the font.
TODO: use D-bit to give each diacritic a type
```
#### Stack Up/Down

Binary file not shown.

Before

Width:  |  Height:  |  Size: 320 KiB

After

Width:  |  Height:  |  Size: 320 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 140 KiB

After

Width:  |  Height:  |  Size: 140 KiB

BIN
demo.PNG

Binary file not shown.

Before

Width:  |  Height:  |  Size: 142 KiB

After

Width:  |  Height:  |  Size: 142 KiB

View File

@@ -1,22 +1,35 @@
package net.torvald.terrarumsansbitmap
/**
* Created by minjaesong on 2021-11-25.
*/
data class DiacriticsAnchor(val type: Int, val x: Int, val y: Int, val xUsed: Boolean, val yUsed: Boolean)
/**
* Created by minjaesong on 2018-08-07.
*/
data class GlyphProps(
val width: Int,
val writeOnTop: Boolean,
val alignWhere: Int, // ALIGN_LEFT..ALIGN_BEFORE
val alignXPos: Int, // 0..15 or DIA_OVERLAY/DIA_JOINER depends on the context
val rtl: Boolean = false,
val isLowheight: Boolean = false,
val nudgeX: Int = 0,
val nudgeY: Int = 0,
val diacriticsAnchors: Array<DiacriticsAnchor> = Array(6) { DiacriticsAnchor(it, 0, 0, false, false) },
val alignWhere: Int = 0, // ALIGN_LEFT..ALIGN_BEFORE
val writeOnTop: Boolean = false,
val stackWhere: Int = 0, // STACK_UP..STACK_UP_N_DOWN
var nudgeRight: Boolean = false,
var extInfo: IntArray? = null,
val extInfo: IntArray = DEFAULT_EXTINFO,
val hasKernData: Boolean = false,
val isLowheight: Boolean = false,
val isKernYtype: Boolean = false,
val kerningMask: Int = 255
val kerningMask: Int = 255,
val rtl: Boolean = false,
) {
companion object {
const val ALIGN_LEFT = 0
@@ -33,9 +46,11 @@ data class GlyphProps(
const val DIA_JOINER = 2
private fun Boolean.toInt() = if (this) 1 else 0
val DEFAULT_EXTINFO = IntArray(15)
}
constructor(width: Int, tags: Int) : this(
/*constructor(width: Int, tags: Int) : this(
width,
tags.ushr(7).and(1) == 1,
tags.ushr(5).and(3),
@@ -59,21 +74,30 @@ data class GlyphProps(
isLowheight,
isKernYtype,
kerningMask
)
)*/
fun isOverlay() = writeOnTop && alignXPos == 1
// fun isOverlay() = writeOnTop && alignXPos == 1
override fun hashCode(): Int {
val tags = rtl.toInt() or alignXPos.shl(1) or alignWhere.shl(5) or
val tags = rtl.toInt() or alignWhere.shl(5) or
writeOnTop.toInt().shl(7) or stackWhere.shl(8)
var hash = -2128831034
extInfo?.forEach {
extInfo.forEach {
hash = hash xor it
hash = hash * 16777619
}
diacriticsAnchors.forEach {
hash = hash xor it.type
hash = hash * 16777619
hash = hash xor (it.x or (if (it.xUsed) 128 else 0))
hash = hash * 16777619
hash = hash xor (it.y or (if (it.yUsed) 128 else 0))
hash = hash * 16777619
}
hash = hash xor tags
hash = hash * 167677619

View File

@@ -30,6 +30,7 @@ import com.badlogic.gdx.graphics.Pixmap
import com.badlogic.gdx.graphics.Texture
import com.badlogic.gdx.graphics.g2d.*
import com.badlogic.gdx.utils.GdxRuntimeException
import net.torvald.terrarumsansbitmap.DiacriticsAnchor
import net.torvald.terrarumsansbitmap.GlyphProps
import java.io.BufferedOutputStream
import java.io.FileOutputStream
@@ -302,7 +303,7 @@ class TerrarumSansBitmap(
// make sure null char is actually null (draws nothing and has zero width)
sheets[SHEET_ASCII_VARW].regions[0].setColor(0)
sheets[SHEET_ASCII_VARW].regions[0].fill()
glyphProps[0] = GlyphProps(0, 0)
glyphProps[0] = GlyphProps(0)
}
override fun getLineHeight(): Float = H.toFloat()
@@ -331,7 +332,7 @@ class TerrarumSansBitmap(
private lateinit var tempLinotype: Texture
private var nullProp = GlyphProps(15, 0)
private var nullProp = GlyphProps(15)
private val pixmapOffsetY = 10
@@ -342,6 +343,8 @@ class TerrarumSansBitmap(
fun drawNormalised(batch: Batch, codepoints: CodepointSequence, x: Float, y: Float): GlyphLayout? {
// codepoints.forEach { dbgprn("${it.charInfo()} ${glyphProps[it]}") }
// Q&D fix for issue #12
// When the line ends with a diacritics, the whole letter won't render
// If the line starts with a letter-with-diacritic, it will error out
@@ -696,6 +699,9 @@ class TerrarumSansBitmap(
return intArrayOf(sheetX, sheetY)
}
private fun Boolean.toInt() = if (this) 1 else 0
private fun Int.tagify() = if (this and 255 == 0) 0 else this
private fun buildWidthTable(pixmap: Pixmap, codeRange: Iterable<Int>, cols: Int = 16) {
val binaryCodeOffset = W_VAR_INIT
@@ -709,64 +715,63 @@ class TerrarumSansBitmap(
val codeStartX = cellX + binaryCodeOffset
val codeStartY = cellY
val tagStartY = codeStartY + 10
var width = 0
var tags = 0
for (y in 0..4) {
// if ALPHA is not zero, assume it's 1
if (pixmap.getPixel(codeStartX, codeStartY + y).and(0xFF) != 0) {
width = width or (1 shl y)
}
}
for (y in 0..9) {
// if ALPHA is not zero, assume it's 1
if (pixmap.getPixel(codeStartX, tagStartY + y).and(0xFF) != 0) {
tags = tags or (1 shl y)
}
}
// lowheight bit
val isLowHeight = (pixmap.getPixel(codeStartX, codeStartY + 5).and(0xFF) != 0)
val width = (0..4).fold(0) { acc, y -> acc or ((pixmap.getPixel(codeStartX, codeStartY + y).and(255) != 0).toInt() shl y) }
val isLowHeight = (pixmap.getPixel(codeStartX, codeStartY + 5).and(255) != 0)
// Keming machine parameters
val kerningBit1 = pixmap.getPixel(codeStartX, codeStartY + 6)
val kerningBit2 = pixmap.getPixel(codeStartX, codeStartY + 7)
val kerningBit3 = pixmap.getPixel(codeStartX, codeStartY + 8)
val isKerningYtype = ((kerningBit1 and 0x80000000.toInt()) != 0)
val kerningMask = kerningBit1.ushr(8).and(0xFFFFFF)
val hasKerningBit = kerningBit1 and 255 != 0//(kerningBit1 and 255 != 0 && kerningMask != 0xFFFF)
val kerningBit1 = pixmap.getPixel(codeStartX, codeStartY + 6).tagify()
val kerningBit2 = pixmap.getPixel(codeStartX, codeStartY + 7).tagify()
val kerningBit3 = pixmap.getPixel(codeStartX, codeStartY + 8).tagify()
val kerningBit4 = pixmap.getPixel(codeStartX, codeStartY + 9).tagify()
var isKernYtype = ((kerningBit1 and 0x80000000.toInt()) != 0)
var kerningMask = kerningBit1.ushr(8).and(0xFFFFFF)
val hasKernData = kerningBit1 and 255 != 0//(kerningBit1 and 255 != 0 && kerningMask != 0xFFFF)
if (!hasKernData) {
isKernYtype = false
kerningMask = 255
}
val nudgingBits = pixmap.getPixel(codeStartX, codeStartY + 10).tagify()
val nudgeX = nudgingBits.ushr(24).toByte().toInt() // signed 8-bit int
val nudgeY = nudgingBits.ushr(16).toByte().toInt() // signed 8-bit int
//dbgprn("$code: Width $width, tags $tags")
if (hasKerningBit)
dbgprn("U+${code.toString(16).padStart(4, '0').toUpperCase()}: W $width, tags $tags, low? $isLowHeight, kern ${kerningMask.toString(16).padStart(6,'0')} (raw: ${kerningBit1.toLong().and(4294967295).toString(16).padStart(8,'0')})")
val diacriticsAnchors = (0..5).map {
val yPos = 11 + (it / 3) * 2
val shift = (3 - (it % 3)) * 8
val yPixel = pixmap.getPixel(codeStartX, codeStartY + yPos).tagify()
val xPixel = pixmap.getPixel(codeStartX, codeStartY + yPos + 1).tagify()
val y = (yPixel ushr shift) and 127
val x = (xPixel ushr shift) and 127
val yUsed = (yPixel ushr shift) >= 128
val xUsed = (yPixel ushr shift) >= 128
/*val isDiacritics = pixmap.getPixel(codeStartX, codeStartY + H - 1).and(0xFF) != 0
if (isDiacritics)
glyphWidth = -glyphWidth*/
DiacriticsAnchor(it, x, y, xUsed, yUsed)
}.toTypedArray()
glyphProps[code] = if (hasKerningBit) GlyphProps(width, tags, isLowHeight, isKerningYtype, kerningMask) else GlyphProps(width, tags)
val alignWhere = (0..1).fold(0) { acc, y -> acc or ((pixmap.getPixel(codeStartX, codeStartY + y + 15).and(255) != 0).toInt() shl y) }
val writeOnTop = pixmap.getPixel(codeStartX, codeStartY + 17).and(255) != 0
val stackWhere = (0..1).fold(0) { acc, y -> acc or ((pixmap.getPixel(codeStartX, codeStartY + y + 18).and(255) != 0).toInt() shl y) }
glyphProps[code] = GlyphProps(width, isLowHeight, nudgeX, nudgeY, diacriticsAnchors, alignWhere, writeOnTop, stackWhere, GlyphProps.DEFAULT_EXTINFO, hasKernData, isKernYtype, kerningMask)
// if (nudgingBits != 0) dbgprn("${code.charInfo()} nudgeX=$nudgeX, nudgeY=$nudgeY, nudgingBits=0x${nudgingBits.toString(16)}")
// extra info
val extCount = glyphProps[code]?.requiredExtInfoCount() ?: 0
if (extCount > 0) {
glyphProps[code]?.extInfo = IntArray(extCount)
for (x in 0 until extCount) {
var info = 0
for (y in 0..18) {
// if ALPHA is not zero, assume it's 1
if (pixmap.getPixel(cellX + x, cellY + y).and(0xFF) != 0) {
if (pixmap.getPixel(cellX + x, cellY + y).and(255) != 0) {
info = info or (1 shl y)
}
}
glyphProps[code]!!.extInfo!![x] = info
glyphProps[code]!!.extInfo[x] = info
}
}
@@ -775,27 +780,27 @@ class TerrarumSansBitmap(
private fun buildWidthTableFixed() {
// fixed-width props
codeRange[SHEET_CJK_PUNCT].forEach { glyphProps[it] = GlyphProps(W_ASIAN_PUNCT, 0) }
codeRange[SHEET_CUSTOM_SYM].forEach { glyphProps[it] = GlyphProps(20, 0) }
codeRange[SHEET_FW_UNI].forEach { glyphProps[it] = GlyphProps(W_UNIHAN, 0) }
codeRange[SHEET_HANGUL].forEach { glyphProps[it] = GlyphProps(W_HANGUL_BASE, 0) }
codeRangeHangulCompat.forEach { glyphProps[it] = GlyphProps(W_HANGUL_BASE, 0) }
codeRange[SHEET_KANA].forEach { glyphProps[it] = GlyphProps(W_KANA, 0) }
codeRange[SHEET_RUNIC].forEach { glyphProps[it] = GlyphProps(9, 0) }
codeRange[SHEET_UNIHAN].forEach { glyphProps[it] = GlyphProps(W_UNIHAN, 0) }
(0xD800..0xDFFF).forEach { glyphProps[it] = GlyphProps(0, 0) }
(0x100000..0x10FFFF).forEach { glyphProps[it] = GlyphProps(0, 0) }
(0xFFFA0..0xFFFFF).forEach { glyphProps[it] = GlyphProps(0, 0) }
codeRange[SHEET_CJK_PUNCT].forEach { glyphProps[it] = GlyphProps(W_ASIAN_PUNCT) }
codeRange[SHEET_CUSTOM_SYM].forEach { glyphProps[it] = GlyphProps(20) }
codeRange[SHEET_FW_UNI].forEach { glyphProps[it] = GlyphProps(W_UNIHAN) }
codeRange[SHEET_HANGUL].forEach { glyphProps[it] = GlyphProps(W_HANGUL_BASE) }
codeRangeHangulCompat.forEach { glyphProps[it] = GlyphProps(W_HANGUL_BASE) }
codeRange[SHEET_KANA].forEach { glyphProps[it] = GlyphProps(W_KANA) }
codeRange[SHEET_RUNIC].forEach { glyphProps[it] = GlyphProps(9) }
codeRange[SHEET_UNIHAN].forEach { glyphProps[it] = GlyphProps(W_UNIHAN) }
(0xD800..0xDFFF).forEach { glyphProps[it] = GlyphProps(0) }
(0x100000..0x10FFFF).forEach { glyphProps[it] = GlyphProps(0) }
(0xFFFA0..0xFFFFF).forEach { glyphProps[it] = GlyphProps(0) }
// manually add width of one orphan insular letter
// WARNING: glyphs in 0xA770..0xA778 has invalid data, further care is required
glyphProps[0x1D79] = GlyphProps(9, 0)
glyphProps[0x1D79] = GlyphProps(9)
// U+007F is DEL originally, but this font stores bitmap of Replacement Character (U+FFFD)
// to this position. String replacer will replace U+FFFD into U+007F.
glyphProps[0x7F] = GlyphProps(15, 0)
glyphProps[0x7F] = GlyphProps(15)
}
@@ -884,7 +889,7 @@ class TerrarumSansBitmap(
posXbuffer[charIndex] = posXbuffer[nonDiacriticCounter]
}
else if (!thisProp.writeOnTop) {
posXbuffer[charIndex] = ((if (thisProp.nudgeRight) 1 else -1) * thisProp.alignXPos) +
posXbuffer[charIndex] = -thisProp.nudgeX +
when (itsProp.alignWhere) {
GlyphProps.ALIGN_RIGHT ->
posXbuffer[nonDiacriticCounter] + W_VAR_INIT + alignmentOffset + interchar + kerning + extraWidth
@@ -898,9 +903,10 @@ class TerrarumSansBitmap(
stackUpwardCounter = 0
stackDownwardCounter = 0
extraWidth = (if (thisProp.nudgeRight) -1 else 1) * thisProp.alignXPos // NOTE: sign is flipped!
extraWidth = thisProp.nudgeX // NOTE: sign is flipped!
}
else if (thisProp.writeOnTop && thisProp.alignXPos == GlyphProps.DIA_JOINER) {
// FIXME HACK: using 0th diacritics' X-anchor pos as a type selector
else if (thisProp.writeOnTop && thisProp.diacriticsAnchors[0].x == GlyphProps.DIA_JOINER) {
posXbuffer[charIndex] = when (itsProp.alignWhere) {
GlyphProps.ALIGN_RIGHT ->
posXbuffer[nonDiacriticCounter] + W_VAR_INIT + alignmentOffset
@@ -919,7 +925,7 @@ class TerrarumSansBitmap(
posXbuffer[nonDiacriticCounter] - (W_VAR_INIT - itsProp.width)
}
GlyphProps.ALIGN_CENTRE -> {
val alignXPos = if (itsProp.alignXPos == 0) itsProp.width.div(2) else itsProp.alignXPos
val alignXPos = if (itsProp.diacriticsAnchors[0].x == 0) itsProp.width.div(2) else itsProp.diacriticsAnchors[0].x
if (itsProp.alignWhere == GlyphProps.ALIGN_RIGHT) {
posXbuffer[nonDiacriticCounter] + alignXPos + (itsProp.width + 1).div(2)
@@ -948,7 +954,7 @@ class TerrarumSansBitmap(
//dbgprn("AAARRRRHHHH for character ${thisChar.toHex()}")
//dbgprn("lastNonDiacriticChar: ${lastNonDiacriticChar.toHex()}")
//dbgprn("cond: ${thisProp.alignXPos == GlyphProps.DIA_OVERLAY}, charIndex: $charIndex")
if (thisProp.alignXPos == GlyphProps.DIA_OVERLAY)
if (thisProp.diacriticsAnchors[0].x == GlyphProps.DIA_OVERLAY)
posYbuffer[charIndex] -= H_OVERLAY_LOWERCASE_SHIFTDOWN * (!flipY).toSign() // if minus-assign doesn't work, try plus-assign
else
posYbuffer[charIndex] -= H_STACKUP_LOWERCASE_SHIFTDOWN * (!flipY).toSign() // if minus-assign doesn't work, try plus-assign
@@ -978,10 +984,10 @@ class TerrarumSansBitmap(
posXbuffer[posXbuffer.lastIndex] = 1 + posXbuffer[posXbuffer.lastIndex - 1] + // adding 1 to house the shadow
if (lastCharProp?.writeOnTop == true) {
val realDiacriticWidth = if (lastCharProp.alignWhere == GlyphProps.ALIGN_CENTRE) {
(lastCharProp.width).div(2) + penultCharProp.alignXPos
(lastCharProp.width).div(2) + penultCharProp.diacriticsAnchors[0].x
}
else if (lastCharProp.alignWhere == GlyphProps.ALIGN_RIGHT) {
(lastCharProp.width) + penultCharProp.alignXPos
(lastCharProp.width) + penultCharProp.diacriticsAnchors[0].x
}
else 0

View File

@@ -7,6 +7,7 @@ import com.badlogic.gdx.graphics.g2d.Batch
import com.badlogic.gdx.graphics.g2d.BitmapFont
import com.badlogic.gdx.graphics.g2d.GlyphLayout
import com.badlogic.gdx.utils.GdxRuntimeException
import net.torvald.terrarumsansbitmap.DiacriticsAnchor
import net.torvald.terrarumsansbitmap.GlyphProps
import net.torvald.terrarumsansbitmap.gdx.*
import net.torvald.terrarumsansbitmap.gdx.CodePoint
@@ -178,7 +179,7 @@ class TerrarumTypewriterBitmap(
pixmap.dispose() // you are terminated
}
glyphProps[0] = GlyphProps(0, 0)
glyphProps[0] = GlyphProps(0)
}
@@ -188,6 +189,8 @@ class TerrarumTypewriterBitmap(
intArrayOf(coff % 16, coff / 16)
}
private fun Boolean.toInt() = if (this) 1 else 0
private fun Int.tagify() = if (this and 255 == 0) 0 else this
private fun buildWidthTable(pixmap: Pixmap, codeRange: Iterable<Int>, cols: Int = 16) {
val binaryCodeOffset = TerrarumSansBitmap.W_VAR_INIT
@@ -202,53 +205,65 @@ class TerrarumTypewriterBitmap(
val codeStartX = cellX + binaryCodeOffset
val codeStartY = cellY
val tagStartY = codeStartY + 10
var width = 0
var tags = 0
val width = (0..4).fold(0) { acc, y -> acc or ((pixmap.getPixel(codeStartX, codeStartY + y).and(255) != 0).toInt() shl y) }
val isLowHeight = (pixmap.getPixel(codeStartX, codeStartY + 5).and(255) != 0)
for (y in 0..3) {
// if ALPHA is not zero, assume it's 1
if (pixmap.getPixel(codeStartX, codeStartY + y).and(0xFF) != 0) {
width = width or (1 shl y)
}
// Keming machine parameters
val kerningBit1 = pixmap.getPixel(codeStartX, codeStartY + 6).tagify()
val kerningBit2 = pixmap.getPixel(codeStartX, codeStartY + 7).tagify()
val kerningBit3 = pixmap.getPixel(codeStartX, codeStartY + 8).tagify()
val kerningBit4 = pixmap.getPixel(codeStartX, codeStartY + 9).tagify()
var isKernYtype = ((kerningBit1 and 0x80000000.toInt()) != 0)
var kerningMask = kerningBit1.ushr(8).and(0xFFFFFF)
val hasKernData = kerningBit1 and 255 != 0//(kerningBit1 and 255 != 0 && kerningMask != 0xFFFF)
if (!hasKernData) {
isKernYtype = false
kerningMask = 255
}
for (y in 0..9) {
// if ALPHA is not zero, assume it's 1
if (pixmap.getPixel(codeStartX, tagStartY + y).and(0xFF) != 0) {
tags = tags or (1 shl y)
}
}
val nudgingBits = pixmap.getPixel(codeStartX, codeStartY + 10).tagify()
val nudgeX = nudgingBits.ushr(16).toByte().toInt() // signed 8-bit int
val nudgeY = nudgingBits.ushr(8).toByte().toInt() // signed 8-bit int
if (code and 127 == 67) width *= -1 // the backspace key
if (debug) println("${code.charInfo()}: Width $width, tags $tags")
val diacriticsAnchors = (0..5).map {
val yPos = 11 + (it / 3)
val shift = (2 - (it % 3)) * 8
val yPixel = pixmap.getPixel(codeStartX, codeStartY + yPos).tagify()
val xPixel = pixmap.getPixel(codeStartX, codeStartY + yPos + 1).tagify()
val y = (yPixel ushr shift) and 127
val x = (xPixel ushr shift) and 127
val yUsed = (yPixel ushr shift) >= 128
val xUsed = (yPixel ushr shift) >= 128
/*val isDiacritics = pixmap.getPixel(codeStartX, codeStartY + H - 1).and(0xFF) != 0
if (isDiacritics)
glyphWidth = -glyphWidth*/
DiacriticsAnchor(it, x, y, xUsed, yUsed)
}.toTypedArray()
val alignWhere = (11..12).fold(0) { acc, y -> acc or ((pixmap.getPixel(codeStartX, codeStartY + y).and(255) != 0).toInt() shl y) }
glyphProps[code] = GlyphProps(width, tags)
val writeOnTop = pixmap.getPixel(codeStartX, codeStartY + 13).and(255) != 0
val stackWhere = (14..15).fold(0) { acc, y -> acc or ((pixmap.getPixel(codeStartX, codeStartY + y).and(255) != 0).toInt() shl y) }
glyphProps[code] = GlyphProps(width, isLowHeight, nudgeX, nudgeY, diacriticsAnchors, alignWhere, writeOnTop, stackWhere, GlyphProps.DEFAULT_EXTINFO, hasKernData, isKernYtype, kerningMask)
// if (code < 256) dbgprn("${code.charInfo()} width: $width, tags: ${glyphProps[code]}")
// extra info
val extCount = glyphProps[code]?.requiredExtInfoCount() ?: 0
if (extCount > 0) {
glyphProps[code]?.extInfo = IntArray(extCount)
for (x in 0 until extCount) {
var info = 0
for (y in 0..18) {
// if ALPHA is not zero, assume it's 1
if (pixmap.getPixel(cellX + x, cellY + y).and(0xFF) != 0) {
if (pixmap.getPixel(cellX + x, cellY + y).and(255) != 0) {
info = info or (1 shl y)
}
}
glyphProps[code]!!.extInfo!![x] = info
glyphProps[code]!!.extInfo[x] = info
}
}
}
}
@@ -257,7 +272,7 @@ class TerrarumTypewriterBitmap(
private var flagFirstRun = true
private var textBuffer = CodepointSequence(256)
private lateinit var tempLinotype: Texture
private var nullProp = GlyphProps(15, 0)
private var nullProp = GlyphProps(15)
fun draw(batch: Batch, codepoints: CodepointSequence, x: Float, y: Float): GlyphLayout? {
@@ -424,7 +439,7 @@ class TerrarumTypewriterBitmap(
if (!thisProp.writeOnTop) {
posXbuffer[charIndex] = ((if (thisProp.nudgeRight) 1 else -1) * thisProp.alignXPos) +
posXbuffer[charIndex] = thisProp.nudgeX +
when (itsProp.alignWhere) {
GlyphProps.ALIGN_RIGHT ->
posXbuffer[nonDiacriticCounter] + TerrarumSansBitmap.W_VAR_INIT + alignmentOffset + interchar + kerning + extraWidth
@@ -438,9 +453,9 @@ class TerrarumTypewriterBitmap(
stackUpwardCounter = 0
stackDownwardCounter = 0
extraWidth = (if (thisProp.nudgeRight) -1 else 1) * thisProp.alignXPos // NOTE: sign is flipped!
extraWidth = -thisProp.nudgeX // NOTE: sign is flipped!
}
else if (thisProp.writeOnTop && thisProp.alignXPos == GlyphProps.DIA_JOINER) {
else if (thisProp.writeOnTop && thisProp.diacriticsAnchors[0].x == GlyphProps.DIA_JOINER) {
posXbuffer[charIndex] = when (itsProp.alignWhere) {
GlyphProps.ALIGN_RIGHT ->
posXbuffer[nonDiacriticCounter] + TerrarumSansBitmap.W_VAR_INIT + alignmentOffset
@@ -459,7 +474,7 @@ class TerrarumTypewriterBitmap(
posXbuffer[nonDiacriticCounter] - (TerrarumSansBitmap.W_VAR_INIT - itsProp.width)
}
GlyphProps.ALIGN_CENTRE -> {
val alignXPos = if (itsProp.alignXPos == 0) itsProp.width.div(2) else itsProp.alignXPos
val alignXPos = if (itsProp.diacriticsAnchors[0].x == 0) itsProp.width.div(2) else itsProp.diacriticsAnchors[0].x
if (itsProp.alignWhere == GlyphProps.ALIGN_RIGHT) {
posXbuffer[nonDiacriticCounter] + alignXPos + (itsProp.width + 1).div(2)
@@ -516,10 +531,10 @@ class TerrarumTypewriterBitmap(
posXbuffer[posXbuffer.lastIndex] = 1 + posXbuffer[posXbuffer.lastIndex - 1] + // adding 1 to house the shadow
if (lastCharProp?.writeOnTop == true) {
val realDiacriticWidth = if (lastCharProp.alignWhere == GlyphProps.ALIGN_CENTRE) {
(lastCharProp.width).div(2) + penultCharProp.alignXPos
(lastCharProp.width).div(2) + penultCharProp.diacriticsAnchors[0].x
}
else if (lastCharProp.alignWhere == GlyphProps.ALIGN_RIGHT) {
(lastCharProp.width) + penultCharProp.alignXPos
(lastCharProp.width) + penultCharProp.diacriticsAnchors[0].x
}
else 0

Binary file not shown.

Before

Width:  |  Height:  |  Size: 20 KiB

After

Width:  |  Height:  |  Size: 20 KiB