newline rendering

This commit is contained in:
Bixilon 2023-06-13 21:25:30 +02:00
parent 1e72bae1e1
commit 8ce641cacf
No known key found for this signature in database
GPG Key ID: 5CAD791931B09AC4
4 changed files with 36 additions and 16 deletions

View File

@ -154,7 +154,7 @@ class ChatComponentRendererTest {
info.assert( info.assert(
lineIndex = 1, lineIndex = 1,
lines = listOf( lines = listOf(
TextLineInfo(BaseComponent(TextComponent("")), 0.0f), TextLineInfo(BaseComponent(), 0.0f),
), ),
size = Vec2(0.0f, 11.0f), size = Vec2(0.0f, 11.0f),
) )
@ -175,10 +175,10 @@ class ChatComponentRendererTest {
fun `basic new line 2`() { fun `basic new line 2`() {
val info = render(TextComponent("bcd\n\nefgh")) val info = render(TextComponent("bcd\n\nefgh"))
info.assert( info.assert(
lineIndex = 1, lineIndex = 2,
lines = listOf( lines = listOf(
TextLineInfo(BaseComponent(TextComponent("bcd")), 5.0f), TextLineInfo(BaseComponent(TextComponent("bcd")), 5.0f),
TextLineInfo(BaseComponent(TextComponent("")), 0.0f), TextLineInfo(BaseComponent(), 0.0f),
TextLineInfo(BaseComponent(TextComponent("efgh")), 14.0f), TextLineInfo(BaseComponent(TextComponent("efgh")), 14.0f),
), ),
size = Vec2(14f, 33.0f), size = Vec2(14f, 33.0f),

View File

@ -26,10 +26,12 @@ import de.bixilon.minosoft.gui.rendering.gui.mesh.GUIVertexOptions
object BaseComponentRenderer : ChatComponentRenderer<BaseComponent> { object BaseComponentRenderer : ChatComponentRenderer<BaseComponent> {
override fun render(offset: TextOffset, fontManager: FontManager, properties: TextRenderProperties, info: TextRenderInfo, consumer: GUIVertexConsumer?, options: GUIVertexOptions?, text: BaseComponent) { override fun render(offset: TextOffset, fontManager: FontManager, properties: TextRenderProperties, info: TextRenderInfo, consumer: GUIVertexConsumer?, options: GUIVertexOptions?, text: BaseComponent): Boolean {
for (part in text.parts) { for (part in text.parts) {
ChatComponentRenderer.render(offset, fontManager, properties, info, consumer, options, part) val filled = ChatComponentRenderer.render(offset, fontManager, properties, info, consumer, options, part)
if (filled) return true
} }
return false
} }
override fun render3dFlat(context: RenderContext, offset: Vec2i, scale: Float, maxSize: Vec2i, consumer: WorldGUIConsumer, text: BaseComponent, light: Int) { override fun render3dFlat(context: RenderContext, offset: Vec2i, scale: Float, maxSize: Vec2i, consumer: WorldGUIConsumer, text: BaseComponent, light: Int) {

View File

@ -37,7 +37,7 @@ interface ChatComponentRenderer<T : ChatComponent> {
/** /**
* Returns true if the text exceeded the maximum size * Returns true if the text exceeded the maximum size
*/ */
fun render(offset: TextOffset, fontManager: FontManager, properties: TextRenderProperties, info: TextRenderInfo, consumer: GUIVertexConsumer?, options: GUIVertexOptions?, text: T) fun render(offset: TextOffset, fontManager: FontManager, properties: TextRenderProperties, info: TextRenderInfo, consumer: GUIVertexConsumer?, options: GUIVertexOptions?, text: T): Boolean
fun render3dFlat(context: RenderContext, offset: Vec2i, scale: Float, maxSize: Vec2i, consumer: WorldGUIConsumer, text: T, light: Int) fun render3dFlat(context: RenderContext, offset: Vec2i, scale: Float, maxSize: Vec2i, consumer: WorldGUIConsumer, text: T, light: Int)
@ -46,11 +46,11 @@ interface ChatComponentRenderer<T : ChatComponent> {
companion object : ChatComponentRenderer<ChatComponent> { companion object : ChatComponentRenderer<ChatComponent> {
const val TEXT_BLOCK_RESOLUTION = 128 const val TEXT_BLOCK_RESOLUTION = 128
override fun render(offset: TextOffset, fontManager: FontManager, properties: TextRenderProperties, info: TextRenderInfo, consumer: GUIVertexConsumer?, options: GUIVertexOptions?, text: ChatComponent) { override fun render(offset: TextOffset, fontManager: FontManager, properties: TextRenderProperties, info: TextRenderInfo, consumer: GUIVertexConsumer?, options: GUIVertexOptions?, text: ChatComponent): Boolean {
when (text) { return when (text) {
is BaseComponent -> BaseComponentRenderer.render(offset, fontManager, properties, info, consumer, options, text) is BaseComponent -> BaseComponentRenderer.render(offset, fontManager, properties, info, consumer, options, text)
is TextComponent -> TextComponentRenderer.render(offset, fontManager, properties, info, consumer, options, text) is TextComponent -> TextComponentRenderer.render(offset, fontManager, properties, info, consumer, options, text)
is EmptyComponent -> return is EmptyComponent -> return false
else -> TODO("Don't know how to render ${text::class.java}") else -> TODO("Don't know how to render ${text::class.java}")
} }
} }

View File

@ -41,8 +41,19 @@ object TextComponentRenderer : ChatComponentRenderer<TextComponent> {
return properties.forcedColor ?: text.color ?: properties.fallbackColor return properties.forcedColor ?: text.color ?: properties.fallbackColor
} }
private fun renderNewline(offset: TextOffset, info: TextRenderInfo) { private fun renderNewline(properties: TextRenderProperties, offset: TextOffset, info: TextRenderInfo, updateSize: Boolean): Boolean {
TODO() val height = offset.getNextLineHeight(properties)
if (!offset.addLine(info, height)) {
info.cutOff = true
return true
}
if (updateSize) {
info.size.y += height
}
return false
} }
private fun renderStrikethrough() { private fun renderStrikethrough() {
@ -53,8 +64,8 @@ object TextComponentRenderer : ChatComponentRenderer<TextComponent> {
TODO() TODO()
} }
override fun render(offset: TextOffset, fontManager: FontManager, properties: TextRenderProperties, info: TextRenderInfo, consumer: GUIVertexConsumer?, options: GUIVertexOptions?, text: TextComponent) { override fun render(offset: TextOffset, fontManager: FontManager, properties: TextRenderProperties, info: TextRenderInfo, consumer: GUIVertexConsumer?, options: GUIVertexOptions?, text: TextComponent): Boolean {
if (text.message.isEmpty()) return if (text.message.isEmpty()) return false
val textFont = fontManager[text.font] val textFont = fontManager[text.font]
val color = getColor(properties, text) val color = getColor(properties, text)
@ -62,12 +73,14 @@ object TextComponentRenderer : ChatComponentRenderer<TextComponent> {
var skipWhitespaces = false var skipWhitespaces = false
val line = StringBuilder() val line = StringBuilder()
var filled = false
for (codePoint in text.message.codePoints()) { for (codePoint in text.message.codePoints()) {
if (codePoint == '\n'.code) { if (codePoint == '\n'.code) {
renderNewline(offset, info) filled = renderNewline(properties, offset, info, consumer == null)
info.lines[info.lineIndex - 1].push(text, line)
skipWhitespaces = true skipWhitespaces = true
continue if (filled) break else continue
} }
if (skipWhitespaces && Character.isWhitespace(codePoint)) { if (skipWhitespaces && Character.isWhitespace(codePoint)) {
continue continue
@ -86,7 +99,10 @@ object TextComponentRenderer : ChatComponentRenderer<TextComponent> {
val lineInfo = renderer.render(offset, color, properties, info, formatting, codePoint, consumer, options) val lineInfo = renderer.render(offset, color, properties, info, formatting, codePoint, consumer, options)
if (consumer != null) continue // already know that information if (consumer != null) continue // already know that information
if (lineInfo == CodePointAddResult.BREAK) break if (lineInfo == CodePointAddResult.BREAK) {
filled = true
break
}
if (lineIndex != info.lineIndex) { if (lineIndex != info.lineIndex) {
// new line started // new line started
@ -98,6 +114,8 @@ object TextComponentRenderer : ChatComponentRenderer<TextComponent> {
if (line.isNotEmpty()) { if (line.isNotEmpty()) {
info.lines[info.lineIndex].push(text, line) info.lines[info.lineIndex].push(text, line)
} }
return filled
} }
override fun calculatePrimitiveCount(text: TextComponent): Int { override fun calculatePrimitiveCount(text: TextComponent): Int {