aboutsummaryrefslogtreecommitdiffstats
path: root/src/jogl/classes
diff options
context:
space:
mode:
authorSven Gothel <[email protected]>2011-06-08 06:00:30 +0200
committerSven Gothel <[email protected]>2011-06-08 06:00:30 +0200
commitf6bd208d8ef15769e13cb959e614349fd1e7cae1 (patch)
tree1761440a136814803361efc79a6f7c35c844a603 /src/jogl/classes
parent138ddda3f346db0f1d8b4bac1760d415e7dc3d70 (diff)
parent820fd3f4e45cfa79e94fad385eb47ff26a5fea2b (diff)
Merge remote-tracking branch 'rsantina/master'
Diffstat (limited to 'src/jogl/classes')
-rwxr-xr-xsrc/jogl/classes/com/jogamp/graph/curve/OutlineShape.java1054
-rw-r--r--src/jogl/classes/com/jogamp/graph/curve/Region.java14
-rw-r--r--src/jogl/classes/com/jogamp/graph/curve/opengl/RegionRenderer.java2
-rw-r--r--src/jogl/classes/com/jogamp/graph/curve/opengl/TextRenderer.java13
-rw-r--r--src/jogl/classes/com/jogamp/graph/curve/tess/Triangulation.java44
-rw-r--r--src/jogl/classes/com/jogamp/graph/curve/tess/Triangulator.java69
-rw-r--r--src/jogl/classes/com/jogamp/graph/geom/Outline.java6
-rwxr-xr-xsrc/jogl/classes/jogamp/graph/curve/opengl/RegionFactory.java6
-rw-r--r--src/jogl/classes/jogamp/graph/curve/tess/CDTriangulator2D.java (renamed from src/jogl/classes/com/jogamp/graph/curve/tess/CDTriangulator2D.java)20
-rw-r--r--src/jogl/classes/jogamp/graph/curve/text/GlyphShape.java64
-rw-r--r--src/jogl/classes/jogamp/graph/curve/text/GlyphString.java42
-rw-r--r--src/jogl/classes/jogamp/graph/font/FontInt.java9
-rw-r--r--src/jogl/classes/jogamp/graph/font/typecast/TypecastFont.java12
-rw-r--r--src/jogl/classes/jogamp/graph/font/typecast/TypecastRenderer.java61
14 files changed, 766 insertions, 650 deletions
diff --git a/src/jogl/classes/com/jogamp/graph/curve/OutlineShape.java b/src/jogl/classes/com/jogamp/graph/curve/OutlineShape.java
index 5b94d6bda..e4f80ab76 100755
--- a/src/jogl/classes/com/jogamp/graph/curve/OutlineShape.java
+++ b/src/jogl/classes/com/jogamp/graph/curve/OutlineShape.java
@@ -1,523 +1,531 @@
-/**
- * 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 com.jogamp.graph.curve;
-
-import java.util.ArrayList;
-import java.util.Collections;
-
-
-import com.jogamp.graph.geom.AABBox;
-import com.jogamp.graph.geom.Outline;
-import com.jogamp.graph.geom.Triangle;
-import com.jogamp.graph.geom.Vertex;
-import com.jogamp.graph.math.VectorUtil;
-
-import com.jogamp.graph.curve.tess.CDTriangulator2D;
-
-/** A Generic shape objects which is defined by a list of Outlines.
- * This Shape can be transformed to Triangulations.
- * The list of triangles generated are render-able by a Region object.
- * The triangulation produced by this Shape will define the
- * closed region defined by the outlines.
- *
- * One or more OutlineShape Object can be associated to a region
- * this is left as a high-level representation of the Objects. For
- * optimizations, flexibility requirements for future features.
- *
- * <br><br>
- * Example to creating an Outline Shape:
- * <pre>
- addVertex(...)
- addVertex(...)
- addVertex(...)
- addEmptyOutline()
- addVertex(...)
- addVertex(...)
- addVertex(...)
- * </pre>
- *
- * The above will create two outlines each with three vertices. By adding these two outlines to
- * the OutlineShape, we are stating that the combination of the two outlines represent the shape.
- * <br>
- *
- * To specify that the shape is curved at a region, the on-curve flag should be set to false
- * for the vertex that is in the middle of the curved region (if the curved region is defined by 3
- * vertices (quadratic curve).
- * <br>
- * In case the curved region is defined by 4 or more vertices the middle vertices should both have
- * the on-curve flag set to false.
- *
- * <br>Example: <br>
- * <pre>
- addVertex(0,0, true);
- addVertex(0,1, false);
- addVertex(1,1, false);
- addVertex(1,0, true);
- * </pre>
- *
- * The above snippet defines a cubic nurbs curve where (0,1 and 1,1)
- * do not belong to the final rendered shape.
- *
- * <i>Implementation Notes:</i><br>
- * <ul>
- * <li> The first vertex of any outline belonging to the shape should be on-curve</li>
- * <li> Intersections between off-curved parts of the outline is not handled</li>
- * </ul>
- *
- * @see Outline
- * @see Region
- */
-public class OutlineShape implements Comparable<OutlineShape> {
- /**
- * Outline's vertices have undefined state until transformed.
- */
- public enum VerticesState {
- UNDEFINED(0), QUADRATIC_NURBS(1);
-
- public final int state;
-
- VerticesState(int state){
- this.state = state;
- }
- }
-
- public static final int DIRTY_BOUNDS = 1 << 0;
-
- private final Vertex.Factory<? extends Vertex> vertexFactory;
- private VerticesState outlineState;
-
- /** The list of {@link Outline}s that are part of this
- * outline shape.
- */
- private ArrayList<Outline> outlines;
- private AABBox bbox;
-
- /** dirty bits DIRTY_BOUNDS */
- private int dirtyBits;
-
- /** Create a new Outline based Shape
- */
- public OutlineShape(Vertex.Factory<? extends Vertex> factory) {
- this.vertexFactory = factory;
- this.outlines = new ArrayList<Outline>(3);
- this.outlines.add(new Outline());
- this.outlineState = VerticesState.UNDEFINED;
- this.bbox = new AABBox();
- this.dirtyBits = 0;
- }
-
- /** Clears all data and reset all states as if this instance was newly created */
- public void clear() {
- outlines.clear();
- outlines.add(new Outline());
- outlineState = VerticesState.UNDEFINED;
- bbox.reset();
- dirtyBits = 0;
- }
-
- /** Returns the associated vertex factory of this outline shape
- * @return Vertex.Factory object
- */
- public final Vertex.Factory<? extends Vertex> vertexFactory() { return vertexFactory; }
-
- public int getOutlineNumber() {
- return outlines.size();
- }
-
- /** Add a new empty {@link Outline}
- * to the end of this shape's outline list.
- * <p>If the {@link #getLastOutline()} is empty already, no new one will be added.</p>
- *
- * After a call to this function all new vertices added
- * will belong to the new outline
- */
- public void addEmptyOutline(){
- if( !getLastOutline().isEmpty() ) {
- outlines.add(new Outline());
- }
- }
-
- /** Appends the {@link Outline} element to the end,
- * ensuring a clean tail.
- *
- * <p>A clean tail is ensured, no double empty Outlines are produced
- * and a pre-existing empty outline will be replaced with the given one. </p>
- *
- * @param outline Outline object to be added
- * @throws NullPointerException if the {@link Outline} element is null
- */
- public void addOutline(Outline outline) throws NullPointerException {
- addOutline(outlines.size(), outline);
- }
-
- /** Insert the {@link Outline} element at the given {@code position}.
- *
- * <p>If the {@code position} indicates the end of this list,
- * a clean tail is ensured, no double empty Outlines are produced
- * and a pre-existing empty outline will be replaced with the given one. </p>
- *
- * @param position of the added Outline
- * @param outline Outline object to be added
- * @throws NullPointerException if the {@link Outline} element is null
- * @throws IndexOutOfBoundsException if position is out of range (position < 0 || position > getOutlineNumber())
- */
- public void addOutline(int position, Outline outline) throws NullPointerException, IndexOutOfBoundsException {
- if (null == outline) {
- throw new NullPointerException("outline is null");
- }
- if( outlines.size() == position ) {
- final Outline lastOutline = getLastOutline();
- if( outline.isEmpty() && lastOutline.isEmpty() ) {
- return;
- }
- if( lastOutline.isEmpty() ) {
- outlines.set(position-1, outline);
- if( 0 == ( dirtyBits & DIRTY_BOUNDS ) ) {
- bbox.resize(outline.getBounds());
- }
- return;
- }
- }
- outlines.add(position, outline);
- if( 0 == ( dirtyBits & DIRTY_BOUNDS ) ) {
- bbox.resize(outline.getBounds());
- }
- }
-
- /** Insert the {@link OutlineShape} elements of type {@link Outline}, .. at the end of this shape,
- * using {@link #addOutline(Outline)} for each element.
- * <p>Closes the current last outline via {@link #closeLastOutline()} before adding the new ones.</p>
- * @param outlineShape OutlineShape elements to be added.
- * @throws NullPointerException if the {@link OutlineShape} is null
- * @throws IndexOutOfBoundsException if position is out of range (position < 0 || position > getOutlineNumber())
- */
- public void addOutlineShape(OutlineShape outlineShape) throws NullPointerException {
- if (null == outlineShape) {
- throw new NullPointerException("OutlineShape is null");
- }
- closeLastOutline();
- for(int i=0; i<outlineShape.getOutlineNumber(); i++) {
- addOutline(outlineShape.getOutline(i));
- }
- }
-
- /** Replaces the {@link Outline} element at the given {@code position}.
- * <p>Sets the bounding box dirty, hence a next call to {@link #getBounds()} will validate it.</p>
- *
- * @param position of the replaced Outline
- * @param outline replacement Outline object
- * @throws NullPointerException if the {@link Outline} element is null
- * @throws IndexOutOfBoundsException if position is out of range (position < 0 || position >= getOutlineNumber())
- */
- public void setOutline(int position, Outline outline) throws NullPointerException, IndexOutOfBoundsException {
- if (null == outline) {
- throw new NullPointerException("outline is null");
- }
- outlines.set(position, outline);
- dirtyBits |= DIRTY_BOUNDS;
- }
-
- /** Removes the {@link Outline} element at the given {@code position}.
- * <p>Sets the bounding box dirty, hence a next call to {@link #getBounds()} will validate it.</p>
- *
- * @param position of the to be removed Outline
- * @throws IndexOutOfBoundsException if position is out of range (position < 0 || position >= getOutlineNumber())
- */
- public final Outline removeOutline(int position) throws IndexOutOfBoundsException {
- dirtyBits |= DIRTY_BOUNDS;
- return outlines.remove(position);
- }
-
- /** Get the last added outline to the list
- * of outlines that define the shape
- * @return the last outline
- */
- public final Outline getLastOutline(){
- return outlines.get(outlines.size()-1);
- }
-
- /** @return the {@code Outline} at {@code position}
- * @throws IndexOutOfBoundsException if position is out of range (position < 0 || position >= getOutlineNumber())
- */
- public Outline getOutline(int position) throws IndexOutOfBoundsException {
- return outlines.get(position);
- }
-
- /** Adds a vertex to the last open outline in the
- * shape.
- * @param v the vertex to be added to the OutlineShape
- */
- public final void addVertex(Vertex v){
- final Outline lo = getLastOutline();
- lo.addVertex(v);
- if( 0 == ( dirtyBits & DIRTY_BOUNDS ) ) {
- bbox.resize(lo.getBounds());
- }
- }
-
- /** Adds a vertex to the last open outline in the shape.
- * at {@code position}
- * @param position indx at which the vertex will be added
- * @param v the vertex to be added to the OutlineShape
- */
- public final void addVertex(int position, Vertex v){
- final Outline lo = getLastOutline();
- lo.addVertex(position, v);
- if( 0 == ( dirtyBits & DIRTY_BOUNDS ) ) {
- bbox.resize(lo.getBounds());
- }
- }
-
- /** Add a 2D {@link Vertex} to the last outline by defining the coordniate attribute
- * of the vertex. The 2D vertex will be represented as Z=0.
- *
- * @param x the x coordinate
- * @param y the y coordniate
- * @param onCurve flag if this vertex is on the final curve or defines a curved region
- * of the shape around this vertex.
- */
- public final void addVertex(float x, float y, boolean onCurve) {
- addVertex(vertexFactory.create(x, y, 0f, onCurve));
- }
-
- /** Add a 3D {@link Vertex} to the last outline by defining the coordniate attribute
- * of the vertex.
- * @param x the x coordinate
- * @param y the y coordinate
- * @param z the z coordinate
- * @param onCurve flag if this vertex is on the final curve or defines a curved region
- * of the shape around this vertex.
- */
- public final void addVertex(float x, float y, float z, boolean onCurve) {
- addVertex(vertexFactory.create(x, y, z, onCurve));
- }
-
- /** Add a vertex to the last outline by passing a float array and specifying the
- * offset and length in which. The attributes of the vertex are located.
- * The attributes should be continuous (stride = 0).
- * Attributes which value are not set (when length less than 3)
- * are set implicitly to zero.
- * @param coordsBuffer the coordinate array where the vertex attributes are to be picked from
- * @param offset the offset in the buffer to the x coordinate
- * @param length the number of attributes to pick from the buffer (maximum 3)
- * @param onCurve flag if this vertex is on the final curve or defines a curved region
- * of the shape around this vertex.
- */
- public final void addVertex(float[] coordsBuffer, int offset, int length, boolean onCurve) {
- addVertex(vertexFactory.create(coordsBuffer, offset, length, onCurve));
- }
-
- /** Closes the last outline in the shape.
- * <p>If last vertex is not equal to first vertex.
- * A new temp vertex is added at the end which
- * is equal to the first.</p>
- */
- public void closeLastOutline(){
- getLastOutline().setClosed(true);
- }
-
- /**
- * @return the outline's vertices state, {@link OutlineShape.VerticesState}
- */
- public final VerticesState getOutlineState() {
- return outlineState;
- }
-
- /** Ensure the outlines represent
- * the specified destinationType.
- *
- * @param destinationType the target outline's vertices state. Currently only {@link OutlineShape.VerticesState#QUADRATIC_NURBS} are supported.
- */
- public void transformOutlines(VerticesState destinationType){
- if(outlineState != destinationType){
- if(destinationType == VerticesState.QUADRATIC_NURBS){
- transformOutlines2Quadratic();
- } else {
- throw new IllegalStateException("destinationType "+destinationType.name()+" not supported (currently "+outlineState.name()+")");
- }
- }
- }
-
- private void transformOutlines2Quadratic(){
- final int count = getOutlineNumber();
- for (int cc = 0; cc < count; cc++){
- final Outline outline = getOutline(cc);
- int vertexNumberLessOne = outline.getVertexNumber() - 1;
- for(int i=0; i < vertexNumberLessOne; i++) {
- final Vertex currentVertex = outline.getVertex(i);
- final Vertex nextVertex = outline.getVertex(i+1);
- if ( !currentVertex.isOnCurve() && !nextVertex.isOnCurve() ) {
- final float[] newCoords = VectorUtil.mid(currentVertex.getCoord(), nextVertex.getCoord());
- final Vertex v = vertexFactory.create(newCoords, 0, 3, true);
- v.setOnCurve(true);
- i++;
- vertexNumberLessOne++;
- outline.addVertex(i, v);
- }
- }
- // Cut off last vertex (which is on-curve)
- // FIXME: original code skipped the last element (it _is_ unrelated to the xform above)
- // FIXME: understand why the last element produces artifacts in rendering
- if( vertexNumberLessOne >= 0 ) {
- outline.removeVertex(vertexNumberLessOne);
- }
- }
- outlineState = VerticesState.QUADRATIC_NURBS;
- }
-
- private void generateVertexIds(){
- int maxVertexId = 0;
- for(int i=0; i<outlines.size(); i++) {
- final ArrayList<Vertex> vertices = outlines.get(i).getVertices();
- for(int pos=0; pos<vertices.size(); pos++) {
- Vertex vert = vertices.get(pos);
- vert.setId(maxVertexId);
- maxVertexId++;
- }
- }
- }
-
- /** @return the list of concatenated vertices associated with all
- * {@code Outline}s of this object
- */
- public ArrayList<Vertex> getVertices() {
- ArrayList<Vertex> vertices = new ArrayList<Vertex>();
- for(int i=0; i<outlines.size(); i++) {
- vertices.addAll(outlines.get(i).getVertices());
- }
- return vertices;
- }
-
- /**
- * Triangulate the {@link OutlineShape} generating a list of triangles
- * @return an arraylist of triangles representing the filled region
- * which is produced by the combination of the outlines
- */
- public ArrayList<Triangle> triangulate() {
- if(outlines.size() == 0){
- return null;
- }
- sortOutlines();
- generateVertexIds();
-
- CDTriangulator2D triangulator2d = new CDTriangulator2D();
- for(int index = 0; index<outlines.size(); index++) {
- triangulator2d.addCurve(outlines.get(index));
- }
-
- ArrayList<Triangle> triangles = triangulator2d.generateTriangulation();
- triangulator2d.reset();
-
- return triangles;
- }
-
- /** Sort the outlines from large
- * to small depending on the AABox
- */
- private void sortOutlines() {
- Collections.sort(outlines);
- Collections.reverse(outlines);
- }
-
- /** Compare two outline shapes with Bounding Box area
- * as criteria.
- * @see java.lang.Comparable#compareTo(java.lang.Object)
- */
- public final int compareTo(OutlineShape outline) {
- float size = getBounds().getSize();
- float newSize = outline.getBounds().getSize();
- if(size < newSize){
- return -1;
- }
- else if(size > newSize){
- return 1;
- }
- return 0;
- }
-
- private final void validateBoundingBox() {
- dirtyBits &= ~DIRTY_BOUNDS;
- bbox.reset();
- for (int i=0; i<outlines.size(); i++) {
- bbox.resize(outlines.get(i).getBounds());
- }
- }
-
- public final AABBox getBounds() {
- if( 0 == ( dirtyBits & DIRTY_BOUNDS ) ) {
- validateBoundingBox();
- }
- return bbox;
- }
-
- /**
- * @param obj the Object to compare this OutlineShape with
- * @return true if {@code obj} is an OutlineShape, not null,
- * same outlineState, equal bounds and equal outlines in the same order
- */
- public boolean equals(Object obj) {
- if( obj == this) {
- return true;
- }
- if( null == obj || !(obj instanceof OutlineShape) ) {
- return false;
- }
- final OutlineShape o = (OutlineShape) obj;
- if(getOutlineState() != o.getOutlineState()) {
- return false;
- }
- if(getOutlineNumber() != o.getOutlineNumber()) {
- return false;
- }
- if( !getBounds().equals( o.getBounds() ) ) {
- return false;
- }
- for (int i=getOutlineNumber()-1; i>=0; i--) {
- if( ! getOutline(i).equals( o.getOutline(i) ) ) {
- return false;
- }
- }
- return true;
- }
-
- /**
- * @return deep clone of this OutlineShape w/o Region
- */
- public OutlineShape clone() {
- OutlineShape o;
- try {
- o = (OutlineShape) super.clone();
- } catch (CloneNotSupportedException e) { throw new InternalError(); }
- o.bbox = bbox.clone();
- o.outlines = new ArrayList<Outline>(outlines.size());
- for(int i=0; i<outlines.size(); i++) {
- o.outlines.add(outlines.get(i).clone());
- }
- return o;
- }
-}
+/**
+ * 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 com.jogamp.graph.curve;
+
+import java.util.ArrayList;
+import java.util.Collections;
+
+import com.jogamp.graph.curve.tess.Triangulation;
+import com.jogamp.graph.curve.tess.Triangulator;
+import com.jogamp.graph.geom.AABBox;
+import com.jogamp.graph.geom.Outline;
+import com.jogamp.graph.geom.Triangle;
+import com.jogamp.graph.geom.Vertex;
+import com.jogamp.graph.math.VectorUtil;
+
+
+/** A Generic shape objects which is defined by a list of Outlines.
+ * This Shape can be transformed to Triangulations.
+ * The list of triangles generated are render-able by a Region object.
+ * The triangulation produced by this Shape will define the
+ * closed region defined by the outlines.
+ *
+ * One or more OutlineShape Object can be associated to a region
+ * this is left as a high-level representation of the Objects. For
+ * optimizations, flexibility requirements for future features.
+ *
+ * <br><br>
+ * Example to creating an Outline Shape:
+ * <pre>
+ addVertex(...)
+ addVertex(...)
+ addVertex(...)
+ addEmptyOutline()
+ addVertex(...)
+ addVertex(...)
+ addVertex(...)
+ * </pre>
+ *
+ * The above will create two outlines each with three vertices. By adding these two outlines to
+ * the OutlineShape, we are stating that the combination of the two outlines represent the shape.
+ * <br>
+ *
+ * To specify that the shape is curved at a region, the on-curve flag should be set to false
+ * for the vertex that is in the middle of the curved region (if the curved region is defined by 3
+ * vertices (quadratic curve).
+ * <br>
+ * In case the curved region is defined by 4 or more vertices the middle vertices should both have
+ * the on-curve flag set to false.
+ *
+ * <br>Example: <br>
+ * <pre>
+ addVertex(0,0, true);
+ addVertex(0,1, false);
+ addVertex(1,1, false);
+ addVertex(1,0, true);
+ * </pre>
+ *
+ * The above snippet defines a cubic nurbs curve where (0,1 and 1,1)
+ * do not belong to the final rendered shape.
+ *
+ * <i>Implementation Notes:</i><br>
+ * <ul>
+ * <li> The first vertex of any outline belonging to the shape should be on-curve</li>
+ * <li> Intersections between off-curved parts of the outline is not handled</li>
+ * </ul>
+ *
+ * @see Outline
+ * @see Region
+ */
+public class OutlineShape implements Comparable<OutlineShape> {
+ /**
+ * Outline's vertices have undefined state until transformed.
+ */
+ public enum VerticesState {
+ UNDEFINED(0), QUADRATIC_NURBS(1);
+
+ public final int state;
+
+ VerticesState(int state){
+ this.state = state;
+ }
+ }
+
+ public static final int DIRTY_BOUNDS = 1 << 0;
+
+ private final Vertex.Factory<? extends Vertex> vertexFactory;
+ private VerticesState outlineState;
+
+ /** The list of {@link Outline}s that are part of this
+ * outline shape.
+ */
+ private ArrayList<Outline> outlines;
+ private AABBox bbox;
+
+ /** dirty bits DIRTY_BOUNDS */
+ private int dirtyBits;
+
+ /** Create a new Outline based Shape
+ */
+ public OutlineShape(Vertex.Factory<? extends Vertex> factory) {
+ this.vertexFactory = factory;
+ this.outlines = new ArrayList<Outline>(3);
+ this.outlines.add(new Outline());
+ this.outlineState = VerticesState.UNDEFINED;
+ this.bbox = new AABBox();
+ this.dirtyBits = 0;
+ }
+
+ /** Clears all data and reset all states as if this instance was newly created */
+ public void clear() {
+ outlines.clear();
+ outlines.add(new Outline());
+ outlineState = VerticesState.UNDEFINED;
+ bbox.reset();
+ dirtyBits = 0;
+ }
+
+ /** Returns the associated vertex factory of this outline shape
+ * @return Vertex.Factory object
+ */
+ public final Vertex.Factory<? extends Vertex> vertexFactory() { return vertexFactory; }
+
+ public int getOutlineNumber() {
+ return outlines.size();
+ }
+
+ /** Add a new empty {@link Outline}
+ * to the end of this shape's outline list.
+ * <p>If the {@link #getLastOutline()} is empty already, no new one will be added.</p>
+ *
+ * After a call to this function all new vertices added
+ * will belong to the new outline
+ */
+ public void addEmptyOutline() {
+ if( !getLastOutline().isEmpty() ) {
+ outlines.add(new Outline());
+ }
+ }
+
+ /** Appends the {@link Outline} element to the end,
+ * ensuring a clean tail.
+ *
+ * <p>A clean tail is ensured, no double empty Outlines are produced
+ * and a pre-existing empty outline will be replaced with the given one. </p>
+ *
+ * @param outline Outline object to be added
+ * @throws NullPointerException if the {@link Outline} element is null
+ */
+ public void addOutline(Outline outline) throws NullPointerException {
+ addOutline(outlines.size(), outline);
+ }
+
+ /** Insert the {@link Outline} element at the given {@code position}.
+ *
+ * <p>If the {@code position} indicates the end of this list,
+ * a clean tail is ensured, no double empty Outlines are produced
+ * and a pre-existing empty outline will be replaced with the given one. </p>
+ *
+ * @param position of the added Outline
+ * @param outline Outline object to be added
+ * @throws NullPointerException if the {@link Outline} element is null
+ * @throws IndexOutOfBoundsException if position is out of range (position < 0 || position > getOutlineNumber())
+ */
+ public void addOutline(int position, Outline outline) throws NullPointerException, IndexOutOfBoundsException {
+ if (null == outline) {
+ throw new NullPointerException("outline is null");
+ }
+ if( outlines.size() == position ) {
+ final Outline lastOutline = getLastOutline();
+ if( outline.isEmpty() && lastOutline.isEmpty() ) {
+ return;
+ }
+ if( lastOutline.isEmpty() ) {
+ outlines.set(position-1, outline);
+ if( 0 == ( dirtyBits & DIRTY_BOUNDS ) ) {
+ bbox.resize(outline.getBounds());
+ }
+ return;
+ }
+ }
+ outlines.add(position, outline);
+ if( 0 == ( dirtyBits & DIRTY_BOUNDS ) ) {
+ bbox.resize(outline.getBounds());
+ }
+ }
+
+ /** Insert the {@link OutlineShape} elements of type {@link Outline}, .. at the end of this shape,
+ * using {@link #addOutline(Outline)} for each element.
+ * <p>Closes the current last outline via {@link #closeLastOutline()} before adding the new ones.</p>
+ * @param outlineShape OutlineShape elements to be added.
+ * @throws NullPointerException if the {@link OutlineShape} is null
+ * @throws IndexOutOfBoundsException if position is out of range (position < 0 || position > getOutlineNumber())
+ */
+ public void addOutlineShape(OutlineShape outlineShape) throws NullPointerException {
+ if (null == outlineShape) {
+ throw new NullPointerException("OutlineShape is null");
+ }
+ closeLastOutline();
+ for(int i=0; i<outlineShape.getOutlineNumber(); i++) {
+ addOutline(outlineShape.getOutline(i));
+ }
+ }
+
+ /** Replaces the {@link Outline} element at the given {@code position}.
+ * <p>Sets the bounding box dirty, hence a next call to {@link #getBounds()} will validate it.</p>
+ *
+ * @param position of the replaced Outline
+ * @param outline replacement Outline object
+ * @throws NullPointerException if the {@link Outline} element is null
+ * @throws IndexOutOfBoundsException if position is out of range (position < 0 || position >= getOutlineNumber())
+ */
+ public void setOutline(int position, Outline outline) throws NullPointerException, IndexOutOfBoundsException {
+ if (null == outline) {
+ throw new NullPointerException("outline is null");
+ }
+ outlines.set(position, outline);
+ dirtyBits |= DIRTY_BOUNDS;
+ }
+
+ /** Removes the {@link Outline} element at the given {@code position}.
+ * <p>Sets the bounding box dirty, hence a next call to {@link #getBounds()} will validate it.</p>
+ *
+ * @param position of the to be removed Outline
+ * @throws IndexOutOfBoundsException if position is out of range (position < 0 || position >= getOutlineNumber())
+ */
+ public final Outline removeOutline(int position) throws IndexOutOfBoundsException {
+ dirtyBits |= DIRTY_BOUNDS;
+ return outlines.remove(position);
+ }
+
+ /** Get the last added outline to the list
+ * of outlines that define the shape
+ * @return the last outline
+ */
+ public final Outline getLastOutline() {
+ return outlines.get(outlines.size()-1);
+ }
+
+ /** @return the {@code Outline} at {@code position}
+ * @throws IndexOutOfBoundsException if position is out of range (position < 0 || position >= getOutlineNumber())
+ */
+ public Outline getOutline(int position) throws IndexOutOfBoundsException {
+ return outlines.get(position);
+ }
+
+ /** Adds a vertex to the last open outline in the
+ * shape.
+ * @param v the vertex to be added to the OutlineShape
+ */
+ public final void addVertex(Vertex v) {
+ final Outline lo = getLastOutline();
+ lo.addVertex(v);
+ if( 0 == ( dirtyBits & DIRTY_BOUNDS ) ) {
+ bbox.resize(lo.getBounds());
+ }
+ }
+
+ /** Adds a vertex to the last open outline in the shape.
+ * at {@code position}
+ * @param position indx at which the vertex will be added
+ * @param v the vertex to be added to the OutlineShape
+ */
+ public final void addVertex(int position, Vertex v) {
+ final Outline lo = getLastOutline();
+ lo.addVertex(position, v);
+ if( 0 == ( dirtyBits & DIRTY_BOUNDS ) ) {
+ bbox.resize(lo.getBounds());
+ }
+ }
+
+ /** Add a 2D {@link Vertex} to the last outline by defining the coordniate attribute
+ * of the vertex. The 2D vertex will be represented as Z=0.
+ *
+ * @param x the x coordinate
+ * @param y the y coordniate
+ * @param onCurve flag if this vertex is on the final curve or defines a curved region
+ * of the shape around this vertex.
+ */
+ public final void addVertex(float x, float y, boolean onCurve) {
+ addVertex(vertexFactory.create(x, y, 0f, onCurve));
+ }
+
+ /** Add a 3D {@link Vertex} to the last outline by defining the coordniate attribute
+ * of the vertex.
+ * @param x the x coordinate
+ * @param y the y coordinate
+ * @param z the z coordinate
+ * @param onCurve flag if this vertex is on the final curve or defines a curved region
+ * of the shape around this vertex.
+ */
+ public final void addVertex(float x, float y, float z, boolean onCurve) {
+ addVertex(vertexFactory.create(x, y, z, onCurve));
+ }
+
+ /** Add a vertex to the last outline by passing a float array and specifying the
+ * offset and length in which. The attributes of the vertex are located.
+ * The attributes should be continuous (stride = 0).
+ * Attributes which value are not set (when length less than 3)
+ * are set implicitly to zero.
+ * @param coordsBuffer the coordinate array where the vertex attributes are to be picked from
+ * @param offset the offset in the buffer to the x coordinate
+ * @param length the number of attributes to pick from the buffer (maximum 3)
+ * @param onCurve flag if this vertex is on the final curve or defines a curved region
+ * of the shape around this vertex.
+ */
+ public final void addVertex(float[] coordsBuffer, int offset, int length, boolean onCurve) {
+ addVertex(vertexFactory.create(coordsBuffer, offset, length, onCurve));
+ }
+
+ /** Closes the last outline in the shape.
+ * <p>If last vertex is not equal to first vertex.
+ * A new temp vertex is added at the end which
+ * is equal to the first.</p>
+ */
+ public void closeLastOutline() {
+ getLastOutline().setClosed(true);
+ }
+
+ /**
+ * @return the outline's vertices state, {@link OutlineShape.VerticesState}
+ */
+ public final VerticesState getOutlineState() {
+ return outlineState;
+ }
+
+ /** Ensure the outlines represent
+ * the specified destinationType.
+ *
+ * @param destinationType the target outline's vertices state. Currently only {@link OutlineShape.VerticesState#QUADRATIC_NURBS} are supported.
+ */
+ public void transformOutlines(VerticesState destinationType) {
+ if(outlineState != destinationType){
+ if(destinationType == VerticesState.QUADRATIC_NURBS){
+ transformOutlines2Quadratic();
+ } else {
+ throw new IllegalStateException("destinationType "+destinationType.name()+" not supported (currently "+outlineState.name()+")");
+ }
+ }
+ }
+
+ private void transformOutlines2Quadratic() {
+ int count = getOutlineNumber();
+ for (int cc = 0; cc < count; cc++) {
+ final Outline outline = getOutline(cc);
+ int vertexCount = outline.getVertexCount();
+
+ for(int i=0; i < vertexCount; i++) {
+ final Vertex currentVertex = outline.getVertex(i);
+ final Vertex nextVertex = outline.getVertex((i+1)%vertexCount);
+ if ( !currentVertex.isOnCurve() && !nextVertex.isOnCurve() ) {
+ final float[] newCoords = VectorUtil.mid(currentVertex.getCoord(),
+ nextVertex.getCoord());
+ final Vertex v = vertexFactory.create(newCoords, 0, 3, true);
+ i++;
+ vertexCount++;
+ outline.addVertex(i, v);
+ }
+ }
+ if(vertexCount <= 0) {
+ outlines.remove(outline);
+ cc--;
+ count--;
+ continue;
+ }
+
+ if( vertexCount > 0 ) {
+ if(VectorUtil.checkEquality(outline.getVertex(0).getCoord(),
+ outline.getLastVertex().getCoord())) {
+ outline.removeVertex(vertexCount-1);
+ }
+ }
+ }
+ outlineState = VerticesState.QUADRATIC_NURBS;
+ }
+
+ private void generateVertexIds() {
+ int maxVertexId = 0;
+ for(int i=0; i<outlines.size(); i++) {
+ final ArrayList<Vertex> vertices = outlines.get(i).getVertices();
+ for(int pos=0; pos<vertices.size(); pos++) {
+ Vertex vert = vertices.get(pos);
+ vert.setId(maxVertexId);
+ maxVertexId++;
+ }
+ }
+ }
+
+ /** @return the list of concatenated vertices associated with all
+ * {@code Outline}s of this object
+ */
+ public ArrayList<Vertex> getVertices() {
+ ArrayList<Vertex> vertices = new ArrayList<Vertex>();
+ for(int i=0; i<outlines.size(); i++) {
+ vertices.addAll(outlines.get(i).getVertices());
+ }
+ return vertices;
+ }
+
+ /**
+ * Triangulate the {@link OutlineShape} generating a list of triangles
+ * @return an arraylist of triangles representing the filled region
+ * which is produced by the combination of the outlines
+ */
+ public ArrayList<Triangle> triangulate() {
+ if(outlines.size() == 0){
+ return null;
+ }
+ sortOutlines();
+ generateVertexIds();
+
+ Triangulator triangulator2d = Triangulation.create();
+ for(int index = 0; index<outlines.size(); index++) {
+ triangulator2d.addCurve(outlines.get(index));
+ }
+
+ ArrayList<Triangle> triangles = triangulator2d.generate();
+ triangulator2d.reset();
+
+ return triangles;
+ }
+
+ /** Sort the outlines from large
+ * to small depending on the AABox
+ */
+ private void sortOutlines() {
+ Collections.sort(outlines);
+ Collections.reverse(outlines);
+ }
+
+ /** Compare two outline shapes with Bounding Box area
+ * as criteria.
+ * @see java.lang.Comparable#compareTo(java.lang.Object)
+ */
+ public final int compareTo(OutlineShape outline) {
+ float size = getBounds().getSize();
+ float newSize = outline.getBounds().getSize();
+ if(size < newSize){
+ return -1;
+ }
+ else if(size > newSize){
+ return 1;
+ }
+ return 0;
+ }
+
+ private final void validateBoundingBox() {
+ dirtyBits &= ~DIRTY_BOUNDS;
+ bbox.reset();
+ for (int i=0; i<outlines.size(); i++) {
+ bbox.resize(outlines.get(i).getBounds());
+ }
+ }
+
+ public final AABBox getBounds() {
+ if( 0 == ( dirtyBits & DIRTY_BOUNDS ) ) {
+ validateBoundingBox();
+ }
+ return bbox;
+ }
+
+ /**
+ * @param obj the Object to compare this OutlineShape with
+ * @return true if {@code obj} is an OutlineShape, not null,
+ * same outlineState, equal bounds and equal outlines in the same order
+ */
+ public boolean equals(Object obj) {
+ if( obj == this) {
+ return true;
+ }
+ if( null == obj || !(obj instanceof OutlineShape) ) {
+ return false;
+ }
+ final OutlineShape o = (OutlineShape) obj;
+ if(getOutlineState() != o.getOutlineState()) {
+ return false;
+ }
+ if(getOutlineNumber() != o.getOutlineNumber()) {
+ return false;
+ }
+ if( !getBounds().equals( o.getBounds() ) ) {
+ return false;
+ }
+ for (int i=getOutlineNumber()-1; i>=0; i--) {
+ if( ! getOutline(i).equals( o.getOutline(i) ) ) {
+ return false;
+ }
+ }
+ return true;
+ }
+
+ /**
+ * @return deep clone of this OutlineShape w/o Region
+ */
+ public OutlineShape clone() {
+ OutlineShape o;
+ try {
+ o = (OutlineShape) super.clone();
+ } catch (CloneNotSupportedException e) { throw new InternalError(); }
+ o.bbox = bbox.clone();
+ o.outlines = new ArrayList<Outline>(outlines.size());
+ for(int i=0; i<outlines.size(); i++) {
+ o.outlines.add(outlines.get(i).clone());
+ }
+ return o;
+ }
+}
diff --git a/src/jogl/classes/com/jogamp/graph/curve/Region.java b/src/jogl/classes/com/jogamp/graph/curve/Region.java
index 46bdedee4..168d8dd70 100644
--- a/src/jogl/classes/com/jogamp/graph/curve/Region.java
+++ b/src/jogl/classes/com/jogamp/graph/curve/Region.java
@@ -39,9 +39,11 @@ public abstract class Region {
public static final boolean DEBUG = Debug.debug("graph.curve");
public static final boolean DEBUG_INSTANCE = false;
- /** Two pass region rendering, slower and more resource hungry (FBO), but AA is perfect.
- * Otherwise the default fast one pass MSAA region rendering is being used. */
- public static final int TWO_PASS_RENDERING_BIT = 1 << 0;
+ /** View based Anti-Aliasing, A Two pass region rendering, slower
+ * and more resource hungry (FBO), but AA is perfect.
+ * Otherwise the default fast one pass MSAA region rendering is being used.
+ */
+ public static final int VBAA_RENDERING_BIT = 1 << 0;
/** Use non uniform weights [0.0 .. 1.9] for curve region rendering.
* Otherwise the default weight 1.0 for Bezier curve region rendering is being applied. */
@@ -57,8 +59,8 @@ public abstract class Region {
protected ArrayList<Triangle> triangles = new ArrayList<Triangle>();
protected ArrayList<Vertex> vertices = new ArrayList<Vertex>();
- public static boolean usesTwoPassRendering(int renderModes) {
- return 0 != ( renderModes & Region.TWO_PASS_RENDERING_BIT );
+ public static boolean isVBAA(int renderModes) {
+ return 0 != ( renderModes & Region.VBAA_RENDERING_BIT );
}
public static boolean usesVariableCurveWeight(int renderModes) {
@@ -71,7 +73,7 @@ public abstract class Region {
public final int getRenderModes() { return renderModes; }
- public boolean usesTwoPassRendering() { return Region.usesTwoPassRendering(renderModes); }
+ public boolean isVBAA() { return Region.isVBAA(renderModes); }
public boolean usesVariableCurveWeight() { return Region.usesVariableCurveWeight(renderModes); }
/** Get the current number of vertices associated
diff --git a/src/jogl/classes/com/jogamp/graph/curve/opengl/RegionRenderer.java b/src/jogl/classes/com/jogamp/graph/curve/opengl/RegionRenderer.java
index 8624c582c..86d962fd8 100644
--- a/src/jogl/classes/com/jogamp/graph/curve/opengl/RegionRenderer.java
+++ b/src/jogl/classes/com/jogamp/graph/curve/opengl/RegionRenderer.java
@@ -38,7 +38,7 @@ public abstract class RegionRenderer extends Renderer {
/**
* Create a Hardware accelerated Region Renderer.
* @param rs the used {@link RenderState}
- * @param renderModes bit-field of modes, e.g. {@link Region#VARIABLE_CURVE_WEIGHT_BIT}, {@link Region#TWO_PASS_RENDERING_BIT}
+ * @param renderModes bit-field of modes, e.g. {@link Region#VARIABLE_CURVE_WEIGHT_BIT}, {@link Region#VBAA_RENDERING_BIT}
* @return an instance of Region Renderer
*/
public static RegionRenderer create(RenderState rs, int renderModes) {
diff --git a/src/jogl/classes/com/jogamp/graph/curve/opengl/TextRenderer.java b/src/jogl/classes/com/jogamp/graph/curve/opengl/TextRenderer.java
index 073afe9bd..b466670cc 100644
--- a/src/jogl/classes/com/jogamp/graph/curve/opengl/TextRenderer.java
+++ b/src/jogl/classes/com/jogamp/graph/curve/opengl/TextRenderer.java
@@ -31,27 +31,20 @@ import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
-import javax.media.opengl.GL;
import javax.media.opengl.GL2ES2;
import jogamp.graph.curve.text.GlyphString;
-import jogamp.graph.font.FontInt;
-import jogamp.graph.geom.plane.AffineTransform;
-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 abstract class TextRenderer extends Renderer {
/**
* Create a Hardware accelerated Text Renderer.
* @param rs the used {@link RenderState}
- * @param renderModes either {@link com.jogamp.graph.curve.opengl.GLRegion#SINGLE_PASS} or {@link com.jogamp.graph.curve.Region#TWO_PASS_RENDERING_BIT}
+ * @param renderModes either {@link com.jogamp.graph.curve.opengl.GLRegion#SINGLE_PASS} or {@link com.jogamp.graph.curve.Region#VBAA_RENDERING_BIT}
*/
- public static TextRenderer create(RenderState rs, int type) {
- return new jogamp.graph.curve.opengl.TextRendererImpl01(rs, type);
+ public static TextRenderer create(RenderState rs, int renderModes) {
+ return new jogamp.graph.curve.opengl.TextRendererImpl01(rs, renderModes);
}
protected TextRenderer(RenderState rs, int type) {
diff --git a/src/jogl/classes/com/jogamp/graph/curve/tess/Triangulation.java b/src/jogl/classes/com/jogamp/graph/curve/tess/Triangulation.java
new file mode 100644
index 000000000..7728efcaf
--- /dev/null
+++ b/src/jogl/classes/com/jogamp/graph/curve/tess/Triangulation.java
@@ -0,0 +1,44 @@
+/**
+ * Copyright 2011 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 com.jogamp.graph.curve.tess;
+
+import jogamp.graph.curve.tess.CDTriangulator2D;
+
+
+public class Triangulation {
+ /** Create a new instance of a triangulation.
+ * Currently only a modified version of Constraint Delaunay
+ * is implemented.
+ * @return instance of a triangulator
+ * @see Triangulator
+ */
+ public static Triangulator create() {
+ return new CDTriangulator2D();
+ }
+}
diff --git a/src/jogl/classes/com/jogamp/graph/curve/tess/Triangulator.java b/src/jogl/classes/com/jogamp/graph/curve/tess/Triangulator.java
new file mode 100644
index 000000000..1ffaccebc
--- /dev/null
+++ b/src/jogl/classes/com/jogamp/graph/curve/tess/Triangulator.java
@@ -0,0 +1,69 @@
+/**
+ * Copyright 2011 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 com.jogamp.graph.curve.tess;
+
+import java.util.ArrayList;
+
+import com.jogamp.graph.geom.Outline;
+import com.jogamp.graph.geom.Triangle;
+
+/** Interface to the triangulation algorithms provided
+ * A triangulation of 2D outlines where you can
+ * provides an easy one or more outlines to be triangulated
+ *
+ * example usage:
+ * addCurve(o1);
+ * addCurve(o2);
+ * addCurve(o3);
+ * generate();
+ * reset();
+ *
+ * @see Outline
+ * @see Triangulation
+ */
+public interface Triangulator {
+
+ /** Add a curve to the list of Outlines
+ * describing the shape
+ * @param outline a bounding {@link Outline}
+ */
+ public void addCurve(Outline outline);
+
+ /** Generate the triangulation of the provided
+ * List of {@link Outline}s
+ * @return an arraylist of {@link Triangle}s resembling the
+ * final shape.
+ */
+ public ArrayList<Triangle> generate();
+
+ /** Reset the triangulation to initial state
+ * Clearing cached data
+ */
+ public void reset();
+}
diff --git a/src/jogl/classes/com/jogamp/graph/geom/Outline.java b/src/jogl/classes/com/jogamp/graph/geom/Outline.java
index 6c1557f7b..9e90e5a2c 100644
--- a/src/jogl/classes/com/jogamp/graph/geom/Outline.java
+++ b/src/jogl/classes/com/jogamp/graph/geom/Outline.java
@@ -57,7 +57,7 @@ public class Outline implements Cloneable, Comparable<Outline> {
public Outline() {
}
- public final int getVertexNumber() {
+ public final int getVertexCount() {
return vertices.size();
}
@@ -207,13 +207,13 @@ public class Outline implements Cloneable, Comparable<Outline> {
return false;
}
final Outline o = (Outline) obj;
- if(getVertexNumber() != o.getVertexNumber()) {
+ if(getVertexCount() != o.getVertexCount()) {
return false;
}
if( !getBounds().equals( o.getBounds() ) ) {
return false;
}
- for (int i=getVertexNumber()-1; i>=0; i--) {
+ for (int i=getVertexCount()-1; i>=0; i--) {
if( ! getVertex(i).equals( o.getVertex(i) ) ) {
return false;
}
diff --git a/src/jogl/classes/jogamp/graph/curve/opengl/RegionFactory.java b/src/jogl/classes/jogamp/graph/curve/opengl/RegionFactory.java
index b5a89b40a..e33a78ed8 100755
--- a/src/jogl/classes/jogamp/graph/curve/opengl/RegionFactory.java
+++ b/src/jogl/classes/jogamp/graph/curve/opengl/RegionFactory.java
@@ -39,14 +39,14 @@ public class RegionFactory {
/**
* Create a Region using the passed render mode
*
- * <p> In case {@link Region#TWO_PASS_RENDERING_BIT} is being requested the default texture unit
+ * <p> In case {@link Region#VBAA_RENDERING_BIT} is being requested the default texture unit
* {@link Region#TWO_PASS_DEFAULT_TEXTURE_UNIT} is being used.</p>
*
* @param rs the RenderState to be used
- * @param renderModes bit-field of modes, e.g. {@link Region#VARIABLE_CURVE_WEIGHT_BIT}, {@link Region#TWO_PASS_RENDERING_BIT}
+ * @param renderModes bit-field of modes, e.g. {@link Region#VARIABLE_CURVE_WEIGHT_BIT}, {@link Region#VBAA_RENDERING_BIT}
*/
public static GLRegion create(int renderModes) {
- if( 0 != ( Region.TWO_PASS_RENDERING_BIT & renderModes ) ){
+ if( 0 != ( Region.VBAA_RENDERING_BIT & renderModes ) ){
return new VBORegion2PES2(renderModes, Region.TWO_PASS_DEFAULT_TEXTURE_UNIT);
}
else{
diff --git a/src/jogl/classes/com/jogamp/graph/curve/tess/CDTriangulator2D.java b/src/jogl/classes/jogamp/graph/curve/tess/CDTriangulator2D.java
index fce2e1bae..10b6d6847 100644
--- a/src/jogl/classes/com/jogamp/graph/curve/tess/CDTriangulator2D.java
+++ b/src/jogl/classes/jogamp/graph/curve/tess/CDTriangulator2D.java
@@ -26,14 +26,12 @@
* or implied, of JogAmp Community.
*/
-package com.jogamp.graph.curve.tess;
+package jogamp.graph.curve.tess;
import java.util.ArrayList;
-import jogamp.graph.curve.tess.GraphOutline;
-import jogamp.graph.curve.tess.GraphVertex;
-import jogamp.graph.curve.tess.Loop;
+import com.jogamp.graph.curve.tess.Triangulator;
import com.jogamp.graph.geom.Outline;
import com.jogamp.graph.geom.Triangle;
import com.jogamp.graph.geom.Vertex;
@@ -46,7 +44,7 @@ import jogamp.opengl.Debug;
* Closed Regions with optional n holes.
*
*/
-public class CDTriangulator2D {
+public class CDTriangulator2D implements Triangulator{
protected static final boolean DEBUG = Debug.debug("Triangulation");
@@ -74,14 +72,9 @@ public class CDTriangulator2D {
loops = new ArrayList<Loop>();
}
- /** Add a curve to the list of profiles provided
- * @param polyline a bounding {@link Outline}
- */
- public void addCurve(Outline polyline){
+ public void addCurve(Outline polyline) {
Loop loop = null;
- // FIXME: multiple in/out and CW/CCW tests (as follows) ??
-
if(!loops.isEmpty()) {
loop = getContainerLoop(polyline);
}
@@ -100,10 +93,7 @@ public class CDTriangulator2D {
}
}
- /** Generate the triangulation of the provided
- * List of {@link Outline}s
- */
- public ArrayList<Triangle> generateTriangulation(){
+ public ArrayList<Triangle> generate() {
for(int i=0;i<loops.size();i++) {
Loop loop = loops.get(i);
int numTries = 0;
diff --git a/src/jogl/classes/jogamp/graph/curve/text/GlyphShape.java b/src/jogl/classes/jogamp/graph/curve/text/GlyphShape.java
index ed51cce98..578148699 100644
--- a/src/jogl/classes/jogamp/graph/curve/text/GlyphShape.java
+++ b/src/jogl/classes/jogamp/graph/curve/text/GlyphShape.java
@@ -29,10 +29,9 @@ package jogamp.graph.curve.text;
import java.util.ArrayList;
-import jogamp.graph.geom.plane.PathIterator;
-
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;
@@ -40,7 +39,6 @@ import com.jogamp.graph.math.Quaternion;
public class GlyphShape {
private Quaternion quat= null;
- private int numVertices = 0;
private OutlineShape shape = null;
/** Create a new Glyph shape
@@ -50,70 +48,24 @@ public class GlyphShape {
shape = new OutlineShape(factory);
}
- /** Create a GlyphShape from a font Path Iterator
- * @param pathIterator the path iterator
- *
- * @see PathIterator
+ /** 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, PathIterator pathIterator){
+ public GlyphShape(Vertex.Factory<? extends Vertex> factory, OutlineShape shape){
this(factory);
-
- if(null != pathIterator){
- while(!pathIterator.isDone()){
- float[] coords = new float[6];
- int segmentType = pathIterator.currentSegment(coords);
- addOutlineVerticesFromGlyphVector(coords, segmentType);
-
- pathIterator.next();
- }
- }
- shape.transformOutlines(OutlineShape.VerticesState.QUADRATIC_NURBS);
+ this.shape = shape;
+ this.shape.transformOutlines(OutlineShape.VerticesState.QUADRATIC_NURBS);
}
public final Vertex.Factory<? extends Vertex> vertexFactory() { return shape.vertexFactory(); }
- private void addVertexToLastOutline(Vertex vertex) {
- //FIXME: assuming font outline comes in CW order
- shape.addVertex(0, vertex);
- }
-
- private void addOutlineVerticesFromGlyphVector(float[] coords, int segmentType){
- switch(segmentType) {
- case PathIterator.SEG_MOVETO:
- shape.closeLastOutline();
- shape.addEmptyOutline();
- addVertexToLastOutline(vertexFactory().create(coords, 0, 2, true));
- numVertices++;
- break;
- case PathIterator.SEG_LINETO:
- addVertexToLastOutline(vertexFactory().create(coords, 0, 2, true));
- numVertices++;
- break;
- case PathIterator.SEG_QUADTO:
- addVertexToLastOutline(vertexFactory().create(coords, 0, 2, false));
- addVertexToLastOutline(vertexFactory().create(coords, 2, 2, true));
- numVertices+=2;
- break;
- case PathIterator.SEG_CUBICTO:
- addVertexToLastOutline(vertexFactory().create(coords, 0, 2, false));
- addVertexToLastOutline(vertexFactory().create(coords, 2, 2, false));
- addVertexToLastOutline(vertexFactory().create(coords, 4, 2, true));
- numVertices+=3;
- break;
- case PathIterator.SEG_CLOSE:
- shape.closeLastOutline();
- break;
- default:
- throw new IllegalArgumentException("Unhandled Segment Type: "+segmentType);
- }
- }
-
public OutlineShape getShape() {
return shape;
}
public int getNumVertices() {
- return numVertices;
+ return shape.getVertices().size();
}
/** Get the rotational Quaternion attached to this Shape
diff --git a/src/jogl/classes/jogamp/graph/curve/text/GlyphString.java b/src/jogl/classes/jogamp/graph/curve/text/GlyphString.java
index cd6cd56aa..2fa708404 100644
--- a/src/jogl/classes/jogamp/graph/curve/text/GlyphString.java
+++ b/src/jogl/classes/jogamp/graph/curve/text/GlyphString.java
@@ -40,10 +40,6 @@ import javax.media.opengl.GL2ES2;
import jogamp.graph.curve.opengl.RegionFactory;
import jogamp.graph.font.FontInt;
-import jogamp.graph.geom.plane.AffineTransform;
-import jogamp.graph.geom.plane.Path2D;
-import jogamp.graph.geom.plane.PathIterator;
-
import com.jogamp.graph.curve.OutlineShape;
import com.jogamp.graph.curve.Region;
@@ -68,9 +64,9 @@ public class GlyphString {
* <p>No caching is performed.</p>
*
* @param shape is not null, add all {@link GlyphShape}'s {@link Outline} to this instance.
- * @param vertexFactory
- * @param font
- * @param str
+ * @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) {
@@ -81,20 +77,17 @@ public class GlyphString {
* <p>No caching is performed.</p>
*
* @param shape is not null, add all {@link GlyphShape}'s {@link Outline} to this instance.
- * @param vertexFactory
- * @param font
- * @param size
- * @param str
+ * @param vertexFactory vertex impl factory {@link Factory}
+ * @param font the target {@link Font}
+ * @param size 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) {
- AffineTransform affineTransform = new AffineTransform(vertexFactory);
-
- Path2D[] paths = new Path2D[str.length()];
- ((FontInt)font).getPaths(str, fontSize, affineTransform, paths);
+ ArrayList<OutlineShape> shapes = ((FontInt)font).getOutlineShapes(str, fontSize, vertexFactory);
GlyphString glyphString = new GlyphString(font.getName(Font.NAME_UNIQUNAME), str);
- glyphString.createfromFontPath(vertexFactory, paths, affineTransform);
+ glyphString.createfromOutlineShapes(vertexFactory, shapes);
if(null != shape) {
for(int i=0; i<glyphString.glyphs.size(); i++) {
shape.addOutlineShape(glyphString.glyphs.get(i).getShape());
@@ -121,19 +114,17 @@ public class GlyphString {
return str;
}
- /** Creates the Curve based Glyphs from a Font
+ /**Creates the Curve based Glyphs from a list of {@link OutlineShape}
* @param vertexFactory vertex impl factory {@link Factory}
- * @param paths a list of FontPath2D objects that define the outline
- * @param affineTransform a global affine transformation applied to the paths.
+ * @param shapes list of {@link OutlineShape}
*/
- public void createfromFontPath(Factory<? extends Vertex> vertexFactory, Path2D[] paths, AffineTransform affineTransform) {
- final int numGlyps = paths.length;
+ public void createfromOutlineShapes(Factory<? extends Vertex> vertexFactory, ArrayList<OutlineShape> shapes) {
+ final int numGlyps = shapes.size();
for (int index=0;index<numGlyps;index++){
- if(paths[index] == null){
+ if(shapes.get(index) == null){
continue;
}
- PathIterator iterator = paths[index].iterator(affineTransform);
- GlyphShape glyphShape = new GlyphShape(vertexFactory, iterator);
+ GlyphShape glyphShape = new GlyphShape(vertexFactory, shapes.get(index));
if(glyphShape.getNumVertices() < 3) {
continue;
@@ -142,10 +133,11 @@ public class GlyphString {
}
}
+
/** 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#TWO_PASS_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);
diff --git a/src/jogl/classes/jogamp/graph/font/FontInt.java b/src/jogl/classes/jogamp/graph/font/FontInt.java
index 6c25f9a80..37660bb2c 100644
--- a/src/jogl/classes/jogamp/graph/font/FontInt.java
+++ b/src/jogl/classes/jogamp/graph/font/FontInt.java
@@ -27,11 +27,14 @@
*/
package jogamp.graph.font;
-import jogamp.graph.geom.plane.AffineTransform;
+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 {
@@ -46,7 +49,5 @@ public interface FontInt extends Font {
public Path2D getPath(float pixelSize);
}
- public void getPaths(CharSequence string, float pixelSize,
- AffineTransform transform, Path2D[] result);
- //TODO: Rami - ADD getOutlines without path2D
+ 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 2e692e5ce..8806f537d 100644
--- a/src/jogl/classes/jogamp/graph/font/typecast/TypecastFont.java
+++ b/src/jogl/classes/jogamp/graph/font/typecast/TypecastFont.java
@@ -27,6 +27,8 @@
*/
package jogamp.graph.font.typecast;
+import java.util.ArrayList;
+
import jogamp.graph.font.FontInt;
import jogamp.graph.font.typecast.ot.OTFont;
import jogamp.graph.font.typecast.ot.OTFontCollection;
@@ -39,9 +41,12 @@ import jogamp.graph.geom.plane.AffineTransform;
import jogamp.graph.geom.plane.Path2D;
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.geom.AABBox;
+import com.jogamp.graph.geom.Vertex;
+import com.jogamp.graph.geom.Vertex.Factory;
class TypecastFont implements FontInt {
static final boolean DEBUG = false;
@@ -208,9 +213,10 @@ class TypecastFont implements FontInt {
}
return result;
}
-
- public void getPaths(CharSequence string, float pixelSize, AffineTransform transform, Path2D[] result) {
- TypecastRenderer.getPaths(this, string, pixelSize, transform, result);
+
+ public ArrayList<OutlineShape> getOutlineShapes(CharSequence string, float pixelSize, Factory<? extends Vertex> vertexFactory) {
+ AffineTransform transform = new AffineTransform(vertexFactory);
+ return TypecastRenderer.getOutlineShapes(this, string, pixelSize, transform, vertexFactory);
}
public float getStringWidth(CharSequence string, float pixelSize) {
diff --git a/src/jogl/classes/jogamp/graph/font/typecast/TypecastRenderer.java b/src/jogl/classes/jogamp/graph/font/typecast/TypecastRenderer.java
index 310b2b274..50b510d23 100644
--- a/src/jogl/classes/jogamp/graph/font/typecast/TypecastRenderer.java
+++ b/src/jogl/classes/jogamp/graph/font/typecast/TypecastRenderer.java
@@ -27,12 +27,19 @@
*/
package jogamp.graph.font.typecast;
+import java.util.ArrayList;
+
+import jogamp.graph.curve.text.GlyphShape;
import jogamp.graph.font.typecast.ot.OTGlyph;
import jogamp.graph.font.typecast.ot.Point;
import jogamp.graph.geom.plane.AffineTransform;
import jogamp.graph.geom.plane.Path2D;
+import jogamp.graph.geom.plane.PathIterator;
+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;
/**
* Factory to build a {@link com.jogamp.graph.geom.Path2D Path2D} from
@@ -40,7 +47,7 @@ import com.jogamp.graph.font.Font;
*/
public class TypecastRenderer {
- public static void getPaths(TypecastFont font,
+ private static void getPaths(TypecastFont font,
CharSequence string, float pixelSize, AffineTransform transform, Path2D[] p)
{
if (string == null) {
@@ -82,6 +89,58 @@ public class TypecastRenderer {
}
}
+ public static ArrayList<OutlineShape> getOutlineShapes(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>();
+ final int numGlyps = paths.length;
+ for (int index=0;index<numGlyps;index++) {
+ if(paths[index] == null){
+ continue;
+ }
+ OutlineShape shape = new OutlineShape(vertexFactory);
+ shapes.add(shape);
+ PathIterator iterator = paths[index].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 shapes;
+ }
+ private static void addPathVertexToOutline(OutlineShape shape, Factory<? extends Vertex> vertexFactory, float[] coords, int segmentType){
+ switch(segmentType) {
+ case PathIterator.SEG_MOVETO:
+ shape.closeLastOutline();
+ shape.addEmptyOutline();
+ shape.addVertex(0, vertexFactory.create(coords, 0, 2, true));
+ //numVertices++;
+ break;
+ case PathIterator.SEG_LINETO:
+ shape.addVertex(0, vertexFactory.create(coords, 0, 2, true));
+ break;
+ case PathIterator.SEG_QUADTO:
+ shape.addVertex(0, vertexFactory.create(coords, 0, 2, false));
+ shape.addVertex(0, vertexFactory.create(coords, 2, 2, true));
+ break;
+ case PathIterator.SEG_CUBICTO:
+ shape.addVertex(0, vertexFactory.create(coords, 0, 2, false));
+ shape.addVertex(0, vertexFactory.create(coords, 2, 2, false));
+ shape.addVertex(0, vertexFactory.create(coords, 4, 2, true));
+ break;
+ case PathIterator.SEG_CLOSE:
+ shape.closeLastOutline();
+ break;
+ default:
+ throw new IllegalArgumentException("Unhandled Segment Type: "+segmentType);
+ }
+ }
+
/**
* Build a {@link com.jogamp.graph.geom.Path2D Path2D} from a
* {@link jogamp.graph.font.typecast.ot.OTGlyph Glyph}. This glyph path can then