aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorSven Gothel <[email protected]>2023-02-12 07:17:16 +0100
committerSven Gothel <[email protected]>2023-02-12 07:17:16 +0100
commit93c51380f34c3eb203f46df52fed49a8a967510e (patch)
tree52d8745dffc4f7581efdc118f7ec0792b7b75315 /src
parent87060fe41b559418ea7b383e162d3d80fb515e0b (diff)
Graph font/typecast: Adopt to our Typecast updates (see below); Fix kerning; Use TestTextRendererNEWT01 to produce validation snaps
- Move kerning handling from Font to Font.Glyph using binary-search for right-glyph-id on kerning subset from this instance (left) - TextRegionUtil: Kerning must be added before translation as it applies before the current right-glyph. - TestTextRendererNEWT01 produces validation snapshots against LibreOffice print-preview snapshots - GPUTextRendererListenerBase01 added another text for kerning validation, show more font-size details (pt, px, mm)
Diffstat (limited to 'src')
-rw-r--r--src/jogl/classes/com/jogamp/graph/curve/opengl/TextRegionUtil.java35
-rw-r--r--src/jogl/classes/com/jogamp/graph/font/Font.java56
-rw-r--r--src/jogl/classes/jogamp/graph/font/typecast/TypecastFont.java61
-rw-r--r--src/jogl/classes/jogamp/graph/font/typecast/TypecastFontConstructor.java4
-rw-r--r--src/jogl/classes/jogamp/graph/font/typecast/TypecastGlyph.java133
-rw-r--r--src/jogl/classes/jogamp/graph/font/typecast/TypecastRenderer.java5
-rw-r--r--src/test/com/jogamp/opengl/test/junit/graph/TestFontsNEWT00.java32
-rw-r--r--src/test/com/jogamp/opengl/test/junit/graph/TestTextRendererNEWT00.java5
-rw-r--r--src/test/com/jogamp/opengl/test/junit/graph/TestTextRendererNEWT01.java146
-rw-r--r--src/test/com/jogamp/opengl/test/junit/graph/TestTextRendererNEWTBugXXXX.java2
-rw-r--r--src/test/com/jogamp/opengl/test/junit/graph/demos/GPURendererListenerBase01.java51
-rw-r--r--src/test/com/jogamp/opengl/test/junit/graph/demos/GPUTextNewtDemo.java4
-rw-r--r--src/test/com/jogamp/opengl/test/junit/graph/demos/GPUTextRendererListenerBase01.java155
-rw-r--r--src/test/com/jogamp/opengl/test/junit/graph/demos/ui/Label.java6
-rw-r--r--src/test/com/jogamp/opengl/test/junit/graph/demos/ui/Label0.java5
-rw-r--r--src/test/com/jogamp/opengl/test/junit/jogl/demos/es2/av/MovieCube.java4
16 files changed, 441 insertions, 263 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 5aa2be258..a4ba4bf52 100644
--- a/src/jogl/classes/com/jogamp/graph/curve/opengl/TextRegionUtil.java
+++ b/src/jogl/classes/com/jogamp/graph/curve/opengl/TextRegionUtil.java
@@ -89,25 +89,21 @@ public class TextRegionUtil {
final int charCount = str.length();
// region.setFlipped(true);
- final Font.Metrics metrics = font.getMetrics();
final int lineHeight = font.getLineHeightFU();
int y = 0;
int advanceTotal = 0;
- char left_character = 0;
- int left_glyphid = 0;
+ Font.Glyph left_glyph = null;
for(int i=0; i< charCount; i++) {
final char character = str.charAt(i);
if( '\n' == character ) {
y -= lineHeight;
advanceTotal = 0;
- left_glyphid = 0;
- left_character = 0;
+ left_glyph = null;
} else if (character == ' ') {
advanceTotal += font.getAdvanceWidthFU(Glyph.ID_SPACE);
- left_glyphid = 0;
- left_character = character;
+ left_glyph = null;
} else {
// reset transform
if( null != transform ) {
@@ -115,27 +111,20 @@ public class TextRegionUtil {
} else {
temp1.setToIdentity();
}
- temp1.translate(advanceTotal, y, temp2);
-
final Font.Glyph glyph = font.getGlyph(character);
final OutlineShape glyphShape = glyph.getShape();
if( null == glyphShape ) {
- left_glyphid = 0;
+ left_glyph = null;
+ temp1.translate(advanceTotal, y, temp2);
continue;
}
- visitor.visit(glyphShape, temp1);
- final int right_glyphid = glyph.getID();
- final int kern = font.getKerningFU(left_glyphid, right_glyphid);
- final int advance = glyph.getAdvanceFU();
- advanceTotal += advance + kern;
- if( Region.DEBUG_INSTANCE && 0 != left_character && kern > 0f ) {
- System.err.println(": '"+left_character+"'/"+left_glyphid+" -> '"+character+"'/"+right_glyphid+
- ": a "+advance+"px + k ["+kern+"em, "+kern+"px = "+(advance+kern)+"px -> "+advanceTotal+"px, y "+y);
+ if( null != left_glyph ) {
+ advanceTotal += left_glyph.getKerningFU(glyph.getID());
}
- // advanceTotal += glyph.getAdvance(pixelSize, true)
- // + font.getKerning(left_glyphid, right_glyphid);
- left_glyphid = right_glyphid;
- left_character = character;
+ temp1.translate(advanceTotal, y, temp2);
+ visitor.visit(glyphShape, temp1);
+ advanceTotal += glyph.getAdvanceFU();
+ left_glyph = glyph;
}
}
}
@@ -351,7 +340,7 @@ public class TextRegionUtil {
protected final String getKey(final Font font, final CharSequence str, final int special) {
final StringBuilder sb = new StringBuilder();
- return font.getName(sb, Font.NAME_UNIQUNAME)
+ return sb.append( font.getName(Font.NAME_UNIQUNAME) )
.append(".").append(str.hashCode()).append(".").append(special).toString();
}
diff --git a/src/jogl/classes/com/jogamp/graph/font/Font.java b/src/jogl/classes/com/jogamp/graph/font/Font.java
index 9f25b5481..5c63227b3 100644
--- a/src/jogl/classes/com/jogamp/graph/font/Font.java
+++ b/src/jogl/classes/com/jogamp/graph/font/Font.java
@@ -144,6 +144,8 @@ public interface Font {
Font getFont();
char getSymbol();
+
+ /** Return this glyph's ID */
int getID();
/**
@@ -188,20 +190,49 @@ public interface Font {
*/
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 */
+ boolean isKerningCrossstream();
+
+ /** Return the number of kerning values stored for this glyph, associated to a right hand glyph. */
+ 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
+ *
+ * @param right_glyphid right glyph code id
+ * @return font-units to be divided by unitsPerEM
+ */
+ int getKerningFU(final int right_glyphid);
+
+ /**
+ * Returns the optional kerning inter-glyph distance within words between this glyph and the given right glyph_id in fractional font em-size [0..1].
+ *
+ * @param right_glyphid right glyph code id
+ * @return fractional font em-size distance [0..1]
+ */
+ float getKerning(final int right_glyphid);
+
OutlineShape getShape();
@Override
int hashCode();
+
+ @Override
+ String toString();
+
+ /** Return all glyph details as string. */
+ String fullString();
}
String getName(final int nameIndex);
- StringBuilder getName(final StringBuilder string, final int nameIndex);
/** Shall return the family and subfamily name, separated a dash.
* <p>{@link #getName(StringBuilder, int)} w/ {@link #NAME_FAMILY} and {@link #NAME_SUBFAMILY}</p>
* <p>Example: "{@code Ubuntu-Regular}"</p> */
- StringBuilder getFullFamilyName(final StringBuilder buffer);
+ String getFullFamilyName();
StringBuilder getAllNames(final StringBuilder string, final String separator);
@@ -225,27 +256,12 @@ public interface Font {
*/
int getAdvanceWidthFU(final int glyphID);
- /**
- * Returns the optional kerning inter-glyph distance within words in fractional font em-size [0..1].
- *
- * @param left_glyphid left glyph code id
- * @param right_glyphid right glyph code id
- * @return fractional font em-size distance [0..1]
- */
- float getKerning(final int left_glyphid, final int right_glyphid);
-
- /**
- * Returns the optional kerning inter-glyph distance within words in fractional font-units to be divided by unitsPerEM
- *
- * @param left_glyphid left glyph code id
- * @param right_glyphid right glyph code id
- * @return font-units to be divided by unitsPerEM
- */
- int getKerningFU(final int left_glyphid, final int right_glyphid);
-
Metrics getMetrics();
+
int getGlyphID(final char symbol);
+
Glyph getGlyph(final char symbol);
+
int getNumGlyphs();
/**
diff --git a/src/jogl/classes/jogamp/graph/font/typecast/TypecastFont.java b/src/jogl/classes/jogamp/graph/font/typecast/TypecastFont.java
index 885261bf9..146bc0380 100644
--- a/src/jogl/classes/jogamp/graph/font/typecast/TypecastFont.java
+++ b/src/jogl/classes/jogamp/graph/font/typecast/TypecastFont.java
@@ -27,13 +27,14 @@
*/
package jogamp.graph.font.typecast;
-import jogamp.graph.font.typecast.ot.OTFont;
import jogamp.graph.font.typecast.ot.OTFontCollection;
+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;
import jogamp.graph.font.typecast.ot.table.KernTable;
import jogamp.graph.font.typecast.ot.table.KerningPair;
@@ -54,7 +55,7 @@ class TypecastFont implements Font {
private static final Vertex.Factory<SVertex> vertexFactory = SVertex.factory();
// private final OTFontCollection fontset;
- /* pp */ final OTFont font;
+ /* pp */ final TTFont font;
private final CmapFormat cmapFormat;
private final int cmapentries;
private final IntObjectHashMap char2Glyph;
@@ -153,22 +154,16 @@ class TypecastFont implements Font {
}
@Override
- public StringBuilder getName(final StringBuilder sb, final int nameIndex) {
- return font.getName(nameIndex, sb);
- }
- @Override
public String getName(final int nameIndex) {
- return getName(null, nameIndex).toString();
+ return font.getName(nameIndex);
}
@Override
public StringBuilder getAllNames(final StringBuilder sb, final String separator) {
return font.getAllNames(sb, separator);
}
@Override
- public StringBuilder getFullFamilyName(StringBuilder sb) {
- sb = getName(sb, Font.NAME_FAMILY).append("-");
- getName(sb, Font.NAME_SUBFAMILY);
- return sb;
+ public String getFullFamilyName() {
+ return getName(Font.NAME_FAMILY) + "-" + getName(Font.NAME_SUBFAMILY);
}
@Override
@@ -190,34 +185,6 @@ class TypecastFont implements Font {
}
@Override
- public final float getKerning(final int left_glyphid, final int right_glyphid) {
- return metrics.getScale( getKerningFU(left_glyphid, right_glyphid) );
- }
-
- @Override
- public int getKerningFU(final int left_glyphid, final int right_glyphid) {
- if( 0 == left_glyphid || 0 == right_glyphid ) {
- return 0;
- }
- final KernTable kern = font.getKernTable();
- if (kern != null) {
- final int kernSubtableCount = kern.getSubtableCount();
- if( 0 < kernSubtableCount ) {
- final KernSubtableFormat0 kst0 = kern.getSubtable0();
- if( null != kst0 && kst0.areKerningValues() && kst0.isHorizontal() && !kst0.isCrossstream() ) {
- for (int i = 0; i < kst0.getKerningPairCount(); i++) {
- final KerningPair kpair = kst0.getKerningPair(i);
- if( kpair.getLeft() == left_glyphid && kpair.getRight() == right_glyphid ) {
- return kpair.getValue();
- }
- }
- }
- }
- }
- return 0;
- }
-
- @Override
public int getGlyphID(final char symbol) {
// enforce mapping as some fonts have an erroneous cmap (FreeSerif-Regular)
switch(symbol) {
@@ -241,7 +208,7 @@ class TypecastFont implements Font {
if (null == result) {
final int glyph_id = getGlyphID( symbol );
- jogamp.graph.font.typecast.ot.OTGlyph glyph = font.getGlyph(glyph_id);
+ jogamp.graph.font.typecast.ot.Glyph glyph = font.getGlyph(glyph_id);
final int glyph_advance;
final AABBox glyph_bbox;
if(null == glyph) {
@@ -264,7 +231,14 @@ class TypecastFont implements Font {
throw new RuntimeException("Could not retrieve glyph for symbol: <"+symbol+"> "+(int)symbol+" -> glyph id "+glyph_id);
}
final OutlineShape shape = TypecastRenderer.buildShape(symbol, glyph, vertexFactory);
- result = new TypecastGlyph(this, symbol, glyph_id, glyph_bbox, glyph_advance, shape);
+ KernSubtable kernSub = null;
+ {
+ final KernTable kern = font.getKernTable();
+ if (kern != null ) {
+ kernSub = kern.getSubtable0();
+ }
+ }
+ result = new TypecastGlyph(this, symbol, glyph_id, glyph_bbox, glyph_advance, kernSub, shape);
if(DEBUG) {
final PostTable post = font.getPostTable();
final String glyph_name = null != post ? post.getGlyphName(glyph_id) : "n/a";
@@ -557,9 +531,10 @@ class TypecastFont implements Font {
@Override
public String toString() {
- return getFullFamilyName(null).toString();
+ return getFullFamilyName();
}
+ @SuppressWarnings("unused")
@Override
public String fullString() {
final StringBuilder sb = new StringBuilder();
@@ -569,7 +544,7 @@ class TypecastFont implements Font {
if( null != font.getVheaTable() ) {
sb.append("\n\n").append(font.getVheaTable());
}
- if( null != font.getKernTable() ) {
+ if( false && null != font.getKernTable() ) { // too long
final PostTable post = font.getPostTable();
final KernTable kern = font.getKernTable();
sb.append("\n\n").append(kern);
diff --git a/src/jogl/classes/jogamp/graph/font/typecast/TypecastFontConstructor.java b/src/jogl/classes/jogamp/graph/font/typecast/TypecastFontConstructor.java
index ef7f38e64..72dd95da2 100644
--- a/src/jogl/classes/jogamp/graph/font/typecast/TypecastFontConstructor.java
+++ b/src/jogl/classes/jogamp/graph/font/typecast/TypecastFontConstructor.java
@@ -40,11 +40,11 @@ public class TypecastFontConstructor implements FontConstructor {
@Override
public Font create(final File ffile) throws IOException {
- return new TypecastFont( OTFontCollection.create(ffile) );
+ return new TypecastFont( new OTFontCollection(ffile) );
}
@Override
public Font create(final InputStream istream, final int streamLen) throws IOException {
- return new TypecastFont( OTFontCollection.create(istream, streamLen) );
+ return new TypecastFont( new OTFontCollection(istream, streamLen) );
}
}
diff --git a/src/jogl/classes/jogamp/graph/font/typecast/TypecastGlyph.java b/src/jogl/classes/jogamp/graph/font/typecast/TypecastGlyph.java
index b36196ee5..b5876758f 100644
--- a/src/jogl/classes/jogamp/graph/font/typecast/TypecastGlyph.java
+++ b/src/jogl/classes/jogamp/graph/font/typecast/TypecastGlyph.java
@@ -32,6 +32,8 @@ import com.jogamp.graph.curve.OutlineShape;
import com.jogamp.graph.font.Font;
import com.jogamp.opengl.math.geom.AABBox;
+import jogamp.graph.font.typecast.ot.table.KernSubtable;
+import jogamp.graph.font.typecast.ot.table.KerningPair;
import jogamp.graph.font.typecast.ot.table.PostTable;
public final class TypecastGlyph implements Font.Glyph {
@@ -170,9 +172,36 @@ public final class TypecastGlyph implements Font.Glyph {
public static final short INVALID_ID = (short)((1 << 16) - 1);
public static final short MAX_ID = (short)((1 << 16) - 2);
+ private static int[][] growPairArray(final int[][] src) {
+ final int length = src.length;
+ final int new_length = length * 2;
+ final int[/*right_glyphid*/][/*value*/] dst = new int[new_length][2];
+ for (int i = 0; i < length; i++) {
+ dst[i][0] = src[i][0];
+ dst[i][1] = src[i][1];
+ }
+ return dst;
+ }
+
+ private static int[][] trimPairArray(final int[][] src, final int new_length) {
+ final int length = src.length;
+ if( new_length >= length ) {
+ return src;
+ }
+ final int[/*right_glyphid*/][/*value*/] dst = new int[new_length][2];
+ for (int i = 0; i < new_length; i++) {
+ dst[i][0] = src[i][0];
+ dst[i][1] = src[i][1];
+ }
+ return dst;
+ }
+
private final char symbol;
- private final OutlineShape shape; // in EM units
private final int id;
+ private final int[/*right_glyphid*/][/*value*/] kerning;
+ private final boolean kerning_horizontal;
+ private final boolean kerning_crossstream;
+ private final OutlineShape shape; // in EM units
private final Metrics metrics;
/**
@@ -184,10 +213,37 @@ public final class TypecastGlyph implements Font.Glyph {
* @param advance from hmtx in font-units
* @param shape
*/
- protected TypecastGlyph(final TypecastFont font, final char symbol, final int id, final AABBox bbox, final int advance, final OutlineShape shape) {
+ protected TypecastGlyph(final TypecastFont font, final char symbol, final int id, final AABBox bbox, final int advance,
+ final KernSubtable kernSub, final OutlineShape shape) {
this.symbol = symbol;
- this.shape = shape;
this.id = id;
+ if( null != kernSub && kernSub.areKerningValues() ) {
+ int pair_sz = 64;
+ int pair_idx = 0;
+ int[/*right_glyphid*/][/*value*/] pairs = new int[pair_sz][2];
+ for (int i = 0; i < kernSub.getKerningPairCount(); i++) {
+ final KerningPair kpair = kernSub.getKerningPair(i);
+ if( kpair.getLeft() == id ) {
+ if( pair_idx == pair_sz ) {
+ pairs = growPairArray(pairs);
+ pair_sz = pairs.length;
+ }
+ pairs[pair_idx][0] = kpair.getRight();
+ pairs[pair_idx][1] = kpair.getValue();
+ ++pair_idx;
+ } else if( kpair.getLeft() > id ) {
+ break; // early out
+ }
+ }
+ this.kerning = trimPairArray(pairs, pair_idx);
+ this.kerning_horizontal = kernSub.isHorizontal();
+ this.kerning_crossstream = kernSub.isCrossstream();
+ } else {
+ this.kerning = new int[0][0];
+ this.kerning_horizontal = true;
+ this.kerning_crossstream = true;
+ }
+ this.shape = shape;
this.metrics = new Metrics(font, bbox, advance);
}
@@ -248,6 +304,39 @@ public final class TypecastGlyph implements Font.Glyph {
}
@Override
+ public final boolean isKerningHorizontal() { return kerning_horizontal; }
+
+ @Override
+ public final boolean isKerningCrossstream() { return kerning_crossstream; }
+
+ @Override
+ public final int getKerningPairCount() { return kerning.length; }
+
+ @Override
+ public final int getKerningFU(final int right_glyphid) {
+ // binary search in ordered kerning table
+ int l = 0;
+ int h = kerning.length-1;
+ while( l <= h ) {
+ final int i = ( l + h ) / 2;
+ final int k_right = kerning[i][0];
+ if ( k_right < right_glyphid ) {
+ l = i + 1;
+ } else if ( k_right > right_glyphid ) {
+ h = i - 1;
+ } else {
+ return kerning[i][1];
+ }
+ }
+ return 0;
+ }
+
+ @Override
+ public final float getKerning(final int right_glyphid) {
+ return getScale( getKerningFU(right_glyphid) );
+ }
+
+ @Override
public final OutlineShape getShape() {
return this.shape;
}
@@ -263,10 +352,38 @@ public final class TypecastGlyph implements Font.Glyph {
public String toString() {
final PostTable post = metrics.getFont().getPostTable();
final String glyph_name = null != post ? post.getGlyphName(id) : "n/a";
- return new StringBuilder()
- .append("Glyph id ").append(id).append(" '").append(glyph_name).append("'")
- .append(", advance ").append(getAdvanceFU())
- .append(", ").append(getBBoxFU())
- .toString();
+ final StringBuilder sb = new StringBuilder();
+ sb.append("Glyph id ").append(id).append(" '").append(glyph_name).append("'")
+ .append(", advance ").append(getAdvanceFU())
+ .append(", kerning[size ").append(kerning.length).append(", horiz ").append(this.isKerningHorizontal()).append(", cross ").append(this.isKerningCrossstream()).append("]");
+ return sb.toString();
+ }
+
+ @Override
+ public String fullString() {
+ final PostTable post = metrics.getFont().getPostTable();
+ final String glyph_name = null != post ? post.getGlyphName(id) : "n/a";
+ final StringBuilder sb = new StringBuilder();
+ sb.append("Glyph id ").append(id).append(" '").append(glyph_name).append("'")
+ .append(", advance ").append(getAdvanceFU())
+ .append(", ").append(getBBoxFU());
+
+ sb.append("\n Kerning: size ").append(kerning.length).append(", horiz ").append(this.isKerningHorizontal()).append(", cross ").append(this.isKerningCrossstream());
+ final int left = getID();
+ for (int i = 0; i < kerning.length; i++) {
+ final int right = kerning[i][0];
+ final int value = kerning[i][1];
+ final String leftS;
+ final String rightS;
+ if( null == post ) {
+ leftS = String.valueOf(left);
+ rightS = String.valueOf(left);
+ } else {
+ leftS = post.getGlyphName(left)+"/"+String.valueOf(left);
+ rightS = post.getGlyphName(right)+"/"+String.valueOf(right);
+ }
+ sb.append("\n kp[").append(i).append("]: ").append(leftS).append(" -> ").append(rightS).append(" = ").append(value);
+ }
+ return sb.toString();
}
}
diff --git a/src/jogl/classes/jogamp/graph/font/typecast/TypecastRenderer.java b/src/jogl/classes/jogamp/graph/font/typecast/TypecastRenderer.java
index 09a63d845..472e3e58e 100644
--- a/src/jogl/classes/jogamp/graph/font/typecast/TypecastRenderer.java
+++ b/src/jogl/classes/jogamp/graph/font/typecast/TypecastRenderer.java
@@ -27,7 +27,6 @@
*/
package jogamp.graph.font.typecast;
-import jogamp.graph.font.typecast.ot.OTGlyph;
import jogamp.graph.font.typecast.ot.Point;
import jogamp.opengl.Debug;
@@ -76,7 +75,7 @@ public class TypecastRenderer {
shape.addVertex(0, p3.x, p3.y, p3.onCurve);
} */
- public static OutlineShape buildShape(final char symbol, final OTGlyph glyph, final Factory<? extends Vertex> vertexFactory) {
+ public static OutlineShape buildShape(final char symbol, final jogamp.graph.font.typecast.ot.Glyph glyph, final Factory<? extends Vertex> vertexFactory) {
//
// See Typecast: GlyphPathFactory.addContourToPath(..)
//
@@ -111,7 +110,7 @@ public class TypecastRenderer {
}
} */
- private static void buildShapeImpl(final OutlineShape shape, final char symbol, final OTGlyph glyph) {
+ private static void buildShapeImpl(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;
diff --git a/src/test/com/jogamp/opengl/test/junit/graph/TestFontsNEWT00.java b/src/test/com/jogamp/opengl/test/junit/graph/TestFontsNEWT00.java
index 9592a06cf..8a2284b67 100644
--- a/src/test/com/jogamp/opengl/test/junit/graph/TestFontsNEWT00.java
+++ b/src/test/com/jogamp/opengl/test/junit/graph/TestFontsNEWT00.java
@@ -36,7 +36,6 @@ import org.junit.runners.MethodSorters;
import com.jogamp.graph.font.Font;
import com.jogamp.graph.font.FontScale;
-import com.jogamp.graph.font.Font.Glyph;
import com.jogamp.opengl.math.FloatUtil;
import com.jogamp.opengl.math.geom.AABBox;
import com.jogamp.opengl.test.junit.util.UITestCase;
@@ -67,14 +66,21 @@ public class TestFontsNEWT00 extends UITestCase {
final float dpi = 96;
for(int i=0; i<fonts.length; i++) {
final Font font = fonts[i];
+ System.err.println("+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++");
+ System.err.println(font.getAllNames(null, "\n"));
+ System.err.println("+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++");
final float pixelSize = FontScale.toPixels(fontSize, dpi);
- System.err.println(font.getFullFamilyName(null).toString()+": "+fontSize+"p, "+dpi+"dpi -> "+pixelSize+"px:");
- testFontGlyphAdvancedSize(font, 'X', pixelSize);
- testFontGlyphAdvancedSize(font, 'j', pixelSize);
- testFontGlyphAdvancedSize(font, ' ', pixelSize);
+ System.err.println(font.getFullFamilyName()+": "+fontSize+"p, "+dpi+"dpi -> "+pixelSize+"px:");
+ System.err.println(font.fullString());
+ testFontGlyph01(font, 'X', pixelSize);
+ testFontGlyph01(font, 'j', pixelSize);
+ testFontGlyph01(font, ' ', pixelSize);
+ testFontGlyph02(font, 'X', 'X');
+ testFontGlyph02(font, 't', '.');
+ testFontGlyph02(font, 'f', 'f');
}
}
- void testFontGlyphAdvancedSize(final Font font, final char c, final float pixelSize) {
+ void testFontGlyph01(final Font font, final char c, final float pixelSize) {
final int glyphID = font.getGlyphID(c);
final int s0 = font.getAdvanceWidthFU(glyphID);
final Font.Glyph glyph = font.getGlyph(c);
@@ -108,4 +114,18 @@ public class TestFontsNEWT00 extends UITestCase {
Assert.assertEquals(s1_em*pixelSize, s1_px, FloatUtil.EPSILON);
Assert.assertEquals(s0_px, s1_px, FloatUtil.EPSILON);
}
+ void testFontGlyph02(final Font font, final char left, final char right) {
+ final int glyphid_left = font.getGlyphID(left);
+ final int glyphid_right = font.getGlyphID(right);
+ final Font.Glyph glyph_left = font.getGlyph(left);
+ final Font.Glyph glyph_right = font.getGlyph(right);
+
+ final int k_val = glyph_left.getKerningFU(glyphid_right);
+
+ System.err.println(" Font "+font.getFullFamilyName());
+ System.err.println(" Char left['"+left+"', id "+glyphid_left+", kpairs "+glyph_left.getKerningPairCount()+
+ "], right['"+right+"', id "+glyphid_right+"], kerning "+k_val);
+ System.err.println(" "+glyph_left);
+ // System.err.println(" "+glyph_left.fullString());
+ }
}
diff --git a/src/test/com/jogamp/opengl/test/junit/graph/TestTextRendererNEWT00.java b/src/test/com/jogamp/opengl/test/junit/graph/TestTextRendererNEWT00.java
index 9cb29365c..c5fe0b903 100644
--- a/src/test/com/jogamp/opengl/test/junit/graph/TestTextRendererNEWT00.java
+++ b/src/test/com/jogamp/opengl/test/junit/graph/TestTextRendererNEWT00.java
@@ -366,10 +366,9 @@ public class TestTextRendererNEWT00 extends UITestCase {
}
String getFontInfo() {
- final float unitsPerEM_Inv = font.getMetrics().getScale(1f);
- final float unitsPerEM = 1f / unitsPerEM_Inv;
+ final float unitsPerEM = font.getMetrics().getUnitsPerEM();
return String.format("Font %s%n %s%nunitsPerEM %f (upem)",
- font.getFullFamilyName(null).toString(),
+ font.getFullFamilyName(),
font.getName(Font.NAME_UNIQUNAME),
unitsPerEM);
}
diff --git a/src/test/com/jogamp/opengl/test/junit/graph/TestTextRendererNEWT01.java b/src/test/com/jogamp/opengl/test/junit/graph/TestTextRendererNEWT01.java
index 305e12f27..6211409f7 100644
--- a/src/test/com/jogamp/opengl/test/junit/graph/TestTextRendererNEWT01.java
+++ b/src/test/com/jogamp/opengl/test/junit/graph/TestTextRendererNEWT01.java
@@ -36,6 +36,7 @@ import com.jogamp.opengl.GLCapabilities;
import com.jogamp.opengl.GLCapabilitiesImmutable;
import com.jogamp.opengl.GLException;
import com.jogamp.opengl.GLProfile;
+import com.jogamp.opengl.math.geom.AABBox;
import jogamp.common.os.PlatformPropsImpl;
@@ -48,6 +49,7 @@ import com.jogamp.common.os.Platform;
import com.jogamp.graph.curve.Region;
import com.jogamp.graph.curve.opengl.RenderState;
import com.jogamp.graph.font.FontFactory;
+import com.jogamp.graph.font.FontSet;
import com.jogamp.graph.geom.SVertex;
import com.jogamp.newt.opengl.GLWindow;
import com.jogamp.opengl.test.junit.graph.demos.GPUTextRendererListenerBase01;
@@ -104,7 +106,7 @@ public class TestTextRendererNEWT01 extends UITestCase {
}
@Test
- public void testTextRendererR2T01() throws InterruptedException {
+ public void testTextRendererR2T01() throws InterruptedException, GLException, IOException {
if(Platform.CPUFamily.X86 != PlatformPropsImpl.CPU_ARCH.family) { // FIXME
// FIXME: Disabled for now - since it doesn't seem fit for mobile (performance wise).
System.err.println("disabled on non desktop (x86) arch for now ..");
@@ -124,42 +126,68 @@ public class TestTextRendererNEWT01 extends UITestCase {
final TextGLListener textGLListener = new TextGLListener(rs, Region.VBAA_RENDERING_BIT, 4 /* sampleCount */, DEBUG, TRACE);
textGLListener.attachInputListenerTo(window);
window.addGLEventListener(textGLListener);
+ textGLListener.setHeadBox(2, true);
+ window.display();
+ // final AABBox headbox = textGLListener.getHeadBox();
+ // GPUTextRendererListenerBase01.upsizeWindowSurface(window, false, (int)(headbox.getWidth()*1.5f), (int)(headbox.getHeight()*2f));
+
+ final Runnable action_per_font = new Runnable() {
+ @Override
+ public void run() {
+ textGLListener.setHeadBox(1, false);
+ textGLListener.setSampleCount(2);
+ window.display();
+ textGLListener.printScreenOnGLThread(window, "./", window.getTitle(), "", false);
+ sleep();
+
+ textGLListener.setHeadBox(2, false);
+ textGLListener.setSampleCount(2);
+ window.display();
+ textGLListener.printScreenOnGLThread(window, "./", window.getTitle(), "", false);
+ sleep();
+
+ textGLListener.setHeadBox(1, false);
+ textGLListener.setSampleCount(3);
+ window.display();
+ textGLListener.printScreenOnGLThread(window, "./", window.getTitle(), "", false);
+ sleep();
+
+ textGLListener.setHeadBox(2, false);
+ textGLListener.setSampleCount(3);
+ window.display();
+ textGLListener.printScreenOnGLThread(window, "./", window.getTitle(), "", false);
+ sleep();
+
+ textGLListener.setHeadBox(1, false);
+ textGLListener.setSampleCount(4);
+ window.display();
+ textGLListener.printScreenOnGLThread(window, "./", window.getTitle(), "", false);
+ sleep();
+
+ textGLListener.setHeadBox(2, false);
+ textGLListener.setSampleCount(4);
+ window.display();
+ textGLListener.printScreenOnGLThread(window, "./", window.getTitle(), "", false);
+ sleep();
+ } };
+
+ if(textGLListener.setFontSet(FontFactory.UBUNTU, FontSet.FAMILY_LIGHT, FontSet.STYLE_NONE)) {
+ action_per_font.run();
+ }
- if(textGLListener.setFontSet(FontFactory.UBUNTU, 0, 0)) {
- textGLListener.setTech(-400, -30, 0f, -1000, 2);
- window.display();
- window.display();
- sleep();
-
- textGLListener.setTech(-400, -30, 0f, -380, 3);
- window.display();
- sleep();
-
- textGLListener.setTech(-400, -20, 0f, -80, 4);
- window.display();
- sleep();
+ if(textGLListener.setFontSet(FontFactory.UBUNTU, FontSet.FAMILY_REGULAR, FontSet.STYLE_NONE)) {
+ action_per_font.run();
}
if(textGLListener.setFontSet(FontFactory.JAVA, 0, 0)) {
- textGLListener.setTech(-400, -30, 0f, -1000, 2);
- window.display();
- window.display();
- sleep();
-
- textGLListener.setTech(-400, -30, 0f, -380, 3);
- window.display();
- sleep();
-
- textGLListener.setTech(-400, -20, 0f, -80, 4);
- window.display();
- sleep();
+ action_per_font.run();
}
destroyWindow(window);
}
@Test
- public void testTextRendererMSAA01() throws InterruptedException {
+ public void testTextRendererMSAA01() throws InterruptedException, GLException, IOException {
final GLProfile glp = GLProfile.get(GLProfile.GL2ES2);
final GLCapabilities caps = new GLCapabilities(glp);
caps.setAlphaBits(4);
@@ -175,43 +203,41 @@ public class TestTextRendererNEWT01 extends UITestCase {
final TextGLListener textGLListener = new TextGLListener(rs, 0, 0 /* sampleCount */, DEBUG, TRACE);
textGLListener.attachInputListenerTo(window);
window.addGLEventListener(textGLListener);
+ textGLListener.setHeadBox(2, true);
+ window.display();
- if(textGLListener.setFontSet(FontFactory.UBUNTU, 0, 0)) {
- textGLListener.setTech(-400, -30, 0f, -1000, 0);
- window.display();
- window.display();
- sleep();
-
- textGLListener.setTech(-400, -30, 0, -380, 0);
- window.display();
- sleep();
+ final Runnable action_per_font = new Runnable() {
+ @Override
+ public void run() {
+ textGLListener.setHeadBox(1, false);
+ textGLListener.setSampleCount(0);
+ window.display();
+ textGLListener.printScreenOnGLThread(window, "./", window.getTitle(), "", false);
+ sleep();
+
+ textGLListener.setHeadBox(2, false);
+ textGLListener.setSampleCount(0);
+ window.display();
+ textGLListener.printScreenOnGLThread(window, "./", window.getTitle(), "", false);
+ sleep();
+ } };
+
+ if(textGLListener.setFontSet(FontFactory.UBUNTU, FontSet.FAMILY_LIGHT, FontSet.STYLE_NONE)) {
+ action_per_font.run();
+ }
- textGLListener.setTech(-400, -20, 0, -80, 0);
- window.display();
- sleep();
+ if(textGLListener.setFontSet(FontFactory.UBUNTU, FontSet.FAMILY_REGULAR, FontSet.STYLE_NONE)) {
+ action_per_font.run();
}
if(textGLListener.setFontSet(FontFactory.JAVA, 0, 0)) {
- textGLListener.setTech(-400, -30, 0f, -1000, 0);
- window.display();
- window.display();
- sleep();
-
- textGLListener.setTech(-400, -30, 0, -380, 0);
- window.display();
- sleep();
-
- textGLListener.setTech(-400, -20, 0, -80, 0);
- window.display();
- sleep();
+ action_per_font.run();
}
destroyWindow(window);
}
private static class TextGLListener extends GPUTextRendererListenerBase01 {
- String winTitle;
-
public TextGLListener(final RenderState rs, final int type, final int sampleCount, final boolean debug, final boolean trace) {
super(rs, type, sampleCount, true, debug, trace);
}
@@ -219,10 +245,10 @@ public class TestTextRendererNEWT01 extends UITestCase {
@Override
public void attachInputListenerTo(final GLWindow window) {
super.attachInputListenerTo(window);
- winTitle = window.getTitle();
}
- public void setTech(final float xt, final float yt, final float angle, final int zoom, final int sampleCount){
- setMatrix(xt, yt, zoom, angle, sampleCount);
+ public void setSampleCount(final int sampleCount){
+ // setMatrix(xt, yt, zoom, angle, sampleCount);
+ setMatrix(0, 0, 0, 0f, sampleCount);
}
@Override
@@ -240,14 +266,6 @@ public class TestTextRendererNEWT01 extends UITestCase {
@Override
public void display(final GLAutoDrawable drawable) {
super.display(drawable);
-
- try {
- printScreen(drawable, "./", winTitle, false);
- } catch (final GLException e) {
- e.printStackTrace();
- } catch (final IOException e) {
- e.printStackTrace();
- }
}
}
}
diff --git a/src/test/com/jogamp/opengl/test/junit/graph/TestTextRendererNEWTBugXXXX.java b/src/test/com/jogamp/opengl/test/junit/graph/TestTextRendererNEWTBugXXXX.java
index 7d285fe43..2c7967dd1 100644
--- a/src/test/com/jogamp/opengl/test/junit/graph/TestTextRendererNEWTBugXXXX.java
+++ b/src/test/com/jogamp/opengl/test/junit/graph/TestTextRendererNEWTBugXXXX.java
@@ -159,7 +159,7 @@ public class TestTextRendererNEWTBugXXXX extends UITestCase {
gl.glClear(GL.GL_COLOR_BUFFER_BIT | GL.GL_DEPTH_BUFFER_BIT);
for(int i=0; i<fonts.length; i++) {
final Font font = fonts[i];
- renderString(drawable, gl, renderer, font, textRenderUtil, font.getFullFamilyName(null).toString()+": "+issues, 0, 0==i?0:-1, -1000, sampleCountIO);
+ renderString(drawable, gl, renderer, font, textRenderUtil, font.getFullFamilyName()+": "+issues, 0, 0==i?0:-1, -1000, sampleCountIO);
if(!onlyIssues) {
renderString(drawable, gl, renderer, font, textRenderUtil, "012345678901234567890123456789", 0, -1, -1000, sampleCountIO);
renderString(drawable, gl, renderer, font, textRenderUtil, "abcdefghijklmnopqrstuvwxyz", 0, -1, -1000, sampleCountIO);
diff --git a/src/test/com/jogamp/opengl/test/junit/graph/demos/GPURendererListenerBase01.java b/src/test/com/jogamp/opengl/test/junit/graph/demos/GPURendererListenerBase01.java
index 311abbcc3..b6b311ac9 100644
--- a/src/test/com/jogamp/opengl/test/junit/graph/demos/GPURendererListenerBase01.java
+++ b/src/test/com/jogamp/opengl/test/junit/graph/demos/GPURendererListenerBase01.java
@@ -126,8 +126,9 @@ public abstract class GPURendererListenerBase01 implements GLEventListener {
final Object upObj = drawable.getUpstreamWidget();
if( upObj instanceof Window ) {
final Window window = (Window) upObj;
- final float[] sDPI = FontScale.perMMToPerInch( window.getPixelsPerMM(new float[2]) );
- System.err.println("DPI "+sDPI[0]+" x "+sDPI[1]);
+ final float[] sPpMM = window.getPixelsPerMM(new float[2]);
+ final float[] sDPI = FontScale.perMMToPerInch( new float[] { sPpMM[0], sPpMM[1] } );
+ System.err.println("DPI "+sDPI[0]+" x "+sDPI[1]+", "+sPpMM[0]+" x "+sPpMM[1]+" pixel/mm");
final float[] hasSurfacePixelScale1 = window.getCurrentSurfaceScale(new float[2]);
System.err.println("HiDPI PixelScale: "+hasSurfacePixelScale1[0]+"x"+hasSurfacePixelScale1[1]+" (has)");
@@ -245,15 +246,29 @@ public abstract class GPURendererListenerBase01 implements GLEventListener {
public void printScreen(final GLAutoDrawable drawable, final String dir, final String tech, final String objName, final boolean exportAlpha) throws GLException, IOException {
final StringWriter sw = new StringWriter();
final PrintWriter pw = new PrintWriter(sw);
- pw.printf("-%03dx%03d-Z%04d-S%02d-%s", drawable.getSurfaceWidth(), drawable.getSurfaceHeight(), (int)Math.abs(zTran), sampleCount[0], objName);
-
+ pw.printf("-%s-S%02d-Z%04d-snap%02d-%03dx%03d", objName, sampleCount[0], (int)Math.abs(zTran), screenshot_num++, drawable.getSurfaceWidth(), drawable.getSurfaceHeight());
final String filename = dir + tech + sw +".png";
if(screenshot.readPixels(drawable.getGL(), false)) {
screenshot.write(new File(filename));
}
}
-
- int screenshot_num = 0;
+ private int screenshot_num = 0;
+
+ public void printScreenOnGLThread(final GLAutoDrawable drawable, final String dir, final String tech, final String objName, final boolean exportAlpha) {
+ drawable.invoke(false, new GLRunnable() {
+ @Override
+ public boolean run(final GLAutoDrawable drawable) {
+ try {
+ printScreen(drawable, dir, tech, objName, exportAlpha);
+ } catch (final GLException e) {
+ e.printStackTrace();
+ } catch (final IOException e) {
+ e.printStackTrace();
+ }
+ return true;
+ }
+ });
+ }
public void setIgnoreInput(final boolean v) {
ignoreInput = v;
@@ -337,25 +352,11 @@ public abstract class GPURendererListenerBase01 implements GLEventListener {
}
}
else if(arg0.getKeyCode() == KeyEvent.VK_S){
- rotate(-1);
- if(null != autoDrawable) {
- autoDrawable.invoke(false, new GLRunnable() {
- @Override
- public boolean run(final GLAutoDrawable drawable) {
- try {
- final String modeS = Region.getRenderModeString(renderModes);
- final String type = modeS + ( Region.hasVariableWeight(renderModes) ? "-vc" : "-uc" ) ;
- printScreen(drawable, "./", "demo-"+type, "snap"+screenshot_num, false);
- screenshot_num++;
- } catch (final GLException e) {
- e.printStackTrace();
- } catch (final IOException e) {
- e.printStackTrace();
- }
- return true;
- }
- });
- }
+ if(null != autoDrawable) {
+ final String modeS = Region.getRenderModeString(renderModes);
+ final String type = modeS + ( Region.hasVariableWeight(renderModes) ? "-vc" : "-uc" ) ;
+ printScreenOnGLThread(autoDrawable, "./", "demo-"+type, "", false);
+ }
}
}
@Override
diff --git a/src/test/com/jogamp/opengl/test/junit/graph/demos/GPUTextNewtDemo.java b/src/test/com/jogamp/opengl/test/junit/graph/demos/GPUTextNewtDemo.java
index c3b1d1473..401450fdb 100644
--- a/src/test/com/jogamp/opengl/test/junit/graph/demos/GPUTextNewtDemo.java
+++ b/src/test/com/jogamp/opengl/test/junit/graph/demos/GPUTextNewtDemo.java
@@ -139,11 +139,11 @@ public class GPUTextNewtDemo {
final float[] sDPI = FontScale.perMMToPerInch( window.getPixelsPerMM(new float[2]) );
final float font_ptpi = 12f;
final float font_ppi = FontScale.toPixels(font_ptpi, sDPI[1]);
- final AABBox fontNameBox = font.getMetricBounds(GPUTextRendererListenerBase01.textX2, font_ppi);
+ final AABBox fontNameBox = font.getMetricBounds(GPUTextRendererListenerBase01.textX1, font_ppi);
System.err.println("GPU Text Newt Demo: "+font.fullString());
System.err.println("GPU Text Newt Demo: screen-dpi: "+sDPI[0]+"x"+sDPI[1]+", font "+font_ptpi+" pt, "+font_ppi+" pixel");
System.err.println("GPU Text Newt Demo: textX2: "+fontNameBox+" pixel");
- window.setSurfaceSize((int)(fontNameBox.getWidth()*1.1f), (int)(fontNameBox.getHeight()*2f));
+ // window.setSurfaceSize((int)(fontNameBox.getWidth()*1.1f), (int)(fontNameBox.getHeight()*2f));
}
// FPSAnimator animator = new FPSAnimator(60);
diff --git a/src/test/com/jogamp/opengl/test/junit/graph/demos/GPUTextRendererListenerBase01.java b/src/test/com/jogamp/opengl/test/junit/graph/demos/GPUTextRendererListenerBase01.java
index e0097bd74..5ae940da7 100644
--- a/src/test/com/jogamp/opengl/test/junit/graph/demos/GPUTextRendererListenerBase01.java
+++ b/src/test/com/jogamp/opengl/test/junit/graph/demos/GPUTextRendererListenerBase01.java
@@ -34,8 +34,9 @@ import com.jogamp.opengl.GL2ES2;
import com.jogamp.opengl.GLAnimatorControl;
import com.jogamp.opengl.GLAutoDrawable;
import com.jogamp.opengl.GLException;
+import com.jogamp.opengl.GLRunnable;
import com.jogamp.opengl.fixedfunc.GLMatrixFunc;
-
+import com.jogamp.common.util.InterruptSource;
import com.jogamp.graph.curve.Region;
import com.jogamp.graph.curve.opengl.GLRegion;
import com.jogamp.graph.curve.opengl.RegionRenderer;
@@ -75,23 +76,23 @@ public abstract class GPUTextRendererListenerBase01 extends GPURendererListenerB
int fontSet = FontFactory.UBUNTU;
Font font;
- int headType = 0;
+ int headType = 1;
boolean drawFPS = true;
final float fontSizeFName = 10f;
final float fontSizeFPS = 10f;
final int[] sampleCountFPS = new int[] { 8 };
float fontSizeHead = 12f;
- float fontSizeBottom = 16f;
- float dpiH = 96;
+ float fontSizeCenter = 16f;
+ float dpiV = 96;
+ float ppmmV = 1;
final int fontSizeModulo = 100;
String fontName;
AABBox fontNameBox;
String headtext;
AABBox headbox;
- static final String text1 = "abcdefghijklmnopqrstuvwxyz\nABCDEFGHIJKLMNOPQRSTUVWXYZ\n0123456789.:,;(*!?/\\\")$%^&-+@~#<>{}[]";
static final String text2 = "The quick brown fox jumps over the lazy dog";
- public static final String textX =
+ public static final String text_help =
"JOGAMP graph demo using Resolution Independent NURBS\n"+
"JOGAMP JOGL - OpenGL ES2 profile\n"+
"Press 1/2 to zoom in/out the below text\n"+
@@ -103,7 +104,7 @@ public abstract class GPUTextRendererListenerBase01 extends GPURendererListenerB
"Press i for live input text input (CR ends it, backspace supported)\n"+
"Press f to toggle fps. H for different text, space for font type\n";
- public static final String textX2 =
+ public static final String textX1 =
"Lorem ipsum dolor sit amet, consectetur adipiscing elit. Donec nec sapien tellus. \n"+
"Ut purus odio, rhoncus sit amet commodo eget, ullamcorper vel urna. Mauris ultricies \n"+
"quam iaculis urna cursus ornare. Nullam ut felis a ante ultrices ultricies nec a elit. \n"+
@@ -113,21 +114,21 @@ public abstract class GPUTextRendererListenerBase01 extends GPURendererListenerB
"in lorem. Maecenas in ipsum ac justo scelerisque sollicitudin. Quisque sit amet neque lorem, \n" +
"-------Press H to change text---------";
- public static final String textX3 =
- "I “Ask Jeff” or ‘Ask Jeff’. Take the chef d’œuvre! Two of [of] (of) ‘of’ “of” of? of! of*.\n"+
- "Les Woëvres, the Fôret de Wœvres, the Voire and Vauvise. Yves is in heaven; D’Amboise is in jail.\n"+
- "Lyford’s in Texas & L’Anse-aux-Griffons in Québec; the Łyna in Poland. Yriarte, Yciar and Ysaÿe are at Yale.\n"+
- "Kyoto and Ryotsu are both in Japan, Kwikpak on the Yukon delta, Kvæven in Norway, Kyulu in Kenya, not in Rwanda.…\n"+
- "Miłosz and Wū Wŭ all in the library? 1510–1620, 11:00 pm, and the 1980s are over.\n"+
- "Ut purus odio, rhoncus sit amet commodo eget, ullamcorper vel urna. Mauris ultricies \n"+
+ public static final String textX2 = // Kvæven -> Kvaven (error)
+ "I “Ask Jeff” or ‘Ask Jeff’. Take the chef d’œuvre! Two of [of] (of) ‘of’ “of” of? of! of*. X\n"+
+ "Les Woëvres, the Fôret de Wœvres, the Voire and Vauvise. Yves is in heaven; D’Amboise is in jail. X\n"+
+ "Lyford’s in Texas & L’Anse-aux-Griffons in Québec; the Łyna in Poland. Yriarte, Yciar and Ysaÿe are at Yale. X\n"+
+ "Kyoto and Ryotsu are both in Japan, Kwikpak on the Yukon delta, Kvaven in Norway, Kyulu in Kenya, not in Rwanda.… X\n"+
+ "Von-Vincke-Straße in Münster, Vdovino in Russia, Ytterbium in the periodic table. Are Toussaint L’Ouverture, Wölfflin, Wolfe, X\n"+
+ "Miłosz and Wū Wŭ all in the library? 1510–1620, 11:00 pm, and the 1980s are over. X\n"+
"-------Press H to change text---------";
- public static final String textX30 =
+ public static final String textX20 = // Kvæven -> Kvaven (error)
"I “Ask Jeff” or ‘Ask Jeff’. Take the chef d’œuvre! Two of [of] (of) ‘of’ “of” of? of! of*.\n"+
"Two of [of] (of) ‘of’ “of” of? of! of*. Ydes, Yffignac and Ygrande are in France: so are Ypres,\n"+
"Les Woëvres, the Fôret de Wœvres, the Voire and Vauvise. Yves is in heaven; D’Amboise is in jail.\n"+
"Lyford’s in Texas & L’Anse-aux-Griffons in Québec; the Łyna in Poland. Yriarte, Yciar and Ysaÿe are at Yale.\n"+
- "Kyoto and Ryotsu are both in Japan, Kwikpak on the Yukon delta, Kvæven in Norway, Kyulu in Kenya, not in Rwanda.…\n"+
+ "Kyoto and Ryotsu are both in Japan, Kwikpak on the Yukon delta, Kvaven in Norway, Kyulu in Kenya, not in Rwanda.…\n"+
"Walton’s in West Virginia, but «Wren» is in Oregon. Tlálpan is near Xochimilco in México.\n"+
"The Zygos & Xylophagou are in Cyprus, Zwettl in Austria, Fænø in Denmark, the Vøringsfossen and Værøy in Norway.\n"+
"Tchula is in Mississippi, the Tittabawassee in Michigan. Twodot is here in Montana, Ywamun in Burma.\n"+
@@ -138,7 +139,10 @@ public abstract class GPUTextRendererListenerBase01 extends GPURendererListenerB
"Ut purus odio, rhoncus sit amet commodo eget, ullamcorper vel urna. Mauris ultricies \n"+
"-------Press H to change text---------";
- StringBuilder userString = new StringBuilder(textX2);
+ static final String textXLast = "abcdefghijklmnopqrstuvwxyz\nABCDEFGHIJKLMNOPQRSTUVWXYZ\n0123456789.:,;(*!?/\\\")$%^&-+@~#<>{}[]";
+
+ Window upstream_window = null;
+ StringBuilder userString = new StringBuilder(textX1);
boolean userInput = false;
public GPUTextRendererListenerBase01(final RenderState rs, final int renderModes, final int sampleCount, final boolean blending, final boolean debug, final boolean trace) {
// NOTE_ALPHA_BLENDING: We use alpha-blending
@@ -153,7 +157,6 @@ public abstract class GPUTextRendererListenerBase01 extends GPURendererListenerB
try {
// this.font = FontFactory.get(fontSet).getDefault();
this.font = FontFactory.get(fontSet).get(FontSet.FAMILY_LIGHT, FontSet.STYLE_NONE);
- dumpFontNames();
this.fontName = font.toString();
} catch (final IOException ioe) {
@@ -163,34 +166,53 @@ public abstract class GPUTextRendererListenerBase01 extends GPURendererListenerB
setMatrix(0, 0, 0, 0f, sampleCount);
}
- void dumpFontNames() {
- System.err.println("+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++");
- System.err.println(font.getAllNames(null, "\n"));
- System.err.println("+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++");
- }
-
void switchHeadBox() {
- headType = ( headType + 1 ) % 5 ;
+ setHeadBox( ( headType + 1 ) % 5, true );
+ }
+ public int getHeadBoxType() { return headType; }
+ public AABBox getHeadBox() { return headbox; }
+ public void setHeadBox(final int choice, final boolean resize) {
+ headType = choice % 5 ;
switch(headType) {
case 0:
headtext = null;
break;
case 1:
- headtext= textX2;
+ headtext= textX1;
break;
case 2:
- headtext= textX;
+ headtext= textX2;
break;
case 3:
- headtext= textX3;
+ headtext= text_help;
break;
default:
- headtext = text1;
+ headtext = textXLast;
}
- if(null != headtext) {
- headbox = font.getMetricBounds(headtext, FontScale.toPixels(fontSizeHead, dpiH));
+ if(resize && null != headtext) {
+ headbox = font.getMetricBounds(headtext, FontScale.toPixels(fontSizeHead, dpiV));
+ if( headtext != text_help ) {
+ upsizeWindowSurface(upstream_window, true, (int)(headbox.getWidth()*1.1f), (int)(headbox.getHeight()*2f));
+ }
+ }
+ }
+
+ public static void upsizeWindowSurface(final Window window, final boolean off_thread, final int w, final int h) {
+ if( null == window ) {
+ return;
+ }
+ final int w2 = Math.max(window.getSurfaceWidth(), w);
+ final int h2 = Math.max(window.getSurfaceHeight(), h);
+ if( off_thread ) {
+ new InterruptSource.Thread() {
+ @Override
+ public void run() {
+ window.setSurfaceSize(w2, h2);
+ } }.start();
+ } else {
+ window.setSurfaceSize(w2, h2);
}
}
@@ -199,21 +221,27 @@ public abstract class GPUTextRendererListenerBase01 extends GPURendererListenerB
super.init(drawable);
final Object upObj = drawable.getUpstreamWidget();
if( upObj instanceof Window ) {
- final Window window = (Window) upObj;
- final float[] sDPI = FontScale.perMMToPerInch( window.getPixelsPerMM(new float[2]) );
- dpiH = sDPI[1];
- System.err.println("Using screen DPI of "+dpiH);
+ upstream_window = (Window) upObj;
+ final float[] sPpMM = upstream_window.getPixelsPerMM(new float[2]);
+ final float[] sDPI = FontScale.perMMToPerInch( new float[] { sPpMM[0], sPpMM[1] } );
+ dpiV = sDPI[1];
+ ppmmV = sPpMM[1];
+ System.err.println("Using vertical screen DPI of "+dpiV+", "+ppmmV+" pixel/mm");
} else {
- System.err.println("Using default DPI of "+dpiH);
+ System.err.println("Using vertical default DPI of "+dpiV+", "+ppmmV+" pixel/mm");
}
- fontNameBox = font.getMetricBounds(fontName, FontScale.toPixels(fontSizeFName, dpiH));
- switchHeadBox();
+ fontNameBox = font.getMetricBounds(fontName, FontScale.toPixels(fontSizeFName, dpiV));
+ setHeadBox(headType, true);
}
@Override
public void reshape(final GLAutoDrawable drawable, final int xstart, final int ystart, final int width, final int height) {
super.reshape(drawable, xstart, ystart, width, height);
+ final Object upObj = drawable.getUpstreamWidget();
+ if( upObj instanceof Window ) {
+ upstream_window = (Window) upObj;
+ }
final float dist = 100f;
nearPlaneX0 = nearPlane1Box.getMinX() * dist;
nearPlaneY0 = nearPlane1Box.getMinY() * dist;
@@ -229,6 +257,7 @@ public abstract class GPUTextRendererListenerBase01 extends GPURendererListenerB
@Override
public void dispose(final GLAutoDrawable drawable) {
+ upstream_window = null;
regionFPS.destroy(drawable.getGL().getGL2ES2());
regionHead.destroy(drawable.getGL().getGL2ES2());
regionBottom.destroy(drawable.getGL().getGL2ES2());
@@ -237,6 +266,10 @@ public abstract class GPUTextRendererListenerBase01 extends GPURendererListenerB
@Override
public void display(final GLAutoDrawable drawable) {
+ final Object upObj = drawable.getUpstreamWidget();
+ if( upObj instanceof Window ) {
+ upstream_window = (Window) upObj;
+ }
final int width = drawable.getSurfaceWidth();
final int height = drawable.getSurfaceHeight();
final GL2ES2 gl = drawable.getGL().getGL2ES2();
@@ -256,14 +289,16 @@ public abstract class GPUTextRendererListenerBase01 extends GPURendererListenerB
pmv.glMatrixMode(GLMatrixFunc.GL_MODELVIEW);
pmv.glLoadIdentity();
rs.setColorStatic(0.1f, 0.1f, 0.1f, 1.0f);
- final float pixelSizeFName = FontScale.toPixels(fontSizeFName, dpiH);
- final float pixelSizeHead = FontScale.toPixels(fontSizeHead, dpiH);
- final float pixelSizeBottom = FontScale.toPixels(fontSizeBottom, dpiH);
+ final float pixelSizeFName = FontScale.toPixels(fontSizeFName, dpiV);
+ final float pixelSizeHead = FontScale.toPixels(fontSizeHead, dpiV);
+ final float mmSizeHead = pixelSizeHead / ppmmV;
+ final float pixelSizeCenter = FontScale.toPixels(fontSizeCenter, dpiV);
+ final float mmSizeCenter = pixelSizeCenter / ppmmV;
renderer.enable(gl, true);
if( drawFPS ) {
- final float pixelSizeFPS = FontScale.toPixels(fontSizeFPS, dpiH);
+ final float pixelSizeFPS = FontScale.toPixels(fontSizeFPS, dpiV);
final float lfps, tfps, td;
final GLAnimatorControl animator = drawable.getAnimator();
if( null != animator ) {
@@ -276,8 +311,11 @@ public abstract class GPUTextRendererListenerBase01 extends GPURendererListenerB
td = 0f;
}
final String modeS = Region.getRenderModeString(regionFPS.getRenderModes());
- final String text = String.format("%03.1f/%03.1f fps, v-sync %d, fontSize [head %.1f, bottom %.1f], %s-samples [%d, this %d], td %4.1f, blend %b, alpha-bits %d",
- lfps, tfps, gl.getSwapInterval(), fontSizeHead, fontSizeBottom, modeS, getSampleCount()[0], sampleCountFPS[0], td,
+ final String text = String.format("%03.1f/%03.1f fps, v-sync %d, dpiV %.2f %.2f px/mm, font[head %.1fpt %.2fpx %.2fmm, center %.1fpt %.2fpx %.2fmm], %s-samples[%d, this %d], blend %b, alpha %d",
+ lfps, tfps, gl.getSwapInterval(), dpiV, ppmmV,
+ fontSizeHead, pixelSizeHead, mmSizeHead,
+ fontSizeCenter, pixelSizeCenter, mmSizeCenter,
+ modeS, getSampleCount()[0], sampleCountFPS[0],
renderer.getRenderState().isHintMaskSet(RenderState.BITHINT_BLENDING_ENABLED),
drawable.getChosenGLCapabilities().getAlphaBits());
@@ -321,7 +359,7 @@ public abstract class GPUTextRendererListenerBase01 extends GPURendererListenerB
textRegionUtil.drawString3D(gl, renderer, font, headtext, null, getSampleCount());
}
- dy += -headbox.getHeight() - font.getLineHeight(pixelSizeBottom);
+ dy += -headbox.getHeight() - font.getLineHeight(pixelSizeCenter);
pmv.glMatrixMode(GLMatrixFunc.GL_MODELVIEW);
pmv.glLoadIdentity();
@@ -330,7 +368,7 @@ public abstract class GPUTextRendererListenerBase01 extends GPURendererListenerB
pmv.glTranslatef(getXTran(), getYTran(), getZTran());
pmv.glRotatef(getAngle(), 0, 1, 0);
{
- final float sxy = ( nearPlaneS * pixelSizeBottom ) / font.getMetrics().getUnitsPerEM();
+ final float sxy = ( nearPlaneS * pixelSizeCenter ) / font.getMetrics().getUnitsPerEM();
pmv.glScalef(sxy, sxy, 1.0f);
}
rs.setColorStatic(0.9f, 0.0f, 0.0f, 1.0f);
@@ -361,14 +399,14 @@ public abstract class GPUTextRendererListenerBase01 extends GPURendererListenerB
public float getFontSizeHead() { return fontSizeHead; }
public void fontBottomIncr(final int v) {
- fontSizeBottom = Math.abs((fontSizeBottom + v) % fontSizeModulo) ;
+ fontSizeCenter = Math.abs((fontSizeCenter + v) % fontSizeModulo) ;
dumpMatrix(true);
}
public void fontHeadIncr(final int v) {
fontSizeHead = Math.abs((fontSizeHead + v) % fontSizeModulo) ;
if(null != headtext) {
- headbox = font.getMetricBounds(headtext, FontScale.toPixels(fontSizeHead, dpiH));
+ headbox = font.getMetricBounds(headtext, FontScale.toPixels(fontSizeHead, dpiV));
}
}
@@ -379,9 +417,8 @@ public abstract class GPUTextRendererListenerBase01 extends GPURendererListenerB
if(null != _font) {
fontSet = set;
font = _font;
- fontName = font.getFullFamilyName(null).toString();
- fontNameBox = font.getMetricBounds(fontName, FontScale.toPixels(fontSizeFName, dpiH));
- dumpFontNames();
+ fontName = font.getFullFamilyName();
+ fontNameBox = font.getMetricBounds(fontName, FontScale.toPixels(fontSizeFName, dpiV));
return true;
}
} catch (final IOException ex) {
@@ -396,9 +433,8 @@ public abstract class GPUTextRendererListenerBase01 extends GPURendererListenerB
if(null != _font) {
fontSet = set;
font = _font;
- fontName = font.getFullFamilyName(null).toString();
- fontNameBox = font.getMetricBounds(fontName, FontScale.toPixels(fontSizeFName, dpiH));
- dumpFontNames();
+ fontName = font.getFullFamilyName()+" (head "+fontSizeHead+"pt)";
+ fontNameBox = font.getMetricBounds(fontName, FontScale.toPixels(fontSizeFName, dpiV));
return true;
}
} catch (final IOException ex) {
@@ -410,9 +446,9 @@ public abstract class GPUTextRendererListenerBase01 extends GPURendererListenerB
public boolean isUserInputMode() { return userInput; }
void dumpMatrix(final boolean bbox) {
- System.err.println("Matrix: " + getXTran() + "/" + getYTran() + " x"+getZTran() + " @"+getAngle() +" fontSize "+fontSizeBottom);
+ System.err.println("Matrix: " + getXTran() + "/" + getYTran() + " x"+getZTran() + " @"+getAngle() +" fontSize "+fontSizeCenter);
if(bbox) {
- System.err.println("bbox: "+font.getMetricBounds(text2, nearPlaneS * FontScale.toPixels(fontSizeBottom, dpiH)));
+ System.err.println("bbox: "+font.getMetricBounds(text2, nearPlaneS * FontScale.toPixels(fontSizeCenter, dpiV)));
}
}
@@ -436,9 +472,10 @@ public abstract class GPUTextRendererListenerBase01 extends GPURendererListenerB
window.removeKeyListener(keyAction);
}
- public void printScreen(final GLAutoDrawable drawable, final String dir, final String tech, final boolean exportAlpha) throws GLException, IOException {
- final String fn = font.getFullFamilyName(null).toString();
- printScreen(drawable, dir, tech, fn.replace(' ', '_'), exportAlpha);
+ @Override
+ public void printScreen(final GLAutoDrawable drawable, final String dir, final String tech, final String objName, final boolean exportAlpha) throws GLException, IOException {
+ final String fn = font.getFullFamilyName().replace(' ', '_').replace('-', '_');
+ super.printScreen(drawable, dir, tech+"-"+fn, "text"+getHeadBoxType()+"-"+objName, exportAlpha);
}
float fontHeadScale = 1f;
diff --git a/src/test/com/jogamp/opengl/test/junit/graph/demos/ui/Label.java b/src/test/com/jogamp/opengl/test/junit/graph/demos/ui/Label.java
index 7d046e687..f7e6e3de9 100644
--- a/src/test/com/jogamp/opengl/test/junit/graph/demos/ui/Label.java
+++ b/src/test/com/jogamp/opengl/test/junit/graph/demos/ui/Label.java
@@ -102,9 +102,13 @@ public class Label extends UIShape {
@Override
protected void addShapeToRegion(final GL2ES2 gl, final RegionRenderer renderer) {
- TextRegionUtil.processString(shapeVisitor, null, font, pixelSize, text, tempT1, tempT2);
+ final AffineTransform t_sxy = new AffineTransform(); // FIXME ?
+ final float sxy = pixelSize / font.getMetrics().getUnitsPerEM();
+ t_sxy.setToScale(sxy, sxy);
+ TextRegionUtil.processString(shapeVisitor, t_sxy, font, text, tempT1, tempT2);
final float[] ctr = box.getCenter();
setRotationOrigin( ctr[0], ctr[1], ctr[2]);
+ // scale(sxy, sxy, 1f);
}
@Override
diff --git a/src/test/com/jogamp/opengl/test/junit/graph/demos/ui/Label0.java b/src/test/com/jogamp/opengl/test/junit/graph/demos/ui/Label0.java
index 7882c713d..6641ce8b4 100644
--- a/src/test/com/jogamp/opengl/test/junit/graph/demos/ui/Label0.java
+++ b/src/test/com/jogamp/opengl/test/junit/graph/demos/ui/Label0.java
@@ -90,7 +90,10 @@ public class Label0 {
box.reset();
this.region = region;
this.tLeft = tLeft;
- TextRegionUtil.processString(shapeVisitor, null, font, pixelSize, text, tempT1, tempT2);
+ final AffineTransform t_sxy = new AffineTransform(); // FIXME ?
+ final float sxy = pixelSize / font.getMetrics().getUnitsPerEM();
+ t_sxy.setToScale(sxy, sxy);
+ TextRegionUtil.processString(shapeVisitor, t_sxy, font, text, tempT1, tempT2);
this.region = null;
this.tLeft = null;
return box;
diff --git a/src/test/com/jogamp/opengl/test/junit/jogl/demos/es2/av/MovieCube.java b/src/test/com/jogamp/opengl/test/junit/jogl/demos/es2/av/MovieCube.java
index 134503520..f4b0540fa 100644
--- a/src/test/com/jogamp/opengl/test/junit/jogl/demos/es2/av/MovieCube.java
+++ b/src/test/com/jogamp/opengl/test/junit/jogl/demos/es2/av/MovieCube.java
@@ -203,8 +203,8 @@ public class MovieCube implements GLEventListener {
pixelScale = 1.0f / ( pixelSize1 * 20f );
// underlineSize: 'underline' amount of pixel below 0/0 (Note: lineGap is negative)
final Font.Metrics metrics = font.getMetrics();
- final float lineGap = metrics.getLineGap(pixelSize1);
- final float descent = metrics.getDescent(pixelSize1);
+ final float lineGap = pixelSize1 * metrics.getScale( metrics.getLineGapFU() );
+ final float descent = pixelSize1 * metrics.getScale( metrics.getDescentFU() );
underlineSize = descent - lineGap;
System.err.println("XXX: dpiH "+dpiH+", fontSize "+fontSize1+", pixelSize "+pixelSize1+", pixelScale "+pixelScale+", fLG "+lineGap+", fDesc "+descent+", underlineSize "+underlineSize);
}