shithub: freetype+ttf2subf

Download patch

ref: cf2c49c80c8337b4326a9a911b2452a88eb23660
parent: 328abf30946ad7c113db8e6bda4fdb4003ae6dda
author: David Turner <[email protected]>
date: Wed Dec 24 13:42:04 EST 2003

* fixed compilation problems in the cache sub-system

        * partial updates to src/autofit

git/fs: mount .git/fs: mount/attach disallowed
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,11 @@
+2003-12-24  David Turner  <[email protected]>
+
+        * fixed compilation problems in the cache sub-system
+
+        * partial updates to src/autofit
+
+        * MERRY X-MAS !
+
 2003-12-23  Werner Lemberg  <[email protected]>
 
 	* src/cff/cffgload.c (cff_lookup_glyph_by_stdcharcode): Handle
@@ -7,10 +15,13 @@
 
 	* include/freetype/internal/ftobjs.h (FT_PAD_FLOOR, FT_PAD_ROUND,
 	FT_PAD_CEIL, FT_PIX_FLOOR, FT_PIX_ROUND, FT_CEIL): New macros.  They
-	are used to avoid compiler warnings with very pedantic compilers. 
+	are used to avoid compiler warnings with very pedantic compilers.
 	Note that `(x) & -64' causes a warning if (x) is not signed.  Use
 	`(x) & ~63' instead!
 	Updated all related code.
+
+        * include/freetype/ftstroke.h, src/base/ftstroke.c: added support
+        for extraction of "inside" and "outside" borders
 
 2003-12-22  Werner Lemberg  <[email protected]>
 
--- a/Jamfile
+++ b/Jamfile
@@ -61,7 +61,8 @@
 # IMPORTANT: You'll need to change the content of "ftmodule.h" as well
 #            if you modify this list or provide your own.
 #
-FT2_COMPONENTS ?= gzip       # support for gzip-compressed files
+FT2_COMPONENTS ?= autofit    # auto-fitter
+                  gzip       # support for gzip-compressed files
                   autohint   # auto-hinter
                   base       # base component (public APIs)
                   bdf        # BDF font driver
--- a/src/autofit/afangles.c
+++ b/src/autofit/afangles.c
@@ -2,6 +2,7 @@
 
   /* this table was generated for AF_ANGLE_PI = 256 */
 #define AF_ANGLE_MAX_ITERS  8
+#define AF_TRIG_MAX_ITERS   9
 
   static const FT_Fixed
   af_angle_arctan_table[9] =
@@ -118,7 +119,7 @@
     if ( theta >= 0 )
       theta = FT_PAD_ROUND( theta, 4 );
     else
-      theta = - FT_PAD_ROUND( -theta, 4 );
+      theta = - FT_PAD_ROUND( theta, 4 );
 
     vec->x = x;
     vec->y = theta;
@@ -171,8 +172,8 @@
   af_sort_pos( FT_UInt   count,
                FT_Pos*   table )
   {
-    FT_Int  i, j;
-    FT_Pos  swap;
+    FT_UInt  i, j;
+    FT_Pos   swap;
 
 
     for ( i = 1; i < count; i++ )
@@ -188,4 +189,26 @@
       }
     }
   }
- 
\ No newline at end of file
+
+
+  FT_LOCAL_DEF( void )
+  af_sort_widths( FT_UInt   count,
+                  AF_Width  table )
+  {
+    FT_UInt      i, j;
+    AF_WidthRec  swap;
+
+
+    for ( i = 1; i < count; i++ )
+    {
+      for ( j = i; j > 0; j-- )
+      {
+        if ( table[j].org > table[j - 1].org )
+          break;
+
+        swap         = table[j];
+        table[j]     = table[j - 1];
+        table[j - 1] = swap;
+      }
+    }
+  }
--- a/src/autofit/afglobal.c
+++ b/src/autofit/afglobal.c
@@ -3,7 +3,7 @@
 
  /* populate this list when you add new scripts
   */
-  static AF_ScriptClass const   af_script_class_list[] =
+  static AF_ScriptClass const   af_script_classes[] =
   {
     & af_latin_script_class,
 
@@ -10,12 +10,12 @@
     NULL  /* do not remove */
   };
 
-#define AF_SCRIPT_LIST_DEFAULT   0    /* index of default script in 'af_script_class_list' */
+#define AF_SCRIPT_LIST_DEFAULT   0    /* index of default script in 'af_script_classes' */
 #define AF_SCRIPT_LIST_NONE      255  /* indicates an uncovered glyph                      */
 
  /*
   *  note that glyph_scripts[] is used to map each glyph into
-  *  an index into the 'af_script_class_list' array.
+  *  an index into the 'af_script_classes' array.
   *
   */
   typedef struct AF_FaceGlobalsRec_
