mirror of
https://github.com/curioustorvald/Terrarum-sans-bitmap.git
synced 2026-03-14 23:16:08 +09:00
fixing up diacritics; complete unipunct
This commit is contained in:
@@ -9,7 +9,8 @@ data class GlyphProps(
|
||||
val alignWhere: Int,
|
||||
val alignXPos: Int,
|
||||
val rtl: Boolean = false,
|
||||
val stackWhere: Int = 0
|
||||
val stackWhere: Int = 0,
|
||||
var extInfo: IntArray? = null
|
||||
) {
|
||||
companion object {
|
||||
const val ALIGN_LEFT = 0
|
||||
@@ -24,6 +25,8 @@ data class GlyphProps(
|
||||
|
||||
const val DIA_OVERLAY = 1
|
||||
const val DIA_JOINER = 2
|
||||
|
||||
private fun Boolean.toInt() = if (this) 1 else 0
|
||||
}
|
||||
|
||||
constructor(width: Int, tags: Int) : this(
|
||||
@@ -36,4 +39,28 @@ data class GlyphProps(
|
||||
)
|
||||
|
||||
fun isOverlay() = writeOnTop && alignXPos == 1
|
||||
|
||||
override fun hashCode(): Int {
|
||||
val tags = rtl.toInt() or alignXPos.shl(1) or alignWhere.shl(5) or
|
||||
writeOnTop.toInt().shl(7) or stackWhere.shl(8)
|
||||
|
||||
var hash = -2128831034
|
||||
|
||||
extInfo?.forEach {
|
||||
hash = hash xor it
|
||||
hash = hash * 16777619
|
||||
}
|
||||
|
||||
hash = hash xor tags
|
||||
hash = hash * 167677619
|
||||
|
||||
return hash
|
||||
}
|
||||
|
||||
override fun equals(other: Any?): Boolean {
|
||||
// comparing hash because I'm lazy
|
||||
return other is GlyphProps && this.hashCode() == other.hashCode()
|
||||
}
|
||||
|
||||
fun requiredExtInfoCount() = if (stackWhere == STACK_BEFORE_N_AFTER) 2 else 0
|
||||
}
|
||||
@@ -31,7 +31,6 @@ import com.badlogic.gdx.graphics.Texture
|
||||
import com.badlogic.gdx.graphics.g2d.*
|
||||
import net.torvald.terrarumsansbitmap.GlyphProps
|
||||
import java.io.BufferedOutputStream
|
||||
import java.io.File
|
||||
import java.io.FileOutputStream
|
||||
import java.util.zip.GZIPInputStream
|
||||
|
||||
@@ -522,7 +521,9 @@ class GameFontBase(fontDir: String, val noShadow: Boolean = false, val flipY: Bo
|
||||
posXbuffer[nonDiacriticCounter] + W_VAR_INIT + alignmentOffset + interchar
|
||||
else
|
||||
posXbuffer[nonDiacriticCounter] + itsProp.width + alignmentOffset + interchar
|
||||
|
||||
nonDiacriticCounter = charIndex
|
||||
|
||||
stackUpwardCounter = 0
|
||||
stackDownwardCounter = 0
|
||||
}
|
||||
@@ -536,46 +537,53 @@ class GameFontBase(fontDir: String, val noShadow: Boolean = false, val flipY: Bo
|
||||
else {
|
||||
// set X pos according to alignment information
|
||||
posXbuffer[charIndex] = when (thisProp.alignWhere) {
|
||||
GlyphProps.ALIGN_LEFT -> posXbuffer[nonDiacriticCounter]
|
||||
GlyphProps.ALIGN_LEFT, GlyphProps.ALIGN_BEFORE -> posXbuffer[nonDiacriticCounter]
|
||||
GlyphProps.ALIGN_RIGHT -> {
|
||||
posXbuffer[nonDiacriticCounter] - (W_VAR_INIT - itsProp.width)
|
||||
}
|
||||
GlyphProps.ALIGN_CENTRE -> {
|
||||
val alignXPos = if (itsProp.alignXPos == 0) itsProp.width.div(2) else itsProp.alignXPos
|
||||
|
||||
posXbuffer[nonDiacriticCounter] + alignXPos - (W_VAR_INIT - 1).div(2)
|
||||
if (itsProp.alignWhere == GlyphProps.ALIGN_RIGHT) {
|
||||
posXbuffer[nonDiacriticCounter] + alignXPos + (itsProp.width + 1).div(2)
|
||||
}
|
||||
else {
|
||||
posXbuffer[nonDiacriticCounter] + alignXPos - (W_VAR_INIT - 1).div(2)
|
||||
}
|
||||
}
|
||||
else -> throw InternalError("Unsupported alignment: ${thisProp.alignWhere}")
|
||||
}
|
||||
|
||||
|
||||
// set Y pos according to diacritics position
|
||||
when (thisProp.stackWhere) {
|
||||
GlyphProps.STACK_DOWN -> {
|
||||
posYbuffer[charIndex] = H_DIACRITICS * stackDownwardCounter
|
||||
stackDownwardCounter++
|
||||
}
|
||||
GlyphProps.STACK_UP -> {
|
||||
posYbuffer[charIndex] = -H_DIACRITICS * stackUpwardCounter
|
||||
|
||||
// shift down on lowercase if applicable
|
||||
if (getSheetType(thisChar) in autoShiftDownOnLowercase &&
|
||||
lastNonDiacriticChar.isLowHeight()) {
|
||||
if (thisProp.alignXPos == GlyphProps.DIA_OVERLAY)
|
||||
posYbuffer[charIndex] += H_OVERLAY_LOWERCASE_SHIFTDOWN
|
||||
else
|
||||
posYbuffer[charIndex] += H_STACKUP_LOWERCASE_SHIFTDOWN
|
||||
if (thisProp.alignWhere == GlyphProps.ALIGN_CENTRE) {
|
||||
when (thisProp.stackWhere) {
|
||||
GlyphProps.STACK_DOWN -> {
|
||||
posYbuffer[charIndex] = H_DIACRITICS * stackDownwardCounter
|
||||
stackDownwardCounter++
|
||||
}
|
||||
GlyphProps.STACK_UP -> {
|
||||
posYbuffer[charIndex] = -H_DIACRITICS * stackUpwardCounter
|
||||
|
||||
stackUpwardCounter++
|
||||
}
|
||||
GlyphProps.STACK_UP_N_DOWN -> {
|
||||
posYbuffer[charIndex] = H_DIACRITICS * stackDownwardCounter
|
||||
stackDownwardCounter++
|
||||
posYbuffer[charIndex] = -H_DIACRITICS * stackUpwardCounter
|
||||
stackUpwardCounter++
|
||||
}
|
||||
// shift down on lowercase if applicable
|
||||
if (getSheetType(thisChar) in autoShiftDownOnLowercase &&
|
||||
lastNonDiacriticChar.isLowHeight()) {
|
||||
if (thisProp.alignXPos == GlyphProps.DIA_OVERLAY)
|
||||
posYbuffer[charIndex] += H_OVERLAY_LOWERCASE_SHIFTDOWN
|
||||
else
|
||||
posYbuffer[charIndex] += H_STACKUP_LOWERCASE_SHIFTDOWN
|
||||
}
|
||||
|
||||
stackUpwardCounter++
|
||||
}
|
||||
GlyphProps.STACK_UP_N_DOWN -> {
|
||||
posYbuffer[charIndex] = H_DIACRITICS * stackDownwardCounter
|
||||
stackDownwardCounter++
|
||||
posYbuffer[charIndex] = -H_DIACRITICS * stackUpwardCounter
|
||||
stackUpwardCounter++
|
||||
}
|
||||
// for BEFORE_N_AFTER, do nothing in here
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -972,6 +980,25 @@ class GameFontBase(fontDir: String, val noShadow: Boolean = false, val flipY: Bo
|
||||
glyphWidth = -glyphWidth*/
|
||||
|
||||
glyphProps[code] = GlyphProps(width, tags)
|
||||
|
||||
// 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) {
|
||||
info = info or (1 shl y)
|
||||
}
|
||||
}
|
||||
|
||||
glyphProps[code]!!.extInfo!![x] = info
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -998,7 +1025,9 @@ class GameFontBase(fontDir: String, val noShadow: Boolean = false, val flipY: Bo
|
||||
glyphProps[0x1D79] = GlyphProps(9, 0)
|
||||
|
||||
|
||||
glyphProps[0xFFFD] = nullProp
|
||||
// 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)
|
||||
}
|
||||
|
||||
private val glyphLayout = GlyphLayout()
|
||||
@@ -1021,15 +1050,34 @@ class GameFontBase(fontDir: String, val noShadow: Boolean = false, val flipY: Bo
|
||||
if (i < this.lastIndex && c.isHighSurrogate()) {
|
||||
val cNext = this[i + 1]
|
||||
|
||||
if (!cNext.isLowSurrogate())
|
||||
throw IllegalArgumentException("Malformed UTF-16 String: High surrogate must be paired with low surrogate")
|
||||
if (!cNext.isLowSurrogate()) {
|
||||
// replace with Unicode replacement char
|
||||
seq.add(0xFFFD)
|
||||
}
|
||||
else {
|
||||
val H = c
|
||||
val L = cNext
|
||||
|
||||
val H = c
|
||||
val L = cNext
|
||||
seq.add(Character.toCodePoint(H, L))
|
||||
|
||||
seq.add(Character.toCodePoint(H, L))
|
||||
|
||||
i++ // skip next char (guaranteed to be Low Surrogate)
|
||||
i++ // skip next char (guaranteed to be Low Surrogate)
|
||||
}
|
||||
}
|
||||
// rearrange {letter, before-and-after diacritics} as {letter, before-diacritics, after-diacritics}
|
||||
// {letter, before-diacritics} part will be dealt with swapping code below
|
||||
// DOES NOT WORK if said diacritics has codepoint > 0xFFFF
|
||||
else if (i < this.lastIndex && this[i + 1].toInt() <= 0xFFFF &&
|
||||
glyphProps[this[i + 1].toInt()]?.stackWhere == GlyphProps.STACK_BEFORE_N_AFTER) {
|
||||
val diacriticsProp = glyphProps[this[i + 1].toInt()]!!
|
||||
seq.add(c.toInt())
|
||||
seq.add(diacriticsProp.extInfo!![0])
|
||||
seq.add(diacriticsProp.extInfo!![1])
|
||||
i++
|
||||
}
|
||||
// U+007F is DEL originally, but this font stores bitmap of Replacement Character (U+FFFD)
|
||||
// to this position. This line will replace U+FFFD into U+007F.
|
||||
else if (c == '<27>') {
|
||||
seq.add(0x7F)
|
||||
}
|
||||
else {
|
||||
seq.add(c.toInt())
|
||||
@@ -1038,10 +1086,10 @@ class GameFontBase(fontDir: String, val noShadow: Boolean = false, val flipY: Bo
|
||||
i++
|
||||
}
|
||||
|
||||
|
||||
// swap position of {letter, diacritics that comes before the letter}
|
||||
i = 1
|
||||
while (i <= seq.lastIndex) {
|
||||
|
||||
if ((glyphProps[seq[i]] ?: nullProp).alignWhere == GlyphProps.ALIGN_BEFORE) {
|
||||
val t = seq[i - 1]
|
||||
seq[i - 1] = seq[i]
|
||||
@@ -1051,7 +1099,6 @@ class GameFontBase(fontDir: String, val noShadow: Boolean = false, val flipY: Bo
|
||||
i++
|
||||
}
|
||||
|
||||
|
||||
return seq
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user