[xorg-commit-diffs] xc/extras/freetype2/src/autohint ahglobal.c, 1.1.4.1, 1.1.4.2 ahglobal.h, 1.1.4.1, 1.1.4.2 ahglyph.c, 1.1.4.1, 1.1.4.2 ahhint.c, 1.1.4.1, 1.1.4.2 ahloader.h, 1.1.4.1, 1.1.4.2 ahmodule.c, 1.1.4.1, 1.1.4.2 ahtypes.h, 1.1.4.1, 1.1.4.2 rules.mk, 1.1, 1.1.4.1 ahoptim.c, 1.1.4.1, NONE ahoptim.h, 1.1.4.1, NONE descrip.mms, 1.1, NONE

Egbert Eich xorg-commit at pdx.freedesktop.org
Thu Apr 15 03:14:34 PDT 2004


Committed by: eich

Update of /cvs/xorg/xc/extras/freetype2/src/autohint
In directory pdx:/home/eich/tstbuild/xc/extras/freetype2/src/autohint

Modified Files:
      Tag: XORG-CURRENT
	ahglobal.c ahglobal.h ahglyph.c ahhint.c ahloader.h ahmodule.c 
	ahtypes.h rules.mk 
Removed Files:
      Tag: XORG-CURRENT
	ahoptim.c ahoptim.h descrip.mms 
Log Message:
2004-04-15  Egbert Eich  <eich at freedesktop.org>
        Merged changes from RELEASE-1 branch
	


Index: ahglobal.c
===================================================================
RCS file: /cvs/xorg/xc/extras/freetype2/src/autohint/ahglobal.c,v
retrieving revision 1.1.4.1
retrieving revision 1.1.4.2
diff -u -d -r1.1.4.1 -r1.1.4.2
--- a/ahglobal.c	26 Nov 2003 22:48:25 -0000	1.1.4.1
+++ b/ahglobal.c	15 Apr 2004 10:14:30 -0000	1.1.4.2
@@ -4,7 +4,7 @@
 /*                                                                         */
 /*    Routines used to compute global metrics automatically (body).        */
 /*                                                                         */
-/*  Copyright 2000-2001, 2002 Catharon Productions Inc.                    */
+/*  Copyright 2000-2001, 2002, 2003 Catharon Productions Inc.              */
 /*  Author: David Turner                                                   */
 /*                                                                         */
 /*  This file is part of the Catharon Typography Project and shall only    */
@@ -27,8 +27,10 @@
 
 #define MAX_TEST_CHARACTERS  12
 
+  /* cf. AH_BLUE_XXX constants in ahtypes.h */
+
   static
-  const char*  blue_chars[AH_BLUE_MAX] =
+  const char* const  blue_chars[AH_BLUE_MAX] =
   {
     "THEZOCQS",
     "HEZLOCUS",
@@ -93,8 +95,8 @@
       goto Exit;
 
     /* we compute the blues simply by loading each character from the */
-    /* 'blue_chars[blues]' string, then compute its top-most and      */
-    /* bottom-most points                                             */
+    /* 'blue_chars[blues]' string, then compute its top-most or       */
+    /* bottom-most points (depending on `AH_IS_TOP_BLUE')             */
 
     AH_LOG(( "blue zones computation\n" ));
     AH_LOG(( "------------------------------------------------\n" ));
@@ -103,6 +105,7 @@
     {
       const char*  p     = blue_chars[blue];
       const char*  limit = p + MAX_TEST_CHARACTERS;
+
       FT_Pos       *blue_ref, *blue_shoot;
 
 
@@ -235,8 +238,8 @@
       AH_LOG(( "\n" ));
 
       /* we have computed the contents of the `rounds' and `flats' tables, */
-      /* now determine the reference and overshoot position of the blue;   */
-      /* we simply take the median value after a simple short              */
+      /* now determine the reference and overshoot position of the blue -- */
+      /* we simply take the median value after a simple sort               */
       sort_values( num_rounds, rounds );
       sort_values( num_flats,  flats  );
 
@@ -312,7 +315,7 @@
     /* stem height of the "-", but it wasn't too good.  Moreover, we now */
     /* have a single character that gives us standard width and height.  */
     {
-      FT_UInt   glyph_index;
+      FT_UInt  glyph_index;
 
 
       glyph_index = FT_Get_Char_Index( hinter->face, 'o' );
@@ -323,7 +326,8 @@
       if ( error )
         goto Exit;
 
-      error = ah_outline_load( hinter->glyph, 0x10000L, 0x10000L, hinter->face );
+      error = ah_outline_load( hinter->glyph, 0x10000L, 0x10000L,
+                               hinter->face );
       if ( error )
         goto Exit;
 
@@ -375,7 +379,7 @@
     }
 
     /* Now, compute the edge distance threshold as a fraction of the */
-    /* smallest width in the font. Set it in `hinter.glyph' too!     */
+    /* smallest width in the font. Set it in `hinter->glyph' too!    */
     if ( edge_distance_threshold == 32000 )
       edge_distance_threshold = 50;
 

Index: ahglobal.h
===================================================================
RCS file: /cvs/xorg/xc/extras/freetype2/src/autohint/ahglobal.h,v
retrieving revision 1.1.4.1
retrieving revision 1.1.4.2
diff -u -d -r1.1.4.1 -r1.1.4.2
--- a/ahglobal.h	26 Nov 2003 22:48:25 -0000	1.1.4.1
+++ b/ahglobal.h	15 Apr 2004 10:14:30 -0000	1.1.4.2
@@ -5,7 +5,7 @@
 /*    Routines used to compute global metrics automatically                */
 /*    (specification).                                                     */
 /*                                                                         */
-/*  Copyright 2000-2001, 2002 Catharon Productions Inc.                    */
+/*  Copyright 2000-2001, 2002, 2003 Catharon Productions Inc.              */
 /*  Author: David Turner                                                   */
 /*                                                                         */
 /*  This file is part of the Catharon Typography Project and shall only    */
@@ -34,16 +34,16 @@
 
 #ifdef  FT_CONFIG_CHESTER_SMALL_F
 
-#  define AH_IS_TOP_BLUE( b )  ( (b) == AH_BLUE_CAPITAL_TOP || \
-                                 (b) == AH_BLUE_SMALL_F_TOP || \
-                                 (b) == AH_BLUE_SMALL_TOP   )
+#define AH_IS_TOP_BLUE( b )  ( (b) == AH_BLUE_CAPITAL_TOP || \
+                               (b) == AH_BLUE_SMALL_F_TOP || \
+                               (b) == AH_BLUE_SMALL_TOP   )
 
-#else /* !CHESTER_SMALL_F */
+#else /* !FT_CONFIG_CHESTER_SMALL_F */
 
-#  define AH_IS_TOP_BLUE( b )  ( (b) == AH_BLUE_CAPITAL_TOP || \
-                                 (b) == AH_BLUE_SMALL_TOP   )
+#define AH_IS_TOP_BLUE( b )  ( (b) == AH_BLUE_CAPITAL_TOP || \
+                               (b) == AH_BLUE_SMALL_TOP   )
 
-#endif /* !CHESTER_SMALL_F */
+#endif /* !FT_CONFIG_CHESTER_SMALL_F */
 
 
   /* compute global metrics automatically */

Index: ahglyph.c
===================================================================
RCS file: /cvs/xorg/xc/extras/freetype2/src/autohint/ahglyph.c,v
retrieving revision 1.1.4.1
retrieving revision 1.1.4.2
diff -u -d -r1.1.4.1 -r1.1.4.2
--- a/ahglyph.c	26 Nov 2003 22:48:25 -0000	1.1.4.1
+++ b/ahglyph.c	15 Apr 2004 10:14:30 -0000	1.1.4.2
@@ -5,7 +5,7 @@
 /*    Routines used to load and analyze a given glyph before hinting       */
 /*    (body).                                                              */
 /*                                                                         */
-/*  Copyright 2000-2001, 2002 Catharon Productions Inc.                    */
+/*  Copyright 2000-2001, 2002, 2003 Catharon Productions Inc.              */
 /*  Author: David Turner                                                   */
 /*                                                                         */
 /*  This file is part of the Catharon Typography Project and shall only    */
@@ -120,8 +120,8 @@
                                : ( seg->dir == AH_DIR_RIGHT
                                      ? "right"
                                      : "none" ) ) ),
-                 seg->link ? (seg->link-segments) : -1,
-                 seg->serif ? (seg->serif-segments) : -1,
+                 seg->link ? ( seg->link - segments ) : -1,
+                 seg->serif ? ( seg->serif - segments ) : -1,
                  (int)seg->num_linked,
                  seg->first - points,
                  seg->last - points );
@@ -135,7 +135,7 @@
 #endif /* AH_DEBUG */
 
 
-  /* compute the direction value of a given vector.. */
+  /* compute the direction value of a given vector */
   static AH_Direction
   ah_compute_direction( FT_Pos  dx,
                         FT_Pos  dy )
@@ -147,6 +147,8 @@
 
     dir = AH_DIR_NONE;
 
