diff options
author | Sven Gothel <[email protected]> | 2014-02-23 06:11:11 +0100 |
---|---|---|
committer | Sven Gothel <[email protected]> | 2014-02-23 06:11:11 +0100 |
commit | f51933f0ebe9ae030c26c066e59a728ce08b8559 (patch) | |
tree | 6723e2343b80a487dba73d51609e2d8fee120b1a /src/jogl/classes/jogamp | |
parent | b68794ae48cf2f133abd9d822f08207cf3404c17 (diff) |
Bug 801: Graph TextRenderer Cleanup Part-1a (unclean)
Remark: This commit is unclean and requires 'Part-1b' due to
merging this commit after more than 2 years!
Graph:
- Use List<OutlineShape> instead of array
allowing more flexible memory managment.
- GLRegion -> Region promotion:
- Region create(List<OutlineShape> outlineShapes, int renderModes)
- Region create(OutlineShape outlineShape, int renderModes)
- Region additions
- void addOutlineShape(OutlineShape shape)
- void addOutlineShapes(List<OutlineShape> shapes)
- RegionRenderer
- draw(..) remove 'position', redundant
-
- Deprecate 'TextRenderer' and 'GlyphString'
Use Region.create(Font.getOutlineShapes(...)) + RegionRenderer instead.
- FontInt -> Font promotion (make public)
- getOutlineShape and getOutlineShapes
- Font.Glyph additions
- 'getID(), hashCode()'
- 'float getScale(float pixelSize)'
- GlyphShape
- Add reference to Glyph allowing GlyphString
to access the font metrics for translation and scaling
- Experimental pre-scale/translation in GlyphString
using default font size and it's metrics
Diffstat (limited to 'src/jogl/classes/jogamp')
9 files changed, 157 insertions, 84 deletions
diff --git a/src/jogl/classes/jogamp/graph/curve/opengl/RegionRendererImpl01.java b/src/jogl/classes/jogamp/graph/curve/opengl/RegionRendererImpl01.java index c34d1cbeb..e6001f4c2 100755 --- a/src/jogl/classes/jogamp/graph/curve/opengl/RegionRendererImpl01.java +++ b/src/jogl/classes/jogamp/graph/curve/opengl/RegionRendererImpl01.java @@ -87,7 +87,7 @@ public class RegionRendererImpl01 extends RegionRenderer { } @Override - protected void drawImpl(GL2ES2 gl, Region region, float[] position, int[] texSize) { + protected void drawImpl(GL2ES2 gl, Region region, int[] texSize) { ((GLRegion)region).draw(gl, rs, vp_width, vp_height, texSize); } } diff --git a/src/jogl/classes/jogamp/graph/curve/opengl/TextRendererImpl01.java b/src/jogl/classes/jogamp/graph/curve/opengl/TextRendererImpl01.java index 158f0240a..f8b1b090b 100644 --- a/src/jogl/classes/jogamp/graph/curve/opengl/TextRendererImpl01.java +++ b/src/jogl/classes/jogamp/graph/curve/opengl/TextRendererImpl01.java @@ -80,7 +80,7 @@ public class TextRendererImpl01 extends TextRenderer { } @Override - public void drawString3D(GL2ES2 gl, Font font, String str, float[] position, int fontSize, int[/*1*/] texSize) { + public void drawString3D(GL2ES2 gl, Font font, String str, int fontSize, int[/*1*/] texSize) { if(!isInitialized()){ throw new GLException("TextRendererImpl01: not initialized!"); } diff --git a/src/jogl/classes/jogamp/graph/curve/tess/CDTriangulator2D.java b/src/jogl/classes/jogamp/graph/curve/tess/CDTriangulator2D.java index 10b6d6847..078f2f332 100644 --- a/src/jogl/classes/jogamp/graph/curve/tess/CDTriangulator2D.java +++ b/src/jogl/classes/jogamp/graph/curve/tess/CDTriangulator2D.java @@ -125,8 +125,9 @@ public class CDTriangulator2D implements Triangulator{ } } Triangle tri = loop.cut(true); - if(tri != null) + if(tri != null) { triangles.add(tri); + } } return triangles; } diff --git a/src/jogl/classes/jogamp/graph/curve/text/GlyphShape.java b/src/jogl/classes/jogamp/graph/curve/text/GlyphShape.java index 578148699..12da966a2 100644 --- a/src/jogl/classes/jogamp/graph/curve/text/GlyphShape.java +++ b/src/jogl/classes/jogamp/graph/curve/text/GlyphShape.java @@ -29,71 +29,84 @@ package jogamp.graph.curve.text; import java.util.ArrayList; +import com.jogamp.graph.font.Font.Glyph; import com.jogamp.graph.geom.Vertex; import com.jogamp.graph.geom.Triangle; import com.jogamp.graph.geom.Vertex.Factory; import com.jogamp.graph.curve.OutlineShape; -import com.jogamp.graph.math.Quaternion; +// import com.jogamp.graph.math.Quaternion; public class GlyphShape { - private Quaternion quat= null; - private OutlineShape shape = null; + // private Quaternion quat= null; + private Glyph glyph; + private OutlineShape shape; /** Create a new Glyph shape * based on Parametric curve control polyline */ public GlyphShape(Vertex.Factory<? extends Vertex> factory){ - shape = new OutlineShape(factory); + this.shape = new OutlineShape(factory); + this.glyph = null; } /** Create a new GlyphShape from a {@link OutlineShape} * @param factory vertex impl factory {@link Factory} * @param shape {@link OutlineShape} representation of the Glyph */ - public GlyphShape(Vertex.Factory<? extends Vertex> factory, OutlineShape shape){ + public GlyphShape(Vertex.Factory<? extends Vertex> factory, Glyph glyph, OutlineShape shape){ this(factory); this.shape = shape; - this.shape.transformOutlines(OutlineShape.VerticesState.QUADRATIC_NURBS); + this.shape.transformOutlines(OutlineShape.VerticesState.QUADRATIC_NURBS); + this.glyph = glyph; + } + + public final void destroy() { + shape.clear(); + shape = null; + glyph = null; } public final Vertex.Factory<? extends Vertex> vertexFactory() { return shape.vertexFactory(); } - public OutlineShape getShape() { + public final Glyph getGlyph() { + return glyph; + } + + public final OutlineShape getShape() { return shape; } - public int getNumVertices() { + public final int getNumVertices() { return shape.getVertices().size(); } /** Get the rotational Quaternion attached to this Shape * @return the Quaternion Object - */ - public Quaternion getQuat() { + public final Quaternion getQuat() { return quat; } - /** Set the Quaternion that shall defien the rotation + * Set the Quaternion that shall defien the rotation * of this shape. * @param quat - */ - public void setQuat(Quaternion quat) { + public final void setQuat(Quaternion quat) { this.quat = quat; } + */ /** Triangluate the glyph shape * @return ArrayList of triangles which define this shape */ - public ArrayList<Triangle> triangulate(){ + public final ArrayList<Triangle> triangulate(){ return shape.triangulate(); } /** Get the list of Vertices of this Object * @return arrayList of Vertices */ - public ArrayList<Vertex> getVertices(){ + public final ArrayList<Vertex> getVertices(){ return shape.getVertices(); } } diff --git a/src/jogl/classes/jogamp/graph/curve/text/GlyphString.java b/src/jogl/classes/jogamp/graph/curve/text/GlyphString.java index f86d02f40..13da49d9e 100644 --- a/src/jogl/classes/jogamp/graph/curve/text/GlyphString.java +++ b/src/jogl/classes/jogamp/graph/curve/text/GlyphString.java @@ -28,6 +28,7 @@ package jogamp.graph.curve.text; import java.util.ArrayList; +import java.util.List; import com.jogamp.graph.font.Font; import com.jogamp.graph.geom.AABBox; @@ -39,7 +40,7 @@ import com.jogamp.graph.geom.opengl.SVertex; import javax.media.opengl.GL2ES2; import jogamp.graph.curve.opengl.RegionFactory; -import jogamp.graph.font.FontInt; +import jogamp.graph.geom.plane.AffineTransform; import com.jogamp.graph.curve.OutlineShape; import com.jogamp.graph.curve.Region; @@ -47,56 +48,61 @@ import com.jogamp.graph.curve.opengl.GLRegion; import com.jogamp.graph.curve.opengl.RenderState; import com.jogamp.opengl.util.PMVMatrix; +/** + * @deprecated use {@link com.jogamp.graph.font.Font#getOutlineShapes(java.util.List, CharSequence, float, Factory)}, + * {@link com.jogamp.graph.curve.Region#create(OutlineShape, int)} + * and a {@link com.jogamp.graph.curve.opengl.RegionRenderer}. + */ 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 final ArrayList<GlyphShape> glyphs = new ArrayList<GlyphShape>(); + private final CharSequence str; + private final String fontname; private GLRegion region; - - private SVertex origin = new SVertex(); + + private final 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 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); + 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 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); - + public static GlyphString createString(OutlineShape shape, Factory<? extends Vertex> vertexFactory, Font font, int fontSize, CharSequence str) { + List<OutlineShape> shapes = font.getOutlineShapes(null, str, fontSize, vertexFactory); + GlyphString glyphString = new GlyphString(font.getName(Font.NAME_UNIQUNAME), str); - glyphString.createfromOutlineShapes(vertexFactory, shapes); + glyphString.createfromOutlineShapes(vertexFactory, font, str, 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 @@ -106,62 +112,77 @@ public class GlyphString { 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} + /**Creates the Curve based Glyphs from a list of {@link OutlineShape} * @param vertexFactory vertex impl factory {@link Factory} - * @param shapes list of {@link OutlineShape} + * @param shapes list of {@link OutlineShape} */ - public void createfromOutlineShapes(Factory<? extends Vertex> vertexFactory, ArrayList<OutlineShape> shapes) { + public void createfromOutlineShapes(Factory<? extends Vertex> vertexFactory, Font font, CharSequence str, List<OutlineShape> shapes) { + if(shapes.size() != str.length()) { + throw new InternalError("XXX"); + } 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)); - + GlyphShape glyphShape = new GlyphShape(vertexFactory, + font.getGlyph(str.charAt(index)), + 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} + * @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); - + float y = 0; + float advanceTotal = 0; + AffineTransform t = new AffineTransform(); + int numVertices = region.getNumVertices(); - + for(int i=0; i< glyphs.size(); i++) { - final GlyphShape glyph = glyphs.get(i); - ArrayList<Triangle> gtris = glyph.triangulate(); + final GlyphShape glyphShape = glyphs.get(i); + Font.Metrics metrics = glyphShape.getGlyph().getFont().getMetrics(); + final float scale = metrics.getScale(STATIC_FONT_SIZE); + t.translate(advanceTotal, y); + t.scale(scale, scale); + + ArrayList<Triangle> gtris = glyphShape.triangulate(); region.addTriangles(gtris); - - final ArrayList<Vertex> gVertices = glyph.getVertices(); + + final ArrayList<Vertex> gVertices = glyphShape.getVertices(); for(int j=0; j<gVertices.size(); j++) { final Vertex gVert = gVertices.get(j); gVert.setId(numVertices++); region.addVertex(gVert); } + + advanceTotal += glyphShape.getGlyph().getAdvance(STATIC_FONT_SIZE, true); } return region; } - - /** Generate a Hashcode for this object + + /** Generate a Hashcode for this object * @return a string defining the hashcode */ public String getTextHashCode(){ @@ -180,15 +201,15 @@ public class GlyphString { * @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. + * @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 + * @return */ public Vertex getOrigin() { return origin; @@ -206,7 +227,7 @@ public class GlyphString { } glyphs.clear(); } - + public AABBox getBounds(){ return region.getBounds(); } diff --git a/src/jogl/classes/jogamp/graph/font/FontInt.java b/src/jogl/classes/jogamp/graph/font/FontInt.java index 20e1ec028..7528a692b 100644 --- a/src/jogl/classes/jogamp/graph/font/FontInt.java +++ b/src/jogl/classes/jogamp/graph/font/FontInt.java @@ -27,14 +27,9 @@ */ package jogamp.graph.font; -import java.util.ArrayList; - import jogamp.graph.geom.plane.Path2D; -import com.jogamp.graph.curve.OutlineShape; import com.jogamp.graph.font.Font; -import com.jogamp.graph.geom.Vertex; -import com.jogamp.graph.geom.Vertex.Factory; public interface FontInt extends Font { @@ -43,5 +38,4 @@ public interface FontInt extends Font { public Path2D getPath(float pixelSize); } - public ArrayList<OutlineShape> getOutlineShapes(CharSequence string, float pixelSize, Factory<? extends Vertex> vertexFactory); } diff --git a/src/jogl/classes/jogamp/graph/font/typecast/TypecastFont.java b/src/jogl/classes/jogamp/graph/font/typecast/TypecastFont.java index 8e465de99..2d13ae32d 100644 --- a/src/jogl/classes/jogamp/graph/font/typecast/TypecastFont.java +++ b/src/jogl/classes/jogamp/graph/font/typecast/TypecastFont.java @@ -27,7 +27,7 @@ */ package jogamp.graph.font.typecast; -import java.util.ArrayList; +import java.util.List; import jogamp.graph.font.FontInt; import jogamp.graph.font.typecast.ot.OTFont; @@ -44,7 +44,6 @@ import com.jogamp.common.util.IntObjectHashMap; import com.jogamp.graph.curve.OutlineShape; import com.jogamp.graph.font.Font; import com.jogamp.graph.font.FontFactory; -import com.jogamp.graph.font.Font.Glyph; import com.jogamp.graph.geom.AABBox; import com.jogamp.graph.geom.Vertex; import com.jogamp.graph.geom.Vertex.Factory; @@ -148,25 +147,31 @@ class TypecastFont implements FontInt { char2Glyph = new IntObjectHashMap(cmapentries + cmapentries/4); } + @Override public StringBuilder getName(StringBuilder sb, int nameIndex) { return font.getName(nameIndex, sb); } + @Override public String getName(int nameIndex) { return getName(null, nameIndex).toString(); } + @Override public StringBuilder getAllNames(StringBuilder sb, String separator) { return font.getAllNames(sb, separator); } + @Override public StringBuilder getFullFamilyName(StringBuilder sb) { sb = getName(sb, Font.NAME_FAMILY).append("-"); getName(sb, Font.NAME_SUBFAMILY); return sb; } + @Override public float getAdvanceWidth(int i, float pixelSize) { return font.getHmtxTable().getAdvanceWidth(i) * metrics.getScale(pixelSize); } + @Override public Metrics getMetrics() { if (metrics == null) { metrics = new TypecastHMetrics(this); @@ -174,6 +179,7 @@ class TypecastFont implements FontInt { return metrics; } + @Override public Glyph getGlyph(char symbol) { TypecastGlyph result = (TypecastGlyph) char2Glyph.get(symbol); if (null == result) { @@ -218,12 +224,19 @@ class TypecastFont implements FontInt { } return result; } - - public ArrayList<OutlineShape> getOutlineShapes(CharSequence string, float pixelSize, Factory<? extends Vertex> vertexFactory) { + + @Override + public OutlineShape getOutlineShape(Glyph glyph, Factory<? extends Vertex> vertexFactory) { + return TypecastRenderer.getOutlineShape(this, glyph, vertexFactory); + } + + @Override + public List<OutlineShape> getOutlineShapes(List<OutlineShape> shapes, CharSequence string, float pixelSize, Factory<? extends Vertex> vertexFactory) { AffineTransform transform = new AffineTransform(vertexFactory); - return TypecastRenderer.getOutlineShapes(this, string, pixelSize, transform, vertexFactory); + return TypecastRenderer.getOutlineShapes(shapes, this, string, pixelSize, transform, vertexFactory); } + @Override public float getStringWidth(CharSequence string, float pixelSize) { float width = 0; final int len = string.length(); @@ -241,6 +254,7 @@ class TypecastFont implements FontInt { return (int)(width + 0.5f); } + @Override public float getStringHeight(CharSequence string, float pixelSize) { int height = 0; @@ -257,6 +271,7 @@ class TypecastFont implements FontInt { return height; } + @Override public AABBox getStringBounds(CharSequence string, float pixelSize) { if (string == null) { return new AABBox(); @@ -287,14 +302,17 @@ class TypecastFont implements FontInt { return new AABBox(0, 0, 0, totalWidth, totalHeight,0); } + @Override final public int getNumGlyphs() { return font.getNumGlyphs(); } + @Override public boolean isPrintableChar( char c ) { return FontFactory.isPrintableChar(c); } + @Override public String toString() { return getFullFamilyName(null).toString(); } diff --git a/src/jogl/classes/jogamp/graph/font/typecast/TypecastGlyph.java b/src/jogl/classes/jogamp/graph/font/typecast/TypecastGlyph.java index a1f1a3292..cdaa2df7e 100644 --- a/src/jogl/classes/jogamp/graph/font/typecast/TypecastGlyph.java +++ b/src/jogl/classes/jogamp/graph/font/typecast/TypecastGlyph.java @@ -228,5 +228,11 @@ public class TypecastGlyph implements FontInt.GlyphInt { this.pathSized = AffineTransform.getScaleInstance(null, size, size).createTransformedShape(getPath()); } return this.pathSized; + } + + public int hashCode() { + // 31 * x == (x << 5) - x + int hash = 31 + font.getName(Font.NAME_UNIQUNAME).hashCode(); + return ((hash << 5) - hash) + id; } } diff --git a/src/jogl/classes/jogamp/graph/font/typecast/TypecastRenderer.java b/src/jogl/classes/jogamp/graph/font/typecast/TypecastRenderer.java index f155345aa..d62f19cb7 100644 --- a/src/jogl/classes/jogamp/graph/font/typecast/TypecastRenderer.java +++ b/src/jogl/classes/jogamp/graph/font/typecast/TypecastRenderer.java @@ -28,6 +28,7 @@ package jogamp.graph.font.typecast; import java.util.ArrayList; +import java.util.List; import jogamp.graph.font.FontInt.GlyphInt; import jogamp.graph.font.typecast.ot.OTGlyph; @@ -64,9 +65,10 @@ public class TypecastRenderer { } AffineTransform t = new AffineTransform(); + final int len = string.length(); float advanceY = lineGap - descent + ascent; float y = 0; - for (int i=0; i<string.length(); i++) + for (int i=0; i<len; i++) { p[i] = new Path2D(); p[i].reset(); @@ -75,26 +77,44 @@ public class TypecastRenderer { if (character == '\n') { y += advanceY; advanceTotal = 0; - continue; } else if (character == ' ') { advanceTotal += font.getAdvanceWidth(Glyph.ID_SPACE, pixelSize); - continue; - } - Glyph glyph = font.getGlyph(character); - Path2D gp = ((GlyphInt)glyph).getPath(); - float scale = metrics.getScale(pixelSize); - t.translate(advanceTotal, y); - t.scale(scale, scale); - p[i].append(gp.iterator(t), false); - advanceTotal += glyph.getAdvance(pixelSize, true); + } else { + final Glyph glyph = font.getGlyph(character); + final Path2D gp = ((GlyphInt)glyph).getPath(); + final float scale = metrics.getScale(pixelSize); + t.translate(advanceTotal, y); + t.scale(scale, scale); + p[i].append(gp.iterator(t), false); + advanceTotal += glyph.getAdvance(pixelSize, true); + } } } - public static ArrayList<OutlineShape> getOutlineShapes(TypecastFont font, CharSequence string, float pixelSize, AffineTransform transform, Factory<? extends Vertex> vertexFactory) { + public static OutlineShape getOutlineShape(TypecastFont font, Glyph glyph, Factory<? extends Vertex> vertexFactory) { + Path2D path = ((GlyphInt)glyph).getPath(); + AffineTransform transform = new AffineTransform(vertexFactory); + OutlineShape shape = new OutlineShape(vertexFactory); + + PathIterator iterator = path.iterator(transform); + if(null != iterator){ + while(!iterator.isDone()){ + float[] coords = new float[6]; + int segmentType = iterator.currentSegment(coords); + addPathVertexToOutline(shape, vertexFactory, coords, segmentType); + iterator.next(); + } + } + return shape; + } + + public static List<OutlineShape> getOutlineShapes(List<OutlineShape> shapes, TypecastFont font, CharSequence string, float pixelSize, AffineTransform transform, Factory<? extends Vertex> vertexFactory) { Path2D[] paths = new Path2D[string.length()]; getPaths(font, string, pixelSize, transform, paths); - ArrayList<OutlineShape> shapes = new ArrayList<OutlineShape>(); + if(null == shapes) { + shapes = new ArrayList<OutlineShape>(); + } final int numGlyps = paths.length; for (int index=0;index<numGlyps;index++) { if(paths[index] == null){ |