/****************************************************************************
 *
 * afhints.c
 *
 *   Auto-fitter hinting routines (body).
 *
 * Copyright (C) 2003-2021 by
 * David Turner, Robert Wilhelm, and Werner Lemberg.
 *
 * This file is part of the FreeType project, and may only be used,
 * modified, and distributed under the terms of the FreeType project
 * license, LICENSE.TXT.  By continuing to use, modify, or distribute
 * this file you indicate that you have read the license and
 * understand and accept it fully.
 *
 */


#include "afhints.h"
#include "aferrors.h"
#include <freetype/internal/ftcalc.h>
#include <freetype/internal/ftdebug.h>


  /**************************************************************************
   *
   * The macro FT_COMPONENT is used in trace mode.  It is an implicit
   * parameter of the FT_TRACE() and FT_ERROR() macros, used to print/log
   * messages during execution.
   */
#undef  FT_COMPONENT
#define FT_COMPONENT  afhints


  FT_LOCAL_DEF( void )
  af_sort_pos( FT_UInt  count,
               FT_Pos*  table )
  {
    FT_UInt  i, j;
    FT_Pos   swap;


    for ( i = 1; i < count; i++ )
    {
      for ( j = i; j > 0; j-- )
      {
        if ( table[j] >= table[j - 1] )
          break;

        swap         = table[j];
        table[j]     = table[j - 1];
        table[j - 1] = swap;
      }
    }
  }


  FT_LOCAL_DEF( void )
  af_sort_and_quantize_widths( FT_UInt*  count,
                               AF_Width  table,
                               FT_Pos    threshold )
  {
    FT_UInt      i, j;
    FT_UInt      cur_idx;
    FT_Pos       cur_val;
    FT_Pos       sum;
    AF_WidthRec  swap;


    if ( *count == 1 )
      return;

    /* sort */
    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;
      }
    }

    cur_idx = 0;
    cur_val = table[cur_idx].org;

    /* compute and use mean values for clusters not larger than  */
    /* `threshold'; this is very primitive and might not yield   */
    /* the best result, but normally, using reference character  */
    /* `o', `*count' is 2, so the code below is fully sufficient */
    for ( i = 1; i < *count; i++ )
    {
      if ( table[i].org - cur_val > threshold ||
           i == *count - 1                    )
      {
        sum = 0;

        /* fix loop for end of array */
        if ( table[i].org - cur_val <= threshold &&
             i == *count - 1                     )
          i++;

        for ( j = cur_idx; j < i; j++ )
        {
          sum         += table[j].org;
          table[j].org = 0;
        }
        table[cur_idx].org = sum / (FT_Pos)j;

        if ( i < *count - 1 )
        {
          cur_idx = i + 1;
          cur_val = table[cur_idx].org;
        }
      }
    }

    cur_idx = 1;

    /* compress array to remove zero values */
    for ( i = 1; i < *count; i++ )
    {
      if ( table[i].org )
        table[cur_idx++] = table[i];
    }

    *count = cur_idx;
  }

  /* Get new segment for given axis. */

  FT_LOCAL_DEF( FT_Error )
  af_axis_hints_new_segment( AF_AxisHints  axis,
                             FT_Memory     memory,
                             AF_Segment   *asegment )
  {
    FT_Error    error   = FT_Err_Ok;
    AF_Segment  segment = NULL;


    if ( axis->num_segments < AF_SEGMENTS_EMBEDDED )
    {
      if ( !axis->segments )
      {
        axis->segments     = axis->embedded.segments;
        axis->max_segments = AF_SEGMENTS_EMBEDDED;
      }
    }
    else if ( axis->num_segments >= axis->max_segments )
    {
      FT_Int  old_max = axis->max_segments;
      FT_Int  new_max = old_max;
      FT_Int  big_max = (FT_Int)( FT_INT_MAX / sizeof ( *segment ) );


      if ( old_max >= big_max )
      {
        error = FT_THROW( Out_Of_Memory );
        goto Exit;
      }

      new_max += ( new_max >> 2 ) + 4;
      if ( new_max < old_max || new_max > big_max )
        new_max = big_max;

      if ( axis->segments == axis->embedded.segments )
      {
        if ( FT_NEW_ARRAY( axis->segments, new_max ) )
          goto Exit;
        ft_memcpy( axis->segments, axis->embedded.segments,
                   sizeof ( axis->embedded.segments ) );
      }
      else
      {
        if ( FT_RENEW_ARRAY( axis->segments, old_max, new_max ) )
          goto Exit;
      }

      axis->max_segments = new_max;
    }

    segment = axis->segments + axis->num_segments++;

  Exit:
    *asegment = segment;
    return error;
  }


  /* Get new edge for given axis, direction, and position, */
  /* without initializing the edge itself.                 */

  FT_LOCAL( FT_Error )
  af_axis_hints_new_edge( AF_AxisHints  axis,
                          FT_Int        fpos,
                          AF_Direction  dir,
                          FT_Bool       top_to_bottom_hinting,
                          FT_Memory     memory,
                          AF_Edge      *anedge )
  {
    FT_Error  error = FT_Err_Ok;
    AF_Edge   edge  = NULL;
    AF_Edge   edges;


    if ( axis->num_edges < AF_EDGES_EMBEDDED )
    {
      if ( !axis->edges )
      {
        axis->edges     = axis->embedded.edges;
        axis->max_edges = AF_EDGES_EMBEDDED;
      }
    }
    else if ( axis->num_edges >= axis->max_edges )
    {
      FT_Int  old_max = axis->max_edges;
      FT_Int  new_max = old_max;
      FT_Int  big_max = (FT_Int)( FT_INT_MAX / sizeof ( *edge ) );


      if ( old_max >= big_max )
      {
        error = FT_THROW( Out_Of_Memory );
        goto Exit;
      }

      new_max += ( new_max >> 2 ) + 4;
      if ( new_max < old_max || new_max > big_max )
        new_max = big_max;

      if ( axis->edges == axis->embedded.edges )
      {
        if ( FT_NEW_ARRAY( axis->edges, new_max ) )
          goto Exit;
        ft_memcpy( axis->edges, axis->embedded.edges,
                   sizeof ( axis->embedded.edges ) );
      }
      else
      {
        if ( FT_RENEW_ARRAY( axis->edges, old_max, new_max ) )
          goto Exit;
      }

      axis->max_edges = new_max;
    }

    edges = axis->edges;
    edge  = edges + axis->num_edges;

    while ( edge > edges )
    {
      if ( top_to_bottom_hinting ? ( edge[-1].fpos > fpos )
                                 : ( edge[-1].fpos < fpos ) )
        break;

      /* we want the edge with same position and minor direction */
      /* to appear before those in the major one in the list     */
      if ( edge[-1].fpos == fpos && dir == axis->major_dir )
        break;

      edge[0] = edge[-1];
      edge--;
    }

    axis->num_edges++;

  Exit:
    *anedge = edge;
    return error;
  }


