/***************************************************************************/
/*                                                                         */
/*  cf2hints.c                                                             */
/*                                                                         */
/*    Adobe's code for handling CFF hints (body).                          */
/*                                                                         */
/*  Copyright 2007-2014 Adobe Systems Incorporated.                        */
/*                                                                         */
/*  This software, and all works of authorship, whether in source or       */
/*  object code form as indicated by the copyright notice(s) included      */
/*  herein (collectively, the "Work") is made available, and may only be   */
/*  used, modified, and distributed under the FreeType Project License,    */
/*  LICENSE.TXT.  Additionally, subject to the terms and conditions of the */
/*  FreeType Project License, each contributor to the Work hereby grants   */
/*  to any individual or legal entity exercising permissions granted by    */
/*  the FreeType Project License and this section (hereafter, "You" or     */
/*  "Your") a perpetual, worldwide, non-exclusive, no-charge,              */
/*  royalty-free, irrevocable (except as stated in this section) patent    */
/*  license to make, have made, use, offer to sell, sell, import, and      */
/*  otherwise transfer the Work, where such license applies only to those  */
/*  patent claims licensable by such contributor that are necessarily      */
/*  infringed by their contribution(s) alone or by combination of their    */
/*  contribution(s) with the Work to which such contribution(s) was        */
/*  submitted.  If You institute patent litigation against any entity      */
/*  (including a cross-claim or counterclaim in a lawsuit) alleging that   */
/*  the Work or a contribution incorporated within the Work constitutes    */
/*  direct or contributory patent infringement, then any patent licenses   */
/*  granted to You under this License for that Work shall terminate as of  */
/*  the date such litigation is filed.                                     */
/*                                                                         */
/*  By using, modifying, or distributing the Work you indicate that you    */
/*  have read and understood the terms and conditions of the               */
/*  FreeType Project License as well as those provided in this section,    */
/*  and you accept them fully.                                             */
/*                                                                         */
/***************************************************************************/


#include "cf2ft.h"
#include FT_INTERNAL_DEBUG_H