+    /* atan(1/12) == 4.7 degrees */
+
     /* test for vertical direction */
     if ( ax * 12 < ay )
     {
@@ -163,10 +165,10 @@
 
 
   /* this function is used by ah_get_orientation (see below) to test */
-  /* the fill direction of a given bbox extrema                      */
+  /* the fill direction of given bbox extremum                       */
   static FT_Int
-  ah_test_extrema( FT_Outline*  outline,
-                   FT_Int       n )
+  ah_test_extremum( FT_Outline*  outline,
+                    FT_Int       n )
   {
     FT_Vector  *prev, *cur, *next;
     FT_Pos      product;
@@ -175,7 +177,9 @@
 
 
     /* we need to compute the `previous' and `next' point */
-    /* for these extrema                                  */
+    /* for this extremum; we check whether the extremum   */
+    /* is start or end of a contour and providing         */
+    /* appropriate values if so                           */
     cur  = outline->points + n;
     prev = cur - 1;
     next = cur + 1;
@@ -183,7 +187,7 @@
     first = 0;
     for ( c = 0; c < outline->n_contours; c++ )
     {
-      last  = outline->contours[c];
+      last = outline->contours[c];
 
       if ( n == first )
         prev = outline->points + last;
@@ -194,6 +198,10 @@
       first = last + 1;
     }
 
+    /* compute the vectorial product -- since we know that the angle */
+    /* is <= 180 degrees (otherwise it wouldn't be an extremum) we   */
+    /* can determine the filling orientation if the product is       */
+    /* either positive or negative                                   */
     product = FT_MulDiv( cur->x  - prev->x,  /* in.x  */
                          next->y - cur->y,   /* out.y */
                          0x40 )
@@ -218,7 +226,7 @@
   /* We do this by computing bounding box points, and computing their      */
   /* curvature.                                                            */
   /*                                                                       */
-  /* The function returns either 1 or -1.                                  */
+  /* The function returns either 1 or 2.                                   */
   /*                                                                       */
   static FT_Int
   ah_get_orientation( FT_Outline*  outline )
@@ -272,20 +280,20 @@
       }
     }
 
-    /* test orientation of the xmin */
-    n = ah_test_extrema( outline, indices_xMin );
+    /* test orientation of the extrema */
+    n = ah_test_extremum( outline, indices_xMin );
     if ( n )
       goto Exit;
 
-    n = ah_test_extrema( outline, indices_yMin );
+    n = ah_test_extremum( outline, indices_yMin );
     if ( n )
       goto Exit;
 
-    n = ah_test_extrema( outline, indices_xMax );
+    n = ah_test_extremum( outline, indices_xMax );
     if ( n )
       goto Exit;
 
-    n = ah_test_extrema( outline, indices_yMax );
+    n = ah_test_extremum( outline, indices_yMax );
     if ( !n )
       n = 1;
 
