summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--src/jogl/classes/com/jogamp/graph/font/Font.java136
-rw-r--r--src/jogl/classes/jogamp/graph/font/typecast/TypecastFont.java74
-rw-r--r--src/jogl/classes/jogamp/graph/font/typecast/TypecastGlyph.java8
-rw-r--r--src/jogl/classes/jogamp/graph/font/typecast/ot/Glyph.java18
-rw-r--r--src/test/com/jogamp/opengl/test/junit/graph/demos/ui/LabelButton.java2
5 files changed, 137 insertions, 101 deletions
diff --git a/src/jogl/classes/com/jogamp/graph/font/Font.java b/src/jogl/classes/com/jogamp/graph/font/Font.java
index 36f00f628..fdef6a612 100644
--- a/src/jogl/classes/com/jogamp/graph/font/Font.java
+++ b/src/jogl/classes/com/jogamp/graph/font/Font.java
@@ -81,42 +81,42 @@ public interface Font {
*/
public interface Metrics {
/**
- * @return ascent in font-units to be divided by {@link #getUnitsPerEM()}
+ * @return ascent in font-units, sourced from `hheaTable' table.
*/
int getAscentFU();
/**
- * @return ascent in font em-size [0..1]
+ * @return ascent in font em-size [0..1], sourced from `hheaTable' table.
*/
float getAscent();
/**
- * @return descent in font-units to be divided by {@link #getUnitsPerEM()}
+ * @return descent in font-units, sourced from `hheaTable' table.
*/
int getDescentFU();
/**
- * @return descend in font em-size [0..1]
+ * @return descend in font em-size [0..1], sourced from `hheaTable' table.
*/
float getDescent();
/**
- * @return line-gap in font-units to be divided by {@link #getUnitsPerEM()}
+ * @return line-gap in font-units, sourced from `hheaTable' table.
*/
int getLineGapFU();
/**
- * @return line-gap in font em-size [0..1]
+ * @return line-gap in font em-size [0..1], sourced from `hheaTable' table.
*/
float getLineGap();
/**
- * @return max-extend in font-units to be divided by {@link #getUnitsPerEM()}
+ * @return max-extend in font-units, sourced from `hheaTable' table.
*/
int getMaxExtendFU();
/**
- * @return max-extend in font em-size [0..1]
+ * @return max-extend in font em-size [0..1], sourced from `hheaTable' table.
*/
float getMaxExtend();
@@ -176,25 +176,31 @@ public interface Font {
float getScale(final int funits);
/**
- * Return the AABBox in font-units to be divided by unitsPerEM
+ * Return the AABBox in font-units, borrowing internal instance.
*/
AABBox getBBoxFU();
/**
- * Return the AABBox in font-units to be divided by unitsPerEM
+ * Return the AABBox in font-units, copying into given dest.
* @param dest AABBox instance set to this metrics boundary in font-units
* @return the given and set AABBox 'dest' in font-units
*/
AABBox getBBoxFU(final AABBox dest);
/**
+ * Return the AABBox in font em-size [0..1], copying into given dest.
* @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 getBBox(final AABBox dest, float[] tmpV3);
- /** Return advance in font units to be divided by unitsPerEM */
+ /**
+ * Return the AABBox in font em-size [0..1], creating a new copy.
+ */
+ AABBox getBBox();
+
+ /** Return advance in font units, sourced from `hmtx` table. */
int getAdvanceFU();
/** Return advance in font em-size [0..1] */
@@ -209,10 +215,10 @@ public interface Font {
int getKerningPairCount();
/**
- * Returns the optional kerning inter-glyph distance within words between this glyph and the given right glyph_id in font-units to be divided by unitsPerEM
+ * Returns the optional kerning inter-glyph distance within words between this glyph and the given right glyph_id in font-units.
*
* @param right_glyphid right glyph code id
- * @return font-units to be divided by unitsPerEM
+ * @return font-units
*/
int getKerningFU(final int right_glyphid);
@@ -246,7 +252,7 @@ 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
+ * Return advance-width of given glyphID in font-units, sourced from `hmtx` table.
* @param glyphID
*/
int getAdvanceWidthFU(final int glyphID);
@@ -266,7 +272,17 @@ public interface Font {
int getNumGlyphs();
/**
- * Return line height in font-units to be divided by unitsPerEM
+ * Return line height in font-units, composed from `hheaTable' table entries.
+ * <pre>
+ * return abs(lineGap) + abs(descent) abs(ascent);
+ * </pre>
+ * or
+ * <pre>
+ * // lineGap negative value
+ * // descent positive value
+ * // ascent negative value
+ * return -1 * ( lineGap - descent + ascent );
+ * </pre>
*/
int getLineHeightFU();
@@ -275,47 +291,89 @@ public interface Font {
*/
float getLineHeight();
- /** 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-height in font-units */
- int getMetricHeightFU(final CharSequence string);
-
- /** Return metric-height in font em-size */
- float getMetricHeight(final CharSequence string);
-
- /** Return layout metric-bounds in font-units, see {@link #getMetricBounds(CharSequence, float)} */
+ /**
+ * Returns metric-bounds in font-units.
+ * <p>
+ * Metric bounds is based on the `hmtx` table's advance of each glyph and `hheaTable' composed line height.
+ * </p>
+ * <p>
+ * For accurate layout consider using {@link #getGlyphBoundsFU(CharSequence)}.
+ * </p>
+ * @see #getMetricBounds(CharSequence)
+ * @see #getGlyphBoundsFU(CharSequence)
+ */
AABBox getMetricBoundsFU(final CharSequence string);
- /** Return layout metric-bounds in font em-size, see {@link #getMetricBounds(CharSequence, float)} */
+ /**
+ * Returns metric-bounds in font em-size.
+ * <p>
+ * Metric bounds is based on the `hmtx` table's advance of each glyph and `hheaTable' composed line height.
+ * </p>
+ * <p>
+ * For accurate layout consider using {@link #getGlyphBounds(CharSequence)}.
+ * </p>
+ * @see #getMetricBoundsFU(CharSequence)
+ * @see #getGlyphBounds(CharSequence)
+ * @see #getGlyphShapeBounds(CharSequence)
+ */
AABBox getMetricBounds(final CharSequence string);
/**
- * Return the bounding box by taking each glyph's font em-sized bounding box into account.
- * @param transform optional given transform
+ * Returns accurate bounding box by taking each glyph's font em-sized bounding box into account.
+ * <p>
+ * Glyph bounds is based on each glyph's bounding box and `hheaTable' composed line height.
+ * </p>
* @param string string text
* @return the bounding box of the given string in font em-size [0..1]
+ * @see #getGlyphBoundsFU(CharSequence)
+ * @see #getGlyphShapeBounds(CharSequence)
+ * @see #getMetricBounds(CharSequence)
*/
- AABBox getPointsBounds(final AffineTransform transform, final CharSequence string);
+ AABBox getGlyphBounds(final CharSequence string);
/**
- * Return the bounding box by taking each glyph's font-units sized bounding box into account.
- * @param transform optional given transform
+ * Returns accurate bounding box by taking each glyph's font-units sized bounding box into account.
+ * <p>
+ * Glyph bounds is based on each glyph's bounding box and `hheaTable' composed line height.
+ * </p>
* @param string string text
* @return the bounding box of the given string in font-units [0..1]
+ * @see #getGlyphBounds(CharSequence)
*/
- AABBox getPointsBoundsFU(final AffineTransform transform, final CharSequence string);
+ AABBox getGlyphBoundsFU(final CharSequence string);
/**
- * Return the bounding box of the given string by taking each glyph's font em-sized OutlineShape into account.
+ * Returns accurate bounding box by taking each glyph's font em-sized {@link OutlineShape} into account.
+ * <p>
+ * Glyph shape bounds is based on each glyph's {@link OutlineShape} and `hheaTable' composed line height.
+ * </p>
+ * <p>
+ * This method is only exposed to validate the produced {@link OutlineShape} against {@link #getGlyphBounds(CharSequence)}.
+ * </p>
* @param transform optional given transform
* @param string string text
* @return the bounding box of the given string in font-units [0..1]
+ * @see #getGlyphShapeBounds(CharSequence)
+ * @see #getGlyphBounds(CharSequence)
+ * @see #getMetricBounds(CharSequence)
+ */
+ AABBox getGlyphShapeBounds(final AffineTransform transform, final CharSequence string);
+
+ /**
+ * Returns accurate bounding box by taking each glyph's font em-sized {@link OutlineShape} into account.
+ * <p>
+ * Glyph shape bounds is based on each glyph's {@link OutlineShape} and `hheaTable' composed line height.
+ * </p>
+ * <p>
+ * This method is only exposed to validate the produced {@link OutlineShape} against {@link #getGlyphBounds(CharSequence)}.
+ * </p>
+ * @param string string text
+ * @return the bounding box of the given string in font-units [0..1]
+ * @see #getGlyphShapeBounds(AffineTransform, CharSequence)
+ * @see #getGlyphBounds(CharSequence)
+ * @see #getMetricBounds(CharSequence)
*/
- AABBox getPointsBounds2(final AffineTransform transform, final CharSequence string);
+ AABBox getGlyphShapeBounds(final CharSequence string);
boolean isPrintableChar(final char c);
@@ -329,7 +387,7 @@ public interface Font {
* @param transform optional given transform
* @param font the target {@link Font}
* @param string string text
- * @return the bounding box of the given string by taking each glyph's font em-sized [0..1] OutlineShape into account.
+ * @return the bounding box of the given string by taking each glyph's font em-sized [0..1] {@link OutlineShape} into account.
*/
AABBox processString(final OutlineShape.Visitor visitor, final AffineTransform transform,
final CharSequence string);
@@ -346,7 +404,7 @@ public interface Font {
* @param string string text
* @param temp1 temporary AffineTransform storage, mandatory
* @param temp2 temporary AffineTransform storage, mandatory
- * @return the bounding box of the given string by taking each glyph's font em-sized [0..1] OutlineShape into account.
+ * @return the bounding box of the given string by taking each glyph's font em-sized [0..1] {@link OutlineShape} into account.
*/
AABBox processString(final OutlineShape.Visitor visitor, final AffineTransform transform,
final CharSequence string,
diff --git a/src/jogl/classes/jogamp/graph/font/typecast/TypecastFont.java b/src/jogl/classes/jogamp/graph/font/typecast/TypecastFont.java
index eeee14365..f5358b74b 100644
--- a/src/jogl/classes/jogamp/graph/font/typecast/TypecastFont.java
+++ b/src/jogl/classes/jogamp/graph/font/typecast/TypecastFont.java
@@ -254,53 +254,13 @@ class TypecastFont implements Font {
public int getLineHeightFU() {
final Metrics metrics = getMetrics();
final int lineGap = metrics.getLineGapFU() ; // negative value!
- final int ascent = metrics.getAscentFU() ; // negative value!
final int descent = metrics.getDescentFU() ; // positive value!
+ final int ascent = metrics.getAscentFU() ; // negative value!
final int advanceY = lineGap - descent + ascent; // negative value!
return -advanceY;
}
@Override
- public float getMetricWidth(final CharSequence string) {
- return metrics.getScale( getMetricWidthFU(string) );
- }
-
- @Override
- public int getMetricWidthFU(final CharSequence string) {
- int 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(getGlyphID(character));
- width += glyph.getAdvanceFU();
- }
- }
- return width;
- }
-
- @Override
- public float getMetricHeight(final CharSequence string) {
- return metrics.getScale( getMetricHeightFU(string) );
- }
-
- @Override
- public int getMetricHeightFU(final CharSequence string) {
- int height = 0;
-
- for (int i=0; i<string.length(); i++) {
- final char character = string.charAt(i);
- if (character != ' ') {
- final Glyph glyph = getGlyph(getGlyphID(character));
- height = (int)Math.ceil(Math.max(glyph.getBBoxFU().getHeight(), height));
- }
- }
- return height;
- }
-
- @Override
public AABBox getMetricBounds(final CharSequence string) {
return getMetricBoundsFU(string).scale2(1.0f/metrics.getUnitsPerEM(), new float[3]);
}
@@ -310,6 +270,7 @@ class TypecastFont implements Font {
if (null == string || 0 == string.length() ) {
return new AABBox();
}
+ final AABBox res = new AABBox();
final int charCount = string.length();
final int lineHeight = getLineHeightFU();
@@ -322,23 +283,28 @@ class TypecastFont implements Font {
if (character == '\n') {
advanceTotal = 0;
y -= lineHeight;
- continue;
+ } else if (character == ' ') {
+ advanceTotal += getAdvanceWidthFU(Glyph.ID_SPACE);
+ } else {
+ advanceTotal += getAdvanceWidthFU( getGlyphID( character ) );
}
- advanceTotal += getAdvanceWidthFU( getGlyphID( character ) );
+ res.resize(advanceTotal, y, 0f);
}
- if (advanceTotal > 0) {
+ if( 0 < advanceTotal ) {
+ // add one line for current non '\n' terminated
y -= lineHeight;
+ res.resize(advanceTotal, y, 0f);
}
- return new AABBox(0,y,0, advanceTotal,0,0);
+ return res;
}
@Override
- public AABBox getPointsBounds(final AffineTransform transform, final CharSequence string) {
- return getPointsBoundsFU(transform, string).scale2(1.0f/metrics.getUnitsPerEM(), new float[3]);
+ public AABBox getGlyphBounds(final CharSequence string) {
+ return getGlyphBoundsFU(string).scale2(1.0f/metrics.getUnitsPerEM(), new float[3]);
}
@Override
- public AABBox getPointsBoundsFU(final AffineTransform transform, final CharSequence string) {
+ public AABBox getGlyphBoundsFU(final CharSequence string) {
if (null == string || 0 == string.length() ) {
return new AABBox();
}
@@ -366,11 +332,7 @@ class TypecastFont implements Font {
left_glyph = null;
} else {
// reset transform
- if( null != transform ) {
- temp1.setTransform(transform);
- } else {
- temp1.setToIdentity();
- }
+ temp1.setToIdentity();
final int glyph_id = getGlyphID(character);
final Font.Glyph glyph = getGlyph(glyph_id);
final OutlineShape glyphShape = glyph.getShape();
@@ -391,7 +353,11 @@ class TypecastFont implements Font {
}
@Override
- public AABBox getPointsBounds2(final AffineTransform transform, final CharSequence string) {
+ public AABBox getGlyphShapeBounds(final CharSequence string) {
+ return getGlyphShapeBounds(null, string);
+ }
+ @Override
+ public AABBox getGlyphShapeBounds(final AffineTransform transform, final CharSequence string) {
if (null == string || 0 == string.length() ) {
return new AABBox();
}
diff --git a/src/jogl/classes/jogamp/graph/font/typecast/TypecastGlyph.java b/src/jogl/classes/jogamp/graph/font/typecast/TypecastGlyph.java
index 9db8fc6d5..12d492f6e 100644
--- a/src/jogl/classes/jogamp/graph/font/typecast/TypecastGlyph.java
+++ b/src/jogl/classes/jogamp/graph/font/typecast/TypecastGlyph.java
@@ -65,7 +65,7 @@ public final class TypecastGlyph implements Font.Glyph {
/** in font-units */
public final AABBox getBBoxFU() { return this.bbox; }
- /** Return advance in font units to be divided by unitsPerEM */
+ /** Return advance in font units, sourced from `hmtx` table. */
public final int getAdvanceFU() { return this.advance; }
@Override
@@ -187,6 +187,12 @@ public final class TypecastGlyph implements Font.Glyph {
}
@Override
+ public final AABBox getBBox() {
+ final AABBox dest = new AABBox();
+ return dest.copy(metrics.getBBoxFU()).scale2(1.0f/metrics.getUnitsPerEM(), new float[2]);
+ }
+
+ @Override
public final int getAdvanceFU() { return metrics.getAdvanceFU(); }
@Override
diff --git a/src/jogl/classes/jogamp/graph/font/typecast/ot/Glyph.java b/src/jogl/classes/jogamp/graph/font/typecast/ot/Glyph.java
index 03a2394d9..5bb610a1c 100644
--- a/src/jogl/classes/jogamp/graph/font/typecast/ot/Glyph.java
+++ b/src/jogl/classes/jogamp/graph/font/typecast/ot/Glyph.java
@@ -31,25 +31,31 @@ public abstract class Glyph {
public Glyph(final int glyph_id) {
_glyph_id = glyph_id;
}
-
+
/** Return the assigned glyph ID of this instance */
public final int getID() { return _glyph_id; }
-
+
public abstract void clearPointData();
- /** Return the AABBox in font-units */
+ /**
+ * Return the AABBox in font-units.
+ * <p>
+ * This is either the GlyphDescripton's min- and maximum for TTF
+ * or the calculated box over all points.
+ * </p>
+ */
public final AABBox getBBox() { return _bbox; }
-
+
/** hmtx value */
public abstract int getAdvanceWidth();
-
+
/** hmtx value */
public abstract short getLeftSideBearing();
public abstract Point getPoint(int i);
public abstract int getPointCount();
-
+
@Override
public abstract String toString();
}
diff --git a/src/test/com/jogamp/opengl/test/junit/graph/demos/ui/LabelButton.java b/src/test/com/jogamp/opengl/test/junit/graph/demos/ui/LabelButton.java
index 4d62cb2b1..59514375c 100644
--- a/src/test/com/jogamp/opengl/test/junit/graph/demos/ui/LabelButton.java
+++ b/src/test/com/jogamp/opengl/test/junit/graph/demos/ui/LabelButton.java
@@ -95,7 +95,7 @@ public class LabelButton extends RoundButton {
// Precompute text-box size .. guessing pixelSize
final float lw = width * ( 1f - spacingX ) ;
final float lh = height * ( 1f - spacingY ) ;
- final AABBox lbox0_em = label.font.getPointsBounds(null, label.text);
+ final AABBox lbox0_em = label.font.getGlyphBounds(label.text);
final float lsx = lw / lbox0_em.getWidth();
final float lsy = lh / lbox0_em.getHeight();
final float lScale = lsx < lsy ? lsx : lsy;