#ifdef FT_DEBUG_AUTOFIT

#include FT_CONFIG_STANDARD_LIBRARY_H

  /* The dump functions are used in the `ftgrid' demo program, too. */
#define AF_DUMP( varformat )          \
          do                          \
          {                           \
            if ( to_stdout )          \
              printf varformat;       \
            else                      \
              FT_TRACE7( varformat ); \
          } while ( 0 )


  static const char*
  af_dir_str( AF_Direction  dir )
  {
    const char*  result;


    switch ( dir )
    {
    case AF_DIR_UP:
      result = "up";
      break;
    case AF_DIR_DOWN:
      result = "down";
      break;
    case AF_DIR_LEFT:
      result = "left";
      break;
    case AF_DIR_RIGHT:
      result = "right";
      break;
    default:
      result = "none";
    }

    return result;
  }


#define AF_INDEX_NUM( ptr, base )  (int)( (ptr) ? ( (ptr) - (base) ) : -1 )


  static char*
  af_print_idx( char* p,
                int   idx )
  {
    if ( idx == -1 )
    {
      p[0] = '-';
      p[1] = '-';
      p[2] = '\0';
    }
    else
      ft_sprintf( p, "%d", idx );

    return p;
  }


  static int
  af_get_segment_index( AF_GlyphHints  hints,
                        int            point_idx,
                        int            dimension )
  {
    AF_AxisHints  axis     = &hints->axis[dimension];
    AF_Point      point    = hints->points + point_idx;
    AF_Segment    segments = axis->segments;
    AF_Segment    limit    = segments + axis->num_segments;
    AF_Segment    segment;


    for ( segment = segments; segment < limit; segment++ )
    {
      if ( segment->first <= segment->last )
      {
        if ( point >= segment->first && point <= segment->last )
          break;
      }
      else
      {
        AF_Point  p = segment->first;


        for (;;)
        {
          if ( point == p )
            goto Exit;

          if ( p == segment->last )
            break;

          p = p->next;
        }
      }
    }

  Exit:
    if ( segment == limit )
      return -1;

    return (int)( segment - segments );
  }


  static int
  af_get_edge_index( AF_GlyphHints  hints,
                     int            segment_idx,
                     int            dimension )
  {
    AF_AxisHints  axis    = &hints->axis[dimension];
    AF_Edge       edges   = axis->edges;
    AF_Segment    segment = axis->segments + segment_idx;


    return segment_idx == -1 ? -1 : AF_INDEX_NUM( segment->edge, edges );
  }


  static int
  af_get_strong_edge_index( AF_GlyphHints  hints,
                            AF_Edge*       strong_edges,
                            int            dimension )
  {
    AF_AxisHints  axis  = &hints->axis[dimension];
    AF_Edge       edges = axis->edges;


    return AF_INDEX_NUM( strong_edges[dimension], edges );
  }


#ifdef __cplusplus
  extern "C" {
#endif
  void
  af_glyph_hints_dump_points( AF_GlyphHints  hints,
                              FT_Bool        to_stdout )
  {
    AF_Point   points  = hints->points;
    AF_Point   limit   = points + hints->num_points;
    AF_Point*  contour = hints->contours;
    AF_Point*  climit  = contour + hints->num_contours;
    AF_Point   point;


    AF_DUMP(( "Table of points:\n" ));

    if ( hints->num_points )
    {
      AF_DUMP(( "  index  hedge  hseg  vedge  vseg  flags "
             /* "  XXXXX  XXXXX XXXXX  XXXXX XXXXX  XXXXXX" */
                "  xorg  yorg  xscale  yscale   xfit    yfit "
             /* " XXXXX XXXXX XXXX.XX XXXX.XX XXXX.XX XXXX.XX" */
                "  hbef  haft  vbef  vaft" ));
             /* " XXXXX XXXXX XXXXX XXXXX" */
    }
    else
      AF_DUMP(( "  (none)\n" ));

    for ( point = points; point < limit; point++ )
    {
      int  point_idx     = AF_INDEX_NUM( point, points );
      int  segment_idx_0 = af_get_segment_index( hints, point_idx, 0 );
      int  segment_idx_1 = af_get_segment_index( hints, point_idx, 1 );

      char  buf1[16], buf2[16], buf3[16], buf4[16];
      char  buf5[16], buf6[16], buf7[16], buf8[16];


      /* insert extra newline at the beginning of a contour */
      if ( contour < climit && *contour == point )
      {
        AF_DUMP(( "\n" ));
        contour++;
      }

      AF_DUMP(( "  %5d  %5s %5s  %5s %5s  %s"
                " %5d %5d %7.2f %7.2f %7.2f %7.2f"
                " %5s %5s %5s %5s\n",
                point_idx,
                af_print_idx( buf1,
                              af_get_edge_index( hints, segment_idx_1, 1 ) ),
                af_print_idx( buf2, segment_idx_1 ),
                af_print_idx( buf3,
                              af_get_edge_index( hints, segment_idx_0, 0 ) ),
                af_print_idx( buf4, segment_idx_0 ),
                ( point->flags & AF_FLAG_NEAR )
                  ? " near "
                  : ( point->flags & AF_FLAG_WEAK_INTERPOLATION )
                    ? " weak "
                    : "strong",

                point->fx,
                point->fy,
                point->ox / 64.0,
                point->oy / 64.0,
                point->x / 64.0,
                point->y / 64.0,

                af_print_idx( buf5, af_get_strong_edge_index( hints,
                                                              point->before,
                                                              1 ) ),
                af_print_idx( buf6, af_get_strong_edge_index( hints,
                                                              point->after,
                                                              1 ) ),
                af_print_idx( buf7, af_get_strong_edge_index( hints,
                                                              point->before,
                                                              0 ) ),
                af_print_idx( buf8, af_get_strong_edge_index( hints,
                                                              point->after,
                                                              0 ) ) ));
    }
    AF_DUMP(( "\n" ));
  }
#ifdef __cplusplus
  }
