Skip to content

Commit

Permalink
color support in text width
Browse files Browse the repository at this point in the history
  • Loading branch information
mcmonkey4eva committed Feb 16, 2022
1 parent 49a9523 commit 870a89a
Show file tree
Hide file tree
Showing 3 changed files with 63 additions and 15 deletions.
2 changes: 1 addition & 1 deletion README.md
Expand Up @@ -3,7 +3,7 @@ The Denizen Scripting Language - Spigot Impl

An implementation of the Denizen Scripting Language for Spigot servers, with strong Citizens interlinks to emphasize the power of using Denizen with NPCs!

**Version 1.2.4**: Compatible with Spigot 1.16.5, 1.17.1, and 1.18!
**Version 1.2.4**: Compatible with Spigot 1.16.5, 1.17.1, and 1.18.1!

**Learn about Denizen from the Beginner's guide:** https://guide.denizenscript.com/guides/background/index.html

Expand Down
Expand Up @@ -306,7 +306,6 @@ public static void registerTags() {
// The width used is based on the vanilla minecraft font. This will not be accurate for other fonts.
// This only currently supports ASCII symbols properly. Unicode symbols will be estimated as 6 pixels.
// Spaces will be preferred to become newlines, unless a line does not contain any spaces.
// This will transfer colors over to new lines as well.
// -->
PropertyParser.<BukkitElementProperties, ElementTag>registerStaticTag(ElementTag.class, "split_lines_by_width", (attribute, object) -> {
int width = attribute.getIntParam();
Expand All @@ -321,7 +320,7 @@ public static void registerTags() {
// Returns the width, in pixels, of the text.
// The width used is based on the vanilla minecraft font. This will not be accurate for other fonts.
// This only currently supports ASCII symbols properly. Unicode symbols will be estimated as 6 pixels.
// This will not work well with elements that contain newlines.
// If the element contains newlines, will return the widest line width.
// -->
PropertyParser.<BukkitElementProperties, ElementTag>registerStaticTag(ElementTag.class, "text_width", (attribute, object) -> {
return new ElementTag(TextWidthHelper.getWidth(object.asString()));
Expand Down
@@ -1,5 +1,8 @@
package com.denizenscript.denizen.utilities;

import com.denizenscript.denizencore.utilities.AsciiMatcher;
import org.bukkit.ChatColor;

public class TextWidthHelper {

public static int[] characterWidthMap = new int[128];
Expand All @@ -26,47 +29,93 @@ public static int getWidth(char c) {
return c > 127 ? 6 : characterWidthMap[c];
}

public static AsciiMatcher formatCharCodeMatcher = new AsciiMatcher("klmnoKLMNO");

public static int getWidth(String str) {
int maxWidth = 0;
int total = 0;
for (char c : str.toCharArray()) {
total += getWidth(c);
boolean bold = false;
char[] rawChars = str.toCharArray();
for (int i = 0; i < rawChars.length; i++) {
char c = rawChars[i];
if (c == ChatColor.COLOR_CHAR && (i + 1) < rawChars.length) {
char c2 = rawChars[i + 1];
if (c2 == '[') {
while (i < rawChars.length && rawChars[i] != ']') {
i++;
}
continue;
}
else if (c2 == 'l' || c2 == 'L') {
bold = true;
}
else if (!formatCharCodeMatcher.isMatch(c2)) {
bold = false;
}
i++;
continue;
}
total += getWidth(c) + (bold ? 2 : 0);
if (c == '\n') {
if (total > maxWidth) {
maxWidth = total;
}
total = 0;
}
}
return total;
return Math.max(total, maxWidth);
}

public static boolean isBold(boolean wasBold, String str) {
boolean bold = wasBold;
char[] rawChars = str.toCharArray();
for (int i = 0; i < rawChars.length; i++) {
char c = rawChars[i];
if (c == ChatColor.COLOR_CHAR && (i + 1) < rawChars.length) {
char c2 = rawChars[i + 1];
if (c2 == 'l' || c2 == 'L') {
bold = true;
}
else if (!formatCharCodeMatcher.isMatch(c2)) {
bold = false;
}
}
}
return bold;
}

public static String splitLines(String str, int width) {
if (width < 8) {
return str;
}
StringBuilder output = new StringBuilder(str.length() * 2);
int curLineWidth = 0;
int lineStart = 0;
boolean bold = false;
mainloop:
for (int i = 0; i < str.length(); i++) {
char c = str.charAt(i);
if (c == '\n') {
output.append(str, lineStart, i + 1);
curLineWidth = 0;
String lastLine = str.substring(lineStart, i + 1);
bold = isBold(bold, lastLine);
output.append(lastLine);
lineStart = i + 1;
continue;
}
curLineWidth += getWidth(c);
if (curLineWidth > width) {
if (getWidth(((bold ? ChatColor.BOLD.toString() : "") + str.substring(lineStart, i))) > width) {
for (int x = i - 1; x > lineStart; x--) {
char xc = str.charAt(x);
if (xc == ' ') {
output.append(str, lineStart, x).append("\n");
curLineWidth = 0;
String lastLine = str.substring(lineStart, x);
bold = isBold(bold, lastLine);
output.append(lastLine).append("\n");
lineStart = x + 1;
i = x;
continue mainloop;
}
}
output.append(str, lineStart, i).append("\n");
curLineWidth = 0;
String lastLine = str.substring(lineStart, i);
bold = isBold(bold, lastLine);
output.append(lastLine).append("\n");
lineStart = i;
}
}
Expand Down

0 comments on commit 870a89a

Please sign in to comment.