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];

Reply via email to