From aa68958a772bebffe426255d3118d22565c9369c Mon Sep 17 00:00:00 2001 From: DaniTheSkunk <> Date: Tue, 13 Dec 2022 04:01:33 +0000 Subject: [PATCH] added max width wrapping in NodeText --- com/danitheskunk/skunkworks/TestNode.java | 9 +++- .../skunkworks/gfx/font/BaseFont.java | 17 ++++++++ .../skunkworks/gfx/font/FontTileset.java | 2 +- .../skunkworks/gfx/font/IFont.java | 2 + .../skunkworks/nodes/NodeText.java | 42 ++++++++++++++++++- 5 files changed, 68 insertions(+), 4 deletions(-) create mode 100644 com/danitheskunk/skunkworks/gfx/font/BaseFont.java diff --git a/com/danitheskunk/skunkworks/TestNode.java b/com/danitheskunk/skunkworks/TestNode.java index dcf3006..2e728c2 100644 --- a/com/danitheskunk/skunkworks/TestNode.java +++ b/com/danitheskunk/skunkworks/TestNode.java @@ -10,6 +10,7 @@ public class TestNode extends BaseGame { private final ISample kick; private final NodeSprite sprite; private final NodeText text; + private final NodeText text2; float[] axes; public TestNode() { @@ -17,12 +18,17 @@ public class TestNode extends BaseGame { kick = loadSample("demoassets/kick.wav"); var font = window.loadFontTileset("fonts/ega-8x14.png"); - text = new NodeText(font, "Hello World!"); + var font2 = window.loadFontTTF("fonts/LiberationSans-Regular.ttf", 24.0f); + text = new NodeText(font, "Hello World! this is an extra long test meow meow nya nya! nyaaa!"); + text2 = new NodeText(font2, "Hello World! this is an extra long test meow meow nya nya! nyaaa!"); + text.setMaxSize(new Vec2i(100, 100)); + text2.setMaxSize(new Vec2i(100, 100)); sprite = new NodeSprite(); sprite.setTexture(loadTexture("demoassets/card.png")); sprite.setPos(new Vec2f(100, 100)); //rootNode.add(sprite); rootNode.add(text); + rootNode.add(text2); //doThing(); } @@ -38,6 +44,7 @@ public class TestNode extends BaseGame { @Override protected void update(double delta) { text.setPos(new Vec2f(640 + 640 * gamepad.getAxis(0), 360 + 360 * gamepad.getAxis(1))); + text2.setPos(new Vec2f(440 + 640 * gamepad.getAxis(0), 360 + 360 * gamepad.getAxis(1))); if(gamepad.getButtonPressed(0)) { playSample(kick); } diff --git a/com/danitheskunk/skunkworks/gfx/font/BaseFont.java b/com/danitheskunk/skunkworks/gfx/font/BaseFont.java new file mode 100644 index 0000000..82b6b65 --- /dev/null +++ b/com/danitheskunk/skunkworks/gfx/font/BaseFont.java @@ -0,0 +1,17 @@ +package com.danitheskunk.skunkworks.gfx.font; + +import java.nio.charset.Charset; +import java.nio.charset.StandardCharsets; + +public abstract class BaseFont implements IFont { + @Override + public int getStringWidth(String str) { + //todo: figure out later + Charset charset = isCP437() ? StandardCharsets.ISO_8859_1 : StandardCharsets.UTF_8; + int width = 0; + for(var ch : str.getBytes(charset)) { + width += getXAdvance(ch); + } + return width; + } +} diff --git a/com/danitheskunk/skunkworks/gfx/font/FontTileset.java b/com/danitheskunk/skunkworks/gfx/font/FontTileset.java index a2c2ee6..5535548 100644 --- a/com/danitheskunk/skunkworks/gfx/font/FontTileset.java +++ b/com/danitheskunk/skunkworks/gfx/font/FontTileset.java @@ -5,7 +5,7 @@ import com.danitheskunk.skunkworks.gfx.ITexture; import java.util.List; -public class FontTileset implements IFont { +public class FontTileset extends BaseFont { private final Vec2i charSize; private final List textures; diff --git a/com/danitheskunk/skunkworks/gfx/font/IFont.java b/com/danitheskunk/skunkworks/gfx/font/IFont.java index f1eb898..2ef7cd5 100644 --- a/com/danitheskunk/skunkworks/gfx/font/IFont.java +++ b/com/danitheskunk/skunkworks/gfx/font/IFont.java @@ -6,6 +6,8 @@ import com.danitheskunk.skunkworks.gfx.ITexture; public interface IFont { int getLineHeight(); + int getStringWidth(String str); + Vec2i getMonospaceSize(); Vec2i getOffset(int ch); diff --git a/com/danitheskunk/skunkworks/nodes/NodeText.java b/com/danitheskunk/skunkworks/nodes/NodeText.java index 832d457..0470749 100644 --- a/com/danitheskunk/skunkworks/nodes/NodeText.java +++ b/com/danitheskunk/skunkworks/nodes/NodeText.java @@ -1,27 +1,65 @@ package com.danitheskunk.skunkworks.nodes; +import com.danitheskunk.skunkworks.Vec2i; import com.danitheskunk.skunkworks.gfx.IRenderContext; import com.danitheskunk.skunkworks.gfx.font.IFont; +import java.util.ArrayList; +import java.util.List; + public class NodeText extends Node { private IFont font; + private List lines; + private Vec2i maxSize; private String text; public NodeText(IFont font, String text) { this.font = font; - this.text = text; + maxSize = Vec2i.ZERO; + lines = new ArrayList<>(); + setText(text); + } + + private void layoutText() { + lines.clear(); + if(maxSize == Vec2i.ZERO) { + lines.add(text); + return; + } + var words = text.split(" "); + String currentLine = words[0]; + for(int i = 1; i < words.length; ++i) { + String newLine = currentLine + " " + words[i]; + if(font.getStringWidth(newLine) > maxSize.getX()) { + lines.add(currentLine); + currentLine = words[i]; + } else { + currentLine = newLine; + } + } + lines.add(currentLine); } @Override public void render(IRenderContext rc) { - rc.drawString(getAbsolutePos().toVec2i(), text, font); + Vec2i pos = getAbsolutePos().toVec2i(); + for(var line : lines) { + rc.drawString(pos, line, font); + pos = Vec2i.add(pos, new Vec2i(0, font.getLineHeight())); + } } public void setFont(IFont font) { this.font = font; } + public void setMaxSize(Vec2i maxSize) { + this.maxSize = maxSize; + layoutText(); + } + public void setText(String text) { this.text = text; + layoutText(); } }