#endif


  static const char*
  af_edge_flags_to_string( FT_UInt  flags )
  {
    static char  temp[32];
    int          pos = 0;


    if ( flags & AF_EDGE_ROUND )
    {
      ft_memcpy( temp + pos, "round", 5 );
      pos += 5;
    }
    if ( flags & AF_EDGE_SERIF )
    {
      if ( pos > 0 )
        temp[pos++] = ' ';
      ft_memcpy( temp + pos, "serif", 5 );
      pos += 5;
    }
    if ( pos == 0 )
      return "normal";

    temp[pos] = '\0';

    return temp;
  }


  /* Dump the array of linked segments. */

#ifdef __cplusplus
  extern "C" {
#endif
  void
  af_glyph_hints_dump_segments( AF_GlyphHints  hints,
                                FT_Bool        to_stdout )
  {
    FT_Int  dimension;


    for ( dimension = 1; dimension >= 0; dimension-- )
    {
      AF_AxisHints  axis     = &hints->axis[dimension];
      AF_Point      points   = hints->points;
      AF_Edge       edges    = axis->edges;
      AF_Segment    segments = axis->segments;
      AF_Segment    limit    = segments + axis->num_segments;
      AF_Segment    seg;

      char  buf1[16], buf2[16], buf3[16];


      AF_DUMP(( "Table of %s segments:\n",
                dimension == AF_DIMENSION_HORZ ? "vertical"
                                               : "horizontal" ));
      if ( axis->num_segments )
      {
        AF_DUMP(( "  index   pos   delta   dir   from   to "
               /* "  XXXXX  XXXXX  XXXXX  XXXXX  XXXX  XXXX" */
                  "  link  serif  edge"
               /* "  XXXX  XXXXX  XXXX" */
                  "  height  extra     flags\n" ));
               /* "  XXXXXX  XXXXX  XXXXXXXXXXX" */
      }
      else
        AF_DUMP(( "  (none)\n" ));

      for ( seg = segments; seg < limit; seg++ )
        AF_DUMP(( "  %5d  %5d  %5d  %5s  %4d  %4d"
                  "  %4s  %5s  %4s"
                  "  %6d  %5d  %11s\n",
                  AF_INDEX_NUM( seg, segments ),
                  seg->pos,
                  seg->delta,
                  af_dir_str( (AF_Direction)seg->dir ),
                  AF_INDEX_NUM( seg->first, points ),
                  AF_INDEX_NUM( seg->last, points ),

                  af_print_idx( buf1, AF_INDEX_NUM( seg->link, segments ) ),
                  af_print_idx( buf2, AF_INDEX_NUM( seg->serif, segments ) ),
                  af_print_idx( buf3, AF_INDEX_NUM( seg->edge, edges ) ),

                  seg->height,
                  seg->height - ( seg->max_coord - seg->min_coord ),
                  af_edge_flags_to_string( seg->flags ) ));
      AF_DUMP(( "\n" ));
    }
  }
#ifdef __cplusplus
  }
#endif


  /* Fetch number of segments. */

#ifdef __cplusplus
  extern "C" {
#endif
  FT_Error
  af_glyph_hints_get_num_segments( AF_GlyphHints  hints,
                                   FT_Int         dimension,
                                   FT_Int*        num_segments )
  {
    AF_Dimension  dim;
    AF_AxisHints  axis;


    dim = ( dimension == 0 ) ? AF_DIMENSION_HORZ : AF_DIMENSION_VERT;

    axis          = &hints->axis[dim];
    *num_segments = axis->num_segments;

    return FT_Err_Ok;
  }
#ifdef __cplusplus
  }
#endif


  /* Fetch offset of segments into user supplied offset array. */

#ifdef __cplusplus
  extern "C" {
#endif
  FT_Error
  af_glyph_hints_get_segment_offset( AF_GlyphHints  hints,
                                     FT_Int         dimension,
                                     FT_Int         idx,
                                     FT_Pos        *offset,
                                     FT_Bool       *is_blue,
                                     FT_Pos        *blue_offset )
  {
    AF_Dimension  dim;
    AF_AxisHints  axis;
    AF_Segment    seg;


    if ( !offset )
      return FT_THROW( Invalid_Argument );

    dim = ( dimension == 0 ) ? AF_DIMENSION_HORZ : AF_DIMENSION_VERT;

    axis = &hints->axis[dim];

    if ( idx < 0 || idx >= axis->num_segments )
      return FT_THROW( Invalid_Argument );

    seg      = &axis->segments[idx];
    *offset  = ( dim == AF_DIMENSION_HORZ ) ? seg->first->fx
                                            : seg->first->fy;
    if ( seg->edge )
      *is_blue = FT_BOOL( seg->edge->blue_edge );
    else
      *is_blue = FALSE;

    if ( *is_blue )
      *blue_offset = seg->edge->blue_edge->org;
    else
      *blue_offset = 0;

    return FT_Err_Ok;
  }
#ifdef __cplusplus
  }
