btex: page numbers and toc/index pagenum fixes

This commit is contained in:
minjaesong
2024-04-28 19:51:31 +09:00
parent 45b1a344f2
commit e1b577b781
7 changed files with 473 additions and 92 deletions

File diff suppressed because one or more lines are too long

View File

@@ -1,69 +0,0 @@
<btexdoc cover="hardcover" inner="standard" papersize="standard">
<cover>
<title>The life and strange surprizing adventures of Robinson Crusoe, of York, mariner: who lived eight and twenty years all alone in an un-inhabited island on the coast of America, near the mouth of the great river of Oroonoque; having been cast on shore by shipwreck, wherein all the men perished but himself, with an account how he was at last as strangely deliver'd by pyrates</title>
<author>Daniel Defoe</author>
<edition>The Fourth Edition</edition>
</cover>
<tocpage><tableofcontents /></tocpage>
<manuscript>
<chapter>What Is a Book</chapter>
<p>This example book is designed to give you the example of the Book Language.</p>
<section>What Really Is a Book</section>
<p>A book is a collection of texts printed in a special way that allows them to be read easily, with
enumerable pages and insertion of other helpful resources, such as illustrations and <a href="btex language">hyperlinks</a>.</p>
<newpage />
<!--<fullpagebox>
<p><span colour="grey">
this page is intentionally left blank
</span></p>
</fullpagebox>-->
<chapter>Writing a Book Using Pen and Papers</chapter>
<p><index id="pen and paper" />If you open a book on a writing table, you will be welcomed with a
toolbar used to put other book elements, such as chapters and sections.</p>
<chapter>Writing a Book Using a Typewriter</chapter>
<p><index id="typewriter" />Typewriters can only write in a single style of font, chapters and
sections are not available.</p>
<chapter>Writing a Book Using a Computer</chapter>
<p>Writing book using a computer requires the use of the Book Typesetting Engine Extended, or <btex />.</p>
<section>Full Control of the Shape</section>
<p><index id="btex language" />With <btex /> you can fully control how your publishing would look like,
from a pile of papers that look like they have been typed out using typewriter, a pile of printouts
that have pictures in it, to a true hardcover book.</p>
<p><index id="cover" />This style is controlled using the <code>cover</code> attribute on the root tag,
with following values: <code>typewriter</code>, <code>printout</code> and <code>hardcover</code>.</p>
<p>Typewriter and Printout are considered not-bound and readers will only see one page at a time,
while Hardcover is considered bound and two pages are presented to the readers.</p>
</manuscript>
<indexpage><tableofindices /></indexpage>
</btexdoc>

Binary file not shown.

View File