@@ -26,7 +26,7 @@
 
     AF_ScriptMetrics   metrics[ AF_SCRIPT_MAX ];
 
-  } AF_FaceGlobalsRec, *AF_FaceGlobals;
+  } AF_FaceGlobalsRec;
 
 
 
@@ -143,7 +143,6 @@
       }
     }
 
-  Exit:
     *aglobals = globals;
     return error;
   }
@@ -163,7 +162,7 @@
         {
           AF_ScriptClass  clazz = af_script_classes[nn];
 
-          FT_ASSERT( globals->metrics[nn].clazz == clazz );
+          FT_ASSERT( globals->metrics[nn]->clazz == clazz );
 
           if ( clazz->script_metrics_done )
             clazz->script_metrics_done( globals->metrics[nn] );
@@ -172,7 +171,7 @@
         }
       }
 
-      globals->glyph_count   = NULL;
+      globals->glyph_count   = 0;
       globals->glyph_scripts = NULL;  /* no need to free this one !! */
       globals->face          = NULL;
       FT_FREE( globals );
@@ -185,7 +184,7 @@
                                FT_UInt            gindex,
                                AF_ScriptMetrics  *ametrics )
   {
-    FT_Script         script;
+    AF_Script         script;
     AF_ScriptMetrics  metrics = NULL;
     FT_UInt           index;
     AF_ScriptClass    clazz;
@@ -198,7 +197,7 @@
     }
 
     index   = globals->glyph_scripts[ gindex ];
-    clazz   = af_script_class_list[ index ];
+    clazz   = af_script_classes[ index ];
     metrics = globals->metrics[ clazz->script ];
     if ( metrics == NULL )
     {
@@ -211,7 +210,7 @@
 
       if ( clazz->script_metrics_init )
       {
-        error = clazz->script_metrics_init( metrics, face );
+        error = clazz->script_metrics_init( metrics, globals->face );
         if ( error )
         {
           if ( clazz->script_metrics_done )
--- a/src/autofit/afhints.c
+++ b/src/autofit/afhints.c
@@ -171,8 +171,8 @@
 
       } while ( end->fx == first->fx && end->fy == first->fy );
 
-      angle_seg = af_angle( end->fx - start->fx,
-                            end->fy - start->fy );
+      angle_seg = af_angle_atan( end->fx - start->fx,
+                                 end->fy - start->fy );
 
       /* extend the segment start whenever possible */
       before = start;
@@ -187,8 +187,8 @@
 
         } while ( before->fx == start->fx && before->fy == start->fy );
 
-        angle_in = af_angle( start->fx - before->fx,
-                             start->fy - before->fy );
+        angle_in = af_angle_atan( start->fx - before->fx,
+                                  start->fy - before->fy );
 
       } while ( angle_in == angle_seg );
 
@@ -211,10 +211,8 @@
 
           } while ( end->fx == after->fx && end->fy == after->fy );
 
-          vec.x     = after->fx - end->fx;
-          vec.y     = after->fy - end->fy;
-          angle_out = af_angle( after->fx - end->fx,
-                                after->fy - end->fy );
+          angle_out = af_angle_atan( after->fx - end->fx,
+                                     after->fy - end->fy );
 
         } while ( angle_out == angle_seg );
 
