mirror of
https://github.com/curioustorvald/Terrarum-sans-bitmap.git
synced 2026-03-15 23:46:09 +09:00
unindentation if the line starts with hangables
This commit is contained in:
@@ -92,7 +92,7 @@ class MovableType(
|
|||||||
|
|
||||||
width = maxOf(width, nextPosX + box.width)
|
width = maxOf(width, nextPosX + box.width)
|
||||||
}
|
}
|
||||||
fun dispatchSlug(align: TypesettingStrategy) {
|
fun dispatchSlug(align: TypesettingStrategy, unindent: Int) {
|
||||||
val frozen = slug.freezeIntoCodepointSequence(font)
|
val frozen = slug.freezeIntoCodepointSequence(font)
|
||||||
|
|
||||||
// insert empty blocks to the left
|
// insert empty blocks to the left
|
||||||
@@ -131,6 +131,10 @@ class MovableType(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (unindent != 0) {
|
||||||
|
frozen.addAll(0, (-unindent).glueSizeToGlueChars())
|
||||||
|
}
|
||||||
|
|
||||||
typesettedSlugs.add(frozen)
|
typesettedSlugs.add(frozen)
|
||||||
|
|
||||||
slug = ArrayList()
|
slug = ArrayList()
|
||||||
@@ -140,7 +144,7 @@ class MovableType(
|
|||||||
///////////////////////////////////////////////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
// the slug is likely end with a glue, must take care of it (but don't modify the slug itself)
|
// the slug is likely end with a glue, must take care of it (but don't modify the slug itself)
|
||||||
fun getBadnessW(box: NoTexGlyphLayout, availableGlues: Int): Triple<Double, Int, Any?> {
|
fun getBadnessW(box: NoTexGlyphLayout, availableGlues: Int, unindentSize: Int): Triple<Double, Int, Any?> {
|
||||||
val slug = slug.toMutableList()
|
val slug = slug.toMutableList()
|
||||||
|
|
||||||
// remove the trailing glue(s?) in the slug copy
|
// remove the trailing glue(s?) in the slug copy
|
||||||
@@ -148,7 +152,7 @@ class MovableType(
|
|||||||
slug.removeLastOrNull()
|
slug.removeLastOrNull()
|
||||||
}
|
}
|
||||||
|
|
||||||
var slugWidth = slug.lastOrNull()?.getEndPos() ?: 0
|
var slugWidth = (slug.lastOrNull()?.getEndPos() ?: 0) - unindentSize
|
||||||
if (slug.isNotEmpty() && slug.last().block.penultimateCharOrNull != null && hangable.contains(slug.last().block.penultimateCharOrNull))
|
if (slug.isNotEmpty() && slug.last().block.penultimateCharOrNull != null && hangable.contains(slug.last().block.penultimateCharOrNull))
|
||||||
slugWidth -= hangWidth
|
slugWidth -= hangWidth
|
||||||
else if (slug.isNotEmpty() && slug.last().block.penultimateCharOrNull != null && hangableFW.contains(slug.last().block.penultimateCharOrNull))
|
else if (slug.isNotEmpty() && slug.last().block.penultimateCharOrNull != null && hangableFW.contains(slug.last().block.penultimateCharOrNull))
|
||||||
@@ -160,14 +164,14 @@ class MovableType(
|
|||||||
return Triple(badness, difference, null)
|
return Triple(badness, difference, null)
|
||||||
}
|
}
|
||||||
|
|
||||||
fun getBadnessT(box: NoTexGlyphLayout, availableGlues: Int): Triple<Double, Int, Any?> {
|
fun getBadnessT(box: NoTexGlyphLayout, availableGlues: Int, unindentSize: Int): Triple<Double, Int, Any?> {
|
||||||
val slug = slug.toMutableList()
|
val slug = slug.toMutableList()
|
||||||
|
|
||||||
// add the box to the slug copy
|
// add the box to the slug copy
|
||||||
val nextPosX = (slug.lastOrNull()?.getEndPos() ?: 0)
|
val nextPosX = (slug.lastOrNull()?.getEndPos() ?: 0)
|
||||||
slug.add(Block(nextPosX, box))
|
slug.add(Block(nextPosX, box))
|
||||||
|
|
||||||
var slugWidth = slugWidth + box.width
|
var slugWidth = slugWidth + box.width - unindentSize
|
||||||
if (slug.isNotEmpty() && slug.last().block.penultimateCharOrNull != null && hangable.contains(slug.last().block.penultimateCharOrNull))
|
if (slug.isNotEmpty() && slug.last().block.penultimateCharOrNull != null && hangable.contains(slug.last().block.penultimateCharOrNull))
|
||||||
slugWidth -= hangWidth
|
slugWidth -= hangWidth
|
||||||
else if (slug.isNotEmpty() && slug.last().block.penultimateCharOrNull != null && hangableFW.contains(slug.last().block.penultimateCharOrNull))
|
else if (slug.isNotEmpty() && slug.last().block.penultimateCharOrNull != null && hangableFW.contains(slug.last().block.penultimateCharOrNull))
|
||||||
@@ -179,7 +183,7 @@ class MovableType(
|
|||||||
return Triple(badness, difference, null)
|
return Triple(badness, difference, null)
|
||||||
}
|
}
|
||||||
|
|
||||||
fun getBadnessH(box: NoTexGlyphLayout, diff: Int, availableGlues: Int): Triple<Double, Int, Any?> {
|
fun getBadnessH(box: NoTexGlyphLayout, diff: Int, availableGlues: Int, unindentSize: Int): Triple<Double, Int, Any?> {
|
||||||
// don't hyphenate if:
|
// don't hyphenate if:
|
||||||
// - the word is too short (5 chars or less)
|
// - the word is too short (5 chars or less)
|
||||||
// - the word is pre-hyphenated (ends with hyphen-null)
|
// - the word is pre-hyphenated (ends with hyphen-null)
|
||||||
@@ -197,7 +201,7 @@ class MovableType(
|
|||||||
val nextPosX = (slug.lastOrNull()?.getEndPos() ?: 0)
|
val nextPosX = (slug.lastOrNull()?.getEndPos() ?: 0)
|
||||||
slug.add(Block(nextPosX, hyphHead))
|
slug.add(Block(nextPosX, hyphHead))
|
||||||
|
|
||||||
var slugWidth = slugWidth + hyphHead.width
|
var slugWidth = slugWidth + hyphHead.width - unindentSize
|
||||||
if (slug.isNotEmpty() && slug.last().block.penultimateCharOrNull != null && hangable.contains(slug.last().block.penultimateCharOrNull))
|
if (slug.isNotEmpty() && slug.last().block.penultimateCharOrNull != null && hangable.contains(slug.last().block.penultimateCharOrNull))
|
||||||
slugWidth -= hangWidth
|
slugWidth -= hangWidth
|
||||||
else if (slug.isNotEmpty() && slug.last().block.penultimateCharOrNull != null && hangableFW.contains(slug.last().block.penultimateCharOrNull))
|
else if (slug.isNotEmpty() && slug.last().block.penultimateCharOrNull != null && hangableFW.contains(slug.last().block.penultimateCharOrNull))
|
||||||
@@ -216,21 +220,34 @@ class MovableType(
|
|||||||
|
|
||||||
if (box.isNotGlue()) {
|
if (box.isNotGlue()) {
|
||||||
// deal with the hangables
|
// deal with the hangables
|
||||||
|
val firstChar = slug.firstOrNull()?.block?.secondCharOrNull
|
||||||
|
val lastChar = box.penultimateCharOrNull
|
||||||
|
val slugUnindent = when (strategy) {
|
||||||
|
TypesettingStrategy.JUSTIFIED -> {
|
||||||
|
if (firstChar == null)
|
||||||
|
0
|
||||||
|
else if (hangable.contains(firstChar))
|
||||||
|
hangWidth
|
||||||
|
else
|
||||||
|
0
|
||||||
|
}
|
||||||
|
else -> 0
|
||||||
|
}
|
||||||
|
|
||||||
|
// if (slugUnindent != 0) println("Slug unindentation $slugUnindent on text ${slug.joinToString(" ") { it.block.text.toReadable() }}")
|
||||||
|
|
||||||
val slugWidthForOverflowCalc = when (strategy) {
|
val slugWidthForOverflowCalc = when (strategy) {
|
||||||
TypesettingStrategy.JUSTIFIED -> {
|
TypesettingStrategy.JUSTIFIED -> {
|
||||||
val penult = box.penultimateCharOrNull
|
if (lastChar == null)
|
||||||
|
slugWidth - slugUnindent
|
||||||
if (penult == null)
|
else if (hangable.contains(lastChar))
|
||||||
slugWidth
|
slugWidth - hangWidth - slugUnindent
|
||||||
else if (hangable.contains(penult))
|
else if (hangableFW.contains(lastChar))
|
||||||
slugWidth - hangWidth
|
slugWidth - hangWidthFW - slugUnindent
|
||||||
else if (hangableFW.contains(penult))
|
|
||||||
slugWidth - hangWidthFW
|
|
||||||
else
|
else
|
||||||
slugWidth
|
slugWidth - slugUnindent
|
||||||
}
|
}
|
||||||
|
else -> slugWidth
|
||||||
TypesettingStrategy.RAGGED_RIGHT, TypesettingStrategy.RAGGED_LEFT, TypesettingStrategy.CENTRED -> slugWidth
|
|
||||||
}
|
}
|
||||||
|
|
||||||
val truePaperWidth = when (strategy) {
|
val truePaperWidth = when (strategy) {
|
||||||
@@ -251,16 +268,19 @@ class MovableType(
|
|||||||
// widthDelta: can be positive or negative
|
// widthDelta: can be positive or negative
|
||||||
var (badnessW, widthDeltaW, _) = getBadnessW(
|
var (badnessW, widthDeltaW, _) = getBadnessW(
|
||||||
box,
|
box,
|
||||||
initialGlueCount
|
initialGlueCount,
|
||||||
|
slugWidthForOverflowCalc
|
||||||
) // widthDeltaW is always positive
|
) // widthDeltaW is always positive
|
||||||
var (badnessT, widthDeltaT, _) = getBadnessT(
|
var (badnessT, widthDeltaT, _) = getBadnessT(
|
||||||
box,
|
box,
|
||||||
initialGlueCount
|
initialGlueCount,
|
||||||
|
slugUnindent
|
||||||
) // widthDeltaT is always positive
|
) // widthDeltaT is always positive
|
||||||
var (badnessH, widthDeltaH, hyph) = getBadnessH(
|
var (badnessH, widthDeltaH, hyph) = getBadnessH(
|
||||||
box,
|
box,
|
||||||
box.width - slugWidthForOverflowCalc,
|
box.width - slugWidthForOverflowCalc,
|
||||||
initialGlueCount
|
initialGlueCount,
|
||||||
|
slugUnindent
|
||||||
) // widthDeltaH can be anything
|
) // widthDeltaH can be anything
|
||||||
|
|
||||||
badnessT -= 0.1 // try to break even
|
badnessT -= 0.1 // try to break even
|
||||||
@@ -365,7 +385,7 @@ class MovableType(
|
|||||||
}
|
}
|
||||||
|
|
||||||
// println(" > Line ${typesettedSlugs.size + 1} Final Slug: [ ${slug.map { it.block.text.toReadable() }.joinToString(" | ")} ]")
|
// println(" > Line ${typesettedSlugs.size + 1} Final Slug: [ ${slug.map { it.block.text.toReadable() }.joinToString(" | ")} ]")
|
||||||
dispatchSlug(strategy)
|
dispatchSlug(strategy, slugUnindent)
|
||||||
}
|
}
|
||||||
// if adding the box would cause overflow (ragged-something, centred)
|
// if adding the box would cause overflow (ragged-something, centred)
|
||||||
else {
|
else {
|
||||||
@@ -376,7 +396,7 @@ class MovableType(
|
|||||||
|
|
||||||
addHyphenatedTail(box)
|
addHyphenatedTail(box)
|
||||||
|
|
||||||
dispatchSlug(strategy)
|
dispatchSlug(strategy, slugUnindent)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// typeset the boxes normally
|
// typeset the boxes normally
|
||||||
@@ -391,7 +411,7 @@ class MovableType(
|
|||||||
|
|
||||||
if (!ignoreThisLine) {
|
if (!ignoreThisLine) {
|
||||||
// println(" > Line ${typesettedSlugs.size + 1} Final Slug: [ ${slug.map { it.block.text.toReadable() }.joinToString(" | ")} ]")
|
// println(" > Line ${typesettedSlugs.size + 1} Final Slug: [ ${slug.map { it.block.text.toReadable() }.joinToString(" | ")} ]")
|
||||||
dispatchSlug(strategy)
|
dispatchSlug(strategy, 0)
|
||||||
}
|
}
|
||||||
} // end of lines.forEach
|
} // end of lines.forEach
|
||||||
|
|
||||||
@@ -1080,6 +1100,8 @@ class MovableType(
|
|||||||
data class NoTexGlyphLayout(val text: CodepointSequence, val width: Int) {
|
data class NoTexGlyphLayout(val text: CodepointSequence, val width: Int) {
|
||||||
val penultimateCharOrNull: CodePoint?
|
val penultimateCharOrNull: CodePoint?
|
||||||
get() = text.getOrNull(text.size - 2)
|
get() = text.getOrNull(text.size - 2)
|
||||||
|
val secondCharOrNull: CodePoint?
|
||||||
|
get() = text.getOrNull(1)
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun createGlyphLayout(font: TerrarumSansBitmap, str: CodepointSequence): NoTexGlyphLayout {
|
private fun createGlyphLayout(font: TerrarumSansBitmap, str: CodepointSequence): NoTexGlyphLayout {
|
||||||
|
|||||||
Reference in New Issue
Block a user