mirror of
https://github.com/curioustorvald/Terrarum.git
synced 2026-03-07 12:21:52 +09:00
btex: img tag with fromgame attrib
This commit is contained in:
@@ -169,12 +169,12 @@
|
||||
|
||||
<callout align="left" class="code"><!--
|
||||
--><img src="http(s) or file URL" height="8"/><br/><!--
|
||||
--><img fromgame="basegame:gui/small.png" height="4"/><br/><!--
|
||||
--><img gameitem="basegame:33" height="1"/>
|
||||
--><img fromgame="basegame:gui/small.png" height="4"/>
|
||||
</callout>
|
||||
|
||||
<p>The <code>height</code> attribute specifies the height of the image <emph>in the number of lines</emph>,
|
||||
rather than pixels, the width is calculated automatically. Image width wider than the text width will cause an error.</p>
|
||||
rather than pixels, the width is calculated automatically; image width wider than the text width
|
||||
will cause an error. The tag optionally takes caption attribute which prints a text below the image.</p>
|
||||
|
||||
<p>Supported image formats: JPEG, PNG, BMP or TGA</p>
|
||||
|
||||
@@ -304,7 +304,9 @@
|
||||
system is there because the book is being printed in the background on separate threads
|
||||
(yes, they are multi-threaded!) to not interfere with the normal gameplay, or else the players will
|
||||
encounter the freezing every time the book is being printed, and this would be a huge minus towards
|
||||
the gameplay experience. If the process exits without any error, the mailing system will be
|
||||
the gameplay experience.</p>
|
||||
|
||||
<p>If the process exits without any error, the mailing system will be
|
||||
notified and will send the mail containing finished books to the player; if the process exits
|
||||
with errors, the mail containing details of the errors will be sent instead.</p>
|
||||
|
||||
|
||||
@@ -142,7 +142,7 @@
|
||||
<li><code>left</code> — 문단을 좌측정렬함</li>
|
||||
<li><code>right</code> — 문단을 우측정렬함</li>
|
||||
<li><code>center</code> — 문단을 중앙정렬함</li>
|
||||
<li><code>justify</code> — 문단을 양끝정렬함. 기본값</li>
|
||||
<li><code>justify</code> — 문단을 양쪽정렬함. 기본값</li>
|
||||
</ul>
|
||||
<p><code>p</code>, <code>span</code>, <code>callout</code> 태그는 추가로 <code>class="code"</code> 속성을 지원한다. 이 속성이 적용된 문구는 <span class="code">코드꼴(code font)</span>을 사용하여 인자된다.</p>
|
||||
|
||||
@@ -162,11 +162,10 @@
|
||||
|
||||
<callout align="left" class="code"><!--
|
||||
--><img src="http(s)나 file URL" height="8"/><br/><!--
|
||||
--><img fromgame="basegame:gui/small.png" height="4"/><br/><!--
|
||||
--><img gameitem="basegame:33" height="1"/>
|
||||
--><img fromgame="basegame:gui/small.png" height="4"/>
|
||||
</callout>
|
||||
|
||||
<p><code>height</code> 속성은 이미지의 높이를 <emph>픽셀 단위가 아닌 줄의 개수</emph>로 지정하어야 한다. 이미지의 너비는 자동으로 계산된다. 텍스트의 너비보다 넓다면 오류가 발생한다.</p>
|
||||
<p><code>height</code> 속성은 이미지의 높이를 <emph>픽셀 단위가 아닌 줄의 개수</emph>로 지정하어야 한다. 이미지의 너비는 자동으로 계산되며, 텍스트의 너비보다 넓다면 오류가 발생한다. 이미지 하단에 문구를 출력하려면 <code>caption</code> 속성을 사용할 수 있다.</p>
|
||||
|
||||
<p>지원하는 이미지 포맷: JPEG·PNG·BMP·TGA</p>
|
||||
|
||||
@@ -268,8 +267,15 @@
|
||||
-->[koKR] 원고가 담긴 <itemname>홀로테이프를</itemname> 출판사로 우편을 통해 보내야 책이 인쇄됩니다.</callout>
|
||||
|
||||
|
||||
<part>일반인 출입금지</part>
|
||||
|
||||
<chapter>왜 책이 인쇄될 때까지 기다려야 하나요? 인쇄기를 직접 사용할 수는 없나요?</chapter>
|
||||
|
||||
<p><btex/> 엔진은 빠른 물건이 아니다. 책을 하나 조판하려면 최소 몇 초가 필요하다. “대기 시스템”은 별도의 스레드 풀에서 (멀티스레딩으로 작동함) 책이 인쇄되도록 하여 게임플레이를 방해하지 않도록 도입되었다. 이것이 없다면 책이 한번 인쇄될 때마다 게임이 ‘응답 없음’ 상태가 될 것이고, 이는 인게임 경험에 매우 부정적으로 작용한다.</p>
|
||||
|
||||
<p>인쇄 프로세스가 오류 없이 종료되었다면, 우편 시스템을 통해 플레이어에게 완성된 책을 배송한다. 오류가 있다면 오류 정보를 담은 우편이 대신 배송된다.</p>
|
||||
|
||||
<p>상기와 같은 이유로 “인쇄기”는 플레이어에게 직접적으로 제공되지 않고, “출판사”와 우편을 통해 간접적으로 이용하는 형태로 제공된다.</p>
|
||||
|
||||
<newpage/>
|
||||
|
||||
|
||||
@@ -48,6 +48,7 @@
|
||||
"src CDATA #IMPLIED
|
||||
fromgame CDATA #IMPLIED
|
||||
gameitem CDATA #IMPLIED
|
||||
caption %Text; #IMPLIED
|
||||
height %Number; #REQUIRED">
|
||||
<!ENTITY % coreattrs
|
||||
"id CDATA #IMPLIED
|
||||
|
||||
@@ -99,7 +99,8 @@ class BTeXDocument : Disposable {
|
||||
Clustfile(DOM, "/${page}.png").also {
|
||||
if (!it.exists()) throw IllegalStateException("No file '${page}.png' on the archive")
|
||||
|
||||
val tempFile = newTempFile("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 = newTempFile("btex-import") // 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.tmp") // tmpfs not working???
|
||||
it.exportFileTo(tempFile.file())
|
||||
val texture = TextureRegion(Texture(tempFile))
|
||||
doc.pageTextures[page] = texture
|
||||
|
||||
@@ -928,21 +928,27 @@ object BTeXParser {
|
||||
val imgHeight = doc.lineHeightInPx * heightInLines - 6
|
||||
val btexObjName = "IMG@${makeRandomObjName()}"
|
||||
val img = attribs["src"]
|
||||
val fromgame = attribs["fromgame"]
|
||||
val caption = attribs["caption"]
|
||||
|
||||
if (listOf(img, fromgame).count { it != null } != 1) {
|
||||
throw IllegalArgumentException()
|
||||
}
|
||||
|
||||
// image overflowing?
|
||||
if (doc.pageLines - doc.linesPrintedOnPage.last() < heightInLines)
|
||||
doc.addNewPage()
|
||||
|
||||
if (img != null) {
|
||||
val tempFile = FileHandle.tempFile("btex_$btexObjName")
|
||||
try {
|
||||
val tempFile = FileHandle.tempFile("btex_$btexObjName")
|
||||
try {
|
||||
|
||||
val inputPixmap = if (img.startsWith("file://")) {
|
||||
// printdbg("Using local file ${img.substring(7)}")
|
||||
val inputPixmap = if (img != null) {
|
||||
if (img.startsWith("file://")) {
|
||||
// printdbg("Using local file ${img.substring(7)}")
|
||||
Pixmap(Gdx.files.absolute(img.substring(7)))
|
||||
}
|
||||
else {
|
||||
// printdbg("Downloading image $img")
|
||||
// printdbg("Downloading image $img")
|
||||
BufferedInputStream(URL(img).openStream()).use { `in` ->
|
||||
FileOutputStream(tempFile.file()).use { fileOutputStream ->
|
||||
val dataBuffer = ByteArray(1024)
|
||||
@@ -954,39 +960,47 @@ object BTeXParser {
|
||||
}
|
||||
Pixmap(tempFile).also { App.disposables.add(it) }
|
||||
}
|
||||
|
||||
val imgWidth = (imgHeight.toFloat() / inputPixmap.height * inputPixmap.width).roundToInt()
|
||||
|
||||
if (imgWidth > doc.textWidth)
|
||||
throw RuntimeException("Image width ($imgWidth) is larger than the text width (${doc.textWidth})")
|
||||
|
||||
val drawCallObj = { parentText: BTeXDrawCall -> object : BTeXBatchDrawCall(imgWidth, (heightInLines - 1).coerceAtLeast(0), parentText) {
|
||||
private lateinit var inputTexture: Texture
|
||||
override fun draw(doc: BTeXDocument, batch: SpriteBatch, x: Float, y: Float, font: TerrarumSansBitmap?) {
|
||||
if (!::inputTexture.isInitialized) {
|
||||
inputTexture = Texture(inputPixmap).also { App.disposables.add(it) }
|
||||
}
|
||||
val destX = (x + (doc.pageDimensionWidth - imgWidth) / 2)
|
||||
val destY = y + 1
|
||||
batch.draw(inputTexture, destX, destY, imgWidth.toFloat(), imgHeight.toFloat())
|
||||
}
|
||||
override fun drawToPixmap(doc: BTeXDocument, pixmap: Pixmap, x: Int, y: Int, font: TerrarumSansBitmap?) {
|
||||
val destX = x
|
||||
val destY = y + 1
|
||||
pixmap.drawPixmap(inputPixmap, 0, 0, inputPixmap.width, inputPixmap.height, destX, destY, imgWidth, imgHeight)
|
||||
}
|
||||
} }
|
||||
|
||||
objDict[btexObjName] = { text: BTeXDrawCall -> drawCallObj(text) }
|
||||
objWidthDict[btexObjName] = imgWidth
|
||||
|
||||
typesetParagraphs(objectMarkerWithWidth(btexObjName, imgWidth), handler, align = "center")
|
||||
}
|
||||
catch (e: IOException) { }
|
||||
catch (e: GdxRuntimeException) { }
|
||||
finally {
|
||||
tempFile.delete()
|
||||
else if (fromgame != null) {
|
||||
val moduleName = fromgame.substringBefore(':')
|
||||
val modulePath = fromgame.substringAfter(':')
|
||||
Pixmap(ModMgr.getGdxFile(moduleName, modulePath))
|
||||
}
|
||||
else throw InternalError()
|
||||
|
||||
val imgWidth = (imgHeight.toFloat() / inputPixmap.height * inputPixmap.width).roundToInt()
|
||||
|
||||
if (imgWidth > doc.textWidth)
|
||||
throw RuntimeException("Image width ($imgWidth) is larger than the text width (${doc.textWidth})")
|
||||
|
||||
val drawCallObj = { parentText: BTeXDrawCall -> object : BTeXBatchDrawCall(imgWidth, (heightInLines - 1).coerceAtLeast(0), parentText) {
|
||||
private lateinit var inputTexture: Texture
|
||||
override fun draw(doc: BTeXDocument, batch: SpriteBatch, x: Float, y: Float, font: TerrarumSansBitmap?) {
|
||||
if (!::inputTexture.isInitialized) {
|
||||
inputTexture = Texture(inputPixmap).also { App.disposables.add(it) }
|
||||
}
|
||||
val destX = (x + (doc.pageDimensionWidth - imgWidth) / 2)
|
||||
val destY = y + 1
|
||||
batch.draw(inputTexture, destX, destY, imgWidth.toFloat(), imgHeight.toFloat())
|
||||
}
|
||||
override fun drawToPixmap(doc: BTeXDocument, pixmap: Pixmap, x: Int, y: Int, font: TerrarumSansBitmap?) {
|
||||
val destX = x
|
||||
val destY = y + 1
|
||||
pixmap.drawPixmap(inputPixmap, 0, 0, inputPixmap.width, inputPixmap.height, destX, destY, imgWidth, imgHeight)
|
||||
}
|
||||
} }
|
||||
|
||||
objDict[btexObjName] = { text: BTeXDrawCall -> drawCallObj(text) }
|
||||
objWidthDict[btexObjName] = imgWidth
|
||||
|
||||
typesetParagraphs(objectMarkerWithWidth(btexObjName, imgWidth), handler, align = "center")
|
||||
if (caption != null)
|
||||
typesetParagraphs("$ccDefault$caption", handler, align = "center")
|
||||
}
|
||||
catch (e: IOException) { }
|
||||
catch (e: GdxRuntimeException) { }
|
||||
finally {
|
||||
tempFile.delete()
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1697,7 +1711,7 @@ object BTeXParser {
|
||||
val dotGap = 10
|
||||
val dotPosEnd = typeWidth - pageNumWidth - dotGap*1.5f
|
||||
|
||||
typesetParagraphs("$ccDefault$heading$name", handler, typeWidth, startingPage = pageToWrite ?: doc.currentPage, align = "justify").let {
|
||||
typesetParagraphs("$ccDefault$heading$name", handler, typeWidth - pageNumWidth - dotGap, startingPage = pageToWrite ?: doc.currentPage, align = "justify").let {
|
||||
it.forEach {
|
||||
it.posX += indentation
|
||||
|
||||
|
||||
@@ -27,11 +27,11 @@ import kotlin.system.measureTimeMillis
|
||||
class BTeXTest : ApplicationAdapter() {
|
||||
|
||||
// val filePath = "btex.xml"
|
||||
// val filePath = "btex_ko.xml"
|
||||
val filePath = "test.xml"
|
||||
val filePath = "btex_ko.xml"
|
||||
// val filePath = "test.xml"
|
||||
// val filePath = "literature/en/daniel_defoe_robinson_crusoe.xml"
|
||||
// val filePath = "literature/ruRU/anton_chekhov_palata_no_6.xml"
|
||||
// val filePath = "literature/koKR/yisang_nalgae.btxbook"
|
||||
// val filePath = "literature/koKR/yisang_nalgae.xml"
|
||||
|
||||
|
||||
private lateinit var document: BTeXDocument
|
||||
|
||||
Reference in New Issue
Block a user