package pers.gwyog.gtneioreplugin.util; import java.util.Arrays; import net.minecraft.client.Minecraft; import net.minecraft.client.gui.FontRenderer; import com.google.common.base.Strings; 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 Array 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; } }