line spacing tests, fix

This commit is contained in:
Bixilon 2023-06-13 21:09:54 +02:00
parent 8ef3deacbe
commit 1e72bae1e1
No known key found for this signature in database
GPG Key ID: 5CAD791931B09AC4
3 changed files with 143 additions and 30 deletions

View File

@ -13,7 +13,6 @@ import de.bixilon.minosoft.gui.rendering.font.types.dummy.DummyFontType
import de.bixilon.minosoft.gui.rendering.gui.mesh.GUIVertexConsumer
import de.bixilon.minosoft.gui.rendering.util.vec.vec2.Vec2Util.MAX
import org.testng.Assert.assertEquals
import org.testng.Assert.assertFalse
import org.testng.annotations.Test
@Test(groups = ["font"])
@ -27,49 +26,164 @@ class ChatComponentRendererTest {
return info
}
private fun TextRenderInfo.assert(
lineIndex: Int? = null,
lines: List<TextLineInfo>? = null,
size: Vec2? = null,
cutOff: Boolean = false,
) {
if (lineIndex != null) assertEquals(this.lineIndex, lineIndex, "Line index mismatch")
if (lines != null) assertEquals(this.lines, lines, "Lines mismatch")
if (size != null) assertEquals(this.size, size, "Size mismatch")
assertEquals(this.cutOff, cutOff, "Cutoff mismatch!")
}
fun noText() {
val info = render(ChatComponent.EMPTY)
assertEquals(info.lineIndex, 0)
assertEquals(info.lines.size, 0)
assertEquals(info.size, Vec2())
info.assert(lineIndex = 0, lines = emptyList(), size = Vec2())
}
fun emptyChar() {
val info = render(TextComponent("a")) // a has a length of 0px
assertEquals(info.lineIndex, 0)
assertEquals(info.lines.size, 0)
assertEquals(info.size, Vec2())
info.assert(lineIndex = 0, lines = emptyList(), size = Vec2())
}
fun singleChar() {
val info = render(TextComponent("b"))
assertEquals(info.lineIndex, 0)
assertEquals(info.lines, listOf(TextLineInfo(BaseComponent(TextComponent("b")), 0.5f)))
assertEquals(info.size, Vec2(0.5f, 11.0f))
assertFalse(info.cutOff)
info.assert(
lineIndex = 0,
lines = listOf(TextLineInfo(BaseComponent(TextComponent("b")), 0.5f)),
size = Vec2(0.5f, 11.0f),
)
}
fun `2 chars`() {
val info = render(TextComponent("bc"))
assertEquals(info.lineIndex, 0)
assertEquals(info.lines, listOf(TextLineInfo(BaseComponent(TextComponent("bc")), 2.5f)))
assertEquals(info.size, Vec2(2.5f, 11.0f)) // b + spacing + c
assertFalse(info.cutOff)
info.assert(
lineIndex = 0,
lines = listOf(TextLineInfo(BaseComponent(TextComponent("bc")), 2.5f)),
size = Vec2(2.5f, 11.0f), // b + spacing + c
)
}
fun `3 chars`() {
val info = render(TextComponent("bcd"))
assertEquals(info.lineIndex, 0)
assertEquals(info.lines, listOf(TextLineInfo(BaseComponent(TextComponent("bcd")), 5.0f)))
assertEquals(info.size, Vec2(5.0f, 11.0f)) // b + spacing + c + spacing + d
assertFalse(info.cutOff)
info.assert(
lineIndex = 0,
lines = listOf(TextLineInfo(BaseComponent(TextComponent("bcd")), 5.0f)),
size = Vec2(5.0f, 11.0f),
)
}
fun `max line size`() {
fun `max line size 1`() {
val info = render(TextComponent("bcdef"), maxSize = Vec2(5.5f, Float.MAX_VALUE))
assertEquals(info.lineIndex, 1)
assertEquals(info.lines, listOf(TextLineInfo(BaseComponent(TextComponent("bcd")), 5.0f), TextLineInfo(BaseComponent(TextComponent("ef")), 5.5f)))
assertEquals(info.size, Vec2(5.5f, 22.0f)) // b + spacing + c + spacing + d \n e + spacing + f
assertFalse(info.cutOff)
info.assert(
lineIndex = 1,
lines = listOf(
TextLineInfo(BaseComponent(TextComponent("bcd")), 5.0f),
TextLineInfo(BaseComponent(TextComponent("ef")), 5.5f),
),
size = Vec2(5.5f, 22.0f),
)
}
fun `max line size 2`() {
val info = render(TextComponent("bcdefg"), maxSize = Vec2(5.5f, Float.MAX_VALUE))
info.assert(
lineIndex = 2,
lines = listOf(
TextLineInfo(BaseComponent(TextComponent("bcd")), 5.0f),
TextLineInfo(BaseComponent(TextComponent("ef")), 5.5f),
TextLineInfo(BaseComponent(TextComponent("g")), 3.0f),
),
size = Vec2(5.5f, 33.0f),
)
}
fun `single line with spacing`() {
val info = render(TextComponent("bcd"), maxSize = Vec2(5.5f, Float.MAX_VALUE), properties = TextRenderProperties(lineSpacing = 100.0f, shadow = false))
info.assert(
lineIndex = 0,
lines = listOf(
TextLineInfo(BaseComponent(TextComponent("bcd")), 5.0f),
),
size = Vec2(5.0f, 11.0f),
)
}
fun `line spacing 1`() {
val info = render(TextComponent("bcdef"), maxSize = Vec2(5.5f, Float.MAX_VALUE), properties = TextRenderProperties(lineSpacing = 1.0f, shadow = false))
info.assert(
lineIndex = 1,
lines = listOf(
TextLineInfo(BaseComponent(TextComponent("bcd")), 5.0f),
TextLineInfo(BaseComponent(TextComponent("ef")), 5.5f),
),
size = Vec2(5.5f, 23.0f),
)
}
fun `line spacing 2`() {
val info = render(TextComponent("bcdefg"), maxSize = Vec2(5.5f, Float.MAX_VALUE), properties = TextRenderProperties(lineSpacing = 1.0f, shadow = false))
info.assert(
lineIndex = 2,
lines = listOf(
TextLineInfo(BaseComponent(TextComponent("bcd")), 5.0f),
TextLineInfo(BaseComponent(TextComponent("ef")), 5.5f),
TextLineInfo(BaseComponent(TextComponent("g")), 3.0f),
),
size = Vec2(5.5f, 35.0f),
)
}
fun `line spacing 3`() {
val info = render(TextComponent("bcdefg"), maxSize = Vec2(5.5f, Float.MAX_VALUE), properties = TextRenderProperties(lineSpacing = 20.0f, shadow = false))
info.assert(
lineIndex = 2,
lines = listOf(
TextLineInfo(BaseComponent(TextComponent("bcd")), 5.0f),
TextLineInfo(BaseComponent(TextComponent("ef")), 5.5f),
TextLineInfo(BaseComponent(TextComponent("g")), 3.0f),
),
size = Vec2(5.5f, 73.0f),
)
}
fun `empty new line`() {
val info = render(TextComponent("\n"))
info.assert(
lineIndex = 1,
lines = listOf(
TextLineInfo(BaseComponent(TextComponent("")), 0.0f),
),
size = Vec2(0.0f, 11.0f),
)
}
fun `basic new line 1`() {
val info = render(TextComponent("b\nb"))
info.assert(
lineIndex = 1,
lines = listOf(
TextLineInfo(BaseComponent(TextComponent("b")), 0.5f),
TextLineInfo(BaseComponent(TextComponent("b")), 0.5f),
),
size = Vec2(0.5f, 22.0f),
)
}
fun `basic new line 2`() {
val info = render(TextComponent("bcd\n\nefgh"))
info.assert(
lineIndex = 1,
lines = listOf(
TextLineInfo(BaseComponent(TextComponent("bcd")), 5.0f),
TextLineInfo(BaseComponent(TextComponent("")), 0.0f),
TextLineInfo(BaseComponent(TextComponent("efgh")), 14.0f),
),
size = Vec2(14f, 33.0f),
)
}
// TODO: shadow, cutoff, underline, strikethrough, using with consumer, formatting (just basic, that is code point renderer's job)
}

