diff --git a/assets/mods/basegame/books/btex.xml b/assets/mods/basegame/books/btex.xml
index 8c7fc2ca1..1d518691f 100644
--- a/assets/mods/basegame/books/btex.xml
+++ b/assets/mods/basegame/books/btex.xml
@@ -9,41 +9,61 @@
+
+
What Is a Book
- This example book is designed to give you the exampe of the Book Language.
+ This example book is designed to give you the example of the Book Language.
- 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 hyperlinks.
+ 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 hyperlinks.
-
- this page is intentionally left blank
-
+
+ this page is intentionally left blank
+
+
+
+
Writing Book Using Pen and Papers
- 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, sections.
+ 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, sections.
+
+
+
Writing Book Using Typewriter
- Typewriters can only write single style of font, therefore chapters and sections are not available.
+ Typewriters can only write single style of font, therefore chapters and
+ sections are not available.
+
+
+
Writing Book using Computer
- Writing book using a computer requires a use of the Book Typesetting Engine Extended, or
+ Writing book using a computer requires a use of the Book Typesetting Engine Extended, or
Full Control of the Shape
- With 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 papers but a fully-featured printouts that have illustrations in it, to a fully-featured hardcover book.
+ With 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 papers but a
+ fully-featured printouts that have illustrations in it, to a fully-featured hardcover book.
- This style is controlled using the cover attribute on the root tag, with following values: typewriter, printout, hardcover
+ This style is controlled using the cover attribute on the root tag,
+ with following values: typewriter, printout, hardcover
- 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.
+ 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.
+
+
diff --git a/lib/TerrarumSansBitmap.jar b/lib/TerrarumSansBitmap.jar
index b2afa551b..e410aa5ab 100644
--- a/lib/TerrarumSansBitmap.jar
+++ b/lib/TerrarumSansBitmap.jar
@@ -1,3 +1,3 @@
version https://git-lfs.github.com/spec/v1
-oid sha256:19cd63d57c4985d2e4f956b2516817941a72cfbf866111e1a2076f9a8ef81443
-size 188141
+oid sha256:ef2bb4f64036ccb2b27f47cb0bb8e34691206170c358d4128512f6aa79f61706
+size 188472
diff --git a/src/net/torvald/btex/BTeXDocument.kt b/src/net/torvald/btex/BTeXDocument.kt
index c9f2c65c4..06e0cbf7d 100644
--- a/src/net/torvald/btex/BTeXDocument.kt
+++ b/src/net/torvald/btex/BTeXDocument.kt
@@ -1,10 +1,8 @@
package net.torvald.terrarum.btex
import com.badlogic.gdx.graphics.Color
-import com.badlogic.gdx.graphics.g2d.BitmapFont
import com.badlogic.gdx.graphics.g2d.SpriteBatch
import com.badlogic.gdx.graphics.g2d.TextureRegion
-import net.torvald.terrarum.App
import net.torvald.terrarum.ui.Toolkit
import net.torvald.terrarumsansbitmap.MovableType
@@ -18,9 +16,9 @@ class BTeXDocument {
var papersize = "standard"
var pageWidth = 420
- var lineHeight = 24
+ var lineHeightInPx = 24
var pageLines = 25
- var pageHeight = pageLines * lineHeight
+ var pageHeight = pageLines * lineHeightInPx
companion object {
val DEFAULT_PAGE_BACK = Color(0xe1e1d7ff.toInt())
@@ -29,14 +27,26 @@ class BTeXDocument {
private val pages = ArrayList()
+ val currentPage: Int
+ get() = pages.size - 1
+ var currentLine: Int = 0
+ private set
fun addNewPage(back: Color = DEFAULT_PAGE_BACK) {
pages.add(BTeXPage(back, pageWidth, pageHeight))
+ currentLine = 0
}
+ /**
+ * Appends draw call to the list. The draw call must be prepared manually so that they would not overflow.
+ * Use `addNewPage` to append the overflowing text to the next page.
+ *
+ * `currentLine` *will* be updated automatically.
+ */
fun appendDrawCall(drawCall: BTeXDrawCall) {
pages.last().appendDrawCall(drawCall)
+ currentLine += drawCall.lineCount
}
fun render(frameDelta: Float, batch: SpriteBatch, page: Int, x: Int, y: Int) {
@@ -64,21 +74,37 @@ class BTeXPage(
}
}
-data class MovableTypeDrawCall(val movableType: MovableType, val rowStart: Int, val rowEnd: Int) {
- fun draw(batch: SpriteBatch, x: Float, y: Float) {
+interface BTeXTextDrawCall {
+ val rowStart: Int
+ val rowEnd: Int
+ fun draw(batch: SpriteBatch, x: Float, y: Float)
+}
+
+data class MovableTypeDrawCall(val movableType: MovableType, override val rowStart: Int, override val rowEnd: Int): BTeXTextDrawCall {
+ override fun draw(batch: SpriteBatch, x: Float, y: Float) {
movableType.draw(batch, x, y, rowStart, rowEnd)
}
}
+/*data class RaggedLeftDrawCall(val raggedType: RaggedType, override val rowStart: Int, override val rowEnd: Int): BTeXTextDrawCall {
+ override fun draw(batch: SpriteBatch, x: Float, y: Float) {
+ raggedType.draw(batch, x, y, rowStart, rowEnd)
+ }
+}*/
+
class BTeXDrawCall(
- val posX: Int,
- val posY: Int,
+ val posX: Int, // position relative to the page start (excluding page margin)
+ val posY: Int, // position relative to the page start (excluding page margin)
val theme: String,
val colour: Color,
- val text: MovableTypeDrawCall? = null,
+ val text: BTeXTextDrawCall? = null,
val texture: TextureRegion? = null,
) {
+ init {
+ if (text != null && texture != null) throw IllegalArgumentException("Text and Texture are both non-null")
+ }
+
fun draw(batch: SpriteBatch, x: Int, y: Int) {
val px = (posX + x).toFloat()
val py = (posY + y).toFloat()
@@ -98,4 +124,9 @@ class BTeXDrawCall(
else throw Error("Text and Texture are both non-null")
}
+ internal val lineCount = if (text != null)
+ text.rowEnd - text.rowStart
+ else
+ TODO()
+
}
\ No newline at end of file
diff --git a/src/net/torvald/btex/BTeXParser.kt b/src/net/torvald/btex/BTeXParser.kt
index 0c815efdb..681431a15 100644
--- a/src/net/torvald/btex/BTeXParser.kt
+++ b/src/net/torvald/btex/BTeXParser.kt
@@ -4,7 +4,11 @@ import com.badlogic.gdx.files.FileHandle
import com.badlogic.gdx.graphics.Color
import net.torvald.terrarum.App
import net.torvald.terrarum.btex.BTeXDocument
+import net.torvald.terrarum.btex.BTeXDrawCall
+import net.torvald.terrarum.btex.MovableTypeDrawCall
import net.torvald.terrarum.gameitems.ItemID
+import net.torvald.terrarumsansbitmap.MovableType
+import net.torvald.terrarumsansbitmap.gdx.TerrarumSansBitmap
import org.xml.sax.Attributes
import org.xml.sax.InputSource
import org.xml.sax.helpers.DefaultHandler
@@ -20,6 +24,9 @@ import kotlin.reflect.full.findAnnotation
*/
object BTeXParser {
+ internal val textTags = hashSetOf("P", "TITLE", "AUTHOR", "EDITION", "CHAPTER", "SECTION")
+ internal val textDecorTags = hashSetOf("SPAN", "CODE")
+
operator fun invoke(file: FileHandle) = invoke(file.file())
operator fun invoke(file: File): BTeXDocument {
@@ -39,7 +46,7 @@ object BTeXParser {
internal class BTeXHandler(val doc: BTeXDocument) : DefaultHandler() {
private val DEFAULT_FONTCOL = Color(0x222222ff)
- private val LINE_HEIGHT = doc.lineHeight
+ private val LINE_HEIGHT = doc.lineHeightInPx
private var cover = ""
private var inner = ""
@@ -56,7 +63,7 @@ object BTeXParser {
private val tagStack = ArrayList() // index zero should be "btex"
-
+ private var currentTheme = ""
private var spanColour: String? = null
@@ -66,6 +73,8 @@ object BTeXParser {
private val elemOpeners: HashMap> = HashMap()
private val elemClosers: HashMap> = HashMap()
+ private val paragraphBuffer = StringBuilder()
+
init {
BTeXHandler::class.declaredFunctions.filter { it.findAnnotation() != null }.forEach {
println("Tag opener: ${it.name}")
@@ -101,14 +110,21 @@ object BTeXParser {
}
override fun startElement(uri: String, localName: String, qName: String, attributes: Attributes) {
- val tag = qName; if (tagStack.isEmpty() && tag.lowercase() != "btexdoc") throw BTeXParsingException("Document is not BTeX")
- tagStack.add(tag)
+ val tag = qName
+ if (tagStack.isEmpty() && tag.lowercase() != "btexdoc") throw BTeXParsingException("Document is not BTeX")
+ val theTag = tag.uppercase()
+
+ if (tagStack.isNotEmpty() && tagStack.any { textTags.contains(it) } && textTags.contains(theTag))
+ throw IllegalStateException("Text tag '$theTag' used inside of text tags (tag stack is ${tagStack.joinToString()})")
+ if (tagStack.isNotEmpty() && !textTags.contains(tagStack.last()) && textDecorTags.contains(theTag))
+ throw IllegalStateException("Text decoration tag '$theTag' used outside of a text tag (tag stack is ${tagStack.joinToString()})")
+
+ tagStack.add(theTag)
val attribs = HashMap().also {
it.putAll((0 until attributes.length).map { attributes.getQName(it) to attributes.getValue(it) })
}
- val theTag = tag.uppercase()
elemOpeners["processElem$theTag"].let {
if (it == null)
@@ -123,7 +139,7 @@ object BTeXParser {
}
}
-// printdbg("Start element \t($tag)")
+// printdbg("Start element \t($theTag)")
}
override fun endElement(uri: String, localName: String, qName: String) {
@@ -147,8 +163,9 @@ object BTeXParser {
val str =
String(ch.sliceArray(start until start + length)).replace('\n', ' ').replace(Regex(" +"), " ")//.trim()
- if (str.isNotBlank()) {
- printdbg("Characters \t\"$str\"")
+ if (str.isNotEmpty()) {
+// printdbg("Characters \t\"$str\"")
+ paragraphBuffer.append(str)
}
}
@@ -170,16 +187,212 @@ object BTeXParser {
typeY += h
}
+ private lateinit var testFont: TerrarumSansBitmap
private fun getFont() = when (cover) {
"typewriter" -> TODO()
- else -> App.fontGame
+ else -> App.fontGame ?: let {
+ if (!::testFont.isInitialized) testFont = TerrarumSansBitmap(App.FONT_DIR)
+ testFont
+ }
}
- private fun getSpanColour(): Color = spanColourMap.getOrDefault(spanColour, DEFAULT_FONTCOL)
+ private val hexColRegexRGBshort = Regex("#[0-9a-fA-F]{3,3}")
+ private val hexColRegexRGB = Regex("#[0-9a-fA-F]{6,6}")
+ private fun getSpanColour(): Color = if (spanColour == null) DEFAULT_FONTCOL
+ else if (spanColour!!.matches(hexColRegexRGB)) {
+ val rs = spanColour!!.substring(1,3)
+ val gs = spanColour!!.substring(3,5)
+ val bs = spanColour!!.substring(5,7)
+
+ val r = rs.toInt(16) / 255f
+ val g = gs.toInt(16) / 255f
+ val b = bs.toInt(16) / 255f
+
+ Color(r, g, b, 1f)
+ }
+ else if (spanColour!!.matches(hexColRegexRGBshort)) {
+ val rs = spanColour!!.substring(1,2)
+ val gs = spanColour!!.substring(2,3)
+ val bs = spanColour!!.substring(3,4)
+
+ val r = rs.toInt(16) / 15f
+ val g = gs.toInt(16) / 15f
+ val b = bs.toInt(16) / 15f
+
+ Color(r, g, b, 1f)
+ }
+ else
+ spanColourMap.getOrDefault(spanColour, DEFAULT_FONTCOL)
+
+ // list of CSS named colours (list supports up to CSS Colors Level 4)
private val spanColourMap = hashMapOf(
- "grey" to Color.LIGHT_GRAY
+ "black" to Color(0x000000ff.toInt()),
+ "silver" to Color(0xc0c0c0ff.toInt()),
+ "gray" to Color(0x808080ff.toInt()),
+ "white" to Color(0xffffffff.toInt()),
+ "maroon" to Color(0x800000ff.toInt()),
+ "red" to Color(0xff0000ff.toInt()),
+ "purple" to Color(0x800080ff.toInt()),
+ "fuchsia" to Color(0xff00ffff.toInt()),
+ "green" to Color(0x008000ff.toInt()),
+ "lime" to Color(0x00ff00ff.toInt()),
+ "olive" to Color(0x808000ff.toInt()),
+ "yellow" to Color(0xffff00ff.toInt()),
+ "navy" to Color(0x000080ff.toInt()),
+ "blue" to Color(0x0000ffff.toInt()),
+ "teal" to Color(0x008080ff.toInt()),
+ "aqua" to Color(0x00ffffff.toInt()),
+ "aliceblue" to Color(0xf0f8ffff.toInt()),
+ "antiquewhite" to Color(0xfaebd7ff.toInt()),
+ "aqua" to Color(0x00ffffff.toInt()),
+ "aquamarine" to Color(0x7fffd4ff.toInt()),
+ "azure" to Color(0xf0ffffff.toInt()),
+ "beige" to Color(0xf5f5dcff.toInt()),
+ "bisque" to Color(0xffe4c4ff.toInt()),
+ "black" to Color(0x000000ff.toInt()),
+ "blanchedalmond" to Color(0xffebcdff.toInt()),
+ "blue" to Color(0x0000ffff.toInt()),
+ "blueviolet" to Color(0x8a2be2ff.toInt()),
+ "brown" to Color(0xa52a2aff.toInt()),
+ "burlywood" to Color(0xdeb887ff.toInt()),
+ "cadetblue" to Color(0x5f9ea0ff.toInt()),
+ "chartreuse" to Color(0x7fff00ff.toInt()),
+ "chocolate" to Color(0xd2691eff.toInt()),
+ "coral" to Color(0xff7f50ff.toInt()),
+ "cornflowerblue" to Color(0x6495edff.toInt()),
+ "cornsilk" to Color(0xfff8dcff.toInt()),
+ "crimson" to Color(0xdc143cff.toInt()),
+ "cyan" to Color(0x00ffffff.toInt()),
+ "darkblue" to Color(0x00008bff.toInt()),
+ "darkcyan" to Color(0x008b8bff.toInt()),
+ "darkgoldenrod" to Color(0xb8860bff.toInt()),
+ "darkgray" to Color(0xa9a9a9ff.toInt()),
+ "darkgreen" to Color(0x006400ff.toInt()),
+ "darkgrey" to Color(0xa9a9a9ff.toInt()),
+ "darkkhaki" to Color(0xbdb76bff.toInt()),
+ "darkmagenta" to Color(0x8b008bff.toInt()),
+ "darkolivegreen" to Color(0x556b2fff.toInt()),
+ "darkorange" to Color(0xff8c00ff.toInt()),
+ "darkorchid" to Color(0x9932ccff.toInt()),
+ "darkred" to Color(0x8b0000ff.toInt()),
+ "darksalmon" to Color(0xe9967aff.toInt()),
+ "darkseagreen" to Color(0x8fbc8fff.toInt()),
+ "darkslateblue" to Color(0x483d8bff.toInt()),
+ "darkslategray" to Color(0x2f4f4fff.toInt()),
+ "darkslategrey" to Color(0x2f4f4fff.toInt()),
+ "darkturquoise" to Color(0x00ced1ff.toInt()),
+ "darkviolet" to Color(0x9400d3ff.toInt()),
+ "deeppink" to Color(0xff1493ff.toInt()),
+ "deepskyblue" to Color(0x00bfffff.toInt()),
+ "dimgray" to Color(0x696969ff.toInt()),
+ "dimgrey" to Color(0x696969ff.toInt()),
+ "dodgerblue" to Color(0x1e90ffff.toInt()),
+ "firebrick" to Color(0xb22222ff.toInt()),
+ "floralwhite" to Color(0xfffaf0ff.toInt()),
+ "forestgreen" to Color(0x228b22ff.toInt()),
+ "fuchsia" to Color(0xff00ffff.toInt()),
+ "gainsboro" to Color(0xdcdcdcff.toInt()),
+ "ghostwhite" to Color(0xf8f8ffff.toInt()),
+ "gold" to Color(0xffd700ff.toInt()),
+ "goldenrod" to Color(0xdaa520ff.toInt()),
+ "gray" to Color(0x808080ff.toInt()),
+ "green" to Color(0x008000ff.toInt()),
+ "greenyellow" to Color(0xadff2fff.toInt()),
+ "grey" to Color(0x808080ff.toInt()),
+ "honeydew" to Color(0xf0fff0ff.toInt()),
+ "hotpink" to Color(0xff69b4ff.toInt()),
+ "indianred" to Color(0xcd5c5cff.toInt()),
+ "indigo" to Color(0x4b0082ff.toInt()),
+ "ivory" to Color(0xfffff0ff.toInt()),
+ "khaki" to Color(0xf0e68cff.toInt()),
+ "lavender" to Color(0xe6e6faff.toInt()),
+ "lavenderblush" to Color(0xfff0f5ff.toInt()),
+ "lawngreen" to Color(0x7cfc00ff.toInt()),
+ "lemonchiffon" to Color(0xfffacdff.toInt()),
+ "lightblue" to Color(0xadd8e6ff.toInt()),
+ "lightcoral" to Color(0xf08080ff.toInt()),
+ "lightcyan" to Color(0xe0ffffff.toInt()),
+ "lightgoldenrodyellow" to Color(0xfafad2ff.toInt()),
+ "lightgray" to Color(0xd3d3d3ff.toInt()),
+ "lightgreen" to Color(0x90ee90ff.toInt()),
+ "lightgrey" to Color(0xd3d3d3ff.toInt()),
+ "lightpink" to Color(0xffb6c1ff.toInt()),
+ "lightsalmon" to Color(0xffa07aff.toInt()),
+ "lightseagreen" to Color(0x20b2aaff.toInt()),
+ "lightskyblue" to Color(0x87cefaff.toInt()),
+ "lightslategray" to Color(0x778899ff.toInt()),
+ "lightslategrey" to Color(0x778899ff.toInt()),
+ "lightsteelblue" to Color(0xb0c4deff.toInt()),
+ "lightyellow" to Color(0xffffe0ff.toInt()),
+ "lime" to Color(0x00ff00ff.toInt()),
+ "limegreen" to Color(0x32cd32ff.toInt()),
+ "linen" to Color(0xfaf0e6ff.toInt()),
+ "magenta" to Color(0xff00ffff.toInt()),
+ "maroon" to Color(0x800000ff.toInt()),
+ "mediumaquamarine" to Color(0x66cdaaff.toInt()),
+ "mediumblue" to Color(0x0000cdff.toInt()),
+ "mediumorchid" to Color(0xba55d3ff.toInt()),
+ "mediumpurple" to Color(0x9370dbff.toInt()),
+ "mediumseagreen" to Color(0x3cb371ff.toInt()),
+ "mediumslateblue" to Color(0x7b68eeff.toInt()),
+ "mediumspringgreen" to Color(0x00fa9aff.toInt()),
+ "mediumturquoise" to Color(0x48d1ccff.toInt()),
+ "mediumvioletred" to Color(0xc71585ff.toInt()),
+ "midnightblue" to Color(0x191970ff.toInt()),
+ "mintcream" to Color(0xf5fffaff.toInt()),
+ "mistyrose" to Color(0xffe4e1ff.toInt()),
+ "moccasin" to Color(0xffe4b5ff.toInt()),
+ "navajowhite" to Color(0xffdeadff.toInt()),
+ "navy" to Color(0x000080ff.toInt()),
+ "oldlace" to Color(0xfdf5e6ff.toInt()),
+ "olive" to Color(0x808000ff.toInt()),
+ "olivedrab" to Color(0x6b8e23ff.toInt()),
+ "orange" to Color(0xffa500ff.toInt()),
+ "orangered" to Color(0xff4500ff.toInt()),
+ "orchid" to Color(0xda70d6ff.toInt()),
+ "palegoldenrod" to Color(0xeee8aaff.toInt()),
+ "palegreen" to Color(0x98fb98ff.toInt()),
+ "paleturquoise" to Color(0xafeeeeff.toInt()),
+ "palevioletred" to Color(0xdb7093ff.toInt()),
+ "papayawhip" to Color(0xffefd5ff.toInt()),
+ "peachpuff" to Color(0xffdab9ff.toInt()),
+ "peru" to Color(0xcd853fff.toInt()),
+ "pink" to Color(0xffc0cbff.toInt()),
+ "plum" to Color(0xdda0ddff.toInt()),
+ "powderblue" to Color(0xb0e0e6ff.toInt()),
+ "purple" to Color(0x800080ff.toInt()),
+ "rebeccapurple" to Color(0x663399ff.toInt()),
+ "red" to Color(0xff0000ff.toInt()),
+ "rosybrown" to Color(0xbc8f8fff.toInt()),
+ "royalblue" to Color(0x4169e1ff.toInt()),
+ "saddlebrown" to Color(0x8b4513ff.toInt()),
+ "salmon" to Color(0xfa8072ff.toInt()),
+ "sandybrown" to Color(0xf4a460ff.toInt()),
+ "seagreen" to Color(0x2e8b57ff.toInt()),
+ "seashell" to Color(0xfff5eeff.toInt()),
+ "sienna" to Color(0xa0522dff.toInt()),
+ "silver" to Color(0xc0c0c0ff.toInt()),
+ "skyblue" to Color(0x87ceebff.toInt()),
+ "slateblue" to Color(0x6a5acdff.toInt()),
+ "slategray" to Color(0x708090ff.toInt()),
+ "slategrey" to Color(0x708090ff.toInt()),
+ "snow" to Color(0xfffafaff.toInt()),
+ "springgreen" to Color(0x00ff7fff.toInt()),
+ "steelblue" to Color(0x4682b4ff.toInt()),
+ "tan" to Color(0xd2b48cff.toInt()),
+ "teal" to Color(0x008080ff.toInt()),
+ "thistle" to Color(0xd8bfd8ff.toInt()),
+ "tomato" to Color(0xff6347ff.toInt()),
+ "transparent" to Color(0),
+ "turquoise" to Color(0x40e0d0ff.toInt()),
+ "violet" to Color(0xee82eeff.toInt()),
+ "wheat" to Color(0xf5deb3ff.toInt()),
+ "white" to Color(0xffffffff.toInt()),
+ "whitesmoke" to Color(0xf5f5f5ff.toInt()),
+ "yellow" to Color(0xffff00ff.toInt()),
+ "yellowgreen" to Color(0x9acd32ff.toInt())
)
private val pageWidthMap = hashMapOf(
@@ -239,14 +452,35 @@ object BTeXParser {
// TODO add post-parsing hook to the handler
}
-
-
-
-
+ @OpenTag // reflective access is impossible with 'private'
+ fun processElemBTEX(handler: BTeXHandler, doc: BTeXDocument, theTag: String, uri: String, attribs: HashMap) {
+ handler.paragraphBuffer.append("BTeX")
+ }
@OpenTag // reflective access is impossible with 'private'
- fun processElemBR(handler: BTeXHandler, doc: BTeXDocument, theTag: String, uri: String, attribs: HashMap) {
+ fun processElemCOVER(handler: BTeXHandler, doc: BTeXDocument, theTag: String, uri: String, attribs: HashMap) {
+ doc.addNewPage(Color(0x6f4a45ff))
+ }
+ @OpenTag // reflective access is impossible with 'private'
+ fun processElemTOC(handler: BTeXHandler, doc: BTeXDocument, theTag: String, uri: String, attribs: HashMap) {
+ doc.addNewPage()
+ }
+
+ @OpenTag // reflective access is impossible with 'private'
+ fun processElemMANUSCRIPT(handler: BTeXHandler, doc: BTeXDocument, theTag: String, uri: String, attribs: HashMap) {
+ doc.addNewPage()
+ }
+
+
+
+
+
+
+
+ @OpenTag // reflective access is impossible with 'private'
+ fun processElemBR(handler: BTeXHandler, doc: BTeXDocument, theTag: String, uri: String, attribs: HashMap) {
+ handler.paragraphBuffer.append("\n")
}
@OpenTag // reflective access is impossible with 'private'
@@ -256,12 +490,63 @@ object BTeXParser {
@OpenTag // reflective access is impossible with 'private'
fun processElemP(handler: BTeXHandler, doc: BTeXDocument, theTag: String, uri: String, attribs: HashMap) {
-
}
@CloseTag // reflective access is impossible with 'private'
fun closeElemP(handler: BTeXHandler, doc: BTeXDocument, theTag: String, uri: String) {
+ printdbg("Par: ${handler.paragraphBuffer}")
+ val font = getFont()
+ val slugs = MovableType(font, handler.paragraphBuffer.toString(), doc.pageWidth)
+
+
+ var remainder = doc.pageLines - doc.currentLine
+ var slugHeight = slugs.height
+ var linesOut = 0
+
+ if (slugHeight > remainder) {
+ val subset = linesOut to linesOut + remainder
+
+ val drawCall = BTeXDrawCall(
+ 0,
+ remainder * doc.pageLines,
+ handler.currentTheme,
+ handler.getSpanColour(),
+ MovableTypeDrawCall(slugs, subset.first, subset.second)
+ )
+
+ doc.appendDrawCall(drawCall)
+
+ linesOut += remainder
+ slugHeight -= remainder
+
+ doc.addNewPage()
+ }
+
+ while (slugHeight > 0) {
+ remainder = minOf(slugHeight, doc.pageLines)
+
+ val subset = linesOut to linesOut + remainder
+
+ val drawCall = BTeXDrawCall(
+ 0,
+ 0,
+ handler.currentTheme,
+ handler.getSpanColour(),
+ MovableTypeDrawCall(slugs, subset.first, subset.second)
+ )
+
+ doc.appendDrawCall(drawCall)
+
+ linesOut += remainder
+ slugHeight -= remainder
+
+ if (remainder == doc.pageLines) {
+ doc.addNewPage()
+ }
+ }
+
+ handler.paragraphBuffer.clear()
}
@OpenTag // reflective access is impossible with 'private'
@@ -275,6 +560,7 @@ object BTeXParser {
fun closeElemSPAN(handler: BTeXHandler, doc: BTeXDocument, theTag: String, uri: String) {
spanColour = null
}
+
}
diff --git a/src/net/torvald/terrarum/tests/BTeXTest.kt b/src/net/torvald/terrarum/tests/BTeXTest.kt
index 0797c6b6a..a96211214 100644
--- a/src/net/torvald/terrarum/tests/BTeXTest.kt
+++ b/src/net/torvald/terrarum/tests/BTeXTest.kt
@@ -1,18 +1,18 @@
package net.torvald.terrarum.tests
+import com.badlogic.gdx.ApplicationAdapter
+import com.badlogic.gdx.backends.lwjgl3.Lwjgl3Application
+import com.badlogic.gdx.backends.lwjgl3.Lwjgl3ApplicationConfiguration
+import com.badlogic.gdx.graphics.glutils.ShaderProgram
import net.torvald.btex.BTeXParser
-import org.xml.sax.Attributes
-import org.xml.sax.HandlerBase
-import org.xml.sax.helpers.DefaultHandler
-import java.io.ByteArrayInputStream
-import java.io.InputStream
-import javax.xml.parsers.SAXParserFactory
+import net.torvald.terrarum.btex.BTeXDocument
/**
* Created by minjaesong on 2023-10-28.
*/
-fun main() {
+class BTeXTest : ApplicationAdapter() {
+
val csiR = "\u001B[31m"
val csiG = "\u001B[32m"
val csi0 = "\u001B[m"
@@ -27,54 +27,87 @@ fun main() {
-
+
+
+
What Is a Book
- This example book is designed to give you the exampe of the Book Language.
+ This example book is designed to give you the example of the Book Language.
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 hyperlinks.
+ enumerable pages and insertion of other helpful resources, such as illustrations and hyperlinks.
-
- this page is intentionally left blank
-
+
+ this page is intentionally left blank
+
+
+
+
Writing Book Using Pen and Papers
- 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, sections.
+ 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, sections.
+
+
+
Writing Book Using Typewriter
- Typewriters can only write single style of font, therefore chapters and sections are not available.
+ Typewriters can only write single style of font, therefore chapters and
+ sections are not available.
+
+
+
Writing Book using Computer
Writing book using a computer requires a use of the Book Typesetting Engine Extended, or
Full Control of the Shape
- With 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 papers but a fully-featured printouts that
- have illustrations in it, to a fully-featured hardcover book.
+ With 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 papers but a
+ fully-featured printouts that have illustrations in it, to a fully-featured hardcover book.
- This style is controlled using the cover attribute on the root tag, with following
- values: typewriter, printout, hardcover
+ This style is controlled using the cover attribute on the root tag,
+ with following values: typewriter, printout, hardcover
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.
+ while Hardcover is considered bound and two pages are presented to the readers.
-
+
+
"""
- val doku = BTeXParser(tex)
+ private lateinit var document: BTeXDocument
+
+ override fun create() {
+ document = BTeXParser.invoke(tex)
+ }
+
+
+
+}
+
+fun main() {
+ ShaderProgram.pedantic = false
+
+ val appConfig = Lwjgl3ApplicationConfiguration()
+ appConfig.useVsync(false)
+ appConfig.setResizable(false)
+ appConfig.setWindowedMode(1280, 720)
+ appConfig.setForegroundFPS(60)
+ appConfig.setOpenGLEmulation(Lwjgl3ApplicationConfiguration.GLEmulation.GL30, 3, 2)
+
+ Lwjgl3Application(BTeXTest(), appConfig)
}
\ No newline at end of file