From dd98cf0ae983429187256ab3236fa7dad1cd13d0 Mon Sep 17 00:00:00 2001 From: Sven Gothel Date: Sun, 19 Feb 2023 05:21:11 +0100 Subject: Graph Font: Add 'name' to Glyph; Drop erroneous Glyph ID_SPACE, ID_CR manual mapping, rely on no-shape for 'space' non-contour. Drop erroneous Glyph ID_SPACE, ID_CR to rely on no-shape for 'space' non-contour resolves different cmap-mappings of fonts, not following 'some std'. Hence getGlyph(glyph_id) no more uses the `font.getGlyph(Glyph.ID_UNKNOWN)` shape, but a null-shape as intended and using the hmtx and hhea table values for asvance and bounds. This fixes 'space' spacing in general and specifically FreeSerif-Regular and the like. This path also simplifies processing/layout of glyphs in process(..) and get*BoundsFU(..). --- .../jogamp/graph/font/typecast/TypecastFont.java | 73 +++++++++------------- .../jogamp/graph/font/typecast/TypecastGlyph.java | 17 +++-- 2 files changed, 40 insertions(+), 50 deletions(-) (limited to 'src/jogl/classes/jogamp') diff --git a/src/jogl/classes/jogamp/graph/font/typecast/TypecastFont.java b/src/jogl/classes/jogamp/graph/font/typecast/TypecastFont.java index 90cc725e0..916e71b67 100644 --- a/src/jogl/classes/jogamp/graph/font/typecast/TypecastFont.java +++ b/src/jogl/classes/jogamp/graph/font/typecast/TypecastFont.java @@ -180,13 +180,8 @@ class TypecastFont implements Font { @Override public int getGlyphID(final char symbol) { - // enforce mapping as some fonts have an erroneous cmap (FreeSerif-Regular) - switch(symbol) { - case ' ': return Glyph.ID_SPACE; - case '\n': return Glyph.ID_CR; - } final int glyphID = cmapFormat.mapCharCode(symbol); - if( 0 != glyphID ) { + if( 0 < glyphID ) { return glyphID; } return Glyph.ID_UNKNOWN; @@ -200,29 +195,23 @@ class TypecastFont implements Font { public Glyph getGlyph(final int glyph_id) { TypecastGlyph result = (TypecastGlyph) idToGlyph.get(glyph_id); if (null == result) { - jogamp.graph.font.typecast.ot.Glyph glyph = font.getGlyph(glyph_id); + final jogamp.graph.font.typecast.ot.Glyph glyph = font.getGlyph(glyph_id); + final PostTable post = font.getPostTable(); + final String glyph_name = null != post ? post.getGlyphName(glyph_id) : ""; + final int glyph_advance; final AABBox glyph_bbox; - if(null == glyph) { - // fallback - glyph = font.getGlyph(Glyph.ID_UNKNOWN); - } - switch( glyph_id ) { - case Glyph.ID_SPACE: - /** fallthrough */ - case Glyph.ID_CR: - glyph_advance = getAdvanceWidthFU(glyph_id); - glyph_bbox = new AABBox(0, 0, 0, glyph_advance, getLineHeightFU(), 0); - break; - default: - glyph_advance = glyph.getAdvanceWidth(); - glyph_bbox = glyph.getBBox(); - break; - } - if(null == glyph) { - throw new RuntimeException("Could not retrieve glyph for glyph id "+glyph_id); + final OutlineShape shape; + if( null != glyph ) { + glyph_advance = glyph.getAdvanceWidth(); + glyph_bbox = glyph.getBBox(); + shape = TypecastRenderer.buildShape(metrics.getUnitsPerEM(), glyph, vertexFactory); + } else { + final int glyph_height = metrics.getAscentFU() - metrics.getDescentFU(); + glyph_advance = getAdvanceWidthFU(glyph_id); + glyph_bbox = new AABBox(0f,0f,0f, glyph_advance, glyph_height, 0f); + shape = null; } - final OutlineShape shape = TypecastRenderer.buildShape(metrics.getUnitsPerEM(), glyph, vertexFactory); KernSubtable kernSub = null; { final KernTable kern = font.getKernTable(); @@ -230,15 +219,15 @@ class TypecastFont implements Font { kernSub = kern.getSubtable0(); } } - result = new TypecastGlyph(this, glyph_id, glyph_bbox, glyph_advance, kernSub, shape); + result = new TypecastGlyph(this, glyph_id, glyph_name, 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"; - System.err.println("New glyph: " + glyph_id + "/'"+glyph_name+"', contours " + glyph.getPointCount() + ": " + shape); - System.err.println(" "+glyph); - System.err.println(" "+result); + System.err.println("New glyph: " + glyph_id + "/'"+glyph_name+"', shape " + (null != shape)); + System.err.println(" tc_glyph "+glyph); + System.err.println(" glyph "+result); + } + if( null != glyph ) { + glyph.clearPointData(); } - glyph.clearPointData(); idToGlyph.put(glyph_id, result); } @@ -279,8 +268,6 @@ class TypecastFont implements Font { if (character == '\n') { advanceTotal = 0; y -= lineHeight; - } else if (character == ' ') { - advanceTotal += getAdvanceWidthFU(Glyph.ID_SPACE); } else { advanceTotal += getAdvanceWidthFU( getGlyphID( character ) ); } @@ -323,17 +310,15 @@ class TypecastFont implements Font { y -= lineHeight; advanceTotal = 0; left_glyph = null; - } else if (character == ' ') { - advanceTotal += getAdvanceWidthFU(Glyph.ID_SPACE); - left_glyph = null; } else { // reset transform temp1.setToIdentity(); final int glyph_id = getGlyphID(character); final Font.Glyph glyph = getGlyph(glyph_id); final OutlineShape glyphShape = glyph.getShape(); - if( null == glyphShape ) { - left_glyph = null; + if( null == glyphShape ) { // also covers 'space' and all non-contour symbols + advanceTotal += glyph.getAdvanceFU(); + left_glyph = null; // break kerning continue; } if( null != left_glyph ) { @@ -395,9 +380,6 @@ class TypecastFont implements Font { y -= lineHeight; advanceTotal = 0; left_glyph = null; - } else if (character == ' ') { - advanceTotal += getAdvanceWidth(Glyph.ID_SPACE); - left_glyph = null; } else { // reset transform if( null != transform ) { @@ -408,8 +390,9 @@ class TypecastFont implements Font { final int glyph_id = getGlyphID(character); final Font.Glyph glyph = getGlyph(glyph_id); final OutlineShape glyphShape = glyph.getShape(); - if( null == glyphShape ) { - left_glyph = null; + if( null == glyphShape ) { // also covers 'space' and all non-contour symbols + advanceTotal += glyph.getAdvance(); + left_glyph = null; // break kerning continue; } if( null != left_glyph ) { diff --git a/src/jogl/classes/jogamp/graph/font/typecast/TypecastGlyph.java b/src/jogl/classes/jogamp/graph/font/typecast/TypecastGlyph.java index 12d492f6e..15f617553 100644 --- a/src/jogl/classes/jogamp/graph/font/typecast/TypecastGlyph.java +++ b/src/jogl/classes/jogamp/graph/font/typecast/TypecastGlyph.java @@ -105,6 +105,7 @@ public final class TypecastGlyph implements Font.Glyph { } private final int id; + private final String name; private final int[/*right_glyphid*/][/*value*/] kerning; private final boolean kerning_horizontal; private final boolean kerning_crossstream; @@ -114,14 +115,16 @@ public final class TypecastGlyph implements Font.Glyph { /** * * @param font + * @param name * @param id * @param bbox in font-units * @param advance from hmtx in font-units * @param shape */ - protected TypecastGlyph(final TypecastFont font, final int id, final AABBox bbox, final int advance, + protected TypecastGlyph(final TypecastFont font, final int id, final String name, final AABBox bbox, final int advance, final KernSubtable kernSub, final OutlineShape shape) { this.id = id; + this.name = name; if( null != kernSub && kernSub.areKerningValues() ) { int pair_sz = 64; int pair_idx = 0; @@ -166,6 +169,11 @@ public final class TypecastGlyph implements Font.Glyph { return this.id; } + @Override + public final String getName() { + return this.name; + } + @Override public final float getScale(final int funits) { return this.metrics.getScale(funits); @@ -245,12 +253,11 @@ public final class TypecastGlyph implements Font.Glyph { @Override public String toString() { - 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("'") + sb.append("Glyph[id ").append(id).append(" '").append(name).append("'") .append(", advance ").append(getAdvanceFU()) - .append(", kerning[size ").append(kerning.length).append(", horiz ").append(this.isKerningHorizontal()).append(", cross ").append(this.isKerningCrossstream()).append("]"); + .append(", kerning[size ").append(kerning.length).append(", horiz ").append(this.isKerningHorizontal()).append(", cross ").append(this.isKerningCrossstream()).append("]") + .append(", shape ").append(null != shape).append("]"); return sb.toString(); } -- cgit v1.2.3