Skip to content

Commit

Permalink
add tag ElementTag.split_lines_by_width and text_width
Browse files Browse the repository at this point in the history
  • Loading branch information
mcmonkey4eva committed Apr 12, 2020
1 parent 6d07fed commit cf0fbd2
Show file tree
Hide file tree
Showing 2 changed files with 108 additions and 0 deletions.
Expand Up @@ -4,7 +4,9 @@
import com.denizenscript.denizen.scripts.containers.core.FormatScriptContainer;
import com.denizenscript.denizen.scripts.containers.core.ItemScriptHelper;
import com.denizenscript.denizen.utilities.FormattedTextHelper;
import com.denizenscript.denizen.utilities.TextWidthHelper;
import com.denizenscript.denizencore.objects.properties.PropertyParser;
import com.denizenscript.denizencore.utilities.CoreUtilities;
import com.denizenscript.denizencore.utilities.debugging.Debug;
import com.denizenscript.denizen.utilities.implementation.BukkitScriptEntryData;
import com.denizenscript.denizen.tags.BukkitTagContext;
Expand Down Expand Up @@ -189,6 +191,36 @@ public static void registerTags() {
new BukkitTagContext(attribute.getScriptEntry())), "PluginTag", attribute.hasAlternative());
}, "asplugin");

// <--[tag]
// @attribute <ElementTag.split_lines_by_width[<#>]>
// @returns ElementTag
// @group element manipulation
// @description
// Returns the element split into separate lines based on a maximum width in pixels per line.
// This uses character width, so for example 20 "W"s and 20 "i"s will be treated differently.
// 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.
// -->
PropertyParser.<BukkitElementProperties>registerTag("split_lines_by_width", (attribute, object) -> {
int width = attribute.getIntContext(1);
return new ElementTag(TextWidthHelper.splitLines(object.asString(), width));
});

// <--[tag]
// @attribute <ElementTag.text_width>
// @returns ElementTag
// @group element manipulation
// @description
// 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.
// -->
PropertyParser.<BukkitElementProperties>registerTag("text_width", (attribute, object) -> {
return new ElementTag(TextWidthHelper.getWidth(object.asString()));
});

// <--[tag]
// @attribute <ElementTag.last_color>
// @returns ElementTag
Expand Down
@@ -0,0 +1,76 @@
package com.denizenscript.denizen.utilities;

public class TextWidthHelper {

public static int[] characterWidthMap = new int[128];

public static void setWidth(int width, String chars) {
for (char c : chars.toCharArray()) {
characterWidthMap[c] = width;
}
}

static {
for (int i = 0; i < 128; i++) {
characterWidthMap[i] = 6;
}
setWidth(2, "!,.:;|i`");
setWidth(3, "'l");
setWidth(4, " []tI");
setWidth(5, "\"()*<>fk{}");
// all other ASCII characters are length=6
setWidth(7, "@~");
}

public static int getWidth(char c) {
return c > 127 ? 6 : characterWidthMap[c];
}

public static int getWidth(String str) {
int total = 0;
for (char c : str.toCharArray()) {
total += getWidth(c);
if (c == '\n') {
total = 0;
}
}
return total;
}

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;
mainloop:
for (int i = 0; i < str.length(); i++) {
char c = str.charAt(i);
if (c == '\n') {
output.append(str, lineStart, i);
curLineWidth = 0;
lineStart = i + 1;
continue;
}
curLineWidth += getWidth(c);
if (curLineWidth > 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;
lineStart = x + 1;
i = x;
continue mainloop;
}
}
output.append(str, lineStart, i);
curLineWidth = 0;
lineStart = i;
}
}
output.append(str, lineStart, str.length());
return output.toString();
}
}

0 comments on commit cf0fbd2

Please sign in to comment.