aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorSven Gothel <[email protected]>2011-03-30 06:59:43 +0200
committerSven Gothel <[email protected]>2011-03-30 06:59:43 +0200
commit55356d999638491980a90cb2263b55c5d2e53e91 (patch)
tree711457c8b1bedcf1d71fd0ba0252155b2895ce7f
parent5f0293b84d0146d9e750ea7e75caaa101ae3b3c3 (diff)
Font Refactoring ; Misc Changes ; Demo/Test Update
Font Refactoring - Notion of distributed FontSet - FontFactory may produce FontSet and/or a Font by absolute ttf file path - Adding support for free Ubuntu fonts - Remove Vertex.Factory dependency for Font creation - Typecast Impl - Fix CmapTable selection - Fix horizontal spacing of space - Misc Changes - HwTextRenderer - Offer reshape for perspective and orthogonal view - Expose PMVMatrix, allowing user to setup their own view math. Demo Update - Dump font set a-zA-Z... - Dump 'lazy dog ..' text - Action: - s: toogle 'font set' - f: toggle fps - v: toggle v-sync - space: toggle font (ubuntu/java) - formated screenshot filename w/ font name Test Update: - add font set iteration
-rw-r--r--src/com/jogamp/graph/curve/HwTextRenderer.java72
-rw-r--r--src/com/jogamp/graph/font/Font.java10
-rw-r--r--src/com/jogamp/graph/font/FontFactory.java60
-rw-r--r--src/com/jogamp/graph/font/FontSet.java60
-rw-r--r--src/demo/GPUTextGLListenerBase01.java115
-rw-r--r--src/demo/GPUTextNewtDemo01.java12
-rw-r--r--src/demo/GPUTextNewtDemo02.java13
-rw-r--r--src/jogamp/graph/font/FontConstructor.java34
-rw-r--r--src/jogamp/graph/font/FontInt.java6
-rw-r--r--src/jogamp/graph/font/JavaFontLoader.java157
-rw-r--r--src/jogamp/graph/font/UbuntuFontLoader.java115
-rw-r--r--src/jogamp/graph/font/typecast/TypecastFont.java148
-rw-r--r--src/jogamp/graph/font/typecast/TypecastFontConstructor.java (renamed from src/jogamp/graph/font/typecast/TypecastFontFactory.java)43
-rw-r--r--src/jogamp/graph/font/typecast/TypecastHMetrics.java (renamed from src/jogamp/graph/font/typecast/TypecastMetrics.java)11
-rw-r--r--src/jogamp/graph/font/typecast/TypecastRenderer.java14
-rw-r--r--src/jogamp/graph/geom/plane/AffineTransform.java7
-rw-r--r--src/net/java/dev/typecast/ot/table/BaseTable.java1
-rw-r--r--src/net/java/dev/typecast/ot/table/CvtTable.java1
-rw-r--r--src/net/java/dev/typecast/ot/table/Os2Table.java1
-rw-r--r--src/net/java/dev/typecast/ot/table/Program.java1
-rw-r--r--src/net/java/dev/typecast/ot/table/TableFactory.java1
-rwxr-xr-xsrc/test/com/jogamp/opengl/test/junit/graph/TestHwTextRenderer01.java134
22 files changed, 688 insertions, 328 deletions
diff --git a/src/com/jogamp/graph/curve/HwTextRenderer.java b/src/com/jogamp/graph/curve/HwTextRenderer.java
index c5f11d522..f3a15975a 100644
--- a/src/com/jogamp/graph/curve/HwTextRenderer.java
+++ b/src/com/jogamp/graph/curve/HwTextRenderer.java
@@ -38,13 +38,10 @@ import javax.media.opengl.fixedfunc.GLMatrixFunc;
import jogamp.graph.curve.text.GlyphString;
import jogamp.graph.font.FontInt;
-import jogamp.graph.font.typecast.TypecastFontFactory;
import jogamp.graph.geom.plane.AffineTransform;
import jogamp.graph.geom.plane.Path2D;
-import com.jogamp.common.util.ReflectionUtil;
import com.jogamp.graph.font.Font;
-import com.jogamp.graph.font.FontFactory;
import com.jogamp.graph.geom.Vertex;
import com.jogamp.graph.geom.opengl.SVertex;
import jogamp.opengl.Debug;
@@ -57,28 +54,6 @@ public class HwTextRenderer {
protected static final boolean DEBUG = Debug.debug("TextRenderer");
static final boolean FONTTOOL_CUSTOM = false;
- private static FontFactory fontFactory;
-
- static {
- FontFactory _fontFactory = null;
-
- if(FONTTOOL_CUSTOM) {
- _fontFactory = (FontFactory) ReflectionUtil.createInstance("jogamp.graph.font.ttf.TTFFontFactory", HwTextRenderer.class.getClassLoader());
- if(null!=_fontFactory) {
- System.err.println("Using custom font tool");
- }
- }
- if(null==_fontFactory) {
- _fontFactory = new TypecastFontFactory();
- }
- fontFactory = _fontFactory;
- }
-
-
- public static FontFactory getFontFactory() {
- return fontFactory;
- }
-
private ShaderState st = new ShaderState();
private PMVMatrix pmvMatrix = new PMVMatrix();
@@ -113,19 +88,6 @@ public class HwTextRenderer {
this.regionType = type;
}
- public Font createFont(Vertex.Factory<? extends Vertex> factory, String name) {
- return fontFactory.createFont(factory, name);
- }
-
-
- public Font createFont(Vertex.Factory<? extends Vertex> factory,
- String[] families,
- String style,
- String variant,
- String weight) {
- return fontFactory.createFont(factory, families, style, variant, weight);
- }
-
/**
* Initialize shaders and bindings for GPU based text Rendering,
* should be called only once.
@@ -162,9 +124,9 @@ public class HwTextRenderer {
gl.glBlendFunc(GL2ES2.GL_SRC_ALPHA, GL2ES2.GL_ONE_MINUS_SRC_ALPHA);
ShaderCode rsVp = ShaderCode.create(gl, GL2ES2.GL_VERTEX_SHADER, 1, HwTextRenderer.class,
- "../shader", "../shader/bin", "curverenderer");
+ "shader", "shader/bin", "curverenderer");
ShaderCode rsFp = ShaderCode.create(gl, GL2ES2.GL_FRAGMENT_SHADER, 1, HwTextRenderer.class,
- "../shader", "../shader/bin", "curverenderer");
+ "shader", "shader/bin", "curverenderer");
ShaderProgram sp = new ShaderProgram();
sp.add(rsVp);
@@ -259,6 +221,8 @@ public class HwTextRenderer {
}
}
+ public final PMVMatrix matrix() { return pmvMatrix; }
+
public void rotate(GL2ES2 gl, float angle, float x, float y, float z){
pmvMatrix.glRotatef(angle, x, y, z);
if(null != gl && st.inUse()) {
@@ -279,7 +243,13 @@ public class HwTextRenderer {
st.glUniform(gl, mgl_PMVMatrix);
}
}
-
+
+ public void setMatrix(GL2ES2 gl){
+ if(null != gl && st.inUse()) {
+ st.glUniform(gl, mgl_PMVMatrix);
+ }
+ }
+
public void updateAllShaderValues(GL2ES2 gl) {
if(null != gl && st.inUse()) {
st.glUniform(gl, mgl_PMVMatrix);
@@ -297,7 +267,7 @@ public class HwTextRenderer {
* @param far
* @return
*/
- public boolean reshape(GL2ES2 gl, float angle, int width, int height, float near, float far){
+ public boolean reshapePerspective(GL2ES2 gl, float angle, int width, int height, float near, float far){
win_width = width;
win_height = height;
float ratio = (float)width/(float)height;
@@ -305,10 +275,26 @@ public class HwTextRenderer {
pmvMatrix.glLoadIdentity();
pmvMatrix.gluPerspective(angle, ratio, near, far);
- st.glUniform(gl, mgl_PMVMatrix);
+ if(null != gl) {
+ st.glUniform(gl, mgl_PMVMatrix);
+ }
return true;
}
+
+ public boolean reshapeOrtho(GL2ES2 gl, int width, int height, float near, float far) {
+ win_width = width;
+ win_height = height;
+ pmvMatrix.glMatrixMode(GLMatrixFunc.GL_PROJECTION);
+ pmvMatrix.glLoadIdentity();
+ pmvMatrix.glOrthof(0, width, 0, height, near, far);
+
+ if(null != gl) {
+ st.glUniform(gl, mgl_PMVMatrix);
+ }
+
+ return true;
+ }
private GlyphString createString(GL2ES2 gl, Font font, int size, String str) {
AffineTransform affineTransform = new AffineTransform(pointFactory);
diff --git a/src/com/jogamp/graph/font/Font.java b/src/com/jogamp/graph/font/Font.java
index fbdf1f474..a4ab527e2 100644
--- a/src/com/jogamp/graph/font/Font.java
+++ b/src/com/jogamp/graph/font/Font.java
@@ -34,17 +34,27 @@ import com.jogamp.graph.geom.AABBox;
*
* TrueType Font Specification:
* http://developer.apple.com/fonts/ttrefman/rm06/Chap6.html
+ *
+ * TrueType Font Table Introduction:
+ * http://scripts.sil.org/cms/scripts/page.php?item_id=IWS-Chapter08
*/
public interface Font {
/**
* Metrics for font
+ *
+ * Depending on the font's direction, horizontal or vertical,
+ * the following tables shall be used:
+ *
+ * Vertical http://developer.apple.com/fonts/TTRefMan/RM06/Chap6vhea.html
+ * Horizontal http://developer.apple.com/fonts/TTRefMan/RM06/Chap6hhea.html
*/
public interface Metrics {
float getAscent(float pixelSize);
float getDescent(float pixelSize);
float getLineGap(float pixelSize);
+ float getMaxExtend(float pixelSize);
float getScale(float pixelSize);
AABBox getBBox(float pixelSize);
}
diff --git a/src/com/jogamp/graph/font/FontFactory.java b/src/com/jogamp/graph/font/FontFactory.java
index b595413ba..1752a693c 100644
--- a/src/com/jogamp/graph/font/FontFactory.java
+++ b/src/com/jogamp/graph/font/FontFactory.java
@@ -1,5 +1,5 @@
/**
- * Copyright 2010 JogAmp Community. All rights reserved.
+ * 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:
@@ -27,16 +27,54 @@
*/
package com.jogamp.graph.font;
-import com.jogamp.graph.geom.Vertex;
+import java.security.AccessController;
-public interface FontFactory {
+import com.jogamp.common.util.ReflectionUtil;
- Font createFont(Vertex.Factory<? extends Vertex> factory,
- String[] families,
- String style,
- String variant,
- String weight);
+import jogamp.graph.font.FontConstructor;
+import jogamp.graph.font.JavaFontLoader;
+import jogamp.graph.font.UbuntuFontLoader;
+import jogamp.opengl.Debug;
- Font createFont(Vertex.Factory<? extends Vertex> factory,
- String name);
-} \ No newline at end of file
+public class FontFactory {
+ /** Ubuntu is the default font family */
+ public static final int UBUNTU = 0;
+
+ /** Java fonts are optional */
+ public static final int JAVA = 1;
+
+ private static final FontConstructor fontConstr;
+
+ static {
+ /**
+ * For example:
+ * "jogamp.graph.font.typecast.TypecastFontFactory" (default)
+ * "jogamp.graph.font.ttf.TTFFontImpl"
+ */
+ String fontImplName = Debug.getProperty("FontImpl", true, AccessController.getContext());
+ if(null == fontImplName) {
+ fontImplName = "jogamp.graph.font.typecast.TypecastFontConstructor";
+ }
+ fontConstr = (FontConstructor) ReflectionUtil.createInstance(fontImplName, FontFactory.class.getClassLoader());
+ }
+
+ public static final FontConstructor getFontConstr() { return fontConstr; }
+
+ public static final FontSet getDefault() {
+ return get(UBUNTU);
+ }
+
+ public static final FontSet get(int font) {
+ switch (font) {
+ case JAVA:
+ return JavaFontLoader.get();
+ default:
+ return UbuntuFontLoader.get();
+ }
+ }
+
+ public static final Font get(String path) {
+ return fontConstr.create(path);
+ }
+
+}
diff --git a/src/com/jogamp/graph/font/FontSet.java b/src/com/jogamp/graph/font/FontSet.java
new file mode 100644
index 000000000..0cee81124
--- /dev/null
+++ b/src/com/jogamp/graph/font/FontSet.java
@@ -0,0 +1,60 @@
+/**
+ * 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.font;
+
+
+public interface FontSet {
+
+ /** Font family REGULAR **/
+ public static final int FAMILY_REGULAR = 0;
+
+ /** Font family LIGHT **/
+ public static final int FAMILY_LIGHT = 1;
+
+ /** Font family MEDIUM **/
+ public static final int FAMILY_MEDIUM = 2;
+
+ /** Font family CONDENSED **/
+ public static final int FAMILY_CONDENSED = 3;
+
+ /** Font family MONO **/
+ public static final int FAMILY_MONOSPACED = 4;
+
+ /** SERIF style/family bit flag. Fallback to Sans Serif. */
+ public static final int STYLE_SERIF = 1 << 1;
+
+ /** BOLD style bit flag */
+ public static final int STYLE_BOLD = 1 << 2;
+
+ /** ITALIC style bit flag */
+ public static final int STYLE_ITALIC = 1 << 3;
+
+ Font getDefault();
+
+ Font get(int family, int stylebits);
+}
diff --git a/src/demo/GPUTextGLListenerBase01.java b/src/demo/GPUTextGLListenerBase01.java
index 4e3a57fd9..eee1efbdb 100644
--- a/src/demo/GPUTextGLListenerBase01.java
+++ b/src/demo/GPUTextGLListenerBase01.java
@@ -29,31 +29,52 @@ package demo;
import java.io.File;
import java.io.IOException;
+import java.io.PrintWriter;
+import java.io.StringWriter;
import javax.media.opengl.GL;
import javax.media.opengl.GL2ES2;
+import javax.media.opengl.GLAnimatorControl;
import javax.media.opengl.GLAutoDrawable;
import javax.media.opengl.GLEventListener;
import javax.media.opengl.GLException;
import javax.media.opengl.GLPipelineFactory;
+import javax.media.opengl.GLRunnable;
import com.jogamp.graph.curve.HwTextRenderer;
import com.jogamp.graph.font.Font;
+import com.jogamp.graph.font.FontFactory;
import com.jogamp.graph.geom.Vertex;
import com.jogamp.newt.event.KeyEvent;
import com.jogamp.newt.event.KeyListener;
import com.jogamp.newt.opengl.GLWindow;
import com.jogamp.opengl.util.awt.Screenshot;
+/**
+ *
+ * Action Keys:
+ * - 1/2: zoom in/out
+ * - 3/4: font +/-
+ * - 6/7: 2nd pass texture size
+ * - 0/9: rotate
+ * - s: toogle draw 'font set'
+ * - f: toggle draw fps
+ * - v: toggle v-sync
+ * - space: toggle font (ubuntu/java)
+ */
public abstract class GPUTextGLListenerBase01 implements GLEventListener {
Vertex.Factory<? extends Vertex> vfactory;
- protected HwTextRenderer textRenderer;
+ protected HwTextRenderer textRenderer;
+ int fontSet = FontFactory.UBUNTU;
Font font;
boolean debug;
boolean trace;
KeyAction keyAction;
+ volatile GLAutoDrawable autoDrawable = null;
+ boolean drawFontSet = true;
+ boolean drawFPS = true;
boolean updateFont = true;
int fontSize = 40;
final int fontSizeModulo = 100;
@@ -71,15 +92,15 @@ public abstract class GPUTextGLListenerBase01 implements GLEventListener {
static final String text2;
static {
- //text1 = "abcdef\nghijklmn\nopqrstuv\nwxyz\n0123456789";
- text1 = "abcdef\nghijklmn\nopqrstuv\nwxyz\n#$!%-+=";
- text2 = text1.toUpperCase();
+ text1 = "abcdefghijklmnopqrstuvwxyz\nABCDEFGHIJKLMNOPQRSTUVWXYZ\n0123456789.:,;(*!?/\\\")$%^&-+@~#<>{}[]";
+ text2 = "The quick brown fox jumps over the lazy dog";
}
public GPUTextGLListenerBase01(Vertex.Factory<? extends Vertex> vfactory, int mode, boolean debug, boolean trace) {
+ // this.font = FontFactory.get(FontFactory.JAVA).getDefault();
+ this.font = FontFactory.get(fontSet).getDefault();
this.vfactory = vfactory;
this.textRenderer = new HwTextRenderer(vfactory, mode);
- this.font = textRenderer.createFont(vfactory, "Lucida Sans Regular");
this.debug = debug;
this.trace = trace;
}
@@ -94,8 +115,8 @@ public abstract class GPUTextGLListenerBase01 implements GLEventListener {
}
public void init(GLAutoDrawable drawable) {
+ autoDrawable = drawable;
GL2ES2 gl = drawable.getGL().getGL2ES2();
-
if(debug) {
gl = gl.getContext().setGL( GLPipelineFactory.create("javax.media.opengl.Debug", null, gl, null) ).getGL2ES2();
}
@@ -109,7 +130,7 @@ public abstract class GPUTextGLListenerBase01 implements GLEventListener {
GL2ES2 gl = drawable.getGL().getGL2ES2();
gl.glViewport(xstart, ystart, width, height);
- textRenderer.reshape(gl, 45.0f, width, height, 0.1f, 7000.0f);
+ textRenderer.reshapePerspective(gl, 45.0f, width, height, 0.1f, 7000.0f);
dumpMatrix(true);
}
@@ -120,9 +141,34 @@ public abstract class GPUTextGLListenerBase01 implements GLEventListener {
gl.glClearColor(1.0f, 1.0f, 1.0f, 1.0f); // Demo02 needs to have this set here as well .. hmm ?
gl.glClear(GL.GL_COLOR_BUFFER_BIT | GL.GL_DEPTH_BUFFER_BIT);
- if(updateMatrix) {
- textRenderer.resetMatrix(gl);
- textRenderer.translate(gl, xTran, yTran, zoom);
+ if(drawFPS || drawFontSet || updateMatrix) {
+ final int width = drawable.getWidth();
+ final int height = drawable.getHeight();
+ final GLAnimatorControl animator = drawable.getAnimator();
+ final boolean _drawFPS = drawFPS && null != animator && animator.getTotalFrames()>10;
+
+ if(_drawFPS || drawFontSet) {
+ textRenderer.reshapeOrtho(null, width, height, 0.1f, 7000.0f);
+ }
+ if(_drawFPS) {
+ final float fps = ( animator.getTotalFrames() * 1000.0f ) / (float) animator.getDuration() ;
+ final String fpsS = String.valueOf(fps);
+ final int fpsSp = fpsS.indexOf('.');
+ textRenderer.resetMatrix(null);
+ textRenderer.translate(gl, 0, 0, -6000);
+ textRenderer.renderString3D(gl, font, fpsS.substring(0, fpsSp+2), position, fontSize, texSize);
+ }
+ if(drawFontSet) {
+ textRenderer.resetMatrix(null);
+ textRenderer.translate(gl, 0, height-50, -6000);
+ textRenderer.renderString3D(gl, font, text1, position, fontSize, texSize);
+ }
+ if(_drawFPS || drawFontSet) {
+ textRenderer.reshapePerspective(null, 45.0f, width, height, 0.1f, 7000.0f);
+ }
+
+ textRenderer.resetMatrix(null);
+ textRenderer.translate(null, xTran, yTran, zoom);
textRenderer.rotate(gl, ang, 0, 1, 0);
updateMatrix = false;
}
@@ -131,6 +177,7 @@ public abstract class GPUTextGLListenerBase01 implements GLEventListener {
}
public void dispose(GLAutoDrawable drawable) {
+ autoDrawable = null;
GL2ES2 gl = drawable.getGL().getGL2ES2();
textRenderer.dispose(gl);
}
@@ -147,6 +194,16 @@ public abstract class GPUTextGLListenerBase01 implements GLEventListener {
dumpMatrix(false);
}
+ public void nextFontSet() {
+ fontSet = ( fontSet == FontFactory.UBUNTU ) ? FontFactory.JAVA : FontFactory.UBUNTU ;
+ font = FontFactory.get(fontSet).getDefault();
+ }
+
+ public void setFontSet(int set, int family, int stylebits) {
+ fontSet = set;
+ font = FontFactory.get(fontSet).get(family, stylebits);
+ }
+
public void move(float x, float y){
xTran += x;
yTran += y;
@@ -183,9 +240,13 @@ public abstract class GPUTextGLListenerBase01 implements GLEventListener {
window.removeKeyListener(keyAction);
}
- public void printScreen(GLWindow window, String dir, String tech, boolean exportAlpha) throws GLException, IOException{
- String filename = dir + tech + "-" + window.getWidth()+ "x" + window.getHeight() + "-T" + texSize + "-Z" + Math.abs(zoom) +".tga";
- Screenshot.writeToTargaFile(new File(filename), window.getWidth(), window.getHeight(), exportAlpha);
+ public void printScreen(String dir, String tech, int width, int height, boolean exportAlpha) throws GLException, IOException {
+ StringWriter sw = new StringWriter();
+ PrintWriter pw = new PrintWriter(sw);
+ pw.printf("-%03dx%03d-Z%04d-T%04d-%s", width, height, (int)Math.abs(zoom), texSize, font.getName());
+
+ String filename = dir + tech + sw +".tga";
+ Screenshot.writeToTargaFile(new File(filename), width, height, exportAlpha);
}
public class KeyAction implements KeyListener {
@@ -228,6 +289,34 @@ public abstract class GPUTextGLListenerBase01 implements GLEventListener {
else if(arg0.getKeyCode() == KeyEvent.VK_9){
rotate(-1);
}
+ else if(arg0.getKeyChar() == 's') {
+ drawFontSet = !drawFontSet;
+ System.err.println("Draw font set: "+drawFontSet);
+ }
+ else if(arg0.getKeyChar() == 'f'){
+ drawFPS = !drawFPS;
+ System.err.println("Draw FPS: "+drawFPS);
+ }
+ else if(arg0.getKeyChar() == 'v') {
+ if(null != autoDrawable) {
+ autoDrawable.invoke(false, new GLRunnable() {
+ public void run(GLAutoDrawable drawable) {
+ GL gl = drawable.getGL();
+ int i = gl.getSwapInterval();
+ i = i==0 ? 1 : 0;
+ gl.setSwapInterval(i);
+ final GLAnimatorControl a = drawable.getAnimator();
+ if( null != a ) {
+ a.resetCounter();
+ }
+ System.err.println("Swap Interval: "+i);
+ }
+ });
+ }
+ }
+ else if(arg0.getKeyChar() == ' ') {
+ nextFontSet();
+ }
}
public void keyTyped(KeyEvent arg0) {}
public void keyReleased(KeyEvent arg0) {}
diff --git a/src/demo/GPUTextNewtDemo01.java b/src/demo/GPUTextNewtDemo01.java
index a07ead417..934eba1ba 100644
--- a/src/demo/GPUTextNewtDemo01.java
+++ b/src/demo/GPUTextNewtDemo01.java
@@ -36,7 +36,7 @@ import javax.media.opengl.GLProfile;
import com.jogamp.graph.curve.Region;
import com.jogamp.graph.geom.opengl.SVertex;
import com.jogamp.newt.opengl.GLWindow;
-import com.jogamp.opengl.util.FPSAnimator;
+import com.jogamp.opengl.util.Animator;
public class GPUTextNewtDemo01 {
static final boolean DEBUG = false;
@@ -61,14 +61,16 @@ public class GPUTextNewtDemo01 {
window = GLWindow.create(caps);
window.setPosition(10, 10);
- window.setSize(400, 400);
+ window.setSize(800, 400);
window.setTitle("GPU Text Newt Demo 01 - r2t0 msaa1");
textGLListener = new TextGLListener();
textGLListener.attachTo(window);
+ window.enablePerfLog(true);
window.setVisible(true);
- FPSAnimator animator = new FPSAnimator(10);
+ // FPSAnimator animator = new FPSAnimator(10);
+ Animator animator = new Animator();
animator.add(window);
animator.start();
}
@@ -76,8 +78,10 @@ public class GPUTextNewtDemo01 {
private class TextGLListener extends GPUTextGLListenerBase01 {
public TextGLListener() {
super(SVertex.factory(), Region.SINGLE_PASS, DEBUG, TRACE);
+ // FBO size unrelated with 1 pass
//setMatrix(-10, 10, 0f, -70, 0);
- setMatrix(-10, 10, 0f, -100, 400);
+ // setMatrix(-80, -30, 0f, -100, 0);
+ setMatrix(-400, -30, 0f, -500, 0);
}
public void init(GLAutoDrawable drawable) {
diff --git a/src/demo/GPUTextNewtDemo02.java b/src/demo/GPUTextNewtDemo02.java
index 012ee9936..b46053f1d 100644
--- a/src/demo/GPUTextNewtDemo02.java
+++ b/src/demo/GPUTextNewtDemo02.java
@@ -36,7 +36,7 @@ import javax.media.opengl.GLProfile;
import com.jogamp.graph.curve.Region;
import com.jogamp.graph.geom.opengl.SVertex;
import com.jogamp.newt.opengl.GLWindow;
-import com.jogamp.opengl.util.FPSAnimator;
+import com.jogamp.opengl.util.Animator;
public class GPUTextNewtDemo02 {
/**
@@ -70,15 +70,17 @@ public class GPUTextNewtDemo02 {
window = GLWindow.create(caps);
window.setPosition(10, 10);
- window.setSize(400, 400);
+ window.setSize(800, 400);
window.setTitle("GPU Text Newt Demo 02 - r2t1 msaa0");
textGLListener = new TextGLListener();
textGLListener.attachTo(window);
+ window.enablePerfLog(true);
window.setVisible(true);
- FPSAnimator animator = new FPSAnimator(60);
+ // FPSAnimator animator = new FPSAnimator(60);
+ Animator animator = new Animator();
animator.add(window);
animator.start();
}
@@ -86,7 +88,10 @@ public class GPUTextNewtDemo02 {
private class TextGLListener extends GPUTextGLListenerBase01 {
public TextGLListener() {
super(SVertex.factory(), Region.TWO_PASS, DEBUG, TRACE);
- setMatrix(-10, 10, 0f, -100, 400);
+ // FIXME: Rami will fix FBO size !!
+ // setMatrix(-10, 10, 0f, -100, 400);
+ // setMatrix(-80, -30, 0f, -100, window.getWidth()*3);
+ setMatrix(-400, -30, 0f, -500, window.getWidth()*3);
}
public void init(GLAutoDrawable drawable) {
diff --git a/src/jogamp/graph/font/FontConstructor.java b/src/jogamp/graph/font/FontConstructor.java
new file mode 100644
index 000000000..a382d292e
--- /dev/null
+++ b/src/jogamp/graph/font/FontConstructor.java
@@ -0,0 +1,34 @@
+/**
+ * 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 jogamp.graph.font;
+
+import com.jogamp.graph.font.Font;
+
+public interface FontConstructor {
+ Font create(String name);
+}
diff --git a/src/jogamp/graph/font/FontInt.java b/src/jogamp/graph/font/FontInt.java
index c18787723..4d9390da2 100644
--- a/src/jogamp/graph/font/FontInt.java
+++ b/src/jogamp/graph/font/FontInt.java
@@ -35,6 +35,12 @@ import com.jogamp.graph.font.Font;
public interface FontInt extends Font {
public interface Glyph extends Font.Glyph {
+ // reserved special glyph IDs
+ // http://scripts.sil.org/cms/scripts/page.php?item_id=IWS-Chapter08#ba57949e
+ public static final int ID_UNKNOWN = 0;
+ public static final int ID_CR = 2;
+ public static final int ID_SPACE = 3;
+
public Path2D getPath(); // unscaled path
public Path2D getPath(float pixelSize);
}
diff --git a/src/jogamp/graph/font/JavaFontLoader.java b/src/jogamp/graph/font/JavaFontLoader.java
index f6954944d..6769a691a 100644
--- a/src/jogamp/graph/font/JavaFontLoader.java
+++ b/src/jogamp/graph/font/JavaFontLoader.java
@@ -27,85 +27,92 @@
*/
package jogamp.graph.font;
-public class JavaFontLoader {
+import com.jogamp.common.util.IntObjectHashMap;
+import com.jogamp.graph.font.Font;
+import com.jogamp.graph.font.FontSet;
+import com.jogamp.graph.font.FontFactory;
- static String javaFontPath;
- static
- {
- javaFontPath = System.getProperty("java.home") + "/lib/fonts/";
- }
+public class JavaFontLoader implements FontSet {
+
+ final static FontSet fontLoader = new JavaFontLoader();
- public static final int MAX_BITMAP_FONT_SIZE = 120;
+ public static FontSet get() {
+ return fontLoader;
+ }
+
+ final static String availableFontFileNames[] =
+ {
+ /* 00 */ "LucidaBrightRegular.ttf",
+ /* 01 */ "LucidaBrightItalic.ttf",
+ /* 02 */ "LucidaBrightDemiBold.ttf",
+ /* 03 */ "LucidaBrightDemiItalic.ttf",
+ /* 04 */ "LucidaSansRegular.ttf",
+ /* 05 */ "LucidaSansDemiBold.ttf",
+ /* 06 */ "LucidaTypewriterRegular.ttf",
+ /* 07 */ "LucidaTypewriterBold.ttf",
+ };
+
+ final String javaFontPath;
+
+ private JavaFontLoader() {
+ javaFontPath = System.getProperty("java.home") + "/lib/fonts/";
+ }
- public static final int MONOSPACED = 1;
- public static final int SERIF = 2;
- public static final int SANSERIF = 3;
- public static final int CURSIVE = 4;
- public static final int FANTASY = 5;
-
- final static String availableJavaFontNames[] =
- {
- "Lucida Bright Regular",
- "Lucida Bright Italic",
- "Lucida Bright Demibold",
- "Lucida Bright Demibold Italic",
- "Lucida Sans Regular",
- "Lucida Sans Demibold",
- "Lucida Sans Typewriter Regular",
- "Lucida Sans Typewriter Bold",
- };
- static public String[] getAvailableNames()
- {
- return availableJavaFontNames;
- }
-
- final static String availableJavaFontFileNames[] =
- {
- "LucidaBrightRegular.ttf",
- "LucidaBrightItalic.ttf",
- "LucidaBrightDemiBold.ttf",
- "LucidaBrightDemiItalic.ttf",
- "LucidaSansRegular.ttf",
- "LucidaSansDemiBold.ttf",
- "LucidaTypewriterRegular.ttf",
- "LucidaTypewriterBold.ttf",
- };
+ static final IntObjectHashMap fontMap = new IntObjectHashMap();
+
+ public Font getDefault() {
+ return get(FAMILY_REGULAR, 0) ; // Sans Serif Regular
+ }
+
+ public Font get(int family, int style) {
+ Font font = (Font)fontMap.get( ( family << 8 ) | style );
+ if (font != null) {
+ return font;
+ }
- static public String get(int type)
- {
- String font = null;
-
- switch (type)
- {
- case MONOSPACED:
- font = getByName("Lucida Sans Typewriter Regular");
- break;
- case SERIF:
- font = getByName("Lucida Bright Regular");
- break;
- case SANSERIF:
- font = getByName("Lucida Sans Regular");
- break;
- case CURSIVE:
- font = getByName("Lucida Bright Regular");
- break;
- case FANTASY:
- font = getByName("Lucida Sans Regular");
- break;
- }
+ // 1st process Sans Serif (2 fonts)
+ if( 0 == ( style & STYLE_SERIF ) ) {
+ if( 0 != ( style & STYLE_BOLD ) ) {
+ font = abspath(availableFontFileNames[5]);
+ } else {
+ font = abspath(availableFontFileNames[4]);
+ }
+ return font;
+ }
+
+ // Serif Fonts ..
+ switch (family) {
+ case FAMILY_LIGHT:
+ case FAMILY_MEDIUM:
+ case FAMILY_CONDENSED:
+ case FAMILY_REGULAR:
+ if( 0 != ( style & STYLE_BOLD ) ) {
+ if( 0 != ( style & STYLE_ITALIC ) ) {
+ font = abspath(availableFontFileNames[3]);
+ } else {
+ font = abspath(availableFontFileNames[2]);
+ }
+ } else if( 0 != ( style & STYLE_ITALIC ) ) {
+ font = abspath(availableFontFileNames[1]);
+ } else {
+ font = abspath(availableFontFileNames[0]);
+ }
+ break;
+
+ case FAMILY_MONOSPACED:
+ if( 0 != ( style & STYLE_BOLD ) ) {
+ font = abspath(availableFontFileNames[7]);
+ } else {
+ font = abspath(availableFontFileNames[6]);
+ }
+ break;
+ }
- return font;
- }
+ return font;
+ }
+
+ Font abspath(String fname) {
+ return FontFactory.getFontConstr().create(javaFontPath+fname);
+ }
- static public String getByName(String name)
- {
- for (int i=0; i<availableJavaFontNames.length; i++)
- {
- if (name.equals(availableJavaFontNames[i]) == true)
- {
- return javaFontPath+availableJavaFontFileNames[i];
- }
- }
- return null;
- }
}
diff --git a/src/jogamp/graph/font/UbuntuFontLoader.java b/src/jogamp/graph/font/UbuntuFontLoader.java
new file mode 100644
index 000000000..77d2cea03
--- /dev/null
+++ b/src/jogamp/graph/font/UbuntuFontLoader.java
@@ -0,0 +1,115 @@
+/**
+ * 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 jogamp.graph.font;
+
+import com.jogamp.graph.font.Font;
+import com.jogamp.graph.font.FontSet;
+import com.jogamp.graph.font.FontFactory;
+import com.jogamp.opengl.util.Locator;
+
+public class UbuntuFontLoader implements FontSet {
+
+ final static FontSet fontLoader = new UbuntuFontLoader();
+
+ public static FontSet get() {
+ return fontLoader;
+ }
+
+ final static String availableFontFileNames[] =
+ {
+ /* 00 */ "Ubuntu-R.ttf", // regular
+ /* 01 */ "Ubuntu-RI.ttf", // regular italic
+ /* 02 */ "Ubuntu-B.ttf", // bold
+ /* 03 */ "Ubuntu-BI.ttf", // bold italic
+ /* 04 */ "Ubuntu-L.ttf", // light
+ /* 05 */ "Ubuntu-LI.ttf", // light italic
+ /* 06 */ "Ubuntu-M.ttf", // medium
+ /* 07 */ "Ubuntu-MI.ttf", // medium italic
+
+ };
+
+ final static String relPath = "fonts/ubuntu/" ;
+
+ private UbuntuFontLoader() {
+ }
+
+ static boolean is(int bits, int bit) {
+ return 0 != ( bits & bit ) ;
+ }
+
+ public Font getDefault() {
+ return get(FAMILY_REGULAR, 0) ; // Sans Serif Regular
+ }
+
+ public Font get(int family, int style)
+ {
+ Font font = null;
+
+ switch (family) {
+ case FAMILY_MONOSPACED:
+ case FAMILY_CONDENSED:
+ case FAMILY_REGULAR:
+ if( is(style, STYLE_BOLD) ) {
+ if( is(style, STYLE_ITALIC) ) {
+ font = abspath(availableFontFileNames[3]);
+ } else {
+ font = abspath(availableFontFileNames[2]);
+ }
+ } else if( is(style, STYLE_ITALIC) ) {
+ font = abspath(availableFontFileNames[1]);
+ } else {
+ font = abspath(availableFontFileNames[0]);
+ }
+ break;
+
+ case FAMILY_LIGHT:
+ if( is(style, STYLE_ITALIC) ) {
+ font = abspath(availableFontFileNames[5]);
+ } else {
+ font = abspath(availableFontFileNames[4]);
+ }
+ break;
+
+ case FAMILY_MEDIUM:
+ if( is(style, STYLE_ITALIC) ) {
+ font = abspath(availableFontFileNames[6]);
+ } else {
+ font = abspath(availableFontFileNames[7]);
+ }
+ break;
+ }
+
+ return font;
+ }
+
+ Font abspath(String fname) {
+ return FontFactory.getFontConstr().create(
+ Locator.getResource(UbuntuFontLoader.class, relPath+fname).getPath() );
+ }
+
+}
diff --git a/src/jogamp/graph/font/typecast/TypecastFont.java b/src/jogamp/graph/font/typecast/TypecastFont.java
index c5e291a55..546eb85e3 100644
--- a/src/jogamp/graph/font/typecast/TypecastFont.java
+++ b/src/jogamp/graph/font/typecast/TypecastFont.java
@@ -27,74 +27,92 @@
*/
package jogamp.graph.font.typecast;
-import java.io.File;
-import java.io.IOException;
-
import jogamp.graph.font.FontInt;
-import jogamp.graph.font.JavaFontLoader;
import jogamp.graph.geom.plane.AffineTransform;
import jogamp.graph.geom.plane.Path2D;
import net.java.dev.typecast.ot.OTFont;
import net.java.dev.typecast.ot.OTFontCollection;
import net.java.dev.typecast.ot.table.CmapFormat;
+import net.java.dev.typecast.ot.table.CmapIndexEntry;
import net.java.dev.typecast.ot.table.CmapTable;
import net.java.dev.typecast.ot.table.HdmxTable;
import net.java.dev.typecast.ot.table.ID;
import com.jogamp.common.util.IntObjectHashMap;
import com.jogamp.graph.geom.AABBox;
-import com.jogamp.graph.geom.Vertex;
class TypecastFont implements FontInt {
static final boolean DEBUG = false;
- final Vertex.Factory<? extends Vertex> pointFactory;
final OTFontCollection fontset;
final OTFont font;
- TypecastMetrics metrics;
+ TypecastHMetrics metrics;
final CmapFormat cmapFormat;
int cmapentries;
- // final IntIntHashMap char2Code;
IntObjectHashMap char2Glyph;
- public static TypecastFont create(Vertex.Factory<? extends Vertex> factory, String name) {
- String path = JavaFontLoader.getByName(name);
- if(null == path) {
- path = name;
- }
- OTFontCollection fontset;
- try {
- fontset = OTFontCollection.create(new File(path));
- return new TypecastFont(factory, fontset);
- } catch (IOException e) {
- e.printStackTrace();
- }
- return null;
- }
-
- public TypecastFont(Vertex.Factory<? extends Vertex> factory, OTFontCollection fontset) {
- this.pointFactory = factory;
+ public TypecastFont(OTFontCollection fontset) {
this.fontset = fontset;
this.font = fontset.getFont(0);
+ // FIXME: Generic attempt to find the best CmapTable,
+ // which is assumed to be the one with the most entries (stupid 'eh?)
CmapTable cmapTable = font.getCmapTable();
- CmapFormat _cmapFormat = null;
- /*
- if(null == _cmapFormat) {
- _cmapFormat = cmapTable.getCmapFormat(ID.platformMacintosh, ID.encodingASCII);
- } */
- if(null == _cmapFormat) {
- // default unicode
- _cmapFormat = cmapTable.getCmapFormat(ID.platformMicrosoft, ID.encodingUnicode);
- }
- if(null == _cmapFormat) {
- // maybe a symbol font ?
- _cmapFormat = cmapTable.getCmapFormat(ID.platformMicrosoft, ID.encodingSymbol);
- }
- if(null == _cmapFormat) {
- throw new RuntimeException("Cannot find a suitable cmap table for font "+font);
+ CmapFormat[] _cmapFormatP = { null, null, null, null };
+ int platform = -1;
+ int platformLength = -1;
+ int encoding = -1;
+ for(int i=0; i<cmapTable.getNumTables(); i++) {
+ CmapIndexEntry cmapIdxEntry = cmapTable.getCmapIndexEntry(i);
+ int pidx = cmapIdxEntry.getPlatformId();
+ CmapFormat cf = cmapIdxEntry.getFormat();
+ if(DEBUG) {
+ System.err.println("CmapFormat["+i+"]: platform " + pidx +
+ ", encoding "+cmapIdxEntry.getEncodingId() + ": "+cf);
+ }
+ if( _cmapFormatP[pidx] == null ||
+ _cmapFormatP[pidx].getLength() < cf.getLength() ) {
+ _cmapFormatP[pidx] = cf;
+ if( cf.getLength() > platformLength ) {
+ platformLength = cf.getLength() ;
+ platform = pidx;
+ encoding = cmapIdxEntry.getEncodingId();
+ }
+ }
}
- cmapFormat = _cmapFormat;
+ if(0 <= platform) {
+ cmapFormat = _cmapFormatP[platform];
+ if(DEBUG) {
+ System.err.println("Selected CmapFormat: platform " + platform +
+ ", encoding "+encoding + ": "+cmapFormat);
+ }
+ } else {
+ CmapFormat _cmapFormat = null;
+ /*if(null == _cmapFormat) {
+ platform = ID.platformMacintosh;
+ encoding = ID.encodingASCII;
+ _cmapFormat = cmapTable.getCmapFormat(platform, encoding);
+ } */
+ if(null == _cmapFormat) {
+ // default unicode
+ platform = ID.platformMicrosoft;
+ encoding = ID.encodingUnicode;
+ _cmapFormat = cmapTable.getCmapFormat((short)platform, (short)encoding);
+ }
+ if(null == _cmapFormat) {
+ // maybe a symbol font ?
+ platform = ID.platformMicrosoft;
+ encoding = ID.encodingSymbol;
+ _cmapFormat = cmapTable.getCmapFormat((short)platform, (short)encoding);
+ }
+ if(null == _cmapFormat) {
+ throw new RuntimeException("Cannot find a suitable cmap table for font "+font);
+ }
+ cmapFormat = _cmapFormat;
+ if(DEBUG) {
+ System.err.println("Selected CmapFormat (2): platform " + platform + ", encoding "+encoding + ": "+cmapFormat);
+ }
+ }
cmapentries = 0;
for (int i = 0; i < cmapFormat.getRangeCount(); ++i) {
@@ -104,21 +122,18 @@ class TypecastFont implements FontInt {
if(DEBUG) {
System.err.println("num glyphs: "+font.getNumGlyphs());
System.err.println("num cmap entries: "+cmapentries);
- }
-
- /*
- char2Code = new IntIntHashMap(cmapentries + cmapentries/4);
- for (int i = 0; i < cmapFormat.getRangeCount(); ++i) {
- CmapFormat.Range range = cmapFormat.getRange(i);
- for (int j = range.getStartCode(); j <= range.getEndCode(); ++j) {
- final int code = cmapFormat.mapCharCode(j);
- char2Code.put(j, code);
- if(code < 50) {
- System.err.println(" char: " + (int)j + " ( " + (char)j +" ) -> " + code);
- }
+ System.err.println("num cmap ranges: "+cmapFormat.getRangeCount());
+
+ for (int i = 0; i < cmapFormat.getRangeCount(); ++i) {
+ CmapFormat.Range range = cmapFormat.getRange(i);
+ for (int j = range.getStartCode(); j <= range.getEndCode(); ++j) {
+ final int code = cmapFormat.mapCharCode(j);
+ if(code < 15) {
+ System.err.println(" char: " + (int)j + " ( " + (char)j +" ) -> " + code);
+ }
+ }
}
}
- */
char2Glyph = new IntObjectHashMap(cmapentries + cmapentries/4);
}
@@ -128,7 +143,7 @@ class TypecastFont implements FontInt {
public Metrics getMetrics() {
if (metrics == null) {
- metrics = new TypecastMetrics(this);
+ metrics = new TypecastHMetrics(this);
}
return metrics;
}
@@ -137,15 +152,30 @@ class TypecastFont implements FontInt {
TypecastGlyph result = (TypecastGlyph) char2Glyph.get(symbol);
if (null == result) {
// final short code = (short) char2Code.get(symbol);
- final short code = (short) cmapFormat.mapCharCode(symbol);
+ short code = (short) cmapFormat.mapCharCode(symbol);
+ if(0 == code && 0 != symbol) {
+ // reserved special glyph IDs by convention
+ switch(symbol) {
+ case ' ': code = Glyph.ID_SPACE; break;
+ case '\n': code = Glyph.ID_CR; break;
+ default: code = Glyph.ID_UNKNOWN;
+ }
+ }
+
net.java.dev.typecast.ot.OTGlyph glyph = font.getGlyph(code);
- final Path2D path = TypecastRenderer.buildPath(glyph);
+ if(null == glyph) {
+ glyph = font.getGlyph(Glyph.ID_UNKNOWN);
+ }
+ if(null == glyph) {
+ throw new RuntimeException("Could not retrieve glyph for symbol: <"+symbol+"> "+(int)symbol+" -> glyph id "+code);
+ }
+ Path2D path = TypecastRenderer.buildPath(glyph);
result = new TypecastGlyph(this, symbol, code, glyph.getBBox(), glyph.getAdvanceWidth(), path);
if(DEBUG) {
System.err.println("New glyph: " + (int)symbol + " ( " + (char)symbol +" ) -> " + code + ", contours " + glyph.getPointCount() + ": " + path);
}
final HdmxTable hdmx = font.getHdmxTable();
- if (null != hdmx) {
+ if (null!= result && null != hdmx) {
/*if(DEBUG) {
System.err.println("hdmx "+hdmx);
}*/
@@ -164,7 +194,7 @@ class TypecastFont implements FontInt {
}
public void getOutline(String string, float pixelSize, AffineTransform transform, Path2D[] result) {
- TypecastRenderer.getOutline(pointFactory, this, string, pixelSize, transform, result);
+ TypecastRenderer.getOutline(this, string, pixelSize, transform, result);
}
public float getStringWidth(String string, float pixelSize) {
diff --git a/src/jogamp/graph/font/typecast/TypecastFontFactory.java b/src/jogamp/graph/font/typecast/TypecastFontConstructor.java
index 04559a138..5fb9d32f7 100644
--- a/src/jogamp/graph/font/typecast/TypecastFontFactory.java
+++ b/src/jogamp/graph/font/typecast/TypecastFontConstructor.java
@@ -27,38 +27,27 @@
*/
package jogamp.graph.font.typecast;
-import java.util.HashMap;
-import java.util.Map;
+import java.io.File;
+import java.io.IOException;
-import com.jogamp.graph.font.Font;
-import com.jogamp.graph.font.FontFactory;
-import com.jogamp.graph.geom.Vertex.Factory;
-import com.jogamp.graph.geom.Vertex;
+import jogamp.graph.font.FontConstructor;
+import net.java.dev.typecast.ot.OTFontCollection;
-public class TypecastFontFactory implements FontFactory {
+import com.jogamp.graph.font.Font;
- Map<String, Font> fonts = new HashMap<String, Font>();
-
- public Font createFont(Factory<? extends Vertex> factory, String name) {
- Font result = fonts.get(name);
- if (result == null) {
- result = TypecastFont.create(factory, name);
- if(result != null) {
- fonts.put(name, result);
- }
- }
- return result;
- }
+public class TypecastFontConstructor implements FontConstructor {
- public Font createFont(Factory<? extends Vertex> factory,
- String[] families,
- String style,
- String variant,
- String weight) {
- throw new Error("not implemented");
+ public Font create(String path) {
+ OTFontCollection fontset;
+ try {
+ fontset = OTFontCollection.create(new File(path));
+ return new TypecastFont(fontset);
+ } catch (IOException e) {
+ e.printStackTrace();
+ }
+ return null;
}
-
-
+
} \ No newline at end of file
diff --git a/src/jogamp/graph/font/typecast/TypecastMetrics.java b/src/jogamp/graph/font/typecast/TypecastHMetrics.java
index 9ca1e3bf7..cd8595498 100644
--- a/src/jogamp/graph/font/typecast/TypecastMetrics.java
+++ b/src/jogamp/graph/font/typecast/TypecastHMetrics.java
@@ -29,11 +29,10 @@ package jogamp.graph.font.typecast;
import net.java.dev.typecast.ot.table.HeadTable;
import net.java.dev.typecast.ot.table.HheaTable;
-
import com.jogamp.graph.font.Font.Metrics;
import com.jogamp.graph.geom.AABBox;
-class TypecastMetrics implements Metrics {
+class TypecastHMetrics implements Metrics {
private final TypecastFont fontImpl;
// HeadTable
@@ -42,11 +41,14 @@ class TypecastMetrics implements Metrics {
private final AABBox bbox;
// HheaTable
private final HheaTable hheaTable;
+ // VheaTable (for horizontal fonts)
+ // private final VheaTable vheaTable;
- public TypecastMetrics(TypecastFont fontImpl) {
+ public TypecastHMetrics(TypecastFont fontImpl) {
this.fontImpl = fontImpl;
headTable = this.fontImpl.font.getHeadTable();
hheaTable = this.fontImpl.font.getHheaTable();
+ // vheaTable = this.fontImpl.font.getVheaTable();
unitsPerEM_Inv = 1.0f / ( (float) headTable.getUnitsPerEm() );
int maxWidth = headTable.getXMax() - headTable.getXMin();
@@ -67,6 +69,9 @@ class TypecastMetrics implements Metrics {
public final float getLineGap(float pixelSize) {
return getScale(pixelSize) * -hheaTable.getLineGap(); // invert
}
+ public final float getMaxExtend(float pixelSize) {
+ return getScale(pixelSize) * hheaTable.getXMaxExtent();
+ }
public final float getScale(float pixelSize) {
return pixelSize * unitsPerEM_Inv;
}
diff --git a/src/jogamp/graph/font/typecast/TypecastRenderer.java b/src/jogamp/graph/font/typecast/TypecastRenderer.java
index 11f1ec028..410f5b73a 100644
--- a/src/jogamp/graph/font/typecast/TypecastRenderer.java
+++ b/src/jogamp/graph/font/typecast/TypecastRenderer.java
@@ -31,9 +31,6 @@ import jogamp.graph.geom.plane.AffineTransform;
import jogamp.graph.geom.plane.Path2D;
import com.jogamp.graph.font.Font;
-import com.jogamp.graph.geom.Vertex;
-import com.jogamp.graph.geom.Vertex.Factory;
-
import net.java.dev.typecast.ot.Point;
import net.java.dev.typecast.ot.OTGlyph;
@@ -43,7 +40,7 @@ import net.java.dev.typecast.ot.OTGlyph;
*/
public class TypecastRenderer {
- public static void getOutline(Factory<? extends Vertex> factory, TypecastFont font,
+ public static void getOutline(TypecastFont font,
String string, float pixelSize, AffineTransform transform, Path2D[] p)
{
if (string == null) {
@@ -55,9 +52,9 @@ public class TypecastRenderer {
float ascent = metrics.getAscent(pixelSize) ;
float descent = metrics.getDescent(pixelSize) ;
if (transform == null) {
- transform = new AffineTransform(factory);
+ transform = new AffineTransform();
}
- AffineTransform t = new AffineTransform(factory);
+ AffineTransform t = new AffineTransform();
float advanceY = lineGap - descent + ascent;
float y = 0;
@@ -71,7 +68,10 @@ public class TypecastRenderer {
y -= advanceY;
advanceTotal = 0;
continue;
- }
+ } else if (character == ' ') {
+ advanceTotal += font.font.getHmtxTable().getAdvanceWidth(TypecastGlyph.ID_SPACE) * metrics.getScale(pixelSize);
+ continue;
+ }
TypecastGlyph glyph = (TypecastGlyph) font.getGlyph(character);
Path2D gp = glyph.getPath();
float scale = metrics.getScale(pixelSize);
diff --git a/src/jogamp/graph/geom/plane/AffineTransform.java b/src/jogamp/graph/geom/plane/AffineTransform.java
index de13ff9de..2ba9f8d06 100644
--- a/src/jogamp/graph/geom/plane/AffineTransform.java
+++ b/src/jogamp/graph/geom/plane/AffineTransform.java
@@ -72,6 +72,13 @@ public class AffineTransform implements Cloneable, Serializable {
*/
transient int type;
+ public AffineTransform() {
+ pointFactory = null;
+ type = TYPE_IDENTITY;
+ m00 = m11 = 1.0f;
+ m10 = m01 = m02 = m12 = 0.0f;
+ }
+
public AffineTransform(Factory<? extends Vertex> factory) {
pointFactory = factory;
type = TYPE_IDENTITY;
diff --git a/src/net/java/dev/typecast/ot/table/BaseTable.java b/src/net/java/dev/typecast/ot/table/BaseTable.java
index 7e6c37a5e..f92de718f 100644
--- a/src/net/java/dev/typecast/ot/table/BaseTable.java
+++ b/src/net/java/dev/typecast/ot/table/BaseTable.java
@@ -24,7 +24,6 @@ import java.io.ByteArrayInputStream;
import java.io.DataInput;
import java.io.DataInputStream;
import java.io.IOException;
-import net.java.dev.typecast.ot.Fixed;
/**
* Baseline Table
diff --git a/src/net/java/dev/typecast/ot/table/CvtTable.java b/src/net/java/dev/typecast/ot/table/CvtTable.java
index 6035c6378..44dc0af41 100644
--- a/src/net/java/dev/typecast/ot/table/CvtTable.java
+++ b/src/net/java/dev/typecast/ot/table/CvtTable.java
@@ -8,7 +8,6 @@
package net.java.dev.typecast.ot.table;
-import java.io.ByteArrayInputStream;
import java.io.DataInput;
import java.io.IOException;
diff --git a/src/net/java/dev/typecast/ot/table/Os2Table.java b/src/net/java/dev/typecast/ot/table/Os2Table.java
index bb3b60101..9ec599724 100644
--- a/src/net/java/dev/typecast/ot/table/Os2Table.java
+++ b/src/net/java/dev/typecast/ot/table/Os2Table.java
@@ -52,7 +52,6 @@ package net.java.dev.typecast.ot.table;
import java.io.DataInput;
import java.io.IOException;
-import net.java.dev.typecast.ot.Fixed;
/**
* @version $Id: Os2Table.java,v 1.2 2004-12-09 23:46:21 davidsch Exp $
diff --git a/src/net/java/dev/typecast/ot/table/Program.java b/src/net/java/dev/typecast/ot/table/Program.java
index 6fd02a469..d4dd094e2 100644
--- a/src/net/java/dev/typecast/ot/table/Program.java
+++ b/src/net/java/dev/typecast/ot/table/Program.java
@@ -10,7 +10,6 @@ package net.java.dev.typecast.ot.table;
import java.io.DataInput;
import java.io.IOException;
-import java.io.ByteArrayInputStream;
/**
* @version $Id: Program.java,v 1.1.1.1 2004-12-05 23:14:57 davidsch Exp $
diff --git a/src/net/java/dev/typecast/ot/table/TableFactory.java b/src/net/java/dev/typecast/ot/table/TableFactory.java
index 632abcf44..28a7a4a97 100644
--- a/src/net/java/dev/typecast/ot/table/TableFactory.java
+++ b/src/net/java/dev/typecast/ot/table/TableFactory.java
@@ -51,7 +51,6 @@
package net.java.dev.typecast.ot.table;
import java.io.DataInputStream;
-import java.io.InputStream;
import java.io.IOException;
import net.java.dev.typecast.ot.OTFont;
import net.java.dev.typecast.ot.OTFontCollection;
diff --git a/src/test/com/jogamp/opengl/test/junit/graph/TestHwTextRenderer01.java b/src/test/com/jogamp/opengl/test/junit/graph/TestHwTextRenderer01.java
index a0b04d69a..7f5ee9d98 100755
--- a/src/test/com/jogamp/opengl/test/junit/graph/TestHwTextRenderer01.java
+++ b/src/test/com/jogamp/opengl/test/junit/graph/TestHwTextRenderer01.java
@@ -7,6 +7,7 @@ import javax.media.opengl.GL;
import javax.media.opengl.GL2ES2;
import javax.media.opengl.GLAutoDrawable;
import javax.media.opengl.GLCapabilities;
+import javax.media.opengl.GLCapabilitiesImmutable;
import javax.media.opengl.GLException;
import javax.media.opengl.GLProfile;
@@ -15,10 +16,9 @@ import org.junit.BeforeClass;
import org.junit.Test;
import com.jogamp.graph.curve.Region;
+import com.jogamp.graph.font.FontFactory;
import com.jogamp.graph.geom.opengl.SVertex;
-import com.jogamp.newt.Window;
import com.jogamp.newt.opengl.GLWindow;
-import com.jogamp.opengl.util.FPSAnimator;
import demo.GPUTextGLListenerBase01;
@@ -30,13 +30,13 @@ public class TestHwTextRenderer01 {
NativeWindowFactory.initSingleton(true);
}
- static void destroyWindow(Window window) {
+ static void destroyWindow(GLWindow window) {
if(null!=window) {
window.destroy();
}
}
- static GLWindow createWindow(String title, GLCapabilities caps, int width, int height) {
+ static GLWindow createWindow(String title, GLCapabilitiesImmutable caps, int width, int height) {
Assert.assertNotNull(caps);
GLWindow window = GLWindow.create(caps);
@@ -53,88 +53,83 @@ public class TestHwTextRenderer01 {
public void testTextRendererR2T01() throws InterruptedException {
GLProfile glp = GLProfile.get(GLProfile.GL3bc);
GLCapabilities caps = new GLCapabilities(glp);
+ caps.setOnscreen(false);
caps.setAlphaBits(4);
- GLWindow window = createWindow("r2t1msaa0", caps, 400,400);
+ GLWindow window = createWindow("r2t1-msaa0", caps, 800,400);
TextGLListener textGLListener = new TextGLListener(Region.TWO_PASS);
- textGLListener.setTech(-10, 10, 0f, -1000, 400);
- textGLListener.attachTo(window);
-
- FPSAnimator animator = new FPSAnimator(10);
- animator.add(window);
- animator.start();
-
- while(!textGLListener.isPrinted()){
- Thread.sleep(100);
- }
+ textGLListener.attachTo(window);
+
+ textGLListener.setFontSet(FontFactory.UBUNTU, 0, 0);
+ textGLListener.setTech(-400, -30, 0f, -1000, 400);
+ window.display();
- textGLListener.resetPrinting();
- textGLListener.setTech(-111, 74, 0, -380, 1100);
- Thread.sleep(100);
- while(!textGLListener.isPrinted()){
- Thread.sleep(100);
- }
-
- textGLListener.resetPrinting();
- textGLListener.setTech(-111, 74, 0, -80, 2500);
- Thread.sleep(100);
- while(!textGLListener.isPrinted()){
- Thread.sleep(100);
- }
+ textGLListener.setTech(-400, -30, 0, -380, 1100);
+ window.display();
- animator.stop();
+ textGLListener.setTech(-400, -20, 0, -80, 2500);
+ window.display();
+
+ textGLListener.setFontSet(FontFactory.JAVA, 0, 0);
+ textGLListener.setTech(-400, -30, 0f, -1000, 400);
+ window.display();
+
+ textGLListener.setTech(-400, -30, 0, -380, 1100);
+ window.display();
+
+ textGLListener.setTech(-400, -20, 0, -80, 2500);
+ window.display();
+
destroyWindow(window);
-
- Thread.sleep(1000);
}
@Test
public void testTextRendererMSAA01() throws InterruptedException {
GLProfile glp = GLProfile.get(GLProfile.GL2ES2);
GLCapabilities caps = new GLCapabilities(glp);
+ caps.setOnscreen(false);
caps.setAlphaBits(4);
caps.setSampleBuffers(true);
caps.setNumSamples(4);
- GLWindow window = createWindow("r2t0msaa1", caps, 400, 400);
+ GLWindow window = createWindow("r2t0-msaa1", caps, 800, 400);
TextGLListener textGLListener = new TextGLListener(Region.SINGLE_PASS);
- textGLListener.setTech(-10, 10, 0f, -1000, 0);
- textGLListener.attachTo(window);
-
- FPSAnimator animator = new FPSAnimator(10);
- animator.add(window);
- animator.start();
-
- while(!textGLListener.isPrinted()){
- Thread.sleep(100);
- }
-
- textGLListener.resetPrinting();
- textGLListener.setTech(-111, 74, 0, -380, 0);
- Thread.sleep(100);
- while(!textGLListener.isPrinted()){
- Thread.sleep(100);
- }
-
- textGLListener.resetPrinting();
- textGLListener.setTech(-111, 74, 0, -80, 0);
- Thread.sleep(100);
- while(!textGLListener.isPrinted()){
- Thread.sleep(100);
- }
-
- animator.stop();
+ textGLListener.attachTo(window);
+
+ textGLListener.setFontSet(FontFactory.UBUNTU, 0, 0);
+ textGLListener.setTech(-400, -30, 0f, -1000, 0);
+ window.display();
+
+ textGLListener.setTech(-400, -30, 0, -380, 0);
+ window.display();
+
+ textGLListener.setTech(-400, -20, 0, -80, 0);
+ window.display();
+
+ textGLListener.setFontSet(FontFactory.JAVA, 0, 0);
+ textGLListener.setTech(-400, -30, 0f, -1000, 0);
+ window.display();
+
+ textGLListener.setTech(-400, -30, 0, -380, 0);
+ window.display();
+
+ textGLListener.setTech(-400, -20, 0, -80, 0);
+ window.display();
+
destroyWindow(window);
-
- Thread.sleep(1000);
}
private class TextGLListener extends GPUTextGLListenerBase01 {
- GLWindow glwindow;
+ String winTitle;
+
public TextGLListener(int type) {
super(SVertex.factory(), type, false, false);
}
+ public void attachTo(GLWindow window) {
+ super.attachTo(window);
+ winTitle = window.getTitle();
+ }
public void setTech(float xt, float yt, float angle, int zoom, int fboSize){
setMatrix(xt, yt, angle, zoom, fboSize);
}
@@ -148,27 +143,12 @@ public class TestHwTextRenderer01 {
textRenderer.setAlpha(gl, 1.0f);
textRenderer.setColor(gl, 0.0f, 0.0f, 0.0f);
}
- public void attachTo(GLWindow window) {
- super.attachTo(window);
- glwindow = window;
- }
-
- public boolean isPrinted(){
- return !printScreen;
- }
- public void resetPrinting(){
- printScreen = true;
- }
-
public void display(GLAutoDrawable drawable) {
super.display(drawable);
try {
- if(printScreen){
- printScreen(glwindow, "./", glwindow.getTitle(), false);
- printScreen = false;
- }
+ printScreen("./", winTitle, drawable.getWidth(), drawable.getHeight(), false);
} catch (GLException e) {
e.printStackTrace();
} catch (IOException e) {