• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 package com.jme3.font;
33 
34 import com.jme3.material.Material;
35 import com.jme3.scene.Geometry;
36 import com.jme3.scene.Mesh;
37 import com.jme3.scene.VertexBuffer;
38 import com.jme3.scene.VertexBuffer.Type;
39 import com.jme3.texture.Texture2D;
40 import com.jme3.util.BufferUtils;
41 import java.nio.ByteBuffer;
42 import java.nio.FloatBuffer;
43 import java.nio.ShortBuffer;
44 import java.util.LinkedList;
45 
46 /**
47  * One page per BitmapText Font Texture.
48  * @author Lim, YongHoon
49  */
50 class BitmapTextPage extends Geometry {
51 
52     private final float[] pos;
53     private final float[] tc;
54     private final short[] idx;
55     private final byte[] color;
56     private final int page;
57     private final Texture2D texture;
58     private final LinkedList<LetterQuad> pageQuads = new LinkedList<LetterQuad>();
59 
BitmapTextPage(BitmapFont font, boolean arrayBased, int page)60     BitmapTextPage(BitmapFont font, boolean arrayBased, int page) {
61         super("BitmapFont", new Mesh());
62 
63         if (font == null) {
64             throw new NullPointerException("'font' cannot be null.");
65         }
66 
67         this.page = page;
68 
69         Material mat = font.getPage(page);
70         if (mat == null) {
71             throw new IllegalStateException("The font's texture was not found!");
72         }
73 
74         setMaterial(mat);
75         this.texture = (Texture2D) mat.getTextureParam("ColorMap").getTextureValue();
76 
77         // initialize buffers
78         Mesh m = getMesh();
79         m.setBuffer(Type.Position, 3, new float[0]);
80         m.setBuffer(Type.TexCoord, 2, new float[0]);
81         m.setBuffer(Type.Color, 4, new byte[0]);
82         m.setBuffer(Type.Index, 3, new short[0]);
83 
84         // scale colors from 0 - 255 range into 0 - 1
85         m.getBuffer(Type.Color).setNormalized(true);
86 
87         arrayBased = true;
88 
89         if (arrayBased) {
90             pos = new float[4 * 3];  // 4 verticies * 3 floats
91             tc = new float[4 * 2];  // 4 verticies * 2 floats
92             idx = new short[2 * 3];  // 2 triangles * 3 indices
93             color = new byte[4 * 4];   // 4 verticies * 4 bytes
94         } else {
95             pos = null;
96             tc = null;
97             idx = null;
98             color = null;
99         }
100     }
101 
BitmapTextPage(BitmapFont font, boolean arrayBased)102     BitmapTextPage(BitmapFont font, boolean arrayBased) {
103         this(font, arrayBased, 0);
104     }
105 
BitmapTextPage(BitmapFont font)106     BitmapTextPage(BitmapFont font) {
107         this(font, false, 0);
108     }
109 
getTexture()110     Texture2D getTexture() {
111         return texture;
112     }
113 
114     @Override
clone()115     public BitmapTextPage clone() {
116         BitmapTextPage clone = (BitmapTextPage) super.clone();
117         clone.mesh = mesh.deepClone();
118         return clone;
119     }
120 
assemble(Letters quads)121     void assemble(Letters quads) {
122         pageQuads.clear();
123         quads.rewind();
124 
125         while (quads.nextCharacter()) {
126             if (quads.isPrintable()) {
127                 if (quads.getCharacterSetPage() == page) {
128                     pageQuads.add(quads.getQuad());
129                 }
130             }
131         }
132 
133         Mesh m = getMesh();
134         int vertCount = pageQuads.size() * 4;
135         int triCount = pageQuads.size() * 2;
136 
137         VertexBuffer pb = m.getBuffer(Type.Position);
138         VertexBuffer tb = m.getBuffer(Type.TexCoord);
139         VertexBuffer ib = m.getBuffer(Type.Index);
140         VertexBuffer cb = m.getBuffer(Type.Color);
141 
142         FloatBuffer fpb = (FloatBuffer) pb.getData();
143         FloatBuffer ftb = (FloatBuffer) tb.getData();
144         ShortBuffer sib = (ShortBuffer) ib.getData();
145         ByteBuffer bcb = (ByteBuffer) cb.getData();
146 
147         // increase capacity of buffers as needed
148         fpb.rewind();
149         fpb = BufferUtils.ensureLargeEnough(fpb, vertCount * 3);
150         fpb.limit(vertCount * 3);
151         pb.updateData(fpb);
152 
153         ftb.rewind();
154         ftb = BufferUtils.ensureLargeEnough(ftb, vertCount * 2);
155         ftb.limit(vertCount * 2);
156         tb.updateData(ftb);
157 
158         bcb.rewind();
159         bcb = BufferUtils.ensureLargeEnough(bcb, vertCount * 4);
160         bcb.limit(vertCount * 4);
161         cb.updateData(bcb);
162 
163         sib.rewind();
164         sib = BufferUtils.ensureLargeEnough(sib, triCount * 3);
165         sib.limit(triCount * 3);
166         ib.updateData(sib);
167 
168         m.updateCounts();
169 
170         // go for each quad and append it to the buffers
171         if (pos != null) {
172             for (int i = 0; i < pageQuads.size(); i++) {
173                 LetterQuad fq = pageQuads.get(i);
174                 fq.storeToArrays(pos, tc, idx, color, i);
175                 fpb.put(pos);
176                 ftb.put(tc);
177                 sib.put(idx);
178                 bcb.put(color);
179             }
180         } else {
181             for (int i = 0; i < pageQuads.size(); i++) {
182                 LetterQuad fq = pageQuads.get(i);
183                 fq.appendPositions(fpb);
184                 fq.appendTexCoords(ftb);
185                 fq.appendIndices(sib, i);
186                 fq.appendColors(bcb);
187             }
188         }
189 
190         fpb.rewind();
191         ftb.rewind();
192         sib.rewind();
193         bcb.rewind();
194 
195         updateModelBound();
196     }
197 }
198