[Xorg-commit] 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,1.1.4.1 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

Kaleb Keithley xorg-commit at pdx.freedesktop.org
Wed May 9 17:30:30 EEST 2007


Committed by: kaleb

Update of /cvs/xorg/xc/extras/freetype2/src/autohint
In directory pdx:/home/kaleb/xorg/xc.XORG-CURRENT/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 
Log Message:
merge most of XFree86 RC3 (4.3.99.903) from vendor branch.
bug #214


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	23 Feb 2004 21:32:36 -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	23 Feb 2004 21:32:36 -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	23 Feb 2004 21:32:36 -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	26 Nov 2003 22:48:25 -0000	1.1.4.1
+++ b/ahhint.c	23 Feb 2004 21:32:36 -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
retrieving revision 1.1.4.1
diff -u -d -r1.1 -r1.1.4.1
--- a/ahloader.h	14 Nov 2003 16:48:24 -0000	1.1
+++ b/ahloader.h	23 Feb 2004 21:32:36 -0000	1.1.4.1
@@ -17,7 +17,6 @@
 /*  Note that this license is compatible with the FreeType license.        */
 /*                                                                         */
 /***************************************************************************/
-/* $XFree86: xc/extras/freetype2/src/autohint/ahloader.h,v 1.2 2003/01/12 03:55:45 tsi Exp $ */
 
 
   /*************************************************************************/
@@ -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	23 Feb 2004 21:32:36 -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	23 Feb 2004 21:32:36 -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	23 Feb 2004 21:32:36 -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





More information about the xorg-commit mailing list