1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
|
package pers.gwyog.gtneioreplugin.util;
import com.google.common.base.Strings;
import java.util.Arrays;
import net.minecraft.client.Minecraft;
import net.minecraft.client.gui.FontRenderer;
public class StringPaddingHack {
private static final int SPACE_WIDTH = 4;
private static final int BOLD_SPACE_WIDTH = 5;
/**
* Given a list of strings, arrange them into the requested number of columns with the specified spacing.
* Up to 3 additional spaces might be added between columns because this function relies on quirky font behaviors.
*
* @param strings List of strings to wrap into columns
* @param numColumns Number of columns, minimum of 1
* @param minColumnSpacing Minimum amount of extra spaces between columns.
* @return strings wrapped into columns
*/
public static String[] stringsToSpacedColumns(String[] strings, int numColumns, int minColumnSpacing) {
if (numColumns < 1) {
throw new IllegalArgumentException(
String.format("Argument numColumns must be 1 or higher, got value %d", numColumns));
}
if (numColumns > 1) {
int sliceSize = strings.length / numColumns;
int remainder = strings.length % numColumns;
String[][] columns = new String[numColumns][];
int totalExtra = 0;
// Arrange all strings into their proper columns so that the list of strings wraps through all columns
for (int i = 0; i < numColumns; i++) {
int extra = 0;
if (remainder > 0) {
remainder--;
extra = 1;
}
columns[i] = Arrays.copyOfRange(
strings, (sliceSize * i) + totalExtra, (sliceSize * (i + 1) + totalExtra + extra));
totalExtra += extra;
}
// Add extra padding to all but the last columns to align the text
for (int i = 0; i < numColumns - 1; i++) {
columns[i] = padStrings(columns[i], minColumnSpacing);
}
// Concatenate all columns into the final result
strings = columns[0];
for (int i = 0; i < sliceSize; i++) {
for (int j = 1; j < numColumns; j++) {
strings[i] += columns[j][i];
}
}
}
return strings;
}
/**
* Pads strings with spaces so that they are of equal length and adds to
* that the number of spaces specified and up to 3 if minExtraSpaces is
* below 3. Added spaces might be bold.
*
* Relies on the quirk of bold space characters being 1 pixel wider than
* regular space characters in the default font renderer.
*
* @param strings List of strings
* @param minExtraSpaces The minimum number of extra spaces to add
* @return List of strings padded with spaces to an equal length
*/
public static String[] padStrings(String[] strings, int minExtraSpaces) {
int[] widths = getStringWidths(strings);
int maxUnPaddedStrLength = 0;
int numSpacesAddedToLongestString = 0;
int maxPaddedStrLength = 0;
// Making string width a multiple of 4 by adding bold spaces of width 5
for (int i = 0; i < strings.length; i++) {
int mod = widths[i] % SPACE_WIDTH;
int numBoldSpacesToAdd = (SPACE_WIDTH - mod) % SPACE_WIDTH;
// Keep track of the number of spaces added to the longest string
if (widths[i] > maxUnPaddedStrLength) {
numSpacesAddedToLongestString = numBoldSpacesToAdd;
maxUnPaddedStrLength = widths[i];
}
strings[i] += "§l" + Strings.repeat(" ", numBoldSpacesToAdd) + "§r";
widths[i] += numBoldSpacesToAdd * BOLD_SPACE_WIDTH;
// Keep track of the current widest string we currently have
if (widths[i] > maxPaddedStrLength) {
maxPaddedStrLength = widths[i];
}
}
// Make sure we pad at least up to the desired number of spaces from the longest string
if (numSpacesAddedToLongestString < minExtraSpaces) {
maxPaddedStrLength += (minExtraSpaces - numSpacesAddedToLongestString) * SPACE_WIDTH;
}
// Add required spaces to equalize length of all strings to at least the target width
for (int i = 0; i < strings.length; i++) {
int numSpacesToAdd = (maxPaddedStrLength - widths[i]) / SPACE_WIDTH;
strings[i] += Strings.repeat(" ", numSpacesToAdd);
widths[i] += numSpacesToAdd * SPACE_WIDTH;
}
return strings;
}
/**
* Returns an array of font widths for the given array of strings
*
* @param strList Array of strings
* @return Array of font widths
*/
protected static int[] getStringWidths(String[] strList) {
FontRenderer font = Minecraft.getMinecraft().fontRenderer;
int[] widths = new int[strList.length];
for (int i = 0; i < strList.length; ++i) {
widths[i] = font.getStringWidth(strList[i]);
}
return widths;
}
}
|