From e70efd2c20a3fb37828364d342586b50f30eb7b1 Mon Sep 17 00:00:00 2001 From: Bixilon Date: Wed, 4 Aug 2021 22:18:11 +0200 Subject: [PATCH] text wrapping --- .../font/renderer/BaseComponentRenderer.kt | 5 +- .../font/renderer/ChatComponentRenderer.kt | 8 +-- .../font/renderer/TextComponentRenderer.kt | 63 +++++++++++++++++-- .../gui/rendering/gui/elements/Element.kt | 4 +- .../gui/elements/text/TextElement.kt | 2 +- .../gui/rendering/gui/hud/HUDRenderer.kt | 20 ++++++ 6 files changed, 87 insertions(+), 15 deletions(-) diff --git a/src/main/java/de/bixilon/minosoft/gui/rendering/font/renderer/BaseComponentRenderer.kt b/src/main/java/de/bixilon/minosoft/gui/rendering/font/renderer/BaseComponentRenderer.kt index 1005c8a8e..fe7c7427c 100644 --- a/src/main/java/de/bixilon/minosoft/gui/rendering/font/renderer/BaseComponentRenderer.kt +++ b/src/main/java/de/bixilon/minosoft/gui/rendering/font/renderer/BaseComponentRenderer.kt @@ -20,9 +20,10 @@ import de.bixilon.minosoft.gui.rendering.gui.mesh.GUIVertexConsumer import glm_.vec2.Vec2i object BaseComponentRenderer : ChatComponentRenderer { - override fun render(offset: Vec2i, z: Int, element: LabeledElement, renderWindow: RenderWindow, consumer: GUIVertexConsumer, text: BaseComponent) { + + override fun render(initialOffset: Vec2i, offset: Vec2i, size: Vec2i, z: Int, element: LabeledElement, renderWindow: RenderWindow, consumer: GUIVertexConsumer, text: BaseComponent) { for (part in text.parts) { - ChatComponentRenderer.render(offset, z, element, renderWindow, consumer, part) + ChatComponentRenderer.render(initialOffset, offset, size, z, element, renderWindow, consumer, part) } } } diff --git a/src/main/java/de/bixilon/minosoft/gui/rendering/font/renderer/ChatComponentRenderer.kt b/src/main/java/de/bixilon/minosoft/gui/rendering/font/renderer/ChatComponentRenderer.kt index 28568bee2..d4e8e2b1d 100644 --- a/src/main/java/de/bixilon/minosoft/gui/rendering/font/renderer/ChatComponentRenderer.kt +++ b/src/main/java/de/bixilon/minosoft/gui/rendering/font/renderer/ChatComponentRenderer.kt @@ -23,15 +23,15 @@ import glm_.vec2.Vec2i interface ChatComponentRenderer { - fun render(offset: Vec2i, z: Int, element: LabeledElement, renderWindow: RenderWindow, consumer: GUIVertexConsumer, text: T) + fun render(initialOffset: Vec2i, offset: Vec2i, size: Vec2i, z: Int, element: LabeledElement, renderWindow: RenderWindow, consumer: GUIVertexConsumer, text: T) companion object : ChatComponentRenderer { - override fun render(offset: Vec2i, z: Int, element: LabeledElement, renderWindow: RenderWindow, consumer: GUIVertexConsumer, text: ChatComponent) { + override fun render(initialOffset: Vec2i, offset: Vec2i, size: Vec2i, z: Int, element: LabeledElement, renderWindow: RenderWindow, consumer: GUIVertexConsumer, text: ChatComponent) { when (text) { - is BaseComponent -> BaseComponentRenderer.render(offset, z, element, renderWindow, consumer, text) - is TextComponent -> TextComponentRenderer.render(offset, z, element, renderWindow, consumer, text) + is BaseComponent -> BaseComponentRenderer.render(initialOffset, offset, size, z, element, renderWindow, consumer, text) + is TextComponent -> TextComponentRenderer.render(initialOffset, offset, size, z, element, renderWindow, consumer, text) else -> TODO("Don't know how to render ${text::class.java}") } } diff --git a/src/main/java/de/bixilon/minosoft/gui/rendering/font/renderer/TextComponentRenderer.kt b/src/main/java/de/bixilon/minosoft/gui/rendering/font/renderer/TextComponentRenderer.kt index cbfb8943e..82f7298e2 100644 --- a/src/main/java/de/bixilon/minosoft/gui/rendering/font/renderer/TextComponentRenderer.kt +++ b/src/main/java/de/bixilon/minosoft/gui/rendering/font/renderer/TextComponentRenderer.kt @@ -25,11 +25,53 @@ import glm_.vec2.Vec2i object TextComponentRenderer : ChatComponentRenderer { - override fun render(offset: Vec2i, z: Int, element: LabeledElement, renderWindow: RenderWindow, consumer: GUIVertexConsumer, text: TextComponent) { + override fun render(initialOffset: Vec2i, offset: Vec2i, size: Vec2i, z: Int, element: LabeledElement, renderWindow: RenderWindow, consumer: GUIVertexConsumer, text: TextComponent) { var first = true + + /** + * @return If the text can't fit into the layout anymore + */ + fun wrap(): Boolean { + val yAdd = Font.CHAR_HEIGHT + Font.VERTICAL_SPACING + if (size.y + yAdd > element.maxSize.y) { + return true + } + offset.x = initialOffset.x + offset.y += yAdd + size.y += yAdd + + return false + } + + /** + * @return If the text can't fit into the layout anymore + */ + fun add(x: Int): Boolean { + if (offset.x - initialOffset.x + x > element.maxSize.x) { + if (wrap()) { + return true + } + } else { + offset.x += x + } + + if (size.x < offset.x - initialOffset.x) { + size.x += x + } + + return false + } + for (char in text.message.toCharArray()) { if (char == '\n') { - offset.y += Font.CHAR_HEIGHT + Font.VERTICAL_SPACING + if (wrap()) { + return + } + continue + } + + // skip wrapped spaces + if (offset.y != initialOffset.y && offset.x == initialOffset.x && char == ' ') { continue } @@ -37,17 +79,26 @@ object TextComponentRenderer : ChatComponentRenderer { if (first) { first = false - } else { - offset.x += Font.HORIZONTAL_SPACING + } else if (offset.x != initialOffset.x && add(Font.HORIZONTAL_SPACING)) { + return } + val width = charData.calculateWidth(text) + + if (offset.x == initialOffset.x && offset.x - initialOffset.x + width > element.maxSize.x) { + return + } charData.render(offset, z, text, consumer) - offset.x += charData.calculateWidth(text) + if (add(width)) { + return + } } if (text.formatting.contains(PreChatFormattingCodes.ITALIC)) { - offset.x += CharData.ITALIC_OFFSET.ceil + val italicOffset = CharData.ITALIC_OFFSET.ceil + offset.x += italicOffset + size.x += italicOffset } } } diff --git a/src/main/java/de/bixilon/minosoft/gui/rendering/gui/elements/Element.kt b/src/main/java/de/bixilon/minosoft/gui/rendering/gui/elements/Element.kt index f9f1f4821..622495de4 100644 --- a/src/main/java/de/bixilon/minosoft/gui/rendering/gui/elements/Element.kt +++ b/src/main/java/de/bixilon/minosoft/gui/rendering/gui/elements/Element.kt @@ -19,8 +19,8 @@ import glm_.vec2.Vec2i abstract class Element { open var prepared: Boolean = false - open var minSize: Vec2i = Vec2i() - open var maxSize: Vec2i = Vec2i() + open var minSize: Vec2i = Vec2i(10, 10) + open var maxSize: Vec2i = Vec2i(50, 50) open var size: Vec2i = Vec2i() diff --git a/src/main/java/de/bixilon/minosoft/gui/rendering/gui/elements/text/TextElement.kt b/src/main/java/de/bixilon/minosoft/gui/rendering/gui/elements/text/TextElement.kt index a95c06b2e..f98ca9278 100644 --- a/src/main/java/de/bixilon/minosoft/gui/rendering/gui/elements/text/TextElement.kt +++ b/src/main/java/de/bixilon/minosoft/gui/rendering/gui/elements/text/TextElement.kt @@ -38,7 +38,7 @@ class TextElement( override fun render(offset: Vec2i, z: Int, consumer: GUIVertexConsumer): Int { - ChatComponentRenderer.render(offset, z, this, renderWindow, consumer, textComponent) + ChatComponentRenderer.render(Vec2i(offset), offset, Vec2i(0, 0), z, this, renderWindow, consumer, textComponent) return LAYERS } diff --git a/src/main/java/de/bixilon/minosoft/gui/rendering/gui/hud/HUDRenderer.kt b/src/main/java/de/bixilon/minosoft/gui/rendering/gui/hud/HUDRenderer.kt index f4a8c01d7..f6a12d562 100644 --- a/src/main/java/de/bixilon/minosoft/gui/rendering/gui/hud/HUDRenderer.kt +++ b/src/main/java/de/bixilon/minosoft/gui/rendering/gui/hud/HUDRenderer.kt @@ -80,6 +80,26 @@ class HUDRenderer( text.render(Vec2i(10, 10), 0, mesh) } + + val text2 = TextElement( + renderWindow = renderWindow, + text = TextComponent( + message = "Moritz\nist toll!!!", + color = ChatColors.BLUE, + formatting = mutableSetOf( + PreChatFormattingCodes.BOLD, + PreChatFormattingCodes.SHADOWED, + PreChatFormattingCodes.UNDERLINED, + PreChatFormattingCodes.ITALIC, + PreChatFormattingCodes.STRIKETHROUGH, + PreChatFormattingCodes.OBFUSCATED + ), + ), + ) + if (!text2.prepared) { + text2.render(Vec2i(10, 60), 0, mesh) + } + mesh.load()