mirror of
https://github.com/curioustorvald/Terrarum.git
synced 2026-06-12 03:24:06 +09:00
print book without GPU
This commit is contained in:
9
.idea/artifacts/TerrarumBuild.xml
generated
9
.idea/artifacts/TerrarumBuild.xml
generated
@@ -30,13 +30,7 @@
|
|||||||
<element id="extracted-dir" path="$PROJECT_DIR$/lib/JTransforms-3.1.jar" path-in-jar="/" />
|
<element id="extracted-dir" path="$PROJECT_DIR$/lib/JTransforms-3.1.jar" path-in-jar="/" />
|
||||||
<element id="extracted-dir" path="$PROJECT_DIR$/lib/JLargeArrays-1.5.jar" path-in-jar="/" />
|
<element id="extracted-dir" path="$PROJECT_DIR$/lib/JLargeArrays-1.5.jar" path-in-jar="/" />
|
||||||
<element id="extracted-dir" path="$PROJECT_DIR$/lib/aircompressor-0.25.jar" path-in-jar="/" />
|
<element id="extracted-dir" path="$PROJECT_DIR$/lib/aircompressor-0.25.jar" path-in-jar="/" />
|
||||||
<element id="extracted-dir" path="$MAVEN_REPOSITORY$/org/jetbrains/kotlin/kotlin-stdlib-jdk8/1.8.22/kotlin-stdlib-jdk8-1.8.22.jar" path-in-jar="/" />
|
|
||||||
<element id="extracted-dir" path="$MAVEN_REPOSITORY$/org/jetbrains/kotlin/kotlin-stdlib/1.8.22/kotlin-stdlib-1.8.22.jar" path-in-jar="/" />
|
|
||||||
<element id="extracted-dir" path="$MAVEN_REPOSITORY$/org/jetbrains/kotlin/kotlin-stdlib-common/1.8.22/kotlin-stdlib-common-1.8.22.jar" path-in-jar="/" />
|
|
||||||
<element id="extracted-dir" path="$MAVEN_REPOSITORY$/org/jetbrains/annotations/13.0/annotations-13.0.jar" path-in-jar="/" />
|
<element id="extracted-dir" path="$MAVEN_REPOSITORY$/org/jetbrains/annotations/13.0/annotations-13.0.jar" path-in-jar="/" />
|
||||||
<element id="extracted-dir" path="$MAVEN_REPOSITORY$/org/jetbrains/kotlin/kotlin-stdlib-jdk7/1.8.22/kotlin-stdlib-jdk7-1.8.22.jar" path-in-jar="/" />
|
|
||||||
<element id="extracted-dir" path="$MAVEN_REPOSITORY$/org/jetbrains/kotlin/kotlin-reflect/1.8.22/kotlin-reflect-1.8.22.jar" path-in-jar="/" />
|
|
||||||
<element id="extracted-dir" path="$MAVEN_REPOSITORY$/org/jetbrains/kotlin/kotlin-test/1.8.22/kotlin-test-1.8.22.jar" path-in-jar="/" />
|
|
||||||
<element id="extracted-dir" path="$PROJECT_DIR$/lib/gdx-1.12.1.jar" path-in-jar="/" />
|
<element id="extracted-dir" path="$PROJECT_DIR$/lib/gdx-1.12.1.jar" path-in-jar="/" />
|
||||||
<element id="extracted-dir" path="$PROJECT_DIR$/lib/gdx-backend-lwjgl3-1.12.1.jar" path-in-jar="/" />
|
<element id="extracted-dir" path="$PROJECT_DIR$/lib/gdx-backend-lwjgl3-1.12.1.jar" path-in-jar="/" />
|
||||||
<element id="extracted-dir" path="$PROJECT_DIR$/lib/lwjgl-3.3.3.jar" path-in-jar="/" />
|
<element id="extracted-dir" path="$PROJECT_DIR$/lib/lwjgl-3.3.3.jar" path-in-jar="/" />
|
||||||
@@ -91,6 +85,9 @@
|
|||||||
<element id="extracted-dir" path="$PROJECT_DIR$/lib/gdx-platform-1.12.1-natives-desktop.jar" path-in-jar="/" />
|
<element id="extracted-dir" path="$PROJECT_DIR$/lib/gdx-platform-1.12.1-natives-desktop.jar" path-in-jar="/" />
|
||||||
<element id="extracted-dir" path="$PROJECT_DIR$/lib/gdx-platform-1.12.1-natives-x86_64.jar" path-in-jar="/" />
|
<element id="extracted-dir" path="$PROJECT_DIR$/lib/gdx-platform-1.12.1-natives-x86_64.jar" path-in-jar="/" />
|
||||||
<element id="extracted-dir" path="$PROJECT_DIR$/lib/TerranVirtualDisk.jar" path-in-jar="/" />
|
<element id="extracted-dir" path="$PROJECT_DIR$/lib/TerranVirtualDisk.jar" path-in-jar="/" />
|
||||||
|
<element id="extracted-dir" path="$MAVEN_REPOSITORY$/org/jetbrains/kotlin/kotlin-stdlib-jdk8/1.9.24/kotlin-stdlib-jdk8-1.9.24.jar" path-in-jar="/" />
|
||||||
|
<element id="extracted-dir" path="$MAVEN_REPOSITORY$/org/jetbrains/kotlin/kotlin-stdlib/1.9.24/kotlin-stdlib-1.9.24.jar" path-in-jar="/" />
|
||||||
|
<element id="extracted-dir" path="$MAVEN_REPOSITORY$/org/jetbrains/kotlin/kotlin-stdlib-jdk7/1.9.24/kotlin-stdlib-jdk7-1.9.24.jar" path-in-jar="/" />
|
||||||
</root>
|
</root>
|
||||||
</artifact>
|
</artifact>
|
||||||
</component>
|
</component>
|
||||||
23
.idea/libraries/KotlinJavaRuntime.xml
generated
23
.idea/libraries/KotlinJavaRuntime.xml
generated
@@ -1,26 +1,23 @@
|
|||||||
<component name="libraryTable">
|
<component name="libraryTable">
|
||||||
<library name="KotlinJavaRuntime" type="repository">
|
<library name="KotlinJavaRuntime" type="repository">
|
||||||
<properties maven-id="org.jetbrains.kotlin:kotlin-stdlib-jdk8:1.8.22" />
|
<properties maven-id="org.jetbrains.kotlin:kotlin-stdlib-jdk8:1.9.24" />
|
||||||
<CLASSES>
|
<CLASSES>
|
||||||
<root url="jar://$MAVEN_REPOSITORY$/org/jetbrains/kotlin/kotlin-stdlib-jdk8/1.8.22/kotlin-stdlib-jdk8-1.8.22.jar!/" />
|
<root url="jar://$MAVEN_REPOSITORY$/org/jetbrains/kotlin/kotlin-stdlib-jdk8/1.9.24/kotlin-stdlib-jdk8-1.9.24.jar!/" />
|
||||||
<root url="jar://$MAVEN_REPOSITORY$/org/jetbrains/kotlin/kotlin-stdlib/1.8.22/kotlin-stdlib-1.8.22.jar!/" />
|
<root url="jar://$MAVEN_REPOSITORY$/org/jetbrains/kotlin/kotlin-stdlib/1.9.24/kotlin-stdlib-1.9.24.jar!/" />
|
||||||
<root url="jar://$MAVEN_REPOSITORY$/org/jetbrains/kotlin/kotlin-stdlib-common/1.8.22/kotlin-stdlib-common-1.8.22.jar!/" />
|
|
||||||
<root url="jar://$MAVEN_REPOSITORY$/org/jetbrains/annotations/13.0/annotations-13.0.jar!/" />
|
<root url="jar://$MAVEN_REPOSITORY$/org/jetbrains/annotations/13.0/annotations-13.0.jar!/" />
|
||||||
<root url="jar://$MAVEN_REPOSITORY$/org/jetbrains/kotlin/kotlin-stdlib-jdk7/1.8.22/kotlin-stdlib-jdk7-1.8.22.jar!/" />
|
<root url="jar://$MAVEN_REPOSITORY$/org/jetbrains/kotlin/kotlin-stdlib-jdk7/1.9.24/kotlin-stdlib-jdk7-1.9.24.jar!/" />
|
||||||
</CLASSES>
|
</CLASSES>
|
||||||
<JAVADOC>
|
<JAVADOC>
|
||||||
<root url="jar://$MAVEN_REPOSITORY$/org/jetbrains/kotlin/kotlin-stdlib-jdk8/1.8.22/kotlin-stdlib-jdk8-1.8.22-javadoc.jar!/" />
|
<root url="jar://$MAVEN_REPOSITORY$/org/jetbrains/kotlin/kotlin-stdlib-jdk8/1.9.24/kotlin-stdlib-jdk8-1.9.24-javadoc.jar!/" />
|
||||||
<root url="jar://$MAVEN_REPOSITORY$/org/jetbrains/kotlin/kotlin-stdlib/1.8.22/kotlin-stdlib-1.8.22-javadoc.jar!/" />
|
<root url="jar://$MAVEN_REPOSITORY$/org/jetbrains/kotlin/kotlin-stdlib/1.9.24/kotlin-stdlib-1.9.24-javadoc.jar!/" />
|
||||||
<root url="jar://$MAVEN_REPOSITORY$/org/jetbrains/kotlin/kotlin-stdlib-common/1.8.22/kotlin-stdlib-common-1.8.22-javadoc.jar!/" />
|
|
||||||
<root url="jar://$MAVEN_REPOSITORY$/org/jetbrains/annotations/13.0/annotations-13.0-javadoc.jar!/" />
|
<root url="jar://$MAVEN_REPOSITORY$/org/jetbrains/annotations/13.0/annotations-13.0-javadoc.jar!/" />
|
||||||
<root url="jar://$MAVEN_REPOSITORY$/org/jetbrains/kotlin/kotlin-stdlib-jdk7/1.8.22/kotlin-stdlib-jdk7-1.8.22-javadoc.jar!/" />
|
<root url="jar://$MAVEN_REPOSITORY$/org/jetbrains/kotlin/kotlin-stdlib-jdk7/1.9.24/kotlin-stdlib-jdk7-1.9.24-javadoc.jar!/" />
|
||||||
</JAVADOC>
|
</JAVADOC>
|
||||||
<SOURCES>
|
<SOURCES>
|
||||||
<root url="jar://$MAVEN_REPOSITORY$/org/jetbrains/kotlin/kotlin-stdlib-jdk8/1.8.22/kotlin-stdlib-jdk8-1.8.22-sources.jar!/" />
|
<root url="jar://$MAVEN_REPOSITORY$/org/jetbrains/kotlin/kotlin-stdlib-jdk8/1.9.24/kotlin-stdlib-jdk8-1.9.24-sources.jar!/" />
|
||||||
<root url="jar://$MAVEN_REPOSITORY$/org/jetbrains/kotlin/kotlin-stdlib/1.8.22/kotlin-stdlib-1.8.22-sources.jar!/" />
|
<root url="jar://$MAVEN_REPOSITORY$/org/jetbrains/kotlin/kotlin-stdlib/1.9.24/kotlin-stdlib-1.9.24-sources.jar!/" />
|
||||||
<root url="jar://$MAVEN_REPOSITORY$/org/jetbrains/kotlin/kotlin-stdlib-common/1.8.22/kotlin-stdlib-common-1.8.22-sources.jar!/" />
|
|
||||||
<root url="jar://$MAVEN_REPOSITORY$/org/jetbrains/annotations/13.0/annotations-13.0-sources.jar!/" />
|
<root url="jar://$MAVEN_REPOSITORY$/org/jetbrains/annotations/13.0/annotations-13.0-sources.jar!/" />
|
||||||
<root url="jar://$MAVEN_REPOSITORY$/org/jetbrains/kotlin/kotlin-stdlib-jdk7/1.8.22/kotlin-stdlib-jdk7-1.8.22-sources.jar!/" />
|
<root url="jar://$MAVEN_REPOSITORY$/org/jetbrains/kotlin/kotlin-stdlib-jdk7/1.9.24/kotlin-stdlib-jdk7-1.9.24-sources.jar!/" />
|
||||||
</SOURCES>
|
</SOURCES>
|
||||||
</library>
|
</library>
|
||||||
</component>
|
</component>
|
||||||
BIN
lib/TerrarumSansBitmap.jar
LFS
BIN
lib/TerrarumSansBitmap.jar
LFS
Binary file not shown.
@@ -5,14 +5,15 @@ import com.badlogic.gdx.files.FileHandle
|
|||||||
import com.badlogic.gdx.graphics.*
|
import com.badlogic.gdx.graphics.*
|
||||||
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 com.badlogic.gdx.utils.Disposable
|
||||||
import net.torvald.terrarum.*
|
import net.torvald.terrarum.FlippingSpriteBatch
|
||||||
|
import net.torvald.terrarum.ceilToInt
|
||||||
import net.torvald.terrarum.imagefont.TinyAlphNum
|
import net.torvald.terrarum.imagefont.TinyAlphNum
|
||||||
import net.torvald.terrarum.modulecomputers.virtualcomputer.tvd.archivers.ClusteredFormatDOM
|
import net.torvald.terrarum.modulecomputers.virtualcomputer.tvd.archivers.ClusteredFormatDOM
|
||||||
import net.torvald.terrarum.modulecomputers.virtualcomputer.tvd.archivers.Clustfile
|
import net.torvald.terrarum.modulecomputers.virtualcomputer.tvd.archivers.Clustfile
|
||||||
import net.torvald.terrarum.modulecomputers.virtualcomputer.tvd.archivers.ClustfileOutputStream
|
import net.torvald.terrarum.modulecomputers.virtualcomputer.tvd.archivers.ClustfileOutputStream
|
||||||
import net.torvald.terrarum.serialise.Common
|
import net.torvald.terrarum.serialise.Common
|
||||||
|
import net.torvald.terrarum.tryDispose
|
||||||
import net.torvald.terrarum.ui.Toolkit
|
import net.torvald.terrarum.ui.Toolkit
|
||||||
import net.torvald.terrarum.utils.JsonFetcher
|
import net.torvald.terrarum.utils.JsonFetcher
|
||||||
import net.torvald.terrarumsansbitmap.MovableType
|
import net.torvald.terrarumsansbitmap.MovableType
|
||||||
@@ -57,6 +58,7 @@ class BTeXDocument : Disposable {
|
|||||||
val DEFAULT_PAGE_BACK = Color(0xe0dfdb_ff.toInt())
|
val DEFAULT_PAGE_BACK = Color(0xe0dfdb_ff.toInt())
|
||||||
// val DEFAULT_PAGE_FORE = Color(0x0a0706_ff)
|
// val DEFAULT_PAGE_FORE = Color(0x0a0706_ff)
|
||||||
val DEFAULT_ORNAMENTS_COL = Color(0x3f3c3b_ff)
|
val DEFAULT_ORNAMENTS_COL = Color(0x3f3c3b_ff)
|
||||||
|
val ccPagenum = TerrarumSansBitmap.toColorCode(0xf333)
|
||||||
|
|
||||||
private fun String.escape() = this.replace("\"", "\\\"")
|
private fun String.escape() = this.replace("\"", "\\\"")
|
||||||
|
|
||||||
@@ -84,7 +86,7 @@ class BTeXDocument : Disposable {
|
|||||||
doc.inner = metaJson["inner"].asString()
|
doc.inner = metaJson["inner"].asString()
|
||||||
doc.papersize = metaJson["papersize"].asString()
|
doc.papersize = metaJson["papersize"].asString()
|
||||||
doc.fromArchive = true
|
doc.fromArchive = true
|
||||||
doc.pageTextures = ArrayList()
|
doc.pageTextures = Array(pageCount) { null }
|
||||||
|
|
||||||
|
|
||||||
println("Title: ${doc.theTitle}")
|
println("Title: ${doc.theTitle}")
|
||||||
@@ -97,7 +99,7 @@ class BTeXDocument : Disposable {
|
|||||||
val tempFile = Gdx.files.external("./.btex-import.png") // must create new file descriptor for every page, or else every page will share a single file descriptor which cause problems
|
val tempFile = Gdx.files.external("./.btex-import.png") // must create new file descriptor for every page, or else every page will share a single file descriptor which cause problems
|
||||||
it.exportFileTo(tempFile.file())
|
it.exportFileTo(tempFile.file())
|
||||||
val texture = TextureRegion(Texture(tempFile))
|
val texture = TextureRegion(Texture(tempFile))
|
||||||
doc.pageTextures.add(texture)
|
doc.pageTextures[page] = texture
|
||||||
|
|
||||||
if (page == 0) {
|
if (page == 0) {
|
||||||
doc.textWidth = texture.regionWidth - 2 * doc.pageMarginH
|
doc.textWidth = texture.regionWidth - 2 * doc.pageMarginH
|
||||||
@@ -117,8 +119,8 @@ class BTeXDocument : Disposable {
|
|||||||
|
|
||||||
internal val pages = ArrayList<BTeXPage>()
|
internal val pages = ArrayList<BTeXPage>()
|
||||||
|
|
||||||
private lateinit var pageTextures: ArrayList<TextureRegion>
|
private lateinit var pagePixmaps: Array<Pixmap?>
|
||||||
private lateinit var pageFrameBuffers: ArrayList<FrameBuffer>
|
private lateinit var pageTextures: Array<TextureRegion?>
|
||||||
|
|
||||||
val currentPage: Int
|
val currentPage: Int
|
||||||
get() = pages.size - 1
|
get() = pages.size - 1
|
||||||
@@ -143,53 +145,44 @@ class BTeXDocument : Disposable {
|
|||||||
linesPrintedOnPage.add(index, 0)
|
linesPrintedOnPage.add(index, 0)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private val lock = Any()
|
||||||
|
private val texturefiedPages = HashSet<Int>()
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Must be called on a thread with GL context!
|
* Must be called on a thread with GL context!
|
||||||
*/
|
*/
|
||||||
fun finalise() {
|
fun finalise(multithread: Boolean = false) {
|
||||||
if (fromArchive) throw IllegalStateException("Document is loaded from the archive and thus cannot be finalised")
|
synchronized(lock) {
|
||||||
if (isFinalised) throw IllegalStateException("Page is already been finalised")
|
if (fromArchive) throw IllegalStateException("Document is loaded from the archive and thus cannot be finalised")
|
||||||
|
if (isFinalised) throw IllegalStateException("Page is already been finalised")
|
||||||
|
|
||||||
// TODO serialise and finalise via CPU (store every page as Pixmap)
|
// serialise and finalise via CPU (store every page as Pixmap)
|
||||||
|
|
||||||
pageTextures = ArrayList()
|
pageTextures = Array(pages.size) { null }
|
||||||
pageFrameBuffers = ArrayList()
|
pagePixmaps = Array(pages.size) { null }
|
||||||
|
|
||||||
val camera = OrthographicCamera(pageDimensionWidth.toFloat(), pageDimensionHeight.toFloat())
|
pages.forEachIndexed { pageNum, page ->
|
||||||
val batch = FlippingSpriteBatch()
|
val pixmap = Pixmap(pageDimensionWidth, pageDimensionHeight, Pixmap.Format.RGBA8888).also {
|
||||||
|
it.blending = Pixmap.Blending.SourceOver
|
||||||
pages.forEachIndexed { pageNum, page ->
|
it.filter = Pixmap.Filter.NearestNeighbour
|
||||||
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)
|
|
||||||
printPageNumber(batch, pageNum, 0, 0)
|
|
||||||
}
|
}
|
||||||
|
page.renderToPixmap(pixmap, 0, 0, pageMarginH, pageMarginV)
|
||||||
|
printPageNumber(pixmap, pageNum, 0, 0)
|
||||||
|
pagePixmaps[pageNum] = pixmap
|
||||||
}
|
}
|
||||||
|
|
||||||
pageTextures.add(TextureRegion(fbo.colorBufferTexture))
|
isFinalised = true
|
||||||
pageFrameBuffers.add(fbo)
|
|
||||||
}
|
}
|
||||||
isFinalised = true
|
|
||||||
|
|
||||||
batch.dispose()
|
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun dispose() {
|
override fun dispose() {
|
||||||
if (isFinalised) {
|
if (isFinalised) {
|
||||||
pageTextures.forEach { it.texture.dispose() }
|
pageTextures.forEach { it?.texture?.dispose() }
|
||||||
pageFrameBuffers.forEach { it.dispose() }
|
pagePixmaps.forEach { it?.tryDispose() }
|
||||||
}
|
}
|
||||||
else if (fromArchive) {
|
else if (fromArchive) {
|
||||||
pageTextures.forEach { it.texture.dispose() }
|
pageTextures.forEach { it?.texture?.dispose() }
|
||||||
|
pagePixmaps.forEach { it?.tryDispose() }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -218,13 +211,9 @@ class BTeXDocument : Disposable {
|
|||||||
it.writeBytes(json.encodeToByteArray())
|
it.writeBytes(json.encodeToByteArray())
|
||||||
}
|
}
|
||||||
|
|
||||||
pageFrameBuffers.forEachIndexed { index, fbo ->
|
pagePixmaps.forEachIndexed { index, pixmap ->
|
||||||
val file = Clustfile(DOM, "$index.png").also {
|
Clustfile(DOM, "$index.png").also { file ->
|
||||||
it.createNewFile()
|
file.createNewFile()
|
||||||
}
|
|
||||||
|
|
||||||
fbo.inAction(null, null) {
|
|
||||||
val pixmap = Pixmap.createFromFrameBuffer(0, 0, fbo.width, fbo.height)
|
|
||||||
val tempFile = Gdx.files.external("./.btex-export.png")
|
val tempFile = Gdx.files.external("./.btex-export.png")
|
||||||
PixmapIO.writePNG(tempFile, pixmap, Deflater.BEST_COMPRESSION, false)
|
PixmapIO.writePNG(tempFile, pixmap, Deflater.BEST_COMPRESSION, false)
|
||||||
val outstream = ClustfileOutputStream(file)
|
val outstream = ClustfileOutputStream(file)
|
||||||
@@ -262,8 +251,13 @@ class BTeXDocument : Disposable {
|
|||||||
fun render(frameDelta: Float, batch: SpriteBatch, page: Int, x: Int, y: Int) {
|
fun render(frameDelta: Float, batch: SpriteBatch, page: Int, x: Int, y: Int) {
|
||||||
batch.color = Color.WHITE
|
batch.color = Color.WHITE
|
||||||
|
|
||||||
if (isFinalised || fromArchive)
|
if (fromArchive || isFinalised && texturefiedPages.contains(page))
|
||||||
batch.draw(pageTextures[page], x.toFloat(), y.toFloat())
|
batch.draw(pageTextures[page], x.toFloat(), y.toFloat())
|
||||||
|
else if (isFinalised && !texturefiedPages.contains(page)) {
|
||||||
|
pageTextures[page] = TextureRegion(Texture(pagePixmaps[page]))
|
||||||
|
texturefiedPages.add(page)
|
||||||
|
batch.draw(pageTextures[page], x.toFloat(), y.toFloat())
|
||||||
|
}
|
||||||
else {
|
else {
|
||||||
pages[page].render(frameDelta, batch, x, y, pageMarginH, pageMarginV)
|
pages[page].render(frameDelta, batch, x, y, pageMarginH, pageMarginV)
|
||||||
printPageNumber(batch, page, x, y)
|
printPageNumber(batch, page, x, y)
|
||||||
@@ -289,6 +283,26 @@ class BTeXDocument : Disposable {
|
|||||||
TinyAlphNum.draw(batch, num, numX.toFloat(), numY.toFloat())
|
TinyAlphNum.draw(batch, num, numX.toFloat(), numY.toFloat())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private fun printPageNumber(pixmap: Pixmap, page: Int, x: Int, y: Int) {
|
||||||
|
val num = "${page + 1}"
|
||||||
|
val numW = TinyAlphNum.getWidth(num)
|
||||||
|
val numX = if (context == "tome") {
|
||||||
|
if (page % 2 == 1)
|
||||||
|
x + pageMarginH
|
||||||
|
else
|
||||||
|
x + pageDimensionWidth - pageMarginH - numW
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
x + (pageDimensionWidth - numW) / 2
|
||||||
|
}
|
||||||
|
val numY = y + pageDimensionHeight - 2 * pageMarginV - 4
|
||||||
|
|
||||||
|
if (page == 0 && context != "tome" || page in tocPageStart until endOfPageStart) {
|
||||||
|
pixmap.setColor(DEFAULT_ORNAMENTS_COL)
|
||||||
|
TinyAlphNum.drawToPixmap(pixmap, "$ccPagenum$num", numX, numY)
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
class BTeXPage(
|
class BTeXPage(
|
||||||
@@ -320,6 +334,18 @@ class BTeXPage(
|
|||||||
|
|
||||||
fun isEmpty() = drawCalls.isEmpty()
|
fun isEmpty() = drawCalls.isEmpty()
|
||||||
fun isNotEmpty() = drawCalls.isNotEmpty()
|
fun isNotEmpty() = drawCalls.isNotEmpty()
|
||||||
|
fun renderToPixmap(pixmap: Pixmap, x: Int, y: Int, marginH: Int, marginV: Int) {
|
||||||
|
drawCalls.sortedBy { if (it.text != null) 16 else 0 }.let { drawCalls ->
|
||||||
|
val backCol = back.cpy().also { it.a = 0.93f }
|
||||||
|
pixmap.setColor(backCol)
|
||||||
|
pixmap.fill()
|
||||||
|
|
||||||
|
pixmap.setColor(Color.WHITE)
|
||||||
|
drawCalls.forEach {
|
||||||
|
it.drawToPixmap(pixmap, x + marginH, y + marginV)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -328,6 +354,10 @@ data class TypesetDrawCall(val movableType: MovableType, val rowStart: Int, val
|
|||||||
fun draw(doc: BTeXDocument, batch: SpriteBatch, x: Float, y: Float) {
|
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))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fun drawToPixmap(doc: BTeXDocument, pixmap: Pixmap, x: Int, y: Int) {
|
||||||
|
movableType.drawToPixmap(pixmap, x, y, rowStart, minOf(rows, doc.pageLines))
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
abstract class BTeXBatchDrawCall(
|
abstract class BTeXBatchDrawCall(
|
||||||
@@ -336,6 +366,7 @@ abstract class BTeXBatchDrawCall(
|
|||||||
val parentText: BTeXDrawCall?// = null
|
val parentText: BTeXDrawCall?// = null
|
||||||
) {
|
) {
|
||||||
abstract fun draw(doc: BTeXDocument, batch: SpriteBatch, x: Float, y: Float, font: TerrarumSansBitmap? = null)
|
abstract fun draw(doc: BTeXDocument, batch: SpriteBatch, x: Float, y: Float, font: TerrarumSansBitmap? = null)
|
||||||
|
abstract fun drawToPixmap(doc: BTeXDocument, pixmap: Pixmap, x: Int, y: Int, font: TerrarumSansBitmap? = null)
|
||||||
}
|
}
|
||||||
|
|
||||||
class BTeXDrawCall(
|
class BTeXDrawCall(
|
||||||
@@ -359,11 +390,6 @@ class BTeXDrawCall(
|
|||||||
val px = (posX + x).toFloat()
|
val px = (posX + x).toFloat()
|
||||||
val py = (posY + y).toFloat()
|
val py = (posY + y).toFloat()
|
||||||
|
|
||||||
if (theme == "code") {
|
|
||||||
// todo draw code background
|
|
||||||
println("code themed")
|
|
||||||
}
|
|
||||||
|
|
||||||
extraDrawFun(batch, px, py)
|
extraDrawFun(batch, px, py)
|
||||||
|
|
||||||
batch.color = Color.WHITE
|
batch.color = Color.WHITE
|
||||||
@@ -384,6 +410,23 @@ class BTeXDrawCall(
|
|||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fun drawToPixmap(pixmap: Pixmap, x: Int, y: Int) {
|
||||||
|
val px = posX + x
|
||||||
|
val py = posY + y
|
||||||
|
|
||||||
|
extraPixmapDrawFun(pixmap, px, py)
|
||||||
|
|
||||||
|
pixmap.setColor(Color.WHITE)
|
||||||
|
|
||||||
|
if (text != null && cmd == null) {
|
||||||
|
text.drawToPixmap(doc, pixmap, px, py)
|
||||||
|
}
|
||||||
|
else if (text == null && cmd != null) {
|
||||||
|
cmd.drawToPixmap(doc, pixmap, px, py, font)
|
||||||
|
}
|
||||||
|
else throw Error("Text and Texture are both non-null")
|
||||||
|
}
|
||||||
|
|
||||||
internal val width: Int
|
internal val width: Int
|
||||||
get() = if (text != null)
|
get() = if (text != null)
|
||||||
text.movableType.width * text.movableType.font.scale
|
text.movableType.width * text.movableType.font.scale
|
||||||
@@ -391,6 +434,7 @@ class BTeXDrawCall(
|
|||||||
cmd!!.width
|
cmd!!.width
|
||||||
|
|
||||||
internal var extraDrawFun: (SpriteBatch, Float, Float) -> Unit = { _, _, _ ->}
|
internal var extraDrawFun: (SpriteBatch, Float, Float) -> Unit = { _, _, _ ->}
|
||||||
|
internal var extraPixmapDrawFun: (Pixmap, Int, Int) -> Unit = { _, _, _ ->}
|
||||||
internal val lineCount = if (text != null)
|
internal val lineCount = if (text != null)
|
||||||
text.rows
|
text.rows
|
||||||
else
|
else
|
||||||
|
|||||||
@@ -2,7 +2,9 @@ package net.torvald.btex
|
|||||||
|
|
||||||
import com.badlogic.gdx.files.FileHandle
|
import com.badlogic.gdx.files.FileHandle
|
||||||
import com.badlogic.gdx.graphics.Color
|
import com.badlogic.gdx.graphics.Color
|
||||||
|
import com.badlogic.gdx.graphics.Pixmap
|
||||||
import com.badlogic.gdx.graphics.g2d.SpriteBatch
|
import com.badlogic.gdx.graphics.g2d.SpriteBatch
|
||||||
|
import com.badlogic.gdx.utils.Disposable
|
||||||
import com.jme3.math.FastMath.DEG_TO_RAD
|
import com.jme3.math.FastMath.DEG_TO_RAD
|
||||||
import net.torvald.colourutil.OKLch
|
import net.torvald.colourutil.OKLch
|
||||||
import net.torvald.colourutil.tosRGB
|
import net.torvald.colourutil.tosRGB
|
||||||
@@ -121,13 +123,6 @@ 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 partTitleFont: TerrarumSansBitmap
|
|
||||||
private lateinit var titleFont: TerrarumSansBitmap
|
|
||||||
private lateinit var subtitleFont: TerrarumSansBitmap
|
|
||||||
|
|
||||||
private val bodyTextShadowAlpha = 0.36f
|
|
||||||
|
|
||||||
private val macrodefs = hashMapOf(
|
private val macrodefs = hashMapOf(
|
||||||
"thepart" to "Part %1\$s",
|
"thepart" to "Part %1\$s",
|
||||||
"parttype" to "I",
|
"parttype" to "I",
|
||||||
@@ -158,6 +153,10 @@ object BTeXParser {
|
|||||||
}
|
}
|
||||||
|
|
||||||
init {
|
init {
|
||||||
|
if (!fontInit) {
|
||||||
|
throw RuntimeException("Font not initialised: call BTeXParser.BTeXHandler.preloadFonts() WITHIN OpenGL-context thread to initialise the fonts.")
|
||||||
|
}
|
||||||
|
|
||||||
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}")
|
||||||
elemOpeners[it.name] = it
|
elemOpeners[it.name] = it
|
||||||
@@ -179,6 +178,14 @@ object BTeXParser {
|
|||||||
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)
|
||||||
}
|
}
|
||||||
|
override fun drawToPixmap(doc: BTeXDocument, pixmap: Pixmap, x: Int, y: Int, font: TerrarumSansBitmap?) {
|
||||||
|
val scale = font!!.scale
|
||||||
|
val interchar = font.interchar
|
||||||
|
font.drawToPixmap(pixmap, "${ccDefault}B", x + ( 0 + 0*interchar)*scale, y + 0*scale)
|
||||||
|
font.drawToPixmap(pixmap, "${ccDefault}T", x + ( 8 + 1*interchar)*scale, y + 0*scale)
|
||||||
|
font.drawToPixmap(pixmap, "${ccDefault}E", x + (15 + 2*interchar)*scale, y + 4*scale)
|
||||||
|
font.drawToPixmap(pixmap, "${ccDefault}X", x + (23 + 3*interchar)*scale, y + 0*scale)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -194,6 +201,15 @@ object BTeXParser {
|
|||||||
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)
|
||||||
}
|
}
|
||||||
|
override fun drawToPixmap(doc: BTeXDocument, pixmap: Pixmap, x: Int, y: Int, font: TerrarumSansBitmap?) {
|
||||||
|
val scale = font!!.scale
|
||||||
|
val interchar = font.interchar
|
||||||
|
font.drawToPixmap(pixmap, "${ccDefault}L", x + (0 + 0 * interchar) * scale, y + 0 * scale)
|
||||||
|
font.drawToPixmap(pixmap, "${ccDefault}ᴀ", x + (4 + 0 * interchar) * scale, y + -4 * scale)
|
||||||
|
font.drawToPixmap(pixmap, "${ccDefault}T", x + (12 + 1 * interchar) * scale, y + 0 * scale)
|
||||||
|
font.drawToPixmap(pixmap, "${ccDefault}E", x + (19 + 2 * interchar) * scale, y + 4 * scale)
|
||||||
|
font.drawToPixmap(pixmap, "${ccDefault}X", x + (27 + 3 * interchar) * scale, y + 0 * scale)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -207,17 +223,17 @@ object BTeXParser {
|
|||||||
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)
|
||||||
}
|
}
|
||||||
|
override fun drawToPixmap(doc: BTeXDocument, pixmap: Pixmap, x: Int, y: Int, font: TerrarumSansBitmap?) {
|
||||||
|
val scale = font!!.scale
|
||||||
|
val interchar = font.interchar
|
||||||
|
font.drawToPixmap(pixmap, "${ccDefault}T", x + (0 + 1 * interchar) * scale, y + 0 * scale)
|
||||||
|
font.drawToPixmap(pixmap, "${ccDefault}E", x + (7 + 2 * interchar) * scale, y + 4 * scale)
|
||||||
|
font.drawToPixmap(pixmap, "${ccDefault}X", x + (15 + 3 * interchar) * scale, y + 0 * scale)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fun dispose() {
|
|
||||||
if (::testFont.isInitialized) testFont.tryDispose()
|
|
||||||
if (::titleFont.isInitialized) titleFont.tryDispose()
|
|
||||||
if (::partTitleFont.isInitialized) partTitleFont.tryDispose()
|
|
||||||
if (::subtitleFont.isInitialized) subtitleFont.tryDispose()
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun warning(e: SAXParseException) {
|
override fun warning(e: SAXParseException) {
|
||||||
e.printStackTrace()
|
e.printStackTrace()
|
||||||
}
|
}
|
||||||
@@ -357,31 +373,18 @@ object BTeXParser {
|
|||||||
|
|
||||||
private fun getFont() = when (cover) {
|
private fun getFont() = when (cover) {
|
||||||
"typewriter" -> TODO()
|
"typewriter" -> TODO()
|
||||||
else -> {
|
else -> testFont
|
||||||
if (!::testFont.isInitialized) testFont = TerrarumSansBitmap(App.FONT_DIR, shadowAlpha = bodyTextShadowAlpha, textCacheSize = 4096)
|
|
||||||
testFont
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun getPartTitleFont(): TerrarumSansBitmap {
|
private fun getPartTitleFont(): TerrarumSansBitmap {
|
||||||
if (!::partTitleFont.isInitialized) partTitleFont = TerrarumSansBitmap(App.FONT_DIR, shadowAlpha = bodyTextShadowAlpha).also {
|
|
||||||
it.interchar = 1
|
|
||||||
}
|
|
||||||
return partTitleFont
|
return partTitleFont
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun getTitleFont(): TerrarumSansBitmap {
|
private fun getTitleFont(): TerrarumSansBitmap {
|
||||||
if (!::titleFont.isInitialized) titleFont = TerrarumSansBitmap(App.FONT_DIR).also {
|
|
||||||
it.interchar = 1
|
|
||||||
it.scale = 2
|
|
||||||
}
|
|
||||||
return titleFont
|
return titleFont
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun getSubtitleFont(): TerrarumSansBitmap {
|
private fun getSubtitleFont(): TerrarumSansBitmap {
|
||||||
if (!::subtitleFont.isInitialized) subtitleFont = TerrarumSansBitmap(App.FONT_DIR).also {
|
|
||||||
it.interchar = 1
|
|
||||||
}
|
|
||||||
return subtitleFont
|
return subtitleFont
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1020,6 +1023,27 @@ object BTeXParser {
|
|||||||
batch.color = oldcol
|
batch.color = oldcol
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
it.extraPixmapDrawFun = { pixmap, x, y ->
|
||||||
|
val width = doc.textWidth - 2 * MARGIN_PARBOX_H
|
||||||
|
val height = it.lineCount * doc.lineHeightInPx
|
||||||
|
|
||||||
|
if (height > 0) {
|
||||||
|
pixmap.setColor(Color(0xccccccff.toInt()))
|
||||||
|
pixmap.fillRectangle(
|
||||||
|
x - MARGIN_PARBOX_H,
|
||||||
|
y - MARGIN_PARBOX_V,
|
||||||
|
width + 2 * MARGIN_PARBOX_H,
|
||||||
|
height + 2 * MARGIN_PARBOX_V
|
||||||
|
)
|
||||||
|
pixmap.setColor(Color(0x999999ff.toInt()))
|
||||||
|
Toolkit.drawBoxBorderToPixmap(pixmap,
|
||||||
|
x - MARGIN_PARBOX_H,
|
||||||
|
y - MARGIN_PARBOX_V,
|
||||||
|
width + 2 * MARGIN_PARBOX_H,
|
||||||
|
height + 2 * MARGIN_PARBOX_V
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
insertOneEmptyLineOrAddNewPage()
|
insertOneEmptyLineOrAddNewPage()
|
||||||
@@ -1291,6 +1315,15 @@ object BTeXParser {
|
|||||||
batch.color = Color.WHITE
|
batch.color = Color.WHITE
|
||||||
Toolkit.fillArea(batch, px, py, pw, 1f)
|
Toolkit.fillArea(batch, px, py, pw, 1f)
|
||||||
}
|
}
|
||||||
|
it.last().extraPixmapDrawFun = { pixmap, x, y ->
|
||||||
|
val px = x
|
||||||
|
val py = y + doc.lineHeightInPx - 1
|
||||||
|
val pw = doc.textWidth - 2 * MARGIN_TITLE_TEXTS
|
||||||
|
pixmap.setColor(Color(1f,1f,1f,.5f))
|
||||||
|
pixmap.fillRectangle(px, py, pw+1, 2)
|
||||||
|
pixmap.setColor(Color.WHITE)
|
||||||
|
pixmap.fillRectangle(px, py, pw, 1)
|
||||||
|
}
|
||||||
|
|
||||||
it.forEach {
|
it.forEach {
|
||||||
it.posX += MARGIN_TITLE_TEXTS
|
it.posX += MARGIN_TITLE_TEXTS
|
||||||
@@ -1389,6 +1422,22 @@ object BTeXParser {
|
|||||||
)
|
)
|
||||||
batch.color = oldCol
|
batch.color = oldCol
|
||||||
}
|
}
|
||||||
|
it.extraPixmapDrawFun = { pixmap, x, y ->
|
||||||
|
pixmap.setColor(DEFAULT_ORNAMENTS_COL.cpy().also { it.a *= bodyTextShadowAlpha })
|
||||||
|
pixmap.fillRectangle(
|
||||||
|
x - (indent - 2),
|
||||||
|
y + doc.lineHeightInPx,
|
||||||
|
7,
|
||||||
|
1 + (it.lineCount - 1).coerceAtLeast(1) * doc.lineHeightInPx
|
||||||
|
)
|
||||||
|
pixmap.setColor(DEFAULT_ORNAMENTS_COL)
|
||||||
|
pixmap.fillRectangle(
|
||||||
|
x - (indent - 2),
|
||||||
|
y + doc.lineHeightInPx,
|
||||||
|
6,
|
||||||
|
(it.lineCount - 1).coerceAtLeast(1) * doc.lineHeightInPx
|
||||||
|
)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1601,11 +1650,25 @@ object BTeXParser {
|
|||||||
font.draw(batch, pageNum, x + typeWidth - pageNumWidth.toFloat(), y)
|
font.draw(batch, pageNum, x + typeWidth - pageNumWidth.toFloat(), y)
|
||||||
|
|
||||||
batch.color = oldCol
|
batch.color = oldCol
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
// println("pos: ($x, $y)\tTOC: $name -- dot start: ${(x + textWidth).div(dotGap).ceilToFloat() * dotGap}, dot end: $dotCursor, typeWidth=$typeWidth, pageNumWidth=$pageNumWidth")
|
// println("pos: ($x, $y)\tTOC: $name -- dot start: ${(x + textWidth).div(dotGap).ceilToFloat() * dotGap}, dot end: $dotCursor, typeWidth=$typeWidth, pageNumWidth=$pageNumWidth")
|
||||||
}
|
}
|
||||||
|
call.extraPixmapDrawFun = { pixmap, x, y ->
|
||||||
|
val font = getFont()
|
||||||
|
val y = y + (call.lineCount - 1).coerceAtLeast(0) * doc.lineHeightInPx
|
||||||
|
|
||||||
|
val textWidth = if (call.text is TypesetDrawCall) {
|
||||||
|
font.getWidthNormalised(call.text.movableType.typesettedSlugs.last())
|
||||||
|
}
|
||||||
|
else call.width
|
||||||
|
|
||||||
|
var dotCursor = (x.toFloat() + textWidth).div(dotGap).ceilToInt() * dotGap
|
||||||
|
while (dotCursor < x + dotPosEnd) {
|
||||||
|
font.drawToPixmap(pixmap, "$ccDefault·", dotCursor + dotGap/2, y)
|
||||||
|
dotCursor += dotGap
|
||||||
|
}
|
||||||
|
|
||||||
|
font.drawToPixmap(pixmap, "$ccDefault$pageNum", x + typeWidth - pageNumWidth, y)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1619,10 +1682,44 @@ object BTeXParser {
|
|||||||
|
|
||||||
|
|
||||||
companion object {
|
companion object {
|
||||||
|
init {
|
||||||
|
App.disposables.add(object : Disposable {
|
||||||
|
override fun dispose() {
|
||||||
|
testFont.dispose()
|
||||||
|
partTitleFont.dispose()
|
||||||
|
titleFont.dispose()
|
||||||
|
subtitleFont.dispose()
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
private val siblingAwareTags = arrayOf(
|
private val siblingAwareTags = arrayOf(
|
||||||
"PART","CHAPTER","SECTION","SUBSECTION","P","I","LI"
|
"PART","CHAPTER","SECTION","SUBSECTION","P","I","LI"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
private val bodyTextShadowAlpha = 0.36f
|
||||||
|
|
||||||
|
private var fontInit = false
|
||||||
|
private lateinit var testFont: TerrarumSansBitmap
|
||||||
|
private lateinit var partTitleFont: TerrarumSansBitmap
|
||||||
|
private lateinit var titleFont: TerrarumSansBitmap
|
||||||
|
private lateinit var subtitleFont: TerrarumSansBitmap
|
||||||
|
|
||||||
|
fun preloadFonts() {
|
||||||
|
testFont = TerrarumSansBitmap(App.FONT_DIR, shadowAlpha = bodyTextShadowAlpha, textCacheSize = 4096)
|
||||||
|
partTitleFont = TerrarumSansBitmap(App.FONT_DIR, shadowAlpha = bodyTextShadowAlpha).also {
|
||||||
|
it.interchar = 1
|
||||||
|
}
|
||||||
|
titleFont = TerrarumSansBitmap(App.FONT_DIR).also {
|
||||||
|
it.interchar = 1
|
||||||
|
it.scale = 2
|
||||||
|
}
|
||||||
|
subtitleFont = TerrarumSansBitmap(App.FONT_DIR).also {
|
||||||
|
it.interchar = 1
|
||||||
|
}
|
||||||
|
fontInit = true
|
||||||
|
}
|
||||||
|
|
||||||
private const val MARGIN_PARBOX_V = 4
|
private const val MARGIN_PARBOX_V = 4
|
||||||
private const val MARGIN_PARBOX_H = 12
|
private const val MARGIN_PARBOX_H = 12
|
||||||
private const val MARGIN_TITLE_TEXTS = 8
|
private const val MARGIN_TITLE_TEXTS = 8
|
||||||
|
|||||||
@@ -1,11 +1,14 @@
|
|||||||
package net.torvald.terrarum.imagefont
|
package net.torvald.terrarum.imagefont
|
||||||
|
|
||||||
|
import com.badlogic.gdx.Gdx
|
||||||
import com.badlogic.gdx.graphics.Color
|
import com.badlogic.gdx.graphics.Color
|
||||||
|
import com.badlogic.gdx.graphics.Pixmap
|
||||||
import com.badlogic.gdx.graphics.g2d.Batch
|
import com.badlogic.gdx.graphics.g2d.Batch
|
||||||
import com.badlogic.gdx.graphics.g2d.BitmapFont
|
import com.badlogic.gdx.graphics.g2d.BitmapFont
|
||||||
import com.badlogic.gdx.graphics.g2d.GlyphLayout
|
import com.badlogic.gdx.graphics.g2d.GlyphLayout
|
||||||
import net.torvald.terrarum.roundToFloat
|
import net.torvald.terrarum.roundToFloat
|
||||||
import net.torvald.terrarumsansbitmap.gdx.TextureRegionPack
|
import net.torvald.terrarumsansbitmap.gdx.TextureRegionPack
|
||||||
|
import kotlin.math.roundToInt
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Created by minjaesong on 2016-04-15.
|
* Created by minjaesong on 2016-04-15.
|
||||||
@@ -16,13 +19,18 @@ object TinyAlphNum : BitmapFont() {
|
|||||||
internal const val H = 13
|
internal const val H = 13
|
||||||
|
|
||||||
internal val fontSheet = TextureRegionPack("./assets/graphics/fonts/7x13_Tamzen7x14b.tga", W+1, H+1)
|
internal val fontSheet = TextureRegionPack("./assets/graphics/fonts/7x13_Tamzen7x14b.tga", W+1, H+1)
|
||||||
|
internal val fontPixmap = Pixmap(Gdx.files.internal("./assets/graphics/fonts/7x13_Tamzen7x14b.tga"))
|
||||||
|
|
||||||
init {
|
init {
|
||||||
setOwnsTexture(true)
|
setOwnsTexture(true)
|
||||||
setUseIntegerPositions(true)
|
setUseIntegerPositions(true)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
override fun dispose() {
|
||||||
|
fontSheet.dispose()
|
||||||
|
fontPixmap.dispose()
|
||||||
|
}
|
||||||
|
|
||||||
fun getWidth(str: String): Int {
|
fun getWidth(str: String): Int {
|
||||||
var l = 0
|
var l = 0
|
||||||
for (char in str) {
|
for (char in str) {
|
||||||
@@ -33,7 +41,8 @@ object TinyAlphNum : BitmapFont() {
|
|||||||
return W * l
|
return W * l
|
||||||
}
|
}
|
||||||
|
|
||||||
lateinit var colMain: Color
|
private var colMain = Color.WHITE
|
||||||
|
private var colMainInt = -1
|
||||||
|
|
||||||
override fun draw(batch: Batch, text: CharSequence, x: Float, y: Float): GlyphLayout? {
|
override fun draw(batch: Batch, text: CharSequence, x: Float, y: Float): GlyphLayout? {
|
||||||
val originalColour = batch.color.cpy()
|
val originalColour = batch.color.cpy()
|
||||||
@@ -65,6 +74,79 @@ object TinyAlphNum : BitmapFont() {
|
|||||||
return null
|
return null
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fun drawToPixmap(pixmap: Pixmap, text: String, x: Int, y: Int) {
|
||||||
|
var charsPrinted = 0
|
||||||
|
|
||||||
|
|
||||||
|
text.forEachIndexed { index, c ->
|
||||||
|
if (isColourCodeHigh(c)) {
|
||||||
|
val cchigh = c
|
||||||
|
val cclow = text[index + 1]
|
||||||
|
val colour = getColour(cchigh, cclow)
|
||||||
|
|
||||||
|
colMainInt = colour.toRGBA8888()
|
||||||
|
}
|
||||||
|
else if (c in 0.toChar()..255.toChar()) {
|
||||||
|
val srcX = (c.code % 16) * (W+1)
|
||||||
|
val srcY = (c.code / 16) * (H+1)
|
||||||
|
val destX = x + charsPrinted * W
|
||||||
|
val destY = y
|
||||||
|
|
||||||
|
pixmap.drawPixmap(fontPixmap, srcX, srcY, W+1, H+1, destX, destY, colMainInt)
|
||||||
|
|
||||||
|
charsPrinted += 1
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/***
|
||||||
|
* @param col RGBA8888 representation
|
||||||
|
*/
|
||||||
|
private fun Pixmap.drawPixmap(pixmap: Pixmap, srcX: Int, srcY: Int, srcW: Int, srcH: Int, destX: Int, destY: Int, col: Int) {
|
||||||
|
for (y in srcY until srcY + srcH) {
|
||||||
|
for (x in srcX until srcX + srcW) {
|
||||||
|
val pixel = pixmap.getPixel(x, y)
|
||||||
|
|
||||||
|
val newPixel = pixel colorTimes col
|
||||||
|
|
||||||
|
this.drawPixel(destX + x - srcX, destY + y - srcY, newPixel)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun Color.toRGBA8888() =
|
||||||
|
(this.r * 255f).toInt().shl(24) or
|
||||||
|
(this.g * 255f).toInt().shl(16) or
|
||||||
|
(this.b * 255f).toInt().shl(8) or
|
||||||
|
(this.a * 255f).toInt()
|
||||||
|
|
||||||
|
/**
|
||||||
|
* RGBA8888 representation
|
||||||
|
*/
|
||||||
|
private fun Int.forceOpaque() = this.and(0xFFFFFF00.toInt()) or 0xFF
|
||||||
|
|
||||||
|
private infix fun Int.colorTimes(other: Int): Int {
|
||||||
|
val thisBytes = IntArray(4) { this.ushr(it * 8).and(255) }
|
||||||
|
val otherBytes = IntArray(4) { other.ushr(it * 8).and(255) }
|
||||||
|
|
||||||
|
return (thisBytes[0] times256 otherBytes[0]) or
|
||||||
|
(thisBytes[1] times256 otherBytes[1]).shl(8) or
|
||||||
|
(thisBytes[2] times256 otherBytes[2]).shl(16) or
|
||||||
|
(thisBytes[3] times256 otherBytes[3]).shl(24)
|
||||||
|
}
|
||||||
|
|
||||||
|
private infix fun Int.times256(other: Int) = multTable255[this][other]
|
||||||
|
|
||||||
|
private val multTable255 = Array(256) { left ->
|
||||||
|
IntArray(256) { right ->
|
||||||
|
(255f * (left / 255f).times(right / 255f)).roundToInt()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
override fun getLineHeight() = H.toFloat()
|
override fun getLineHeight() = H.toFloat()
|
||||||
override fun getCapHeight() = getLineHeight()
|
override fun getCapHeight() = getLineHeight()
|
||||||
override fun getXHeight() = getLineHeight()
|
override fun getXHeight() = getLineHeight()
|
||||||
|
|||||||
@@ -13,7 +13,9 @@ import com.badlogic.gdx.graphics.glutils.ShaderProgram
|
|||||||
import net.torvald.btex.BTeXParser
|
import net.torvald.btex.BTeXParser
|
||||||
import net.torvald.terrarum.*
|
import net.torvald.terrarum.*
|
||||||
import net.torvald.terrarum.btex.BTeXDocument
|
import net.torvald.terrarum.btex.BTeXDocument
|
||||||
|
import net.torvald.terrarum.imagefont.TinyAlphNum
|
||||||
import net.torvald.terrarum.langpack.Lang
|
import net.torvald.terrarum.langpack.Lang
|
||||||
|
import net.torvald.terrarum.ui.Toolkit
|
||||||
import net.torvald.unicode.EMDASH
|
import net.torvald.unicode.EMDASH
|
||||||
import java.io.File
|
import java.io.File
|
||||||
import kotlin.system.measureTimeMillis
|
import kotlin.system.measureTimeMillis
|
||||||
@@ -44,7 +46,10 @@ class BTeXTest : ApplicationAdapter() {
|
|||||||
)
|
)
|
||||||
|
|
||||||
override fun create() {
|
override fun create() {
|
||||||
Lang.invoke()
|
Lang
|
||||||
|
TinyAlphNum
|
||||||
|
Toolkit
|
||||||
|
BTeXParser.BTeXHandler.preloadFonts()
|
||||||
|
|
||||||
batch = FlippingSpriteBatch(1000)
|
batch = FlippingSpriteBatch(1000)
|
||||||
camera = OrthographicCamera(1280f, 720f)
|
camera = OrthographicCamera(1280f, 720f)
|
||||||
@@ -57,26 +62,27 @@ class BTeXTest : ApplicationAdapter() {
|
|||||||
val isBookFinalised = filePath.endsWith(".btxbook")
|
val isBookFinalised = filePath.endsWith(".btxbook")
|
||||||
|
|
||||||
if (!isBookFinalised) {
|
if (!isBookFinalised) {
|
||||||
measureTimeMillis {
|
Thread {
|
||||||
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()
|
document.finalise()
|
||||||
documentHandler.dispose()
|
}.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")
|
||||||
}*/
|
}*/
|
||||||
|
}.start()
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
measureTimeMillis {
|
measureTimeMillis {
|
||||||
@@ -96,28 +102,35 @@ class BTeXTest : ApplicationAdapter() {
|
|||||||
|
|
||||||
gdxClearAndEnableBlend(.063f, .070f, .086f, 1f)
|
gdxClearAndEnableBlend(.063f, .070f, .086f, 1f)
|
||||||
|
|
||||||
val drawX = (1280 - (pageGap + document.pageDimensionWidth*2)) / 2
|
if (::document.isInitialized) {
|
||||||
val drawY = 24
|
if (document.isFinalised) {
|
||||||
|
val drawX = (1280 - (pageGap + document.pageDimensionWidth * 2)) / 2
|
||||||
|
val drawY = 24
|
||||||
|
|
||||||
batch.inUse {
|
batch.inUse {
|
||||||
batch.color = Color.WHITE
|
batch.color = Color.WHITE
|
||||||
batch.draw(bg, 0f, 0f)
|
batch.draw(bg, 0f, 0f)
|
||||||
|
|
||||||
if (scroll - 1 in document.pageIndices)
|
if (scroll - 1 in document.pageIndices)
|
||||||
document.render(0f, batch, scroll - 1, drawX, drawY)
|
document.render(0f, batch, scroll - 1, drawX, drawY)
|
||||||
if (scroll in document.pageIndices)
|
if (scroll in document.pageIndices)
|
||||||
document.render(0f, batch, scroll, drawX + (6 + document.pageDimensionWidth), drawY)
|
document.render(0f, batch, scroll, drawX + (6 + document.pageDimensionWidth), drawY)
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
if (Gdx.input.isKeyJustPressed(Input.Keys.LEFT))
|
||||||
|
scroll = (scroll - 2).coerceAtLeast(0)
|
||||||
|
else if (Gdx.input.isKeyJustPressed(Input.Keys.RIGHT))
|
||||||
|
scroll =
|
||||||
|
(scroll + 2).coerceAtMost(
|
||||||
|
document.pageIndices.endInclusive.toFloat().div(2f).ceilToInt().times(2)
|
||||||
|
)
|
||||||
|
else if (Gdx.input.isKeyJustPressed(Input.Keys.PAGE_UP))
|
||||||
|
scroll = 0
|
||||||
|
else if (Gdx.input.isKeyJustPressed(Input.Keys.PAGE_DOWN))
|
||||||
|
scroll = document.pageIndices.endInclusive.toFloat().div(2f).ceilToInt().times(2)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
if (Gdx.input.isKeyJustPressed(Input.Keys.LEFT))
|
|
||||||
scroll = (scroll - 2).coerceAtLeast(0)
|
|
||||||
else if (Gdx.input.isKeyJustPressed(Input.Keys.RIGHT))
|
|
||||||
scroll = (scroll + 2).coerceAtMost(document.pageIndices.endInclusive.toFloat().div(2f).ceilToInt().times(2))
|
|
||||||
else if (Gdx.input.isKeyJustPressed(Input.Keys.PAGE_UP))
|
|
||||||
scroll = 0
|
|
||||||
else if (Gdx.input.isKeyJustPressed(Input.Keys.PAGE_DOWN))
|
|
||||||
scroll = document.pageIndices.endInclusive.toFloat().div(2f).ceilToInt().times(2)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -188,6 +188,18 @@ object Toolkit : Disposable {
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// draws highly simplified box border
|
||||||
|
fun drawBoxBorderToPixmap(pixmap: Pixmap, x: Int, y: Int, w: Int, h: Int) {
|
||||||
|
// top edge
|
||||||
|
pixmap.fillRectangle(x, y - 1, w, 1)
|
||||||
|
// bottom edge
|
||||||
|
pixmap.fillRectangle(x, y + h, w, 1)
|
||||||
|
// left edge
|
||||||
|
pixmap.fillRectangle(x - 1, y, 1, h)
|
||||||
|
// right edge
|
||||||
|
pixmap.fillRectangle(x + w, y, 1, h)
|
||||||
|
}
|
||||||
|
|
||||||
private lateinit var blurtex0: Texture
|
private lateinit var blurtex0: Texture
|
||||||
private lateinit var blurtex1: Texture
|
private lateinit var blurtex1: Texture
|
||||||
private lateinit var blurtex2: Texture
|
private lateinit var blurtex2: Texture
|
||||||
|
|||||||
Reference in New Issue
Block a user