package net.tylermurphy.Minecraft.UI.Text; import java.util.ArrayList; import java.util.List; import net.tylermurphy.Minecraft.UI.UIText; public class TextMeshCreator { protected static final double LINE_HEIGHT = 0.03f; protected static final int SPACE_ASCII = 32; private MetaFile metaData; public TextMeshCreator(String metaFile) { metaData = new MetaFile(metaFile); } public TextMeshData createTextMesh(UIText text) { List lines = createStructure(text); TextMeshData data = createQuadVertices(text, lines); return data; } private List createStructure(UIText text) { char[] chars = text.getTextString().toCharArray(); List lines = new ArrayList(); Line currentLine = new Line(metaData.getSpaceWidth(), text.getFontSize(), text.getMaxLineSize()); Word currentWord = new Word(text.getFontSize()); for (char c : chars) { int ascii = (int) c; if (ascii == SPACE_ASCII) { boolean added = currentLine.attemptToAddWord(currentWord); if (!added) { lines.add(currentLine); currentLine = new Line(metaData.getSpaceWidth(), text.getFontSize(), text.getMaxLineSize()); currentLine.attemptToAddWord(currentWord); } currentWord = new Word(text.getFontSize()); continue; } Character character = metaData.getCharacter(ascii); currentWord.addCharacter(character); } completeStructure(lines, currentLine, currentWord, text); return lines; } private void completeStructure(List lines, Line currentLine, Word currentWord, UIText text) { boolean added = currentLine.attemptToAddWord(currentWord); if (!added) { lines.add(currentLine); currentLine = new Line(metaData.getSpaceWidth(), text.getFontSize(), text.getMaxLineSize()); currentLine.attemptToAddWord(currentWord); } lines.add(currentLine); } private TextMeshData createQuadVertices(UIText text, List lines) { text.setNumberOfLines(lines.size()); double curserX = 0f; double curserY = 0f; double maxX = 0; List vertices = new ArrayList(); List textureCoords = new ArrayList(); for (Line line : lines) { if (text.isCentered()) { curserX = (line.getMaxLength() - line.getLineLength()) / 2; } for (Word word : line.getWords()) { for (Character letter : word.getCharacters()) { double newMaxX = addVerticesForCharacter(curserX, curserY, letter, text.getFontSize(), vertices); maxX = Math.max(newMaxX, maxX); addTexCoords(textureCoords, letter.getxTextureCoord(), letter.getyTextureCoord(), letter.getXMaxTextureCoord(), letter.getYMaxTextureCoord()); curserX += letter.getxAdvance() * text.getFontSize(); } curserX += metaData.getSpaceWidth() * text.getFontSize(); } curserX = 0; curserY += LINE_HEIGHT * text.getFontSize(); } text.setMaxX(maxX); return new TextMeshData(listToArray(vertices), listToArray(textureCoords)); } private double addVerticesForCharacter(double curserX, double curserY, Character character, double fontSize, List vertices) { double x = curserX + (character.getxOffset() * fontSize); double y = curserY + (character.getyOffset() * fontSize); double maxX = x + (character.getSizeX() * fontSize); double maxY = y + (character.getSizeY() * fontSize); double properX = (2 * x) - 1; double properY = (-2 * y) + 1; double properMaxX = (2 * maxX) - 1; double properMaxY = (-2 * maxY) + 1; addVertices(vertices, properX, properY, properMaxX, properMaxY); return maxX; } private static void addVertices(List vertices, double x, double y, double maxX, double maxY) { vertices.add((float) x); vertices.add((float) y); vertices.add((float) x); vertices.add((float) maxY); vertices.add((float) maxX); vertices.add((float) maxY); vertices.add((float) maxX); vertices.add((float) maxY); vertices.add((float) maxX); vertices.add((float) y); vertices.add((float) x); vertices.add((float) y); } private static void addTexCoords(List texCoords, double x, double y, double maxX, double maxY) { texCoords.add((float) x); texCoords.add((float) y); texCoords.add((float) x); texCoords.add((float) maxY); texCoords.add((float) maxX); texCoords.add((float) maxY); texCoords.add((float) maxX); texCoords.add((float) maxY); texCoords.add((float) maxX); texCoords.add((float) y); texCoords.add((float) x); texCoords.add((float) y); } private static float[] listToArray(List listOfFloats) { float[] array = new float[listOfFloats.size()]; for (int i = 0; i < array.length; i++) { array[i] = listOfFloats.get(i); } return array; } }