all must go
[rrdtool.git] / libraries / freetype-2.0.5 / ahhint.c
diff --git a/libraries/freetype-2.0.5/ahhint.c b/libraries/freetype-2.0.5/ahhint.c
deleted file mode 100644 (file)
index 12f43fd..0000000
+++ /dev/null
@@ -1,1407 +0,0 @@
-/***************************************************************************/
-/*                                                                         */
-/*  ahhint.c                                                               */
-/*                                                                         */
-/*    Glyph hinter (body).                                                 */
-/*                                                                         */
-/*  Copyright 2000-2001 Catharon Productions Inc.                          */
-/*  Author: David Turner                                                   */
-/*                                                                         */
-/*  This file is part of the Catharon Typography Project and shall only    */
-/*  be used, modified, and distributed under the terms of the Catharon     */
-/*  Open Source License that should come with this file under the name     */
-/*  `CatharonLicense.txt'.  By continuing to use, modify, or distribute    */
-/*  this file you indicate that you have read the license and              */
-/*  understand and accept it fully.                                        */
-/*                                                                         */
-/*  Note that this license is compatible with the FreeType license.        */
-/*                                                                         */
-/***************************************************************************/
-
-
-#include <ft2build.h>
-#include "ahhint.h"
-#include "ahglyph.h"
-#include "ahangles.h"
-#include "aherrors.h"
-#include FT_OUTLINE_H
-
-
-#define FACE_GLOBALS( face )  ((AH_Face_Globals*)(face)->autohint.data)
-
-#define AH_USE_IUP
-
-
-  /*************************************************************************/
-  /*************************************************************************/
-  /****                                                                 ****/
-  /****   Hinting routines                                              ****/
-  /****                                                                 ****/
-  /*************************************************************************/
-  /*************************************************************************/
-
-
-  /* snap a given width in scaled coordinates to one of the */
-  /* current standard widths                                */
-  static FT_Pos
-  ah_snap_width( FT_Pos*  widths,
-                 FT_Int   count,
-                 FT_Pos   width )
-  {
-    int     n;
-    FT_Pos  best      = 64 + 32 + 2;
-    FT_Pos  reference = width;
-
-
-    for ( n = 0; n < count; n++ )
-    {
-      FT_Pos  w;
-      FT_Pos  dist;
-
-
-      w = widths[n];
-      dist = width - w;
-      if ( dist < 0 )
-        dist = -dist;
-      if ( dist < best )
-      {
-        best      = dist;
-        reference = w;
-      }
-    }
-
-    if ( width >= reference )
-    {
-      width -= 0x21;
-      if ( width < reference )
-        width = reference;
-    }
-    else
-    {
-      width += 0x21;
-      if ( width > reference )
-        width = reference;
-    }
-
-    return width;
-  }
-
-
-  /* align one stem edge relative to the previous stem edge */
-  static void
-  ah_align_linked_edge( AH_Hinter*  hinter,
-                        AH_Edge*    base_edge,
-                        AH_Edge*    stem_edge,
-                        int         vertical )
-  {
-    FT_Pos       dist    = stem_edge->opos - base_edge->opos;
-    AH_Globals*  globals = &hinter->globals->scaled;
-    FT_Pos       sign    = 1;
-
-
-    if ( dist < 0 )
-    {
-      dist = -dist;
-      sign = -1;
-    }
-
-    if ( vertical )
-    {
-      dist = ah_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 )
-        dist = ( dist + 16 ) & -64;
-      else
-        dist = 64;
-    }
-    else
-    {
-      dist = ah_snap_width( globals->widths,  globals->num_widths, dist );
-
-      if ( hinter->flags & ah_hinter_monochrome )
-      {
-        /* monochrome horizontal hinting: snap widths to integer pixels */
-        /* with a different threshold                                   */
-        if ( dist < 64 )
-          dist = 64;
-        else
-          dist = ( dist + 32 ) & -64;
-      }
-      else
-      {
-        /* for horizontal anti-aliased hinting, we adopt a more subtle */
-        /* approach: we strengthen small stems, round stems whose size */
-        /* is between 1 and 2 pixels to an integer, otherwise nothing  */
-        if ( dist < 48 )
-          dist = ( dist + 64 ) >> 1;
-
-        else if ( dist < 128 )
-          dist = ( dist + 42 ) & -64;
-      }
-    }
-
-    stem_edge->pos = base_edge->pos + sign * dist;
-  }
-
-
-  static void
-  ah_align_serif_edge( AH_Hinter*  hinter,
-                       AH_Edge*    base,
-                       AH_Edge*    serif )
-  {
-    FT_Pos  dist;
-    FT_Pos  sign = 1;
-
-    UNUSED( hinter );
-
-
-    dist = serif->opos - base->opos;
-    if ( dist < 0 )
-    {
-      dist = -dist;
-      sign = -1;
-    }
-
-    /* do not strengthen serifs */
-    if ( base->flags & ah_edge_done )
-    {
-      if ( dist > 64 )
-        dist = ( dist + 16 ) & -64;
-
-      else if ( dist <= 32 )
-        dist = ( dist + 33 ) >> 1;
-    }
-
-    serif->pos = base->pos + sign * dist;
-  }
-
-
-  /*************************************************************************/
-  /*************************************************************************/
-  /*************************************************************************/
-  /****                                                                 ****/
-  /****       E D G E   H I N T I N G                                   ****/
-  /****                                                                 ****/
-  /*************************************************************************/
-  /*************************************************************************/
-  /*************************************************************************/
-
-
-  /* Another alternative edge hinting algorithm */
-  static void
-  ah_hint_edges_3( AH_Hinter*  hinter )
-  {
-    AH_Edge*     edges;
-    AH_Edge*     edge_limit;
-    AH_Outline*  outline = hinter->glyph;
-    FT_Int       dimension;
-
-
-    edges      = outline->horz_edges;
-    edge_limit = edges + outline->num_hedges;
-
-    for ( dimension = 1; dimension >= 0; dimension-- )
-    {
-      AH_Edge*  edge;
-      AH_Edge*  anchor = 0;
-      int       has_serifs = 0;
-
-
-      if ( hinter->disable_vert_edges && !dimension )
-        goto Next_Dimension;
-
-      if ( hinter->disable_horz_edges && dimension )
-        goto Next_Dimension;
-
-      /* we begin by aligning all stems relative to the blue zone */
-      /* if needed -- that's only for horizontal edges            */
-      if ( dimension )
-      {
-        for ( edge = edges; edge < edge_limit; edge++ )
-        {
-          FT_Pos*  blue;
-          AH_Edge  *edge1, *edge2;
-
-
-          if ( edge->flags & ah_edge_done )
-            continue;
-
-          blue  = edge->blue_edge;
-          edge1 = 0;
-          edge2 = edge->link;
-
-          if ( blue )
-          {
-            edge1 = edge;
-          }
-          else if (edge2 && edge2->blue_edge)
-          {
-            blue  = edge2->blue_edge;
-            edge1 = edge2;
-            edge2 = edge;
-          }
-
-          if ( !edge1 )
-            continue;
-
-          edge1->pos    = blue[0];
-          edge1->flags |= ah_edge_done;
-
-          if ( edge2 && !edge2->blue_edge )
-          {
-            ah_align_linked_edge( hinter, edge1, edge2, dimension );
-            edge2->flags |= ah_edge_done;
-          }
-
-          if ( !anchor )
-            anchor = edge;
-         }
-       }
-
-      /* 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_Edge  *edge2;
-
-
-        if ( edge->flags & ah_edge_done )
-          continue;
-
-        /* skip all non-stem edges */
-        edge2 = edge->link;
-        if ( !edge2 )
-        {
-          has_serifs++;
-          continue;
-        }
-
-        /* now, align the stem */
-
-        /* this should not happen, but it's better to be safe.. */
-        if ( edge2->blue_edge || edge2 < edge )
-        {
-
-#if 0
-          printf( "strange blue alignement, edge %d to %d\n",
-                  edge - edges, edge2 - edges );
-#endif
-
-          ah_align_linked_edge( hinter, edge2, edge, dimension );
-          edge->flags |= ah_edge_done;
-          continue;
-        }
-
-        {
-          FT_Bool  min = 0;
-          FT_Pos   delta;
-
-          if ( !anchor )
-          {
-            edge->pos = ( edge->opos + 32 ) & -64;
-            anchor    = edge;
-          }
-          else
-            edge->pos = anchor->pos +
-                        ( ( edge->opos - anchor->opos + 32 ) & -64 );
-
-          edge->flags |= ah_edge_done;
-
-          if ( edge > edges && edge->pos < edge[-1].pos )
-          {
-            edge->pos = edge[-1].pos;
-            min       = 1;
-          }
-
-          ah_align_linked_edge( hinter, edge, edge2, dimension );
-          delta = 0;
-          if ( edge2 + 1 < edge_limit        &&
-               edge2[1].flags & ah_edge_done )
-            delta = edge2[1].pos - edge2->pos;
-
-          if ( delta < 0 )
-          {
-            edge2->pos += delta;
-            if ( !min )
-              edge->pos += delta;
-          }
-          edge2->flags |= ah_edge_done;
-        }
-      }
-
-      if ( !has_serifs )
-        goto Next_Dimension;
-
-      /* 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 )
-          continue;
-
-        if ( edge->serif )
-        {
-          ah_align_serif_edge( hinter, edge->serif, edge );
-        }
-        else if ( !anchor )
-        {
-          edge->pos = ( edge->opos + 32 ) & -64;
-          anchor    = edge;
-        }
-        else
-          edge->pos = anchor->pos +
-                      ( ( edge->opos-anchor->opos + 32 ) & -64 );
-
-        edge->flags |= ah_edge_done;
-
-        if ( edge > edges && edge->pos < edge[-1].pos )
-          edge->pos = edge[-1].pos;
-
-        if ( edge + 1 < edge_limit        &&
-             edge[1].flags & ah_edge_done &&
-             edge->pos > edge[1].pos      )
-          edge->pos = edge[1].pos;
-      }
-
-    Next_Dimension:
-      edges      = outline->vert_edges;
-      edge_limit = edges + outline->num_vedges;
-    }
-  }
-
-
-  FT_LOCAL_DEF void
-  ah_hinter_hint_edges( AH_Hinter*  hinter,
-                        FT_Bool     no_horz_edges,
-                        FT_Bool     no_vert_edges )
-  {
-    hinter->disable_horz_edges = no_horz_edges;
-    hinter->disable_vert_edges = no_vert_edges;
-
-    /* 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 );
-
-#if 0
-      /* outline optimizer removed temporarily */
-      if ( hinter->flags & ah_hinter_optimize )
-      {
-        AH_Optimizer  opt;
-
-
-        if ( !AH_Optimizer_Init( &opt, hinter->glyph, hinter->memory ) )
-        {
-          AH_Optimizer_Compute( &opt );
-          AH_Optimizer_Done( &opt );
-        }
-      }
-#endif
-
-    }
-  }
-
-
-  /*************************************************************************/
-  /*************************************************************************/
-  /*************************************************************************/
-  /****                                                                 ****/
-  /****       P O I N T   H I N T I N G                                 ****/
-  /****                                                                 ****/
-  /*************************************************************************/
-  /*************************************************************************/
-  /*************************************************************************/
-
-  static void
-  ah_hinter_align_edge_points( AH_Hinter*  hinter )
-  {
-    AH_Outline*  outline = hinter->glyph;
-    AH_Edge*     edges;
-    AH_Edge*     edge_limit;
-    FT_Int       dimension;
-
-
-    edges      = outline->horz_edges;
-    edge_limit = edges + outline->num_hedges;
-
-    for ( dimension = 1; dimension >= 0; dimension-- )
-    {
-      AH_Edge*   edge;
-
-
-      edge = edges;
-      for ( ; edge < edge_limit; edge++ )
-      {
-        /* move the points of each segment     */
-        /* in each edge to the edge's position */
-        AH_Segment*  seg = edge->first;
-
-
-        do
-        {
-          AH_Point*  point = seg->first;
-
-
-          for (;;)
-          {
-            if ( dimension )
-            {
-              point->y      = edge->pos;
-              point->flags |= ah_flah_touch_y;
-            }
-            else
-            {
-              point->x      = edge->pos;
-              point->flags |= ah_flah_touch_x;
-            }
-
-            if ( point == seg->last )
-              break;
-
-            point = point->next;
-          }
-
-          seg = seg->edge_next;
-
-        } while ( seg != edge->first );
-      }
-
-      edges      = outline->vert_edges;
-      edge_limit = edges + outline->num_vedges;
-    }
-  }
-
-
-  /* hint the strong points -- this is equivalent to the TrueType `IP' */
-  static void
-  ah_hinter_align_strong_points( AH_Hinter*  hinter )
-  {
-    AH_Outline*  outline = hinter->glyph;
-    FT_Int       dimension;
-    AH_Edge*     edges;
-    AH_Edge*     edge_limit;
-    AH_Point*    points;
-    AH_Point*    point_limit;
-    AH_Flags     touch_flag;
-
-
-    points      = outline->points;
-    point_limit = points + outline->num_points;
-
-    edges       = outline->horz_edges;
-    edge_limit  = edges + outline->num_hedges;
-    touch_flag  = ah_flah_touch_y;
-
-    for ( dimension = 1; dimension >= 0; dimension-- )
-    {
-      AH_Point*  point;
-      AH_Edge*   edge;
-
-
-      if ( edges < edge_limit )
-        for ( point = points; point < point_limit; point++ )
-        {
-          FT_Pos  u, ou, fu;  /* point position */
-          FT_Pos  delta;
-
-
-          if ( point->flags & touch_flag )
-            continue;
-
-#ifndef AH_OPTION_NO_WEAK_INTERPOLATION
-          /* if this point is candidate to weak interpolation, we will  */
-          /* interpolate it after all strong points have been processed */
-          if ( point->flags & ah_flah_weak_interpolation )
-            continue;
-#endif
-
-          if ( dimension )
-          {
-            u  = point->fy;
-            ou = point->oy;
-          }
-          else
-          {
-            u  = point->fx;
-            ou = point->ox;
-          }
-
-          fu = u;
-
-          /* is the point before the first edge? */
-          edge  = edges;
-          delta = edge->fpos - u;
-          if ( delta >= 0 )
-          {
-            u = edge->pos - ( edge->opos - ou );
-            goto Store_Point;
-          }
-
-          /* is the point after the last edge ? */
-          edge  = edge_limit - 1;
-          delta = u - edge->fpos;
-          if ( delta >= 0 )
-          {
-            u = edge->pos + ( ou - edge->opos );
-            goto Store_Point;
-          }
-
-          /* otherwise, interpolate the point in between */
-          {
-            AH_Edge*  before = 0;
-            AH_Edge*  after  = 0;
-
-
-            for ( edge = edges; edge < edge_limit; edge++ )
-            {
-              if ( u == edge->fpos )
-              {
-                u = edge->pos;
-                goto Store_Point;
-              }
-              if ( u < edge->fpos )
-                break;
-              before = edge;
-            }
-
-            for ( edge = edge_limit - 1; edge >= edges; edge-- )
-            {
-              if ( u == edge->fpos )
-              {
-                u = edge->pos;
-                goto Store_Point;
-              }
-              if ( u > edge->fpos )
-                break;
-              after = edge;
-            }
-
-            /* assert( before && after && before != after ) */
-            u = before->pos + FT_MulDiv( fu - before->fpos,
-                                         after->pos - before->pos,
-                                         after->fpos - before->fpos );
-          }
-
-        Store_Point:
-
-          /* save the point position */
-          if ( dimension )
-            point->y = u;
-          else
-            point->x = u;
-
-          point->flags |= touch_flag;
-        }
-
-      edges      = outline->vert_edges;
-      edge_limit = edges + outline->num_vedges;
-      touch_flag = ah_flah_touch_x;
-    }
-  }
-
-
-#ifndef AH_OPTION_NO_WEAK_INTERPOLATION
-
-  static void
-  ah_iup_shift( AH_Point*  p1,
-                AH_Point*  p2,
-                AH_Point*  ref )
-  {
-    AH_Point*  p;
-    FT_Pos     delta = ref->u - ref->v;
-
-
-    for ( p = p1; p < ref; p++ )
-      p->u = p->v + delta;
-
-    for ( p = ref + 1; p <= p2; p++ )
-      p->u = p->v + delta;
-  }
-
-
-  static void
-  ah_iup_interp( AH_Point*  p1,
-                 AH_Point*  p2,
-                 AH_Point*  ref1,
-                 AH_Point*  ref2 )
-  {
-    AH_Point*  p;
-    FT_Pos     u;
-    FT_Pos     v1 = ref1->v;
-    FT_Pos     v2 = ref2->v;
-    FT_Pos     d1 = ref1->u - v1;
-    FT_Pos     d2 = ref2->u - v2;
-
-
-    if ( p1 > p2 )
-      return;
-
-    if ( v1 == v2 )
-    {
-      for ( p = p1; p <= p2; p++ )
-      {
-        u = p->v;
-
-        if ( u <= v1 )
-          u += d1;
-        else
-          u += d2;
-
-        p->u = u;
-      }
-      return;
-    }
-
-    if ( v1 < v2 )
-    {
-      for ( p = p1; p <= p2; p++ )
-      {
-        u = p->v;
-
-        if ( u <= v1 )
-          u += d1;
-        else if ( u >= v2 )
-          u += d2;
-        else
-          u = ref1->u + FT_MulDiv( u - v1, ref2->u - ref1->u, v2 - v1 );
-
-        p->u = u;
-      }
-    }
-    else
-    {
-      for ( p = p1; p <= p2; p++ )
-      {
-        u = p->v;
-
-        if ( u <= v2 )
-          u += d2;
-        else if ( u >= v1 )
-          u += d1;
-        else
-          u = ref1->u + FT_MulDiv( u - v1, ref2->u - ref1->u, v2 - v1 );
-
-        p->u = u;
-      }
-    }
-  }
-
-
-  /* interpolate weak points -- this is equivalent to the TrueType `IUP' */
-  static void
-  ah_hinter_align_weak_points( AH_Hinter*  hinter )
-  {
-    AH_Outline*  outline = hinter->glyph;
-    FT_Int       dimension;
-    AH_Point*    points;
-    AH_Point*    point_limit;
-    AH_Point**   contour_limit;
-    AH_Flags     touch_flag;
-
-
-    points      = outline->points;
-    point_limit = points + outline->num_points;
-
-    /* PASS 1: Move segment points to edge positions */
-
-    touch_flag = ah_flah_touch_y;
-
-    contour_limit = outline->contours + outline->num_contours;
-
-    ah_setup_uv( outline, ah_uv_oy );
-
-    for ( dimension = 1; dimension >= 0; dimension-- )
-    {
-      AH_Point*   point;
-      AH_Point*   end_point;
-      AH_Point*   first_point;
-      AH_Point**  contour;
-
-
-      point   = points;
-      contour = outline->contours;
-
-      for ( ; contour < contour_limit; contour++ )
-      {
-        point       = *contour;
-        end_point   = point->prev;
-        first_point = point;
-
-        while ( point <= end_point && !( point->flags & touch_flag ) )
-          point++;
-
-        if ( point <= end_point )
-        {
-          AH_Point*  first_touched = point;
-          AH_Point*  cur_touched   = point;
-
-
-          point++;
-          while ( point <= end_point )
-          {
-            if ( point->flags & touch_flag )
-            {
-              /* we found two successive touched points; we interpolate */
-              /* all contour points between them                        */
-              ah_iup_interp( cur_touched + 1, point - 1,
-                             cur_touched, point );
-              cur_touched = point;
-            }
-            point++;
-          }
-
-          if ( cur_touched == first_touched )
-          {
-            /* this is a special case: only one point was touched in the */
-            /* contour; we thus simply shift the whole contour           */
-            ah_iup_shift( first_point, end_point, cur_touched );
-          }
-          else
-          {
-            /* now interpolate after the last touched point to the end */
-            /* of the contour                                          */
-            ah_iup_interp( cur_touched + 1, end_point,
-                           cur_touched, first_touched );
-
-            /* if the first contour point isn't touched, interpolate */
-            /* from the contour start to the first touched point     */
-            if ( first_touched > points )
-              ah_iup_interp( first_point, first_touched - 1,
-                             cur_touched, first_touched );
-          }
-        }
-      }
-
-      /* now save the interpolated values back to x/y */
-      if ( dimension )
-      {
-        for ( point = points; point < point_limit; point++ )
-          point->y = point->u;
-
-        touch_flag = ah_flah_touch_x;
-        ah_setup_uv( outline, ah_uv_ox );
-      }
-      else
-      {
-        for ( point = points; point < point_limit; point++ )
-          point->x = point->u;
-
-        break;  /* exit loop */
-      }
-    }
-  }
-
-#endif /* !AH_OPTION_NO_WEAK_INTERPOLATION */
-
-
-  FT_LOCAL_DEF void
-  ah_hinter_align_points( AH_Hinter*  hinter )
-  {
-    ah_hinter_align_edge_points( hinter );
-
-#ifndef AH_OPTION_NO_STRONG_INTERPOLATION
-    ah_hinter_align_strong_points( hinter );
-#endif
-
-#ifndef AH_OPTION_NO_WEAK_INTERPOLATION
-    ah_hinter_align_weak_points( hinter );
-#endif
-  }
-
-
-  /*************************************************************************/
-  /*************************************************************************/
-  /*************************************************************************/
-  /****                                                                 ****/
-  /****       H I N T E R   O B J E C T   M E T H O D S                 ****/
-  /****                                                                 ****/
-  /*************************************************************************/
-  /*************************************************************************/
-  /*************************************************************************/
-
-
-  /* scale and fit the global metrics */
-  static void
-  ah_hinter_scale_globals( AH_Hinter*  hinter,
-                           FT_Fixed    x_scale,
-                           FT_Fixed    y_scale )
-  {
-    FT_Int            n;
-    AH_Face_Globals*  globals = hinter->globals;
-    AH_Globals*       design = &globals->design;
-    AH_Globals*       scaled = &globals->scaled;
-
-
-    /* copy content */
-    *scaled = *design;
-
-    /* scale the standard widths & heights */
-    for ( n = 0; n < design->num_widths; n++ )
-      scaled->widths[n] = FT_MulFix( design->widths[n], x_scale );
-
-    for ( n = 0; n < design->num_heights; n++ )
-      scaled->heights[n] = FT_MulFix( design->heights[n], y_scale );
-
-    /* scale the blue zones */
-    for ( n = 0; n < ah_blue_max; n++ )
-    {
-      FT_Pos  delta, delta2;
-
-
-      delta = design->blue_shoots[n] - design->blue_refs[n];
-      delta2 = delta;
-      if ( delta < 0 )
-        delta2 = -delta2;
-      delta2 = FT_MulFix( delta2, y_scale );
-
-      if ( delta2 < 32 )
-        delta2 = 0;
-      else if ( delta2 < 64 )
-        delta2 = 32 + ( ( ( delta2 - 32 ) + 16 ) & -32 );
-      else
-        delta2 = ( delta2 + 32 ) & -64;
-
-      if ( delta < 0 )
-        delta2 = -delta2;
-
-      scaled->blue_refs[n] =
-        ( FT_MulFix( design->blue_refs[n], y_scale ) + 32 ) & -64;
-      scaled->blue_shoots[n] = scaled->blue_refs[n] + delta2;
-    }
-
-    globals->x_scale = x_scale;
-    globals->y_scale = y_scale;
-  }
-
-
-  static void
-  ah_hinter_align( AH_Hinter*  hinter )
-  {
-    ah_hinter_align_edge_points( hinter );
-    ah_hinter_align_points( hinter );
-  }
-
-
-  /* finalize a hinter object */
-  FT_LOCAL_DEF void
-  ah_hinter_done( AH_Hinter*  hinter )
-  {
-    if ( hinter )
-    {
-      FT_Memory  memory = hinter->memory;
-
-
-      ah_loader_done( hinter->loader );
-      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   */
-      /*       release it                                         */
-      hinter->globals = 0;
-      hinter->face    = 0;
-
-      FREE( hinter );
-    }
-  }
-
-
-  /* create a new empty hinter object */
-  FT_LOCAL_DEF FT_Error
-  ah_hinter_new( FT_Library   library,
-                 AH_Hinter**  ahinter )
-  {
-    AH_Hinter*  hinter = 0;
-    FT_Memory   memory = library->memory;
-    FT_Error    error;
-
-
-    *ahinter = 0;
-
-    /* allocate object */
-    if ( ALLOC( hinter, sizeof ( *hinter ) ) )
-      goto Exit;
-
-    hinter->memory = memory;
-    hinter->flags  = 0;
-
-    /* allocate outline and loader */
-    error = ah_outline_new( memory, &hinter->glyph )  ||
-            ah_loader_new ( memory, &hinter->loader ) ||
-            ah_loader_create_extra( hinter->loader );
-    if ( error )
-      goto Exit;
-
-    *ahinter = hinter;
-
-  Exit:
-    if ( error )
-      ah_hinter_done( hinter );
-
-    return error;
-  }
-
-
-  /* create a face's autohint globals */
-  FT_LOCAL_DEF FT_Error
-  ah_hinter_new_face_globals( AH_Hinter*   hinter,
-                              FT_Face      face,
-                              AH_Globals*  globals )
-  {
-    FT_Error          error;
-    FT_Memory         memory = hinter->memory;
-    AH_Face_Globals*  face_globals;
-
-
-    if ( ALLOC( face_globals, sizeof ( *face_globals ) ) )
-      goto Exit;
-
-    hinter->face    = face;
-    hinter->globals = face_globals;
-
-    if ( globals )
-      face_globals->design = *globals;
-    else
-      ah_hinter_compute_globals( hinter );
-
-    face->autohint.data      = face_globals;
-    face->autohint.finalizer = (FT_Generic_Finalizer)
-                                 ah_hinter_done_face_globals;
-    face_globals->face       = face;
-
-  Exit:
-    return error;
-  }
-
-
-  /* discard a face's autohint globals */
-  FT_LOCAL_DEF void
-  ah_hinter_done_face_globals( AH_Face_Globals*  globals )
-  {
-    FT_Face    face   = globals->face;
-    FT_Memory  memory = face->memory;
-
-
-    FREE( globals );
-  }
-
-
-  static FT_Error
-  ah_hinter_load( AH_Hinter*  hinter,
-                  FT_UInt     glyph_index,
-                  FT_UInt     load_flags,
-                  FT_UInt     depth )
-  {
-    FT_Face           face     = hinter->face;
-    FT_GlyphSlot      slot     = face->glyph;
-    FT_Slot_Internal  internal = slot->internal;
-    FT_Fixed          x_scale  = face->size->metrics.x_scale;
-    FT_Fixed          y_scale  = face->size->metrics.y_scale;
-    FT_Error          error;
-    AH_Outline*       outline  = hinter->glyph;
-    AH_Loader*        gloader  = hinter->loader;
-    FT_Bool           no_horz_hints = FT_BOOL(
-                        ( load_flags & AH_HINT_NO_HORZ_EDGES ) != 0 );
-    FT_Bool           no_vert_hints = FT_BOOL(
-                        ( load_flags & AH_HINT_NO_VERT_EDGES ) != 0 );
-
-
-    /* load the glyph */
-    error = FT_Load_Glyph( face, glyph_index, load_flags );
-    if ( error )
-      goto Exit;
-
-    /* Set `hinter->transformed' after loading with FT_LOAD_NO_RECURSE. */
-    hinter->transformed = internal->glyph_transformed;
-
-    if ( hinter->transformed )
-    {
-      FT_Matrix  imatrix;
-
-      imatrix              = internal->glyph_matrix;
-      hinter->trans_delta  = internal->glyph_delta;
-      hinter->trans_matrix = imatrix;
-
-      FT_Matrix_Invert( &imatrix );
-      FT_Vector_Transform( &hinter->trans_delta, &imatrix );
-    }
-
-    /* set linear horizontal metrics */
-    slot->linearHoriAdvance = slot->metrics.horiAdvance;
-    slot->linearVertAdvance = slot->metrics.vertAdvance;
-
-    switch ( slot->format )
-    {
-    case ft_glyph_format_outline:
-
-      /* translate glyph outline if we need to */
-      if ( hinter->transformed )
-      {
-        FT_UInt     n     = slot->outline.n_points;
-        FT_Vector*  point = slot->outline.points;
-
-
-        for ( ; n > 0; point++, n-- )
-        {
-          point->x += hinter->trans_delta.x;
-          point->y += hinter->trans_delta.y;
-        }
-      }
-
-      /* 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 )
-        goto Exit;
-
-      MEM_Copy( gloader->current.extra_points, slot->outline.points,
-                slot->outline.n_points * sizeof ( FT_Vector ) );
-
-      MEM_Copy( gloader->current.outline.contours, slot->outline.contours,
-                slot->outline.n_contours * sizeof ( short ) );
-
-      MEM_Copy( gloader->current.outline.tags, slot->outline.tags,
-                slot->outline.n_points * sizeof ( char ) );
-
-      gloader->current.outline.n_points   = slot->outline.n_points;
-      gloader->current.outline.n_contours = slot->outline.n_contours;
-
-      /* compute original phantom points */
-      hinter->pp1.x = 0;
-      hinter->pp1.y = 0;
-      hinter->pp2.x = FT_MulFix( slot->metrics.horiAdvance, x_scale );
-      hinter->pp2.y = 0;
-
-      /* be sure to check for spacing glyphs */
-      if ( slot->outline.n_points == 0 )
-        goto Hint_Metrics;
-
-      /* now, load the slot image into the auto-outline, and run the */
-      /* automatic hinting process                                   */
-      error = ah_outline_load( outline, face );   /* XXX: change to slot */
-      if ( error )
-        goto Exit;
-
-      /* perform feature detection */
-      ah_outline_detect_features( outline );
-
-      if ( !no_horz_hints )
-      {
-        ah_outline_compute_blue_edges( outline, hinter->globals );
-        ah_outline_scale_blue_edges( outline, hinter->globals );
-      }
-
-      /* perform alignment control */
-      ah_hinter_hint_edges( hinter, no_horz_hints, no_vert_hints );
-      ah_hinter_align( hinter );
-
-      /* now save the current outline into the loader's current table */
-      ah_outline_save( outline, gloader );
-
-      /* we now need to hint the metrics according to the change in */
-      /* width/positioning that occured during the hinting process  */
-      {
-        FT_Pos    old_advance;
-        FT_Pos    old_lsb, new_lsb;
-        AH_Edge*  edge1 = outline->vert_edges;     /* leftmost edge  */
-        AH_Edge*  edge2 = edge1 +
-                          outline->num_vedges - 1; /* rightmost edge */
-
-
-        old_advance = hinter->pp2.x;
-        old_lsb     = edge1->opos;
-        new_lsb     = edge1->pos;
-
-        hinter->pp1.x = ( ( new_lsb - old_lsb ) + 32 ) & -64;
-        hinter->pp2.x = ( ( edge2->pos +
-                            ( old_advance - edge2->opos ) ) + 32 ) & -64;
-      }
-
-      /* good, we simply add the glyph to our loader's base */
-      ah_loader_add( gloader );
-      break;
-
-    case ft_glyph_format_composite:
-      {
-        FT_UInt       nn, num_subglyphs = slot->num_subglyphs;
-        FT_UInt       num_base_subgs, start_point;
-        FT_SubGlyph*  subglyph;
-
-
-        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 );
-        if ( error )
-          goto Exit;
-
-        MEM_Copy( gloader->current.subglyphs, slot->subglyphs,
-                  num_subglyphs * sizeof ( FT_SubGlyph ) );
-
-        gloader->current.num_subglyphs = num_subglyphs;
-        num_base_subgs = gloader->base.num_subglyphs;
-
-        /* now, read each subglyph independently */
-        for ( nn = 0; nn < num_subglyphs; nn++ )
-        {
-          FT_Vector  pp1, pp2;
-          FT_Pos     x, y;
-          FT_UInt    num_points, num_new_points, num_base_points;
-
-
-          /* gloader.current.subglyphs can change during glyph loading due */
-          /* to re-allocation -- we must recompute the current subglyph on */
-          /* each iteration                                                */
-          subglyph = gloader->base.subglyphs + num_base_subgs + nn;
-
-          pp1 = hinter->pp1;
-          pp2 = hinter->pp2;
-
-          num_base_points = gloader->base.outline.n_points;
-
-          error = ah_hinter_load( hinter, subglyph->index,
-                                  load_flags, depth + 1 );
-          if ( error )
-            goto Exit;
-
-          /* recompute subglyph pointer */
-          subglyph = gloader->base.subglyphs + num_base_subgs + nn;
-
-          if ( subglyph->flags & FT_SUBGLYPH_FLAG_USE_MY_METRICS )
-          {
-            pp1 = hinter->pp1;
-            pp2 = hinter->pp2;
-          }
-          else
-          {
-            hinter->pp1 = pp1;
-            hinter->pp2 = pp2;
-          }
-
-          num_points     = gloader->base.outline.n_points;
-          num_new_points = num_points - num_base_points;
-
-          /* now perform the transform required for this subglyph */
-
-          if ( subglyph->flags & ( FT_SUBGLYPH_FLAG_SCALE    |
-                                   FT_SUBGLYPH_FLAG_XY_SCALE |
-                                   FT_SUBGLYPH_FLAG_2X2      ) )
-          {
-            FT_Vector*  cur   = gloader->base.outline.points +
-                                num_base_points;
-            FT_Vector*  org   = gloader->base.extra_points +
-                                num_base_points;
-            FT_Vector*  limit = cur + num_new_points;
-
-
-            for ( ; cur < limit; cur++, org++ )
-            {
-              FT_Vector_Transform( cur, &subglyph->transform );
-              FT_Vector_Transform( org, &subglyph->transform );
-            }
-          }
-
-          /* apply offset */
-
-          if ( !( subglyph->flags & FT_SUBGLYPH_FLAG_ARGS_ARE_XY_VALUES ) )
-          {
-            FT_Int      k = subglyph->arg1;
-            FT_UInt     l = subglyph->arg2;
-            FT_Vector*  p1;
-            FT_Vector*  p2;
-
-
-            if ( start_point + k >= num_base_points          ||
-                               l >= (FT_UInt)num_new_points  )
-            {
-              error = AH_Err_Invalid_Composite;
-              goto Exit;
-            }
-
-            l += num_base_points;
-
-            /* 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;
-
-            x = p1->x - p2->x;
-            y = p1->y - p2->y;
-          }
-          else
-          {
-            x = FT_MulFix( subglyph->arg1, x_scale );
-            y = FT_MulFix( subglyph->arg2, y_scale );
-
-            x = ( x + 32 ) & -64;
-            y = ( y + 32 ) & -64;
-          }
-
-          {
-            FT_Outline  dummy = gloader->base.outline;
-
-
-            dummy.points  += num_base_points;
-            dummy.n_points = (short)num_new_points;
-
-            FT_Outline_Translate( &dummy, x, y );
-          }
-        }
-      }
-      break;
-
-    default:
-      /* we don't support other formats (yet?) */
-      error = AH_Err_Unimplemented_Feature;
-    }
-
-  Hint_Metrics:
-    if ( depth == 0 )
-    {
-      FT_BBox  bbox;
-
-
-      /* transform the hinted outline if needed */
-      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                                            */
-      if ( hinter->pp1.x )
-        FT_Outline_Translate( &gloader->base.outline, -hinter->pp1.x, 0 );
-
-      FT_Outline_Get_CBox( &gloader->base.outline, &bbox );
-      bbox.xMin &= -64;
-      bbox.yMin &= -64;
-      bbox.xMax  = ( bbox.xMax + 63 ) & -64;
-      bbox.yMax  = ( bbox.yMax + 63 ) & -64;
-
-      slot->metrics.width        = bbox.xMax - bbox.xMin;
-      slot->metrics.height       = bbox.yMax - bbox.yMin;
-      slot->metrics.horiBearingX = bbox.xMin;
-      slot->metrics.horiBearingY = bbox.yMax;
-      slot->metrics.horiAdvance  = hinter->pp2.x - hinter->pp1.x;
-      /* XXX: TO DO - slot->linearHoriAdvance */
-
-      /* now copy outline into glyph slot */
-      ah_loader_rewind( slot->internal->loader );
-      error = ah_loader_copy_points( slot->internal->loader, gloader );
-      if ( error )
-        goto Exit;
-
-      slot->outline = slot->internal->loader->base.outline;
-      slot->format  = ft_glyph_format_outline;
-    }
-
-  Exit:
-    return error;
-  }
-
-
-  /* load and hint a given glyph */
-  FT_LOCAL_DEF FT_Error
-  ah_hinter_load_glyph( AH_Hinter*    hinter,
-                        FT_GlyphSlot  slot,
-                        FT_Size       size,
-                        FT_UInt       glyph_index,
-                        FT_Int        load_flags )
-  {
-    FT_Face           face         = slot->face;
-    FT_Error          error;
-    FT_Fixed          x_scale      = size->metrics.x_scale;
-    FT_Fixed          y_scale      = size->metrics.y_scale;
-    AH_Face_Globals*  face_globals = FACE_GLOBALS( face );
-
-
-    /* first of all, we need to check that we're using the correct face and */
-    /* global hints to load the glyph                                       */
-    if ( hinter->face != face || hinter->globals != face_globals )
-    {
-      hinter->face = face;
-      if ( !face_globals )
-      {
-        error = ah_hinter_new_face_globals( hinter, face, 0 );
-        if ( error )
-          goto Exit;
-
-      }
-      hinter->globals = FACE_GLOBALS( face );
-      face_globals    = FACE_GLOBALS( face );
-
-    }
-
-    /* now, we must check the current character pixel size to see if we */
-    /* need to rescale the global metrics                               */
-    if ( face_globals->x_scale != x_scale ||
-         face_globals->y_scale != y_scale )
-      ah_hinter_scale_globals( hinter, x_scale, y_scale );
-
-    ah_loader_rewind( hinter->loader );
-
-#if 1
-    load_flags  = FT_LOAD_NO_SCALE
-                | FT_LOAD_IGNORE_TRANSFORM ;
-#else
-    load_flags |= FT_LOAD_NO_SCALE | FT_LOAD_NO_RECURSE;
-#endif
-
-    error = ah_hinter_load( hinter, glyph_index, load_flags, 0 );
-
-  Exit:
-    return error;
-  }
-
-
-  /* retrieve a face's autohint globals for client applications */
-  FT_LOCAL_DEF void
-  ah_hinter_get_global_hints( AH_Hinter*  hinter,
-                              FT_Face     face,
-                              void**      global_hints,
-                              long*       global_len )
-  {
-    AH_Globals*  globals = 0;
-    FT_Memory    memory  = hinter->memory;
-    FT_Error     error;
-
-
-    /* allocate new master globals */
-    if ( ALLOC( globals, sizeof ( *globals ) ) )
-      goto Fail;
-
-    /* compute face globals if needed */
-    if ( !FACE_GLOBALS( face ) )
-    {
-      error = ah_hinter_new_face_globals( hinter, face, 0 );
-      if ( error )
-        goto Fail;
-    }
-
-    *globals      = FACE_GLOBALS( face )->design;
-    *global_hints = globals;
-    *global_len   = sizeof( *globals );
-
-    return;
-
-  Fail:
-    FREE( globals );
-
-    *global_hints = 0;
-    *global_len   = 0;
-  }
-
-
-  FT_LOCAL_DEF void
-  ah_hinter_done_global_hints( AH_Hinter*  hinter,
-                               void*       global_hints )
-  {
-    FT_Memory  memory = hinter->memory;
-
-
-    FREE( global_hints );
-  }
-
-
-/* END */