summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRoman Kennke <roman@kennke.org>2006-12-14 20:32:54 +0000
committerRoman Kennke <roman@kennke.org>2006-12-14 20:32:54 +0000
commitf09e4046b6d9d19a58ddfe1f3bb9b72ec30aa89d (patch)
tree1dbfe07b0f4e83bdbdb19ac126b6b702be0273c0
parent6bdc4dc04b911a4ab8d8602834a1807873f0e6bc (diff)
downloadclasspath-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--ChangeLog53
-rw-r--r--gnu/java/awt/font/autofit/AutoHinter.java9
-rw-r--r--gnu/java/awt/font/autofit/AxisHints.java26
-rw-r--r--gnu/java/awt/font/autofit/Edge.java70
-rw-r--r--gnu/java/awt/font/autofit/GlyphHints.java13
-rw-r--r--gnu/java/awt/font/autofit/Latin.java231
-rw-r--r--gnu/java/awt/font/autofit/LatinAxis.java2
-rw-r--r--gnu/java/awt/font/autofit/Script.java4
-rw-r--r--gnu/java/awt/font/autofit/Segment.java6
-rw-r--r--gnu/java/awt/font/opentype/Hinter.java9
-rw-r--r--gnu/java/awt/font/opentype/OpenTypeFont.java3
-rw-r--r--gnu/java/awt/font/opentype/Scaler.java3
-rw-r--r--gnu/java/awt/font/opentype/truetype/GlyphLoader.java33
-rw-r--r--gnu/java/awt/font/opentype/truetype/TrueTypeScaler.java7
14 files changed, 444 insertions, 25 deletions
diff --git a/ChangeLog b/ChangeLog
index 490dac16a..5853dd53e 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -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;
}