mirror of
https://github.com/curioustorvald/Terrarum.git
synced 2026-06-11 11:04:05 +09:00
btex: fix: part typesetting with OBJ would not get centred correctly
This commit is contained in:
BIN
lib/TerrarumSansBitmap.jar
LFS
BIN
lib/TerrarumSansBitmap.jar
LFS
Binary file not shown.
@@ -313,22 +313,20 @@ class BTeXPage(
|
|||||||
fun isNotEmpty() = drawCalls.isNotEmpty()
|
fun isNotEmpty() = drawCalls.isNotEmpty()
|
||||||
}
|
}
|
||||||
|
|
||||||
interface BTeXTextDrawCall {
|
|
||||||
val rowStart: Int
|
|
||||||
val rows: Int
|
|
||||||
fun draw(doc: BTeXDocument, batch: SpriteBatch, x: Float, y: Float)
|
|
||||||
}
|
|
||||||
|
|
||||||
data class TypesetDrawCall(val movableType: MovableType, override val rowStart: Int, override val rows: Int): BTeXTextDrawCall {
|
data class TypesetDrawCall(val movableType: MovableType, val rowStart: Int, val rows: Int) {
|
||||||
override fun draw(doc: BTeXDocument, batch: SpriteBatch, x: Float, y: Float) {
|
fun getText(): List<CodepointSequence> = movableType.typesettedSlugs.subList(rowStart, minOf(movableType.typesettedSlugs.size, rowStart + rows))
|
||||||
|
fun draw(doc: BTeXDocument, batch: SpriteBatch, x: Float, y: Float) {
|
||||||
movableType.draw(batch, x, y, rowStart, minOf(rows, doc.pageLines))
|
movableType.draw(batch, x, y, rowStart, minOf(rows, doc.pageLines))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
interface BTeXBatchDrawCall {
|
abstract class BTeXBatchDrawCall(
|
||||||
fun getWidth(): Int
|
val width: Int,
|
||||||
fun getLineHeight(): Int
|
val lineHeight: Int,
|
||||||
fun draw(doc: BTeXDocument, batch: SpriteBatch, x: Float, y: Float, font: TerrarumSansBitmap? = null)
|
val parentText: BTeXDrawCall?// = null
|
||||||
|
) {
|
||||||
|
abstract fun draw(doc: BTeXDocument, batch: SpriteBatch, x: Float, y: Float, font: TerrarumSansBitmap? = null)
|
||||||
}
|
}
|
||||||
|
|
||||||
class BTeXDrawCall(
|
class BTeXDrawCall(
|
||||||
@@ -336,11 +334,14 @@ class BTeXDrawCall(
|
|||||||
var posX: Int, // position relative to the page start (excluding page margin)
|
var posX: Int, // position relative to the page start (excluding page margin)
|
||||||
var posY: Int, // position relative to the page start (excluding page margin)
|
var posY: Int, // position relative to the page start (excluding page margin)
|
||||||
val theme: String,
|
val theme: String,
|
||||||
val text: BTeXTextDrawCall? = null,
|
val text: TypesetDrawCall? = null,
|
||||||
val cmd: BTeXBatchDrawCall? = null,
|
val cmd: BTeXBatchDrawCall? = null,
|
||||||
val font: TerrarumSansBitmap? = null
|
val font: TerrarumSansBitmap? = null
|
||||||
) {
|
) {
|
||||||
|
|
||||||
|
internal var deltaX = 0 // used by the BTexParser.typeset*()
|
||||||
|
internal var deltaY = 0 // used by the BTexParser.typeset*()
|
||||||
|
|
||||||
init {
|
init {
|
||||||
if (text != null && cmd != null) throw IllegalArgumentException("Text and Texture are both non-null")
|
if (text != null && cmd != null) throw IllegalArgumentException("Text and Texture are both non-null")
|
||||||
}
|
}
|
||||||
@@ -376,18 +377,15 @@ class BTeXDrawCall(
|
|||||||
|
|
||||||
internal val width: Int
|
internal val width: Int
|
||||||
get() = if (text != null)
|
get() = if (text != null)
|
||||||
if (text is TypesetDrawCall)
|
text.movableType.width * text.movableType.font.scale
|
||||||
text.movableType.width * text.movableType.font.scale
|
|
||||||
else
|
|
||||||
TODO()
|
|
||||||
else
|
else
|
||||||
cmd!!.getWidth()
|
cmd!!.width
|
||||||
|
|
||||||
internal var extraDrawFun: (SpriteBatch, Float, Float) -> Unit = { _, _, _ ->}
|
internal var extraDrawFun: (SpriteBatch, Float, Float) -> Unit = { _, _, _ ->}
|
||||||
internal val lineCount = if (text != null)
|
internal val lineCount = if (text != null)
|
||||||
text.rows
|
text.rows
|
||||||
else
|
else
|
||||||
cmd!!.getLineHeight()
|
cmd!!.lineHeight
|
||||||
|
|
||||||
companion object {
|
companion object {
|
||||||
private fun CodepointSequence.isBlank() = this.all { whitespaces.contains(it) }
|
private fun CodepointSequence.isBlank() = this.all { whitespaces.contains(it) }
|
||||||
|
|||||||
@@ -28,7 +28,6 @@ import java.io.File
|
|||||||
import java.io.FileInputStream
|
import java.io.FileInputStream
|
||||||
import java.io.StringReader
|
import java.io.StringReader
|
||||||
import javax.xml.parsers.SAXParserFactory
|
import javax.xml.parsers.SAXParserFactory
|
||||||
import kotlin.math.absoluteValue
|
|
||||||
import kotlin.math.roundToInt
|
import kotlin.math.roundToInt
|
||||||
import kotlin.reflect.KFunction
|
import kotlin.reflect.KFunction
|
||||||
import kotlin.reflect.full.declaredFunctions
|
import kotlin.reflect.full.declaredFunctions
|
||||||
@@ -91,7 +90,8 @@ object BTeXParser {
|
|||||||
paragraphBuffer.clear()
|
paragraphBuffer.clear()
|
||||||
}
|
}
|
||||||
|
|
||||||
private val objDict = HashMap<String, BTeXBatchDrawCall>()
|
private val objDict = HashMap<String, (BTeXDrawCall) -> BTeXBatchDrawCall>()
|
||||||
|
private val objWidthDict = HashMap<String, Int>()
|
||||||
|
|
||||||
private var lastTagAtDepth = Array(24) { "" }
|
private var lastTagAtDepth = Array(24) { "" }
|
||||||
private var pTagCntAtDepth = IntArray(24)
|
private var pTagCntAtDepth = IntArray(24)
|
||||||
@@ -115,9 +115,9 @@ object BTeXParser {
|
|||||||
|
|
||||||
private val bodyTextShadowAlpha = 0.36f
|
private val bodyTextShadowAlpha = 0.36f
|
||||||
|
|
||||||
private fun StringBuilder.appendObject(id: String) {
|
private fun StringBuilder.appendObjectPlaceholder(id: String) {
|
||||||
(objDict[id] ?: throw NullPointerException("No OBJ with id '$id' exists")).let {
|
(objWidthDict[id] ?: throw NullPointerException("No OBJ with id '$id' exists")).let {
|
||||||
this.append(objectMarkerWithWidth(id, it.getWidth()))
|
this.append(objectMarkerWithWidth(id, it))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -132,42 +132,45 @@ object BTeXParser {
|
|||||||
elemClosers[it.name] = it
|
elemClosers[it.name] = it
|
||||||
}
|
}
|
||||||
|
|
||||||
objDict["TAG@BTEX"] = object : BTeXBatchDrawCall {
|
objWidthDict["TAG@BTEX"] = 32
|
||||||
override fun getWidth() = 32
|
objDict["TAG@BTEX"] = { text: BTeXDrawCall ->
|
||||||
override fun getLineHeight() = 0
|
object : BTeXBatchDrawCall(32, 0, text) {
|
||||||
override fun draw(doc: BTeXDocument, batch: SpriteBatch, x: Float, y: Float, font: TerrarumSansBitmap?) {
|
override fun draw(doc: BTeXDocument, batch: SpriteBatch, x: Float, y: Float, font: TerrarumSansBitmap?) {
|
||||||
val scale = font!!.scale
|
val scale = font!!.scale
|
||||||
val interchar = font.interchar
|
val interchar = font.interchar
|
||||||
font.draw(batch, "${ccDefault}B", x + ( 0 + 0*interchar)*scale, y + 0*scale)
|
font.draw(batch, "${ccDefault}B", x + ( 0 + 0*interchar)*scale, y + 0*scale)
|
||||||
font.draw(batch, "${ccDefault}T", x + ( 8 + 1*interchar)*scale, y + 0*scale)
|
font.draw(batch, "${ccDefault}T", x + ( 8 + 1*interchar)*scale, y + 0*scale)
|
||||||
font.draw(batch, "${ccDefault}E", x + (15 + 2*interchar)*scale, y + 4*scale)
|
font.draw(batch, "${ccDefault}E", x + (15 + 2*interchar)*scale, y + 4*scale)
|
||||||
font.draw(batch, "${ccDefault}X", x + (23 + 3*interchar)*scale, y + 0*scale)
|
font.draw(batch, "${ccDefault}X", x + (23 + 3*interchar)*scale, y + 0*scale)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
objDict["TAG@LATEX"] = object : BTeXBatchDrawCall {
|
objWidthDict["TAG@LATEX"] = 36
|
||||||
override fun getWidth() = 36
|
objDict["TAG@LATEX"] = { text: BTeXDrawCall ->
|
||||||
override fun getLineHeight() = 0
|
object : BTeXBatchDrawCall(36, 0, text) {
|
||||||
override fun draw(doc: BTeXDocument, batch: SpriteBatch, x: Float, y: Float, font: TerrarumSansBitmap?) {
|
override fun draw(doc: BTeXDocument, batch: SpriteBatch, x: Float, y: Float, font: TerrarumSansBitmap?) {
|
||||||
val scale = font!!.scale
|
val scale = font!!.scale
|
||||||
val interchar = font.interchar
|
val interchar = font.interchar
|
||||||
font.draw(batch, "${ccDefault}L", x + ( 0 + 0*interchar)*scale, y + 0*scale)
|
font.draw(batch, "${ccDefault}L", x + (0 + 0 * interchar) * scale, y + 0 * scale)
|
||||||
font.draw(batch, "${ccDefault}ᴀ", x + ( 4 + 0*interchar)*scale, y + -4*scale)
|
font.draw(batch, "${ccDefault}ᴀ", x + (4 + 0 * interchar) * scale, y + -4 * scale)
|
||||||
font.draw(batch, "${ccDefault}T", x + (12 + 1*interchar)*scale, y + 0*scale)
|
font.draw(batch, "${ccDefault}T", x + (12 + 1 * interchar) * scale, y + 0 * scale)
|
||||||
font.draw(batch, "${ccDefault}E", x + (19 + 2*interchar)*scale, y + 4*scale)
|
font.draw(batch, "${ccDefault}E", x + (19 + 2 * interchar) * scale, y + 4 * scale)
|
||||||
font.draw(batch, "${ccDefault}X", x + (27 + 3*interchar)*scale, y + 0*scale)
|
font.draw(batch, "${ccDefault}X", x + (27 + 3 * interchar) * scale, y + 0 * scale)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
objDict["TAG@TEX"] = object : BTeXBatchDrawCall {
|
objWidthDict["TAG@TEX"] = 24
|
||||||
override fun getWidth() = 24
|
objDict["TAG@TEX"] = { text: BTeXDrawCall ->
|
||||||
override fun getLineHeight() = 0
|
object : BTeXBatchDrawCall(24, 0, text) {
|
||||||
override fun draw(doc: BTeXDocument, batch: SpriteBatch, x: Float, y: Float, font: TerrarumSansBitmap?) {
|
override fun draw(doc: BTeXDocument, batch: SpriteBatch, x: Float, y: Float, font: TerrarumSansBitmap?) {
|
||||||
val scale = font!!.scale
|
val scale = font!!.scale
|
||||||
val interchar = font.interchar
|
val interchar = font.interchar
|
||||||
font.draw(batch, "${ccDefault}T", x + ( 0 + 1*interchar)*scale, y + 0*scale)
|
font.draw(batch, "${ccDefault}T", x + (0 + 1 * interchar) * scale, y + 0 * scale)
|
||||||
font.draw(batch, "${ccDefault}E", x + ( 7 + 2*interchar)*scale, y + 4*scale)
|
font.draw(batch, "${ccDefault}E", x + (7 + 2 * interchar) * scale, y + 4 * scale)
|
||||||
font.draw(batch, "${ccDefault}X", x + (15 + 3*interchar)*scale, y + 0*scale)
|
font.draw(batch, "${ccDefault}X", x + (15 + 3 * interchar) * scale, y + 0 * scale)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -620,17 +623,17 @@ object BTeXParser {
|
|||||||
|
|
||||||
@OpenTag // reflective access is impossible with 'private'
|
@OpenTag // reflective access is impossible with 'private'
|
||||||
fun processElemBTEX(handler: BTeXHandler, doc: BTeXDocument, uri: String, attribs: HashMap<String, String>) {
|
fun processElemBTEX(handler: BTeXHandler, doc: BTeXDocument, uri: String, attribs: HashMap<String, String>) {
|
||||||
handler.paragraphBuffer.appendObject("TAG@BTEX")
|
handler.paragraphBuffer.appendObjectPlaceholder("TAG@BTEX")
|
||||||
}
|
}
|
||||||
|
|
||||||
@OpenTag // reflective access is impossible with 'private'
|
@OpenTag // reflective access is impossible with 'private'
|
||||||
fun processElemLATEX(handler: BTeXHandler, doc: BTeXDocument, uri: String, attribs: HashMap<String, String>) {
|
fun processElemLATEX(handler: BTeXHandler, doc: BTeXDocument, uri: String, attribs: HashMap<String, String>) {
|
||||||
handler.paragraphBuffer.appendObject("TAG@LATEX")
|
handler.paragraphBuffer.appendObjectPlaceholder("TAG@LATEX")
|
||||||
}
|
}
|
||||||
|
|
||||||
@OpenTag // reflective access is impossible with 'private'
|
@OpenTag // reflective access is impossible with 'private'
|
||||||
fun processElemTEX(handler: BTeXHandler, doc: BTeXDocument, uri: String, attribs: HashMap<String, String>) {
|
fun processElemTEX(handler: BTeXHandler, doc: BTeXDocument, uri: String, attribs: HashMap<String, String>) {
|
||||||
handler.paragraphBuffer.appendObject("TAG@TEX")
|
handler.paragraphBuffer.appendObjectPlaceholder("TAG@TEX")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -1008,8 +1011,10 @@ object BTeXParser {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private fun typesetPartHeading(num: Int, thePar: String, handler: BTeXHandler, indent: Int = 16, width: Int = doc.textWidth) {
|
private fun typesetPartHeading(num: Int, thePar: String, handler: BTeXHandler, indent: Int = 16, width: Int = doc.textWidth) {
|
||||||
typesetParagraphs("${ccDefault}Part ${num.toRomanNum()}", handler)
|
typesetParagraphs("${ccDefault}⁃ Part ${num.toRomanNum()} ⁃", handler)
|
||||||
typesetParagraphs(titleFont, "$ccDefault$thePar\n ", handler)
|
typesetParagraphs(" ", handler)
|
||||||
|
// typesetParagraphs(getTitleFont(), "$ccDefault$thePar", handler)
|
||||||
|
typesetParagraphs(getSubtitleFont(), "$ccDefault$thePar", handler)
|
||||||
|
|
||||||
// get global yDelta
|
// get global yDelta
|
||||||
doc.currentPageObj.let { page ->
|
doc.currentPageObj.let { page ->
|
||||||
@@ -1022,18 +1027,40 @@ object BTeXParser {
|
|||||||
|
|
||||||
|
|
||||||
page.drawCalls.forEach {
|
page.drawCalls.forEach {
|
||||||
// get individual xDelta
|
val text = it.text?.getText()
|
||||||
val xStart = it.posX
|
val batchCall = it.cmd
|
||||||
val xEnd = it.posX + it.width
|
/*if (text != null) {
|
||||||
val pageWidth = doc.textWidth
|
println("Part draw call (${text.size} lines, pos: ${it.posX}, ${it.posY}, width: ${it.width}):" +
|
||||||
|
"\n${text.joinToString("\n") { it.toReadable() }}")
|
||||||
|
}
|
||||||
|
else if (batchCall != null) {
|
||||||
|
println("Part draw call (batch, pos: ${it.posX}, ${it.posY}, width: ${it.width})")
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
println("wtf?")
|
||||||
|
}*/
|
||||||
|
|
||||||
val newXpos = (pageWidth - (xEnd - xStart)) / 2
|
// set posX
|
||||||
val xDelta = newXpos - xStart
|
//// if the batchcall has parent text, use parent's delta value to move things around
|
||||||
|
if (batchCall != null && batchCall.parentText != null) {
|
||||||
|
it.posX += it.cmd.parentText!!.deltaX
|
||||||
|
it.deltaX += it.cmd.parentText!!.deltaX
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
// get individual xDelta
|
||||||
|
val xDelta = (doc.textWidth - it.width) / 2
|
||||||
|
|
||||||
// apply the movement
|
// apply the movement
|
||||||
it.posX += xDelta
|
it.posX += xDelta
|
||||||
|
it.deltaX += xDelta
|
||||||
|
}
|
||||||
|
|
||||||
|
// set posY
|
||||||
it.posY += yDelta
|
it.posY += yDelta
|
||||||
|
it.deltaY += yDelta
|
||||||
}
|
}
|
||||||
|
|
||||||
|
println()
|
||||||
}
|
}
|
||||||
|
|
||||||
/*doc.currentPageObj.let { page ->
|
/*doc.currentPageObj.let { page ->
|
||||||
@@ -1117,7 +1144,9 @@ object BTeXParser {
|
|||||||
val subset = linesOut to remainder
|
val subset = linesOut to remainder
|
||||||
val posYline = doc.linesPrintedOnPage[pageNum]
|
val posYline = doc.linesPrintedOnPage[pageNum]
|
||||||
|
|
||||||
(textToDrawCall(handler, posYline, slugs, subset.first, subset.second) + parseAndGetObjDrawCalls(font, handler, posYline, slugs, subset.first, subset.second)).let {
|
val textDrawCalls = textToDrawCall(handler, posYline, slugs, subset.first, subset.second)
|
||||||
|
val objectDrawCalls = parseAndGetObjDrawCalls(textDrawCalls[0], font, handler, posYline, slugs, subset.first, subset.second)
|
||||||
|
(textDrawCalls + objectDrawCalls).let {
|
||||||
it.forEach {
|
it.forEach {
|
||||||
doc.appendDrawCall(doc.pages[pageNum], it); drawCalls.add(it)
|
doc.appendDrawCall(doc.pages[pageNum], it); drawCalls.add(it)
|
||||||
}
|
}
|
||||||
@@ -1135,7 +1164,9 @@ object BTeXParser {
|
|||||||
val subset = linesOut to remainder
|
val subset = linesOut to remainder
|
||||||
val posYline = doc.linesPrintedOnPage[pageNum]
|
val posYline = doc.linesPrintedOnPage[pageNum]
|
||||||
|
|
||||||
(textToDrawCall(handler, posYline, slugs, subset.first, subset.second) + parseAndGetObjDrawCalls(font, handler, posYline, slugs, subset.first, subset.second)).let {
|
val textDrawCalls = textToDrawCall(handler, posYline, slugs, subset.first, subset.second)
|
||||||
|
val objectDrawCalls = parseAndGetObjDrawCalls(textDrawCalls[0], font, handler, posYline, slugs, subset.first, subset.second)
|
||||||
|
(textDrawCalls + objectDrawCalls).let {
|
||||||
it.forEach {
|
it.forEach {
|
||||||
doc.appendDrawCall(doc.pages[pageNum], it); drawCalls.add(it)
|
doc.appendDrawCall(doc.pages[pageNum], it); drawCalls.add(it)
|
||||||
}
|
}
|
||||||
@@ -1155,22 +1186,22 @@ object BTeXParser {
|
|||||||
return drawCalls
|
return drawCalls
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun textToDrawCall(handler: BTeXHandler, posYline: Int, slugs: MovableType, lineStart: Int, lineEnd: Int): List<BTeXDrawCall> {
|
private fun textToDrawCall(handler: BTeXHandler, posYline: Int, slugs: MovableType, lineStart: Int, lineCount: Int): List<BTeXDrawCall> {
|
||||||
return listOf(
|
return listOf(
|
||||||
BTeXDrawCall(
|
BTeXDrawCall(
|
||||||
doc,
|
doc,
|
||||||
0,
|
0,
|
||||||
posYline * doc.lineHeightInPx,
|
posYline * doc.lineHeightInPx,
|
||||||
handler.currentTheme,
|
handler.currentTheme,
|
||||||
TypesetDrawCall(slugs, lineStart, lineEnd)
|
TypesetDrawCall(slugs, lineStart, lineCount)
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun parseAndGetObjDrawCalls(font: TerrarumSansBitmap, handler: BTeXHandler, posYline: Int, slugs: MovableType, lineStart: Int, lineEnd: Int): List<BTeXDrawCall> {
|
private fun parseAndGetObjDrawCalls(textDrawCall: BTeXDrawCall, font: TerrarumSansBitmap, handler: BTeXHandler, posYline: Int, slugs: MovableType, lineStart: Int, lineCount: Int): List<BTeXDrawCall> {
|
||||||
val out = ArrayList<BTeXDrawCall>()
|
val out = ArrayList<BTeXDrawCall>()
|
||||||
|
|
||||||
slugs.typesettedSlugs.subList(lineStart, lineEnd).forEachIndexed { lineNumCnt, line ->
|
slugs.typesettedSlugs.subList(lineStart, lineStart + lineCount).forEachIndexed { lineNumCnt, line ->
|
||||||
line.mapIndexed { i, c -> i to c }.filter { it.second == OBJ }.map { it.first }.forEach { xIndex ->
|
line.mapIndexed { i, c -> i to c }.filter { it.second == OBJ }.map { it.first }.forEach { xIndex ->
|
||||||
val x = font.getWidthNormalised(CodepointSequence(line.subList(0, xIndex)))
|
val x = font.getWidthNormalised(CodepointSequence(line.subList(0, xIndex)))
|
||||||
val y = (posYline + lineNumCnt) * doc.lineHeightInPx
|
val y = (posYline + lineNumCnt) * doc.lineHeightInPx
|
||||||
@@ -1191,8 +1222,8 @@ object BTeXParser {
|
|||||||
x,
|
x,
|
||||||
y,
|
y,
|
||||||
handler.currentTheme,
|
handler.currentTheme,
|
||||||
cmd = objDict[idbuf.toString()] ?: throw NullPointerException("No OBJ with id '$idbuf' exists"),
|
cmd = objDict[idbuf.toString()]?.invoke(textDrawCall) ?: throw NullPointerException("No OBJ with id '$idbuf' exists"),
|
||||||
font = font
|
font = font,
|
||||||
)
|
)
|
||||||
|
|
||||||
out.add(extraDrawCall)
|
out.add(extraDrawCall)
|
||||||
|
|||||||
Reference in New Issue
Block a user