From 4566b88ac437323337bf1f8699766b007a931c4e Mon Sep 17 00:00:00 2001 From: syeyoung Date: Wed, 25 Jan 2023 18:39:33 +0900 Subject: - Builder style textstyle - Text now parses formatting codes. Signed-off-by: syeyoung --- .../dungeonsguide/mod/guiv2/elements/Text.java | 115 ++++++++++++++++++++- .../richtext/styles/ParentDelegatingTextStyle.java | 3 +- 2 files changed, 112 insertions(+), 6 deletions(-) (limited to 'mod/src/main') diff --git a/mod/src/main/java/kr/syeyoung/dungeonsguide/mod/guiv2/elements/Text.java b/mod/src/main/java/kr/syeyoung/dungeonsguide/mod/guiv2/elements/Text.java index 341a0282..23442d06 100644 --- a/mod/src/main/java/kr/syeyoung/dungeonsguide/mod/guiv2/elements/Text.java +++ b/mod/src/main/java/kr/syeyoung/dungeonsguide/mod/guiv2/elements/Text.java @@ -42,6 +42,7 @@ import net.minecraft.client.renderer.GlStateManager; import java.util.ArrayList; import java.util.Collections; import java.util.List; +import java.util.Locale; import java.util.concurrent.CopyOnWriteArrayList; public class Text extends AnnotatedExportOnlyWidget { @@ -75,21 +76,125 @@ public class Text extends AnnotatedExportOnlyWidget { public Text() { text.addOnUpdate((a,b) -> { - richText.setRootSpan(new TextSpan(textStyle, b)); + updateText(); }); wordBreak.addOnUpdate((a,b) -> { richText.setBreakWord(b == WordBreak.WORD ? BreakWord.WORD : BreakWord.ALL); }); lineSpacing.addOnUpdate((a,b) -> { - textStyle.topAscent = b; - richText.setRootSpan(new TextSpan(textStyle, text.getValue())); + updateText(); }); textAlign.addOnUpdate((a,b) -> { richText.setAlign(b == TextAlign.LEFT ? RichText.TextAlign.LEFT : b == TextAlign.CENTER ? RichText.TextAlign.CENTER : RichText.TextAlign.RIGHT); }); color.addOnUpdate((a,b) -> { - textStyle.textShader = new SingleColorShader(b); - richText.setRootSpan(new TextSpan(textStyle, text.getValue())); + updateText(); }); } + + private void updateText() { + textStyle.textShader = new SingleColorShader(color.getValue()); + textStyle.underlineShader = new SingleColorShader(color.getValue()); + textStyle.strikeThroughShader = new SingleColorShader(color.getValue()); + textStyle.topAscent = lineSpacing.getValue() - 1; + TextSpan textSpan = new TextSpan(textStyle, ""); + for (TextSpan textSpan2 : parseText(text.getValue())) { + textSpan.addChild(textSpan2); + } + richText.setRootSpan(textSpan); + } + + private static final int[] colorCode = new int[32]; + static { + for(int i = 0; i < 32; ++i) { + int j = (i >> 3 & 1) * 85; + int k = (i >> 2 & 1) * 170 + j; + int l = (i >> 1 & 1) * 170 + j; + int i1 = (i & 1) * 170 + j; + if (i == 6) { + k += 85; + } + + if (i >= 16) { + k /= 4; + l /= 4; + i1 /= 4; + } + + colorCode[i] = (k & 255) << 16 | (l & 255) << 8 | i1 & 255; + } + } + private List parseText(String text) { + Boolean boldStyle = null, strikethroughStyle = null, underlineStyle = null, italicStyle = null; + Integer textColor = null; + List spans = new ArrayList<>(); + + StringBuilder stringBuilder = new StringBuilder(); + for(int i = 0; i < text.length(); ++i) { + char c0 = text.charAt(i); + if (c0 == 167 && i + 1 < text.length()) { + if (!stringBuilder.toString().isEmpty()) { + spans.add(new TextSpan( + new ParentDelegatingTextStyle() + .setTextShader(textColor == null ? null : new SingleColorShader(textColor | 0xFF000000)) + .setBold(boldStyle) + .setStrikeThroughShader(textColor == null ? null : new SingleColorShader(textColor | 0xFF000000)) + .setStrikeThrough(strikethroughStyle) + .setUnderlineShader(textColor == null ? null : new SingleColorShader(textColor | 0xFF000000)) + .setUnderline(underlineStyle) + .setItalics(italicStyle), + stringBuilder.toString() + )); + stringBuilder = new StringBuilder(); + } + + + int i1 = "0123456789abcdefklmnor".indexOf(text.toLowerCase(Locale.ENGLISH).charAt(i + 1)); + if (i1 < 16) { + boldStyle = false; + strikethroughStyle = false; + underlineStyle = false; + italicStyle = false; + if (i1 < 0) { + i1 = 15; + } + textColor = colorCode[i1]; + } else if (i1 == 16) { + } else if (i1 == 17) { + boldStyle = true; + } else if (i1 == 18) { + strikethroughStyle = true; + } else if (i1 == 19) { + underlineStyle = true; + } else if (i1 == 20) { + italicStyle = true; + } else { + boldStyle = false; + strikethroughStyle = false; + underlineStyle = false; + italicStyle = false; + textColor = null; + } + + ++i; + } else { + stringBuilder.append(c0); + } + } + + if (!stringBuilder.toString().isEmpty()) { + spans.add(new TextSpan( + new ParentDelegatingTextStyle() + .setTextShader(textColor == null ? null : new SingleColorShader(textColor | 0xFF000000)) + .setBold(boldStyle) + .setStrikeThroughShader(textColor == null ? null : new SingleColorShader(textColor | 0xFF000000)) + .setStrikeThrough(strikethroughStyle) + .setUnderlineShader(textColor == null ? null : new SingleColorShader(textColor | 0xFF000000)) + .setUnderline(underlineStyle) + .setItalics(italicStyle), + stringBuilder.toString() + )); + } + return spans; + } } diff --git a/mod/src/main/java/kr/syeyoung/dungeonsguide/mod/guiv2/elements/richtext/styles/ParentDelegatingTextStyle.java b/mod/src/main/java/kr/syeyoung/dungeonsguide/mod/guiv2/elements/richtext/styles/ParentDelegatingTextStyle.java index 9889c98e..e8f74858 100644 --- a/mod/src/main/java/kr/syeyoung/dungeonsguide/mod/guiv2/elements/richtext/styles/ParentDelegatingTextStyle.java +++ b/mod/src/main/java/kr/syeyoung/dungeonsguide/mod/guiv2/elements/richtext/styles/ParentDelegatingTextStyle.java @@ -24,8 +24,9 @@ import kr.syeyoung.dungeonsguide.mod.guiv2.elements.richtext.shaders.Shader; import kr.syeyoung.dungeonsguide.mod.guiv2.elements.richtext.shaders.SingleColorShader; import lombok.Getter; import lombok.Setter; +import lombok.experimental.Accessors; -@Setter +@Setter @Accessors(chain = true) public class ParentDelegatingTextStyle implements ITextStyle { public Double size; public Double topAscent; -- cgit