@@ -3,8 +3,7 @@ package net.torvald.terrarum.btex
import com.badlogic.gdx.graphics.Color
import com.badlogic.gdx.graphics.g2d.SpriteBatch
import com.badlogic.gdx.graphics.g2d.TextureRegion
import net.torvald.terrarum.blendNormalPremultAlpha
import net.torvald.terrarum.blendNormalStraightAlpha
import net.torvald.terrarum.imagefont.TinyAlphNum
import net.torvald.terrarum.ui.Toolkit
import net.torvald.terrarumsansbitmap.MovableType
import net.torvald.terrarumsansbitmap.gdx.CodepointSequence
@@ -20,7 +19,7 @@ class BTeXDocument {
var textWidth = 480
var lineHeightInPx = 24
var pageLines = 25
var pageLines = 24
val textHeight: Int
get() = pageLines * lineHeightInPx
@@ -30,11 +29,15 @@ class BTeXDocument {
val pageDimensionWidth: Int
get() = 2 * pageMarginH + textWidth
val pageDimensionHeight: Int
get() = 2 * pageMarginV + textHeight
get() = 2 * pageMarginV + textHeight + pageLines // add a pagenum row
var endOfPageStart = 2147483647
var tocPageStart = 2
companion object {
val DEFAULT_PAGE_BACK = Color(0xe0dfdb_ff.toInt())
val DEFAULT_PAGE_FORE = Color(0x0a0706_ff)
val DEFAULT_ORNAMENTS_COL = Color(0x3f3c3b_ff)
}
internal val pages = ArrayList<BTeXPage>()
@@ -50,6 +53,8 @@ class BTeXDocument {
internal val linesPrintedOnPage = ArrayList<Int>()
@Transient private val fontNum = TinyAlphNum
fun addNewPage(back: Color = DEFAULT_PAGE_BACK) {
pages.add(BTeXPage(back, pageDimensionWidth, pageDimensionHeight))
linesPrintedOnPage.add(0)
@@ -81,6 +86,25 @@ class BTeXDocument {
fun render(frameDelta: Float, batch: SpriteBatch, page: Int, x: Int, y: Int) {
pages[page].render(frameDelta, batch, x, y, pageMarginH, pageMarginV)
// paint page number
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) {
batch.color = DEFAULT_ORNAMENTS_COL
TinyAlphNum.draw(batch, num, numX.toFloat(), numY.toFloat())
}
}
}

View File

@@ -7,6 +7,7 @@ import net.torvald.colourutil.OKLch
import net.torvald.colourutil.tosRGB
import net.torvald.terrarum.App
import net.torvald.terrarum.btex.BTeXDocument
import net.torvald.terrarum.btex.BTeXDocument.Companion.DEFAULT_ORNAMENTS_COL
import net.torvald.terrarum.btex.BTeXDocument.Companion.DEFAULT_PAGE_FORE
import net.torvald.terrarum.btex.BTeXDrawCall
import net.torvald.terrarum.btex.MovableTypeDrawCall
@@ -88,7 +89,7 @@ object BTeXParser {
private var lastTagAtDepth = Array(24) { "" }
private var pTagCntAtDepth = IntArray(24)
private data class CptSect(val type: String, var alt: String?, var pagenum: Int)
private data class CptSect(val type: String, var alt: String?)
private data class CptSectInfo(val type: String, var name: String, var pagenum: Int)
private val cptSectStack = ArrayList<CptSect>()
@@ -465,7 +466,7 @@ object BTeXParser {
"examination" to 640,
)
private val pageHeightMap = hashMapOf(
"standard" to 25,
"standard" to 24,
"examination" to 18,
)
@@ -575,13 +576,15 @@ object BTeXParser {
@OpenTag // reflective access is impossible with 'private'
fun processElemTOCPAGE(handler: BTeXHandler, doc: BTeXDocument, uri: String, attribs: HashMap<String, String>) {
doc.addNewPage() // toc: openright
typesetChapterHeading("Table of Contents", handler, 16)
val header = attribs["title"] ?: "Table of Contents"
typesetChapterHeading(header, handler, 16)
}
@OpenTag // reflective access is impossible with 'private'
fun processElemINDEXPAGE(handler: BTeXHandler, doc: BTeXDocument, uri: String, attribs: HashMap<String, String>) {
doc.addNewPage()
typesetChapterHeading("Index", handler, 16)
val header = attribs["title"] ?: "Index"
typesetChapterHeading(header, handler, 16)
}
@OpenTag // reflective access is impossible with 'private'
@@ -657,7 +660,7 @@ object BTeXParser {
@OpenTag // reflective access is impossible with 'private'
fun processElemINDEX(handler: BTeXHandler, doc: BTeXDocument, uri: String, attribs: HashMap<String, String>) {
attribs["id"]?.let {
indexMap[it] = doc.currentPage
indexMap[it] = doc.currentPage + 1
}
}
@@ -761,18 +764,18 @@ object BTeXParser {
handler.paragraphBuffer.clear()
if (attribs["hide"] == null)
cptSectStack.add(CptSect("chapter", attribs["alt"], doc.currentPage))
cptSectStack.add(CptSect("chapter", attribs["alt"]))
else
cptSectStack.add(CptSect("chapter-hidden", attribs["alt"], doc.currentPage))
cptSectStack.add(CptSect("chapter-hidden", attribs["alt"]))
}
@OpenTag // reflective access is impossible with 'private'
fun processElemSECTION(handler: BTeXHandler, doc: BTeXDocument, uri: String, attribs: HashMap<String, String>) {
handler.paragraphBuffer.clear()
if (attribs["hide"] == null)
cptSectStack.add(CptSect("section", attribs["alt"], doc.currentPage))
cptSectStack.add(CptSect("section", attribs["alt"]))
else
cptSectStack.add(CptSect("section-hidden", attribs["alt"], doc.currentPage))
cptSectStack.add(CptSect("section-hidden", attribs["alt"]))
}
@CloseTag // reflective access is impossible with 'private'
fun closeElemCHAPTER(handler: BTeXHandler, doc: BTeXDocument, uri: String, siblingIndex: Int) {
@@ -784,7 +787,7 @@ object BTeXParser {
val cptSectInfo = cptSectStack.removeLast()
if (!cptSectInfo.type.endsWith("-hidden"))
cptSectMap.add(CptSectInfo("chapter", cptSectInfo.alt ?: thePar, cptSectInfo.pagenum))
cptSectMap.add(CptSectInfo("chapter", cptSectInfo.alt ?: thePar, doc.currentPage))
handler.paragraphBuffer.clear()
}
@@ -798,7 +801,7 @@ object BTeXParser {
val cptSectInfo = cptSectStack.removeLast()
if (!cptSectInfo.type.endsWith("-hidden"))
cptSectMap.add(CptSectInfo("section", cptSectInfo.alt ?: thePar, cptSectInfo.pagenum))
cptSectMap.add(CptSectInfo("section", cptSectInfo.alt ?: thePar, doc.currentPage))
handler.paragraphBuffer.clear()
}
@@ -828,6 +831,7 @@ object BTeXParser {
@CloseTag
fun closeElemBTEXDOC(handler: BTeXHandler, doc: BTeXDocument, uri: String, siblingIndex: Int) {
// make sure the last pair ends with paper and end-cover
doc.endOfPageStart = doc.currentPage + 1
if (doc.pages.size % 2 == 1) doc.addNewPage()
doc.addNewPage()
}
@@ -884,11 +888,11 @@ object BTeXParser {
it.forEach {
it.extraDrawFun = { batch, x, y ->
val oldCol = batch.color.cpy()
val otherCol = batch.color.cpy().also { it.a *= bodyTextShadowAlpha }
batch.color = otherCol
batch.color = DEFAULT_ORNAMENTS_COL.cpy().also { it.a *= bodyTextShadowAlpha }
Toolkit.fillArea(batch, x - (indent - 2), y + doc.lineHeightInPx, 7f, 1 + (it.lineCount - 1).coerceAtLeast(1) * doc.lineHeightInPx.toFloat())
batch.color = oldCol
batch.color = DEFAULT_ORNAMENTS_COL
Toolkit.fillArea(batch, x - (indent - 2), y + doc.lineHeightInPx, 6f, (it.lineCount - 1).coerceAtLeast(1) * doc.lineHeightInPx.toFloat())
batch.color = oldCol
}
}
}

View File

@@ -39,7 +39,7 @@ object TinyAlphNum : BitmapFont() {
override fun draw(batch: Batch, text: CharSequence, x: Float, y: Float): GlyphLayout? {
val originalColour = batch.color.cpy()
colMain = batch.color.cpy()
colShadow = colMain.cpy().mul(0.5f, 0.5f, 0.5f, 1f)
colShadow = colMain.cpy().mul(1f, 1f, 1f, 0.5f)
val x = x.roundToFloat()
val y = y.roundToFloat()

View File

@@ -24,8 +24,8 @@ import net.torvald.terrarum.inUse
class BTeXTest : ApplicationAdapter() {
// val filePath = "btex.xml"
val filePath = "literature/koKR/yisang_nalgae.xml"
// val filePath = "test.xml"
val filePath = "literature/ruRU/anton_chekhov_palata_no_6.xml"
// val filePath = "literature/koKR/yisang_nalgae.xml"
private lateinit var document: BTeXDocument