btex: finalising option for the btexdoc

This commit is contained in:
minjaesong
2024-04-28 22:54:45 +09:00
parent e1b577b781
commit fa8054adac
4 changed files with 101 additions and 21 deletions

Binary file not shown.

View File

@@ -1,8 +1,14 @@
package net.torvald.terrarum.btex
import com.badlogic.gdx.graphics.Color
import com.badlogic.gdx.graphics.OrthographicCamera
import com.badlogic.gdx.graphics.Pixmap
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.glutils.FrameBuffer
import com.badlogic.gdx.utils.Disposable
import net.torvald.terrarum.*
import net.torvald.terrarum.imagefont.TinyAlphNum
import net.torvald.terrarum.ui.Toolkit
import net.torvald.terrarumsansbitmap.MovableType
@@ -11,7 +17,7 @@ import net.torvald.terrarumsansbitmap.gdx.CodepointSequence
/**
* Created by minjaesong on 2023-10-28.
*/
class BTeXDocument {
class BTeXDocument : Disposable {
var context = "tome" // tome (cover=hardcover), sheets (cover=typewriter or cover=printout), examination (def=examination)
var font = "default" // default or typewriter
var inner = "standard"
@@ -42,6 +48,8 @@ class BTeXDocument {
internal val pages = ArrayList<BTeXPage>()
private lateinit var pageTextures: ArrayList<TextureRegion>
val currentPage: Int
get() = pages.size - 1
@@ -65,6 +73,48 @@ class BTeXDocument {
linesPrintedOnPage.add(index, 0)
}
/**
* Must be called on a thread with GL context!
*/
fun finalise() {
if (isFinalised) throw IllegalStateException("Page is already been finalised")
pageTextures = ArrayList()
val camera = OrthographicCamera(pageDimensionWidth.toFloat(), pageDimensionHeight.toFloat())
val batch = FlippingSpriteBatch()
pages.forEach { page ->
val fbo = FrameBuffer(Pixmap.Format.RGBA8888, pageDimensionWidth, pageDimensionHeight, false)
fbo.inAction(null, null) {
camera.setToOrtho(false, pageDimensionWidth.toFloat(), pageDimensionHeight.toFloat())
camera.position?.set((pageDimensionWidth / 2f).roundToFloat(), (pageDimensionHeight / 2f).roundToFloat(), 0f) // TODO floor? ceil? round?
camera.update()
batch.projectionMatrix = camera.combined
blendNormalStraightAlpha(batch)
batch.inUse {
page.render(0f, batch, 0, 0, pageMarginH, pageMarginV)
}
}
pageTextures.add(TextureRegion(fbo.colorBufferTexture))
}
isFinalised = true
batch.dispose()
}
override fun dispose() {
if (isFinalised) {
pageTextures.forEach { it.texture.dispose() }
}
}
var isFinalised = false; private set
/**
* Appends draw call to the list. The draw call must be prepared manually so that they would not overflow.
* Use `addNewPage` to append the overflowing text to the next page.
@@ -85,7 +135,12 @@ class BTeXDocument {
}
fun render(frameDelta: Float, batch: SpriteBatch, page: Int, x: Int, y: Int) {
pages[page].render(frameDelta, batch, x, y, pageMarginH, pageMarginV)
batch.color = Color.WHITE
if (!isFinalised)
pages[page].render(frameDelta, batch, x, y, pageMarginH, pageMarginV)
else
batch.draw(pageTextures[page], x.toFloat(), y.toFloat())
// paint page number
val num = "${page+1}"

View File

@@ -14,6 +14,7 @@ import net.torvald.terrarum.btex.MovableTypeDrawCall
import net.torvald.terrarum.ceilToFloat
import net.torvald.terrarum.gameitems.ItemID
import net.torvald.terrarum.toHex
import net.torvald.terrarum.tryDispose
import net.torvald.terrarum.ui.Toolkit
import net.torvald.terrarum.worlddrawer.toRGBA
import net.torvald.terrarumsansbitmap.MovableType
@@ -42,22 +43,24 @@ object BTeXParser {
operator fun invoke(file: FileHandle) = invoke(file.file())
operator fun invoke(file: File): BTeXDocument {
operator fun invoke(file: File): Pair<BTeXDocument, BTeXHandler> {
val doc = BTeXDocument()
val parser = SAXParserFactory.newDefaultInstance().newSAXParser()
val stream = FileInputStream(file)
parser.parse(stream, BTeXHandler(doc))
return doc
val handler = BTeXHandler(doc)
parser.parse(stream, handler)
return doc to handler
}
operator fun invoke(string: String): BTeXDocument {
operator fun invoke(string: String): Pair<BTeXDocument, BTeXHandler> {
val doc = BTeXDocument()
val parser = SAXParserFactory.newDefaultInstance().newSAXParser()
parser.parse(InputSource(StringReader(string)), BTeXHandler(doc))
return doc
val handler = BTeXHandler(doc)
parser.parse(InputSource(StringReader(string)), handler)
return doc to handler
}
internal class BTeXHandler(val doc: BTeXDocument) : DefaultHandler() {
class BTeXHandler(val doc: BTeXDocument) : DefaultHandler() {
private val DEFAULT_FONTCOL = DEFAULT_PAGE_FORE
private val LINE_HEIGHT = doc.lineHeightInPx
@@ -101,6 +104,12 @@ object BTeXParser {
private var hasCover = false
private var coverCol: Color? = null
private lateinit var testFont: TerrarumSansBitmap
private lateinit var titleFont: TerrarumSansBitmap
private lateinit var subtitleFont: TerrarumSansBitmap
private val bodyTextShadowAlpha = 0.36f
init {
BTeXHandler::class.declaredFunctions.filter { it.findAnnotation<OpenTag>() != null }.forEach {
// println("Tag opener: ${it.name}")
@@ -113,6 +122,12 @@ object BTeXParser {
}
}
fun dispose() {
if (::testFont.isInitialized) testFont.tryDispose()
if (::titleFont.isInitialized) titleFont.tryDispose()
if (::subtitleFont.isInitialized) subtitleFont.tryDispose()
}
private fun printdbg(message: String?) {
val CSI = "\u001B[32m"
val timeNow = System.currentTimeMillis()
@@ -232,16 +247,10 @@ object BTeXParser {
}
}
private lateinit var testFont: TerrarumSansBitmap
private lateinit var titleFont: TerrarumSansBitmap
private lateinit var subtitleFont: TerrarumSansBitmap
private val bodyTextShadowAlpha = 0.36f
private fun getFont() = when (cover) {
"typewriter" -> TODO()
else -> {
if (!::testFont.isInitialized) testFont = TerrarumSansBitmap(App.FONT_DIR, shadowAlpha = bodyTextShadowAlpha)
if (!::testFont.isInitialized) testFont = TerrarumSansBitmap(App.FONT_DIR, shadowAlpha = bodyTextShadowAlpha, textCacheSize = 65536)
testFont
}
}
@@ -841,7 +850,7 @@ object BTeXParser {
private fun typesetBookTitle(thePar: String, handler: BTeXHandler) {
val label = "\n" + thePar
typesetParagraphs(getTitleFont(), label, handler, (doc.textWidth - 16) / 2).also {
typesetParagraphs(getTitleFont(), label, handler, doc.textWidth - 16).also {
val addedLines = it.sumOf { it.lineCount }
doc.linesPrintedOnPage[doc.currentPage] += addedLines

View File

@@ -16,6 +16,7 @@ import net.torvald.terrarum.btex.BTeXDocument
import net.torvald.terrarum.ceilToInt
import net.torvald.terrarum.gdxClearAndEnableBlend
import net.torvald.terrarum.inUse
import kotlin.system.measureTimeMillis
/**
@@ -24,11 +25,13 @@ import net.torvald.terrarum.inUse
class BTeXTest : ApplicationAdapter() {
// val filePath = "btex.xml"
val filePath = "literature/ruRU/anton_chekhov_palata_no_6.xml"
val filePath = "literature/en/daniel_defoe_robinson_crusoe.xml"
// val filePath = "literature/ruRU/anton_chekhov_palata_no_6.xml"
// val filePath = "literature/koKR/yisang_nalgae.xml"
private lateinit var document: BTeXDocument
private lateinit var documentHandler: BTeXParser.BTeXHandler
private lateinit var batch: FlippingSpriteBatch
private lateinit var camera: OrthographicCamera
@@ -43,7 +46,20 @@ class BTeXTest : ApplicationAdapter() {
bg = TextureRegion(Texture(Gdx.files.internal("test_assets/real_bg_with_guides.png")))
document = BTeXParser.invoke(Gdx.files.internal("./assets/mods/basegame/books/$filePath"))
measureTimeMillis {
val f = BTeXParser.invoke(Gdx.files.internal("./assets/mods/basegame/books/$filePath"))
document = f.first
documentHandler = f.second
}.also {
println("Time spent on typesetting [ms]: $it")
}
measureTimeMillis {
document.finalise()
documentHandler.dispose()
}.also {
println("Time spent on finalising [ms]: $it")
}
}
private var scroll = 0