aboutsummaryrefslogtreecommitdiffstats
path: root/src/jogl
diff options
context:
space:
mode:
authorSven Gothel <[email protected]>2014-02-27 23:56:13 +0100
committerSven Gothel <[email protected]>2014-02-27 23:56:13 +0100
commit67ec86e539a3db0d06e5cc3550db453589594384 (patch)
tree66d006ff20407cb6bfc16fb288a5d4665df077cf /src/jogl
parent2cafc01f08f9ab05748be6eeb82c417de38b31f7 (diff)
Bug 801: Graph TextRenderer Cleanup Part-4: Text[Render->Region]Util API: Better separation of cached and uncached regions
Diffstat (limited to 'src/jogl')
-rw-r--r--src/jogl/classes/com/jogamp/graph/curve/opengl/TextRegionUtil.java (renamed from src/jogl/classes/com/jogamp/graph/curve/opengl/TextRenderUtil.java)83
-rw-r--r--src/jogl/classes/com/jogamp/graph/font/Font.java6
-rw-r--r--src/jogl/classes/jogamp/graph/font/typecast/TypecastFont.java43
3 files changed, 64 insertions, 68 deletions
diff --git a/src/jogl/classes/com/jogamp/graph/curve/opengl/TextRenderUtil.java b/src/jogl/classes/com/jogamp/graph/curve/opengl/TextRegionUtil.java
index 944050a14..e7ed335ec 100644
--- a/src/jogl/classes/com/jogamp/graph/curve/opengl/TextRenderUtil.java
+++ b/src/jogl/classes/com/jogamp/graph/curve/opengl/TextRegionUtil.java
@@ -30,7 +30,6 @@ package com.jogamp.graph.curve.opengl;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
-import java.util.List;
import javax.media.opengl.GL2ES2;
import javax.media.opengl.GLException;
@@ -41,47 +40,36 @@ import com.jogamp.graph.curve.OutlineShape;
import com.jogamp.graph.curve.Region;
import com.jogamp.graph.font.Font;
import com.jogamp.graph.font.Font.Glyph;
-import com.jogamp.graph.geom.Triangle;
import com.jogamp.graph.geom.Vertex;
import com.jogamp.graph.geom.Vertex.Factory;
/**
- *
- * FIXME: Add VBO Vertex Factory for drawString3D !
- *
+ * Text {@link GLRegion} Utility Class
*/
-public class TextRenderUtil {
+public class TextRegionUtil {
public final RegionRenderer renderer;
- public TextRenderUtil(final RegionRenderer renderer) {
+ public TextRegionUtil(final RegionRenderer renderer) {
this.renderer = renderer;
}
/**
- * Generate a Region to represent this Object.
- * <p>
- * Each glyph is cached and reused.
- * </p>
- *
- * @param renderModes bit-field of modes, e.g. {@link Region#VARIABLE_CURVE_WEIGHT_BIT}, {@link Region#VBAA_RENDERING_BIT}
+ * Add the string in 3D space w.r.t. the font and pixelSize at the end of the {@link GLRegion}.
+ * @param region the {@link GLRegion} sink
* @param vertexFactory vertex impl factory {@link Factory}
* @param font the target {@link Font}
* @param str string text
* @param pixelSize
*/
- public static GLRegion createRegion(final int renderModes, final Factory<? extends Vertex> vertexFactory,
- final Font font, final CharSequence str, final int pixelSize) {
+ public static void addStringToRegion(final GLRegion region, final Factory<? extends Vertex> vertexFactory,
+ final Font font, final CharSequence str, final int pixelSize) {
final int charCount = str.length();
- final GLRegion region = GLRegion.create(renderModes);
// region.setFlipped(true);
final Font.Metrics metrics = font.getMetrics();
+ final float lineHeight = font.getLineHeight(pixelSize);
- final float lineGap = metrics.getLineGap(pixelSize) ;
- final float ascent = metrics.getAscent(pixelSize) ;
- final float descent = metrics.getDescent(pixelSize) ;
- final float advanceY = lineGap - descent + ascent;
final float scale = metrics.getScale(pixelSize);
final AffineTransform transform = new AffineTransform(vertexFactory);
final AffineTransform t = new AffineTransform(vertexFactory);
@@ -92,7 +80,7 @@ public class TextRenderUtil {
for(int i=0; i< charCount; i++) {
final char character = str.charAt(i);
if( '\n' == character ) {
- y += advanceY;
+ y -= lineHeight;
advanceTotal = 0;
} else if (character == ' ') {
advanceTotal += font.getAdvanceWidth(Glyph.ID_SPACE, pixelSize);
@@ -114,37 +102,41 @@ public class TextRenderUtil {
advanceTotal += glyph.getAdvance(pixelSize, true);
}
}
- return region;
}
/**
- * Render the String in 3D space wrt to the font provided at the position provided
- * the outlines will be generated, if not yet generated
+ * Render the string in 3D space w.r.t. the font and pixelSize
+ * using a cached {@link GLRegion} for reuse.
+ * <p>
+ * Cached {@link GLRegion}s will be destroyed w/ {@link #clear(GL2ES2)} or to free memory.
+ * </p>
* @param gl the current GL state
* @param font {@link Font} to be used
* @param str text to be rendered
* @param pixelSize font size
- * @param texWidth desired texture width for multipass-rendering.
+ * @param texSize desired texture width for multipass-rendering.
* The actual used texture-width is written back when mp rendering is enabled, otherwise the store is untouched.
* @throws Exception if TextRenderer not initialized
*/
public void drawString3D(final GL2ES2 gl,
- final Font font, final CharSequence str, final int pixelSize, final int[/*1*/] texSize) {
- if(!renderer.isInitialized()){
+ final Font font, final CharSequence str, final int pixelSize,
+ final int[/*1*/] texSize) {
+ if( !renderer.isInitialized() ) {
throw new GLException("TextRendererImpl01: not initialized!");
}
final RenderState rs = renderer.getRenderState();
GLRegion region = getCachedRegion(font, str, pixelSize);
if(null == region) {
- region = createRegion(renderer.getRenderModes(), rs.getVertexFactory(), font, str, pixelSize);
+ region = GLRegion.create(renderer.getRenderModes());
+ addStringToRegion(region, rs.getVertexFactory(), font, str, pixelSize);
addCachedRegion(gl, font, str, pixelSize, region);
}
region.draw(gl, renderer, texSize);
}
/**
- * Render the String in 3D space wrt to the font provided at the position provided
- * the outlines will be generated, if not yet generated
+ * Render the string in 3D space w.r.t. the font and pixelSize
+ * using a temporary {@link GLRegion}, which will be destroyed afterwards.
* @param gl the current GL state
* @param font {@link Font} to be used
* @param str text to be rendered
@@ -154,27 +146,22 @@ public class TextRenderUtil {
* @throws Exception if TextRenderer not initialized
*/
public static void drawString3D(final RegionRenderer renderer, final GL2ES2 gl,
- final Font font, final CharSequence str, final int fontSize, final int[/*1*/] texSize) {
+ final Font font, final CharSequence str, final int fontSize,
+ final int[/*1*/] texSize) {
if(!renderer.isInitialized()){
throw new GLException("TextRendererImpl01: not initialized!");
}
final RenderState rs = renderer.getRenderState();
- GLRegion region = createRegion(renderer.getRenderModes(), rs.getVertexFactory(), font, str, fontSize);
+ final GLRegion region = GLRegion.create(renderer.getRenderModes());
+ addStringToRegion(region, rs.getVertexFactory(), font, str, fontSize);
region.draw(gl, renderer, texSize);
+ region.destroy(gl, renderer);
}
- /** FIXME
- public void flushCache(GL2ES2 gl) {
- Iterator<GlyphString> iterator = stringCacheMap.values().iterator();
- while(iterator.hasNext()){
- GlyphString glyphString = iterator.next();
- glyphString.destroy(gl, rs);
- }
- stringCacheMap.clear();
- stringCacheArray.clear();
- } */
-
- public void destroy(GL2ES2 gl) {
+ /**
+ * Clear all cached {@link GLRegions}.
+ */
+ public void clear(GL2ES2 gl) {
// fluchCache(gl) already called
final Iterator<GLRegion> iterator = stringCacheMap.values().iterator();
while(iterator.hasNext()){
@@ -252,9 +239,11 @@ public class TextRenderUtil {
protected final void removeCachedRegion(GL2ES2 gl, int idx) {
final String key = stringCacheArray.remove(idx);
- final GLRegion region = stringCacheMap.remove(key);
- if(null != region) {
- region.destroy(gl, renderer);
+ if( null != key ) {
+ final GLRegion region = stringCacheMap.remove(key);
+ if(null != region) {
+ region.destroy(gl, renderer);
+ }
}
}
diff --git a/src/jogl/classes/com/jogamp/graph/font/Font.java b/src/jogl/classes/com/jogamp/graph/font/Font.java
index afffe0654..122015218 100644
--- a/src/jogl/classes/com/jogamp/graph/font/Font.java
+++ b/src/jogl/classes/com/jogamp/graph/font/Font.java
@@ -73,6 +73,9 @@ public interface Font {
/**
* Glyph for font
+ *
+ * http://developer.apple.com/textfonts/TTRefMan/RM06/Chap6cmap.html
+ * http://developer.apple.com/textfonts/TTRefMan/RM06/Chap6glyf.html
*/
public interface Glyph {
// reserved special glyph IDs
@@ -103,11 +106,12 @@ public interface Font {
public StringBuilder getAllNames(StringBuilder string, String separator);
- public float getAdvanceWidth(int i, float pixelSize);
+ public float getAdvanceWidth(int glyphID, float pixelSize);
public Metrics getMetrics();
public Glyph getGlyph(char symbol);
public int getNumGlyphs();
+ public float getLineHeight(float pixelSize);
public float getStringWidth(CharSequence string, float pixelSize);
public float getStringHeight(CharSequence string, float pixelSize);
public AABBox getStringBounds(CharSequence string, float pixelSize);
diff --git a/src/jogl/classes/jogamp/graph/font/typecast/TypecastFont.java b/src/jogl/classes/jogamp/graph/font/typecast/TypecastFont.java
index 81c06cd83..8dd9ce4d7 100644
--- a/src/jogl/classes/jogamp/graph/font/typecast/TypecastFont.java
+++ b/src/jogl/classes/jogamp/graph/font/typecast/TypecastFont.java
@@ -166,8 +166,8 @@ class TypecastFont implements Font {
}
@Override
- public float getAdvanceWidth(int i, float pixelSize) {
- return font.getHmtxTable().getAdvanceWidth(i) * metrics.getScale(pixelSize);
+ public float getAdvanceWidth(int glyphID, float pixelSize) {
+ return font.getHmtxTable().getAdvanceWidth(glyphID) * metrics.getScale(pixelSize);
}
@Override
@@ -197,7 +197,7 @@ class TypecastFont implements Font {
if(null == glyph) {
throw new RuntimeException("Could not retrieve glyph for symbol: <"+symbol+"> "+(int)symbol+" -> glyph id "+code);
}
- final OutlineShape shape = TypecastRenderer.buildShape(glyph, vertexFactory);
+ final OutlineShape shape = TypecastRenderer.buildShape(symbol, glyph, vertexFactory);
result = new TypecastGlyph(this, symbol, code, glyph.getBBox(), glyph.getAdvanceWidth(), shape);
if(DEBUG) {
System.err.println("New glyph: " + (int)symbol + " ( " + symbol +" ) -> " + code + ", contours " + glyph.getPointCount() + ": " + shape);
@@ -222,12 +222,21 @@ class TypecastFont implements Font {
}
@Override
+ public float getLineHeight(float pixelSize) {
+ final Metrics metrics = getMetrics();
+ final float lineGap = metrics.getLineGap(pixelSize) ; // negative value!
+ final float ascent = metrics.getAscent(pixelSize) ; // negative value!
+ final float descent = metrics.getDescent(pixelSize) ; // positive value!
+ final float advanceY = lineGap - descent + ascent; // negative value!
+ return -advanceY;
+ }
+
+ @Override
public float getStringWidth(CharSequence string, float pixelSize) {
float width = 0;
final int len = string.length();
- for (int i=0; i< len; i++)
- {
- char character = string.charAt(i);
+ for (int i=0; i< len; i++) {
+ final char character = string.charAt(i);
if (character == '\n') {
width = 0;
} else {
@@ -235,7 +244,6 @@ class TypecastFont implements Font {
width += glyph.getAdvance(pixelSize, false);
}
}
-
return (int)(width + 0.5f);
}
@@ -243,12 +251,10 @@ class TypecastFont implements Font {
public float getStringHeight(CharSequence string, float pixelSize) {
int height = 0;
- for (int i=0; i<string.length(); i++)
- {
- char character = string.charAt(i);
- if (character != ' ')
- {
- Glyph glyph = getGlyph(character);
+ for (int i=0; i<string.length(); i++) {
+ final char character = string.charAt(i);
+ if (character != ' ') {
+ final Glyph glyph = getGlyph(character);
AABBox bbox = glyph.getBBox(pixelSize);
height = (int)Math.ceil(Math.max(bbox.getHeight(), height));
}
@@ -261,11 +267,8 @@ class TypecastFont implements Font {
if (string == null) {
return new AABBox();
}
- final Metrics metrics = getMetrics();
- final float lineGap = metrics.getLineGap(pixelSize);
- final float ascent = metrics.getAscent(pixelSize);
- final float descent = metrics.getDescent(pixelSize);
- final float advanceY = lineGap - descent + ascent;
+ final float lineHeight = getLineHeight(pixelSize);
+
float totalHeight = 0;
float totalWidth = 0;
float curLineWidth = 0;
@@ -274,14 +277,14 @@ class TypecastFont implements Font {
if (character == '\n') {
totalWidth = Math.max(curLineWidth, totalWidth);
curLineWidth = 0;
- totalHeight -= advanceY;
+ totalHeight += lineHeight;
continue;
}
Glyph glyph = getGlyph(character);
curLineWidth += glyph.getAdvance(pixelSize, true);
}
if (curLineWidth > 0) {
- totalHeight -= advanceY;
+ totalHeight += lineHeight;
totalWidth = Math.max(curLineWidth, totalWidth);
}
return new AABBox(0, 0, 0, totalWidth, totalHeight,0);