diff options
author | Roman Kennke <roman@kennke.org> | 2006-12-14 20:32:54 +0000 |
---|---|---|
committer | Roman Kennke <roman@kennke.org> | 2006-12-14 20:32:54 +0000 |
commit | f09e4046b6d9d19a58ddfe1f3bb9b72ec30aa89d (patch) | |
tree | 1dbfe07b0f4e83bdbdb19ac126b6b702be0273c0 | |
parent | 6bdc4dc04b911a4ab8d8602834a1807873f0e6bc (diff) | |
download | classpath-f09e4046b6d9d19a58ddfe1f3bb9b72ec30aa89d.tar.gz |
2006-12-14 Roman Kennke <kennke@aicas.com>
* gnu/java/awt/font/autofit/AutoHinter.java
(hints): New field.
(applyHints): New method. Implements the actual hinting.
* gnu/java/awt/font/autofit/AxisHints.java
(edges): New field.
(AxisHints): Initialize edges field.
(newEdge): New method. Records a new edge and sorts it into the
existing list.
* gnu/java/awt/font/autofit/Edge.java: New class.
* gnu/java/awt/font/autofit/GlyphHints.java
(GlyphHints): Initialize the scales with 1.
(doHorizontal): New method.
(doVertical): New method.
* gnu/java/awt/font/autofit/Latin.java
(alignEdgePoints): New stub method.
(alignStrongPoints): New stub method.
(alignWeakPoints): New stub method.
(applyHints): Take outline as argument. Implemented skeleton.
(computeBlueEdges): New stub method.
(computeEdges): New method. Detects edges on a glyph outline.
(detectFeatures): New methods. Performs local feature analysis.
(hintEdges): New stub method.
(initBlues): Remove debug output.
* gnu/java/awt/font/autofit/LatinAxis.java
(edgeDistanceThreshold): Changed to be an int
(as fixed-point decimal).
* gnu/java/awt/font/autofit/Script.java
(applyHints): Include the outline in the method call.
* gnu/java/awt/font/autofit/Segment.java
(FLAG_EDGE_NORMAL): Set value to 0.
(FLAG_EDGE_SERIF): New constant.
(FLAG_EDGE_DONE): New constant.
(edge): New field.
(edgeNext): New field.
* gnu/java/awt/font/opentype/Hinter.java
(applyHints): New method. Applies the hints to the specified outline.
* gnu/java/awt/font/opentype/OpenTypeFont.java
(getGlyphOutline): Check the hinter and call the scaler with the
hinter.
* gnu/java/awt/font/opentype/Scaler.java
(getOutline): Also pass a Hinter.
* gnu/java/awt/font/opentype/truetype/GlyphLoader.java
(loadCompoundGlyph): Also accept a hinter argument.
(loadGlyph): Also accept a hinter argument.
(loadSimpleGlyph): Also accept a hinter argument. Hint the
resulting outline.
(loadSubGlyph): Also accept a hinter argument.
* gnu/java/awt/font/opentype/truetype/TrueTypeScaler.java
(getOutline): Accept hinter and pass it to the loader.
(getRawOutline): Pass null hinter to the loader.
-rw-r--r-- | ChangeLog | 53 | ||||
-rw-r--r-- | gnu/java/awt/font/autofit/AutoHinter.java | 9 | ||||
-rw-r--r-- | gnu/java/awt/font/autofit/AxisHints.java | 26 | ||||
-rw-r--r-- | gnu/java/awt/font/autofit/Edge.java | 70 | ||||
-rw-r--r-- | gnu/java/awt/font/autofit/GlyphHints.java | 13 | ||||
-rw-r--r-- | gnu/java/awt/font/autofit/Latin.java | 231 | ||||
-rw-r--r-- | gnu/java/awt/font/autofit/LatinAxis.java | 2 | ||||
-rw-r--r-- | gnu/java/awt/font/autofit/Script.java | 4 | ||||
-rw-r--r-- | gnu/java/awt/font/autofit/Segment.java | 6 | ||||
-rw-r--r-- | gnu/java/awt/font/opentype/Hinter.java | 9 | ||||
-rw-r--r-- | gnu/java/awt/font/opentype/OpenTypeFont.java | 3 | ||||
-rw-r--r-- | gnu/java/awt/font/opentype/Scaler.java | 3 | ||||
-rw-r--r-- | gnu/java/awt/font/opentype/truetype/GlyphLoader.java | 33 | ||||
-rw-r--r-- | gnu/java/awt/font/opentype/truetype/TrueTypeScaler.java | 7 |
14 files changed, 444 insertions, 25 deletions
@@ -1,5 +1,58 @@ 2006-12-14 Roman Kennke <kennke@aicas.com> + * gnu/java/awt/font/autofit/AutoHinter.java + (hints): New field. + (applyHints): New method. Implements the actual hinting. + * gnu/java/awt/font/autofit/AxisHints.java + (edges): New field. + (AxisHints): Initialize edges field. + (newEdge): New method. Records a new edge and sorts it into the + existing list. + * gnu/java/awt/font/autofit/Edge.java: New class. + * gnu/java/awt/font/autofit/GlyphHints.java + (GlyphHints): Initialize the scales with 1. + (doHorizontal): New method. + (doVertical): New method. + * gnu/java/awt/font/autofit/Latin.java + (alignEdgePoints): New stub method. + (alignStrongPoints): New stub method. + (alignWeakPoints): New stub method. + (applyHints): Take outline as argument. Implemented skeleton. + (computeBlueEdges): New stub method. + (computeEdges): New method. Detects edges on a glyph outline. + (detectFeatures): New methods. Performs local feature analysis. + (hintEdges): New stub method. + (initBlues): Remove debug output. + * gnu/java/awt/font/autofit/LatinAxis.java + (edgeDistanceThreshold): Changed to be an int + (as fixed-point decimal). + * gnu/java/awt/font/autofit/Script.java + (applyHints): Include the outline in the method call. + * gnu/java/awt/font/autofit/Segment.java + (FLAG_EDGE_NORMAL): Set value to 0. + (FLAG_EDGE_SERIF): New constant. + (FLAG_EDGE_DONE): New constant. + (edge): New field. + (edgeNext): New field. + * gnu/java/awt/font/opentype/Hinter.java + (applyHints): New method. Applies the hints to the specified outline. + * gnu/java/awt/font/opentype/OpenTypeFont.java + (getGlyphOutline): Check the hinter and call the scaler with the + hinter. + * gnu/java/awt/font/opentype/Scaler.java + (getOutline): Also pass a Hinter. + * gnu/java/awt/font/opentype/truetype/GlyphLoader.java + (loadCompoundGlyph): Also accept a hinter argument. + (loadGlyph): Also accept a hinter argument. + (loadSimpleGlyph): Also accept a hinter argument. Hint the + resulting outline. + (loadSubGlyph): Also accept a hinter argument. + * gnu/java/awt/font/opentype/truetype/TrueTypeScaler.java + (getOutline): Accept hinter and pass it to the loader. + (getRawOutline): Pass null hinter to the loader. + +2006-12-14 Roman Kennke <kennke@aicas.com> + * gnu/java/awt/font/autofit/LatinBlue.java: New class. diff --git a/gnu/java/awt/font/autofit/AutoHinter.java b/gnu/java/awt/font/autofit/AutoHinter.java index 18af677bf..6f948e0cb 100644 --- a/gnu/java/awt/font/autofit/AutoHinter.java +++ b/gnu/java/awt/font/autofit/AutoHinter.java @@ -40,6 +40,7 @@ package gnu.java.awt.font.autofit; import gnu.java.awt.font.opentype.Hinter; import gnu.java.awt.font.opentype.OpenTypeFont; +import gnu.java.awt.font.opentype.truetype.Zone; /** * The public interface to the automatic gridfitter. @@ -49,6 +50,7 @@ public class AutoHinter { Latin latinScript; LatinMetrics metrics; + GlyphHints hints; public void init(OpenTypeFont font) { @@ -57,4 +59,11 @@ public class AutoHinter metrics = new LatinMetrics(font); latinScript.initMetrics(metrics, font); } + + public void applyHints(Zone outline) + { + if (hints == null) + hints = new GlyphHints(); + latinScript.applyHints(hints, outline, metrics); + } } diff --git a/gnu/java/awt/font/autofit/AxisHints.java b/gnu/java/awt/font/autofit/AxisHints.java index 0cea9c4bf..e17c51521 100644 --- a/gnu/java/awt/font/autofit/AxisHints.java +++ b/gnu/java/awt/font/autofit/AxisHints.java @@ -45,10 +45,12 @@ class AxisHints int majorDir; int numSegments; int numEdges; + Edge[] edges; AxisHints() { segments = new Segment[4]; + edges = new Edge[4]; } Segment newSegment() @@ -67,4 +69,28 @@ class AxisHints numSegments++; return seg; } + + public Edge newEdge(int pos) + { + if (numEdges >= edges.length) + { + // Grow array. + int newMax = edges.length; + newMax += (newMax >> 2) + 4; // From FreeType. + Edge[] newEdges = new Edge[newMax]; + System.arraycopy(edges, 0, newEdges, 0, numEdges); + edges = newEdges; + } + int edgeIndex = numEdges; + Edge edge = edges[edgeIndex] = new Edge(); + while (edgeIndex > 0 && edges[edgeIndex].fpos > pos) + { + edges[edgeIndex] = edges[edgeIndex - 1]; + edgeIndex--; + } + edges[edgeIndex] = edge; + numEdges++; + edge.fpos = pos; + return edge; + } } diff --git a/gnu/java/awt/font/autofit/Edge.java b/gnu/java/awt/font/autofit/Edge.java new file mode 100644 index 000000000..b71b2247c --- /dev/null +++ b/gnu/java/awt/font/autofit/Edge.java @@ -0,0 +1,70 @@ +/* Edge.java -- An edge of segments + Copyright (C) 2006 Free Software Foundation, Inc. + +This file is part of GNU Classpath. + +GNU Classpath is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 2, or (at your option) +any later version. + +GNU Classpath is distributed in the hope that it will be useful, but +WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +General Public License for more details. + +You should have received a copy of the GNU General Public License +along with GNU Classpath; see the file COPYING. If not, write to the +Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA +02110-1301 USA. + +Linking this library statically or dynamically with other modules is +making a combined work based on this library. Thus, the terms and +conditions of the GNU General Public License cover the whole +combination. + +As a special exception, the copyright holders of this library give you +permission to link this library with independent modules to produce an +executable, regardless of the license terms of these independent +modules, and to copy and distribute the resulting executable under +terms of your choice, provided that you also meet, for each linked +independent module, the terms and conditions of the license of that +module. An independent module is a module which is not derived from +or based on this library. If you modify this library, you may extend +this exception to your version of the library, but you are not +obligated to do so. If you do not wish to do so, delete this +exception statement from your version. */ + + +package gnu.java.awt.font.autofit; + +class Edge +{ + int fpos; + Segment first; + Segment last; + int opos; + Edge link; + Edge serif; + int flags; + int dir; + + public String toString() + { + StringBuilder s = new StringBuilder(); + s.append("[Edge] id"); + s.append(hashCode()); + s.append(", fpos: "); + s.append(fpos); + s.append(", opos: "); + s.append(opos); + s.append(", dir: "); + s.append(dir); + s.append(", serif: "); + s.append(serif != null ? serif.hashCode() : "null"); + s.append(", link: "); + s.append(link != null ? link.hashCode() : "null"); + s.append(", flags: " + flags); + return s.toString(); + } +} diff --git a/gnu/java/awt/font/autofit/GlyphHints.java b/gnu/java/awt/font/autofit/GlyphHints.java index 208a7f875..8b20ea320 100644 --- a/gnu/java/awt/font/autofit/GlyphHints.java +++ b/gnu/java/awt/font/autofit/GlyphHints.java @@ -38,6 +38,7 @@ exception statement from your version. */ package gnu.java.awt.font.autofit; +import gnu.java.awt.font.opentype.truetype.Fixed; import gnu.java.awt.font.opentype.truetype.Point; import gnu.java.awt.font.opentype.truetype.Zone; @@ -71,6 +72,9 @@ class GlyphHints axis = new AxisHints[Constants.DIMENSION_MAX]; axis[Constants.DIMENSION_VERT] = new AxisHints(); axis[Constants.DIMENSION_HORZ] = new AxisHints(); + + xScale = Fixed.ONE; + yScale = Fixed.ONE; } void rescale(ScriptMetrics m) @@ -276,4 +280,13 @@ class GlyphHints } } + boolean doHorizontal() + { + return true; // Check scaler flags here. + } + + boolean doVertical() + { + return true; // Check scaler flags here. + } } diff --git a/gnu/java/awt/font/autofit/Latin.java b/gnu/java/awt/font/autofit/Latin.java index 13c59f8f5..4587d987e 100644 --- a/gnu/java/awt/font/autofit/Latin.java +++ b/gnu/java/awt/font/autofit/Latin.java @@ -42,6 +42,7 @@ import java.awt.geom.AffineTransform; import java.util.HashSet; import gnu.java.awt.font.opentype.OpenTypeFont; +import gnu.java.awt.font.opentype.truetype.Fixed; import gnu.java.awt.font.opentype.truetype.Point; import gnu.java.awt.font.opentype.truetype.Zone; @@ -76,10 +77,58 @@ class Latin new String[]{"THEZOCQS", "HEZLOCUS", "fijkdbh", "xzroesc", "xzroesc", "pqgjy"}; - public void applyHints(GlyphHints hints, ScriptMetrics metrics) + public void applyHints(GlyphHints hints, Zone outline, ScriptMetrics metrics) + { + hints.reload(outline); + hints.rescale(metrics); + if (hints.doHorizontal()) + { + detectFeatures(hints, DIMENSION_HORZ); + } + if (hints.doVertical()) + { + detectFeatures(hints, DIMENSION_VERT); + computeBlueEdges(hints, (LatinMetrics) metrics); + } + // Grid-fit the outline. + for (int dim = 0; dim < DIMENSION_MAX; dim++) + { + if (dim == DIMENSION_HORZ && hints.doHorizontal() + || dim == DIMENSION_VERT && hints.doVertical()) + { + hintEdges(hints, dim); + alignEdgePoints(hints, dim); + alignStrongPoints(hints, dim); + alignWeakPoints(hints, dim); + + } + } + // FreeType does a save call here. I guess that's not needed as we operate + // on the live glyph data anyway. + } + + private void alignWeakPoints(GlyphHints hints, int dim) { // TODO Auto-generated method stub + + } + private void alignStrongPoints(GlyphHints hints, int dim) + { + // TODO Auto-generated method stub + + } + + private void alignEdgePoints(GlyphHints hints, int dim) + { + // TODO Auto-generated method stub + + } + + private void hintEdges(GlyphHints hints, int dim) + { + // TODO Auto-generated method stub + } public void doneMetrics(ScriptMetrics metrics) @@ -426,7 +475,7 @@ class Latin blue.flags |= LatinBlue.FLAG_ADJUSTMENT; } // Debug: print out the blue zones. - System.err.println("blue zone #" + bb + ": " + blue); + // System.err.println("blue zone #" + bb + ": " + blue); } } @@ -555,4 +604,182 @@ class Latin { return b == CAPITAL_TOP || b == SMALL_F_TOP || b == SMALL_TOP; } + + private void detectFeatures(GlyphHints hints, int dim) + { + computeSegments(hints, dim); + linkSegments(hints, dim); + computeEdges(hints, dim); + } + + private void computeEdges(GlyphHints hints, int dim) + { + AxisHints axis = hints.axis[dim]; + LatinAxis laxis = ((LatinMetrics) hints.metrics).axis[dim]; + Segment[] segments = axis.segments; + int numSegments = axis.numSegments; + Segment seg; + int upDir; + int scale; + int edgeDistanceThreshold; + axis.numEdges = 0; + scale = dim == DIMENSION_HORZ ? hints.xScale : hints.yScale; + upDir = dim == DIMENSION_HORZ ? DIR_UP : DIR_RIGHT; + + // We will begin by generating a sorted table of edges for the + // current direction. To do so, we simply scan each segment and try + // to find an edge in our table that corresponds to its position. + // + // If no edge is found, we create one and insert a new edge in the + // sorted table. Otherwise, we simply add the segment to the egde's + // list which will be processed in the second step to compute the + // edge's properties. + // + // Note that the edge table is sorted along the segment/edge + // position. + + edgeDistanceThreshold = Fixed.mul(laxis.edgeDistanceTreshold, scale); + if (edgeDistanceThreshold > 64 / 4) + edgeDistanceThreshold = 64 / 4; + edgeDistanceThreshold = Fixed.div(edgeDistanceThreshold, scale); + + for (int i = 0; i < numSegments; i++) + { + seg = segments[i]; + Edge found = null; + for (int ee = 0; ee < axis.numEdges; ee++) + { + Edge edge = axis.edges[ee]; + int dist = seg.pos - edge.fpos; + if (dist < 0) + dist = -dist; + if (dist < edgeDistanceThreshold) + { + found = edge; + break; + } + } + if (found == null) + { + // Insert new edge in the list and sort according to + // the position. + Edge edge = axis.newEdge(seg.pos); + edge.first = seg; + edge.last = seg; + edge.fpos = seg.pos; + edge.opos = Fixed.mul(seg.pos, scale); + seg.edgeNext = seg; + seg.edge = edge; + } + else + { + seg.edgeNext = found.first; + found.last.edgeNext = seg; + found.last = seg; + seg.edge = found; + } + } + // Good. We will now compute each edge's properties according to + // segments found on its position. Basically these are: + // - Edge's main direction. + // - Stem edge, serif edge, or both (which defaults to stem edge). + // - Rounded edge, straight or both (which defaults to straight). + // - Link for edge. + + // Now, compute each edge properties. + for (int e = 0; e < axis.numEdges; e++) + { + Edge edge = axis.edges[e]; + // Does it contain round segments? + int isRound = 0; + // Does it contain straight segments? + int isStraight = 0; + // Number of upward segments. + int ups = 0; + // Number of downward segments. + int downs = 0; + + seg = edge.first; + do + { + // Check for roundness of segment. + if ((seg.flags & Segment.FLAG_EDGE_ROUND) != 0) + isRound++; + else + isStraight++; + + // Check for segment direction. + if (seg.dir == upDir) + ups += seg.maxPos - seg.minPos; + else + downs += seg.maxPos - seg.minPos; + + // Check for links. If seg.serif is set, then seg.link must + // be ignored. + boolean isSerif = seg.serif != null && seg.serif.edge != edge; + if (seg.link != null || isSerif) + { + Edge edge2 = edge.link; + Segment seg2 = seg.link; + if (isSerif) + { + seg2 = seg.serif; + edge2 = edge.serif; + } + if (edge2 != null) + { + int edgeDelta = edge.fpos - edge2.fpos; + if (edgeDelta < 0) + edgeDelta = -edgeDelta; + int segDelta = seg.pos - seg2.pos; + if (segDelta < 0) + segDelta = -segDelta; + if (segDelta < edgeDelta) + edge2 = seg2.edge; + } + else + { + edge2 = seg2.edge; + } + if (isSerif) + { + edge.serif = edge2; + edge2.flags |= Segment.FLAG_EDGE_SERIF; + } + else + { + edge.link = edge2; + } + } + seg = seg.edgeNext; + } while (seg != edge.first); + edge.flags = Segment.FLAG_EDGE_NORMAL; + if (isRound > 0 && isRound > isStraight) + edge.flags |= Segment.FLAG_EDGE_ROUND; + + // Set the edge's main direction. + edge.dir = DIR_NONE; + if (ups > downs) + edge.dir = upDir; + else if (ups < downs) + edge.dir = -upDir; + else if (ups == downs) + edge.dir = 0; + + // Gets rid of serif if link is set. This gets rid of many + // unpleasant artifacts. + if (edge.serif != null && edge.link != null) + { + edge.serif = null; + } + + // Debug: Print out all edges. + // System.err.println("edge# " + e + ": " + edge); + } + } + + private void computeBlueEdges(GlyphHints hints, LatinMetrics metrics) + { + // TODO: Implement. + } } diff --git a/gnu/java/awt/font/autofit/LatinAxis.java b/gnu/java/awt/font/autofit/LatinAxis.java index d8341c865..a720cd93c 100644 --- a/gnu/java/awt/font/autofit/LatinAxis.java +++ b/gnu/java/awt/font/autofit/LatinAxis.java @@ -49,7 +49,7 @@ class LatinAxis int widthCount; Width[] widths; - float edgeDistanceTreshold; + int edgeDistanceTreshold; LatinBlue[] blues; int blueCount; LatinAxis() diff --git a/gnu/java/awt/font/autofit/Script.java b/gnu/java/awt/font/autofit/Script.java index 3b353010f..d394ff2e6 100644 --- a/gnu/java/awt/font/autofit/Script.java +++ b/gnu/java/awt/font/autofit/Script.java @@ -39,6 +39,7 @@ exception statement from your version. */ package gnu.java.awt.font.autofit; import gnu.java.awt.font.opentype.OpenTypeFont; +import gnu.java.awt.font.opentype.truetype.Zone; /** * Defines script specific methods for the auto fitter. @@ -57,6 +58,5 @@ interface Script void initHints(GlyphHints hints, ScriptMetrics metrics); - void applyHints(GlyphHints hints, /* some outline object, */ - ScriptMetrics metrics); + void applyHints(GlyphHints hints, Zone outline, ScriptMetrics metrics); } diff --git a/gnu/java/awt/font/autofit/Segment.java b/gnu/java/awt/font/autofit/Segment.java index 45e0ff5ad..640e82ce2 100644 --- a/gnu/java/awt/font/autofit/Segment.java +++ b/gnu/java/awt/font/autofit/Segment.java @@ -43,8 +43,10 @@ import gnu.java.awt.font.opentype.truetype.Point; class Segment { + static final int FLAG_EDGE_NORMAL = 0; static final int FLAG_EDGE_ROUND = 1; - static final int FLAG_EDGE_NORMAL = 2; + static final int FLAG_EDGE_SERIF = 2; + static final int FLAG_EDGE_DONE = 4; int dir; int flags; Segment link; @@ -58,6 +60,8 @@ class Segment int maxPos; int score; int len; + Segment edgeNext; + Edge edge; public String toString() { diff --git a/gnu/java/awt/font/opentype/Hinter.java b/gnu/java/awt/font/opentype/Hinter.java index d2e13b854..1e48e1108 100644 --- a/gnu/java/awt/font/opentype/Hinter.java +++ b/gnu/java/awt/font/opentype/Hinter.java @@ -38,6 +38,8 @@ exception statement from your version. */ package gnu.java.awt.font.opentype; +import gnu.java.awt.font.opentype.truetype.Zone; + /** * The interface to a hinting implementation. */ @@ -49,4 +51,11 @@ public interface Hinter * @param face the font for which the hinter should be used */ void init(OpenTypeFont face); + + /** + * Hints the specified outline. + * + * @param outline the outline to hint + */ + void applyHints(Zone outline); } diff --git a/gnu/java/awt/font/opentype/OpenTypeFont.java b/gnu/java/awt/font/opentype/OpenTypeFont.java index ce66e2908..3504161d1 100644 --- a/gnu/java/awt/font/opentype/OpenTypeFont.java +++ b/gnu/java/awt/font/opentype/OpenTypeFont.java @@ -699,8 +699,9 @@ public final class OpenTypeFont /* The synchronization is needed because the scaler is not * synchronized. */ + checkHinter(); return scaler.getOutline(glyph, pointSize, transform, - antialias, fractionalMetrics); + antialias, fractionalMetrics, hinter); } /** diff --git a/gnu/java/awt/font/opentype/Scaler.java b/gnu/java/awt/font/opentype/Scaler.java index 83a31c576..9e12d9da0 100644 --- a/gnu/java/awt/font/opentype/Scaler.java +++ b/gnu/java/awt/font/opentype/Scaler.java @@ -90,7 +90,8 @@ public abstract class Scaler float pointSize, AffineTransform transform, boolean antialias, - boolean fractionalMetrics); + boolean fractionalMetrics, + Hinter hinter); /** diff --git a/gnu/java/awt/font/opentype/truetype/GlyphLoader.java b/gnu/java/awt/font/opentype/truetype/GlyphLoader.java index 3733afe92..249a87dd4 100644 --- a/gnu/java/awt/font/opentype/truetype/GlyphLoader.java +++ b/gnu/java/awt/font/opentype/truetype/GlyphLoader.java @@ -38,6 +38,8 @@ exception statement from your version. */ package gnu.java.awt.font.opentype.truetype; +import gnu.java.awt.font.opentype.Hinter; + import java.awt.geom.AffineTransform; import java.nio.ByteBuffer; @@ -112,17 +114,17 @@ final class GlyphLoader double pointSize, AffineTransform transform, boolean antialias, - Zone glyphZone) + Zone glyphZone, Hinter hinter) { glyphZone.setNumPoints(4); loadSubGlyph(glyphIndex, pointSize, transform, antialias, glyphZone, - 0, 0); + 0, 0, hinter); } public void loadGlyph(int glyphIndex, AffineTransform transform, - Zone glyphZone) + Zone glyphZone, Hinter hinter) { - loadGlyph(glyphIndex, unitsPerEm, transform, false, glyphZone); + loadGlyph(glyphIndex, unitsPerEm, transform, false, glyphZone, hinter); } private void loadSubGlyph(int glyphIndex, @@ -131,7 +133,8 @@ final class GlyphLoader boolean antialias, Zone glyphZone, int preTranslateX, - int preTranslateY) + int preTranslateY, + Hinter hinter) { ByteBuffer glyph; int numContours; @@ -159,11 +162,11 @@ final class GlyphLoader if (numContours >= 0) loadSimpleGlyph(glyphIndex, pointSize, transform, antialias, numContours, glyph, glyphZone, - preTranslateX, preTranslateY); + preTranslateX, preTranslateY, hinter); else loadCompoundGlyph(glyphIndex, pointSize, transform, antialias, glyph, glyphZone, - preTranslateX, preTranslateY); + preTranslateX, preTranslateY, hinter); } @@ -172,7 +175,8 @@ final class GlyphLoader boolean antialias, int numContours, ByteBuffer glyph, Zone glyphZone, - int preTranslateX, int preTranslateY) + int preTranslateX, int preTranslateY, + Hinter hinter) { int numPoints; int posInstructions, numInstructions; @@ -203,10 +207,10 @@ final class GlyphLoader glyphZone.transform(pointSize, transform, unitsPerEm, preTranslateX, preTranslateY); - if (execInstructions) - { - // FIXME: Hint the glyph. - } + if (execInstructions && hinter != null) + { + hinter.applyHints(glyphZone); + } } @@ -229,7 +233,8 @@ final class GlyphLoader boolean antialias, ByteBuffer glyph, Zone glyphZone, - int preTranslateX, int preTranslateY) + int preTranslateX, int preTranslateY, + Hinter hinter) { short flags; int subGlyphIndex; @@ -326,7 +331,7 @@ final class GlyphLoader loadSubGlyph(subGlyphIndex, pointSize, componentTransform, antialias, subGlyphZone, Math.round((float) e + preTranslateX), - Math.round(-((float) f + preTranslateY))); + Math.round(-((float) f + preTranslateY)), hinter); glyphZone.combineWithSubGlyph(subGlyphZone, 4); glyph.limit(lim).position(pos); } diff --git a/gnu/java/awt/font/opentype/truetype/TrueTypeScaler.java b/gnu/java/awt/font/opentype/truetype/TrueTypeScaler.java index 8dfdeff07..8de135a89 100644 --- a/gnu/java/awt/font/opentype/truetype/TrueTypeScaler.java +++ b/gnu/java/awt/font/opentype/truetype/TrueTypeScaler.java @@ -37,6 +37,7 @@ exception statement from your version. */ package gnu.java.awt.font.opentype.truetype; +import gnu.java.awt.font.opentype.Hinter; import gnu.java.awt.font.opentype.Scaler; import java.awt.FontFormatException; @@ -191,17 +192,17 @@ public final class TrueTypeScaler float pointSize, AffineTransform deviceTransform, boolean antialias, - boolean fractionalMetrics) + boolean fractionalMetrics, Hinter hinter) { glyphLoader.loadGlyph(glyphIndex, pointSize, deviceTransform, - antialias, glyphZone); + antialias, glyphZone, hinter); return glyphZone.getPath(); } public Zone getRawOutline(int glyphIndex, AffineTransform transform) { Zone zone = new Zone(glyphZone.getCapacity()); - glyphLoader.loadGlyph(glyphIndex, transform, zone); + glyphLoader.loadGlyph(glyphIndex, transform, zone, null); return zone; } |