Java tutorial
/* * Copyright 2014 MovingBlocks * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.terasology.rendering.assets.font; import java.util.ArrayDeque; import java.util.Deque; import java.util.List; import java.util.Map; import javax.vecmath.Vector3f; import org.terasology.rendering.FontColor; import org.terasology.rendering.assets.material.Material; import org.terasology.rendering.assets.mesh.Mesh; import org.terasology.rendering.assets.mesh.MeshBuilder; import org.terasology.rendering.nui.Color; import org.terasology.rendering.nui.HorizontalAlign; import com.google.common.collect.Maps; /** * @author Immortius */ public class FontMeshBuilder { private static final float SHADOW_DEPTH = -1; private Font font; private Color defaultColor; public FontMeshBuilder(Font font) { this.font = font; } public Map<Material, Mesh> createTextMesh(List<String> lines, int width, HorizontalAlign alignment, Color baseColor, Color shadowColor) { this.defaultColor = baseColor; Map<Material, MeshBuilder> meshBuilders = Maps.newLinkedHashMap(); addLinesToMesh(lines, meshBuilders, width, alignment, shadowColor); Map<Material, Mesh> result = Maps.newLinkedHashMap(); for (Map.Entry<Material, MeshBuilder> entry : meshBuilders.entrySet()) { result.put(entry.getKey(), entry.getValue().build()); } return result; } private void addLinesToMesh(List<String> lines, Map<Material, MeshBuilder> meshBuilders, int maxWidth, HorizontalAlign alignment, Color shadowColor) { int y = 0; Deque<Color> prevColors = new ArrayDeque<>(); Color currentColor = defaultColor; for (String line : lines) { int w = font.getWidth(line); int x = alignment.getOffset(w, maxWidth); for (char c : line.toCharArray()) { FontCharacter character = font.getCharacterData(c); if (character != null && character.getPage() != null) { MeshBuilder builder = meshBuilders.get(character.getPageMat()); if (builder == null) { builder = new MeshBuilder(); meshBuilders.put(character.getPageMat(), builder); } if (shadowColor.a() != 0) { addCharacter(builder, character, x, y, shadowColor, 1, 1, SHADOW_DEPTH); } addCharacter(builder, character, x, y, currentColor, 0, 0, 0); x += character.getxAdvance(); } else if (FontColor.isValid(c)) { if (c == FontColor.getReset()) { if (!prevColors.isEmpty()) { currentColor = prevColors.removeLast(); } } else { prevColors.addLast(currentColor); currentColor = FontColor.toColor(c); } } } y += font.getLineHeight(); } } private void addCharacter(MeshBuilder builder, FontCharacter character, int x, int y, Color color, float xOffset, float yOffset, float depth) { float top = y + character.getyOffset() + yOffset; float bottom = top + character.getHeight() + yOffset; float left = x + character.getxOffset() + xOffset; float right = left + character.getWidth() + xOffset; float texTop = character.getY(); float texBottom = texTop + character.getTexHeight(); float texLeft = character.getX(); float texRight = texLeft + character.getTexWidth(); Vector3f v1 = new Vector3f(left, top, depth); Vector3f v2 = new Vector3f(right, top, depth); Vector3f v3 = new Vector3f(right, bottom, depth); Vector3f v4 = new Vector3f(left, bottom, depth); builder.addPoly(v1, v2, v3, v4); builder.addColor(color, color, color, color); builder.addTexCoord(texLeft, texTop); builder.addTexCoord(texRight, texTop); builder.addTexCoord(texRight, texBottom); builder.addTexCoord(texLeft, texBottom); } }