@@ -295,16 +293,20 @@
 
   FT_LOCAL_DEF( FT_Error )
   af_glyph_hints_reset( AF_GlyphHints  hints,
-                        FT_Outline*    outline,
-                        FT_Fixed       x_scale,
-                        FT_Fixed       y_scale,
-                        FT_Pos         x_delta,
-                        FT_Pos         y_delta )
+                        AF_Scaler      scaler,
+                        FT_Outline*    outline )
   {
-    FT_Error     error        = AF_Err_Ok;
-
+    FT_Error     error        = FT_Err_Ok;
+    AF_Point     points;
     FT_UInt      old_max, new_max;
+    FT_Fixed     x_scale = scaler->x_scale;
+    FT_Fixed     y_scale = scaler->y_scale;
+    FT_Pos       x_delta = scaler->x_delta;
+    FT_Pos       y_delta = scaler->y_delta;
 
+    hints->scaler_flags = scaler->flags;
+    hints->other_flags  = 0;
+
     hints->num_points    = 0;
     hints->num_contours  = 0;
 
@@ -350,7 +352,7 @@
 
 #undef  OFF_INCREMENT
 #define OFF_INCREMENT( _off, _type, _count )   \
-     ((((_off) + sizeof(_type)) & ~(sizeof(_type)) + ((_count)*sizeof(_type)))
+     ( FT_PAD_CEIL( _off, sizeof(_type) ) + (_count)*sizeof(_type))
 
       off1 = OFF_INCREMENT( 0, AF_PointRec, new_max );
       off2 = OFF_INCREMENT( off1, AF_SegmentRec, new_max );
@@ -467,7 +469,7 @@
             contour_index++;
             if ( point + 1 < point_limit )
             {
-              end   = points + source->contours[contour_index];
+              end   = points + outline->contours[contour_index];
               first = point + 1;
               prev  = end;
             }
@@ -524,8 +526,8 @@
             if ( point->out_dir != AF_DIR_NONE )
               goto Is_Weak_Point;
 
-            angle_in  = af_angle( in_x, in_y );
-            angle_out = af_angle( out_x, out_y );
+            angle_in  = af_angle_atan( in_x, in_y );
+            angle_out = af_angle_atan( out_x, out_y );
             delta     = af_angle_diff( angle_in, angle_out );
 
             if ( delta < 2 && delta > -2 )
@@ -616,7 +618,7 @@
                                       AF_Dimension   dim )
   {
     AF_Point      points      = hints->points;
-    AF_Point      point_limit = points + hints->num_points;;
+    AF_Point      point_limit = points + hints->num_points;
     AF_AxisHints  axis        = &hints->axis[dim];
     AF_Edge       edges       = axis->edges;
     AF_Edge       edge_limit  = edges + axis->num_edges;
@@ -650,7 +652,7 @@
              !( point->flags & AF_FLAG_INFLECTION )         )
           continue;
 
-        if ( dimension )
+        if ( dim == AF_DIMENSION_VERT )
         {
           u  = point->fy;
           ou = point->oy;
--- a/src/autofit/afhints.h
+++ b/src/autofit/afhints.h
@@ -179,12 +179,27 @@
     AF_Point*     contours;
 
     AF_AxisHintsRec  axis[ AF_DIMENSION_MAX ];
+    
+    FT_UInt32         scaler_flags;  /* copy of scaler flags */
+    FT_UInt32         other_flags;   /* free for script-specific implementations */
+    AF_ScriptMetrics  metrics;
 
   } AF_GlyphHintsRec;
 
 
+#define  AF_HINTS_TEST_SCALER(h,f)  ( (h)->scaler_flags & (f) )
+#define  AF_HINTS_TEST_OTHER(h,f)   ( (h)->other_flags  & (f) )
 
+#define  AF_HINTS_DO_HORIZONTAL(h)  \
+            !AF_HINTS_TEST_SCALER(h,AF_SCALER_FLAG_NO_HORIZONTAL)
 
+#define  AF_HINTS_DO_VERTICAL(h)    \
+            !AF_HINTS_TEST_SCALER(h,AF_SCALER_FLAG_NO_VERTICAL)
+
+#define  AF_HINTS_DO_ADVANCE(h)     \
+            !AF_HINTS_TEST_SCALER(h,AF_SCALER_FLAG_NO_ADVANCE)
+
+
   FT_LOCAL( AF_Direction )
   af_direction_compute( FT_Pos  dx,
                         FT_Pos  dy );
@@ -201,11 +216,8 @@
   */
   FT_LOCAL( FT_Error )
   af_glyph_hints_reset( AF_GlyphHints  hints,
-                        FT_Outline*    outline,
-                        FT_Fixed       x_scale,
-                        FT_Fixed       y_scale,
-                        FT_Pos         x_delta,
-                        FT_Pos         y_delta );
+                        AF_Scaler      scaler,
+                        FT_Outline*    outline );
 
   FT_LOCAL( void )
   af_glyph_hints_align_edge_points( AF_GlyphHints  hints,
--- a/src/autofit/aflatin.c
+++ b/src/autofit/aflatin.c
@@ -22,8 +22,10 @@
 
     /* For now, compute the standard width and height from the `o' */
     {
+      FT_Error      error;
       FT_UInt       glyph_index;
       AF_Dimension  dim;
+      AF_ScalerRec  scaler[1];
 
 
       glyph_index = FT_Get_Char_Index( face, 'o' );
@@ -30,12 +32,17 @@
       if ( glyph_index == 0 )
         goto Exit;
 
-      error = FT_Load_Glyph( hinter->face, glyph_index, FT_LOAD_NO_SCALE );
+      error = FT_Load_Glyph( face, glyph_index, FT_LOAD_NO_SCALE );
       if ( error || face->glyph->outline.n_points <= 0 )
         goto Exit;
 
-      error = af_glyph_hints_reset( hints, &face->glyph->outline,
-                                    0x10000L, 0x10000L );
+      scaler->x_scale     = scaler->y_scale = 0x10000L;
+      scaler->x_delta     = scaler->y_delta = 0;
+      scaler->face        = face;
+      scaler->render_mode = 0;
+      scaler->flags       = 0;
+
+      error = af_glyph_hints_reset( hints, scaler, &face->glyph->outline );
       if ( error )
         goto Exit;
 
@@ -67,16 +74,16 @@
               dist = -dist;
 
             if ( num_widths < AF_LATIN_MAX_WIDTHS )
-              axis->widths[ num_widths++ ] = dist;
+              axis->widths[ num_widths++ ].org = dist;
           }
         }
 
