mirror of
https://github.com/curioustorvald/Terrarum.git
synced 2026-06-11 02:54:04 +09:00
btex: <a> boxing better detection of hyphenation
This commit is contained in:
@@ -343,6 +343,24 @@ data class BTeXClickable(
|
|||||||
) {
|
) {
|
||||||
var deltaX = 0
|
var deltaX = 0
|
||||||
var deltaY = 0
|
var deltaY = 0
|
||||||
|
|
||||||
|
fun debugDrawHitboxToPixmap(pixmap: Pixmap, doc: BTeXDocument) {
|
||||||
|
pixmap.drawRectangle(
|
||||||
|
posX - HBPADH + doc.pageMarginH,
|
||||||
|
posY - HBPADV + doc.pageMarginV,
|
||||||
|
width + 2 * HBPADH,
|
||||||
|
doc.lineHeightInPx + 2 * HBPADV
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
fun pointInHitbox(doc: BTeXDocument, x: Int, y: Int) =
|
||||||
|
(x in posX - HBPADH + doc.pageMarginH until posX - HBPADH + doc.pageMarginH + width + 2 * HBPADH &&
|
||||||
|
y in posY - HBPADV + doc.pageMarginV until posY - HBPADV + doc.pageMarginV + doc.lineHeightInPx + 2 * HBPADV)
|
||||||
|
|
||||||
|
companion object {
|
||||||
|
private const val HBPADH = 0
|
||||||
|
private const val HBPADV = 1
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
class BTeXPage(
|
class BTeXPage(
|
||||||
@@ -407,7 +425,7 @@ class BTeXPage(
|
|||||||
// debug underlines on clickableElements
|
// debug underlines on clickableElements
|
||||||
clickableElements.forEach {
|
clickableElements.forEach {
|
||||||
pixmap.setColor(HREF_UNDERLINE)
|
pixmap.setColor(HREF_UNDERLINE)
|
||||||
pixmap.drawRectangle(it.posX + doc.pageMarginH, it.posY + doc.pageMarginV, it.width, doc.lineHeightInPx)
|
it.debugDrawHitboxToPixmap(pixmap, doc)
|
||||||
}
|
}
|
||||||
|
|
||||||
// print texts
|
// print texts
|
||||||
|
|||||||
@@ -1653,10 +1653,10 @@ object BTeXParser {
|
|||||||
|
|
||||||
val indexOfSequence = str.indexOfSequence(objSeq)
|
val indexOfSequence = str.indexOfSequence(objSeq)
|
||||||
|
|
||||||
val theIndex = if (objectIsSplit) -(objSeq.size + 4) else indexOfSequence
|
val theIndex = if (objectIsSplit) -(objSeq.size) else indexOfSequence
|
||||||
|
|
||||||
theIndex?.let { index -> // we never know which line the object appears
|
theIndex?.let { index -> // we never know which line the object appears
|
||||||
val wordOffset = index + objSeq.size + 4 // must be index of starting NUL
|
val wordOffset = index + objSeq.size // must be index of starting NUL
|
||||||
// target word is on the current line
|
// target word is on the current line
|
||||||
if (wordOffset < str.size) {
|
if (wordOffset < str.size) {
|
||||||
var wordEnd = wordOffset + 1 // will be right on the ending NUL
|
var wordEnd = wordOffset + 1 // will be right on the ending NUL
|
||||||
@@ -1724,10 +1724,10 @@ object BTeXParser {
|
|||||||
|
|
||||||
val indexOfSequence = str.indexOfSequence(objSeq)
|
val indexOfSequence = str.indexOfSequence(objSeq)
|
||||||
|
|
||||||
val theIndex = if (objectIsSplit) -(objSeq.size + 4) else indexOfSequence
|
val theIndex = if (objectIsSplit) -(objSeq.size) else indexOfSequence
|
||||||
|
|
||||||
theIndex?.let { index -> // we never know which line the object appears
|
theIndex?.let { index -> // we never know which line the object appears
|
||||||
val wordOffset = index + objSeq.size + 4 // must be index of starting NUL
|
val wordOffset = index + objSeq.size // must be index of starting NUL
|
||||||
// target word is on the current line
|
// target word is on the current line
|
||||||
if (wordOffset < str.size) {
|
if (wordOffset < str.size) {
|
||||||
var wordEnd = wordOffset + 1 // will be right on the ending NUL
|
var wordEnd = wordOffset + 1 // will be right on the ending NUL
|
||||||
@@ -1735,6 +1735,10 @@ object BTeXParser {
|
|||||||
while (!(wordEnd >= str.size || str[wordEnd] == OBJ)) {
|
while (!(wordEnd >= str.size || str[wordEnd] == OBJ)) {
|
||||||
wordEnd++
|
wordEnd++
|
||||||
}
|
}
|
||||||
|
// if searching finished without finding OBJ, mark it
|
||||||
|
val objectIsSplit2 = (wordEnd >= str.size)
|
||||||
|
|
||||||
|
// retrieve the actual word
|
||||||
val substr = CodepointSequence(str.subList(wordOffset + 1, wordEnd))
|
val substr = CodepointSequence(str.subList(wordOffset + 1, wordEnd))
|
||||||
|
|
||||||
printdbg("2HREF word: ${substr.toReadable()}")
|
printdbg("2HREF word: ${substr.toReadable()}")
|
||||||
@@ -1748,7 +1752,7 @@ object BTeXParser {
|
|||||||
}
|
}
|
||||||
doc.appendClickable(doc.pages[pageNum], clickable); clickables.add(clickable)
|
doc.appendClickable(doc.pages[pageNum], clickable); clickables.add(clickable)
|
||||||
|
|
||||||
objectIsSplit = false
|
objectIsSplit = objectIsSplit2
|
||||||
}
|
}
|
||||||
// target word is on the next line (probably)
|
// target word is on the next line (probably)
|
||||||
else {
|
else {
|
||||||
@@ -2083,7 +2087,11 @@ object BTeXParser {
|
|||||||
if (pattern.isEmpty())
|
if (pattern.isEmpty())
|
||||||
throw IllegalArgumentException("Pattern is empty")
|
throw IllegalArgumentException("Pattern is empty")
|
||||||
if (this.isEmpty())
|
if (this.isEmpty())
|
||||||
throw IllegalArgumentException("Pattern is empty")
|
throw IllegalArgumentException("String is empty")
|
||||||
|
|
||||||
|
// pattern cannot exist because the string is shorter than the pattern
|
||||||
|
if (this.size < pattern.size)
|
||||||
|
return null
|
||||||
|
|
||||||
// next[i] stores the index of the next best partial match
|
// next[i] stores the index of the next best partial match
|
||||||
val next = IntArray(pattern.size + 1)
|
val next = IntArray(pattern.size + 1)
|
||||||
|
|||||||
@@ -8,17 +8,20 @@ import com.badlogic.gdx.backends.lwjgl3.Lwjgl3ApplicationConfiguration
|
|||||||
import com.badlogic.gdx.graphics.Color
|
import com.badlogic.gdx.graphics.Color
|
||||||
import com.badlogic.gdx.graphics.OrthographicCamera
|
import com.badlogic.gdx.graphics.OrthographicCamera
|
||||||
import com.badlogic.gdx.graphics.Texture
|
import com.badlogic.gdx.graphics.Texture
|
||||||
|
import com.badlogic.gdx.graphics.g2d.SpriteBatch
|
||||||
import com.badlogic.gdx.graphics.g2d.TextureRegion
|
import com.badlogic.gdx.graphics.g2d.TextureRegion
|
||||||
import com.badlogic.gdx.graphics.glutils.ShaderProgram
|
import com.badlogic.gdx.graphics.glutils.ShaderProgram
|
||||||
import net.torvald.btex.BTeXDocViewer
|
import net.torvald.btex.BTeXDocViewer
|
||||||
import net.torvald.btex.BTeXParser
|
import net.torvald.btex.BTeXParser
|
||||||
import net.torvald.terrarum.*
|
import net.torvald.terrarum.FlippingSpriteBatch
|
||||||
import net.torvald.terrarum.btex.BTeXDocument
|
import net.torvald.terrarum.btex.BTeXDocument
|
||||||
|
import net.torvald.terrarum.gdxClearAndEnableBlend
|
||||||
import net.torvald.terrarum.imagefont.TinyAlphNum
|
import net.torvald.terrarum.imagefont.TinyAlphNum
|
||||||
|
import net.torvald.terrarum.inUse
|
||||||
import net.torvald.terrarum.langpack.Lang
|
import net.torvald.terrarum.langpack.Lang
|
||||||
import net.torvald.terrarum.ui.Toolkit
|
import net.torvald.terrarum.ui.Toolkit
|
||||||
import net.torvald.unicode.EMDASH
|
import net.torvald.unicode.EMDASH
|
||||||
import java.io.File
|
import java.util.concurrent.atomic.AtomicReference
|
||||||
import kotlin.system.measureTimeMillis
|
import kotlin.system.measureTimeMillis
|
||||||
|
|
||||||
|
|
||||||
@@ -27,8 +30,8 @@ import kotlin.system.measureTimeMillis
|
|||||||
*/
|
*/
|
||||||
class BTeXTest : ApplicationAdapter() {
|
class BTeXTest : ApplicationAdapter() {
|
||||||
|
|
||||||
// val filePath = "btex.xml"
|
val filePath = "btex.xml"
|
||||||
val filePath = "btex_ko.xml"
|
// val filePath = "btex_ko.xml"
|
||||||
// val filePath = "test.xml"
|
// val filePath = "test.xml"
|
||||||
// val filePath = "literature/en/daniel_defoe_robinson_crusoe.xml"
|
// val filePath = "literature/en/daniel_defoe_robinson_crusoe.xml"
|
||||||
// val filePath = "literature/ruRU/anton_chekhov_palata_no_6.xml"
|
// val filePath = "literature/ruRU/anton_chekhov_palata_no_6.xml"
|
||||||
@@ -47,6 +50,10 @@ class BTeXTest : ApplicationAdapter() {
|
|||||||
"bucks" to "121687"
|
"bucks" to "121687"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
private val errorInfo = AtomicReference<Throwable?>().also {
|
||||||
|
it.set(null)
|
||||||
|
}
|
||||||
|
|
||||||
override fun create() {
|
override fun create() {
|
||||||
Lang
|
Lang
|
||||||
TinyAlphNum
|
TinyAlphNum
|
||||||
@@ -65,25 +72,31 @@ class BTeXTest : ApplicationAdapter() {
|
|||||||
|
|
||||||
if (!isBookFinalised) {
|
if (!isBookFinalised) {
|
||||||
Thread {
|
Thread {
|
||||||
measureTimeMillis {
|
try {
|
||||||
val f = BTeXParser.invoke(Gdx.files.internal("./assets/mods/basegame/books/$filePath"), varMap)
|
measureTimeMillis {
|
||||||
document = f.first
|
val f = BTeXParser.invoke(Gdx.files.internal("./assets/mods/basegame/books/$filePath"), varMap)
|
||||||
documentHandler = f.second
|
document = f.first
|
||||||
}.also {
|
documentHandler = f.second
|
||||||
println("Time spent on typesetting [ms]: $it")
|
}.also {
|
||||||
}
|
println("Time spent on typesetting [ms]: $it")
|
||||||
|
}
|
||||||
|
|
||||||
measureTimeMillis {
|
measureTimeMillis {
|
||||||
document.finalise(true)
|
document.finalise(true)
|
||||||
}.also {
|
}.also {
|
||||||
println("Time spent on finalising [ms]: $it")
|
println("Time spent on finalising [ms]: $it")
|
||||||
}
|
}
|
||||||
|
|
||||||
/*measureTimeMillis {
|
/*measureTimeMillis {
|
||||||
document.serialise(File("./assets/mods/basegame/books/${filePath.replace(".xml", ".btxbook")}"))
|
document.serialise(File("./assets/mods/basegame/books/${filePath.replace(".xml", ".btxbook")}"))
|
||||||
}.also {
|
}.also {
|
||||||
println("Time spent on serialisation [ms]: $it")
|
println("Time spent on serialisation [ms]: $it")
|
||||||
}*/
|
}*/
|
||||||
|
}
|
||||||
|
catch (e: Throwable) {
|
||||||
|
errorInfo.set(e)
|
||||||
|
e.printStackTrace()
|
||||||
|
}
|
||||||
}.start()
|
}.start()
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
@@ -100,6 +113,30 @@ class BTeXTest : ApplicationAdapter() {
|
|||||||
|
|
||||||
private val drawY = 24
|
private val drawY = 24
|
||||||
|
|
||||||
|
private fun drawLoadingMsg(batch: SpriteBatch, stage: String) {
|
||||||
|
val e = errorInfo.get()
|
||||||
|
if (e != null) {
|
||||||
|
val st = e.message!!.split('\n').let {
|
||||||
|
val idx = it.indexOfFirst { it.startsWith("Caused by: ") }
|
||||||
|
it.subList(idx, it.size)
|
||||||
|
}
|
||||||
|
val th = 14 * st.size
|
||||||
|
val tw = st.maxOf { it.length } * 7
|
||||||
|
|
||||||
|
val tx = (1280 - tw) / 2
|
||||||
|
val ty = (720 - th) / 2
|
||||||
|
|
||||||
|
batch.color = Color.CORAL
|
||||||
|
st.forEachIndexed { i, s ->
|
||||||
|
TinyAlphNum.draw(batch, s, tx.toFloat(), ty + 14f*i)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
batch.color = Color.WHITE
|
||||||
|
Toolkit.drawTextCentered(batch, TinyAlphNum, stage, 1280, 0, 354)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
override fun render() {
|
override fun render() {
|
||||||
Gdx.graphics.setTitle("BTeXTest $EMDASH F: ${Gdx.graphics.framesPerSecond}")
|
Gdx.graphics.setTitle("BTeXTest $EMDASH F: ${Gdx.graphics.framesPerSecond}")
|
||||||
|
|
||||||
@@ -127,8 +164,7 @@ class BTeXTest : ApplicationAdapter() {
|
|||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
batch.inUse {
|
batch.inUse {
|
||||||
batch.color = Color.WHITE
|
drawLoadingMsg(batch, "Rendering...")
|
||||||
Toolkit.drawTextCentered(batch, TinyAlphNum, "Rendering...", 1280, 0, 354)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -145,8 +181,7 @@ class BTeXTest : ApplicationAdapter() {
|
|||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
batch.inUse {
|
batch.inUse {
|
||||||
batch.color = Color.WHITE
|
drawLoadingMsg(batch, "Typesetting...")
|
||||||
Toolkit.drawTextCentered(batch, TinyAlphNum, "Typesetting...", 1280, 0, 354)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user