diff options
Diffstat (limited to 'src/jogamp/graph/font')
-rw-r--r-- | src/jogamp/graph/font/FontInt.java | 9 | ||||
-rw-r--r-- | src/jogamp/graph/font/typecast/TypecastFont.java | 99 | ||||
-rw-r--r-- | src/jogamp/graph/font/typecast/TypecastFontFactory.java | 11 | ||||
-rw-r--r-- | src/jogamp/graph/font/typecast/TypecastGlyph.java | 135 | ||||
-rw-r--r-- | src/jogamp/graph/font/typecast/TypecastMetrics.java | 65 | ||||
-rw-r--r-- | src/jogamp/graph/font/typecast/TypecastRenderer.java | 14 |
6 files changed, 170 insertions, 163 deletions
diff --git a/src/jogamp/graph/font/FontInt.java b/src/jogamp/graph/font/FontInt.java index 5b938bdbf..c18787723 100644 --- a/src/jogamp/graph/font/FontInt.java +++ b/src/jogamp/graph/font/FontInt.java @@ -35,11 +35,10 @@ import com.jogamp.graph.font.Font; public interface FontInt extends Font { public interface Glyph extends Font.Glyph { - public Path2D getPath(); - public Path2D getPathForPixelSize(float pixelSize); + public Path2D getPath(); // unscaled path + public Path2D getPath(float pixelSize); } - public void getOutline(String string, - AffineTransform transform, - Path2D[] result); + public void getOutline(String string, float pixelSize, + AffineTransform transform, Path2D[] result); } diff --git a/src/jogamp/graph/font/typecast/TypecastFont.java b/src/jogamp/graph/font/typecast/TypecastFont.java index 86c9601de..b95dccf21 100644 --- a/src/jogamp/graph/font/typecast/TypecastFont.java +++ b/src/jogamp/graph/font/typecast/TypecastFont.java @@ -38,6 +38,7 @@ import net.java.dev.typecast.ot.OTFont; import net.java.dev.typecast.ot.OTFontCollection; import net.java.dev.typecast.ot.table.CmapFormat; import net.java.dev.typecast.ot.table.CmapTable; +import net.java.dev.typecast.ot.table.HdmxTable; import net.java.dev.typecast.ot.table.ID; import com.jogamp.common.util.IntObjectHashMap; @@ -50,30 +51,28 @@ class TypecastFont implements FontInt { final Vertex.Factory<? extends Vertex> pointFactory; final OTFontCollection fontset; final OTFont font; - final int size; - Metrics metrics; + TypecastMetrics metrics; final CmapFormat cmapFormat; int cmapentries; // final IntIntHashMap char2Code; IntObjectHashMap char2Glyph; - public static TypecastFont create(Vertex.Factory<? extends Vertex> factory, String name, int size) { + public static TypecastFont create(Vertex.Factory<? extends Vertex> factory, String name) { String path = JavaFontLoader.getByName(name); OTFontCollection fontset; try { fontset = OTFontCollection.create(new File(path)); - return new TypecastFont(factory, fontset, size); + return new TypecastFont(factory, fontset); } catch (IOException e) { e.printStackTrace(); } return null; } - public TypecastFont(Vertex.Factory<? extends Vertex> factory, OTFontCollection fontset, int size) { + public TypecastFont(Vertex.Factory<? extends Vertex> factory, OTFontCollection fontset) { this.pointFactory = factory; this.fontset = fontset; this.font = fontset.getFont(0); - this.size = size; CmapTable cmapTable = font.getCmapTable(); CmapFormat _cmapFormat = null; @@ -124,10 +123,6 @@ class TypecastFont implements FontInt { return fontset.getFileName(); } - public float getSize() { - return size; - } - public Metrics getMetrics() { if (metrics == null) { metrics = new TypecastMetrics(this); @@ -146,28 +141,90 @@ class TypecastFont implements FontInt { if(DEBUG) { System.err.println("New glyph: " + (int)symbol + " ( " + (char)symbol +" ) -> " + code + ", contours " + glyph.getPointCount() + ": " + path); } + final HdmxTable hdmx = font.getHdmxTable(); + if (null != hdmx) { + /*if(DEBUG) { + System.err.println("hdmx "+hdmx); + }*/ + for (int i=0; i<hdmx.getNumberOfRecords(); i++) + { + final HdmxTable.DeviceRecord dr = hdmx.getRecord(i); + result.addAdvance(dr.getWidth(code), dr.getPixelSize()); + if(DEBUG) { + System.err.println("hdmx advance : pixelsize = "+dr.getWidth(code)+" : "+ dr.getPixelSize()); + } + } + } char2Glyph.put(symbol, result); } return result; } - public void getOutline(String string, AffineTransform transform, Path2D[] result) { - TypecastRenderer.getOutline(pointFactory, this, string, transform, result); + public void getOutline(String string, float pixelSize, AffineTransform transform, Path2D[] result) { + TypecastRenderer.getOutline(pointFactory, this, string, pixelSize, transform, result); } - public float getStringWidth(String string) { - // return 0f; // FIXME font.getStringWidthForPixelSize(string, size); - throw new RuntimeException("n/a"); + public float getStringWidth(String string, float pixelSize) { + float width = 0; + final int len = string.length(); + for (int i=0; i< len; i++) + { + char character = string.charAt(i); + if (character == '\n') { + width = 0; + } else { + Glyph glyph = getGlyph(character); + width += glyph.getAdvance(pixelSize, false); + } + } + + return (int)(width + 0.5f); } - public float getStringHeight(String string) { - // return 0f; // FIXME font.getStringHeightForPixelSize(string, size); - throw new RuntimeException("n/a"); + public float getStringHeight(String string, float pixelSize) { + int height = 0; + + for (int i=0; i<string.length(); i++) + { + char character = string.charAt(i); + if (character != ' ') + { + Glyph glyph = getGlyph(character); + AABBox bbox = glyph.getBBox(pixelSize); + height = (int)Math.ceil(Math.max(bbox.getHeight(), height)); + } + } + return height; } - public AABBox getStringBounds(CharSequence string) { - // return null; // FIXME font.getStringBoundsForPixelSize(string, size); - throw new RuntimeException("n/a"); + public AABBox getStringBounds(CharSequence string, float pixelSize) { + if (string == null) { + return new AABBox(); + } + final Metrics metrics = getMetrics(); + final float lineGap = metrics.getLineGap(pixelSize); + final float ascent = metrics.getAscent(pixelSize); + final float descent = metrics.getDescent(pixelSize); + final float advanceY = lineGap - descent + ascent; + float totalHeight = 0; + float totalWidth = 0; + float curLineWidth = 0; + for (int i=0; i<string.length(); i++) { + char character = string.charAt(i); + if (character == '\n') { + totalWidth = Math.max(curLineWidth, totalWidth); + curLineWidth = 0; + totalHeight -= advanceY; + continue; + } + Glyph glyph = getGlyph(character); + curLineWidth += glyph.getAdvance(pixelSize, true); + } + if (curLineWidth > 0) { + totalHeight -= advanceY; + totalWidth = Math.max(curLineWidth, totalWidth); + } + return new AABBox(0, 0, 0, totalWidth, totalHeight,0); } final public int getNumGlyphs() { diff --git a/src/jogamp/graph/font/typecast/TypecastFontFactory.java b/src/jogamp/graph/font/typecast/TypecastFontFactory.java index 6179986fe..04559a138 100644 --- a/src/jogamp/graph/font/typecast/TypecastFontFactory.java +++ b/src/jogamp/graph/font/typecast/TypecastFontFactory.java @@ -40,12 +40,12 @@ public class TypecastFontFactory implements FontFactory { Map<String, Font> fonts = new HashMap<String, Font>(); - public Font createFont(Factory<? extends Vertex> factory, String name, int size) { - Font result = fonts.get(name + ":"+size); + public Font createFont(Factory<? extends Vertex> factory, String name) { + Font result = fonts.get(name); if (result == null) { - result = TypecastFont.create(factory, name, size); + result = TypecastFont.create(factory, name); if(result != null) { - fonts.put(name+":"+size, result); + fonts.put(name, result); } } return result; @@ -56,8 +56,7 @@ public class TypecastFontFactory implements FontFactory { String[] families, String style, String variant, - String weight, - String size) { + String weight) { throw new Error("not implemented"); } diff --git a/src/jogamp/graph/font/typecast/TypecastGlyph.java b/src/jogamp/graph/font/typecast/TypecastGlyph.java index 9bb582974..88d865f9c 100644 --- a/src/jogamp/graph/font/typecast/TypecastGlyph.java +++ b/src/jogamp/graph/font/typecast/TypecastGlyph.java @@ -27,6 +27,8 @@ */ package jogamp.graph.font.typecast; +import java.util.HashMap; + import jogamp.graph.font.FontInt; import jogamp.graph.geom.plane.AffineTransform; import jogamp.graph.geom.plane.Path2D; @@ -37,93 +39,58 @@ import com.jogamp.graph.geom.AABBox; public class TypecastGlyph implements FontInt.Glyph { public class Advance { - Font font; - float advance; - float advances[]; // in pixels - float sizes[]; - float advanceCached = -1; // in pixels - float sizeCached = -1; + final Font font; + final float advance; + HashMap<Float, Float> size2advance = new HashMap<Float, Float>(); public Advance(Font font, float advance) { this.font = font; this.advance = advance; - - this.advances = new float[0]; - this.sizes = new float[0]; } - public float getScaleForPixelSize(float pixelSize) + public void reset() { + size2advance.clear(); + } + + public float getScale(float pixelSize) { - return this.font.getMetrics().getScaleForPixelSize(pixelSize); + return this.font.getMetrics().getScale(pixelSize); } public void add(float advance, float size) { - float advancesNew[] = new float[this.advances.length+1]; - float sizesNew[] = new float[this.sizes.length+1]; - - for (int i=0; i<this.advances.length; i++) { - advancesNew[i] = this.advances[i]; - sizesNew[i] = this.sizes[i]; - } - - advancesNew[advancesNew.length-1] = advance; - sizesNew[sizesNew.length-1] = size; - - this.advances = advancesNew; - this.sizes = sizesNew; + size2advance.put(size, advance); } public float get(float size, boolean useFrationalMetrics) { - if (this.sizeCached != size) { - this.sizeCached = size; - - float value = (this.advance * getScaleForPixelSize(size)); + Float fo = size2advance.get(size); + if(null == fo) { + float value = (this.advance * getScale(size)); if (useFrationalMetrics == false) { //value = (float)Math.ceil(value); // value = (int)value; value = (int) ( value + 0.5f ) ; // TODO: check } - - if (true) - { - for (int i=0; i<this.advances.length; i++) - { - if (this.sizes[i] == size) - { - value = this.advances[i]; - break; - } - } - } - - this.advanceCached = value; + size2advance.put(size, value); + return value; } - return this.advanceCached; + return fo.floatValue(); } public String toString() { - String string = ""; - for (int i=0; i<this.advances.length; i++) { - string += " size: "+this.sizes[i]+" advance: "+this.advances[i]+"\n"; - } - if (string.length() > 0) { - string = "\n advances: \n"+string; - } return "\nAdvance:"+ "\n advance: "+this.advance+ - string; + "\n advances: \n"+size2advance; } } public class Metrics { AABBox bbox; - AABBox bbox_sized; - Advance advance; + Advance advance; public Metrics(Font font, AABBox bbox, float advance) { @@ -131,9 +98,13 @@ public class TypecastGlyph implements FontInt.Glyph { this.advance = new Advance(font, advance); } - public float getScaleForPixelSize(float pixelSize) + public void reset() { + advance.reset(); + } + + public float getScale(float pixelSize) { - return this.advance.getScaleForPixelSize(pixelSize); + return this.advance.getScale(pixelSize); } public AABBox getBBox() @@ -146,7 +117,7 @@ public class TypecastGlyph implements FontInt.Glyph { this.advance.add(advance, size); } - public float getAdvanceForPixelSize(float size, boolean useFrationalMetrics) + public float getAdvance(float size, boolean useFrationalMetrics) { return this.advance.get(size, useFrationalMetrics); } @@ -197,6 +168,11 @@ public class TypecastGlyph implements FontInt.Glyph { this.metrics = new Metrics(this.font, bbox, this.advance); } + public void reset(Path2D path) { + this.path = path; + this.metrics.reset(); + } + public Font getFont() { return this.font; } @@ -221,51 +197,36 @@ public class TypecastGlyph implements FontInt.Glyph { return this.id; } - public float getScaleForPixelSize(float pixelSize) { - return this.metrics.getScaleForPixelSize(pixelSize); + public float getScale(float pixelSize) { + return this.metrics.getScale(pixelSize); } - public AABBox getBBox(float size) { - AABBox newBox = getBBox().clone(); - newBox.scale(size); - return newBox; - } - - public AABBox getBBoxForPixelSize(float pixelSize) { - return getBBox(getScaleForPixelSize(pixelSize)); + public AABBox getBBox(float pixelSize) { + final float size = getScale(pixelSize); + AABBox newBox = getBBox().clone(); + newBox.scale(size); + return newBox; } protected void addAdvance(float advance, float size) { this.metrics.addAdvance(advance, size); } - public float getAdvanceForPixelSize(float size, boolean useFrationalMetrics) { - return this.metrics.getAdvanceForPixelSize(size, useFrationalMetrics); - } - - public float getAdvance() { - return getAdvanceForPixelSize(font.getSize(), false); + public float getAdvance(float pixelSize, boolean useFrationalMetrics) { + return this.metrics.getAdvance(pixelSize, useFrationalMetrics); } public Path2D getPath() { - return getPath(getScaleForPixelSize(font.getSize())); + return this.path; } - private Path2D getPath(float size) - { + public Path2D getPath(float pixelSize) { + final float size = getScale(pixelSize); + if (this.numberSized != size) { - this.numberSized = size; - this.pathSized = AffineTransform.getScaleInstance(null, size, size).createTransformedShape(getPath()); + this.numberSized = size; + this.pathSized = AffineTransform.getScaleInstance(null, size, size).createTransformedShape(getPath()); } return this.pathSized; - } - - public Path2D getPathForPixelSize(float pixelSize) { - return getPath(getScaleForPixelSize(pixelSize)); - } - - public Path2D getNormalPath() { - return this.path; - } - + } } diff --git a/src/jogamp/graph/font/typecast/TypecastMetrics.java b/src/jogamp/graph/font/typecast/TypecastMetrics.java index 541ed90d8..9ca1e3bf7 100644 --- a/src/jogamp/graph/font/typecast/TypecastMetrics.java +++ b/src/jogamp/graph/font/typecast/TypecastMetrics.java @@ -37,51 +37,42 @@ class TypecastMetrics implements Metrics { private final TypecastFont fontImpl; // HeadTable + private final HeadTable headTable; private final float unitsPerEM_Inv; - private final float unitsPerEM_Inv_sized; - private final AABBox bbox_sized; - + private final AABBox bbox; // HheaTable - private final float ascend_sized; - private final float descent_sized; - private final float linegap_sized; + private final HheaTable hheaTable; public TypecastMetrics(TypecastFont fontImpl) { this.fontImpl = fontImpl; - final HeadTable headTable = this.fontImpl.font.getHeadTable(); - unitsPerEM_Inv = 1.0f / ( (float) headTable.getUnitsPerEm() ); - unitsPerEM_Inv_sized = this.fontImpl.size * unitsPerEM_Inv; - int maxWidth = headTable.getXMax() - headTable.getXMin(); - int maxHeight = headTable.getYMax() - headTable.getYMin(); - float lowx= headTable.getXMin(); - float lowy = -(headTable.getYMin()+maxHeight); - float highx = lowx + maxWidth; - float highy = lowy + maxHeight; - bbox_sized = new AABBox(lowx, lowy, 0, highx, highy, 0); // invert - bbox_sized.scale(unitsPerEM_Inv_sized); - - final HheaTable hheaTable = this.fontImpl.font.getHheaTable(); - ascend_sized = unitsPerEM_Inv_sized * -hheaTable.getAscender(); // invert - descent_sized = unitsPerEM_Inv_sized * -hheaTable.getDescender(); // invert - linegap_sized = unitsPerEM_Inv_sized * -hheaTable.getLineGap(); // invert + headTable = this.fontImpl.font.getHeadTable(); + hheaTable = this.fontImpl.font.getHheaTable(); + unitsPerEM_Inv = 1.0f / ( (float) headTable.getUnitsPerEm() ); + + int maxWidth = headTable.getXMax() - headTable.getXMin(); + int maxHeight = headTable.getYMax() - headTable.getYMin(); + float lowx= headTable.getXMin(); + float lowy = -(headTable.getYMin()+maxHeight); + float highx = lowx + maxWidth; + float highy = lowy + maxHeight; + bbox = new AABBox(lowx, lowy, 0, highx, highy, 0); // invert } - - public final float getAscent() { - return ascend_sized; + + public final float getAscent(float pixelSize) { + return getScale(pixelSize) * -hheaTable.getAscender(); // invert } - public final float getDescent() { - return descent_sized; + public final float getDescent(float pixelSize) { + return getScale(pixelSize) * -hheaTable.getDescender(); // invert } - public final float getLineGap() { - return linegap_sized; + public final float getLineGap(float pixelSize) { + return getScale(pixelSize) * -hheaTable.getLineGap(); // invert } - public final float getScale() { - return unitsPerEM_Inv_sized; - } - public float getScaleForPixelSize(float pixelSize) { - return pixelSize * unitsPerEM_Inv; - } - public final AABBox getBBox() { - return bbox_sized; + public final float getScale(float pixelSize) { + return pixelSize * unitsPerEM_Inv; + } + public final AABBox getBBox(float pixelSize) { + AABBox res = new AABBox(bbox.getLow(), bbox.getHigh()); + res.scale(getScale(pixelSize)); + return res; } }
\ No newline at end of file diff --git a/src/jogamp/graph/font/typecast/TypecastRenderer.java b/src/jogamp/graph/font/typecast/TypecastRenderer.java index 74e5cd604..11f1ec028 100644 --- a/src/jogamp/graph/font/typecast/TypecastRenderer.java +++ b/src/jogamp/graph/font/typecast/TypecastRenderer.java @@ -44,16 +44,16 @@ import net.java.dev.typecast.ot.OTGlyph; public class TypecastRenderer { public static void getOutline(Factory<? extends Vertex> factory, TypecastFont font, - String string, AffineTransform transform, Path2D[] p) + String string, float pixelSize, AffineTransform transform, Path2D[] p) { if (string == null) { return; } Font.Metrics metrics = font.getMetrics(); float advanceTotal = 0; - float lineGap = metrics.getLineGap() ; - float ascent = metrics.getAscent() ; - float descent = metrics.getDescent() ; + float lineGap = metrics.getLineGap(pixelSize) ; + float ascent = metrics.getAscent(pixelSize) ; + float descent = metrics.getDescent(pixelSize) ; if (transform == null) { transform = new AffineTransform(factory); } @@ -73,12 +73,12 @@ public class TypecastRenderer { continue; } TypecastGlyph glyph = (TypecastGlyph) font.getGlyph(character); - Path2D gp = glyph.getNormalPath(); - float scale = metrics.getScale(); + Path2D gp = glyph.getPath(); + float scale = metrics.getScale(pixelSize); t.translate(advanceTotal, y); t.scale(scale, scale); p[i].append(gp.iterator(t), false); - advanceTotal += glyph.getAdvanceForPixelSize(font.getSize(), true); + advanceTotal += glyph.getAdvance(pixelSize, true); } } |