improve empty code point rendering

Reported-By: turtius
This commit is contained in:
Moritz Zwerger 2023-07-29 22:13:24 +02:00
parent 442964619d
commit b7ef4b95c6
No known key found for this signature in database
GPG Key ID: 5CAD791931B09AC4
4 changed files with 48 additions and 6 deletions

View File

@ -65,7 +65,12 @@ class ChatComponentRendererTest {
fun emptyChar() { fun emptyChar() {
val info = render(TextComponent("a")) // a has a length of 0px val info = render(TextComponent("a")) // a has a length of 0px
info.assert(lineIndex = 0, lines = emptyList(), size = Vec2()) info.assert(lineIndex = 0, lines = listOf(LineRenderInfo(BaseComponent())), size = Vec2())
}
fun `empty char and then char`() {
val info = render(TextComponent("ab")) // a has a length of 0px
info.assert(lineIndex = 0, lines = listOf(LineRenderInfo(BaseComponent("b"), width = 0.5f)), size = Vec2(0.5f, 11f))
} }
fun singleChar() { fun singleChar() {
@ -475,5 +480,32 @@ class ChatComponentRendererTest {
)) ))
} }
fun `render empty chars and newline`() {
val consumer = DummyComponentConsumer()
val text = TextComponent("aaaa\naaaa")
val info = render(text, fontManager = FontManager(consumer.Font()), consumer = consumer)
info.assert(lineIndex = 1, size = Vec2(0.0f, 11.0f), lines = listOf(
LineRenderInfo(BaseComponent(), 0.0f),
LineRenderInfo(BaseComponent(), 0.0f),
))
consumer.assert(*arrayOf<DummyComponentConsumer.RendererdCodePoint>())
}
fun `render empty chars mixed and newline`() {
val text = TextComponent("abaaa\naaaba")
val consumer = DummyComponentConsumer()
val info = render(text, fontManager = FontManager(consumer.Font()), consumer = consumer)
info.assert(lineIndex = 1, size = Vec2(0.5f, 22.0f), lines = listOf(
LineRenderInfo(BaseComponent("b"), 0.5f),
LineRenderInfo(BaseComponent("b"), 0.5f),
))
consumer.assert(
DummyComponentConsumer.RendererdCodePoint(Vec2(10, 10)),
DummyComponentConsumer.RendererdCodePoint(Vec2(10, 21)),
)
}
// TODO: shadow, formatting (italic; strikethrough; underlined) // TODO: shadow, formatting (italic; strikethrough; underlined)
} }

View File

@ -71,7 +71,7 @@ interface CodePointRenderer {
if (consumer != null) { if (consumer != null) {
render(offset.offset, properties, color, properties.shadow, FormattingCodes.BOLD in formatting, FormattingCodes.ITALIC in formatting, properties.scale, consumer, options) render(offset.offset, properties, color, properties.shadow, FormattingCodes.BOLD in formatting, FormattingCodes.ITALIC in formatting, properties.scale, consumer, options)
} else { } else {
info.update(offset, properties, width, spacing) // info should only be updated when we determinate text properties, we know all that already when actually rendering it } info.update(offset, properties, width, spacing, false) // info should only be updated when we determinate text properties, we know all that already when actually rendering it }
} }
offset.offset.x += width offset.offset.x += width

View File

@ -80,8 +80,9 @@ object TextComponentRenderer : ChatComponentRenderer<TextComponent> {
private fun LineRenderInfo.pushAndRender(offset: Vec2, text: TextComponent, line: StringBuilder, width: Float, color: RGBColor, properties: TextRenderProperties, consumer: GUIVertexConsumer?, options: GUIVertexOptions?) { private fun LineRenderInfo.pushAndRender(offset: Vec2, text: TextComponent, line: StringBuilder, width: Float, color: RGBColor, properties: TextRenderProperties, consumer: GUIVertexConsumer?, options: GUIVertexOptions?) {
push(text, line) if (consumer == null) {
if (consumer != null) { push(text, line)
} else {
renderFormatting(offset, text, width, color, properties, consumer, options) renderFormatting(offset, text, width, color, properties, consumer, options)
} }
} }
@ -102,6 +103,7 @@ object TextComponentRenderer : ChatComponentRenderer<TextComponent> {
var skipWhitespaces = false var skipWhitespaces = false
val line = StringBuilder() val line = StringBuilder()
var update = false
var filled = false var filled = false
val lineStart = Vec2(offset.offset) val lineStart = Vec2(offset.offset)
@ -119,6 +121,7 @@ object TextComponentRenderer : ChatComponentRenderer<TextComponent> {
} }
lineStart(offset.offset) lineStart(offset.offset)
skipWhitespaces = true skipWhitespaces = true
update = false
if (filled) break else continue if (filled) break else continue
} }
if (skipWhitespaces && Character.isWhitespace(codePoint)) { if (skipWhitespaces && Character.isWhitespace(codePoint)) {
@ -127,12 +130,14 @@ object TextComponentRenderer : ChatComponentRenderer<TextComponent> {
val renderer = getRenderer(codePoint, properties, textFont, fontManager) val renderer = getRenderer(codePoint, properties, textFont, fontManager)
if (renderer != null && renderer.calculateWidth(properties.scale, properties.shadow) <= 0.0f) { if (renderer != null && renderer.calculateWidth(properties.scale, properties.shadow) <= 0.0f) {
update = true
continue continue
} }
skipWhitespaces = false skipWhitespaces = false
if (renderer == null) { if (renderer == null) {
continue continue
} }
update = false
val lineIndex = info.lineIndex val lineIndex = info.lineIndex
@ -159,6 +164,9 @@ object TextComponentRenderer : ChatComponentRenderer<TextComponent> {
line.appendCodePoint(codePoint) line.appendCodePoint(codePoint)
} }
if (update && consumer == null) {
info.update(offset, properties, 0.0f, 0.0f, true)
}
if (line.isNotEmpty()) { if (line.isNotEmpty()) {
info.lines[info.lineIndex].pushAndRender(lineStart, text, line, offset.offset.x - lineStart.x, color, properties, consumer, options) info.lines[info.lineIndex].pushAndRender(lineStart, text, line, offset.offset.x - lineStart.x, color, properties, consumer, options)
} }

View File

@ -26,7 +26,7 @@ class TextRenderInfo(
var cutOff = false var cutOff = false
fun update(offset: TextOffset, properties: TextRenderProperties, width: Float, spacing: Float): LineRenderInfo { fun update(offset: TextOffset, properties: TextRenderProperties, width: Float, spacing: Float, empty: Boolean): LineRenderInfo {
size.x = maxOf(offset.offset.x - offset.initial.x + width, size.x) size.x = maxOf(offset.offset.x - offset.initial.x + width, size.x)
val line: LineRenderInfo val line: LineRenderInfo
@ -34,7 +34,9 @@ class TextRenderInfo(
// first char of all lines // first char of all lines
line = LineRenderInfo() line = LineRenderInfo()
lines += line lines += line
size.y += properties.lineHeight if (!empty) {
size.y += properties.lineHeight
}
} else { } else {
line = lines[lineIndex] line = lines[lineIndex]
} }