Skip to content

Commit 6aa2752

Browse files
Adopt lombok.val, standardize List types, and centralize Android text wrapping in SystemTextBase
Desktop: use val when iterating textLines/segments for cleaner syntax. Android: remove local wrapText, call base wrapText(parseMarkupToSegments, maxWidth), switch measureLine/drawTextLine to List<ColoredSegment>, and use val in loops. Base: generalize textLines to List<List<ColoredSegment>>, unify markup handling via a single MARKUP_PATTERN, add color tag support ([color:text]) with name/hex parsing, and minor cleanup in highlightColor. This reduces duplication, standardizes collection types, and consolidates wrapping/markup logic.
1 parent 0583001 commit 6aa2752

File tree

3 files changed

+73
-61
lines changed

3 files changed

+73
-61
lines changed

RemixedDungeon/src/android/java/com/nyrds/platform/gfx/SystemText.java

Lines changed: 13 additions & 48 deletions
Original file line numberDiff line numberDiff line change
@@ -23,10 +23,12 @@
2323
import org.jetbrains.annotations.NotNull;
2424

2525
import java.util.ArrayList;
26+
import java.util.List;
2627
import java.util.Map;
2728
import java.util.concurrent.ConcurrentHashMap;
2829

2930
import lombok.Synchronized;
31+
import lombok.val;
3032

