mirror of
https://github.com/curioustorvald/Terrarum.git
synced 2026-03-07 12:21:52 +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/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="$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/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-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="/" />
|
||||
@@ -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-x86_64.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>
|
||||
</artifact>
|
||||
</component>
|
||||
23
.idea/libraries/KotlinJavaRuntime.xml
generated
23
.idea/libraries/KotlinJavaRuntime.xml
generated
@@ -1,26 +1,23 @@
|
||||
<component name="libraryTable">
|
||||
<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>
|
||||
<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/1.8.22/kotlin-stdlib-1.8.22.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/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.9.24/kotlin-stdlib-1.9.24.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>
|
||||
<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/1.8.22/kotlin-stdlib-1.8.22-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/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.9.24/kotlin-stdlib-1.9.24-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>
|
||||
<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/1.8.22/kotlin-stdlib-1.8.22-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/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.9.24/kotlin-stdlib-1.9.24-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>
|
||||
</library>
|
||||
</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.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.FlippingSpriteBatch
|
||||
import net.torvald.terrarum.ceilToInt
|
||||
import net.torvald.terrarum.imagefont.TinyAlphNum
|
||||
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.ClustfileOutputStream
|
||||
import net.torvald.terrarum.serialise.Common
|
||||
import net.torvald.terrarum.tryDispose
|
||||
import net.torvald.terrarum.ui.Toolkit
|
||||
import net.torvald.terrarum.utils.JsonFetcher
|
||||
import net.torvald.terrarumsansbitmap.MovableType
|
||||
@@ -57,6 +58,7 @@ class BTeXDocument : Disposable {
|
||||
val DEFAULT_PAGE_BACK = Color(0xe0dfdb_ff.toInt())
|
||||
// val DEFAULT_PAGE_FORE = Color(0x0a0706_ff)
|
||||
val DEFAULT_ORNAMENTS_COL = Color(0x3f3c3b_ff)
|
||||
val ccPagenum = TerrarumSansBitmap.toColorCode(0xf333)
|
||||
|
||||
private fun String.escape() = this.replace("\"", "\\\"")
|
||||
|
||||
@@ -84,7 +86,7 @@ class BTeXDocument : Disposable {
|
||||
doc.inner = metaJson["inner"].asString()
|
||||
doc.papersize = metaJson["papersize"].asString()
|
||||
doc.fromArchive = true
|
||||
doc.pageTextures = ArrayList()
|
||||
doc.pageTextures = Array(pageCount) { null }
|
||||
|
||||
|
||||
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
|
||||
it.exportFileTo(tempFile.file())
|
||||
val texture = TextureRegion(Texture(tempFile))
|
||||
doc.pageTextures.add(texture)
|
||||
doc.pageTextures[page] = texture
|
||||
|
||||
if (page == 0) {
|
||||
doc.textWidth = texture.regionWidth - 2 * doc.pageMarginH
|
||||
@@ -117,8 +119,8 @@ class BTeXDocument : Disposable {
|
||||
|
||||
internal val pages = ArrayList<BTeXPage>()
|
||||
|
||||
private lateinit var pageTextures: ArrayList<TextureRegion>
|
||||
private lateinit var pageFrameBuffers: ArrayList<FrameBuffer>
|
||||
private lateinit var pagePixmaps: Array<Pixmap?>
|
||||
private lateinit var pageTextures: Array<TextureRegion?>
|
||||
|
||||
val currentPage: Int
|
||||
get() = pages.size - 1
|
||||
@@ -143,53 +145,44 @@ class BTeXDocument : Disposable {
|
||||
linesPrintedOnPage.add(index, 0)
|
||||
}
|
||||
|
||||
private val lock = Any()
|
||||
private val texturefiedPages = HashSet<Int>()
|
||||
|
||||
/**
|
||||
* Must be called on a thread with GL context!
|
||||
*/
|
||||
fun finalise() {
|
||||
if (fromArchive) throw IllegalStateException("Document is loaded from the archive and thus cannot be finalised")
|
||||
if (isFinalised) throw IllegalStateException("Page is already been finalised")
|
||||
fun finalise(multithread: Boolean = false) {
|
||||
synchronized(lock) {
|
||||
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()
|
||||
pageFrameBuffers = ArrayList()
|
||||
pageTextures = Array(pages.size) { null }
|
||||
pagePixmaps = Array(pages.size) { null }
|
||||
|
||||
val camera = OrthographicCamera(pageDimensionWidth.toFloat(), pageDimensionHeight.toFloat())
|
||||
val batch = FlippingSpriteBatch()
|
||||
|
||||
pages.forEachIndexed { pageNum, 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)
|
||||
printPageNumber(batch, pageNum, 0, 0)
|
||||
pages.forEachIndexed { pageNum, page ->
|
||||
val pixmap = Pixmap(pageDimensionWidth, pageDimensionHeight, Pixmap.Format.RGBA8888).also {
|
||||
it.blending = Pixmap.Blending.SourceOver
|
||||
it.filter = Pixmap.Filter.NearestNeighbour
|
||||
}
|
||||
page.renderToPixmap(pixmap, 0, 0, pageMarginH, pageMarginV)
|
||||
printPageNumber(pixmap, pageNum, 0, 0)
|
||||
pagePixmaps[pageNum] = pixmap
|
||||
}
|
||||
|
||||
pageTextures.add(TextureRegion(fbo.colorBufferTexture))
|
||||
pageFrameBuffers.add(fbo)
|
||||
isFinalised = true
|
||||
}
|
||||
isFinalised = true
|
||||
|
||||
batch.dispose()
|
||||
}
|
||||
|
||||
override fun dispose() {
|
||||
if (isFinalised) {
|
||||
pageTextures.forEach { it.texture.dispose() }
|
||||
pageFrameBuffers.forEach { it.dispose() }
|
||||
pageTextures.forEach { it?.texture?.dispose() }
|
||||
pagePixmaps.forEach { it?.tryDispose() }
|
||||
}
|
||||
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())
|
||||
}
|
||||
|
||||
pageFrameBuffers.forEachIndexed { index, fbo ->
|
||||
val file = Clustfile(DOM, "$index.png").also {
|
||||
it.createNewFile()
|
||||
}
|
||||
|
||||
fbo.inAction(null, null) {
|
||||
val pixmap = Pixmap.createFromFrameBuffer(0, 0, fbo.width, fbo.height)
|
||||
pagePixmaps.forEachIndexed { index, pixmap ->
|
||||
Clustfile(DOM, "$index.png").also { file ->
|
||||
file.createNewFile()
|
||||
val tempFile = Gdx.files.external("./.btex-export.png")
|
||||
PixmapIO.writePNG(tempFile, pixmap, Deflater.BEST_COMPRESSION, false)
|
||||
val outstream = ClustfileOutputStream(file)
|
||||
@@ -262,8 +251,13 @@ class BTeXDocument : Disposable {
|
||||
fun render(frameDelta: Float, batch: SpriteBatch, page: Int, x: Int, y: Int) {
|
||||
batch.color = Color.WHITE
|
||||
|
||||
if (isFinalised || fromArchive)
|
||||
if (fromArchive || isFinalised && texturefiedPages.contains(page))
|
||||
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 {
|
||||
pages[page].render(frameDelta, batch, x, y, pageMarginH, pageMarginV)
|
||||
printPageNumber(batch, page, x, y)
|
||||
@@ -289,6 +283,26 @@ class BTeXDocument : Disposable {
|
||||
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(
|
||||
@@ -320,6 +334,18 @@ class BTeXPage(
|
||||
|
||||
fun isEmpty() = drawCalls.isEmpty()
|
||||
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) {
|
||||
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(
|
||||
@@ -336,6 +366,7 @@ abstract class BTeXBatchDrawCall(
|
||||
val parentText: BTeXDrawCall?// = 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(
|
||||
@@ -359,11 +390,6 @@ class BTeXDrawCall(
|
||||
val px = (posX + x).toFloat()
|
||||
val py = (posY + y).toFloat()
|
||||
|
||||
if (theme == "code") {
|
||||
// todo draw code background
|
||||
println("code themed")
|
||||
}
|
||||
|
||||
extraDrawFun(batch, px, py)
|
||||
|
||||
batch.color = Color.WHITE
|
||||
@@ -384,6 +410,23 @@ class BTeXDrawCall(
|
||||
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
|
||||
get() = if (text != null)
|
||||
text.movableType.width * text.movableType.font.scale
|
||||
@@ -391,6 +434,7 @@ class BTeXDrawCall(
|
||||
cmd!!.width
|
||||
|
||||
internal var extraDrawFun: (SpriteBatch, Float, Float) -> Unit = { _, _, _ ->}
|
||||
internal var extraPixmapDrawFun: (Pixmap, Int, Int) -> Unit = { _, _, _ ->}
|
||||
internal val lineCount = if (text != null)
|
||||
text.rows
|
||||
else
|
||||
|
||||
@@ -2,7 +2,9 @@ package net.torvald.btex
|
||||
|
||||
import com.badlogic.gdx.files.FileHandle
|
||||
import com.badlogic.gdx.graphics.Color
|
||||
import com.badlogic.gdx.graphics.Pixmap
|
||||
import com.badlogic.gdx.graphics.g2d.SpriteBatch
|
||||
import com.badlogic.gdx.utils.Disposable
|
||||
import com.jme3.math.FastMath.DEG_TO_RAD
|
||||
import net.torvald.colourutil.OKLch
|
||||
import net.torvald.colourutil.tosRGB
|
||||
@@ -121,13 +123,6 @@ object BTeXParser {
|
||||
private var hasCover = false
|
||||
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(
|
||||
"thepart" to "Part %1\$s",
|
||||
"parttype" to "I",
|
||||
@@ -158,6 +153,10 @@ object BTeXParser {
|
||||
}
|
||||
|
||||
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 {
|
||||
// println("Tag opener: ${it.name}")
|
||||
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}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}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}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) {
|
||||
e.printStackTrace()
|
||||
}
|
||||
@@ -357,31 +373,18 @@ object BTeXParser {
|
||||
|
||||
private fun getFont() = when (cover) {
|
||||
"typewriter" -> TODO()
|
||||
else -> {
|
||||
if (!::testFont.isInitialized) testFont = TerrarumSansBitmap(App.FONT_DIR, shadowAlpha = bodyTextShadowAlpha, textCacheSize = 4096)
|
||||
testFont
|
||||
}
|
||||
else -> testFont
|
||||
}
|
||||
|
||||
private fun getPartTitleFont(): TerrarumSansBitmap {
|
||||
if (!::partTitleFont.isInitialized) partTitleFont = TerrarumSansBitmap(App.FONT_DIR, shadowAlpha = bodyTextShadowAlpha).also {
|
||||
it.interchar = 1
|
||||
}
|
||||
return partTitleFont
|
||||
}
|
||||
|
||||
private fun getTitleFont(): TerrarumSansBitmap {
|
||||
if (!::titleFont.isInitialized) titleFont = TerrarumSansBitmap(App.FONT_DIR).also {
|
||||
it.interchar = 1
|
||||
it.scale = 2
|
||||
}
|
||||
return titleFont
|
||||
}
|
||||
|
||||
private fun getSubtitleFont(): TerrarumSansBitmap {
|
||||
if (!::subtitleFont.isInitialized) subtitleFont = TerrarumSansBitmap(App.FONT_DIR).also {
|
||||
it.interchar = 1
|
||||
}
|
||||
return subtitleFont
|
||||
}
|
||||
|
||||
@@ -1020,6 +1023,27 @@ object BTeXParser {
|
||||
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()
|
||||
@@ -1291,6 +1315,15 @@ object BTeXParser {
|
||||
batch.color = Color.WHITE
|
||||
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.posX += MARGIN_TITLE_TEXTS
|
||||
@@ -1389,6 +1422,22 @@ object BTeXParser {
|
||||
)
|
||||
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)
|
||||
|
||||
batch.color = oldCol
|
||||
|
||||
|
||||
|
||||
// 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 {
|
||||
init {
|
||||
App.disposables.add(object : Disposable {
|
||||
override fun dispose() {
|
||||
testFont.dispose()
|
||||
partTitleFont.dispose()
|
||||
titleFont.dispose()
|
||||
subtitleFont.dispose()
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
private val siblingAwareTags = arrayOf(
|
||||
"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_H = 12
|
||||
private const val MARGIN_TITLE_TEXTS = 8
|
||||
|
||||
@@ -1,11 +1,14 @@
|
||||
package net.torvald.terrarum.imagefont
|
||||
|
||||
import com.badlogic.gdx.Gdx
|
||||
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.BitmapFont
|
||||
import com.badlogic.gdx.graphics.g2d.GlyphLayout
|
||||
import net.torvald.terrarum.roundToFloat
|
||||
import net.torvald.terrarumsansbitmap.gdx.TextureRegionPack
|
||||
import kotlin.math.roundToInt
|
||||
|
||||
/**
|
||||
* Created by minjaesong on 2016-04-15.
|
||||
@@ -16,13 +19,18 @@ object TinyAlphNum : BitmapFont() {
|
||||
internal const val H = 13
|
||||
|
||||
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 {
|
||||
setOwnsTexture(true)
|
||||
setUseIntegerPositions(true)
|
||||
}
|
||||
|
||||
override fun dispose() {
|
||||
fontSheet.dispose()
|
||||
fontPixmap.dispose()
|
||||
}
|
||||
|
||||
fun getWidth(str: String): Int {
|
||||
var l = 0
|
||||
for (char in str) {
|
||||
@@ -33,7 +41,8 @@ object TinyAlphNum : BitmapFont() {
|
||||
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? {
|
||||
val originalColour = batch.color.cpy()
|
||||
@@ -65,6 +74,79 @@ object TinyAlphNum : BitmapFont() {
|
||||
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 getCapHeight() = getLineHeight()
|
||||
override fun getXHeight() = getLineHeight()
|
||||
|
||||
@@ -13,7 +13,9 @@ import com.badlogic.gdx.graphics.glutils.ShaderProgram
|
||||
import net.torvald.btex.BTeXParser
|
||||
import net.torvald.terrarum.*
|
||||
import net.torvald.terrarum.btex.BTeXDocument
|
||||
import net.torvald.terrarum.imagefont.TinyAlphNum
|
||||
import net.torvald.terrarum.langpack.Lang
|
||||
import net.torvald.terrarum.ui.Toolkit
|
||||
import net.torvald.unicode.EMDASH
|
||||
import java.io.File
|
||||
import kotlin.system.measureTimeMillis
|
||||
@@ -44,7 +46,10 @@ class BTeXTest : ApplicationAdapter() {
|
||||
)
|
||||
|
||||
override fun create() {
|
||||
Lang.invoke()
|
||||
Lang
|
||||
TinyAlphNum
|
||||
Toolkit
|
||||
BTeXParser.BTeXHandler.preloadFonts()
|
||||
|
||||
batch = FlippingSpriteBatch(1000)
|
||||
camera = OrthographicCamera(1280f, 720f)
|
||||
@@ -57,26 +62,27 @@ class BTeXTest : ApplicationAdapter() {
|
||||
val isBookFinalised = filePath.endsWith(".btxbook")
|
||||
|
||||
if (!isBookFinalised) {
|
||||
measureTimeMillis {
|
||||
val f = BTeXParser.invoke(Gdx.files.internal("./assets/mods/basegame/books/$filePath"), varMap)
|
||||
document = f.first
|
||||
documentHandler = f.second
|
||||
}.also {
|
||||
println("Time spent on typesetting [ms]: $it")
|
||||
}
|
||||
Thread {
|
||||
measureTimeMillis {
|
||||
val f = BTeXParser.invoke(Gdx.files.internal("./assets/mods/basegame/books/$filePath"), varMap)
|
||||
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")
|
||||
}
|
||||
measureTimeMillis {
|
||||
document.finalise()
|
||||
}.also {
|
||||
println("Time spent on finalising [ms]: $it")
|
||||
}
|
||||
|
||||
measureTimeMillis {
|
||||
/*measureTimeMillis {
|
||||
document.serialise(File("./assets/mods/basegame/books/${filePath.replace(".xml", ".btxbook")}"))
|
||||
}.also {
|
||||
println("Time spent on serialisation [ms]: $it")
|
||||
}*/
|
||||
}.also {
|
||||
println("Time spent on serialisation [ms]: $it")
|
||||
}*/
|
||||
}.start()
|
||||
}
|
||||
else {
|
||||
measureTimeMillis {
|
||||
@@ -96,28 +102,35 @@ class BTeXTest : ApplicationAdapter() {
|
||||
|
||||
gdxClearAndEnableBlend(.063f, .070f, .086f, 1f)
|
||||
|
||||
val drawX = (1280 - (pageGap + document.pageDimensionWidth*2)) / 2
|
||||
val drawY = 24
|
||||
if (::document.isInitialized) {
|
||||
if (document.isFinalised) {
|
||||
val drawX = (1280 - (pageGap + document.pageDimensionWidth * 2)) / 2
|
||||
val drawY = 24
|
||||
|
||||
batch.inUse {
|
||||
batch.color = Color.WHITE
|
||||
batch.draw(bg, 0f, 0f)
|
||||
batch.inUse {
|
||||
batch.color = Color.WHITE
|
||||
batch.draw(bg, 0f, 0f)
|
||||
|
||||
if (scroll - 1 in document.pageIndices)
|
||||
document.render(0f, batch, scroll - 1, drawX, drawY)
|
||||
if (scroll in document.pageIndices)
|
||||
document.render(0f, batch, scroll, drawX + (6 + document.pageDimensionWidth), drawY)
|
||||
if (scroll - 1 in document.pageIndices)
|
||||
document.render(0f, batch, scroll - 1, drawX, drawY)
|
||||
if (scroll in document.pageIndices)
|
||||
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 blurtex1: Texture
|
||||
private lateinit var blurtex2: Texture
|
||||
|
||||
Reference in New Issue
Block a user