mirror of
https://github.com/curioustorvald/Terrarum.git
synced 2026-06-13 12:04:06 +09:00
btex: finalising option for the btexdoc
This commit is contained in:
BIN
lib/TerrarumSansBitmap.jar
LFS
BIN
lib/TerrarumSansBitmap.jar
LFS
Binary file not shown.
@@ -1,8 +1,14 @@
|
|||||||
package net.torvald.terrarum.btex
|
package net.torvald.terrarum.btex
|
||||||
|
|
||||||
import com.badlogic.gdx.graphics.Color
|
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.SpriteBatch
|
||||||
import com.badlogic.gdx.graphics.g2d.TextureRegion
|
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.imagefont.TinyAlphNum
|
||||||
import net.torvald.terrarum.ui.Toolkit
|
import net.torvald.terrarum.ui.Toolkit
|
||||||
import net.torvald.terrarumsansbitmap.MovableType
|
import net.torvald.terrarumsansbitmap.MovableType
|
||||||
@@ -11,7 +17,7 @@ import net.torvald.terrarumsansbitmap.gdx.CodepointSequence
|
|||||||
/**
|
/**
|
||||||
* Created by minjaesong on 2023-10-28.
|
* 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 context = "tome" // tome (cover=hardcover), sheets (cover=typewriter or cover=printout), examination (def=examination)
|
||||||
var font = "default" // default or typewriter
|
var font = "default" // default or typewriter
|
||||||
var inner = "standard"
|
var inner = "standard"
|
||||||
@@ -42,6 +48,8 @@ class BTeXDocument {
|
|||||||
|
|
||||||
internal val pages = ArrayList<BTeXPage>()
|
internal val pages = ArrayList<BTeXPage>()
|
||||||
|
|
||||||
|
private lateinit var pageTextures: ArrayList<TextureRegion>
|
||||||
|
|
||||||
val currentPage: Int
|
val currentPage: Int
|
||||||
get() = pages.size - 1
|
get() = pages.size - 1
|
||||||
|
|
||||||
@@ -65,6 +73,48 @@ class BTeXDocument {
|
|||||||
linesPrintedOnPage.add(index, 0)
|
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.
|
* 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.
|
* 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) {
|
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
|
// paint page number
|
||||||
val num = "${page+1}"
|
val num = "${page+1}"
|
||||||
|
|||||||
@@ -14,6 +14,7 @@ import net.torvald.terrarum.btex.MovableTypeDrawCall
|
|||||||
import net.torvald.terrarum.ceilToFloat
|
import net.torvald.terrarum.ceilToFloat
|
||||||
import net.torvald.terrarum.gameitems.ItemID
|
import net.torvald.terrarum.gameitems.ItemID
|
||||||
import net.torvald.terrarum.toHex
|
import net.torvald.terrarum.toHex
|
||||||
|
import net.torvald.terrarum.tryDispose
|
||||||
import net.torvald.terrarum.ui.Toolkit
|
import net.torvald.terrarum.ui.Toolkit
|
||||||
import net.torvald.terrarum.worlddrawer.toRGBA
|
import net.torvald.terrarum.worlddrawer.toRGBA
|
||||||
import net.torvald.terrarumsansbitmap.MovableType
|
import net.torvald.terrarumsansbitmap.MovableType
|
||||||
@@ -42,22 +43,24 @@ object BTeXParser {
|
|||||||
|
|
||||||
operator fun invoke(file: FileHandle) = invoke(file.file())
|
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 doc = BTeXDocument()
|
||||||
val parser = SAXParserFactory.newDefaultInstance().newSAXParser()
|
val parser = SAXParserFactory.newDefaultInstance().newSAXParser()
|
||||||
val stream = FileInputStream(file)
|
val stream = FileInputStream(file)
|
||||||
parser.parse(stream, BTeXHandler(doc))
|
val handler = BTeXHandler(doc)
|
||||||
return 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 doc = BTeXDocument()
|
||||||
val parser = SAXParserFactory.newDefaultInstance().newSAXParser()
|
val parser = SAXParserFactory.newDefaultInstance().newSAXParser()
|
||||||
parser.parse(InputSource(StringReader(string)), BTeXHandler(doc))
|
val handler = BTeXHandler(doc)
|
||||||
return 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 DEFAULT_FONTCOL = DEFAULT_PAGE_FORE
|
||||||
private val LINE_HEIGHT = doc.lineHeightInPx
|
private val LINE_HEIGHT = doc.lineHeightInPx
|
||||||
|
|
||||||
@@ -101,6 +104,12 @@ object BTeXParser {
|
|||||||
private var hasCover = false
|
private var hasCover = false
|
||||||
private var coverCol: Color? = null
|
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 {
|
init {
|
||||||
BTeXHandler::class.declaredFunctions.filter { it.findAnnotation<OpenTag>() != null }.forEach {
|
BTeXHandler::class.declaredFunctions.filter { it.findAnnotation<OpenTag>() != null }.forEach {
|
||||||
// println("Tag opener: ${it.name}")
|
// 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?) {
|
private fun printdbg(message: String?) {
|
||||||
val CSI = "\u001B[32m"
|
val CSI = "\u001B[32m"
|
||||||
val timeNow = System.currentTimeMillis()
|
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) {
|
private fun getFont() = when (cover) {
|
||||||
"typewriter" -> TODO()
|
"typewriter" -> TODO()
|
||||||
else -> {
|
else -> {
|
||||||
if (!::testFont.isInitialized) testFont = TerrarumSansBitmap(App.FONT_DIR, shadowAlpha = bodyTextShadowAlpha)
|
if (!::testFont.isInitialized) testFont = TerrarumSansBitmap(App.FONT_DIR, shadowAlpha = bodyTextShadowAlpha, textCacheSize = 65536)
|
||||||
testFont
|
testFont
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -841,7 +850,7 @@ object BTeXParser {
|
|||||||
|
|
||||||
private fun typesetBookTitle(thePar: String, handler: BTeXHandler) {
|
private fun typesetBookTitle(thePar: String, handler: BTeXHandler) {
|
||||||
val label = "\n" + thePar
|
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 }
|
val addedLines = it.sumOf { it.lineCount }
|
||||||
doc.linesPrintedOnPage[doc.currentPage] += addedLines
|
doc.linesPrintedOnPage[doc.currentPage] += addedLines
|
||||||
|
|
||||||
|
|||||||
@@ -16,6 +16,7 @@ import net.torvald.terrarum.btex.BTeXDocument
|
|||||||
import net.torvald.terrarum.ceilToInt
|
import net.torvald.terrarum.ceilToInt
|
||||||
import net.torvald.terrarum.gdxClearAndEnableBlend
|
import net.torvald.terrarum.gdxClearAndEnableBlend
|
||||||
import net.torvald.terrarum.inUse
|
import net.torvald.terrarum.inUse
|
||||||
|
import kotlin.system.measureTimeMillis
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -24,11 +25,13 @@ import net.torvald.terrarum.inUse
|
|||||||
class BTeXTest : ApplicationAdapter() {
|
class BTeXTest : ApplicationAdapter() {
|
||||||
|
|
||||||
// val filePath = "btex.xml"
|
// 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"
|
// val filePath = "literature/koKR/yisang_nalgae.xml"
|
||||||
|
|
||||||
|
|
||||||
private lateinit var document: BTeXDocument
|
private lateinit var document: BTeXDocument
|
||||||
|
private lateinit var documentHandler: BTeXParser.BTeXHandler
|
||||||
private lateinit var batch: FlippingSpriteBatch
|
private lateinit var batch: FlippingSpriteBatch
|
||||||
private lateinit var camera: OrthographicCamera
|
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")))
|
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
|
private var scroll = 0
|
||||||
|
|||||||
Reference in New Issue
Block a user