Home | History | Annotate | Download | only in font
      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 
     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 
    102     BitmapTextPage(BitmapFont font, boolean arrayBased) {
    103         this(font, arrayBased, 0);
    104     }
    105 
    106     BitmapTextPage(BitmapFont font) {
    107         this(font, false, 0);
    108     }
    109 
    110     Texture2D getTexture() {
    111         return texture;
    112     }
    113 
    114     @Override
    115     public BitmapTextPage clone() {
    116         BitmapTextPage clone = (BitmapTextPage) super.clone();
    117         clone.mesh = mesh.deepClone();
    118         return clone;
    119     }
    120 
    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