diff options
Diffstat (limited to 'src')
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) {
|