1/* 2 * Copyright (c) 2009-2010 jMonkeyEngine 3 * All rights reserved. 4 * 5 * Redistribution and use in source and binary forms, with or without 6 * modification, are permitted provided that the following conditions are 7 * met: 8 * 9 * * Redistributions of source code must retain the above copyright 10 * notice, this list of conditions and the following disclaimer. 11 * 12 * * Redistributions in binary form must reproduce the above copyright 13 * notice, this list of conditions and the following disclaimer in the 14 * documentation and/or other materials provided with the distribution. 15 * 16 * * Neither the name of 'jMonkeyEngine' nor the names of its contributors 17 * may be used to endorse or promote products derived from this software 18 * without specific prior written permission. 19 * 20 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 21 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED 22 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 23 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR 24 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 25 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 26 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR 27 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF 28 * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING 29 * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 30 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 31 */ 32 33package com.jme3.font.plugins; 34 35import com.jme3.asset.*; 36import com.jme3.font.BitmapCharacter; 37import com.jme3.font.BitmapCharacterSet; 38import com.jme3.font.BitmapFont; 39import com.jme3.material.Material; 40import com.jme3.material.MaterialDef; 41import com.jme3.material.RenderState.BlendMode; 42import com.jme3.texture.Texture; 43import java.io.BufferedReader; 44import java.io.IOException; 45import java.io.InputStream; 46import java.io.InputStreamReader; 47 48public class BitmapFontLoader implements AssetLoader { 49 50 private BitmapFont load(AssetManager assetManager, String folder, InputStream in) throws IOException{ 51 MaterialDef spriteMat = 52 (MaterialDef) assetManager.loadAsset(new AssetKey("Common/MatDefs/Misc/Unshaded.j3md")); 53 54 BitmapCharacterSet charSet = new BitmapCharacterSet(); 55 Material[] matPages = null; 56 BitmapFont font = new BitmapFont(); 57 58 BufferedReader reader = new BufferedReader(new InputStreamReader(in)); 59 String regex = "[\\s=]+"; 60 61 font.setCharSet(charSet); 62 while (reader.ready()){ 63 String line = reader.readLine(); 64 String[] tokens = line.split(regex); 65 if (tokens[0].equals("info")){ 66 // Get rendered size 67 for (int i = 1; i < tokens.length; i++){ 68 if (tokens[i].equals("size")){ 69 charSet.setRenderedSize(Integer.parseInt(tokens[i + 1])); 70 } 71 } 72 }else if (tokens[0].equals("common")){ 73 // Fill out BitmapCharacterSet fields 74 for (int i = 1; i < tokens.length; i++){ 75 String token = tokens[i]; 76 if (token.equals("lineHeight")){ 77 charSet.setLineHeight(Integer.parseInt(tokens[i + 1])); 78 }else if (token.equals("base")){ 79 charSet.setBase(Integer.parseInt(tokens[i + 1])); 80 }else if (token.equals("scaleW")){ 81 charSet.setWidth(Integer.parseInt(tokens[i + 1])); 82 }else if (token.equals("scaleH")){ 83 charSet.setHeight(Integer.parseInt(tokens[i + 1])); 84 }else if (token.equals("pages")){ 85 // number of texture pages 86 matPages = new Material[Integer.parseInt(tokens[i + 1])]; 87 font.setPages(matPages); 88 } 89 } 90 }else if (tokens[0].equals("page")){ 91 int index = -1; 92 Texture tex = null; 93 94 for (int i = 1; i < tokens.length; i++){ 95 String token = tokens[i]; 96 if (token.equals("id")){ 97 index = Integer.parseInt(tokens[i + 1]); 98 }else if (token.equals("file")){ 99 String file = tokens[i + 1]; 100 if (file.startsWith("\"")){ 101 file = file.substring(1, file.length()-1); 102 } 103 TextureKey key = new TextureKey(folder + file, true); 104 key.setGenerateMips(false); 105 tex = assetManager.loadTexture(key); 106 tex.setMagFilter(Texture.MagFilter.Bilinear); 107 tex.setMinFilter(Texture.MinFilter.BilinearNoMipMaps); 108 } 109 } 110 // set page 111 if (index >= 0 && tex != null){ 112 Material mat = new Material(spriteMat); 113 mat.setTexture("ColorMap", tex); 114 mat.setBoolean("VertexColor", true); 115 mat.getAdditionalRenderState().setBlendMode(BlendMode.Alpha); 116 matPages[index] = mat; 117 } 118 }else if (tokens[0].equals("char")){ 119 // New BitmapCharacter 120 BitmapCharacter ch = null; 121 for (int i = 1; i < tokens.length; i++){ 122 String token = tokens[i]; 123 if (token.equals("id")){ 124 int index = Integer.parseInt(tokens[i + 1]); 125 ch = new BitmapCharacter(); 126 charSet.addCharacter(index, ch); 127 }else if (token.equals("x")){ 128 ch.setX(Integer.parseInt(tokens[i + 1])); 129 }else if (token.equals("y")){ 130 ch.setY(Integer.parseInt(tokens[i + 1])); 131 }else if (token.equals("width")){ 132 ch.setWidth(Integer.parseInt(tokens[i + 1])); 133 }else if (token.equals("height")){ 134 ch.setHeight(Integer.parseInt(tokens[i + 1])); 135 }else if (token.equals("xoffset")){ 136 ch.setXOffset(Integer.parseInt(tokens[i + 1])); 137 }else if (token.equals("yoffset")){ 138 ch.setYOffset(Integer.parseInt(tokens[i + 1])); 139 }else if (token.equals("xadvance")){ 140 ch.setXAdvance(Integer.parseInt(tokens[i + 1])); 141 } else if (token.equals("page")) { 142 ch.setPage(Integer.parseInt(tokens[i + 1])); 143 } 144 } 145 }else if (tokens[0].equals("kerning")){ 146 // Build kerning list 147 int index = 0; 148 int second = 0; 149 int amount = 0; 150 151 for (int i = 1; i < tokens.length; i++){ 152 if (tokens[i].equals("first")){ 153 index = Integer.parseInt(tokens[i + 1]); 154 }else if (tokens[i].equals("second")){ 155 second = Integer.parseInt(tokens[i + 1]); 156 }else if (tokens[i].equals("amount")){ 157 amount = Integer.parseInt(tokens[i + 1]); 158 } 159 } 160 161 BitmapCharacter ch = charSet.getCharacter(index); 162 ch.addKerning(second, amount); 163 } 164 } 165 return font; 166 } 167 168 public Object load(AssetInfo info) throws IOException { 169 InputStream in = null; 170 try { 171 in = info.openStream(); 172 BitmapFont font = load(info.getManager(), info.getKey().getFolder(), in); 173 return font; 174 } finally { 175 if (in != null){ 176 in.close(); 177 } 178 } 179 } 180 181} 182