This fixes the hinting of strong points and the computation of
inflection points in the autohinter.
2007-01-04 Roman Kennke <[EMAIL PROTECTED]>
* gnu/java/awt/font/autofit/GlyphHints.java
(alignStrongPoints): Don't special case the vertical dimension.
(computeInflectionPoints): Corrected computation of inflection
points.
* gnu/java/awt/font/autofit/Utils.java
(ANGLE_4PI): Removed.
(ANGLE_PI2): New constant for PI/2.
(ANGLE_PI4): New constant for PI/4.
(angleDiff): Fixed.
(atan): Fixed.
/Roman
Index: gnu/java/awt/font/autofit/GlyphHints.java
===================================================================
RCS file: /cvsroot/classpath/classpath/gnu/java/awt/font/autofit/GlyphHints.java,v
retrieving revision 1.6
diff -u -1 -5 -r1.6 GlyphHints.java
--- gnu/java/awt/font/autofit/GlyphHints.java 16 Dec 2006 20:51:02 -0000 1.6
+++ gnu/java/awt/font/autofit/GlyphHints.java 4 Jan 2007 10:29:04 -0000
@@ -200,62 +200,63 @@
}
computeInflectionPoints();
}
private void setWeakPoint(Point p)
{
p.setFlags((byte) (p.getFlags() | Point.FLAG_WEAK_INTERPOLATION));
}
/**
* Computes the inflection points for a glyph.
*/
private void computeInflectionPoints()
{
// Do each contour separately.
- for (int c = 0; c < contours.length; c++)
+ contours : for (int c = 0; c < contours.length; c++)
{
Point point = contours[c];
Point first = point;
Point start = point;
Point end = point;
do
{
end = end.getNext();
if (end == first)
- return;
+ continue contours;
} while (end.getOrigX() == first.getOrigX()
&& end.getOrigY() == first.getOrigY());
-
- // Extend segment whenever possible.
+
+ // Extend segment start whenever possible.
Point before = start;
int angleIn;
int angleSeg = Utils.atan(end.getOrigX() - start.getOrigX(),
end.getOrigY() - start.getOrigY());
do
{
do
{
start = before;
before = before.getPrev();
if (before == first)
- return;
+ continue contours;
} while (before.getOrigX() == start.getOrigX()
&& before.getOrigY() == start.getOrigY());
angleIn = Utils.atan(start.getOrigX() - before.getOrigX(),
start.getOrigY() - before.getOrigY());
} while (angleIn == angleSeg);
+
first = start;
int diffIn = Utils.angleDiff(angleIn, angleSeg);
// Now, process all segments in the contour.
Point after;
boolean finished = false;
int angleOut, diffOut;
do
{
// First, extend the current segment's end whenever possible.
after = end;
do
{
do
{
end = after;
@@ -494,41 +495,41 @@
int u, ou, fu, delta;
if (dim == DIMENSION_VERT)
{
u = point.getOrigY();
ou = point.getScaledY();
}
else
{
u = point.getOrigX();
ou = point.getScaledX();
}
fu = u;
// Is the point before the first edge?
Edge edge = edges[0];
// Inversed vertical dimension.
- delta = dim == DIMENSION_HORZ ? edge.fpos - u : u - edge.fpos;
+ delta = edge.fpos - u;
if (delta >= 0)
{
u = edge.pos - (edge.opos - ou);
storePoint(point, u, dim, touchFlag);
}
else
{
// Is the point after the last edge?
edge = edges[numEdges - 1];
- delta = dim == DIMENSION_HORZ ? u - edge.fpos : edge.fpos - u;
+ delta = u - edge.fpos;
if (delta >= 0)
{
u = edge.pos + (ou - edge.opos);
storePoint(point, u, dim, touchFlag);
}
else
{
// Find enclosing edges.
int min = 0;
int max = numEdges;
int mid, fpos;
boolean found = false;
while (min < max)
{
mid = (max + min) / 2;
Index: gnu/java/awt/font/autofit/Utils.java
===================================================================
RCS file: /cvsroot/classpath/classpath/gnu/java/awt/font/autofit/Utils.java,v
retrieving revision 1.3
diff -u -1 -5 -r1.3 Utils.java
--- gnu/java/awt/font/autofit/Utils.java 15 Dec 2006 00:59:46 -0000 1.3
+++ gnu/java/awt/font/autofit/Utils.java 4 Jan 2007 10:29:04 -0000
@@ -73,32 +73,33 @@
46, 46, 46, 46, 46, 47, 47, 47,
47, 48, 48, 48, 48, 48, 49, 49,
49, 49, 50, 50, 50, 50, 50, 51,
51, 51, 51, 51, 52, 52, 52, 52,
52, 53, 53, 53, 53, 53, 54, 54,
54, 54, 54, 55, 55, 55, 55, 55,
56, 56, 56, 56, 56, 57, 57, 57,
57, 57, 57, 58, 58, 58, 58, 58,
59, 59, 59, 59, 59, 59, 60, 60,
60, 60, 60, 61, 61, 61, 61, 61,
61, 62, 62, 62, 62, 62, 62, 63,
63, 63, 63, 63, 63, 64, 64, 64
};
private static final int ANGLE_PI = 256;
+ private static final int ANGLE_PI2 = ANGLE_PI / 2;
+ private static final int ANGLE_PI4 = ANGLE_PI / 4;
private static final int ANGLE_2PI = ANGLE_PI * 2;
- private static final int ANGLE_4PI = ANGLE_PI * 4;
/**
* Computes the direction constant for the specified vector. The vector is
* given as differential value already.
*
* @param dx the x vector
* @param dy the y vector
*
* @return the direction of that vector, or DIR_NONE, if that vector is not
* approximating against one of the major axises
*/
static int computeDirection(int dx, int dy)
{
int dir = DIR_NONE;
if (dx < 0)
@@ -139,72 +140,77 @@
}
public static int atan(int dx, int dy)
{
int angle;
// Trivial cases.
if (dy == 0)
{
angle = 0;
if (dx < 0)
angle = ANGLE_PI;
return angle;
}
else if (dx == 0)
{
- angle = ANGLE_2PI;
+ angle = ANGLE_PI2;
if (dy < 0)
- angle = - ANGLE_2PI;
+ angle = - ANGLE_PI2;
return angle;
}
angle = 0;
if (dx < 0)
{
dx = -dx;
dy = -dy;
angle = ANGLE_PI;
}
if (dy < 0)
{
int tmp = dx;
dx = -dy;
dy = tmp;
- angle = - ANGLE_2PI;
+ angle -= ANGLE_PI2;
}
if (dx == 0 && dy == 0)
return 0;
+
if (dx == dy)
- angle += ANGLE_4PI;
+ angle += ANGLE_PI4;
else if (dx > dy)
- angle += ATAN[Fixed.div(dy, dx) >> (26 - ATAN_BITS)];
+ {
+ angle += ATAN[Fixed.div(dy, dx) << (ATAN_BITS - 6)];
+ }
else
- angle += ANGLE_2PI - ATAN[Fixed.div(dx, dy) >> (26 - ATAN_BITS)];
+ {
+ angle += ANGLE_PI2 - ATAN[Fixed.div(dx, dy) << (ATAN_BITS - 6)];
+ }
- if (angle > Math.PI)
+ if (angle > ANGLE_PI)
angle -= ANGLE_2PI;
return angle;
}
public static int angleDiff(int ang1, int ang2)
{
int delta = ang2 - ang1;
delta %= ANGLE_2PI;
if (delta < 0)
delta += ANGLE_2PI;
- if (delta > ANGLE_2PI)
+ if (delta > ANGLE_PI)
delta -= ANGLE_2PI;
return delta;
}
static void sort(int num, int[] array)
{
int swap;
for (int i = 1; i < num; i++)
{
for (int j = i; j > 0; j--)
{
if (array[j] > array[j - 1])
break;
swap = array[j];
array[j] = array[j - 1];