#include "cf2glue.h"
#include "cf2font.h"
#include "cf2hints.h"
#include "cf2intrp.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  trace_cf2hints


  typedef struct  CF2_HintMoveRec_
  {
    size_t     j;          /* index of upper hint map edge   */
    CF2_Fixed  moveUp;     /* adjustment to optimum position */

  } CF2_HintMoveRec, *CF2_HintMove;


  /* Compute angular momentum for winding order detection.  It is called */
  /* for all lines and curves, but not necessarily in element order.     */
  static CF2_Int
  cf2_getWindingMomentum( CF2_Fixed  x1,
                          CF2_Fixed  y1,
                          CF2_Fixed  x2,
                          CF2_Fixed  y2 )
  {
    /* cross product of pt1 position from origin with pt2 position from  */
    /* pt1; we reduce the precision so that the result fits into 32 bits */

    return ( x1 >> 16 ) * ( ( y2 - y1 ) >> 16 ) -
           ( y1 >> 16 ) * ( ( x2 - x1 ) >> 16 );
  }


  /*
   * Construct from a StemHint; this is used as a parameter to
   * `cf2_blues_capture'.
   * `hintOrigin' is the character space displacement of a seac accent.
   * Adjust stem hint for darkening here.
   *
   */
  static void
  cf2_hint_init( CF2_Hint            hint,
                 const CF2_ArrStack  stemHintArray,
                 size_t              indexStemHint,
                 const CF2_Font      font,
                 CF2_Fixed           hintOrigin,
                 CF2_Fixed           scale,
                 FT_Bool             bottom )
  {
    CF2_Fixed               width;
    const CF2_StemHintRec*  stemHint;


    FT_ZERO( hint );

    stemHint = (const CF2_StemHintRec*)cf2_arrstack_getPointer(
                                         stemHintArray,
                                         indexStemHint );

    width = stemHint->max - stemHint->min;

    if ( width == cf2_intToFixed( -21 ) )
    {
      /* ghost bottom */

      if ( bottom )
      {
        hint->csCoord = stemHint->max;
        hint->flags   = CF2_GhostBottom;
      }
      else
        hint->flags = 0;
    }

    else if ( width == cf2_intToFixed( -20 ) )
    {
      /* ghost top */

      if ( bottom )
        hint->flags = 0;
      else
      {
        hint->csCoord = stemHint->min;
        hint->flags   = CF2_GhostTop;
      }
    }

    else if ( width < 0 )
    {
      /* inverted pair */

      /*
       * Hints with negative widths were produced by an early version of a
       * non-Adobe font tool.  The Type 2 spec allows edge (ghost) hints
       * with negative widths, but says
       *
       *   All other negative widths have undefined meaning.
       *
       * CoolType has a silent workaround that negates the hint width; for
       * permissive mode, we do the same here.
       *
       * Note: Such fonts cannot use ghost hints, but should otherwise work.
       * Note: Some poor hints in our faux fonts can produce negative
       *       widths at some blends.  For example, see a light weight of
       *       `u' in ASerifMM.
       *
       */
      if ( bottom )
      {
        hint->csCoord = stemHint->max;
        hint->flags   = CF2_PairBottom;
      }
      else
      {
        hint->csCoord = stemHint->min;
        hint->flags   = CF2_PairTop;
      }
    }

    else
    {
      /* normal pair */

      if ( bottom )
      {
        hint->csCoord = stemHint->min;
        hint->flags   = CF2_PairBottom;
      }
      else
      {
        hint->csCoord = stemHint->max;
        hint->flags   = CF2_PairTop;
      }
    }

    /* Now that ghost hints have been detected, adjust this edge for      */
    /* darkening.  Bottoms are not changed; tops are incremented by twice */
    /* `darkenY'.                                                         */
    if ( cf2_hint_isTop( hint ) )
      hint->csCoord += 2 * font->darkenY;

    hint->csCoord += hintOrigin;
    hint->scale    = scale;
    hint->index    = indexStemHint;   /* index in original stem hint array */

    /* if original stem hint has been used, use the same position */
    if ( hint->flags != 0 && stemHint->used )
    {
      if ( cf2_hint_isTop( hint ) )
        hint->dsCoord = stemHint->maxDS;
      else
        hint->dsCoord = stemHint->minDS;

      cf2_hint_lock( hint );
    }
    else
      hint->dsCoord = FT_MulFix( hint->csCoord, scale );
  }


  /* initialize an invalid hint map element */
  static void
  cf2_hint_initZero( CF2_Hint  hint )
  {
    FT_ZERO( hint );
  }


  FT_LOCAL_DEF( FT_Bool )
  cf2_hint_isValid( const CF2_Hint  hint )
  {
    return (FT_Bool)( hint->flags != 0 );
  }


  static FT_Bool
  cf2_hint_isPair( const CF2_Hint  hint )
  {
    return (FT_Bool)( ( hint->flags                      &
                        ( CF2_PairBottom | CF2_PairTop ) ) != 0 );
  }


  static FT_Bool
  cf2_hint_isPairTop( const CF2_Hint  hint )
  {
    return (FT_Bool)( ( hint->flags & CF2_PairTop ) != 0 );
  }


  FT_LOCAL_DEF( FT_Bool )
  cf2_hint_isTop( const CF2_Hint  hint )
  {
    return (FT_Bool)( ( hint->flags                    &
                        ( CF2_PairTop | CF2_GhostTop ) ) != 0 );
  }


  FT_LOCAL_DEF( FT_Bool )
  cf2_hint_isBottom( const CF2_Hint  hint )
  {
    return (FT_Bool)( ( hint->flags                          &
                        ( CF2_PairBottom | CF2_GhostBottom ) ) != 0 );
  }


  static FT_Bool
  cf2_hint_isLocked( const CF2_Hint  hint )
  {
    return (FT_Bool)( ( hint->flags & CF2_Locked ) != 0 );
  }


  static FT_Bool
  cf2_hint_isSynthetic( const CF2_Hint  hint )
  {
    return (FT_Bool)( ( hint->flags & CF2_Synthetic ) != 0 );
  }


  FT_LOCAL_DEF( void )
  cf2_hint_lock( CF2_Hint  hint )
  {
    hint->flags |= CF2_Locked;
  }


  FT_LOCAL_DEF( void )
  cf2_hintmap_init( CF2_HintMap   hintmap,
                    CF2_Font      font,
                    CF2_HintMap   initialMap,
                    CF2_ArrStack  hintMoves,
                    CF2_Fixed     scale )
  {
    FT_ZERO( hintmap );

    /* copy parameters from font instance */
    hintmap->hinted         = font->hinted;
    hintmap->scale          = scale;
    hintmap->font           = font;
    hintmap->initialHintMap = initialMap;
    /* will clear in `cf2_hintmap_adjustHints' */
    hintmap->hintMoves      = hintMoves;
  }


  static FT_Bool
  cf2_hintmap_isValid( const CF2_HintMap  hintmap )
  {
    return hintmap->isValid;
  }


  /* transform character space coordinate to device space using hint map */
  static CF2_Fixed
  cf2_hintmap_map( CF2_HintMap  hintmap,
                   CF2_Fixed    csCoord )
  {
    if ( hintmap->count == 0 || ! hintmap->hinted )
    {
      /* there are no hints; use uniform scale and zero offset */
      return FT_MulFix( csCoord, hintmap->scale );
    }
    else
    {
      /* start linear search from last hit */
      CF2_UInt  i = hintmap->lastIndex;

      FT_ASSERT( hintmap->lastIndex < CF2_MAX_HINT_EDGES );

      /* search up */
      while ( i < hintmap->count - 1                  &&
              csCoord >= hintmap->edge[i + 1].csCoord )
        i += 1;

      /* search down */
      while ( i > 0 && csCoord < hintmap->edge[i].csCoord )
        i -= 1;

      hintmap->lastIndex = i;

      if ( i == 0 && csCoord < hintmap->edge[0].csCoord )
      {
        /* special case for points below first edge: use uniform scale */
        return FT_MulFix( csCoord - hintmap->edge[0].csCoord,
                          hintmap->scale ) +
                 hintmap->edge[0].dsCoord;
      }
      else
      {
        /*
         * Note: entries with duplicate csCoord are allowed.
         * Use edge[i], the highest entry where csCoord >= entry[i].csCoord
         */
        return FT_MulFix( csCoord - hintmap->edge[i].csCoord,
                          hintmap->edge[i].scale ) +
                 hintmap->edge[i].dsCoord;
      }
    }
  }


  /*
   * This hinting policy moves a hint pair in device space so that one of
   * its two edges is on a device pixel boundary (its fractional part is
   * zero).  `cf2_hintmap_insertHint' guarantees no overlap in CS
   * space.  Ensure here that there is no overlap in DS.
   *
   * In the first pass, edges are adjusted relative to adjacent hints.
   * Those that are below have already been adjusted.  Those that are
   * above have not yet been adjusted.  If a hint above blocks an
   * adjustment to an optimal position, we will try again in a second
   * pass.  The second pass is top-down.
   *
   */

  static void
  cf2_hintmap_adjustHints( CF2_HintMap  hintmap )
  {
    size_t  i, j;


    cf2_arrstack_clear( hintmap->hintMoves );      /* working storage */

    /*
     * First pass is bottom-up (font hint order) without look-ahead.
     * Locked edges are already adjusted.
     * Unlocked edges begin with dsCoord from `initialHintMap'.
     * Save edges that are not optimally adjusted in `hintMoves' array,
     * and process them in second pass.
     */

    for ( i = 0; i < hintmap->count; i++ )
    {
      FT_Bool  isPair = cf2_hint_isPair( &hintmap->edge[i] );


      /* index of upper edge (same value for ghost hint) */
      j = isPair ? i + 1 : i;

      FT_ASSERT( j < hintmap->count );
      FT_ASSERT( cf2_hint_isValid( &hintmap->edge[i] ) );
      FT_ASSERT( cf2_hint_isValid( &hintmap->edge[j] ) );
      FT_ASSERT( cf2_hint_isLocked( &hintmap->edge[i] ) ==
                   cf2_hint_isLocked( &hintmap->edge[j] ) );

      if ( !cf2_hint_isLocked( &hintmap->edge[i] ) )
      {
        /* hint edge is not locked, we can adjust it */
        CF2_Fixed  fracDown = cf2_fixedFraction( hintmap->edge[i].dsCoord );
        CF2_Fixed  fracUp   = cf2_fixedFraction( hintmap->edge[j].dsCoord );

        /* calculate all four possibilities; moves down are negative */
        CF2_Fixed  downMoveDown = 0 - fracDown;
        CF2_Fixed  upMoveDown   = 0 - fracUp;
        CF2_Fixed  downMoveUp   = fracDown == 0
                                    ? 0
                                    : cf2_intToFixed( 1 ) - fracDown;
        CF2_Fixed  upMoveUp     = fracUp == 0
                                    ? 0
                                    : cf2_intToFixed( 1 ) - fracUp;

        /* smallest move up */
        CF2_Fixed  moveUp   = FT_MIN( downMoveUp, upMoveUp );
        /* smallest move down */
        CF2_Fixed  moveDown = FT_MAX( downMoveDown, upMoveDown );

        /* final amount to move edge or edge pair */
        CF2_Fixed  move;

        CF2_Fixed  downMinCounter = CF2_MIN_COUNTER;
        CF2_Fixed  upMinCounter   = CF2_MIN_COUNTER;
        FT_Bool    saveEdge       = FALSE;


        /* minimum counter constraint doesn't apply when adjacent edges */
        /* are synthetic                                                */
        /* TODO: doesn't seem a big effect; for now, reduce the code    */
#if 0
        if ( i == 0                                        ||
             cf2_hint_isSynthetic( &hintmap->edge[i - 1] ) )
          downMinCounter = 0;

        if ( j >= hintmap->count - 1                       ||
             cf2_hint_isSynthetic( &hintmap->edge[j + 1] ) )
          upMinCounter = 0;
#endif

        /* is there room to move up?                                    */
        /* there is if we are at top of array or the next edge is at or */
        /* beyond proposed move up?                                     */
        if ( j >= hintmap->count - 1                            ||
             hintmap->edge[j + 1].dsCoord >=
               hintmap->edge[j].dsCoord + moveUp + upMinCounter )
        {
          /* there is room to move up; is there also room to move down? */
          if ( i == 0                                                 ||
               hintmap->edge[i - 1].dsCoord <=
                 hintmap->edge[i].dsCoord + moveDown - downMinCounter )
          {
            /* move smaller absolute amount */
            move = ( -moveDown < moveUp ) ? moveDown : moveUp;  /* optimum */
          }
          else
            move = moveUp;
        }
        else
        {
          /* is there room to move down? */
          if ( i == 0                                                 ||
               hintmap->edge[i - 1].dsCoord <=
                 hintmap->edge[i].dsCoord + moveDown - downMinCounter )
          {
            move     = moveDown;
            /* true if non-optimum move */
            saveEdge = (FT_Bool)( moveUp < -moveDown );
          }
          else
          {
            /* no room to move either way without overlapping or reducing */
            /* the counter too much                                       */
            move     = 0;
            saveEdge = TRUE;
          }
        }

        /* Identify non-moves and moves down that aren't optimal, and save */
        /* them for second pass.                                           */
        /* Do this only if there is an unlocked edge above (which could    */
        /* possibly move).                                                 */
        if ( saveEdge                                    &&
             j < hintmap->count - 1                      &&
             !cf2_hint_isLocked( &hintmap->edge[j + 1] ) )
        {
          CF2_HintMoveRec  savedMove;


          savedMove.j      = j;
          /* desired adjustment in second pass */
          savedMove.moveUp = moveUp - move;

          cf2_arrstack_push( hintmap->hintMoves, &savedMove );
        }

        /* move the edge(s) */
        hintmap->edge[i].dsCoord += move;
        if ( isPair )
          hintmap->edge[j].dsCoord += move;
      }

      /* assert there are no overlaps in device space */
      FT_ASSERT( i == 0                                                   ||
                 hintmap->edge[i - 1].dsCoord <= hintmap->edge[i].dsCoord );
      FT_ASSERT( i < j                                                ||
                 hintmap->edge[i].dsCoord <= hintmap->edge[j].dsCoord );

      /* adjust the scales, avoiding divide by zero */
      if ( i > 0 )
      {
        if ( hintmap->edge[i].csCoord != hintmap->edge[i - 1].csCoord )
          hintmap->edge[i - 1].scale =
            FT_DivFix(
              hintmap->edge[i].dsCoord - hintmap->edge[i - 1].dsCoord,
              hintmap->edge[i].csCoord - hintmap->edge[i - 1].csCoord );
      }

      if ( isPair )
      {
        if ( hintmap->edge[j].csCoord != hintmap->edge[j - 1].csCoord )
          hintmap->edge[j - 1].scale =
            FT_DivFix(
              hintmap->edge[j].dsCoord - hintmap->edge[j - 1].dsCoord,
              hintmap->edge[j].csCoord - hintmap->edge[j - 1].csCoord );

        i += 1;     /* skip upper edge on next loop */
      }
    }

    /* second pass tries to move non-optimal hints up, in case there is */
    /* room now                                                         */
    for ( i = cf2_arrstack_size( hintmap->hintMoves ); i > 0; i-- )
    {
      CF2_HintMove  hintMove = (CF2_HintMove)
                      cf2_arrstack_getPointer( hintmap->hintMoves, i - 1 );


      j = hintMove->j;

      /* this was tested before the push, above */
      FT_ASSERT( j < hintmap->count - 1 );

      /* is there room to move up? */
      if ( hintmap->edge[j + 1].dsCoord >=
             hintmap->edge[j].dsCoord + hintMove->moveUp + CF2_MIN_COUNTER )
      {
        /* there is more room now, move edge up */
        hintmap->edge[j].dsCoord += hintMove->moveUp;

        if ( cf2_hint_isPair( &hintmap->edge[j] ) )
        {
          FT_ASSERT( j > 0 );
          hintmap->edge[j - 1].dsCoord += hintMove->moveUp;
        }
      }
    }
  }


  /* insert hint edges into map, sorted by csCoord */
  static void
  cf2_hintmap_insertHint( CF2_HintMap  hintmap,
                          CF2_Hint     bottomHintEdge,
                          CF2_Hint     topHintEdge )
  {
    CF2_UInt  indexInsert;

    /* set default values, then check for edge hints */
    FT_Bool   isPair         = TRUE;
    CF2_Hint  firstHintEdge  = bottomHintEdge;
    CF2_Hint  secondHintEdge = topHintEdge;


    /* one or none of the input params may be invalid when dealing with */
    /* edge hints; at least one edge must be valid                      */
    FT_ASSERT( cf2_hint_isValid( bottomHintEdge ) ||
               cf2_hint_isValid( topHintEdge )    );

    /* determine how many and which edges to insert */
    if ( !cf2_hint_isValid( bottomHintEdge ) )
    {
      /* insert only the top edge */
      firstHintEdge = topHintEdge;
      isPair        = FALSE;
    }
    else if ( !cf2_hint_isValid( topHintEdge ) )
    {
      /* insert only the bottom edge */
      isPair = FALSE;
    }

    /* paired edges must be in proper order */
    FT_ASSERT( !isPair                                         ||
               topHintEdge->csCoord >= bottomHintEdge->csCoord );

    /* linear search to find index value of insertion point */
    indexInsert = 0;
    for ( ; indexInsert < hintmap->count; indexInsert++ )
    {
      if ( hintmap->edge[indexInsert].csCoord >= firstHintEdge->csCoord )
        break;
    }

    /*
     * Discard any hints that overlap in character space.  Most often, this
     * is while building the initial map, where captured hints from all
     * zones are combined.  Define overlap to include hints that `touch'
     * (overlap zero).  Hiragino Sans/Gothic fonts have numerous hints that
     * touch.  Some fonts have non-ideographic glyphs that overlap our
     * synthetic hints.
     *
     * Overlap also occurs when darkening stem hints that are close.
     *
     */
    if ( indexInsert < hintmap->count )
    {
      /* we are inserting before an existing edge:    */
      /* verify that an existing edge is not the same */
      if ( hintmap->edge[indexInsert].csCoord == firstHintEdge->csCoord )
        return; /* ignore overlapping stem hint */

      /* verify that a new pair does not straddle the next edge */
      if ( isPair                                                        &&
           hintmap->edge[indexInsert].csCoord <= secondHintEdge->csCoord )
        return; /* ignore overlapping stem hint */

      /* verify that we are not inserting between paired edges */
      if ( cf2_hint_isPairTop( &hintmap->edge[indexInsert] ) )
        return; /* ignore overlapping stem hint */
    }

    /* recompute device space locations using initial hint map */
    if ( cf2_hintmap_isValid( hintmap->initialHintMap ) &&
         !cf2_hint_isLocked( firstHintEdge )            )
    {
      if ( isPair )
      {
        /* Use hint map to position the center of stem, and nominal scale */
        /* to position the two edges.  This preserves the stem width.     */
        CF2_Fixed  midpoint  = cf2_hintmap_map(
                                 hintmap->initialHintMap,
                                 ( secondHintEdge->csCoord +
                                   firstHintEdge->csCoord ) / 2 );
        CF2_Fixed  halfWidth = FT_MulFix(
                                 ( secondHintEdge->csCoord -
                                   firstHintEdge->csCoord ) / 2,
                                 hintmap->scale );


        firstHintEdge->dsCoord  = midpoint - halfWidth;
        secondHintEdge->dsCoord = midpoint + halfWidth;
      }
      else
        firstHintEdge->dsCoord = cf2_hintmap_map( hintmap->initialHintMap,
                                                  firstHintEdge->csCoord );
    }

    /*
     * Discard any hints that overlap in device space; this can occur
     * because locked hints have been moved to align with blue zones.
     *
     * TODO: Although we might correct this later during adjustment, we
     * don't currently have a way to delete a conflicting hint once it has
     * been inserted.  See v2.030 MinionPro-Regular, 12 ppem darkened,
     * initial hint map for second path, glyph 945 (the perispomeni (tilde)
     * in U+1F6E, Greek omega with psili and perispomeni).  Darkening is
     * 25.  Pair 667,747 initially conflicts in design space with top edge
     * 660.  This is because 667 maps to 7.87, and the top edge was
     * captured by a zone at 8.0.  The pair is later successfully inserted
     * in a zone without the top edge.  In this zone it is adjusted to 8.0,
     * and no longer conflicts with the top edge in design space.  This
     * means it can be included in yet a later zone which does have the top
     * edge hint.  This produces a small mismatch between the first and
     * last points of this path, even though the hint masks are the same.
     * The density map difference is tiny (1/256).
     *
     */

    if ( indexInsert > 0 )
    {
      /* we are inserting after an existing edge */
      if ( firstHintEdge->dsCoord < hintmap->edge[indexInsert - 1].dsCoord )
        return;
    }

    if ( indexInsert < hintmap->count )
    {
      /* we are inserting before an existing edge */
      if ( isPair )
      {
        if ( secondHintEdge->dsCoord > hintmap->edge[indexInsert].dsCoord )
          return;
      }
      else
      {
        if ( firstHintEdge->dsCoord > hintmap->edge[indexInsert].dsCoord )
          return;
      }
    }

    /* make room to insert */
    {
      CF2_UInt  iSrc = hintmap->count - 1;
      CF2_UInt  iDst = isPair ? hintmap->count + 1 : hintmap->count;

      CF2_UInt  count = hintmap->count - indexInsert;


      if ( iDst >= CF2_MAX_HINT_EDGES )
      {
        FT_TRACE4(( "cf2_hintmap_insertHint: too many hintmaps\n" ));
        return;
      }

      while ( count-- )
        hintmap->edge[iDst--] = hintmap->edge[iSrc--];

      /* insert first edge */
      hintmap->edge[indexInsert] = *firstHintEdge;         /* copy struct */
      hintmap->count += 1;

      if ( isPair )
      {
        /* insert second edge */
        hintmap->edge[indexInsert + 1] = *secondHintEdge;  /* copy struct */
        hintmap->count                += 1;
      }
    }

    return;
  }


  /*
   * Build a map from hints and mask.
   *
   * This function may recur one level if `hintmap->initialHintMap' is not yet
   * valid.
   * If `initialMap' is true, simply build initial map.
   *
   * Synthetic hints are used in two ways.  A hint at zero is inserted, if
   * needed, in the initial hint map, to prevent translations from
   * propagating across the origin.  If synthetic em box hints are enabled
   * for ideographic dictionaries, then they are inserted in all hint
   * maps, including the initial one.
   *
   */
  FT_LOCAL_DEF( void )
  cf2_hintmap_build( CF2_HintMap   hintmap,
                     CF2_ArrStack  hStemHintArray,
                     CF2_ArrStack  vStemHintArray,
                     CF2_HintMask  hintMask,
                     CF2_Fixed     hintOrigin,
                     FT_Bool       initialMap )
  {
    FT_Byte*  maskPtr;

    CF2_Font         font = hintmap->font;
    CF2_HintMaskRec  tempHintMask;

    size_t   bitCount, i;
    FT_Byte  maskByte;


    /* check whether initial map is constructed */
    if ( !initialMap && !cf2_hintmap_isValid( hintmap->initialHintMap ) )
    {
      /* make recursive call with initialHintMap and temporary mask; */
      /* temporary mask will get all bits set, below */
      cf2_hintmask_init( &tempHintMask, hintMask->error );
      cf2_hintmap_build( hintmap->initialHintMap,
                         hStemHintArray,
                         vStemHintArray,
                         &tempHintMask,
                         hintOrigin,
                         TRUE );
    }

    if ( !cf2_hintmask_isValid( hintMask ) )
    {
      /* without a hint mask, assume all hints are active */
      cf2_hintmask_setAll( hintMask,
                           cf2_arrstack_size( hStemHintArray ) +
                             cf2_arrstack_size( vStemHintArray ) );
      if ( !cf2_hintmask_isValid( hintMask ) )
          return;                   /* too many stem hints */
    }

    /* begin by clearing the map */
    hintmap->count     = 0;
    hintmap->lastIndex = 0;

    /* make a copy of the hint mask so we can modify it */
    tempHintMask = *hintMask;
    maskPtr      = cf2_hintmask_getMaskPtr( &tempHintMask );

    /* use the hStem hints only, which are first in the mask */
    bitCount = cf2_arrstack_size( hStemHintArray );

    /* Defense-in-depth.  Should never return here. */
    if ( bitCount > hintMask->bitCount )
        return;

    /* synthetic embox hints get highest priority */
    if ( font->blues.doEmBoxHints )
    {
      CF2_HintRec  dummy;


      cf2_hint_initZero( &dummy );   /* invalid hint map element */

      /* ghost bottom */
      cf2_hintmap_insertHint( hintmap,
                              &font->blues.emBoxBottomEdge,
                              &dummy );
      /* ghost top */
      cf2_hintmap_insertHint( hintmap,
                              &dummy,
                              &font->blues.emBoxTopEdge );
    }

    /* insert hints captured by a blue zone or already locked (higher */
    /* priority)                                                      */
    for ( i = 0, maskByte = 0x80; i < bitCount; i++ )
    {
      if ( maskByte & *maskPtr )
      {
        /* expand StemHint into two `CF2_Hint' elements */
        CF2_HintRec  bottomHintEdge, topHintEdge;


        cf2_hint_init( &bottomHintEdge,
                       hStemHintArray,
                       i,
                       font,
                       hintOrigin,
                       hintmap->scale,
                       TRUE /* bottom */ );
        cf2_hint_init( &topHintEdge,
                       hStemHintArray,
                       i,
                       font,
                       hintOrigin,
                       hintmap->scale,
                       FALSE /* top */ );

        if ( cf2_hint_isLocked( &bottomHintEdge ) ||
             cf2_hint_isLocked( &topHintEdge )    ||
             cf2_blues_capture( &font->blues,
                                &bottomHintEdge,
                                &topHintEdge )   )
        {
          /* insert captured hint into map */
          cf2_hintmap_insertHint( hintmap, &bottomHintEdge, &topHintEdge );

          *maskPtr &= ~maskByte;      /* turn off the bit for this hint */
        }
      }

      if ( ( i & 7 ) == 7 )
      {
        /* move to next mask byte */
        maskPtr++;
        maskByte = 0x80;
      }
      else
        maskByte >>= 1;
    }

    /* initial hint map includes only captured hints plus maybe one at 0 */

    /*
     * TODO: There is a problem here because we are trying to build a
     *       single hint map containing all captured hints.  It is
     *       possible for there to be conflicts between captured hints,
     *       either because of darkening or because the hints are in
     *       separate hint zones (we are ignoring hint zones for the
     *       initial map).  An example of the latter is MinionPro-Regular
     *       v2.030 glyph 883 (Greek Capital Alpha with Psili) at 15ppem.
     *       A stem hint for the psili conflicts with the top edge hint
     *       for the base character.  The stem hint gets priority because
     *       of its sort order.  In glyph 884 (Greek Capital Alpha with
     *       Psili and Oxia), the top of the base character gets a stem
     *       hint, and the psili does not.  This creates different initial
     *       maps for the two glyphs resulting in different renderings of
     *       the base character.  Will probably defer this either as not
     *       worth the cost or as a font bug.  I don't think there is any
     *       good reason for an accent to be captured by an alignment
     *       zone.  -darnold 2/12/10
     */

    if ( initialMap )
    {
      /* Apply a heuristic that inserts a point for (0,0), unless it's     */
      /* already covered by a mapping.  This locks the baseline for glyphs */
      /* that have no baseline hints.                                      */

      if ( hintmap->count == 0                           ||
           hintmap->edge[0].csCoord > 0                  ||
           hintmap->edge[hintmap->count - 1].csCoord < 0 )
      {
        /* all edges are above 0 or all edges are below 0; */
        /* construct a locked edge hint at 0               */

        CF2_HintRec  edge, invalid;


        cf2_hint_initZero( &edge );

        edge.flags = CF2_GhostBottom |
                     CF2_Locked      |
                     CF2_Synthetic;
        edge.scale = hintmap->scale;

        cf2_hint_initZero( &invalid );
        cf2_hintmap_insertHint( hintmap, &edge, &invalid );
      }
    }
    else
    {
      /* insert remaining hints */

      maskPtr = cf2_hintmask_getMaskPtr( &tempHintMask );

      for ( i = 0, maskByte = 0x80; i < bitCount; i++ )
      {
        if ( maskByte & *maskPtr )
        {
          CF2_HintRec  bottomHintEdge, topHintEdge;


          cf2_hint_init( &bottomHintEdge,
                         hStemHintArray,
                         i,
                         font,
                         hintOrigin,
                         hintmap->scale,
                         TRUE /* bottom */ );
          cf2_hint_init( &topHintEdge,
                         hStemHintArray,
                         i,
                         font,
                         hintOrigin,
                         hintmap->scale,
                         FALSE /* top */ );

          cf2_hintmap_insertHint( hintmap, &bottomHintEdge, &topHintEdge );
        }

        if ( ( i & 7 ) == 7 )
        {
          /* move to next mask byte */
          maskPtr++;
          maskByte = 0x80;
        }
        else
          maskByte >>= 1;
      }
    }

    /*
     * Note: The following line is a convenient place to break when
     *       debugging hinting.  Examine `hintmap->edge' for the list of
     *       enabled hints, then step over the call to see the effect of
     *       adjustment.  We stop here first on the recursive call that
     *       creates the initial map, and then on each counter group and
     *       hint zone.
     */

    /* adjust positions of hint edges that are not locked to blue zones */
    cf2_hintmap_adjustHints( hintmap );

    /* save the position of all hints that were used in this hint map; */
    /* if we use them again, we'll locate them in the same position    */
    if ( !initialMap )
    {
      for ( i = 0; i < hintmap->count; i++ )
      {
        if ( !cf2_hint_isSynthetic( &hintmap->edge[i] ) )
        {
          /* Note: include both valid and invalid edges            */
          /* Note: top and bottom edges are copied back separately */
          CF2_StemHint  stemhint = (CF2_StemHint)
                          cf2_arrstack_getPointer( hStemHintArray,
                                                   hintmap->edge[i].index );


          if ( cf2_hint_isTop( &hintmap->edge[i] ) )
            stemhint->maxDS = hintmap->edge[i].dsCoord;
          else
            stemhint->minDS = hintmap->edge[i].dsCoord;

          stemhint->used = TRUE;
        }
      }
    }

    /* hint map is ready to use */
    hintmap->isValid = TRUE;

    /* remember this mask has been used */
    cf2_hintmask_setNew( hintMask, FALSE );
  }


  FT_LOCAL_DEF( void )
  cf2_glyphpath_init( CF2_GlyphPath         glyphpath,
                      CF2_Font              font,
                      CF2_OutlineCallbacks  callbacks,
                      CF2_Fixed             scaleY,
                      /* CF2_Fixed  hShift, */
                      CF2_ArrStack          hStemHintArray,
                      CF2_ArrStack          vStemHintArray,
                      CF2_HintMask          hintMask,
                      CF2_Fixed             hintOriginY,
                      const CF2_Blues       blues,
                      const FT_Vector*      fractionalTranslation )
  {
    FT_ZERO( glyphpath );

    glyphpath->font      = font;
    glyphpath->callbacks = callbacks;

    cf2_arrstack_init( &glyphpath->hintMoves,
                       font->memory,
                       &font->error,
                       sizeof ( CF2_HintMoveRec ) );

    cf2_hintmap_init( &glyphpath->initialHintMap,
                      font,
                      &glyphpath->initialHintMap,
                      &glyphpath->hintMoves,
                      scaleY );
    cf2_hintmap_init( &glyphpath->firstHintMap,
                      font,
                      &glyphpath->initialHintMap,
                      &glyphpath->hintMoves,
                      scaleY );
    cf2_hintmap_init( &glyphpath->hintMap,
                      font,
                      &glyphpath->initialHintMap,
                      &glyphpath->hintMoves,
                      scaleY );

    glyphpath->scaleX = font->innerTransform.a;
    glyphpath->scaleC = font->innerTransform.c;
    glyphpath->scaleY = font->innerTransform.d;

    glyphpath->fractionalTranslation = *fractionalTranslation;

#if 0
    glyphpath->hShift = hShift;       /* for fauxing */
#endif

    glyphpath->hStemHintArray = hStemHintArray;
    glyphpath->vStemHintArray = vStemHintArray;
    glyphpath->hintMask       = hintMask;      /* ptr to current mask */
    glyphpath->hintOriginY    = hintOriginY;
    glyphpath->blues          = blues;
    glyphpath->darken         = font->darkened; /* TODO: should we make copies? */
    glyphpath->xOffset        = font->darkenX;
    glyphpath->yOffset        = font->darkenY;
    glyphpath->miterLimit     = 2 * FT_MAX(
                                     cf2_fixedAbs( glyphpath->xOffset ),
                                     cf2_fixedAbs( glyphpath->yOffset ) );

    /* .1 character space unit */
    glyphpath->snapThreshold = cf2_floatToFixed( 0.1f );

    glyphpath->moveIsPending = TRUE;
    glyphpath->pathIsOpen    = FALSE;
    glyphpath->pathIsClosing = FALSE;
    glyphpath->elemIsQueued  = FALSE;
  }


  FT_LOCAL_DEF( void )
  cf2_glyphpath_finalize( CF2_GlyphPath  glyphpath )
  {
    cf2_arrstack_finalize( &glyphpath->hintMoves );
  }


  /*
   * Hint point in y-direction and apply outerTransform.
   * Input `current' hint map (which is actually delayed by one element).
   * Input x,y point in Character Space.
   * Output x,y point in Device Space, including translation.
   */
  static void
  cf2_glyphpath_hintPoint( CF2_GlyphPath  glyphpath,
                           CF2_HintMap    hintmap,
                           FT_Vector*     ppt,
                           CF2_Fixed      x,
                           CF2_Fixed      y )
  {
    FT_Vector  pt;   /* hinted point in upright DS */


    pt.x = FT_MulFix( glyphpath->scaleX, x ) +
             FT_MulFix( glyphpath->scaleC, y );
    pt.y = cf2_hintmap_map( hintmap, y );

    ppt->x = FT_MulFix( glyphpath->font->outerTransform.a, pt.x )   +
               FT_MulFix( glyphpath->font->outerTransform.c, pt.y ) +
               glyphpath->fractionalTranslation.x;
    ppt->y = FT_MulFix( glyphpath->font->outerTransform.b, pt.x )   +
               FT_MulFix( glyphpath->font->outerTransform.d, pt.y ) +
               glyphpath->fractionalTranslation.y;
  }


  /*
   * From two line segments, (u1,u2) and (v1,v2), compute a point of
   * intersection on the corresponding lines.
   * Return false if no intersection is found, or if the intersection is
   * too far away from the ends of the line segments, u2 and v1.
   *
   */
  static FT_Bool
  cf2_glyphpath_computeIntersection( CF2_GlyphPath     glyphpath,
                                     const FT_Vector*  u1,
                                     const FT_Vector*  u2,
                                     const FT_Vector*  v1,
                                     const FT_Vector*  v2,
                                     FT_Vector*        intersection )
  {
    /*
     * Let `u' be a zero-based vector from the first segment, `v' from the
     * second segment.
     * Let `w 'be the zero-based vector from `u1' to `v1'.
     * `perp' is the `perpendicular dot product'; see
     * http://mathworld.wolfram.com/PerpDotProduct.html.
     * `s' is the parameter for the parametric line for the first segment
     * (`u').
     *
     * See notation in
     * http://softsurfer.com/Archive/algorithm_0104/algorithm_0104B.htm.
     * Calculations are done in 16.16, but must handle the squaring of
     * line lengths in character space.  We scale all vectors by 1/32 to
     * avoid overflow.  This allows values up to 4095 to be squared.  The
     * scale factor cancels in the divide.
     *
     * TODO: the scale factor could be computed from UnitsPerEm.
     *
     */

#define cf2_perp( a, b )                                    \
          ( FT_MulFix( a.x, b.y ) - FT_MulFix( a.y, b.x ) )

  /* round and divide by 32 */
#define CF2_CS_SCALE( x )         \
          ( ( (x) + 0x10 ) >> 5 )

    FT_Vector  u, v, w;      /* scaled vectors */
    CF2_Fixed  denominator, s;


    u.x = CF2_CS_SCALE( u2->x - u1->x );
    u.y = CF2_CS_SCALE( u2->y - u1->y );
    v.x = CF2_CS_SCALE( v2->x - v1->x );
    v.y = CF2_CS_SCALE( v2->y - v1->y );
    w.x = CF2_CS_SCALE( v1->x - u1->x );
    w.y = CF2_CS_SCALE( v1->y - u1->y );

    denominator = cf2_perp( u, v );

    if ( denominator == 0 )
      return FALSE;           /* parallel or coincident lines */

    s = FT_DivFix( cf2_perp( w, v ), denominator );

    intersection->x = u1->x + FT_MulFix( s, u2->x - u1->x );
    intersection->y = u1->y + FT_MulFix( s, u2->y - u1->y );

    /*
     * Special case snapping for horizontal and vertical lines.
     * This cleans up intersections and reduces problems with winding
     * order detection.
     * Sample case is sbc cd KozGoPr6N-Medium.otf 20 16685.
     * Note: these calculations are in character space.
     *
     */

    if ( u1->x == u2->x                                                     &&
         cf2_fixedAbs( intersection->x - u1->x ) < glyphpath->snapThreshold )
      intersection->x = u1->x;
    if ( u1->y == u2->y                                                     &&
         cf2_fixedAbs( intersection->y - u1->y ) < glyphpath->snapThreshold )
      intersection->y = u1->y;

    if ( v1->x == v2->x                                                     &&
         cf2_fixedAbs( intersection->x - v1->x ) < glyphpath->snapThreshold )
      intersection->x = v1->x;
    if ( v1->y == v2->y                                                     &&
         cf2_fixedAbs( intersection->y - v1->y ) < glyphpath->snapThreshold )
      intersection->y = v1->y;

    /* limit the intersection distance from midpoint of u2 and v1 */
    if ( cf2_fixedAbs( intersection->x - ( u2->x + v1->x ) / 2 ) >
           glyphpath->miterLimit                                   ||
         cf2_fixedAbs( intersection->y - ( u2->y + v1->y ) / 2 ) >
           glyphpath->miterLimit                                   )
      return FALSE;

    return TRUE;
  }


  /*
   * Push the cached element (glyphpath->prevElem*) to the outline
   * consumer.  When a darkening offset is used, the end point of the
   * cached element may be adjusted to an intersection point or we may
   * synthesize a connecting line to the current element.  If we are
   * closing a subpath, we may also generate a connecting line to the start
   * point.
   *
   * This is where Character Space (CS) is converted to Device Space (DS)
   * using a hint map.  This calculation must use a HintMap that was valid
   * at the time the element was saved.  For the first point in a subpath,
   * that is a saved HintMap.  For most elements, it just means the caller
   * has delayed building a HintMap from the current HintMask.
   *
   * Transform each point with outerTransform and call the outline
   * callbacks.  This is a general 3x3 transform:
   *
   *   x' = a*x + c*y + tx, y' = b*x + d*y + ty
   *
   * but it uses 4 elements from CF2_Font and the translation part
   * from CF2_GlyphPath.
   *
   */
  static void
  cf2_glyphpath_pushPrevElem( CF2_GlyphPath  glyphpath,
                              CF2_HintMap    hintmap,
                              FT_Vector*     nextP0,
                              FT_Vector      nextP1,
                              FT_Bool        close )
  {
    CF2_CallbackParamsRec  params;

    FT_Vector*  prevP0;
    FT_Vector*  prevP1;

    FT_Vector  intersection    = { 0, 0 };
    FT_Bool    useIntersection = FALSE;


    FT_ASSERT( glyphpath->prevElemOp == CF2_PathOpLineTo ||
               glyphpath->prevElemOp == CF2_PathOpCubeTo );

    if ( glyphpath->prevElemOp == CF2_PathOpLineTo )
    {
      prevP0 = &glyphpath->prevElemP0;
      prevP1 = &glyphpath->prevElemP1;
    }
    else
    {
      prevP0 = &glyphpath->prevElemP2;
      prevP1 = &glyphpath->prevElemP3;
    }

    /* optimization: if previous and next elements are offset by the same */
    /* amount, then there will be no gap, and no need to compute an       */
    /* intersection.                                                      */
    if ( prevP1->x != nextP0->x || prevP1->y != nextP0->y )
    {
      /* previous element does not join next element:             */
      /* adjust end point of previous element to the intersection */
      useIntersection = cf2_glyphpath_computeIntersection( glyphpath,
                                                           prevP0,
                                                           prevP1,
                                                           nextP0,
                                                           &nextP1,
                                                           &intersection );
      if ( useIntersection )
      {
        /* modify the last point of the cached element (either line or */
        /* curve)                                                      */
        *prevP1 = intersection;
      }
    }

    params.pt0 = glyphpath->currentDS;

    switch( glyphpath->prevElemOp )
    {
    case CF2_PathOpLineTo:
      params.op = CF2_PathOpLineTo;

      /* note: pt2 and pt3 are unused */

      if ( close )
      {
        /* use first hint map if closing */
        cf2_glyphpath_hintPoint( glyphpath,
                                 &glyphpath->firstHintMap,
                                 &params.pt1,
                                 glyphpath->prevElemP1.x,
                                 glyphpath->prevElemP1.y );
      }
      else
      {
        cf2_glyphpath_hintPoint( glyphpath,
                                 hintmap,
                                 &params.pt1,
                                 glyphpath->prevElemP1.x,
                                 glyphpath->prevElemP1.y );
      }

      /* output only non-zero length lines */
      if ( params.pt0.x != params.pt1.x || params.pt0.y != params.pt1.y )
      {
        glyphpath->callbacks->lineTo( glyphpath->callbacks, &params );

        glyphpath->currentDS = params.pt1;
      }
      break;

    case CF2_PathOpCubeTo:
      params.op = CF2_PathOpCubeTo;

      /* TODO: should we intersect the interior joins (p1-p2 and p2-p3)? */
      cf2_glyphpath_hintPoint( glyphpath,
                               hintmap,
                               &params.pt1,
                               glyphpath->prevElemP1.x,
                               glyphpath->prevElemP1.y );
      cf2_glyphpath_hintPoint( glyphpath,
                               hintmap,
                               &params.pt2,
                               glyphpath->prevElemP2.x,
                               glyphpath->prevElemP2.y );
      cf2_glyphpath_hintPoint( glyphpath,
                               hintmap,
                               &params.pt3,
                               glyphpath->prevElemP3.x,
                               glyphpath->prevElemP3.y );

      glyphpath->callbacks->cubeTo( glyphpath->callbacks, &params );

      glyphpath->currentDS = params.pt3;

      break;
    }

    if ( !useIntersection || close )
    {
      /* insert connecting line between end of previous element and start */
      /* of current one                                                   */
      /* note: at the end of a subpath, we might do both, so use `nextP0' */
      /* before we change it, below                                       */

      if ( close )
      {
        /* if we are closing the subpath, then nextP0 is in the first     */
        /* hint zone                                                      */
        cf2_glyphpath_hintPoint( glyphpath,
                                 &glyphpath->firstHintMap,
                                 &params.pt1,
                                 nextP0->x,
                                 nextP0->y );
      }
      else
      {
        cf2_glyphpath_hintPoint( glyphpath,
                                 hintmap,
                                 &params.pt1,
                                 nextP0->x,
                                 nextP0->y );
      }

      if ( params.pt1.x != glyphpath->currentDS.x ||
           params.pt1.y != glyphpath->currentDS.y )
      {
        /* length is nonzero */
        params.op  = CF2_PathOpLineTo;
        params.pt0 = glyphpath->currentDS;

        /* note: pt2 and pt3 are unused */
        glyphpath->callbacks->lineTo( glyphpath->callbacks, &params );

        glyphpath->currentDS = params.pt1;
      }
    }

    if ( useIntersection )
    {
      /* return intersection point to caller */
      *nextP0 = intersection;
    }
  }


  /* push a MoveTo element based on current point and offset of current */
  /* element                                                            */
  static void
  cf2_glyphpath_pushMove( CF2_GlyphPath  glyphpath,
                          FT_Vector      start )
  {
    CF2_CallbackParamsRec  params;


    params.op  = CF2_PathOpMoveTo;
    params.pt0 = glyphpath->currentDS;

    /* Test if move has really happened yet; it would have called */
    /* `cf2_hintmap_build' to set `isValid'.                   */
    if ( !cf2_hintmap_isValid( &glyphpath->hintMap ) )
    {
      /* we are here iff first subpath is missing a moveto operator: */
      /* synthesize first moveTo to finish initialization of hintMap */
      cf2_glyphpath_moveTo( glyphpath,
                            glyphpath->start.x,
                            glyphpath->start.y );
    }

    cf2_glyphpath_hintPoint( glyphpath,
                             &glyphpath->hintMap,
                             &params.pt1,
                             start.x,
                             start.y );

    /* note: pt2 and pt3 are unused */
    glyphpath->callbacks->moveTo( glyphpath->callbacks, &params );

    glyphpath->currentDS    = params.pt1;
    glyphpath->offsetStart0 = start;
  }


  /*
   * All coordinates are in character space.
   * On input, (x1, y1) and (x2, y2) give line segment.
   * On output, (x, y) give offset vector.
   * We use a piecewise approximation to trig functions.
   *
   * TODO: Offset true perpendicular and proper length
   *       supply the y-translation for hinting here, too,
   *       that adds yOffset unconditionally to *y.
   */
  static void
  cf2_glyphpath_computeOffset( CF2_GlyphPath  glyphpath,
                               CF2_Fixed      x1,
                               CF2_Fixed      y1,
                               CF2_Fixed      x2,
                               CF2_Fixed      y2,
                               CF2_Fixed*     x,
                               CF2_Fixed*     y )
  {
    CF2_Fixed  dx = x2 - x1;
    CF2_Fixed  dy = y2 - y1;


    /* note: negative offsets don't work here; negate deltas to change */
    /* quadrants, below                                                */
    if ( glyphpath->font->reverseWinding )
    {
      dx = -dx;
      dy = -dy;
    }

    *x = *y = 0;

    if ( !glyphpath->darken )
        return;

    /* add momentum for this path element */
    glyphpath->callbacks->windingMomentum +=
      cf2_getWindingMomentum( x1, y1, x2, y2 );

    /* note: allow mixed integer and fixed multiplication here */
    if ( dx >= 0 )
    {
      if ( dy >= 0 )
      {
        /* first quadrant, +x +y */

        if ( dx > 2 * dy )
        {
          /* +x */
          *x = 0;
          *y = 0;
        }
        else if ( dy > 2 * dx )
        {
          /* +y */
          *x = glyphpath->xOffset;
          *y = glyphpath->yOffset;
        }
        else
        {
          /* +x +y */
          *x = FT_MulFix( cf2_floatToFixed( 0.7 ),
                          glyphpath->xOffset );
          *y = FT_MulFix( cf2_floatToFixed( 1.0 - 0.7 ),
                          glyphpath->yOffset );
        }
      }
      else
      {
        /* fourth quadrant, +x -y */

        if ( dx > -2 * dy )
        {
          /* +x */
          *x = 0;
          *y = 0;
        }
        else if ( -dy > 2 * dx )
        {
          /* -y */
          *x = -glyphpath->xOffset;
          *y = glyphpath->yOffset;
        }
        else
        {
          /* +x -y */
          *x = FT_MulFix( cf2_floatToFixed( -0.7 ),
                          glyphpath->xOffset );
          *y = FT_MulFix( cf2_floatToFixed( 1.0 - 0.7 ),
                          glyphpath->yOffset );
        }
      }
    }
    else
    {
      if ( dy >= 0 )
      {
        /* second quadrant, -x +y */

        if ( -dx > 2 * dy )
        {
          /* -x */
          *x = 0;
          *y = 2 * glyphpath->yOffset;
        }
        else if ( dy > -2 * dx )
        {
          /* +y */
          *x = glyphpath->xOffset;
          *y = glyphpath->yOffset;
        }
        else
        {
          /* -x +y */
          *x = FT_MulFix( cf2_floatToFixed( 0.7 ),
                          glyphpath->xOffset );
          *y = FT_MulFix( cf2_floatToFixed( 1.0 + 0.7 ),
                          glyphpath->yOffset );
        }
      }
      else
      {
        /* third quadrant, -x -y */

        if ( -dx > -2 * dy )
        {
          /* -x */
          *x = 0;
          *y = 2 * glyphpath->yOffset;
        }
        else if ( -dy > -2 * dx )
        {
          /* -y */
          *x = -glyphpath->xOffset;
          *y = glyphpath->yOffset;
        }
        else
        {
          /* -x -y */
          *x = FT_MulFix( cf2_floatToFixed( -0.7 ),
                          glyphpath->xOffset );
          *y = FT_MulFix( cf2_floatToFixed( 1.0 + 0.7 ),
                          glyphpath->yOffset );
        }
      }
    }
  }


  /*
   * The functions cf2_glyphpath_{moveTo,lineTo,curveTo,closeOpenPath} are
   * called by the interpreter with Character Space (CS) coordinates.  Each
   * path element is placed into a queue of length one to await the
   * calculation of the following element.  At that time, the darkening
   * offset of the following element is known and joins can be computed,
   * including possible modification of this element, before mapping to
   * Device Space (DS) and passing it on to the outline consumer.
   *
   */
  FT_LOCAL_DEF( void )
  cf2_glyphpath_moveTo( CF2_GlyphPath  glyphpath,
                        CF2_Fixed      x,
                        CF2_Fixed      y )
  {
    cf2_glyphpath_closeOpenPath( glyphpath );

    /* save the parameters of the move for later, when we'll know how to */
    /* offset it;                                                        */
    /* also save last move point */
    glyphpath->currentCS.x = glyphpath->start.x = x;
    glyphpath->currentCS.y = glyphpath->start.y = y;

    glyphpath->moveIsPending = TRUE;

    /* ensure we have a valid map with current mask */
    if ( !cf2_hintmap_isValid( &glyphpath->hintMap ) ||
         cf2_hintmask_isNew( glyphpath->hintMask )   )
      cf2_hintmap_build( &glyphpath->hintMap,
                         glyphpath->hStemHintArray,
                         glyphpath->vStemHintArray,
                         glyphpath->hintMask,
                         glyphpath->hintOriginY,
                         FALSE );

    /* save a copy of current HintMap to use when drawing initial point */
    glyphpath->firstHintMap = glyphpath->hintMap;     /* structure copy */
  }


  FT_LOCAL_DEF( void )
  cf2_glyphpath_lineTo( CF2_GlyphPath  glyphpath,
                        CF2_Fixed      x,
                        CF2_Fixed      y )
  {
    CF2_Fixed  xOffset, yOffset;
    FT_Vector  P0, P1;
    FT_Bool    newHintMap;

    /*
     * New hints will be applied after cf2_glyphpath_pushPrevElem has run.
     * In case this is a synthesized closing line, any new hints should be
     * delayed until this path is closed (`cf2_hintmask_isNew' will be
     * called again before the next line or curve).
     */

    /* true if new hint map not on close */
    newHintMap = cf2_hintmask_isNew( glyphpath->hintMask ) &&
                 !glyphpath->pathIsClosing;

    /*
     * Zero-length lines may occur in the charstring.  Because we cannot
     * compute darkening offsets or intersections from zero-length lines,
     * it is best to remove them and avoid artifacts.  However, zero-length
     * lines in CS at the start of a new hint map can generate non-zero
     * lines in DS due to hint substitution.  We detect a change in hint
     * map here and pass those zero-length lines along.
     */

    /*
     * Note: Find explicitly closed paths here with a conditional
     *       breakpoint using
     *
     *         !gp->pathIsClosing && gp->start.x == x && gp->start.y == y
     *
     */

    if ( glyphpath->currentCS.x == x &&
         glyphpath->currentCS.y == y &&
         !newHintMap                 )
      /*
       * Ignore zero-length lines in CS where the hint map is the same
       * because the line in DS will also be zero length.
       *
       * Ignore zero-length lines when we synthesize a closing line because
       * the close will be handled in cf2_glyphPath_pushPrevElem.
       */
      return;

    cf2_glyphpath_computeOffset( glyphpath,
                                 glyphpath->currentCS.x,
                                 glyphpath->currentCS.y,
                                 x,
                                 y,
                                 &xOffset,
                                 &yOffset );

    /* construct offset points */
    P0.x = glyphpath->currentCS.x + xOffset;
    P0.y = glyphpath->currentCS.y + yOffset;
    P1.x = x + xOffset;
    P1.y = y + yOffset;

    if ( glyphpath->moveIsPending )
    {
      /* emit offset 1st point as MoveTo */
      cf2_glyphpath_pushMove( glyphpath, P0 );

      glyphpath->moveIsPending = FALSE;  /* adjust state machine */
      glyphpath->pathIsOpen    = TRUE;

      glyphpath->offsetStart1 = P1;              /* record second point */
    }

    if ( glyphpath->elemIsQueued )
    {
      FT_ASSERT( cf2_hintmap_isValid( &glyphpath->hintMap ) ||
                 glyphpath->hintMap.count == 0              );

      cf2_glyphpath_pushPrevElem( glyphpath,
                                  &glyphpath->hintMap,
                                  &P0,
                                  P1,
                                  FALSE );
    }

    /* queue the current element with offset points */
    glyphpath->elemIsQueued = TRUE;
    glyphpath->prevElemOp   = CF2_PathOpLineTo;
    glyphpath->prevElemP0   = P0;
    glyphpath->prevElemP1   = P1;

    /* update current map */
    if ( newHintMap )
      cf2_hintmap_build( &glyphpath->hintMap,
                         glyphpath->hStemHintArray,
                         glyphpath->vStemHintArray,
                         glyphpath->hintMask,
                         glyphpath->hintOriginY,
                         FALSE );

    glyphpath->currentCS.x = x;     /* pre-offset current point */
    glyphpath->currentCS.y = y;
  }


  FT_LOCAL_DEF( void )
  cf2_glyphpath_curveTo( CF2_GlyphPath  glyphpath,
                         CF2_Fixed      x1,
                         CF2_Fixed      y1,
                         CF2_Fixed      x2,
                         CF2_Fixed      y2,
                         CF2_Fixed      x3,
                         CF2_Fixed      y3 )
  {
    CF2_Fixed  xOffset1, yOffset1, xOffset3, yOffset3;
    FT_Vector  P0, P1, P2, P3;


    /* TODO: ignore zero length portions of curve?? */
    cf2_glyphpath_computeOffset( glyphpath,
                                 glyphpath->currentCS.x,
                                 glyphpath->currentCS.y,
                                 x1,
                                 y1,
                                 &xOffset1,
                                 &yOffset1 );
    cf2_glyphpath_computeOffset( glyphpath,
                                 x2,
                                 y2,
                                 x3,
                                 y3,
                                 &xOffset3,
                                 &yOffset3 );

    /* add momentum from the middle segment */
    glyphpath->callbacks->windingMomentum +=
      cf2_getWindingMomentum( x1, y1, x2, y2 );

    /* construct offset points */
    P0.x = glyphpath->currentCS.x + xOffset1;
    P0.y = glyphpath->currentCS.y + yOffset1;
    P1.x = x1 + xOffset1;
    P1.y = y1 + yOffset1;
    /* note: preserve angle of final segment by using offset3 at both ends */
    P2.x = x2 + xOffset3;
    P2.y = y2 + yOffset3;
    P3.x = x3 + xOffset3;
    P3.y = y3 + yOffset3;

    if ( glyphpath->moveIsPending )
    {
      /* emit offset 1st point as MoveTo */
      cf2_glyphpath_pushMove( glyphpath, P0 );

      glyphpath->moveIsPending = FALSE;
      glyphpath->pathIsOpen    = TRUE;

      glyphpath->offsetStart1 = P1;              /* record second point */
    }

    if ( glyphpath->elemIsQueued )
    {
      FT_ASSERT( cf2_hintmap_isValid( &glyphpath->hintMap ) ||
                 glyphpath->hintMap.count == 0              );

      cf2_glyphpath_pushPrevElem( glyphpath,
                                  &glyphpath->hintMap,
                                  &P0,
                                  P1,
                                  FALSE );
    }

    /* queue the current element with offset points */
    glyphpath->elemIsQueued = TRUE;
    glyphpath->prevElemOp   = CF2_PathOpCubeTo;
    glyphpath->prevElemP0   = P0;
    glyphpath->prevElemP1   = P1;
    glyphpath->prevElemP2   = P2;
    glyphpath->prevElemP3   = P3;

    /* update current map */
    if ( cf2_hintmask_isNew( glyphpath->hintMask ) )
      cf2_hintmap_build( &glyphpath->hintMap,
                         glyphpath->hStemHintArray,
                         glyphpath->vStemHintArray,
                         glyphpath->hintMask,
                         glyphpath->hintOriginY,
                         FALSE );

    glyphpath->currentCS.x = x3;       /* pre-offset current point */
    glyphpath->currentCS.y = y3;
  }


  FT_LOCAL_DEF( void )
  cf2_glyphpath_closeOpenPath( CF2_GlyphPath  glyphpath )
  {
    if ( glyphpath->pathIsOpen )
    {
      /*
       * A closing line in Character Space line is always generated below
       * with `cf2_glyphPath_lineTo'.  It may be ignored later if it turns
       * out to be zero length in Device Space.
       */
      glyphpath->pathIsClosing = TRUE;

      cf2_glyphpath_lineTo( glyphpath,
                            glyphpath->start.x,
                            glyphpath->start.y );

      /* empty the final element from the queue and close the path */
      if ( glyphpath->elemIsQueued )
        cf2_glyphpath_pushPrevElem( glyphpath,
                                    &glyphpath->hintMap,
                                    &glyphpath->offsetStart0,
                                    glyphpath->offsetStart1,
                                    TRUE );

      /* reset state machine */
      glyphpath->moveIsPending = TRUE;
      glyphpath->pathIsOpen    = FALSE;
      glyphpath->pathIsClosing = FALSE;
      glyphpath->elemIsQueued  = FALSE;
    }
  }


/* END */