#endif


  /* Dump the array of linked edges. */

#ifdef __cplusplus
  extern "C" {
#endif
  void
  af_glyph_hints_dump_edges( AF_GlyphHints  hints,
                             FT_Bool        to_stdout )
  {
    FT_Int  dimension;


    for ( dimension = 1; dimension >= 0; dimension-- )
    {
      AF_AxisHints  axis  = &hints->axis[dimension];
      AF_Edge       edges = axis->edges;
      AF_Edge       limit = edges + axis->num_edges;
      AF_Edge       edge;

      char  buf1[16], buf2[16];


      /*
       * note: AF_DIMENSION_HORZ corresponds to _vertical_ edges
       *       since they have a constant X coordinate.
       */
      if ( dimension == AF_DIMENSION_HORZ )
        AF_DUMP(( "Table of %s edges (1px=%.2fu, 10u=%.2fpx):\n",
                  "vertical",
                  65536.0 * 64.0 / hints->x_scale,
                  10.0 * hints->x_scale / 65536.0 / 64.0 ));
      else
        AF_DUMP(( "Table of %s edges (1px=%.2fu, 10u=%.2fpx):\n",
                  "horizontal",
                  65536.0 * 64.0 / hints->y_scale,
                  10.0 * hints->y_scale / 65536.0 / 64.0 ));

      if ( axis->num_edges )
      {
        AF_DUMP(( "  index    pos     dir   link  serif"
               /* "  XXXXX  XXXX.XX  XXXXX  XXXX  XXXXX" */
                  "  blue    opos     pos       flags\n" ));
               /* "    X   XXXX.XX  XXXX.XX  XXXXXXXXXXX" */
      }
      else
        AF_DUMP(( "  (none)\n" ));

      for ( edge = edges; edge < limit; edge++ )
        AF_DUMP(( "  %5d  %7.2f  %5s  %4s  %5s"
                  "    %c   %7.2f  %7.2f  %11s\n",
                  AF_INDEX_NUM( edge, edges ),
                  (int)edge->opos / 64.0,
                  af_dir_str( (AF_Direction)edge->dir ),
                  af_print_idx( buf1, AF_INDEX_NUM( edge->link, edges ) ),
                  af_print_idx( buf2, AF_INDEX_NUM( edge->serif, edges ) ),

                  edge->blue_edge ? 'y' : 'n',
                  edge->opos / 64.0,
                  edge->pos / 64.0,
                  af_edge_flags_to_string( edge->flags ) ));
      AF_DUMP(( "\n" ));
    }
  }
#ifdef __cplusplus
  }
#endif

#undef AF_DUMP