@@ -306,14 +314,14 @@
   ah_outline_new( FT_Memory    memory,
                   AH_Outline*  aoutline )
   {
-    FT_Error     error;
-    AH_Outline   outline;
+    FT_Error    error;
+    AH_Outline  outline;
 
 
     if ( !FT_NEW( outline ) )
     {
       outline->memory = memory;
-      *aoutline = outline;
+      *aoutline       = outline;
     }
 
     return error;
@@ -452,7 +460,7 @@
 
     /* We can't rely on the value of `FT_Outline.flags' to know the fill  */
     /* direction used for a glyph, given that some fonts are broken (e.g. */
-    /* the Arphic ones). We thus recompute it each time we need to.       */
+    /* the Arphic ones).  We thus recompute it each time we need to.      */
     /*                                                                    */
     outline->vert_major_dir = AH_DIR_UP;
     outline->horz_major_dir = AH_DIR_LEFT;
@@ -479,7 +487,7 @@
 
       /* compute coordinates */
       {
-        FT_Vector*  vec     = source->points;
+        FT_Vector*  vec = source->points;
 
 
         for ( point = points; point < point_limit; vec++, point++ )
@@ -503,9 +511,11 @@
           switch ( FT_CURVE_TAG( *tag ) )
           {
           case FT_CURVE_TAG_CONIC:
-            point->flags = AH_FLAG_CONIC; break;
+            point->flags = AH_FLAG_CONIC;
+            break;
           case FT_CURVE_TAG_CUBIC:
-            point->flags = AH_FLAG_CUBIC; break;
+            point->flags = AH_FLAG_CUBIC;
+            break;
           default:
             ;
           }
@@ -585,7 +595,7 @@
           point->out_dir = ah_compute_direction( ovec.x, ovec.y );
 
 #ifndef AH_OPTION_NO_WEAK_INTERPOLATION
-          if ( point->flags & (AH_FLAG_CONIC | AH_FLAG_CUBIC) )
+          if ( point->flags & ( AH_FLAG_CONIC | AH_FLAG_CUBIC ) )
           {
           Is_Weak_Point:
             point->flags |= AH_FLAG_WEAK_INTERPOLATION;
@@ -631,48 +641,70 @@
     AH_Point  point_limit = point + outline->num_points;
 
 
-    for ( ; point < point_limit; point++ )
+    switch ( source )
     {
-      FT_Pos  u, v;
+    case AH_UV_FXY:
+      for ( ; point < point_limit; point++ )
+      {
+        point->u = point->fx;
+        point->v = point->fy;
+      }
+      break;
 
+    case AH_UV_FYX:
+      for ( ; point < point_limit; point++ )
+      {
+        point->u = point->fy;
+        point->v = point->fx;
+      }
+      break;
 
-      switch ( source )
+    case AH_UV_OXY:
+      for ( ; point < point_limit; point++ )
       {
-      case AH_UV_FXY:
-        u = point->fx;
-        v = point->fy;
-        break;
-      case AH_UV_FYX:
-        u = point->fy;
-        v = point->fx;
-        break;
-      case AH_UV_OXY:
-        u = point->ox;
-        v = point->oy;
-        break;
-      case AH_UV_OYX:
-        u = point->oy;
-        v = point->ox;
-        break;
-      case AH_UV_YX:
-        u = point->y;
-        v = point->x;
-        break;
-      case AH_UV_OX:
-        u = point->x;
-        v = point->ox;
-        break;
-      case AH_UV_OY:
-        u = point->y;
-        v = point->oy;
-        break;
-      default:
-        u = point->x;
-        v = point->y;
-        break;
+        point->u = point->ox;
+        point->v = point->oy;
+      }
+      break;
+
+    case AH_UV_OYX:
+      for ( ; point < point_limit; point++ )
+      {
+        point->u = point->oy;
+        point->v = point->ox;
+      }
+      break;
+
+    case AH_UV_YX:
+      for ( ; point < point_limit; point++ )
+      {
+        point->u = point->y;
+        point->v = point->x;
+      }
+      break;
+
+    case AH_UV_OX:
+      for ( ; point < point_limit; point++ )
+      {
+        point->u = point->x;
+        point->v = point->ox;
+      }
+      break;
+
+    case AH_UV_OY:
+      for ( ; point < point_limit; point++ )
+      {
+        point->u = point->y;
+        point->v = point->oy;
+      }
+      break;
+
+    default:
+      for ( ; point < point_limit; point++ )
+      {
+        point->u = point->x;
+        point->v = point->y;
       }
-      point->u = u;
-      point->v = v;
     }
   }
 
@@ -681,8 +713,8 @@
   static void
   ah_outline_compute_inflections( AH_Outline  outline )
   {
-    AH_Point*  contour       =  outline->contours;
-    AH_Point*  contour_limit =  contour + outline->num_contours;
+    AH_Point*  contour       = outline->contours;
+    AH_Point*  contour_limit = contour + outline->num_contours;
 
 
     /* load original coordinates in (u,v) */
@@ -692,10 +724,10 @@
     for ( ; contour < contour_limit; contour++ )
     {
       FT_Vector  vec;
-      AH_Point   point   = contour[0];
-      AH_Point   first   = point;
-      AH_Point   start   = point;
-      AH_Point   end     = point;
+      AH_Point   point = contour[0];
+      AH_Point   first = point;
+      AH_Point   start = point;
+      AH_Point   end   = point;
       AH_Point   before;
       AH_Point   after;
       AH_Angle   angle_in, angle_seg, angle_out;
@@ -769,7 +801,6 @@
         {
           /* diff_in and diff_out have different signs, we have */
           /* inflection points here...                          */
-
           do
           {
             start->flags |= AH_FLAG_INFLECTION;
@@ -829,10 +860,10 @@
       /* do each contour separately */
       for ( ; contour < contour_limit; contour++ )
       {
-        AH_Point  point   = contour[0];
-        AH_Point  last    = point->prev;
-        int       on_edge = 0;
-        FT_Pos    min_pos = +32000;  /* minimum segment pos != min_coord */
+        AH_Point  point   =  contour[0];
+        AH_Point  last    =  point->prev;
+        int       on_edge =  0;
+        FT_Pos    min_pos =  32000;  /* minimum segment pos != min_coord */
         FT_Pos    max_pos = -32000;  /* maximum segment pos != max_coord */
         FT_Bool   passed;
 
@@ -850,7 +881,7 @@
         }
 #endif
 
-        if ( point == last )  /* skip singletons -- just in case? */
+        if ( point == last )  /* skip singletons -- just in case */
           continue;
 
         if ( ABS( last->out_dir )  == major_dir &&
@@ -941,6 +972,8 @@
             segment->first    = point;
             segment->last     = point;
             segment->contour  = contour;
+            segment->score    = 32000;
+            segment->link     = NULL;
             on_edge           = 1;
 
 #ifdef AH_HINT_METRICS
@@ -963,11 +996,11 @@
       /* we do this by inserting fake segments when needed            */
       if ( dimension == 0 )
       {
-        AH_Point  point       =  outline->points;
-        AH_Point  point_limit =  point + outline->num_points;
+        AH_Point  point       = outline->points;
+        AH_Point  point_limit = point + outline->num_points;
 
-        FT_Pos    min_pos     =  32000;
-        FT_Pos    max_pos     = -32000;
+        FT_Pos    min_pos =  32000;
+        FT_Pos    max_pos = -32000;
 
 
         min_point = 0;
@@ -1002,6 +1035,8 @@
           segment->first = min_point;
           segment->last  = min_point;
           segment->pos   = min_pos;
+          segment->score = 32000;
+          segment->link  = NULL;
 
           num_segments++;
           segment++;
@@ -1018,6 +1053,8 @@
           segment->first = max_point;
           segment->last  = max_point;
           segment->pos   = max_pos;
+          segment->score = 32000;
+          segment->link  = NULL;
 
           num_segments++;
           segment++;
@@ -1030,6 +1067,7 @@
       segments       = outline->vert_segments;
       major_dir      = AH_DIR_UP;
       p_num_segments = &outline->num_vsegments;
+
       ah_setup_uv( outline, AH_UV_FXY );
     }
   }
@@ -1038,22 +1076,22 @@
   FT_LOCAL_DEF( void )
   ah_outline_link_segments( AH_Outline  outline )
   {
-    AH_Segment  segments;
-    AH_Segment  segment_limit;
-    int         dimension;
-
+    AH_Segment    segments;
+    AH_Segment    segment_limit;
+    AH_Direction  major_dir;
+    int           dimension;
 
-    ah_setup_uv( outline, AH_UV_FYX );
 
     segments      = outline->horz_segments;
     segment_limit = segments + outline->num_hsegments;
+    major_dir     = outline->horz_major_dir;
 
     for ( dimension = 1; dimension >= 0; dimension-- )
     {
       AH_Segment  seg1;
       AH_Segment  seg2;
 
-
+#if 0
       /* now compare each segment to the others */
       for ( seg1 = segments; seg1 < segment_limit; seg1++ )
       {
@@ -1070,7 +1108,7 @@
         if ( best_segment )
           best_score = seg1->score;
         else
-          best_score = 32000;
+          best_score = +32000;
 
         for ( seg2 = segments; seg2 < segment_limit; seg2++ )
           if ( seg1 != seg2 && seg1->dir + seg2->dir == 0 )
@@ -1125,28 +1163,86 @@
         {
           seg1->link  = best_segment;
           seg1->score = best_score;
-
           best_segment->num_linked++;
         }
+      }
+#endif /* 0 */
 
-      } /* edges 1 */
+#if 1
+      /* the following code does the same, but much faster! */
+
+      /* now compare each segment to the others */
+      for ( seg1 = segments; seg1 < segment_limit; seg1++ )
+      {
+        /* the fake segments are introduced to hint the metrics -- */
+        /* we must never link them to anything                     */
+        if ( seg1->first == seg1->last || seg1->dir != major_dir )
+          continue;
+
+        for ( seg2 = segments; seg2 < segment_limit; seg2++ )
+          if ( seg2 != seg1 && seg1->dir + seg2->dir == 0 )
+          {
+            FT_Pos  pos1 = seg1->pos;
+            FT_Pos  pos2 = seg2->pos;
+            FT_Pos  dist = pos2 - pos1;
+
+
+            if ( dist < 0 )
+              continue;
+
+            {
+              FT_Pos  min = seg1->min_coord;
+              FT_Pos  max = seg1->max_coord;
+              FT_Pos  len, score;
+
+
+              if ( min < seg2->min_coord )
+                min = seg2->min_coord;
+
+              if ( max > seg2->max_coord )
+                max = seg2->max_coord;
+
+              len = max - min;
+              if ( len >= 8 )
+              {
+                score = dist + 3000 / len;
+
+                if ( score < seg1->score )
+                {
+                  seg1->score = score;
+                  seg1->link  = seg2;
+                }
+
+                if ( score < seg2->score )
+                {
+                  seg2->score = score;
+                  seg2->link  = seg1;
+                }
+              }
+            }
+          }
+      }
+#endif /* 1 */
 
       /* now, compute the `serif' segments */
       for ( seg1 = segments; seg1 < segment_limit; seg1++ )
       {
         seg2 = seg1->link;
 
-        if ( seg2 && seg2->link != seg1 )
+        if ( seg2 )
         {
-          seg1->link  = 0;
-          seg1->serif = seg2->link;
+          seg2->num_linked++;
+          if ( seg2->link != seg1 )
+          {
+            seg1->link  = 0;
+            seg1->serif = seg2->link;
+          }
         }
       }
 
-      ah_setup_uv( outline, AH_UV_FXY );
-
       segments      = outline->vert_segments;
       segment_limit = segments + outline->num_vsegments;
+      major_dir     = outline->vert_major_dir;
     }
   }
 
@@ -1199,6 +1295,9 @@
       if ( edge_distance_threshold > 64 / 4 )
         edge_distance_threshold = 64 / 4;
 
+      edge_distance_threshold = FT_DivFix( edge_distance_threshold,
+                                           scale );
+
       edge_limit = edges;
       for ( seg = segments; seg < segment_limit; seg++ )
       {
@@ -1215,7 +1314,6 @@
           if ( dist < 0 )
             dist = -dist;
 
-          dist = FT_MulFix( dist, scale );
           if ( dist < edge_distance_threshold )
           {
             found = edge;
@@ -1253,7 +1351,6 @@
           edge->last            = seg;
         }
       }
-
       *p_num_edges = (FT_Int)( edge_limit - edges );
 
 
@@ -1264,13 +1361,19 @@
       /*                                                                   */
       /*  - edge's main direction                                          */
       /*  - stem edge, serif edge or both (which defaults to stem then)    */
-      /*  - rounded edge, straigth or both (which defaults to straight)    */
+      /*  - rounded edge, straight or both (which defaults to straight)    */
       /*  - link for edge                                                  */
       /*                                                                   */
       /*********************************************************************/
 
       /* first of all, set the `edge' field in each segment -- this is */
       /* required in order to compute edge links                       */
+
+      /* Note that I've tried to remove this loop, setting
+       * the "edge" field of each segment directly in the
+       * code above.  For some reason, it slows down execution
+       * speed -- on a Sun.
+       */
       for ( edge = edges; edge < edge_limit; edge++ )
       {
         seg = edge->first;
@@ -1358,12 +1461,12 @@
             }
             else
               edge->link  = edge2;
-#else /* !CHESTER_SERIF */
+#else /* !FT_CONFIG_CHESTER_SERIF */
             if ( is_serif )
               edge->serif = edge2;
             else
               edge->link  = edge2;
-#endif
+#endif /* !FT_CONFIG_CHESTER_SERIF */
           }
 
           seg = seg->edge_next;
@@ -1383,10 +1486,10 @@
           edge->dir = up_dir;
 
         else if ( ups < downs )
-          edge->dir = - up_dir;
+          edge->dir = -up_dir;
 
         else if ( ups == downs )
-          edge->dir = 0;  /* both up and down !! */
+          edge->dir = 0;  /* both up and down! */
 
         /* gets rid of serifs if link is set                */
         /* XXX: This gets rid of many unpleasant artefacts! */
@@ -1459,7 +1562,7 @@
 
         ref   = globals->blue_refs[blue];
         shoot = globals->blue_shoots[blue];
-        dist  = ref-shoot;
+        dist  = ref - shoot;
         if ( dist < 0 )
           dist = -dist;
 
@@ -1477,7 +1580,7 @@
         return;
     }
 
-    /* compute for each horizontal edge, which blue zone is closer */
+    /* for each horizontal edge search the blue zone which is closest */
     for ( ; edge < edge_limit; edge++ )
     {
       AH_Blue  blue;
@@ -1493,7 +1596,7 @@
         best_dist = 64 / 2;
 #else
       if ( best_dist > 64 / 4 )
-         best_dist = 64 / 4;
+        best_dist = 64 / 4;
 #endif
 
       for ( blue = AH_BLUE_CAPITAL_TOP; blue < AH_BLUE_MAX; blue++ )
@@ -1507,6 +1610,7 @@
         FT_Bool  is_major_dir =
                    FT_BOOL( edge->dir == outline->horz_major_dir );
 
+
         if ( !blue_active[blue] )
           continue;
 
@@ -1569,7 +1673,7 @@
   /*    ah_outline_scale_blue_edges                                        */
   /*                                                                       */
   /* <Description>                                                         */
-  /*    This functions must be called before hinting in order to re-adjust */
+  /*    This function must be called before hinting in order to re-adjust  */
   /*    the contents of the detected edges (basically change the `blue     */
   /*    edge' pointer from `design units' to `scaled ones').               */
   /*                                                                       */

Index: ahhint.c
===================================================================
RCS file: /cvs/xorg/xc/extras/freetype2/src/autohint/ahhint.c,v
retrieving revision 1.1.4.1
retrieving revision 1.1.4.2
diff -u -d -r1.1.4.1 -r1.1.4.2
--- a/ahhint.c	24 Feb 2004 03:33:08 -0000	1.1.4.1
+++ b/ahhint.c	15 Apr 2004 10:14:30 -0000	1.1.4.2
@@ -4,7 +4,7 @@
 /*                                                                         */
 /*    Glyph hinter (body).                                                 */
 /*                                                                         */
-/*  Copyright 2000-2001, 2002 Catharon Productions Inc.                    */
+/*  Copyright 2000-2001, 2002, 2003 Catharon Productions Inc.              */
 /*  Author: David Turner                                                   */
 /*                                                                         */
 /*  This file is part of the Catharon Typography Project and shall only    */
@@ -27,11 +27,12 @@
 #include FT_OUTLINE_H
 
 
-#define FACE_GLOBALS( face )  ((AH_Face_Globals)(face)->autohint.data)
+#define FACE_GLOBALS( face )  ( (AH_Face_Globals)(face)->autohint.data )
 
 #define AH_USE_IUP
 #define OPTIM_STEM_SNAP
 
+
   /*************************************************************************/
   /*************************************************************************/
   /****                                                                 ****/
@@ -70,7 +71,7 @@
       }
     }
 
-    scaled = (reference+32) & -64;
+    scaled = ( reference + 32 ) & -64;
 
     if ( width >= reference )
     {
@@ -88,7 +89,9 @@
 
 
   /* compute the snapped width of a given stem */
+
 #ifdef FT_CONFIG_CHESTER_SERIF
+
   static FT_Pos
   ah_compute_stem_width( AH_Hinter      hinter,
                          int            vertical,
@@ -114,7 +117,7 @@
     else if ( (  vertical && !hinter->do_vert_snapping ) ||
               ( !vertical && !hinter->do_horz_snapping ) )
     {
-      /* smooth hinting process, very lightly quantize the stem width */
+      /* smooth hinting process: very lightly quantize the stem width */
       /*                                                              */
 
       /* leave the widths of serifs alone */
@@ -148,8 +151,8 @@
 
         if ( dist < 3 * 64 )
         {
-          delta = ( dist & 63 );
-          dist &= -64;
+          delta  = dist & 63;
+          dist  &= -64;
 
           if ( delta < 10 )
             dist += delta;
@@ -169,7 +172,7 @@
     }
     else
     {
-      /* strong hinting process, snap the stem width to integer pixels */
+      /* strong hinting process: snap the stem width to integer pixels */
       /*                                                               */
       if ( vertical )
       {
@@ -184,7 +187,7 @@
       }
       else
       {
-        dist = ah_snap_width( globals->widths,  globals->num_widths, dist );
+        dist = ah_snap_width( globals->widths, globals->num_widths, dist );
 
         if ( hinter->flags & AH_HINTER_MONOCHROME )
         {
@@ -206,7 +209,7 @@
           else if ( dist < 128 )
             dist = ( dist + 22 ) & -64;
           else
-            /* XXX: round otherwise, prevent color fringes in LCD mode */
+            /* XXX: round otherwise to prevent color fringes in LCD mode */
             dist = ( dist + 32 ) & -64;
         }
       }
@@ -218,7 +221,9 @@
 
     return dist;
   }
-#else /* !CHESTER_SERIF */
+
+#else /* !FT_CONFIG_CHESTER_SERIF */
+
   static FT_Pos
   ah_compute_stem_width( AH_Hinter  hinter,
                          int        vertical,
@@ -242,7 +247,7 @@
     else if ( (  vertical && !hinter->do_vert_snapping ) ||
               ( !vertical && !hinter->do_horz_snapping ) )
     {
-      /* smooth hinting process, very lightly quantize the stem width */
+      /* smooth hinting process: very lightly quantize the stem width */
       /*                                                              */
       if ( dist < 64 )
         dist = 64;
@@ -263,8 +268,8 @@
 
         if ( dist < 3 * 64 )
         {
-          delta = ( dist & 63 );
-          dist &= -64;
+          delta  = dist & 63;
+          dist  &= -64;
 
           if ( delta < 10 )
             dist += delta;
@@ -284,7 +289,7 @@
     }
     else
     {
-      /* strong hinting process, snap the stem width to integer pixels */
+      /* strong hinting process: snap the stem width to integer pixels */
       /*                                                               */
       if ( vertical )
       {
@@ -299,7 +304,7 @@
       }
       else
       {
-        dist = ah_snap_width( globals->widths,  globals->num_widths, dist );
+        dist = ah_snap_width( globals->widths, globals->num_widths, dist );
 
         if ( hinter->flags & AH_HINTER_MONOCHROME )
         {
@@ -321,7 +326,7 @@
           else if ( dist < 128 )
             dist = ( dist + 22 ) & -64;
           else
-            /* XXX: round otherwise, prevent color fringes in LCD mode */
+            /* XXX: round otherwise to prevent color fringes in LCD mode */
             dist = ( dist + 32 ) & -64;
         }
       }
@@ -332,7 +337,8 @@
 
     return dist;
   }
-#endif /* !CHESTER_SERIF */
+
+#endif /* !FT_CONFIG_CHESTER_SERIF */
 
 
   /* align one stem edge relative to the previous stem edge */
@@ -345,17 +351,23 @@
     FT_Pos  dist = stem_edge->opos - base_edge->opos;
 
 #ifdef FT_CONFIG_CHESTER_SERIF
+
     FT_Pos  fitted_width = ah_compute_stem_width( hinter,
                                                   vertical,
                                                   dist,
                                                   base_edge->flags,
                                                   stem_edge->flags );
 
+
     stem_edge->pos = base_edge->pos + fitted_width;
+
 #else
+
     stem_edge->pos = base_edge->pos +
                      ah_compute_stem_width( hinter, vertical, dist );
+
 #endif
+
   }
 
 
@@ -371,6 +383,7 @@
     FT_UNUSED( hinter );
     FT_UNUSED( vertical );
 
+
     dist = serif->opos - base->opos;
     if ( dist < 0 )
     {
@@ -378,15 +391,16 @@
       sign = -1;
     }
 
-    /* do not touch serifs widths !! */
 #if 0
+    /* do not touch serifs widths! */
     if ( base->flags & AH_EDGE_DONE )
     {
       if ( dist >= 64 )
-        dist = (dist+8) & -64;
+        dist = ( dist + 8 ) & -64;
 
       else if ( dist <= 32 && !vertical )
         dist = ( dist + 33 ) >> 1;
+
       else
         dist = 0;
     }
@@ -407,14 +421,14 @@
   /*************************************************************************/
 
 
-  /* Another alternative edge hinting algorithm */
-  static void
-  ah_hint_edges_3( AH_Hinter  hinter )
+  FT_LOCAL_DEF( void )
+  ah_hinter_hint_edges( AH_Hinter  hinter )
   {
     AH_Edge     edges;
     AH_Edge     edge_limit;
     AH_Outline  outline = hinter->glyph;
     FT_Int      dimension;
+    FT_Int      n_edges;
 
 
     edges      = outline->horz_edges;
@@ -454,7 +468,7 @@
           {
             edge1 = edge;
           }
-          else if (edge2 && edge2->blue_edge)
+          else if ( edge2 && edge2->blue_edge )
           {
             blue  = edge2->blue_edge;
             edge1 = edge2;
@@ -478,8 +492,8 @@
         }
       }
 
-      /* now, we will align all stem edges, trying to maintain the */
-      /* relative order of stems in the glyph..                    */
+      /* now we will align all stem edges, trying to maintain the */
+      /* relative order of stems in the glyph                     */
       for ( edge = edges; edge < edge_limit; edge++ )
       {
         AH_EdgeRec*  edge2;
@@ -496,12 +510,11 @@
           continue;
         }
 
-        /* now, align the stem */
+        /* now align the stem */
 
-        /* this should not happen, but it's better to be safe. */
+        /* this should not happen, but it's better to be safe */
         if ( edge2->blue_edge || edge2 < edge )
         {
-
           ah_align_linked_edge( hinter, edge2, edge, dimension );
           edge->flags |= AH_EDGE_DONE;
           continue;
@@ -509,15 +522,18 @@
 
         if ( !anchor )
         {
+
 #ifdef FT_CONFIG_CHESTER_STEM
-          FT_Pos   org_len, org_center, cur_len;
-          FT_Pos   cur_pos1, error1, error2, u_off, d_off;
 
-          org_len    = edge2->opos - edge->opos;
-          cur_len    = ah_compute_stem_width( hinter, dimension, org_len,
-                                              edge->flags, edge2->flags   );
+          FT_Pos  org_len, org_center, cur_len;
+          FT_Pos  cur_pos1, error1, error2, u_off, d_off;
 
-          if (cur_len <= 64 )
+
+          org_len = edge2->opos - edge->opos;
+          cur_len = ah_compute_stem_width( hinter, dimension, org_len,
+                                           edge->flags, edge2->flags );
+
+          if ( cur_len <= 64 )
             u_off = d_off = 32;
           else
           {
@@ -551,44 +567,54 @@
           else
             edge->pos = ( edge->opos + 32 ) & -64;
 
-          anchor    = edge;
+          anchor = edge;
 
           edge->flags |= AH_EDGE_DONE;
 
           ah_align_linked_edge( hinter, edge, edge2, dimension );
-#else /* !CHESTER_STEM */
+
+#else /* !FT_CONFIG_CHESTER_STEM */
+
           edge->pos = ( edge->opos + 32 ) & -64;
           anchor    = edge;
 
           edge->flags |= AH_EDGE_DONE;
 
           ah_align_linked_edge( hinter, edge, edge2, dimension );
-#endif /* !CHESTER_STEM */
+
+#endif /* !FT_CONFIG_CHESTER_STEM */
+
         }
         else
         {
-          FT_Pos   org_pos, org_len, org_center, cur_len;
-          FT_Pos   cur_pos1, cur_pos2, delta1, delta2;
+          FT_Pos  org_pos, org_len, org_center, cur_len;
+          FT_Pos  cur_pos1, cur_pos2, delta1, delta2;
 
 
-          org_pos    = anchor->pos + (edge->opos - anchor->opos);
+          org_pos    = anchor->pos + ( edge->opos - anchor->opos );
           org_len    = edge2->opos - edge->opos;
           org_center = org_pos + ( org_len >> 1 );
 
 #ifdef FT_CONFIG_CHESTER_SERIF
-          cur_len    = ah_compute_stem_width( hinter, dimension, org_len,
-                                              edge->flags, edge2->flags  );
-#else  /* !CHESTER_SERIF */
-          cur_len    = ah_compute_stem_width( hinter, dimension, org_len );
-#endif /* !CHESTER_SERIF */
+
+          cur_len = ah_compute_stem_width( hinter, dimension, org_len,
+                                           edge->flags, edge2->flags  );
+
+
+#else  /* !FT_CONFIG_CHESTER_SERIF */
+
+          cur_len = ah_compute_stem_width( hinter, dimension, org_len );
+
+#endif /* !FT_CONFIG_CHESTER_SERIF */
 
 #ifdef FT_CONFIG_CHESTER_STEM
+
           if ( cur_len < 96 )
           {
             FT_Pos  u_off, d_off;
 
 
-            cur_pos1   = ( org_center + 32 ) & -64;
+            cur_pos1 = ( org_center + 32 ) & -64;
 
             if (cur_len <= 64 )
               u_off = d_off = 32;
@@ -598,11 +624,11 @@
               d_off = 26;
             }
 
-            delta1 = org_center - (cur_pos1 - u_off);
+            delta1 = org_center - ( cur_pos1 - u_off );
             if ( delta1 < 0 )
               delta1 = -delta1;
 
-            delta2 = org_center - (cur_pos1 + d_off);
+            delta2 = org_center - ( cur_pos1 + d_off );
             if ( delta2 < 0 )
               delta2 = -delta2;
 
@@ -616,8 +642,7 @@
           }
           else
           {
-
-            org_pos    = anchor->pos + (edge->opos - anchor->opos);
+            org_pos    = anchor->pos + ( edge->opos - anchor->opos );
             org_len    = edge2->opos - edge->opos;
             org_center = org_pos + ( org_len >> 1 );
 
@@ -638,7 +663,7 @@
             edge2->pos = edge->pos + cur_len;
           }
 
-#else /* !CHESTER_STEM */
+#else /* !FT_CONFIG_CHESTER_STEM */
 
           cur_pos1   = ( org_pos + 32 ) & -64;
           delta1     = ( cur_pos1 + ( cur_len >> 1 ) - org_center );
@@ -653,7 +678,7 @@
           edge->pos  = ( delta1 <= delta2 ) ? cur_pos1 : cur_pos2;
           edge2->pos = edge->pos + cur_len;
 
-#endif /* !CHESTER_STEM */
+#endif /* !FT_CONFIG_CHESTER_STEM */
 
           edge->flags  |= AH_EDGE_DONE;
           edge2->flags |= AH_EDGE_DONE;
@@ -663,11 +688,73 @@
         }
       }
 
+      /* make sure that lowercase m's maintain their symmetry */
+
+      /* In general, lowercase m's have six vertical edges if they are sans */
+      /* serif, or twelve if they are avec serif.  This implementation is   */
+      /* based on that assumption, and seems to work very well with most    */
+      /* faces.  However, if for a certain face this assumption is not      */
+      /* true, the m is just rendered like before.  In addition, any stem   */
+      /* correction will only be applied to symmetrical glyphs (even if the */
+      /* glyph is not an m), so the potential for unwanted distortion is    */
+      /* relatively low.                                                    */
+
+      /* We don't handle horizontal edges since we can't easily assure that */
+      /* the third (lowest) stem aligns with the base line; it might end up */
+      /* one pixel higher or lower.                                         */
+
+      n_edges = edge_limit - edges;
+      if ( !dimension && ( n_edges == 6 || n_edges == 12 ) )
+      {
+        AH_EdgeRec  *edge1, *edge2, *edge3;
+        FT_Pos       dist1, dist2, span, delta;
+
+
+        if ( n_edges == 6 )
+        {
+          edge1 = edges;
+          edge2 = edges + 2;
+          edge3 = edges + 4;
+        }
+        else
+        {
+          edge1 = edges + 1;
+          edge2 = edges + 5;
+          edge3 = edges + 9;
+        }
+
+        dist1 = edge2->opos - edge1->opos;
+        dist2 = edge3->opos - edge2->opos;
+
+        span = dist1 - dist2;
+        if ( span < 0 )
+          span = -span;
+
+        if ( span < 8 )
+        {
+          delta = edge3->pos - ( 2 * edge2->pos - edge1->pos );
+          edge3->pos -= delta;
+          if ( edge3->link )
+            edge3->link->pos -= delta;
+
+          /* move the serifs along with the stem */
+          if ( n_edges == 12 )
+          {
+            ( edges + 8 )->pos -= delta;
+            ( edges + 11 )->pos -= delta;
+          }
+
+          edge3->flags |= AH_EDGE_DONE;
+          if ( edge3->link )
+            edge3->link->flags |= AH_EDGE_DONE;
+        }
+      }
+
       if ( !has_serifs )
         goto Next_Dimension;
 
-      /* now, hint the remaining edges (serifs and single) in order */
-      /* to complete our processing                                 */
+      /* now hint the remaining edges (serifs and single) in order */
+      /* to complete our processing                                */
       for ( edge = edges; edge < edge_limit; edge++ )
       {
         if ( edge->flags & AH_EDGE_DONE )
@@ -702,18 +789,6 @@
   }
 
 
-  FT_LOCAL_DEF( void )
-  ah_hinter_hint_edges( AH_Hinter  hinter )
-  {
-    /* AH_Interpolate_Blue_Edges( hinter ); -- doesn't seem to help      */
-    /* reduce the problem of the disappearing eye in the `e' of Times... */
-    /* also, creates some artifacts near the blue zones?                 */
-    {
-      ah_hint_edges_3( hinter );
-    }
-  }
-
-
   /*************************************************************************/
   /*************************************************************************/
   /*************************************************************************/
@@ -785,6 +860,7 @@
 
 
   /* hint the strong points -- this is equivalent to the TrueType `IP' */
+  /* hinting instruction                                               */
   static void
   ah_hinter_align_strong_points( AH_Hinter  hinter )
   {
@@ -850,7 +926,7 @@
             goto Store_Point;
           }
 
-          /* is the point after the last edge ? */
+          /* is the point after the last edge? */
           edge  = edge_limit - 1;
           delta = u - edge->fpos;
           if ( delta >= 0 )
@@ -859,6 +935,51 @@
             goto Store_Point;
           }
 
+#if 1
+          {
+            FT_UInt  min, max, mid;
+            FT_Pos   fpos;
+
+
+            /* find enclosing edges */
+            min = 0;
+            max = edge_limit - edges;
+
+            while ( min < max )
+            {
+              mid  = ( max + min ) >> 1;
+              edge = edges + mid;
+              fpos = edge->fpos;
+
+              if ( u < fpos )
+                max = mid;
+              else if ( u > fpos )
+                min = mid + 1;
+              else
+              {
+                /* we are on the edge */
+                u = edge->pos;
+                goto Store_Point;
+              }
+            }
+
+            {
+              AH_Edge  before = edges + min - 1;
+              AH_Edge  after  = edges + min + 0;
+
+
+              /* assert( before && after && before != after ) */
+              if ( before->scale == 0 )
+                before->scale = FT_DivFix( after->pos - before->pos,
+                                           after->fpos - before->fpos );
+
+              u = before->pos + FT_MulFix( fu - before->fpos,
+                                           before->scale );
+            }
+          }
+
+#else /* !0 */
+
           /* otherwise, interpolate the point in between */
           {
             AH_Edge  before = 0;
@@ -889,12 +1010,16 @@
               after = edge;
             }
 
-            /* assert( before && after && before != after ) */
-            u = before->pos + FT_MulDiv( fu - before->fpos,
-                                         after->pos - before->pos,
-                                         after->fpos - before->fpos );
+            if ( before->scale == 0 )
+              before->scale = FT_DivFix( after->pos - before->pos,
+                                        after->fpos - before->fpos );
+
+            u = before->pos + FT_MulFix( fu - before->fpos,
+                                        before->scale );
           }
 
+#endif /* !0 */
+
         Store_Point:
 
           /* save the point position */
@@ -1001,6 +1126,7 @@
 
 
   /* interpolate weak points -- this is equivalent to the TrueType `IUP' */
+  /* hinting instruction                                                 */
   static void
   ah_hinter_align_weak_points( AH_Hinter  hinter )
   {
@@ -1141,8 +1267,8 @@
   {
     FT_Int           n;
     AH_Face_Globals  globals = hinter->globals;
-    AH_Globals       design = &globals->design;
-    AH_Globals       scaled = &globals->scaled;
+    AH_Globals       design  = &globals->design;
+    AH_Globals       scaled  = &globals->scaled;
 
 
     /* copy content */
@@ -1211,7 +1337,7 @@
       ah_outline_done( hinter->glyph );
 
       /* note: the `globals' pointer is _not_ owned by the hinter */
-      /*       but by the current face object, we don't need to   */
+      /*       but by the current face object; we don't need to   */
       /*       release it                                         */
       hinter->globals = 0;
       hinter->face    = 0;
@@ -1360,8 +1486,8 @@
         }
       }
 
-      /* copy the outline points in the loader's current                */
-      /* extra points, which is used to keep original glyph coordinates */
+      /* copy the outline points in the loader's current               */
+      /* extra points which is used to keep original glyph coordinates */
       error = ah_loader_check_points( gloader, slot->outline.n_points + 2,
                                       slot->outline.n_contours );
       if ( error )
@@ -1389,8 +1515,8 @@
       if ( slot->outline.n_points == 0 )
         goto Hint_Metrics;
 
-      /* now, load the slot image into the auto-outline, and run the */
-      /* automatic hinting process                                   */
+      /* now load the slot image into the auto-outline and run the */
+      /* automatic hinting process                                 */
       error = ah_outline_load( outline, x_scale, y_scale, face );
       if ( error )
         goto Exit;
@@ -1446,7 +1572,7 @@
         FT_SubGlyph  subglyph;
 
 
-        start_point   = gloader->base.outline.n_points;
+        start_point = gloader->base.outline.n_points;
 
         /* first of all, copy the subglyph descriptors in the glyph loader */
         error = ah_loader_check_subglyphs( gloader, num_subglyphs );
@@ -1529,8 +1655,8 @@
             FT_Vector*  p2;
 
 
-            if ( start_point + k >= num_base_points          ||
-                               l >= (FT_UInt)num_new_points  )
+            if ( start_point + k >= num_base_points         ||
+                               l >= (FT_UInt)num_new_points )
             {
               error = AH_Err_Invalid_Composite;
               goto Exit;
@@ -1538,7 +1664,7 @@
 
             l += num_base_points;
 
-            /* for now, only use the current point coordinates     */
+            /* for now, only use the current point coordinates;    */
             /* we may consider another approach in the near future */
             p1 = gloader->base.outline.points + start_point + k;
             p2 = gloader->base.outline.points + start_point + l;
@@ -1583,8 +1709,8 @@
       if ( hinter->transformed )
         FT_Outline_Transform( &gloader->base.outline, &hinter->trans_matrix );
 
-      /* we must translate our final outline by -pp1.x, and compute */
-      /* the new metrics                                            */
+      /* we must translate our final outline by -pp1.x and compute */
+      /* the new metrics                                           */
       if ( hinter->pp1.x )
         FT_Outline_Translate( &gloader->base.outline, -hinter->pp1.x, 0 );
 
@@ -1599,8 +1725,8 @@
       slot->metrics.horiBearingX = bbox.xMin;
       slot->metrics.horiBearingY = bbox.yMax;
 
-      /* for mono-width fonts (like Andale, Courier, etc.), we need */
-      /* to keep the original rounded advance width                 */
+      /* for mono-width fonts (like Andale, Courier, etc.) we need */
+      /* to keep the original rounded advance width                */
       if ( !FT_IS_FIXED_WIDTH( slot->face ) )
         slot->metrics.horiAdvance = hinter->pp2.x - hinter->pp1.x;
       else
@@ -1641,7 +1767,7 @@
     FT_Fixed         x_scale      = size->metrics.x_scale;
     FT_Fixed         y_scale      = size->metrics.y_scale;
     AH_Face_Globals  face_globals = FACE_GLOBALS( face );
-    FT_Render_Mode   hint_mode    = FT_LOAD_TARGET_MODE(load_flags);
+    FT_Render_Mode   hint_mode    = FT_LOAD_TARGET_MODE( load_flags );
 
 
     /* first of all, we need to check that we're using the correct face and */
@@ -1662,20 +1788,23 @@
     }
 
 #ifdef FT_CONFIG_CHESTER_BLUE_SCALE
+
    /* try to optimize the y_scale so that the top of non-capital letters
     * is aligned on a pixel boundary whenever possible
     */
     {
       AH_Globals  design = &face_globals->design;
-      FT_Pos      shoot  = design->blue_shoots[ AH_BLUE_SMALL_TOP ];
+      FT_Pos      shoot  = design->blue_shoots[AH_BLUE_SMALL_TOP];
 
-     /* the value of 'shoot' will be -1000 if the font doesn't have */
-     /* small latin letters; we simply check the sign here...       */
+
+      /* the value of 'shoot' will be -1000 if the font doesn't have */
+      /* small latin letters; we simply check the sign here...       */
       if ( shoot > 0 )
       {
         FT_Pos  scaled = FT_MulFix( shoot, y_scale );
         FT_Pos  fitted = ( scaled + 32 ) & -64;
 
+
         if ( scaled != fitted )
         {
          /* adjust y_scale
@@ -1685,10 +1814,11 @@
          /* adust x_scale
           */
           if ( fitted < scaled )
-            x_scale -= x_scale/50;  /* x_scale*0.98 with integers */
+            x_scale -= x_scale / 50;  /* x_scale*0.98 with integers */
         }
       }
     }
+
 #endif /* FT_CONFIG_CHESTER_BLUE_SCALE */
 
     /* now, we must check the current character pixel size to see if we */
@@ -1720,12 +1850,9 @@
 
     hinter->do_stem_adjust   = FT_BOOL( hint_mode != FT_RENDER_MODE_LIGHT );
 
-#if 1
-    load_flags  = FT_LOAD_NO_SCALE
-                | FT_LOAD_IGNORE_TRANSFORM ;
-#else
-    load_flags |= FT_LOAD_NO_SCALE | FT_LOAD_NO_RECURSE;
-#endif
+    load_flags |= FT_LOAD_NO_SCALE
+                | FT_LOAD_IGNORE_TRANSFORM;
+    load_flags &= ~FT_LOAD_RENDER;
 
     error = ah_hinter_load( hinter, glyph_index, load_flags, 0 );
 

Index: ahloader.h
===================================================================
RCS file: /cvs/xorg/xc/extras/freetype2/src/autohint/ahloader.h,v
retrieving revision 1.1.4.1
retrieving revision 1.1.4.2
diff -u -d -r1.1.4.1 -r1.1.4.2
--- a/ahloader.h	5 Mar 2004 13:38:42 -0000	1.1.4.1
+++ b/ahloader.h	15 Apr 2004 10:14:30 -0000	1.1.4.2
@@ -17,7 +17,6 @@
 /*  Note that this license is compatible with the FreeType license.        */
 /*                                                                         */
 /***************************************************************************/
-/* $XFree86$ */
 
 
   /*************************************************************************/
@@ -39,19 +38,19 @@
 
 #include FT_INTERNAL_GLYPH_LOADER_H
 
-#define AH_Load    FT_GlyphLoad
-#define AH_Loader  FT_GlyphLoader
+  #define AH_Load    FT_GlyphLoad
+  #define AH_Loader  FT_GlyphLoader
 
-#define ah_loader_new              FT_GlyphLoader_New
-#define ah_loader_done             FT_GlyphLoader_Done
-#define ah_loader_reset            FT_GlyphLoader_Reset
-#define ah_loader_rewind           FT_GlyphLoader_Rewind
-#define ah_loader_create_extra     FT_GlyphLoader_CreateExtra
-#define ah_loader_check_points     FT_GlyphLoader_CheckPoints
-#define ah_loader_check_subglyphs  FT_GlyphLoader_CheckSubGlyphs
-#define ah_loader_prepare          FT_GlyphLoader_Prepare
-#define ah_loader_add              FT_GlyphLoader_Add
-#define ah_loader_copy_points      FT_GlyphLoader_CopyPoints
+  #define ah_loader_new              FT_GlyphLoader_New
+  #define ah_loader_done             FT_GlyphLoader_Done
+  #define ah_loader_reset            FT_GlyphLoader_Reset
+  #define ah_loader_rewind           FT_GlyphLoader_Rewind
+  #define ah_loader_create_extra     FT_GlyphLoader_CreateExtra
+  #define ah_loader_check_points     FT_GlyphLoader_CheckPoints
+  #define ah_loader_check_subglyphs  FT_GlyphLoader_CheckSubGlyphs
+  #define ah_loader_prepare          FT_GlyphLoader_Prepare
+  #define ah_loader_add              FT_GlyphLoader_Add
+  #define ah_loader_copy_points      FT_GlyphLoader_CopyPoints
 
 
 FT_END_HEADER

Index: ahmodule.c
===================================================================
RCS file: /cvs/xorg/xc/extras/freetype2/src/autohint/ahmodule.c,v
retrieving revision 1.1.4.1
retrieving revision 1.1.4.2
diff -u -d -r1.1.4.1 -r1.1.4.2
--- a/ahmodule.c	26 Nov 2003 22:48:25 -0000	1.1.4.1
+++ b/ahmodule.c	15 Apr 2004 10:14:30 -0000	1.1.4.2
@@ -4,7 +4,7 @@
 /*                                                                         */
 /*    Auto-hinting module implementation (declaration).                    */
 /*                                                                         */
-/*  Copyright 2000-2001, 2002 Catharon Productions Inc.                    */
+/*  Copyright 2000-2001, 2002, 2003 Catharon Productions Inc.              */
 /*  Author: David Turner                                                   */
 /*                                                                         */
 /*  This file is part of the Catharon Typography Project and shall only    */
@@ -119,7 +119,7 @@
   FT_CALLBACK_TABLE_DEF
   const FT_Module_Class  autohint_module_class =
   {
-    ft_module_hinter,
+    FT_MODULE_HINTER,
     sizeof ( FT_AutoHinterRec ),
 
     "autohinter",

Index: ahtypes.h
===================================================================
RCS file: /cvs/xorg/xc/extras/freetype2/src/autohint/ahtypes.h,v
retrieving revision 1.1.4.1
retrieving revision 1.1.4.2
diff -u -d -r1.1.4.1 -r1.1.4.2
--- a/ahtypes.h	26 Nov 2003 22:48:25 -0000	1.1.4.1
+++ b/ahtypes.h	15 Apr 2004 10:14:30 -0000	1.1.4.2
@@ -5,7 +5,7 @@
 /*    General types and definitions for the auto-hint module               */
 /*    (specification only).                                                */
 /*                                                                         */
-/*  Copyright 2000-2001, 2002 Catharon Productions Inc.                    */
+/*  Copyright 2000-2001, 2002, 2003 Catharon Productions Inc.              */
 /*  Author: David Turner                                                   */
 /*                                                                         */
 /*  This file is part of the Catharon Typography Project and shall only    */
@@ -78,16 +78,6 @@
 
   /*************************************************************************/
   /*                                                                       */
-  /* If this option is defined, only weak interpolation will be used to    */
-  /* place the points between edges.  Otherwise, `strong' points are       */
-  /* detected and later hinted through strong interpolation to correct     */
-  /* some unpleasant artefacts.                                            */
-  /*                                                                       */
-#undef AH_OPTION_NO_STRONG_INTERPOLATION
-
-
-  /*************************************************************************/
-  /*                                                                       */
   /* Undefine this macro if you don't want to hint the metrics.  There is  */
   /* no reason to do this (at least for non-CJK scripts), except for       */
   /* experimentation.                                                      */
@@ -121,7 +111,7 @@
   /*************************************************************************/
 
 
-  /* see agangles.h */
+  /* see ahangles.h */
   typedef FT_Int  AH_Angle;
 
 
@@ -201,10 +191,6 @@
   /*                                                                       */
   /*    out_dir   :: The direction of the outwards vector (point->next).   */
   /*                                                                       */
-  /*    in_angle  :: The angle of the inwards vector.                      */
-  /*                                                                       */
-  /*    out_angle :: The angle of the outwards vector.                     */
-  /*                                                                       */
   /*    next      :: The next point in same contour.                       */
   /*                                                                       */
   /*    prev      :: The previous point in same contour.                   */
@@ -220,9 +206,6 @@
     AH_Direction  in_dir;   /* direction of inwards vector  */
     AH_Direction  out_dir;  /* direction of outwards vector */
 
-    AH_Angle      in_angle;
-    AH_Angle      out_angle;
-
     AH_Point      next;     /* next point in contour     */
     AH_Point      prev;     /* previous point in contour */
 
@@ -244,16 +227,9 @@
   /*                                                                       */
   /*    dir        :: The segment direction.                               */
   /*                                                                       */
-  /*    first      :: The first point in the segment.                      */
-  /*                                                                       */
-  /*    last       :: The last point in the segment.                       */
-  /*                                                                       */
-  /*    contour    :: A pointer to the first point of the segment's        */
-  /*                  contour.                                             */
-  /*                                                                       */
-  /*    pos        :: The segment position in font units.                  */
+  /*    min_coord  :: The minimum coordinate of the segment.               */
   /*                                                                       */
-  /*    size       :: The segment size.                                    */
+  /*    max_coord  :: The maximum coordinate of the segment.               */
   /*                                                                       */
   /*    edge       :: The edge of the current segment.                     */
   /*                                                                       */
@@ -267,15 +243,17 @@
   /*                                                                       */
   /*    score      :: Used to score the segment when selecting them.       */
   /*                                                                       */
+  /*    first      :: The first point in the segment.                      */
+  /*                                                                       */
+  /*    last       :: The last point in the segment.                       */
+  /*                                                                       */
+  /*    contour    :: A pointer to the first point of the segment's        */
+  /*                  contour.                                             */
+  /*                                                                       */
   typedef struct  AH_SegmentRec_
   {
     AH_Edge_Flags  flags;
     AH_Direction   dir;
-
-    AH_Point       first;       /* first point in edge segment             */
-    AH_Point       last;        /* last point in edge segment              */
-    AH_Point*      contour;     /* ptr to first point of segment's contour */
-
     FT_Pos         pos;         /* position of segment           */
     FT_Pos         min_coord;   /* minimum coordinate of segment */
     FT_Pos         max_coord;   /* maximum coordinate of segment */
@@ -288,6 +266,10 @@
     FT_Pos         num_linked;  /* number of linked segments  */
     FT_Pos         score;
 
+    AH_Point       first;       /* first point in edge segment             */
+    AH_Point       last;        /* last point in edge segment              */
+    AH_Point*      contour;     /* ptr to first point of segment's contour */
+
   } AH_SegmentRec;
 
 
@@ -302,50 +284,55 @@
   /*    located on it.                                                     */
   /*                                                                       */
   /* <Fields>                                                              */
-  /*    flags      :: The segment edge flags (straight, rounded, etc.).    */
+  /*    fpos       :: The original edge position in font units.            */
   /*                                                                       */
-  /*    dir        :: The main segment direction on this edge.             */
+  /*    opos       :: The original scaled edge position.                   */
   /*                                                                       */
-  /*    first      :: The first edge segment.                              */
+  /*    pos        :: The hinted edge position.                            */
   /*                                                                       */
-  /*    last       :: The last edge segment.                               */
+  /*    flags      :: The segment edge flags (straight, rounded, etc.).    */
   /*                                                                       */
-  /*    fpos       :: The original edge position in font units.            */
+  /*    dir        :: The main segment direction on this edge.             */
   /*                                                                       */
-  /*    opos       :: The original scaled edge position.                   */
+  /*    scale      :: Scaling factor between original and hinted edge      */
+  /*                  positions.                                           */
   /*                                                                       */
-  /*    pos        :: The hinted edge position.                            */
+  /*    blue_edge  :: Indicate the blue zone edge this edge is related to. */
+  /*                  Only set for some of the horizontal edges in a latin */
+  /*                  font.                                                */
   /*                                                                       */
   /*    link       :: The linked edge.                                     */
   /*                                                                       */
   /*    serif      :: The serif edge.                                      */
   /*                                                                       */
-  /*    num_paired :: The number of other edges that pair to this one.     */
+  /*    num_linked :: The number of other edges that pair to this one.     */
   /*                                                                       */
   /*    score      :: Used to score the edge when selecting them.          */
   /*                                                                       */
-  /*    blue_edge  :: Indicate the blue zone edge this edge is related to. */
-  /*                  Only set for some of the horizontal edges in a Latin */
-  /*                  font.                                                */
+  /*    first      :: The first edge segment.                              */
+  /*                                                                       */
+  /*    last       :: The last edge segment.                               */
   /*                                                                       */
   typedef struct  AH_EdgeRec_
   {
-    AH_Edge_Flags  flags;
-    AH_Direction   dir;
-
-    AH_Segment     first;
-    AH_Segment     last;
-
     FT_Pos         fpos;
     FT_Pos         opos;
     FT_Pos         pos;
 
+    AH_Edge_Flags  flags;
+    AH_Direction   dir;
+    FT_Fixed       scale;
+    FT_Pos*        blue_edge;
+
     AH_Edge        link;
     AH_Edge        serif;
     FT_Int         num_linked;
 
     FT_Int         score;
-    FT_Pos*        blue_edge;
+
+    AH_Segment     first;
+    AH_Segment     last;
+
 
   } AH_EdgeRec;
 
@@ -368,7 +355,7 @@
 
     FT_Int        max_contours;
     FT_Int        num_contours;
-    AH_Point *    contours;
+    AH_Point*     contours;
 
     FT_Int        num_hedges;
     AH_Edge       horz_edges;
@@ -387,24 +374,24 @@
 
 #ifdef FT_CONFIG_CHESTER_SMALL_F
 
-#  define AH_BLUE_CAPITAL_TOP     0                              /* THEZOCQS */
-#  define AH_BLUE_CAPITAL_BOTTOM  ( AH_BLUE_CAPITAL_TOP + 1 )    /* HEZLOCUS */
-#  define AH_BLUE_SMALL_F_TOP     ( AH_BLUE_CAPITAL_BOTTOM + 1 ) /* fijkdbh  */
-#  define AH_BLUE_SMALL_TOP       ( AH_BLUE_SMALL_F_TOP + 1 )    /* xzroesc  */
-#  define AH_BLUE_SMALL_BOTTOM    ( AH_BLUE_SMALL_TOP + 1 )      /* xzroesc  */
-#  define AH_BLUE_SMALL_MINOR     ( AH_BLUE_SMALL_BOTTOM + 1 )   /* pqgjy    */
-#  define AH_BLUE_MAX             ( AH_BLUE_SMALL_MINOR + 1 )
+#define AH_BLUE_CAPITAL_TOP     0                              /* THEZOCQS */
+#define AH_BLUE_CAPITAL_BOTTOM  ( AH_BLUE_CAPITAL_TOP + 1 )    /* HEZLOCUS */
+#define AH_BLUE_SMALL_F_TOP     ( AH_BLUE_CAPITAL_BOTTOM + 1 ) /* fijkdbh  */
+#define AH_BLUE_SMALL_TOP       ( AH_BLUE_SMALL_F_TOP + 1 )    /* xzroesc  */
+#define AH_BLUE_SMALL_BOTTOM    ( AH_BLUE_SMALL_TOP + 1 )      /* xzroesc  */
+#define AH_BLUE_SMALL_MINOR     ( AH_BLUE_SMALL_BOTTOM + 1 )   /* pqgjy    */
+#define AH_BLUE_MAX             ( AH_BLUE_SMALL_MINOR + 1 )
 
-#else /* !CHESTER_SMALL_F */
+#else /* !FT_CONFIG_CHESTER_SMALL_F */
 
-#  define AH_BLUE_CAPITAL_TOP     0                              /* THEZOCQS */
-#  define AH_BLUE_CAPITAL_BOTTOM  ( AH_BLUE_CAPITAL_TOP + 1 )    /* HEZLOCUS */
-#  define AH_BLUE_SMALL_TOP       ( AH_BLUE_CAPITAL_BOTTOM + 1)  /* xzroesc  */
-#  define AH_BLUE_SMALL_BOTTOM    ( AH_BLUE_SMALL_TOP + 1 )      /* xzroesc  */
-#  define AH_BLUE_SMALL_MINOR     ( AH_BLUE_SMALL_BOTTOM + 1 )   /* pqgjy    */
-#  define AH_BLUE_MAX             ( AH_BLUE_SMALL_MINOR + 1 )
+#define AH_BLUE_CAPITAL_TOP     0                              /* THEZOCQS */
+#define AH_BLUE_CAPITAL_BOTTOM  ( AH_BLUE_CAPITAL_TOP + 1 )    /* HEZLOCUS */
+#define AH_BLUE_SMALL_TOP       ( AH_BLUE_CAPITAL_BOTTOM + 1 ) /* xzroesc  */
+#define AH_BLUE_SMALL_BOTTOM    ( AH_BLUE_SMALL_TOP + 1 )      /* xzroesc  */
+#define AH_BLUE_SMALL_MINOR     ( AH_BLUE_SMALL_BOTTOM + 1 )   /* pqgjy    */
+#define AH_BLUE_MAX             ( AH_BLUE_SMALL_MINOR + 1 )
 
-#endif /* !CHESTER_SMALL_F */
+#endif /* !FT_CONFIG_CHESTER_SMALL_F */
 
   typedef FT_Int  AH_Blue;
 
@@ -429,6 +416,9 @@
   /*                                                                       */
   /*    num_heights :: The number of heights.                              */
   /*                                                                       */
+  /*    stds        :: A two-element array giving the default stem width   */
+  /*                   and height.                                         */
+  /*                                                                       */
   /*    widths      :: Snap widths, including standard one.                */
   /*                                                                       */
   /*    heights     :: Snap height, including standard one.                */
@@ -474,6 +464,9 @@
   /*                                                                       */
   /*    y_scale :: The current vertical scale.                             */
   /*                                                                       */
+  /*    control_overshoot ::                                               */
+  /*               Currently unused.                                       */
+  /*                                                                       */
   typedef struct  AH_Face_GlobalsRec_
   {
     FT_Face        face;
@@ -486,39 +479,39 @@
   } AH_Face_GlobalsRec, *AH_Face_Globals;
 
 
-  typedef struct  AH_HinterRec
+  typedef struct  AH_HinterRec_
   {
-    FT_Memory         memory;
-    AH_Hinter_Flags   flags;
+    FT_Memory        memory;
+    AH_Hinter_Flags  flags;
 
-    FT_Int            algorithm;
-    FT_Face           face;
+    FT_Int           algorithm;
+    FT_Face          face;
 
-    AH_Face_Globals   globals;
+    AH_Face_Globals  globals;
 
-    AH_Outline        glyph;
+    AH_Outline       glyph;
 
-    AH_Loader         loader;
-    FT_Vector         pp1;
-    FT_Vector         pp2;
+    AH_Loader        loader;
+    FT_Vector        pp1;
+    FT_Vector        pp2;
 
-    FT_Bool           transformed;
-    FT_Vector         trans_delta;
-    FT_Matrix         trans_matrix;
+    FT_Bool          transformed;
+    FT_Vector        trans_delta;
+    FT_Matrix        trans_matrix;
 
-    FT_Bool           do_horz_hints;     /* disable X hinting            */
-    FT_Bool           do_vert_hints;     /* disable Y hinting            */
-    FT_Bool           do_horz_snapping;  /* disable X stem size snapping */
-    FT_Bool           do_vert_snapping;  /* disable Y stem size snapping */
-    FT_Bool           do_stem_adjust;    /* disable light stem snapping  */
+    FT_Bool          do_horz_hints;     /* disable X hinting            */
+    FT_Bool          do_vert_hints;     /* disable Y hinting            */
+    FT_Bool          do_horz_snapping;  /* disable X stem size snapping */
+    FT_Bool          do_vert_snapping;  /* disable Y stem size snapping */
+    FT_Bool          do_stem_adjust;    /* disable light stem snapping  */
 
   } AH_HinterRec, *AH_Hinter;
 
 
-#ifdef  DEBUG_HINTER
-  extern AH_Hinter   ah_debug_hinter;
-  extern FT_Bool     ah_debug_disable_horz;
-  extern FT_Bool     ah_debug_disable_vert;
+#ifdef DEBUG_HINTER
+  extern AH_Hinter  ah_debug_hinter;
+  extern FT_Bool    ah_debug_disable_horz;
+  extern FT_Bool    ah_debug_disable_vert;
 #else
 #define ah_debug_disable_horz  0
 #define ah_debug_disable_vert  0

Index: rules.mk
===================================================================
RCS file: /cvs/xorg/xc/extras/freetype2/src/autohint/rules.mk,v
retrieving revision 1.1
retrieving revision 1.1.4.1
diff -u -d -r1.1 -r1.1.4.1
--- a/rules.mk	14 Nov 2003 16:48:24 -0000	1.1
+++ b/rules.mk	15 Apr 2004 10:14:30 -0000	1.1.4.1
@@ -3,7 +3,7 @@
 #
 
 
-# Copyright 2000, 2001 Catharon Productions Inc.
+# Copyright 2000, 2001, 2002, 2003 Catharon Productions Inc.
 # Author: David Turner
 #
 # This file is part of the Catharon Typography Project and shall only
@@ -18,29 +18,28 @@
 
 # AUTO driver directory
 #
-AUTO_DIR  := $(SRC_)autohint
-AUTO_DIR_ := $(AUTO_DIR)$(SEP)
+AUTO_DIR := $(SRC_DIR)/autohint
 
 
 # compilation flags for the driver
 #
-AUTO_COMPILE := $(FT_COMPILE) $I$(AUTO_DIR)
+AUTO_COMPILE := $(FT_COMPILE) $I$(subst /,$(COMPILER_SEP),$(AUTO_DIR))
 
 
 # AUTO driver sources (i.e., C files)
 #
-AUTO_DRV_SRC := $(AUTO_DIR_)ahangles.c  \
-                $(AUTO_DIR_)ahglobal.c  \
-                $(AUTO_DIR_)ahglyph.c   \
-                $(AUTO_DIR_)ahhint.c    \
-                $(AUTO_DIR_)ahmodule.c
+AUTO_DRV_SRC := $(AUTO_DIR)/ahangles.c \
+                $(AUTO_DIR)/ahglobal.c \
+                $(AUTO_DIR)/ahglyph.c  \
+                $(AUTO_DIR)/ahhint.c   \
+                $(AUTO_DIR)/ahmodule.c
 
 # AUTO driver headers
 #
 AUTO_DRV_H := $(AUTO_DRV_SRC:%c=%h)  \
-              $(AUTO_DIR_)ahloader.h \
-              $(AUTO_DIR_)ahtypes.h \
-              $(AUTO_DIR_)aherrors.h
+              $(AUTO_DIR)/ahloader.h \
+              $(AUTO_DIR)/ahtypes.h  \
+              $(AUTO_DIR)/aherrors.h
 
 
 # AUTO driver object(s)
@@ -48,25 +47,25 @@
 #   AUTO_DRV_OBJ_M is used during `multi' builds.
 #   AUTO_DRV_OBJ_S is used during `single' builds.
 #
-AUTO_DRV_OBJ_M := $(AUTO_DRV_SRC:$(AUTO_DIR_)%.c=$(OBJ_)%.$O)
-AUTO_DRV_OBJ_S := $(OBJ_)autohint.$O
+AUTO_DRV_OBJ_M := $(AUTO_DRV_SRC:$(AUTO_DIR)/%.c=$(OBJ_DIR)/%.$O)
+AUTO_DRV_OBJ_S := $(OBJ_DIR)/autohint.$O
 
 # AUTO driver source file for single build
 #
-AUTO_DRV_SRC_S := $(AUTO_DIR_)autohint.c
+AUTO_DRV_SRC_S := $(AUTO_DIR)/autohint.c
 
 
 # AUTO driver - single object
 #
 $(AUTO_DRV_OBJ_S): $(AUTO_DRV_SRC_S) $(AUTO_DRV_SRC) \
                    $(FREETYPE_H) $(AUTO_DRV_H)
-	$(AUTO_COMPILE) $T$@ $(AUTO_DRV_SRC_S)
+	$(AUTO_COMPILE) $T$(subst /,$(COMPILER_SEP),$@ $(AUTO_DRV_SRC_S))
 
 
 # AUTO driver - multiple objects
 #
-$(OBJ_)%.$O: $(AUTO_DIR_)%.c $(FREETYPE_H) $(AUTO_DRV_H)
-	$(AUTO_COMPILE) $T$@ $<
+$(OBJ_DIR)/%.$O: $(AUTO_DIR)/%.c $(FREETYPE_H) $(AUTO_DRV_H)
+	$(AUTO_COMPILE) $T$(subst /,$(COMPILER_SEP),$@ $<)
 
 
 # update main driver object lists

--- ahoptim.c DELETED ---

--- ahoptim.h DELETED ---

--- descrip.mms DELETED ---




More information about the xorg-commit-diffs mailing list