-        af_sort_pos( axis->widths, num_widths );
+        af_sort_widths( num_widths, axis->widths );
         axis->width_count = num_widths;
 
         /* we will now try to find the smallest width */
-        if ( num_widths > 0 && axis->widths[0] < edge_distance_threshold )
-          edge_distance_threshold = axis->widths[0];
+        if ( num_widths > 0 && axis->widths[0].org < edge_distance_threshold )
+          edge_distance_threshold = axis->widths[0].org;
 
         /* Now, compute the edge distance threshold as a fraction of the */
         /* smallest width in the font. Set it in `hinter->glyph' too!    */
@@ -129,7 +136,7 @@
     AF_LOG(( "blue zones computation\n" ));
     AF_LOG(( "------------------------------------------------\n" ));
 
-    for ( bb = 0; bb < AF_BLUE_MAX; bb++ )
+    for ( bb = 0; bb < AF_LATIN_BLUE_MAX; bb++ )
     {
       const char*  p     = af_latin_blue_chars[bb];
       const char*  limit = p + AF_LATIN_MAX_TEST_CHARACTERS;
@@ -275,7 +282,7 @@
       af_sort_pos( num_rounds, rounds );
       af_sort_pos( num_flats,  flats );
 
-      blue       = axis->blues[ axis->blue_count ];
+      blue       = & axis->blues[ axis->blue_count ];
       blue_ref   = & blue->ref.org;
       blue_shoot = & blue->shoot.org;
 
@@ -284,7 +291,7 @@
       if ( num_flats == 0 )
       {
         *blue_ref    =
-        *blue->shoot = rounds[num_rounds / 2];
+        *blue_shoot = rounds[num_rounds / 2];
       }
       else if ( num_rounds == 0 )
       {
@@ -366,7 +373,7 @@
       delta = scaler->y_delta;
     }
 
-    axis = metrics->axis[ dim ];
+    axis = & metrics->axis[ dim ];
 
     if ( axis->scale == scale && axis->delta == delta )
       return;
@@ -414,8 +421,8 @@
   af_latin_metrics_scale( AF_LatinMetrics  metrics,
                           AF_Scaler        scaler )
   {
-    af_latin_metrics_scale( metrics, scaler, AF_DIMENSION_HORZ );
-    af_latin_metrics_scale( metrics, scaler, AF_DIMENSION_VERT );
+    af_latin_metrics_scale_dim( metrics, scaler, AF_DIMENSION_HORZ );
+    af_latin_metrics_scale_dim( metrics, scaler, AF_DIMENSION_VERT );
   }
 
 
@@ -437,7 +444,7 @@
     FT_Int        num_segments  =  0;
     AF_Point*     contour       =  hints->contours;
     AF_Point*     contour_limit =  contour + hints->num_contours;
-    AF_Direction  major_dir;
+    AF_Direction  major_dir, segment_dir;
 
 #ifdef AF_HINT_METRICS
     AF_Point    min_point     =  0;
@@ -802,7 +809,7 @@
     /*                                                                   */
     /*********************************************************************/
 
-    edge_distance_threshold = FT_MulFix( outline->edge_distance_threshold,
+    edge_distance_threshold = FT_MulFix( hints->edge_distance_threshold,
                                          scale );
     if ( edge_distance_threshold > 64 / 4 )
       edge_distance_threshold = 64 / 4;
@@ -863,7 +870,7 @@
         edge->last            = seg;
       }
     }
-    *p_num_edges = (FT_Int)( edge_limit - edges );
+    axis->num_edges = (FT_Int)( edge_limit - edges );
 
 
     /*********************************************************************/
@@ -1012,7 +1019,7 @@
   {
     af_latin_hints_compute_segments( hints, dim );
     af_latin_hints_link_segments   ( hints, dim );
-    af_latin_hints_compute_edges   ( hints dim );
+    af_latin_hints_compute_edges   ( hints, dim );
   }
 
 
@@ -1039,7 +1046,7 @@
 
 
       /* compute the initial threshold as a fraction of the EM size */