#endif /* !FT_DEBUG_AUTOFIT */


  /* Compute the direction value of a given vector. */

  FT_LOCAL_DEF( AF_Direction )
  af_direction_compute( FT_Pos  dx,
                        FT_Pos  dy )
  {
    FT_Pos        ll, ss;  /* long and short arm lengths */
    AF_Direction  dir;     /* candidate direction        */


    if ( dy >= dx )
    {
      if ( dy >= -dx )
      {
        dir = AF_DIR_UP;
        ll  = dy;
        ss  = dx;
      }
      else
      {
        dir = AF_DIR_LEFT;
        ll  = -dx;
        ss  = dy;
      }
    }
    else /* dy < dx */
    {
      if ( dy >= -dx )
      {
        dir = AF_DIR_RIGHT;
        ll  = dx;
        ss  = dy;
      }
      else
      {
        dir = AF_DIR_DOWN;
        ll  = -dy;
        ss  = dx;
      }
    }

    /* return no direction if arm lengths do not differ enough       */
    /* (value 14 is heuristic, corresponding to approx. 4.1 degrees) */
    /* the long arm is never negative                                */
    if ( ll <= 14 * FT_ABS( ss ) )
      dir = AF_DIR_NONE;

    return dir;
  }


  FT_LOCAL_DEF( void )
  af_glyph_hints_init( AF_GlyphHints  hints,
                       FT_Memory      memory )
  {
    /* no need to initialize the embedded items */
    FT_MEM_ZERO( hints, sizeof ( *hints ) - sizeof ( hints->embedded ) );
    hints->memory = memory;
  }


  FT_LOCAL_DEF( void )
  af_glyph_hints_done( AF_GlyphHints  hints )
  {
    FT_Memory  memory;
    int        dim;


    if ( !( hints && hints->memory ) )
      return;

    memory = hints->memory;

    /*
     * note that we don't need to free the segment and edge
     * buffers since they are really within the hints->points array
     */
    for ( dim = 0; dim < AF_DIMENSION_MAX; dim++ )
    {
      AF_AxisHints  axis = &hints->axis[dim];


      axis->num_segments = 0;
      axis->max_segments = 0;
      if ( axis->segments != axis->embedded.segments )
        FT_FREE( axis->segments );

      axis->num_edges = 0;
      axis->max_edges = 0;
      if ( axis->edges != axis->embedded.edges )
        FT_FREE( axis->edges );
    }

    if ( hints->contours != hints->embedded.contours )
      FT_FREE( hints->contours );
    hints->max_contours = 0;
    hints->num_contours = 0;

    if ( hints->points != hints->embedded.points )
      FT_FREE( hints->points );
    hints->max_points = 0;
    hints->num_points = 0;

    hints->memory = NULL;
  }


  /* Reset metrics. */

  FT_LOCAL_DEF( void )
  af_glyph_hints_rescale( AF_GlyphHints    hints,
                          AF_StyleMetrics  metrics )
  {
    hints->metrics      = metrics;
    hints->scaler_flags = metrics->scaler.flags;
  }


  /* Recompute all AF_Point in AF_GlyphHints from the definitions */
  /* in a source outline.                                         */

  FT_LOCAL_DEF( FT_Error )
  af_glyph_hints_reload( AF_GlyphHints  hints,
                         FT_Outline*    outline )
  {
    FT_Error   error   = FT_Err_Ok;
    AF_Point   points;
    FT_UInt    old_max, new_max;
    FT_Fixed   x_scale = hints->x_scale;
    FT_Fixed   y_scale = hints->y_scale;
    FT_Pos     x_delta = hints->x_delta;
    FT_Pos     y_delta = hints->y_delta;
    FT_Memory  memory  = hints->memory;


    hints->num_points   = 0;
    hints->num_contours = 0;

    hints->axis[0].num_segments = 0;
    hints->axis[0].num_edges    = 0;
    hints->axis[1].num_segments = 0;
    hints->axis[1].num_edges    = 0;

    /* first of all, reallocate the contours array if necessary */
    new_max = (FT_UInt)outline->n_contours;
    old_max = (FT_UInt)hints->max_contours;

    if ( new_max <= AF_CONTOURS_EMBEDDED )
    {
      if ( !hints->contours )
      {
        hints->contours     = hints->embedded.contours;
        hints->max_contours = AF_CONTOURS_EMBEDDED;
      }
    }
    else if ( new_max > old_max )
    {
      if ( hints->contours == hints->embedded.contours )
        hints->contours = NULL;

      new_max = ( new_max + 3 ) & ~3U; /* round up to a multiple of 4 */

      if ( FT_RENEW_ARRAY( hints->contours, old_max, new_max ) )
        goto Exit;

      hints->max_contours = (FT_Int)new_max;
    }

    /*
     * then reallocate the points arrays if necessary --
     * note that we reserve two additional point positions, used to
     * hint metrics appropriately
     */
    new_max = (FT_UInt)( outline->n_points + 2 );
    old_max = (FT_UInt)hints->max_points;

    if ( new_max <= AF_POINTS_EMBEDDED )
    {
      if ( !hints->points )
      {
        hints->points     = hints->embedded.points;
        hints->max_points = AF_POINTS_EMBEDDED;
      }
    }
    else if ( new_max > old_max )
    {
      if ( hints->points == hints->embedded.points )
        hints->points = NULL;

      new_max = ( new_max + 2 + 7 ) & ~7U; /* round up to a multiple of 8 */

      if ( FT_RENEW_ARRAY( hints->points, old_max, new_max ) )
        goto Exit;

      hints->max_points = (FT_Int)new_max;
    }

    hints->num_points   = outline->n_points;
    hints->num_contours = outline->n_contours;

    /* 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.       */
    /*                                                                     */
    hints->axis[AF_DIMENSION_HORZ].major_dir = AF_DIR_UP;
    hints->axis[AF_DIMENSION_VERT].major_dir = AF_DIR_LEFT;

    if ( FT_Outline_Get_Orientation( outline ) == FT_ORIENTATION_POSTSCRIPT )
    {
      hints->axis[AF_DIMENSION_HORZ].major_dir = AF_DIR_DOWN;
      hints->axis[AF_DIMENSION_VERT].major_dir = AF_DIR_RIGHT;
    }

    hints->x_scale = x_scale;
    hints->y_scale = y_scale;
    hints->x_delta = x_delta;
    hints->y_delta = y_delta;

    points = hints->points;
    if ( hints->num_points == 0 )
      goto Exit;

    {
      AF_Point  point;
      AF_Point  point_limit = points + hints->num_points;

      /* value 20 in `near_limit' is heuristic */
      FT_UInt  units_per_em = hints->metrics->scaler.face->units_per_EM;
      FT_Int   near_limit   = 20 * units_per_em / 2048;


      /* compute coordinates & Bezier flags, next and prev */
      {
        FT_Vector*  vec           = outline->points;
        char*       tag           = outline->tags;
        FT_Short    endpoint      = outline->contours[0];
        AF_Point    end           = points + endpoint;
        AF_Point    prev          = end;
        FT_Int      contour_index = 0;


        for ( point = points; point < point_limit; point++, vec++, tag++ )
        {
          FT_Pos  out_x, out_y;


          point->in_dir  = (FT_Char)AF_DIR_NONE;
          point->out_dir = (FT_Char)AF_DIR_NONE;

          point->fx = (FT_Short)vec->x;
          point->fy = (FT_Short)vec->y;
          point->ox = point->x = FT_MulFix( vec->x, x_scale ) + x_delta;
          point->oy = point->y = FT_MulFix( vec->y, y_scale ) + y_delta;

          end->fx = (FT_Short)outline->points[endpoint].x;
          end->fy = (FT_Short)outline->points[endpoint].y;

          switch ( FT_CURVE_TAG( *tag ) )
          {
          case FT_CURVE_TAG_CONIC:
            point->flags = AF_FLAG_CONIC;
            break;
          case FT_CURVE_TAG_CUBIC:
            point->flags = AF_FLAG_CUBIC;
            break;
          default:
            point->flags = AF_FLAG_NONE;
          }

          out_x = point->fx - prev->fx;
          out_y = point->fy - prev->fy;

          if ( FT_ABS( out_x ) + FT_ABS( out_y ) < near_limit )
            prev->flags |= AF_FLAG_NEAR;

          point->prev = prev;
          prev->next  = point;
          prev        = point;

          if ( point == end )
          {
            if ( ++contour_index < outline->n_contours )
            {
              endpoint = outline->contours[contour_index];
              end      = points + endpoint;
              prev     = end;
            }
          }

#ifdef FT_DEBUG_AUTOFIT
          point->before[0] = NULL;
          point->before[1] = NULL;
          point->after[0]  = NULL;
          point->after[1]  = NULL;
#endif

        }
      }

      /* set up the contours array */
      {
        AF_Point*  contour       = hints->contours;
        AF_Point*  contour_limit = contour + hints->num_contours;
        short*     end           = outline->contours;
        short      idx           = 0;


        for ( ; contour < contour_limit; contour++, end++ )
        {
          contour[0] = points + idx;
          idx        = (short)( end[0] + 1 );
        }
      }

      {
        /*
         * Compute directions of `in' and `out' vectors.
         *
         * Note that distances between points that are very near to each
         * other are accumulated.  In other words, the auto-hinter either
         * prepends the small vectors between near points to the first
         * non-near vector, or the sum of small vector lengths exceeds a
         * threshold, thus `grouping' the small vectors.  All intermediate
         * points are tagged as weak; the directions are adjusted also to
         * be equal to the accumulated one.
         */

        FT_Int  near_limit2 = 2 * near_limit - 1;

        AF_Point*  contour;
        AF_Point*  contour_limit = hints->contours + hints->num_contours;


        for ( contour = hints->contours; contour < contour_limit; contour++ )
        {
          AF_Point  first = *contour;
          AF_Point  next, prev, curr;

          FT_Pos  out_x, out_y;


          /* since the first point of a contour could be part of a */
          /* series of near points, go backwards to find the first */
          /* non-near point and adjust `first'                     */

          point = first;
          prev  = first->prev;

          while ( prev != first )
          {
            out_x = point->fx - prev->fx;
            out_y = point->fy - prev->fy;

            /*
             * We use Taxicab metrics to measure the vector length.
             *
             * Note that the accumulated distances so far could have the
             * opposite direction of the distance measured here.  For this
             * reason we use `near_limit2' for the comparison to get a
             * non-near point even in the worst case.
             */
            if ( FT_ABS( out_x ) + FT_ABS( out_y ) >= near_limit2 )
              break;

            point = prev;
            prev  = prev->prev;
          }

          /* adjust first point */
          first = point;

          /* now loop over all points of the contour to get */
          /* `in' and `out' vector directions               */

          curr = first;

          /*
           * We abuse the `u' and `v' fields to store index deltas to the
           * next and previous non-near point, respectively.
           *
           * To avoid problems with not having non-near points, we point to
           * `first' by default as the next non-near point.
           *
           */
          curr->u  = (FT_Pos)( first - curr );
          first->v = -curr->u;

          out_x = 0;
          out_y = 0;

          next = first;
          do
          {
            AF_Direction  out_dir;


            point = next;
            next  = point->next;

            out_x += next->fx - point->fx;
            out_y += next->fy - point->fy;

            if ( FT_ABS( out_x ) + FT_ABS( out_y ) < near_limit )
            {
              next->flags |= AF_FLAG_WEAK_INTERPOLATION;
              continue;
            }

            curr->u = (FT_Pos)( next - curr );
            next->v = -curr->u;

            out_dir = af_direction_compute( out_x, out_y );

            /* adjust directions for all points inbetween; */
            /* the loop also updates position of `curr'    */
            curr->out_dir = (FT_Char)out_dir;
            for ( curr = curr->next; curr != next; curr = curr->next )
            {
              curr->in_dir  = (FT_Char)out_dir;
              curr->out_dir = (FT_Char)out_dir;
            }
            next->in_dir = (FT_Char)out_dir;

            curr->u  = (FT_Pos)( first - curr );
            first->v = -curr->u;

            out_x = 0;
            out_y = 0;

          } while ( next != first );
        }

        /*
         * The next step is to `simplify' an outline's topology so that we
         * can identify local extrema more reliably: A series of
         * non-horizontal or non-vertical vectors pointing into the same
         * quadrant are handled as a single, long vector.  From a
         * topological point of the view, the intermediate points are of no
         * interest and thus tagged as weak.
         */

        for ( point = points; point < point_limit; point++ )
        {
          if ( point->flags & AF_FLAG_WEAK_INTERPOLATION )
            continue;

          if ( point->in_dir  == AF_DIR_NONE &&
               point->out_dir == AF_DIR_NONE )
          {
            /* check whether both vectors point into the same quadrant */

            FT_Pos  in_x, in_y;
            FT_Pos  out_x, out_y;

            AF_Point  next_u = point + point->u;
            AF_Point  prev_v = point + point->v;


            in_x = point->fx - prev_v->fx;
            in_y = point->fy - prev_v->fy;

            out_x = next_u->fx - point->fx;
            out_y = next_u->fy - point->fy;

            if ( ( in_x ^ out_x ) >= 0 && ( in_y ^ out_y ) >= 0 )
            {
              /* yes, so tag current point as weak */
              /* and update index deltas           */

              point->flags |= AF_FLAG_WEAK_INTERPOLATION;

              prev_v->u = (FT_Pos)( next_u - prev_v );
              next_u->v = -prev_v->u;
            }
          }
        }

        /*
         * Finally, check for remaining weak points.  Everything else not
         * collected in edges so far is then implicitly classified as strong
         * points.
         */

        for ( point = points; point < point_limit; point++ )
        {
          if ( point->flags & AF_FLAG_WEAK_INTERPOLATION )
            continue;

          if ( point->flags & AF_FLAG_CONTROL )
          {
            /* control points are always weak */
          Is_Weak_Point:
            point->flags |= AF_FLAG_WEAK_INTERPOLATION;
          }
          else if ( point->out_dir == point->in_dir )
          {
            if ( point->out_dir != AF_DIR_NONE )
            {
              /* current point lies on a horizontal or          */
              /* vertical segment (but doesn't start or end it) */
              goto Is_Weak_Point;
            }

            {
              AF_Point  next_u = point + point->u;
              AF_Point  prev_v = point + point->v;


              if ( ft_corner_is_flat( point->fx  - prev_v->fx,
                                      point->fy  - prev_v->fy,
                                      next_u->fx - point->fx,
                                      next_u->fy - point->fy ) )
              {
                /* either the `in' or the `out' vector is much more  */
                /* dominant than the other one, so tag current point */
                /* as weak and update index deltas                   */

                prev_v->u = (FT_Pos)( next_u - prev_v );
                next_u->v = -prev_v->u;

                goto Is_Weak_Point;
              }
            }
          }
          else if ( point->in_dir == -point->out_dir )
          {
            /* current point forms a spike */
            goto Is_Weak_Point;
          }
        }
      }
    }

  Exit:
    return error;
  }


  /* Store the hinted outline in an FT_Outline structure. */

  FT_LOCAL_DEF( void )
  af_glyph_hints_save( AF_GlyphHints  hints,
                       FT_Outline*    outline )
  {
    AF_Point    point = hints->points;
    AF_Point    limit = point + hints->num_points;
    FT_Vector*  vec   = outline->points;
    char*       tag   = outline->tags;


    for ( ; point < limit; point++, vec++, tag++ )
    {
      vec->x = point->x;
      vec->y = point->y;

      if ( point->flags & AF_FLAG_CONIC )
        tag[0] = FT_CURVE_TAG_CONIC;
      else if ( point->flags & AF_FLAG_CUBIC )
        tag[0] = FT_CURVE_TAG_CUBIC;
      else
        tag[0] = FT_CURVE_TAG_ON;
    }
  }


  /****************************************************************
   *
   *                     EDGE POINT GRID-FITTING
   *
   ****************************************************************/


  /* Align all points of an edge to the same coordinate value, */
  /* either horizontally or vertically.                        */

  FT_LOCAL_DEF( void )
  af_glyph_hints_align_edge_points( AF_GlyphHints  hints,
                                    AF_Dimension   dim )
  {
    AF_AxisHints  axis          = & hints->axis[dim];
    AF_Segment    segments      = axis->segments;
    AF_Segment    segment_limit = segments + axis->num_segments;
    AF_Segment    seg;


    if ( dim == AF_DIMENSION_HORZ )
    {
      for ( seg = segments; seg < segment_limit; seg++ )
      {
        AF_Edge   edge = seg->edge;
        AF_Point  point, first, last;


        if ( !edge )
          continue;

        first = seg->first;
        last  = seg->last;
        point = first;
        for (;;)
        {
          point->x      = edge->pos;
          point->flags |= AF_FLAG_TOUCH_X;

          if ( point == last )
            break;

          point = point->next;
        }
      }
    }
    else
    {
      for ( seg = segments; seg < segment_limit; seg++ )
      {
        AF_Edge   edge = seg->edge;
        AF_Point  point, first, last;


        if ( !edge )
          continue;

        first = seg->first;
        last  = seg->last;
        point = first;
        for (;;)
        {
          point->y      = edge->pos;
          point->flags |= AF_FLAG_TOUCH_Y;

          if ( point == last )
            break;

          point = point->next;
        }
      }
    }
  }


  /****************************************************************
   *
   *                    STRONG POINT INTERPOLATION
   *
   ****************************************************************/


  /* Hint the strong points -- this is equivalent to the TrueType `IP' */
  /* hinting instruction.                                              */

  FT_LOCAL_DEF( void )
  af_glyph_hints_align_strong_points( AF_GlyphHints  hints,
                                      AF_Dimension   dim )
  {
    AF_Point      points      = hints->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;
    FT_UInt       touch_flag;


    if ( dim == AF_DIMENSION_HORZ )
      touch_flag = AF_FLAG_TOUCH_X;
    else
      touch_flag  = AF_FLAG_TOUCH_Y;

    if ( edges < edge_limit )
    {
      AF_Point  point;
      AF_Edge   edge;


      for ( point = points; point < point_limit; point++ )
      {
        FT_Pos  u, ou, fu;  /* point position */
        FT_Pos  delta;


        if ( point->flags & touch_flag )
          continue;

        /* if this point is candidate to weak interpolation, we       */
        /* interpolate it after all strong points have been processed */

        if ( ( point->flags & AF_FLAG_WEAK_INTERPOLATION ) )
          continue;

        if ( dim == AF_DIMENSION_VERT )
        {
          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 );

#ifdef FT_DEBUG_AUTOFIT
          point->before[dim] = edge;
          point->after[dim]  = NULL;
#endif

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

#ifdef FT_DEBUG_AUTOFIT
          point->before[dim] = NULL;
          point->after[dim]  = edge;
#endif

          goto Store_Point;
        }

        {
          FT_PtrDist  min, max, mid;
          FT_Pos      fpos;


          /* find enclosing edges */
          min = 0;
          max = edge_limit - edges;

#if 1
          /* for a small number of edges, a linear search is better */
          if ( max <= 8 )
          {
            FT_PtrDist  nn;


            for ( nn = 0; nn < max; nn++ )
              if ( edges[nn].fpos >= u )
                break;

            if ( edges[nn].fpos == u )
            {
              u = edges[nn].pos;
              goto Store_Point;
            }
            min = nn;
          }
          else
#endif
          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;

#ifdef FT_DEBUG_AUTOFIT
              point->before[dim] = NULL;
              point->after[dim]  = NULL;
#endif

              goto Store_Point;
            }
          }

          /* point is not on an edge */
          {
            AF_Edge  before = edges + min - 1;
            AF_Edge  after  = edges + min + 0;


#ifdef FT_DEBUG_AUTOFIT
            point->before[dim] = before;
            point->after[dim]  = after;
#endif

            /* 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 );
          }
        }

      Store_Point:
        /* save the point position */
        if ( dim == AF_DIMENSION_HORZ )
          point->x = u;
        else
          point->y = u;

        point->flags |= touch_flag;
      }
    }
  }


  /****************************************************************
   *
   *                    WEAK POINT INTERPOLATION
   *
   ****************************************************************/


  /* Shift the original coordinates of all points between `p1' and */
  /* `p2' to get hinted coordinates, using the same difference as  */
  /* given by `ref'.                                               */

  static void
  af_iup_shift( AF_Point  p1,
                AF_Point  p2,
                AF_Point  ref )
  {
    AF_Point  p;
    FT_Pos    delta = ref->u - ref->v;


    if ( delta == 0 )
      return;

    for ( p = p1; p < ref; p++ )
      p->u = p->v + delta;

    for ( p = ref + 1; p <= p2; p++ )
      p->u = p->v + delta;
  }


  /* Interpolate the original coordinates of all points between `p1' and  */
  /* `p2' to get hinted coordinates, using `ref1' and `ref2' as the       */
  /* reference points.  The `u' and `v' members are the current and       */
  /* original coordinate values, respectively.                            */
  /*                                                                      */
  /* Details can be found in the TrueType bytecode specification.         */

  static void
  af_iup_interp( AF_Point  p1,
                 AF_Point  p2,
                 AF_Point  ref1,
                 AF_Point  ref2 )
  {
    AF_Point  p;
    FT_Pos    u, v1, v2, u1, u2, d1, d2;


    if ( p1 > p2 )
      return;

    if ( ref1->v > ref2->v )
    {
      p    = ref1;
      ref1 = ref2;
      ref2 = p;
    }

    v1 = ref1->v;
    v2 = ref2->v;
    u1 = ref1->u;
    u2 = ref2->u;
    d1 = u1 - v1;
    d2 = u2 - v2;

    if ( u1 == u2 || v1 == v2 )
    {
      for ( p = p1; p <= p2; p++ )
      {
        u = p->v;

        if ( u <= v1 )
          u += d1;
        else if ( u >= v2 )
          u += d2;
        else
          u = u1;

        p->u = u;
      }
    }
    else
    {
      FT_Fixed  scale = FT_DivFix( u2 - u1, v2 - v1 );


      for ( p = p1; p <= p2; p++ )
      {
        u = p->v;

        if ( u <= v1 )
          u += d1;
        else if ( u >= v2 )
          u += d2;
        else
          u = u1 + FT_MulFix( u - v1, scale );

        p->u = u;
      }
    }
  }


  /* Hint the weak points -- this is equivalent to the TrueType `IUP' */
  /* hinting instruction.                                             */

  FT_LOCAL_DEF( void )
  af_glyph_hints_align_weak_points( AF_GlyphHints  hints,
                                    AF_Dimension   dim )
  {
    AF_Point   points        = hints->points;
    AF_Point   point_limit   = points + hints->num_points;
    AF_Point*  contour       = hints->contours;
    AF_Point*  contour_limit = contour + hints->num_contours;
    FT_UInt    touch_flag;
    AF_Point   point;
    AF_Point   end_point;
    AF_Point   first_point;


    /* PASS 1: Move segment points to edge positions */

    if ( dim == AF_DIMENSION_HORZ )
    {
      touch_flag = AF_FLAG_TOUCH_X;

      for ( point = points; point < point_limit; point++ )
      {
        point->u = point->x;
        point->v = point->ox;
      }
    }
    else
    {
      touch_flag = AF_FLAG_TOUCH_Y;

      for ( point = points; point < point_limit; point++ )
      {
        point->u = point->y;
        point->v = point->oy;
      }
    }

    for ( ; contour < contour_limit; contour++ )
    {
      AF_Point  first_touched, last_touched;


      point       = *contour;
      end_point   = point->prev;
      first_point = point;

      /* find first touched point */
      for (;;)
      {
        if ( point > end_point )  /* no touched point in contour */
          goto NextContour;

        if ( point->flags & touch_flag )
          break;

        point++;
      }

      first_touched = point;

      for (;;)
      {
        FT_ASSERT( point <= end_point                 &&
                   ( point->flags & touch_flag ) != 0 );

        /* skip any touched neighbours */
        while ( point < end_point                    &&
                ( point[1].flags & touch_flag ) != 0 )
          point++;

        last_touched = point;

        /* find the next touched point, if any */
        point++;
        for (;;)
        {
          if ( point > end_point )
            goto EndContour;

          if ( ( point->flags & touch_flag ) != 0 )
            break;

          point++;
        }

        /* interpolate between last_touched and point */
        af_iup_interp( last_touched + 1, point - 1,
                       last_touched, point );
      }

    EndContour:
      /* special case: only one point was touched */
      if ( last_touched == first_touched )
        af_iup_shift( first_point, end_point, first_touched );

      else /* interpolate the last part */
      {
        if ( last_touched < end_point )
          af_iup_interp( last_touched + 1, end_point,
                         last_touched, first_touched );

        if ( first_touched > points )
          af_iup_interp( first_point, first_touched - 1,
                         last_touched, first_touched );
      }

    NextContour:
      ;
    }

    /* now save the interpolated values back to x/y */
    if ( dim == AF_DIMENSION_HORZ )
    {
      for ( point = points; point < point_limit; point++ )
        point->x = point->u;
    }
    else
    {
      for ( point = points; point < point_limit; point++ )
        point->y = point->u;
    }
  }


/* END */