3133
public class SystemText extends SystemTextBase {
3234

@@ -175,50 +177,9 @@ public void kill() {
175177

176178
private float fontHeight;
177179

178-
private void wrapText() {
179-
textLines.clear();
180-
java.util.List<ColoredSegment> allSegments = parseMarkupToSegments(originalText);
181-
hasMarkup = !allSegments.isEmpty() && allSegments.size() > 1;
180+
182181

183-
ArrayList<ColoredSegment> currentLine = new ArrayList<>();
184-
float currentLineWidth = 0;
185-
186-
for (ColoredSegment segment : allSegments) {
187-
String[] paragraphs = segment.text.split("\n", -1);
188-
189-
for (int p = 0; p < paragraphs.length; p++) {
190-
String paragraph = paragraphs[p];
191-
String[] words = paragraph.split("(?<=\\s)|(?=\\s)"); // Split while keeping spaces
192-
193-
for (String word : words) {
194-
if (word.isEmpty()) continue;
195-
196-
float wordWidth = symbolWidth(word);
197-
198-
if (needWidth && !currentLine.isEmpty() && currentLineWidth + wordWidth > (maxWidth / scale.x)) {
199-
textLines.add(new ArrayList<>(currentLine)); // Add a copy as ArrayList to the common List
200-
currentLine = new ArrayList<>();
201-
currentLineWidth = 0;
202-
}
203-
204-
currentLine.add(new ColoredSegment(word, segment.color));
205-
currentLineWidth += wordWidth;
206-
}
207-
208-
if (p < paragraphs.length - 1) { // This was a newline character
209-
textLines.add(new ArrayList<>(currentLine)); // Add a copy as ArrayList to the common List
210-
currentLine = new ArrayList<>();
211-
currentLineWidth = 0;
212-
}
213-
}
214-
}
215-
216-
if (!currentLine.isEmpty()) {
217-
textLines.add(new ArrayList<>(currentLine)); // Add a copy as ArrayList to the common List
218-
}
219-
}
220-
221-
private float measureLine(ArrayList<ColoredSegment> line) {
182+
private float measureLine(List<ColoredSegment> line) {
222183
float lineWidth = 0;
223184
for(ColoredSegment seg : line) {
224185
lineWidth += symbolWidth(seg.text);
@@ -238,9 +199,13 @@ private void createText() {
238199
setWidth(0);
239200
setHeight(0);
240201

241-
wrapText();
202+
// Use the base class wrapText method with appropriate max width
203+
float maxWidthForWrapping = needWidth ? (maxWidth / scale.x) : Float.MAX_VALUE;
204+
val wrappedLines = wrapText(parseMarkupToSegments(originalText), maxWidthForWrapping);
205+
textLines.clear();
206+
textLines.addAll(wrappedLines);
242207

243-
for (var line : textLines) {
208+
for (val line : textLines) {
244209
setHeight(height + fontHeight);
245210

246211
float lineWidth = measureLine(line); // Convert to ArrayList for measureLine method
@@ -262,8 +227,8 @@ private void createText() {
262227
bitmapCache.put(key, bitmap);
263228

264229
Canvas canvas = new Canvas(bitmap.bmp);
265-
drawTextLine(line, canvas, contourPaint); // Convert to ArrayList for drawTextLine
266-
drawTextLine(line, canvas, textPaint); // Convert to ArrayList for drawTextLine
230+
drawTextLine(line, canvas, contourPaint);
231+
drawTextLine(line, canvas, textPaint);
267232

268233
cacheMiss++;
269234
} else {
@@ -279,7 +244,7 @@ private void createText() {
279244
}
280245
}
281246

282-
private void drawTextLine(ArrayList<ColoredSegment> line, Canvas canvas, TextPaint paint) {
247+
private void drawTextLine(List<ColoredSegment> line, Canvas canvas, TextPaint paint) {
283248
float y = (fontHeight) * oversample - paint.descent();
284249
float x = 0.5f * oversample;
285250

RemixedDungeon/src/main/java/com/watabou/noosa/SystemTextBase.java

Lines changed: 56 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -6,16 +6,29 @@
66

77
import java.util.ArrayList;
88
import java.util.List;
9+
import java.util.HashMap;
10+
import java.util.Map;
911
import java.util.regex.Matcher;
1012
import java.util.regex.Pattern;
1113

1214
public abstract class SystemTextBase extends Text {
13-
// Combined markup pattern for violet highlighting (_text_) and bronze ("text")
14-
protected static final Pattern MARKUP_PATTERN = Pattern.compile("_(.*?)_|\"(.*?)\"");
15-
// Markup pattern for highlighting (_text_)
16-
protected static final Pattern HIGHLIGHTER = Pattern.compile("_(.*?)_");
17-
// Markup pattern for bronze text ("text")
18-
protected static final Pattern BRONZE_HIGHLIGHTER = Pattern.compile("\"(.*?)\"");
15+
// Combined markup pattern for violet highlighting (_text_), bronze ("text"), and generic color tags ([color:text])
16+
protected static final Pattern MARKUP_PATTERN = Pattern.compile("_(.*?)_|\"(.*?)\"|\\[(#?[a-zA-Z0-9]+):(.*?)?\\]");
17+
18+
private static final Map<String, Integer> COLOR_MAP = new HashMap<>();
19+
static {
20+
COLOR_MAP.put("red", 0xFFFF0000);
21+
COLOR_MAP.put("green", 0xFF00FF00);
22+
COLOR_MAP.put("blue", 0xFF0000FF);
23+
COLOR_MAP.put("yellow", 0xFFFFFF00);
24+
COLOR_MAP.put("cyan", 0xFF00FFFF);
25+
COLOR_MAP.put("magenta", 0xFFFF00FF);
26+
COLOR_MAP.put("white", 0xFFFFFFFF);
27+
COLOR_MAP.put("black", 0xFF000000);
28+
COLOR_MAP.put("gray", 0xFF808080);
29+
COLOR_MAP.put("orange", 0xFFFFA500);
30+
COLOR_MAP.put("purple", 0xFF800080);
31+
}
1932

2033
protected static float fontScale = Float.NaN;
2134

@@ -67,7 +80,7 @@ public static void updateFontScale() {
6780
* Subclasses can override if needed
6881
*/
6982
protected void parseMarkup(String input) {
70-
if (input != null && (HIGHLIGHTER.matcher(input).find() || BRONZE_HIGHLIGHTER.matcher(input).find())) {
83+
if (input != null && MARKUP_PATTERN.matcher(input).find()) {
7184
hasMarkup = true;
7285
}
7386
}
@@ -80,15 +93,17 @@ protected void parseMarkup(String input) {
8093
protected String extractPlainText(String str) {
8194
if (str == null) return "";
8295

83-
// Remove both underscore markup (_text_) and quote markup ("text")
84-
return str.replaceAll("_(.*?)_", "$1").replaceAll("\"(.*?)\"", "$1");
96+
// Remove underscore, quote, and color tag markup
97+
return str.replaceAll("_(.*?)_", "$1")
98+
.replaceAll("\"(.*?)\"", "$1")
99+
.replaceAll("\\[(#?[a-zA-Z0-9]+):(.*?)?\\]", "$2");
85100
}
86101

87102
/**
88103
* Set the highlight color for marked text
89104
*/
90105
public void highlightColor(int color) {
91-
this.highlightColor = color;
106+
highlightColor = color;
92107
if (hasMarkup) {
93108
dirty = true;
94109
}
@@ -128,6 +143,32 @@ public void text(@NotNull String str) {
128143
// Parse markup in the original text
129144
parseMarkup(str);
130145
}
146+
147+
/**
148+
* Parse a color string (hex or name) into an ARGB integer.
149+
* @param colorStr The color string (e.g., "#FF0000", "red")
150+
* @return The integer ARGB color
151+
*/
152+
private int parseColorString(String colorStr) {
153+
if (colorStr == null || colorStr.isEmpty()) {
154+
return defaultColor;
155+
}
156+
String lowerCaseColor = colorStr.toLowerCase();
157+
if (COLOR_MAP.containsKey(lowerCaseColor)) {
158+
return COLOR_MAP.get(lowerCaseColor);
159+
}
160+
if (colorStr.startsWith("#")) {
161+
try {
162+
long color = Long.parseLong(colorStr.substring(1), 16);
163+
if (colorStr.length() == 7) { // #RRGGBB
164+
return (int) (0xFF000000 | color);
165+
} else if (colorStr.length() == 9) { // #AARRGGBB
166+
return (int) color;
167+
}
168+
} catch (NumberFormatException ignored) {}
169+
}
170+
return defaultColor; // Fallback
171+
}
131172

132173
/**
133174
* Parse markup in the input string and convert to a list of colored segments.
@@ -149,6 +190,10 @@ protected List<ColoredSegment> parseMarkupToSegments(String input) {
149190
segments.add(new ColoredSegment(m.group(1), highlightColor));
150191
} else if (m.group(2) != null) {
151192
segments.add(new ColoredSegment(m.group(2), bronzeColor));
193+
} else if (m.group(3) != null) {
194+
String text = m.group(4) != null ? m.group(4) : "";
195+
int color = parseColorString(m.group(3));
196+
segments.add(new ColoredSegment(text, color));
152197
}
153198
lastEnd = m.end();
154199
}
@@ -216,7 +261,7 @@ protected List<List<ColoredSegment>> wrapText(List<ColoredSegment> allSegments,
216261
/**
217262
* Store the text lines after parsing and wrapping
218263
*/
219-
protected final ArrayList<ArrayList<ColoredSegment>> textLines = new ArrayList<>();
264+
protected final List<List<ColoredSegment>> textLines = new ArrayList<>();
220265

221266
/**
222267
* Invalidate caches - to be implemented by subclasses

RemixedDungeonDesktop/src/libgdx/java/com/nyrds/platform/gfx/SystemText.java

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,8 @@
1919
import java.util.List;
2020
import java.util.Map;
2121

22+
import lombok.val;
23+
2224
public class SystemText extends SystemTextBase {
2325
private static FreeTypeFontGenerator pixelGenerator;
2426
private static FreeTypeFontGenerator fallbackGenerator;
@@ -218,9 +220,9 @@ protected void measure() {
218220
float totalHeight = 0;
219221
float maxLineWidth = 0;
220222

221-
for (java.util.List<com.watabou.noosa.SystemTextBase.ColoredSegment> line : textLines) {
223+
for (val line : textLines) {
222224
float currentLineWidth = 0;
223-
for (com.watabou.noosa.SystemTextBase.ColoredSegment segment : line) {
225+
for (val segment : line) {
224226
pseudoGlyphLayout.setText(fontData, segment.text);
225227
currentLineWidth += pseudoGlyphLayout.width;
226228
}

0 commit comments

Comments
 (0)