/** * Copyright 2010 JogAmp Community. All rights reserved. * * Redistribution and use in source and binary forms, with or without modification, are * permitted provided that the following conditions are met: * * 1. Redistributions of source code must retain the above copyright notice, this list of * conditions and the following disclaimer. * * 2. Redistributions in binary form must reproduce the above copyright notice, this list * of conditions and the following disclaimer in the documentation and/or other materials * provided with the distribution. * * THIS SOFTWARE IS PROVIDED BY JogAmp Community ``AS IS'' AND ANY EXPRESS OR IMPLIED * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL JogAmp Community OR * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * * The views and conclusions contained in the software and documentation are those of the * authors and should not be interpreted as representing official policies, either expressed * or implied, of JogAmp Community. */ package jogamp.graph.curve.text; import java.util.ArrayList; import com.jogamp.graph.font.Font; import com.jogamp.graph.geom.Vertex; import com.jogamp.graph.geom.Triangle; import com.jogamp.graph.geom.Vertex.Factory; import com.jogamp.graph.geom.opengl.SVertex; import javax.media.opengl.GL2ES2; import jogamp.graph.curve.opengl.RegionFactory; import jogamp.graph.font.FontInt; import com.jogamp.graph.curve.OutlineShape; import com.jogamp.graph.curve.Region; import com.jogamp.graph.curve.opengl.GLRegion; import com.jogamp.graph.curve.opengl.RenderState; import com.jogamp.opengl.math.geom.AABBox; import com.jogamp.opengl.util.PMVMatrix; public class GlyphString { /** Static font size for all default font OutlineShape generations via {@link #createString(OutlineShape, Factory, Font, String)}. * <p>The actual font size shall be accomplished by the GL PMV matrix.</p> */ public static final int STATIC_FONT_SIZE = 10; private ArrayList<GlyphShape> glyphs = new ArrayList<GlyphShape>(); private CharSequence str; private String fontname; private GLRegion region; private SVertex origin = new SVertex(); /** * <p>Uses {@link #STATIC_FONT_SIZE}.</p> * <p>No caching is performed.</p> * * @param shape is not null, add all {@link GlyphShape}'s {@link Outline} to this instance. * @param vertexFactory vertex impl factory {@link Factory} * @param font the target {@link Font} * @param str string text * @return the created {@link GlyphString} instance */ public static GlyphString createString(OutlineShape shape, Factory<? extends Vertex> vertexFactory, Font font, String str) { return createString(shape, vertexFactory, font, STATIC_FONT_SIZE, str); } /** * <p>No caching is performed.</p> * * @param shape is not null, add all {@link GlyphShape}'s {@link Outline} to this instance. * @param vertexFactory vertex impl factory {@link Factory} * @param font the target {@link Font} * @param fontSize font size * @param str string text * @return the created {@link GlyphString} instance */ public static GlyphString createString(OutlineShape shape, Factory<? extends Vertex> vertexFactory, Font font, int fontSize, String str) { ArrayList<OutlineShape> shapes = ((FontInt)font).getOutlineShapes(str, fontSize, vertexFactory); GlyphString glyphString = new GlyphString(font.getName(Font.NAME_UNIQUNAME), str); glyphString.createfromOutlineShapes(vertexFactory, shapes); if(null != shape) { for(int i=0; i<glyphString.glyphs.size(); i++) { shape.addOutlineShape(glyphString.glyphs.get(i).getShape()); } } return glyphString; } /** Create a new GlyphString object * @param fontname the name of the font that this String is * associated with * @param str the string object */ public GlyphString(String fontname, CharSequence str){ this.fontname = fontname; this.str = str; } public void addGlyphShape(GlyphShape glyph){ glyphs.add(glyph); } public CharSequence getString(){ return str; } /**Creates the Curve based Glyphs from a list of {@link OutlineShape} * @param vertexFactory vertex impl factory {@link Factory} * @param shapes list of {@link OutlineShape} */ public void createfromOutlineShapes(Factory<? extends Vertex> vertexFactory, ArrayList<OutlineShape> shapes) { final int numGlyps = shapes.size(); for (int index=0;index<numGlyps;index++){ if(shapes.get(index) == null){ continue; } GlyphShape glyphShape = new GlyphShape(vertexFactory, shapes.get(index)); if(glyphShape.getNumVertices() < 3) { continue; } addGlyphShape(glyphShape); } } /** Generate a OGL Region to represent this Object. * @param gl the current gl object * @param rs the current attached RenderState * @param renderModes bit-field of modes, e.g. {@link Region#VARIABLE_CURVE_WEIGHT_BIT}, {@link Region#VBAA_RENDERING_BIT} */ public GLRegion createRegion(GL2ES2 gl, int renderModes){ region = RegionFactory.create(renderModes); // region.setFlipped(true); int numVertices = region.getNumVertices(); for(int i=0; i< glyphs.size(); i++) { final GlyphShape glyph = glyphs.get(i); ArrayList<Triangle> gtris = glyph.triangulate(); region.addTriangles(gtris); final ArrayList<Vertex> gVertices = glyph.getVertices(); for(int j=0; j<gVertices.size(); j++) { final Vertex gVert = gVertices.get(j); gVert.setId(numVertices++); region.addVertex(gVert); } } return region; } /** Generate a Hashcode for this object * @return a string defining the hashcode */ public String getTextHashCode(){ return "" + fontname.hashCode() + str.hashCode(); } /** Render the Object based using the associated Region * previously generated. */ public void renderString3D(GL2ES2 gl) { region.draw(gl, null, 0, 0, null); } /** Render the Object based using the associated Region * previously generated. * @param matrix current {@link PMVMatrix}. * @param rs the RenderState to be used * @param vp_width current screen width * @param vp_height current screen height * @param texWidth desired texture width for multipass-rendering. * The actual used texture-width is written back when mp rendering is enabled, otherwise the store is untouched. */ public void renderString3D(GL2ES2 gl, RenderState rs, int vp_width, int vp_height, int[/*1*/] texWidth) { region.draw(gl, rs, vp_width, vp_height, texWidth); } /** Get the Origin of this GlyphString * @return */ public Vertex getOrigin() { return origin; } /** Destroy the associated OGL objects * @param rs the current attached RenderState */ public void destroy(GL2ES2 gl, RenderState rs) { if(null != gl && null != rs) { region.destroy(gl, rs); region = null; } else if(null != region) { throw new InternalError("destroy called w/o GL context, but has a region"); } glyphs.clear(); } public AABBox getBounds(){ return region.getBounds(); } }