-      best_dist = FT_MulFix( metrics->units_pe_EM / 40, scale );
+      best_dist = FT_MulFix( metrics->units_per_em / 40, scale );
 
       if ( best_dist > 64 / 2 )
         best_dist = 64 / 2;
@@ -1051,14 +1058,14 @@
 
        /* skip inactive blue zones (i.e. those that are too small
         */
-        if ( !(bb->flags & AF_LATIN_BLUE_ACTIVE) )
+        if ( !(blue->flags & AF_LATIN_BLUE_ACTIVE) )
           continue;
 
         /* if it is a top zone, check for right edges -- if it is a bottom */
         /* zone, check for left edges                                      */
         /*                                                                 */
-        /* of course, that's for TrueType XXX                              */
-        is_top_blue  = (bb->flags & AF_LATIN_BLUE_TOP) != 0;
+        /* of course, that's for TrueType                                  */
+        is_top_blue  = (blue->flags & AF_LATIN_BLUE_TOP) != 0;
         is_major_dir = FT_BOOL( edge->dir == axis->major_dir );
 
         /* if it is a top zone, the edge must be against the major    */
@@ -1074,7 +1081,7 @@
           if ( dist < 0 )
             dist = -dist;
 
-          dist = FT_MulFix( dist, y_scale );
+          dist = FT_MulFix( dist, scale );
           if ( dist < best_dist )
           {
             best_dist = dist;
@@ -1091,12 +1098,12 @@
 
             if ( is_top_blue ^ is_under_ref )
             {
-              blue = _pos = globals->blue_shoots + blue;
+              blue = latin->blues + bb;
               dist = edge->fpos - blue->shoot.org;
               if ( dist < 0 )
                 dist = -dist;
 
-              dist = FT_MulFix( dist, y_scale );
+              dist = FT_MulFix( dist, scale );
               if ( dist < best_dist )
               {
                 best_dist = dist;
@@ -1116,21 +1123,53 @@
   static FT_Error
   af_latin_hints_init( AF_GlyphHints    hints,
                        AF_Scaler        scaler,
+                       FT_Outline*      outline,
                        AF_LatinMetrics  metrics )
   {
-    FT_Error  error;
+    FT_Error        error;
+    FT_Render_Mode  mode;
 
-    error = af_glyph_hints_reset( hints, &scaler->outline,
-                                  scaler->x_scale,
-                                  scaler->y_scale,
-                                  scaler->x_delta,
-                                  scaler->y_delta );
-   if (error)
-     goto Exit;
+    error = af_glyph_hints_reset( hints, scaler, outline );
+    if (error)
+      goto Exit;
 
-   af_latin_hints_detect_features( hints, metrics );
-   af_latin_hints_compute_blue_edges( hints, metrics );
 
+   /* compute flags depending on render mode, etc...
+    */
+
+    mode = scaler->render_mode;
+
+   /* we snap the width of vertical stems for the monochrome and
+    * horizontal LCD rendering targets only.
+    */
+    if ( mode == FT_RENDER_MODE_MONO || mode == FT_RENDER_MODE_LCD )
+      hints->other_flags |= AF_LATIN_HINTS_HORZ_SNAP;
+
+   /* we snap the width of horizontal stems for the monochrome and
+    * vertical LCD rendering targets only.
+    */
+    if ( mode == FT_RENDER_MODE_MONO || mode == FT_RENDER_MODE_LCD_V )
+      hints->other_flags |= AF_LATIN_HINTS_VERT_SNAP;
+      
+   /* XXX
+    */
+    if ( mode != FT_RENDER_MODE_LIGHT )
+      hints->other_flags |= AF_LATIN_HINTS_STEM_ADJUST;
+
+    if ( mode == FT_RENDER_MODE_MONO )
+      hints->other_flags |= AF_LATIN_HINTS_MONO;
+
+   /* analyze glyph outline
+    */
+    if ( AF_HINTS_DO_HORIZONTAL(hints) )
+      af_latin_hints_detect_features( hints, AF_DIMENSION_HORZ );
+     
+    if ( AF_HINTS_DO_VERTICAL(hints) )
+    {
+      af_latin_hints_detect_features( hints, AF_DIMENSION_VERT );
+      af_latin_hints_compute_blue_edges( hints, metrics );
+    }
+
  Exit:
    return error;
   }
@@ -1193,17 +1232,21 @@
   /* compute the snapped width of a given stem */
 
   static FT_Pos
-  af_latin_compute_stem_width( AF_GylphHints  hints,
+  af_latin_compute_stem_width( AF_GlyphHints  hints,
                                AF_Dimension   dim,
                                FT_Pos         width,
                                AF_Edge_Flags  base_flags,
                                AF_Edge_Flags  stem_flags )
   {
-    AF_Globals  globals  = &hinter->globals->scaled;
-    FT_Pos      dist     = width;
-    FT_Int      sign     = 0;
-    FT_Bool     vertical = FT_BOOL( dim == AF_DIMENSION_VERT );
+    AF_LatinMetrics  metrics  = (AF_LatinMetrics) hints->metrics;
+    AF_LatinAxis     axis     = & metrics->axis[ dim ];
+    FT_Pos           dist     = width;
+    FT_Int           sign     = 0;
+    FT_Int           vertical = AF_HINTS_DO_VERTICAL( hints );
+      
 
+    if ( !AF_LATIN_HINTS_DO_STEM_ADJUST( hints ) )
+      return width;
 
     if ( dist < 0 )
     {
@@ -1211,13 +1254,9 @@
       sign = 1;
     }
 
-    if ( !hinter->do_stem_adjust )
+    if ( (  vertical && !AF_LATIN_HINTS_DO_VERT_SNAPPING( hints ) ) ||
+         ( !vertical && !AF_LATIN_HINTS_DO_HORZ_SNAPPING( hints ) ) )
     {
-      /* leave stem widths unchanged */
-    }
-    else if ( (  vertical && !hinter->do_vert_snapping ) ||
-              ( !vertical && !hinter->do_horz_snapping ) )
-    {
       /* smooth hinting process: very lightly quantize the stem width */
       /*                                                              */
 
@@ -1234,20 +1273,27 @@
       else if ( dist < 56 )
         dist = 56;
 
+      if ( axis->width_count > 0 )
       {
-        FT_Pos  delta = dist - globals->stds[vertical];
+        FT_Pos  delta;
 
-
-        if ( delta < 0 )
-          delta = -delta;
-
-        if ( delta < 40 )
+       /* compare to standard width
+        */
+        if ( axis->width_count > 0 )
         {
-          dist = globals->stds[vertical];
-          if ( dist < 48 )
-            dist = 48;
+          delta = dist - axis->widths[0].cur;
+          
+          if ( delta < 0 )
+            delta = -delta;
 
-          goto Done_Width;
+          if ( delta < 40 )
+          {
+            dist = axis->widths[ 0 ].cur;
+            if ( dist < 48 )
+              dist = 48;
+
+            goto Done_Width;
+          }
         }
 
         if ( dist < 3 * 64 )
@@ -1275,10 +1321,10 @@
     {
       /* strong hinting process: snap the stem width to integer pixels */
       /*                                                               */
+      dist = af_latin_snap_width( axis->widths, axis->width_count, dist );
+
       if ( vertical )
       {
-        dist = af_snap_width( globals->heights, globals->num_heights, dist );
-
         /* in the case of vertical hinting, always round */
         /* the stem heights to integer pixels            */
         if ( dist >= 64 )
@@ -1288,9 +1334,7 @@
       }
       else
       {
-        dist = af_snap_width( globals->widths, globals->num_widths, dist );
-
-        if ( hinter->flags & AF_HINTER_MONOCHROME )
+        if ( AF_LATIN_HINTS_DO_MONO( hints ) )
         {
           /* monochrome horizontal hinting: snap widths to integer pixels */
           /* with a different threshold                                   */
@@ -1310,7 +1354,7 @@
           else if ( dist < 128 )
             dist = ( dist + 22 ) & ~63;
           else
-            /* XXX: round otherwise to prevent color fringes in LCD mode */
+            /* round otherwise to prevent color fringes in LCD mode */
             dist = ( dist + 32 ) & ~63;
         }
       }
@@ -1384,8 +1428,8 @@
     {
       for ( edge = edges; edge < edge_limit; edge++ )
       {
-        AF_Width*  blue;
-        AF_Edge    edge1, edge2;
+        AF_Width  blue;
+        AF_Edge   edge1, edge2;
 
 
         if ( edge->flags & AF_EDGE_DONE )
@@ -1446,7 +1490,7 @@
       /* this should not happen, but it's better to be safe */
       if ( edge2->blue_edge || edge2 < edge )
       {
-        af_latin_align_linked_edge( hinter, edge2, edge, dimension );
+        af_latin_align_linked_edge( hints, dim, edge2, edge );
         edge->flags |= AF_EDGE_DONE;
         continue;
       }
@@ -1510,8 +1554,8 @@
         org_len    = edge2->opos - edge->opos;
         org_center = org_pos + ( org_len >> 1 );
 
-        cur_len = af_compute_stem_width( hinter, dimension, org_len,
-                                         edge->flags, edge2->flags  );
+        cur_len = af_latin_compute_stem_width( hints, dim, org_len,
+                                               edge->flags, edge2->flags  );
 
         if ( cur_len < 96 )
         {
@@ -1550,8 +1594,8 @@
           org_len    = edge2->opos - edge->opos;
           org_center = org_pos + ( org_len >> 1 );
 
-          cur_len    = af_compute_stem_width( hinter, dimension, org_len,
-                                              edge->flags, edge2->flags );
+          cur_len    = af_latin_compute_stem_width( hints, dim, org_len,
+                                                    edge->flags, edge2->flags );
 
           cur_pos1   = FT_PIX_ROUND( org_pos );
           delta1     = ( cur_pos1 + ( cur_len >> 1 ) - org_center );
@@ -1648,7 +1692,7 @@
           continue;
 
         if ( edge->serif )
-          af_align_serif_edge( hinter, edge->serif, edge, dimension );
+          af_latin_align_serif_edge( hints, edge->serif, edge );
         else if ( !anchor )
         {
           edge->pos = FT_PIX_ROUND( edge->opos );
@@ -1655,7 +1699,7 @@
           anchor    = edge;
         }
         else
-          edge->pos = anchor->pos +
+          edge->pos = anchor->pos + 
                       FT_PIX_ROUND( edge->opos - anchor->opos );
 
         edge->flags |= AF_EDGE_DONE;
@@ -1677,8 +1721,20 @@
                         AF_Scaler        scaler,
                         AF_LatinMetrics  metrics )
   {
-    /* XXX */
-    return FT_Err_Unimplemented;
+    AF_Dimension  dim;
+    
+    for ( dim = 0; dim < AF_DIMENSION_MAX; dim++ )
+    {
+      if ( (dim == AF_DIMENSION_HORZ && AF_LATIN_HINTS_DO_HORIZONTAL(hints)) ||
+           (dim == AF_DIMENSION_VERT && AF_LATIN_HINTS_DO_VERTICAL(hints))   )
+      {
+        af_latin_hint_edges( hints, dim );
+        af_glyph_hints_align_edge_points( hints, dim );
+        af_glyph_hints_align_strong_points( hints, dim );
+        af_glyph_hints_align_weak_points( hints, dim );
+      }
+    }
+    return 0;
   }
 
  /***************************************************************************/
@@ -1699,7 +1755,7 @@
   FT_LOCAL_DEF( const AF_ScriptClassRec )  af_latin_script_class =
   {
     AF_SCRIPT_LATIN,
-    &af_latin_script_uniranges,
+    af_latin_uniranges,
 
     sizeof( AF_LatinMetricsRec ),
     (AF_Script_InitMetricsFunc)  af_latin_metrics_init,
--- a/src/autofit/aflatin.h
+++ b/src/autofit/aflatin.h
@@ -9,7 +9,7 @@
   * the latin-specific script class
   *
   */
-  FT_LOCAL( const FT_ScriptClassRec )    af_latin_script_class;
+  FT_LOCAL( const AF_ScriptClassRec )    af_latin_script_class;
 
  /***************************************************************************/
  /***************************************************************************/
@@ -54,7 +54,7 @@
     AF_LATIN_BLUE_ACTIVE = (1 << 0),
     AF_LATIN_BLUE_TOP    = (1 << 1),
     
-    AF_LATIN_BLUE_MAX
+    AF_LATIN_BLUE_FLAG_MAX
   };
 
 
@@ -79,7 +79,7 @@
    /* ignored for horizontal metrics */
     FT_Bool          control_overshoot;
     FT_UInt          blue_count;
-    AF_LatinBlueRec  blues;
+    AF_LatinBlueRec  blues[ AF_LATIN_BLUE_MAX ];
 
   } AF_LatinAxisRec, *AF_LatinAxis;
 
@@ -93,6 +93,7 @@
   } AF_LatinMetricsRec, *AF_LatinMetrics;
 
 
+
   FT_LOCAL( FT_Error )
   af_latin_metrics_init( AF_LatinMetrics  metrics,
                          FT_Face          face );
@@ -110,6 +111,26 @@
  /*****                                                                 *****/
  /***************************************************************************/
  /***************************************************************************/
+
+  enum
+  {
+    AF_LATIN_HINTS_HORZ_SNAP   = (1 << 0),  /* enable stem width snapping  */
+    AF_LATIN_HINTS_VERT_SNAP   = (1 << 1),  /* enable stem height snapping */
+    AF_LATIN_HINTS_STEM_ADJUST = (1 << 2),  /* enable stem width/height adjustment */
+    AF_LATIN_HINTS_MONO        = (1 << 3),  /* indicate monochrome rendering */
+  };
+
+#define  AF_LATIN_HINTS_DO_HORZ_SNAP(h) \
+   AF_HINTS_TEST_OTHER(h,AF_LATIN_HINTS_HORZ_SNAP)
+
+#define  AF_LATIN_HINTS_DO_VERT_SNAP(h) \
+   AF_HINTS_TEST_OTHER(h,AF_LATIN_HINTS_VERT_SNAP)
+
+#define  AF_LATIN_HINTS_DO_STEM_ADJUST(h)  \
+   AF_HINTS_TEST_OTHER(h,AF_LATIN_HINTS_STEM_ADJUST)
+
+#define  AF_LATIN_HINTS_DO_MONO(h)  \
+   AF_HINTS_TEST_OTHER(h,AF_LATIN_HINTS_MONO)
 
 
  /* this shouldn't normally be exported. However, other scripts might
--- a/src/autofit/aftypes.h
+++ b/src/autofit/aftypes.h
@@ -3,6 +3,9 @@
 
 #include <ft2build.h>
 #include FT_FREETYPE_H
+#include FT_OUTLINE_H
+#include FT_INTERNAL_OBJECTS_H
+#include FT_INTERNAL_DEBUG_H
 
 FT_BEGIN_HEADER
 
@@ -44,10 +47,15 @@
   } AF_WidthRec, *AF_Width;
 
 
-  AF_LOCAL( void )
+  FT_LOCAL( void )
   af_sort_pos( FT_UInt   count,
                FT_Pos*   table );
 
+  FT_LOCAL( void )
+  af_sort_widths( FT_UInt   count,
+                  AF_Width  widths );
+
+
  /**************************************************************************/
  /**************************************************************************/
  /*****                                                                *****/
@@ -75,8 +83,8 @@
   *
   */
   FT_LOCAL( AF_Angle )
-  af_angle( FT_Pos  dx,
-            FT_Pos  dy );
+  af_angle_atan( FT_Pos  dx,
+                 FT_Pos  dy );
 
 
  /*
@@ -109,7 +117,7 @@
   typedef struct AF_OutlineRec_
   {
     FT_Face          face;
-    FT_OutlineRec    outline;
+    FT_Outline       outline;
     FT_UInt          outline_resolution;
 
     FT_Int           advance;
@@ -231,8 +239,9 @@
     FT_UInt32    first;
     FT_UInt32    last;
 
-  } AF_Script_UniRangeRec, *AF_Script_UniRange;
+  } AF_Script_UniRangeRec;
 
+  typedef const AF_Script_UniRangeRec *  AF_Script_UniRange;
 
   typedef struct AF_ScriptClassRec_
   {
--- a/src/cache/ftccache.c
+++ b/src/cache/ftccache.c
@@ -460,7 +460,7 @@
       }
     }
     goto AddNode;
-  }                     
+  }
 
 
   FT_EXPORT_DEF( FT_Error )
@@ -529,7 +529,7 @@
   {
     FT_UFast     i, count;
     FTC_Manager  manager = cache->manager;
-    FTC_Node     free    = NULL;
+    FTC_Node     frees   = NULL;
 
     count = cache->p + cache->mask;
     for ( i = 0; i < count; i++ )
@@ -547,8 +547,8 @@
         if ( cache->clazz.node_remove_faceid( node, face_id, cache ) )
         {
           *pnode = node->link;
-          node->link = free;
-          free       = node;
+          node->link = frees;
+          frees      = node;
         }
         else
           pnode = &node->link;
@@ -557,12 +557,12 @@
 
    /* remove all nodes in the free list
     */
-    while ( free )
+    while ( frees )
     {
       FTC_Node  node;
 
-      node = free;
-      free = node->link;
+      node  = frees;
+      frees = node->link;
 
       manager->cur_weight -= cache->clazz.node_weight( node, cache );
       ftc_node_mru_unlink( node, manager );
--- a/src/cache/ftcmru.c
+++ b/src/cache/ftcmru.c
@@ -258,7 +258,6 @@
                    FTC_MruNode  *anode )
   {
     FTC_MruNode  node;
-    FT_Error     error = 0;
 
     node = FTC_MruList_Find( list, key );
     if ( node == NULL )
--- a/src/cache/ftcsbits.c
+++ b/src/cache/ftcsbits.c
@@ -235,7 +235,7 @@
     FT_ULong   size;
 
 
-    FT_ASSERT( snode->count <= FTC_SBITS_ITEM_PER_NODE );
+    FT_ASSERT( snode->count <= FTC_SBIT_ITEM_PER_NODE );
 
     /* the node itself */
     size = sizeof ( *snode );