From 0ca388141cb322e709e7f5bb872a2001f3ff5491 Mon Sep 17 00:00:00 2001 From: Snownee Date: Mon, 15 Mar 2021 13:00:55 +0800 Subject: [PATCH] Better line breaking --- .../create/foundation/item/TooltipHelper.java | 25 +----- .../create/foundation/ponder/PonderUI.java | 3 +- .../ponder/content/PonderTagScreen.java | 3 +- .../ponder/elements/TextWindowElement.java | 5 +- .../create/foundation/utility/FontHelper.java | 85 +++++++++++++++++++ 5 files changed, 94 insertions(+), 27 deletions(-) create mode 100644 src/main/java/com/simibubi/create/foundation/utility/FontHelper.java diff --git a/src/main/java/com/simibubi/create/foundation/item/TooltipHelper.java b/src/main/java/com/simibubi/create/foundation/item/TooltipHelper.java index 94d292b7a..39d191611 100644 --- a/src/main/java/com/simibubi/create/foundation/item/TooltipHelper.java +++ b/src/main/java/com/simibubi/create/foundation/item/TooltipHelper.java @@ -21,6 +21,7 @@ import com.simibubi.create.content.contraptions.components.flywheel.engine.Engin import com.simibubi.create.content.contraptions.goggles.IHaveGoggleInformation; import com.simibubi.create.content.curiosities.tools.AllToolTiers; import com.simibubi.create.foundation.item.ItemDescription.Palette; +import com.simibubi.create.foundation.utility.FontHelper; import com.simibubi.create.foundation.utility.Lang; import net.minecraft.client.Minecraft; @@ -88,30 +89,8 @@ public class TooltipHelper { words.add(word); } - // Apply hard wrap FontRenderer font = Minecraft.getInstance().fontRenderer; - List lines = new LinkedList<>(); - StringBuilder currentLine = new StringBuilder(); - int width = 0; - for (String word : words) { - int newWidth = font.getStringWidth(word); - if (width + newWidth > maxWidthPerLine) { - if (width > 0) { - String line = currentLine.toString(); - lines.add(line); - currentLine = new StringBuilder(); - width = 0; - } else { - lines.add(word); - continue; - } - } - currentLine.append(word); - width += newWidth; - } - if (width > 0) { - lines.add(currentLine.toString()); - } + List lines = FontHelper.cutString(font, markedUp, maxWidthPerLine); // Format String lineStart = Strings.repeat(" ", indent); diff --git a/src/main/java/com/simibubi/create/foundation/ponder/PonderUI.java b/src/main/java/com/simibubi/create/foundation/ponder/PonderUI.java index f4f9d5d38..229be5f19 100644 --- a/src/main/java/com/simibubi/create/foundation/ponder/PonderUI.java +++ b/src/main/java/com/simibubi/create/foundation/ponder/PonderUI.java @@ -25,6 +25,7 @@ import com.simibubi.create.foundation.ponder.content.PonderTagScreen; import com.simibubi.create.foundation.ponder.ui.PonderButton; import com.simibubi.create.foundation.renderState.SuperRenderTypeBuffer; import com.simibubi.create.foundation.utility.ColorHelper; +import com.simibubi.create.foundation.utility.FontHelper; import com.simibubi.create.foundation.utility.Iterate; import com.simibubi.create.foundation.utility.Lang; import com.simibubi.create.foundation.utility.animation.LerpedFloat; @@ -486,7 +487,7 @@ public class PonderUI extends AbstractSimiScreen { RenderSystem.translated(x, y, 0); RenderSystem.rotatef(indexDiff * -75, 1, 0, 0); RenderSystem.translated(0, 0, 5); - font.drawSplitString(title, 0, 0, left.x - 51, ColorHelper.applyAlpha(textColor, 1 - indexDiff)); + FontHelper.drawSplitString(font, title, 0, 0, left.x - 51, ColorHelper.applyAlpha(textColor, 1 - indexDiff)); RenderSystem.popMatrix(); if (chapter != null) { diff --git a/src/main/java/com/simibubi/create/foundation/ponder/content/PonderTagScreen.java b/src/main/java/com/simibubi/create/foundation/ponder/content/PonderTagScreen.java index a443af1f2..09abfaadb 100644 --- a/src/main/java/com/simibubi/create/foundation/ponder/content/PonderTagScreen.java +++ b/src/main/java/com/simibubi/create/foundation/ponder/content/PonderTagScreen.java @@ -16,6 +16,7 @@ import com.simibubi.create.foundation.ponder.PonderUI; import com.simibubi.create.foundation.ponder.ui.ChapterLabel; import com.simibubi.create.foundation.ponder.ui.LayoutHelper; import com.simibubi.create.foundation.ponder.ui.PonderButton; +import com.simibubi.create.foundation.utility.FontHelper; import com.simibubi.create.foundation.utility.Lang; import net.minecraft.block.Block; @@ -197,7 +198,7 @@ public class PonderTagScreen extends AbstractSimiScreen { PonderUI.renderBox(x - 3, y - 3, w + 6, h + 6, false); RenderSystem.translated(0, 0, 100); - font.drawSplitString(desc, x, y, w, 0xeeeeee); + FontHelper.drawSplitString(font, desc, x, y, w, 0xeeeeee); RenderSystem.popMatrix(); } diff --git a/src/main/java/com/simibubi/create/foundation/ponder/elements/TextWindowElement.java b/src/main/java/com/simibubi/create/foundation/ponder/elements/TextWindowElement.java index 615169fee..b41861a36 100644 --- a/src/main/java/com/simibubi/create/foundation/ponder/elements/TextWindowElement.java +++ b/src/main/java/com/simibubi/create/foundation/ponder/elements/TextWindowElement.java @@ -10,6 +10,7 @@ import com.simibubi.create.foundation.ponder.PonderScene; import com.simibubi.create.foundation.ponder.PonderUI; import com.simibubi.create.foundation.ponder.content.PonderPalette; import com.simibubi.create.foundation.utility.ColorHelper; +import com.simibubi.create.foundation.utility.FontHelper; import net.minecraft.util.math.MathHelper; import net.minecraft.util.math.Vec2f; @@ -120,8 +121,8 @@ public class TextWindowElement extends AnimatedOverlayElement { RenderSystem.popMatrix(); } - screen.getFontRenderer() - .drawSplitString(bakedText, targetX - 10, 3, textWidth, ColorHelper.applyAlpha(brighterColor, fade)); + FontHelper.drawSplitString(screen.getFontRenderer(), bakedText, targetX - 10, 3, textWidth, + ColorHelper.applyAlpha(brighterColor, fade)); RenderSystem.popMatrix(); } diff --git a/src/main/java/com/simibubi/create/foundation/utility/FontHelper.java b/src/main/java/com/simibubi/create/foundation/utility/FontHelper.java new file mode 100644 index 000000000..a22218685 --- /dev/null +++ b/src/main/java/com/simibubi/create/foundation/utility/FontHelper.java @@ -0,0 +1,85 @@ +package com.simibubi.create.foundation.utility; + +import java.text.BreakIterator; +import java.util.LinkedList; +import java.util.List; + +import net.minecraft.client.gui.FontRenderer; +import net.minecraft.client.renderer.IRenderTypeBuffer; +import net.minecraft.client.renderer.Matrix4f; +import net.minecraft.client.renderer.Tessellator; +import net.minecraft.client.renderer.TransformationMatrix; +import net.minecraftforge.client.MinecraftForgeClient; + +public final class FontHelper { + + private FontHelper() { + } + + public static List cutString(FontRenderer font, String text, int maxWidthPerLine) { + // Split words + List words = new LinkedList<>(); + BreakIterator iterator = BreakIterator.getLineInstance(MinecraftForgeClient.getLocale()); + iterator.setText(text); + int start = iterator.first(); + for (int end = iterator.next(); end != BreakIterator.DONE; start = end, end = iterator.next()) { + String word = text.substring(start, end); + words.add(word); + } + // Apply hard wrap + List lines = new LinkedList<>(); + StringBuilder currentLine = new StringBuilder(); + int width = 0; + for (String word : words) { + int newWidth = font.getStringWidth(word); + if (width + newWidth > maxWidthPerLine) { + if (width > 0) { + String line = currentLine.toString(); + lines.add(line); + currentLine = new StringBuilder(); + width = 0; + } else { + lines.add(word); + continue; + } + } + currentLine.append(word); + width += newWidth; + } + if (width > 0) { + lines.add(currentLine.toString()); + } + return lines; + } + + public static void drawSplitString(FontRenderer font, String text, int x, int y, int width, int color) { + List list = cutString(font, text, width); + Matrix4f matrix4f = TransformationMatrix.identity().getMatrix(); + + for (String s : list) { + float f = (float) x; + if (font.getBidiFlag()) { + int i = font.getStringWidth(font.bidiReorder(s)); + f += (float) (width - i); + } + + draw(font, s, f, (float) y, color, matrix4f, false); + y += 9; + } + } + + private static int draw(FontRenderer font, String p_228078_1_, float p_228078_2_, float p_228078_3_, + int p_228078_4_, Matrix4f p_228078_5_, boolean p_228078_6_) { + if (p_228078_1_ == null) { + return 0; + } else { + IRenderTypeBuffer.Impl irendertypebuffer$impl = IRenderTypeBuffer + .immediate(Tessellator.getInstance().getBuffer()); + int i = font.draw(p_228078_1_, p_228078_2_, p_228078_3_, p_228078_4_, p_228078_6_, p_228078_5_, + irendertypebuffer$impl, false, 0, 15728880); + irendertypebuffer$impl.draw(); + return i; + } + } + +}