diff options
author | Sven Gothel <[email protected]> | 2023-02-13 07:01:54 +0100 |
---|---|---|
committer | Sven Gothel <[email protected]> | 2023-02-13 07:01:54 +0100 |
commit | 6d2009d33495a01ae3b59a4be6004c1a5e7007ad (patch) | |
tree | 1294462baa6b0ef3a2389e7fe6f4d878a0e8d4c1 /src/jogl/classes | |
parent | 93c51380f34c3eb203f46df52fed49a8a967510e (diff) |
Graph Type Rendering: Drop pixelSize and use font em-size [0..1] throughout system.
- All pixelSize metrics methods are dropped in Font*
- TypecastGlyph.Advance dropped, i.e. dropping prescales glyph advance based on pixelSize
- TextRegionUtil produces OutlineShape in font em-size [0..1] added to GLRegion
- Adjusted demos
Diffstat (limited to 'src/jogl/classes')
7 files changed, 157 insertions, 398 deletions
diff --git a/src/jogl/classes/com/jogamp/graph/curve/opengl/TextRegionUtil.java b/src/jogl/classes/com/jogamp/graph/curve/opengl/TextRegionUtil.java index a4ba4bf52..4af40bf1c 100644 --- a/src/jogl/classes/com/jogamp/graph/curve/opengl/TextRegionUtil.java +++ b/src/jogl/classes/com/jogamp/graph/curve/opengl/TextRegionUtil.java @@ -42,7 +42,10 @@ import com.jogamp.graph.geom.Vertex.Factory; import com.jogamp.graph.geom.plane.AffineTransform; /** - * Text {@link GLRegion} Utility Class + * Text Type Rendering Utility Class adding the {@link Font.Glyph}s {@link OutlineShape} to a {@link GLRegion}. + * <p> + * {@link OutlineShape}s are all produced in font em-size [0..1]. + * </p> */ public class TextRegionUtil { @@ -55,6 +58,9 @@ public class TextRegionUtil { public static interface ShapeVisitor { /** * Visiting the given {@link OutlineShape} with it's corresponding {@link AffineTransform}. + * <p> + * The shape is in font em-size [0..1]. + * </p> * @param shape may be used as is, otherwise a copy shall be made if intended to be modified. * @param t may be used immediately as is, otherwise a copy shall be made if stored. */ @@ -74,14 +80,16 @@ public class TextRegionUtil { /** * Visit each {@link Font.Glyph}'s {@link OutlineShape} with the given {@link ShapeVisitor} - * additionally passing the progressed {@link AffineTransform} in font-units. - * The latter reflects the given font metric in font-units and hence character position. + * additionally passing the progressed {@link AffineTransform}. + * <p> + * The produced shapes are in font em-size [0..1], but can be adjusted with the given transform, progressed and passed to the visitor. + * </p> * @param visitor * @param transform optional given transform * @param font the target {@link Font} * @param str string text - * @param temp1 temporary AffineTransform storage, mandatory, will be passed to {@link ShapeVisitor#visit(OutlineShape, AffineTransform)} and can be modified. - * @param temp2 temporary AffineTransform storage, mandatory, can be re-used in {@link ShapeVisitor#visit(OutlineShape, AffineTransform)} by user code. + * @param temp1 temporary AffineTransform storage, mandatory + * @param temp2 temporary AffineTransform storage, mandatory */ public static void processString(final ShapeVisitor visitor, final AffineTransform transform, final Font font, final CharSequence str, @@ -89,10 +97,10 @@ public class TextRegionUtil { final int charCount = str.length(); // region.setFlipped(true); - final int lineHeight = font.getLineHeightFU(); + final float lineHeight = font.getLineHeight(); - int y = 0; - int advanceTotal = 0; + float y = 0; + float advanceTotal = 0; Font.Glyph left_glyph = null; for(int i=0; i< charCount; i++) { @@ -102,7 +110,7 @@ public class TextRegionUtil { advanceTotal = 0; left_glyph = null; } else if (character == ' ') { - advanceTotal += font.getAdvanceWidthFU(Glyph.ID_SPACE); + advanceTotal += font.getAdvanceWidth(Glyph.ID_SPACE); left_glyph = null; } else { // reset transform @@ -115,24 +123,23 @@ public class TextRegionUtil { final OutlineShape glyphShape = glyph.getShape(); if( null == glyphShape ) { left_glyph = null; - temp1.translate(advanceTotal, y, temp2); continue; } if( null != left_glyph ) { - advanceTotal += left_glyph.getKerningFU(glyph.getID()); + advanceTotal += left_glyph.getKerning(glyph.getID()); } temp1.translate(advanceTotal, y, temp2); visitor.visit(glyphShape, temp1); - advanceTotal += glyph.getAdvanceFU(); + advanceTotal += glyph.getAdvance(); left_glyph = glyph; } } } /** - * Add the string in 3D space w.r.t. the font using font-units at the end of the {@link GLRegion}. + * Add the string in 3D space w.r.t. the font in font em-size [0..1] at the end of the {@link GLRegion}. * <p> - * The resulting GLRegion should be scaled by the chosen pixelSize of the font divided by the font's unitsPerEM. + * The shapes added to the GLRegion are in font em-size [0..1]. * </p> * @param region the {@link GLRegion} sink * @param vertexFactory vertex impl factory {@link Factory} @@ -154,9 +161,9 @@ public class TextRegionUtil { } /** - * Render the string in 3D space w.r.t. the font using font-units at the end of an internally cached {@link GLRegion}. + * Render the string in 3D space w.r.t. the font int font em-size [0..1] at the end of an internally cached {@link GLRegion}. * <p> - * The resulting GLRegion should be scaled by the chosen pixelSize of the font divided by the font's unitsPerEM. + * The shapes added to the GLRegion are in font em-size [0..1]. * </p> * <p> * Cached {@link GLRegion}s will be destroyed w/ {@link #clear(GL2ES2)} or to free memory. @@ -187,9 +194,9 @@ public class TextRegionUtil { } /** - * Render the string in 3D space w.r.t. the font using font-units at the end of an internally temporary {@link GLRegion}. + * Render the string in 3D space w.r.t. the font in font em-size [0..1] at the end of an internally temporary {@link GLRegion}. * <p> - * The resulting GLRegion should be scaled by the chosen pixelSize of the font divided by the font's unitsPerEM. + * The shapes added to the GLRegion are in font em-size [0..1]. * </p> * <p> * In case of a multisampling region renderer, i.e. {@link Region#VBAA_RENDERING_BIT}, recreating the {@link GLRegion} @@ -222,10 +229,10 @@ public class TextRegionUtil { } /** - * Render the string in 3D space w.r.t. the font using font-units at the end of the given {@link GLRegion}, + * Render the string in 3D space w.r.t. the font in font em-size [0..1] at the end of the given {@link GLRegion}, * which will {@link GLRegion#clear(GL2ES2) cleared} beforehand. * <p> - * The resulting GLRegion should be scaled by the chosen pixelSize of the font divided by the font's unitsPerEM. + * The shapes added to the GLRegion are in font em-size [0..1]. * </p> * @param gl the current GL state * @param font {@link Font} to be used diff --git a/src/jogl/classes/com/jogamp/graph/font/Font.java b/src/jogl/classes/com/jogamp/graph/font/Font.java index 5c63227b3..2d26b1a85 100644 --- a/src/jogl/classes/com/jogamp/graph/font/Font.java +++ b/src/jogl/classes/com/jogamp/graph/font/Font.java @@ -86,20 +86,40 @@ public interface Font { int getAscentFU(); /** + * @return ascent in font em-size [0..1] + */ + float getAscent(); + + /** * @return descent in font-units to be divided by {@link #getUnitsPerEM()} */ int getDescentFU(); /** + * @return descend in font em-size [0..1] + */ + float getDescent(); + + /** * @return line-gap in font-units to be divided by {@link #getUnitsPerEM()} */ int getLineGapFU(); /** + * @return line-gap in font em-size [0..1] + */ + float getLineGap(); + + /** * @return max-extend in font-units to be divided by {@link #getUnitsPerEM()} */ int getMaxExtendFU(); + /** + * @return max-extend in font em-size [0..1] + */ + float getMaxExtend(); + /** Returns the font's units per EM from the 'head' table. One em square covers one glyph. */ int getUnitsPerEM(); @@ -117,15 +137,13 @@ public interface Font { * @param dest AABBox instance set to this metrics boundary in font-units * @return the given and set AABBox 'dest' in font units */ - AABBox getBBox(final AABBox dest); + AABBox getBBoxFU(final AABBox dest); /** - * @param dest AABBox instance set to this metrics boundary w/ given pixelSize - * @param pixelSize pixel-size of font, for resolution correct pixel-size use {@link FontScale#toPixels(float, float)} - * @param tmpV3 caller provided temporary 3-component vector - * @return the given and set AABBox 'dest' in pixel size + * @param dest AABBox instance set to this metrics boundary in font em-size [0..1] + * @return the given and set AABBox 'dest' in font units */ - AABBox getBBox(final AABBox dest, final float pixelSize, final float[] tmpV3); + AABBox getBBox(final AABBox dest, final float[] tmpV3); } /** @@ -159,12 +177,9 @@ public interface Font { float getScale(final int funits); /** - * @param dest AABBox instance set to this metrics boundary w/ given pixelSize - * @param pixelSize pixel-size of font, for resolution correct pixel-size use {@link FontScale#toPixels(float, float)} - * @param tmpV3 caller provided temporary 3-component vector - * @return the given and set AABBox 'dest' in pixel size + * Return the AABBox in font-units to be divided by unitsPerEM */ - AABBox getBBox(final AABBox dest, final float pixelSize, float[] tmpV3); + AABBox getBBoxFU(); /** * Return the AABBox in font-units to be divided by unitsPerEM @@ -174,9 +189,11 @@ public interface Font { AABBox getBBoxFU(final AABBox dest); /** - * Return the AABBox in font-units to be divided by unitsPerEM + * @param dest AABBox instance set to this metrics boundary in font em-size [0..1] + * @param tmpV3 caller provided temporary 3-component vector + * @return the given and set AABBox 'dest' in font em-size [0..1] */ - AABBox getBBoxFU(); + AABBox getBBox(final AABBox dest, float[] tmpV3); /** Return advance in font units to be divided by unitsPerEM */ int getAdvanceFU(); @@ -184,12 +201,6 @@ public interface Font { /** Return advance in font em-size [0..1] */ float getAdvance(); - /** - * @param pixelSize pixel-size of font, for resolution correct pixel-size use {@link FontScale#toPixels(float, float)} - * @return pixel size of advance - */ - float getAdvance(final float pixelSize); - /** True if kerning values are horizontal, otherwise vertical */ boolean isKerningHorizontal(); /** True if kerning values are perpendicular to text flow, otherwise along with flow */ @@ -226,7 +237,6 @@ public interface Font { String fullString(); } - String getName(final int nameIndex); /** Shall return the family and subfamily name, separated a dash. @@ -237,12 +247,10 @@ public interface Font { StringBuilder getAllNames(final StringBuilder string, final String separator); /** - * + * Return advance-width of given glyphID in font-units to be divided by unitsPerEM * @param glyphID - * @param pixelSize pixel-size of font, for resolution correct pixel-size use {@link FontScale#toPixels(float, float)} - * @return pixel size of advance width */ - float getAdvanceWidth(final int glyphID, final float pixelSize); + int getAdvanceWidthFU(final int glyphID); /** * Return advance-width of given glyphID in font em-size [0..1] @@ -250,12 +258,6 @@ public interface Font { */ float getAdvanceWidth(final int glyphID); - /** - * Return advance-width of given glyphID in font-units to be divided by unitsPerEM - * @param glyphID - */ - int getAdvanceWidthFU(final int glyphID); - Metrics getMetrics(); int getGlyphID(final char symbol); @@ -265,79 +267,49 @@ public interface Font { int getNumGlyphs(); /** - * - * @param pixelSize pixel-size of font, for resolution correct pixel-size use {@link FontScale#toPixels(float, float)} - * @return pixel size of line height + * Return line height in font-units to be divided by unitsPerEM */ - float getLineHeight(final float pixelSize); + int getLineHeightFU(); /** * Return line height in font em-size [0..1] */ float getLineHeight(); - /** - * Return line height in font-units to be divided by unitsPerEM - */ - int getLineHeightFU(); - - /** - * - * @param string - * @param pixelSize pixel-size of font, for resolution correct pixel-size use {@link FontScale#toPixels(float, float)} - * @return pixel size of metric width - */ - float getMetricWidth(final CharSequence string, final float pixelSize); + /** Return metric-width in font-units */ + int getMetricWidthFU(final CharSequence string); /** Return metric-width in font em-size */ float getMetricWidth(final CharSequence string); - /** Return metric-width in font-units */ - int getMetricWidthFU(final CharSequence string); - - /** - * - * @param string - * @param pixelSize pixel-size of font, for resolution correct pixel-size use {@link FontScale#toPixels(float, float)} - * @return pixel size of metric height - */ - float getMetricHeight(final CharSequence string, final float pixelSize); + /** Return metric-height in font-units */ + int getMetricHeightFU(final CharSequence string); /** Return metric-height in font em-size */ float getMetricHeight(final CharSequence string); - /** Return metric-height in font-units */ - int getMetricHeightFU(final CharSequence string); - - /** - * Return the <i>layout</i> bounding box as computed by each glyph's metrics. - * The result is not pixel correct, but reflects layout specific metrics. - * <p> - * See {@link #getPointsBounds(AffineTransform, CharSequence, float, AffineTransform, AffineTransform)} for pixel correct results. - * </p> - * @param string string text - * @param pixelSize pixel-size of font, for resolution correct pixel-size use {@link FontScale#toPixels(float, float)} - */ - AABBox getMetricBounds(final CharSequence string, final float pixelSize); + /** Return layout metric-bounds in font-units, see {@link #getMetricBounds(CharSequence, float)} */ + AABBox getMetricBoundsFU(final CharSequence string); /** Return layout metric-bounds in font em-size, see {@link #getMetricBounds(CharSequence, float)} */ AABBox getMetricBounds(final CharSequence string); - /** Return layout metric-bounds in font-units, see {@link #getMetricBounds(CharSequence, float)} */ - AABBox getMetricBoundsFU(final CharSequence string); - /** - * Return the bounding box by taking each glyph's point-based bounding box into account. + * Return the bounding box by taking each glyph's font-unit sized bounding box into account. * @param transform optional given transform * @param string string text - * @param pixelSize pixel-size of font, for resolution correct pixel-size use {@link FontScale#toPixels(float, float)} + * @return the bounding box of the given string in font-units [0..1] */ - AABBox getPointsBounds(final AffineTransform transform, final CharSequence string, final float pixelSize); + AABBox getPointsBoundsFU(final AffineTransform transform, final CharSequence string); + /** + * Return the bounding box by taking each glyph's font em-sized bounding box into account. + * @param transform optional given transform + * @param string string text + * @return the bounding box of the given string in font em-size [0..1] + */ AABBox getPointsBounds(final AffineTransform transform, final CharSequence string); - AABBox getPointsBoundsFU(final AffineTransform transform, final CharSequence string); - boolean isPrintableChar(final char c); /** Shall return {@link #getFullFamilyName()} */ diff --git a/src/jogl/classes/com/jogamp/opengl/math/geom/AABBox.java b/src/jogl/classes/com/jogamp/opengl/math/geom/AABBox.java index d54142e38..234b2121b 100644 --- a/src/jogl/classes/com/jogamp/opengl/math/geom/AABBox.java +++ b/src/jogl/classes/com/jogamp/opengl/math/geom/AABBox.java @@ -582,7 +582,10 @@ public class AABBox { } /** - * Scale this AABBox by a constant + * Scale this AABBox by a constant around fixed center + * <p> + * high and low is recomputed by scaling its distance to fixed center. + * </p> * @param size a constant float value * @param tmpV3 caller provided temporary 3-component vector * @return this AABBox for chaining @@ -605,6 +608,22 @@ public class AABBox { } /** + * Scale this AABBox by a constant, recomputing center + * <p> + * high and low is scaled and center recomputed. + * </p> + * @param size a constant float value + * @param tmpV3 caller provided temporary 3-component vector + * @return this AABBox for chaining + */ + public final AABBox scale2(final float size, final float[] tmpV3) { + VectorUtil.scaleVec3(high, high, size); // in-place scale + VectorUtil.scaleVec3(low, low, size); // in-place scale + computeCenter(); + return this; + } + + /** * Translate this AABBox by a float[3] vector * @param t the float[3] translation vector * @return this AABBox for chaining diff --git a/src/jogl/classes/jogamp/graph/font/typecast/TypecastFont.java b/src/jogl/classes/jogamp/graph/font/typecast/TypecastFont.java index 146bc0380..382d35a73 100644 --- a/src/jogl/classes/jogamp/graph/font/typecast/TypecastFont.java +++ b/src/jogl/classes/jogamp/graph/font/typecast/TypecastFont.java @@ -32,7 +32,6 @@ import jogamp.graph.font.typecast.ot.TTFont; import jogamp.graph.font.typecast.ot.table.CmapFormat; import jogamp.graph.font.typecast.ot.table.CmapIndexEntry; import jogamp.graph.font.typecast.ot.table.CmapTable; -import jogamp.graph.font.typecast.ot.table.HdmxTable; import jogamp.graph.font.typecast.ot.table.ID; import jogamp.graph.font.typecast.ot.table.KernSubtable; import jogamp.graph.font.typecast.ot.table.KernSubtableFormat0; @@ -50,7 +49,6 @@ import com.jogamp.graph.geom.plane.AffineTransform; import com.jogamp.opengl.math.geom.AABBox; class TypecastFont implements Font { - static final boolean USE_PRESCALED_ADVANCE = false; static final boolean DEBUG = false; private static final Vertex.Factory<SVertex> vertexFactory = SVertex.factory(); @@ -167,10 +165,6 @@ class TypecastFont implements Font { } @Override - public float getAdvanceWidth(final int glyphID, final float pixelSize) { - return pixelSize * metrics.getScale( font.getHmtxTable().getAdvanceWidth(glyphID) ); - } - @Override public float getAdvanceWidth(final int glyphID) { return metrics.getScale( font.getHmtxTable().getAdvanceWidth(glyphID) ); } @@ -230,7 +224,7 @@ class TypecastFont implements Font { if(null == glyph) { throw new RuntimeException("Could not retrieve glyph for symbol: <"+symbol+"> "+(int)symbol+" -> glyph id "+glyph_id); } - final OutlineShape shape = TypecastRenderer.buildShape(symbol, glyph, vertexFactory); + final OutlineShape shape = TypecastRenderer.buildShape(metrics.getUnitsPerEM(), symbol, glyph, vertexFactory); KernSubtable kernSub = null; { final KernTable kern = font.getKernTable(); @@ -248,33 +242,12 @@ class TypecastFont implements Font { } glyph.clearPointData(); - if( TypecastFont.USE_PRESCALED_ADVANCE ) { - final HdmxTable hdmx = font.getHdmxTable(); - if (null!= result && null != hdmx) { - /*if(DEBUG) { - System.err.println("hdmx "+hdmx); - }*/ - for (int i=0; i<hdmx.getNumberOfRecords(); i++) - { - final HdmxTable.DeviceRecord dr = hdmx.getRecord(i); - if(DEBUG) { - System.err.println("hdmx advance : pixelsize "+dr.getPixelSize()+" -> advance "+dr.getWidth(glyph_id)); - } - result.addAdvance(dr.getPixelSize(), dr.getWidth(glyph_id)); - } - } - } char2Glyph.put(symbol, result); } return result; } @Override - public float getLineHeight(final float pixelSize) { - return pixelSize * metrics.getScale( getLineHeightFU() ); - } - - @Override public float getLineHeight() { return metrics.getScale( getLineHeightFU() ); } @@ -290,26 +263,6 @@ class TypecastFont implements Font { } @Override - public float getMetricWidth(final CharSequence string, final float pixelSize) { - if( !TypecastFont.USE_PRESCALED_ADVANCE ) { - return pixelSize * getMetricWidth(string); - } else { - float width = 0; - final int len = string.length(); - for (int i=0; i< len; i++) { - final char character = string.charAt(i); - if (character == '\n') { - width = 0; - } else { - final Glyph glyph = getGlyph(character); - width += glyph.getAdvance(pixelSize); // uses pixelSize mapping, different than glyph.getAdvanceFU() - } - } - return width; - } - } - - @Override public float getMetricWidth(final CharSequence string) { return metrics.getScale( getMetricWidthFU(string) ); } @@ -331,11 +284,6 @@ class TypecastFont implements Font { } @Override - public float getMetricHeight(final CharSequence string, final float pixelSize) { - return pixelSize * getMetricHeight(string); - } - - @Override public float getMetricHeight(final CharSequence string) { return metrics.getScale( getMetricHeightFU(string) ); } @@ -355,40 +303,8 @@ class TypecastFont implements Font { } @Override - public AABBox getMetricBounds(final CharSequence string, final float pixelSize) { - if( !TypecastFont.USE_PRESCALED_ADVANCE ) { - return getMetricBoundsFU(string).scale(pixelSize/metrics.getUnitsPerEM(), new float[3]); - } else { - if (string == null) { - return new AABBox(); - } - final int charCount = string.length(); - final float lineHeight = getLineHeight(pixelSize); - float totalHeight = 0; - float totalWidth = 0; - float curLineWidth = 0; - for (int i=0; i<charCount; i++) { - final char character = string.charAt(i); - if (character == '\n') { - totalWidth = Math.max(curLineWidth, totalWidth); - curLineWidth = 0; - totalHeight += lineHeight; - continue; - } - final Glyph glyph = getGlyph(character); - curLineWidth += glyph.getAdvance(pixelSize); // uses pixelSize mapping, different than glyph.getAdvanceFU() - } - if (curLineWidth > 0) { - totalHeight += lineHeight; - totalWidth = Math.max(curLineWidth, totalWidth); - } - return new AABBox(0, 0, 0, totalWidth, totalHeight,0); - } - } - - @Override public AABBox getMetricBounds(final CharSequence string) { - return getMetricBoundsFU(string).scale(1.0f/metrics.getUnitsPerEM(), new float[3]); + return getMetricBoundsFU(string).scale2(1.0f/metrics.getUnitsPerEM(), new float[3]); } @Override @@ -419,62 +335,6 @@ class TypecastFont implements Font { } @Override - public AABBox getPointsBounds(final AffineTransform transform, final CharSequence string, final float pixelSize) { - if( !TypecastFont.USE_PRESCALED_ADVANCE ) { - return getPointsBoundsFU(transform, string).scale(pixelSize/metrics.getUnitsPerEM(), new float[3]); - } else { - if (string == null) { - return new AABBox(); - } - final AffineTransform temp1 = new AffineTransform(); - final AffineTransform temp2 = new AffineTransform(); - final float pixelSize2 = pixelSize / metrics.getUnitsPerEM(); - final int charCount = string.length(); - final float lineHeight = getLineHeight(pixelSize); - final AABBox tbox = new AABBox(); - final AABBox res = new AABBox(); - - float y = 0; - float advanceTotal = 0; - - for(int i=0; i< charCount; i++) { - final char character = string.charAt(i); - if( '\n' == character ) { - y -= lineHeight; - advanceTotal = 0; - } else if (character == ' ') { - advanceTotal += getAdvanceWidth(Glyph.ID_SPACE, pixelSize); - } else { - // reset transform - if( null != transform ) { - temp1.setTransform(transform); - } else { - temp1.setToIdentity(); - } - temp1.translate(advanceTotal, y, temp2); - temp1.scale(pixelSize2, pixelSize2, temp2); - tbox.reset(); - - final Font.Glyph glyph = getGlyph(character); - res.resize(temp1.transform(glyph.getBBoxFU(), tbox)); - - final OutlineShape glyphShape = glyph.getShape(); - if( null == glyphShape ) { - continue; - } - advanceTotal += glyph.getAdvance(pixelSize); - } - } - return res; - } - } - - @Override - public AABBox getPointsBounds(final AffineTransform transform, final CharSequence string) { - return getPointsBoundsFU(transform, string).scale(1.0f/metrics.getUnitsPerEM(), new float[3]); - } - - @Override public AABBox getPointsBoundsFU(final AffineTransform transform, final CharSequence string) { if (string == null) { return new AABBox(); @@ -520,6 +380,11 @@ class TypecastFont implements Font { } @Override + public AABBox getPointsBounds(final AffineTransform transform, final CharSequence string) { + return getPointsBoundsFU(transform, string).scale2(1.0f/metrics.getUnitsPerEM(), new float[3]); + } + + @Override final public int getNumGlyphs() { return font.getNumGlyphs(); } diff --git a/src/jogl/classes/jogamp/graph/font/typecast/TypecastGlyph.java b/src/jogl/classes/jogamp/graph/font/typecast/TypecastGlyph.java index b5876758f..e6a655661 100644 --- a/src/jogl/classes/jogamp/graph/font/typecast/TypecastGlyph.java +++ b/src/jogl/classes/jogamp/graph/font/typecast/TypecastGlyph.java @@ -27,7 +27,6 @@ */ package jogamp.graph.font.typecast; -import com.jogamp.common.util.IntIntHashMap; import com.jogamp.graph.curve.OutlineShape; import com.jogamp.graph.font.Font; import com.jogamp.opengl.math.geom.AABBox; @@ -38,76 +37,11 @@ import jogamp.graph.font.typecast.ot.table.PostTable; public final class TypecastGlyph implements Font.Glyph { - /** Scaled hmtx value */ - public static final class Advance - { - private final Font font; - private final int advance; // in font-units - private final IntIntHashMap size2advanceI; - - public Advance(final Font font, final int advance) - { - this.font = font; - this.advance = advance; - if( TypecastFont.USE_PRESCALED_ADVANCE ) { - size2advanceI = new IntIntHashMap(); - size2advanceI.setKeyNotFoundValue(0); - } else { - size2advanceI = null; - } - } - - public final void reset() { - if( TypecastFont.USE_PRESCALED_ADVANCE ) { - size2advanceI.clear(); - } - } - - public final Font getFont() { return font; } - - public final int getUnitsPerEM() { return this.font.getMetrics().getUnitsPerEM(); } - - public final float getScale(final int funits) - { - return this.font.getMetrics().getScale(funits); - } - - public final void add(final float pixelSize, final float advance) - { - if( TypecastFont.USE_PRESCALED_ADVANCE ) { - size2advanceI.put(Float.floatToIntBits(pixelSize), Float.floatToIntBits(advance)); - } - } - - public final float get(final float pixelSize) - { - if( !TypecastFont.USE_PRESCALED_ADVANCE ) { - return pixelSize * font.getMetrics().getScale( advance ); - } else { - final int sI = Float.floatToIntBits( (float) Math.ceil( pixelSize ) ); - final int aI = size2advanceI.get(sI); - if( 0 != aI ) { - return Float.intBitsToFloat(aI); - } - return pixelSize * font.getMetrics().getScale( advance ); - } - } - - @Override - public final String toString() - { - return "\nAdvance:"+ - "\n advance: "+this.advance+ - "\n advances: \n"+size2advanceI; - } - } - public static final class Metrics { private final TypecastFont font; private final AABBox bbox; // in font-units private final int advance; // in font-units - private final Advance advance2; /** * @@ -120,17 +54,6 @@ public final class TypecastGlyph implements Font.Glyph { this.font = font; this.bbox = bbox; this.advance = advance; - if( TypecastFont.USE_PRESCALED_ADVANCE ) { - this.advance2 = new Advance(font, advance); - } else { - this.advance2 = null; - } - } - - public final void reset() { - if( TypecastFont.USE_PRESCALED_ADVANCE ) { - advance2.reset(); - } } public final TypecastFont getFont() { return font; } @@ -145,27 +68,12 @@ public final class TypecastGlyph implements Font.Glyph { /** Return advance in font units to be divided by unitsPerEM */ public final int getAdvanceFU() { return this.advance; } - public final void addAdvance(final float pixelSize, final float advance) { - if( TypecastFont.USE_PRESCALED_ADVANCE ) { - this.advance2.add(pixelSize, advance); - } - } - - public final float getAdvance(final float pixelSize) { - if( TypecastFont.USE_PRESCALED_ADVANCE ) { - return this.advance2.get(pixelSize); - } else { - return pixelSize * font.getMetrics().getScale( advance ); - } - } - @Override public final String toString() { return "\nMetrics:"+ "\n bbox: "+this.bbox+ - "\n advance: "+this.advance+ - "\n advance2: "+this.advance2; + "\n advance: "+this.advance; } } @@ -272,8 +180,8 @@ public final class TypecastGlyph implements Font.Glyph { } @Override - public final AABBox getBBox(final AABBox dest, final float pixelSize, final float[] tmpV3) { - return dest.copy(metrics.getBBoxFU()).scale(pixelSize/metrics.getUnitsPerEM(), tmpV3); + public final AABBox getBBoxFU() { + return metrics.getBBoxFU(); } @Override @@ -282,8 +190,8 @@ public final class TypecastGlyph implements Font.Glyph { } @Override - public final AABBox getBBoxFU() { - return metrics.getBBoxFU(); + public final AABBox getBBox(final AABBox dest, final float[] tmpV3) { + return dest.copy(metrics.getBBoxFU()).scale2(1.0f/metrics.getUnitsPerEM(), tmpV3); } @Override @@ -292,17 +200,6 @@ public final class TypecastGlyph implements Font.Glyph { @Override public float getAdvance() { return getScale( getAdvanceFU() ); } - protected final void addAdvance(final float pixelSize, final float advance) { - if( TypecastFont.USE_PRESCALED_ADVANCE ) { - this.metrics.addAdvance(pixelSize, advance); - } - } - - @Override - public final float getAdvance(final float pixelSize) { - return metrics.getAdvance(pixelSize); - } - @Override public final boolean isKerningHorizontal() { return kerning_horizontal; } diff --git a/src/jogl/classes/jogamp/graph/font/typecast/TypecastHMetrics.java b/src/jogl/classes/jogamp/graph/font/typecast/TypecastHMetrics.java index 705246822..274114e4a 100644 --- a/src/jogl/classes/jogamp/graph/font/typecast/TypecastHMetrics.java +++ b/src/jogl/classes/jogamp/graph/font/typecast/TypecastHMetrics.java @@ -69,21 +69,41 @@ final class TypecastHMetrics implements Metrics { } @Override + public float getAscent() { + return getScale( getAscentFU() ); + } + + @Override public int getDescentFU() { return -hheaTable.getDescender(); // inverted } @Override + public float getDescent() { + return getScale( getDescentFU() ); + } + + @Override public int getLineGapFU() { return -hheaTable.getLineGap(); // inverted } @Override + public float getLineGap() { + return getScale( getLineGapFU() ); + } + + @Override public int getMaxExtendFU() { return hheaTable.getXMaxExtent(); } @Override + public float getMaxExtend() { + return getScale( getMaxExtendFU() ); + } + + @Override public final int getUnitsPerEM() { return unitsPerEM; } @@ -94,12 +114,12 @@ final class TypecastHMetrics implements Metrics { } @Override - public final AABBox getBBox(final AABBox dest) { + public final AABBox getBBoxFU(final AABBox dest) { return dest.copy(bbox); } @Override - public final AABBox getBBox(final AABBox dest, final float pixelSize, final float[] tmpV3) { - return dest.setSize(bbox.getLow(), bbox.getHigh()).scale(pixelSize*unitsPerEM_inv, tmpV3); + public AABBox getBBox(final AABBox dest, final float[] tmpV3) { + return dest.setSize(bbox.getLow(), bbox.getHigh()).scale2(unitsPerEM_inv, tmpV3); } } diff --git a/src/jogl/classes/jogamp/graph/font/typecast/TypecastRenderer.java b/src/jogl/classes/jogamp/graph/font/typecast/TypecastRenderer.java index 472e3e58e..60319d842 100644 --- a/src/jogl/classes/jogamp/graph/font/typecast/TypecastRenderer.java +++ b/src/jogl/classes/jogamp/graph/font/typecast/TypecastRenderer.java @@ -47,70 +47,49 @@ import com.jogamp.graph.geom.Vertex.Factory; public class TypecastRenderer { private static final boolean DEBUG = Debug.debug("graph.font.Renderer"); - private static void addShapeMoveTo(final OutlineShape shape, final Point p1) { + private static void addShapeMoveTo(final float unitsPerEM, final OutlineShape shape, final Point p1) { if( DEBUG ) { System.err.println("Shape.MoveTo: "+p1); } shape.closeLastOutline(false); shape.addEmptyOutline(); - shape.addVertex(0, p1.x, p1.y, p1.onCurve); + shape.addVertex(0, p1.x/unitsPerEM, p1.y/unitsPerEM, p1.onCurve); } - private static void addShapeLineTo(final OutlineShape shape, final Point p1) { + private static void addShapeLineTo(final float unitsPerEM, final OutlineShape shape, final Point p1) { if( DEBUG ) { System.err.println("Shape.LineTo: "+p1); } - shape.addVertex(0, p1.x, p1.y, p1.onCurve); + shape.addVertex(0, p1.x/unitsPerEM, p1.y/unitsPerEM, p1.onCurve); } - private static void addShapeQuadTo(final OutlineShape shape, final Point p1, final Point p2) { + private static void addShapeQuadTo(final float unitsPerEM, final OutlineShape shape, final Point p1, final Point p2) { if( DEBUG ) { System.err.println("Shape.QuadTo: "+p1+", "+p2); } - shape.addVertex(0, p1.x, p1.y, p1.onCurve); - shape.addVertex(0, p2.x, p2.y, p2.onCurve); + shape.addVertex(0, p1.x/unitsPerEM, p1.y/unitsPerEM, p1.onCurve); + shape.addVertex(0, p2.x/unitsPerEM, p2.y/unitsPerEM, p2.onCurve); } - private static void addShapeQuadTo(final OutlineShape shape, final Point p1, final float p2x, - final float p2y, final boolean p2OnCurve) { + private static void addShapeQuadTo(final float unitsPerEM, final OutlineShape shape, final Point p1, + final float p2x, final float p2y, final boolean p2OnCurve) { if( DEBUG ) { System.err.println("Shape.QuadTo: "+p1+", p2 "+p2x+", "+p2y+", onCurve "+p2OnCurve); } - shape.addVertex(0, p1.x, p1.y, p1.onCurve); - shape.addVertex(0, p2x, p2y, p2OnCurve); + shape.addVertex(0, p1.x/unitsPerEM, p1.y/unitsPerEM, p1.onCurve); + shape.addVertex(0, p2x/unitsPerEM, p2y/unitsPerEM, p2OnCurve); } /** - private static void addShapeCubicTo(final OutlineShape shape, Factory<? extends Vertex> vertexFactory, Point p1, Point p2, Point p3) { - shape.addVertex(0, p1.x, p1.y, p1.onCurve); - shape.addVertex(0, p2.x, p2.y, p2.onCurve); - shape.addVertex(0, p3.x, p3.y, p3.onCurve); + private static void addShapeCubicTo(final float unitsPerEM, final OutlineShape shape, Factory<? extends Vertex> vertexFactory, Point p1, Point p2, Point p3) { + shape.addVertex(0, p1.x/unitsPerEM, p1.y/unitsPerEM, p1.onCurve); + shape.addVertex(0, p2.x/unitsPerEM, p2.y/unitsPerEM, p2.onCurve); + shape.addVertex(0, p3.x/unitsPerEM, p3.y/unitsPerEM, p3.onCurve); } */ - public static OutlineShape buildShape(final char symbol, final jogamp.graph.font.typecast.ot.Glyph glyph, final Factory<? extends Vertex> vertexFactory) { + public static OutlineShape buildShape(final int unitsPerEM, final char symbol, final jogamp.graph.font.typecast.ot.Glyph glyph, final Factory<? extends Vertex> vertexFactory) { // // See Typecast: GlyphPathFactory.addContourToPath(..) // - if (glyph == null) { return null; } final OutlineShape shape = new OutlineShape(vertexFactory); - buildShapeImpl(shape, symbol, glyph); + buildShapeImpl(unitsPerEM, shape, symbol, glyph); shape.setIsQuadraticNurbs(); return shape; } - /** - private static void buildShapeImpl02(final OutlineShape shape, char symbol, OTGlyph glyph, Factory<? extends Vertex> vertexFactory) { - // Iterate through all of the points in the glyph. Each time we find a - // contour end point, add the point range to the path. - int startIndex = 0; - int count = 0; - for (int i = 0; i < glyph.getPointCount(); i++) { - count++; - if ( glyph.getPoint(i).endOfContour ) { - for(int j=0; j<count; j++) { - final Point p = glyph.getPoint(startIndex + j); - shape.addVertex(0, vertexFactory.create(p.x, p.y, 0, p.onCurve)); - } - shape.closeLastOutline(false); - startIndex = i + 1; - count = 0; - } - } - } */ - - private static void buildShapeImpl(final OutlineShape shape, final char symbol, final jogamp.graph.font.typecast.ot.Glyph glyph) { + private static void buildShapeImpl(final float unitsPerEM, final OutlineShape shape, final char symbol, final jogamp.graph.font.typecast.ot.Glyph glyph) { // Iterate through all of the points in the glyph. Each time we find a // contour end point, add the point range to the path. int startIndex = 0; @@ -140,7 +119,7 @@ public class TypecastRenderer { System.err.println("\t p3["+p3Idx+"] "+p3); } if(offset == 0) { - addShapeMoveTo(shape, p0); + addShapeMoveTo(unitsPerEM, shape, p0); // gp.moveTo(point.x, point.y); } @@ -156,7 +135,7 @@ public class TypecastRenderer { // s = new Line2D.Float(point.x, point.y, p1.x, p1.y); // gp.lineTo( p1.x, p1.y ); - addShapeLineTo(shape, p1); + addShapeLineTo(unitsPerEM, shape, p1); offset++; } else { if (p2.onCurve) { @@ -165,17 +144,17 @@ public class TypecastRenderer { // s = new QuadCurve2D.Float( point.x, point.y, p1.x, p1.y, p2.x, p2.y); // gp.quadTo(p1.x, p1.y, p2.x, p2.y); - addShapeQuadTo(shape, p1, p2); + addShapeQuadTo(unitsPerEM, shape, p1, p2); offset+=2; } else { if (null != p3 && p3.onCurve) { // Branch-3: point.onCurve && !p1.onCurve && !p2.onCurve && p3.onCurve if( DEBUG ) { System.err.println("B3 .. 2-quad p0-p1-p1_2, p1_2-p2-p3 **** 2QUAD"); } // addShapeCubicTo(shape, vertexFactory, p1, p2, p3); - addShapeQuadTo(shape, p1, midValue(p1.x, p2.x), + addShapeQuadTo(unitsPerEM, shape, p1, midValue(p1.x, p2.x), midValue(p1.y, p2.y), true); - addShapeQuadTo(shape, p2, p3); + addShapeQuadTo(unitsPerEM, shape, p2, p3); offset+=3; } else { // Branch-4: point.onCurve && !p1.onCurve && !p2.onCurve && !p3.onCurve @@ -184,7 +163,7 @@ public class TypecastRenderer { // s = new QuadCurve2D.Float(point.x,point.y,p1.x,p1.y, // midValue(p1.x, p2.x), midValue(p1.y, p2.y)); // gp.quadTo(p1.x, p1.y, midValue(p1.x, p2.x), midValue(p1.y, p2.y)); - addShapeQuadTo(shape, p1, midValue(p1.x, p2.x), + addShapeQuadTo(unitsPerEM, shape, p1, midValue(p1.x, p2.x), midValue(p1.y, p2.y), true); offset+=2; // Skip p2 as done in Typecast @@ -198,7 +177,7 @@ public class TypecastRenderer { // s = new QuadCurve2D.Float(midValue(pM.x, point.x), midValue(pM.y, point.y), // point.x, point.y, // midValue(point.x, p1.x), midValue(point.y, p1.y)); - addShapeQuadTo(shape, p0, midValue(p0.x, p1.x), + addShapeQuadTo(unitsPerEM, shape, p0, midValue(p0.x, p1.x), midValue(p0.y, p1.y), true); offset++; } else { @@ -207,7 +186,7 @@ public class TypecastRenderer { // s = new QuadCurve2D.Float(midValue(pM.x, point.x), midValue(pM.y, point.y), // point.x, point.y, p1.x, p1.y); // gp.quadTo(point.x, point.y, p1.x, p1.y); - addShapeQuadTo(shape, p0, p1); + addShapeQuadTo(unitsPerEM, shape, p0, p1); offset++; } } |