View File

@ -19,6 +19,8 @@ import de.bixilon.minosoft.gui.rendering.font.types.FontType
object DummyFontType : FontType {
private val chars: Array<DummyCodePointRenderer?> = arrayOfNulls(26) // a-z
// a:0 b:0.5 c:1.0 d:1.5 e:2.0 f:2.5 g:3.0 h:3.5
init {
build()
}

View File

@ -44,15 +44,12 @@ class TextOffset(
fun getNextLineHeight(properties: TextRenderProperties): Float {
var height = properties.lineHeight
if (offset.y != initial.y) {
// previous line present
height += properties.lineSpacing * properties.scale
}
height += properties.lineSpacing * properties.scale
return height
}
fun addLine(properties: TextRenderProperties, info: TextRenderInfo, height: Float): Boolean {
fun addLine(info: TextRenderInfo, height: Float): Boolean {
if (!fitsY(info, height)) return false
offset.y += height
@ -66,7 +63,7 @@ class TextOffset(
fun canAdd(properties: TextRenderProperties, info: TextRenderInfo, width: Float, height: Float): CodePointAddResult {
if (fitsInLine(properties, info, width)) return CodePointAddResult.FINE
if (addLine(properties, info, height) && fitsInLine(properties, info, width)) return CodePointAddResult.NEW_LINE
if (addLine(info, height) && fitsInLine(properties, info, width)) return CodePointAddResult.NEW_LINE
info.cutOff = true
return CodePointAddResult.BREAK