/***************************************************************************/
/*                                                                         */
/*  pfrgload.c                                                             */
/*                                                                         */
/*    FreeType PFR glyph loader (body).                                    */
/*                                                                         */
/*  Copyright 2002-2015 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 "pfrgload.h"
#include "pfrsbit.h"
#include "pfrload.h"            /* for macro definitions */
#include FT_INTERNAL_DEBUG_H

#include "pfrerror.h"

#undef  FT_COMPONENT
#define FT_COMPONENT  trace_pfr


  /*************************************************************************/
  /*************************************************************************/
  /*****                                                               *****/
  /*****                      PFR GLYPH BUILDER                        *****/
  /*****                                                               *****/
  /*************************************************************************/
  /*************************************************************************/


  FT_LOCAL_DEF( void )
  pfr_glyph_init( PFR_Glyph       glyph,
                  FT_GlyphLoader  loader )
  {
    FT_ZERO( glyph );

    glyph->loader     = loader;
    glyph->path_begun = 0;

    FT_GlyphLoader_Rewind( loader );
  }


  FT_LOCAL_DEF( void )
  pfr_glyph_done( PFR_Glyph  glyph )
  {
    FT_Memory  memory = glyph->loader->memory;


    FT_FREE( glyph->x_control );
    glyph->y_control = NULL;

    glyph->max_xy_control = 0;
#if 0
    glyph->num_x_control  = 0;
    glyph->num_y_control  = 0;
#endif

    FT_FREE( glyph->subs );

    glyph->max_subs = 0;
    glyph->num_subs = 0;

    glyph->loader     = NULL;
    glyph->path_begun = 0;
  }


  /* close current contour, if any */
  static void
  pfr_glyph_close_contour( PFR_Glyph  glyph )
  {
    FT_GlyphLoader  loader  = glyph->loader;
    FT_Outline*     outline = &loader->current.outline;
    FT_Int          last, first;


    if ( !glyph->path_begun )
      return;

    /* compute first and last point indices in current glyph outline */
    last  = outline->n_points - 1;
    first = 0;
    if ( outline->n_contours > 0 )
      first = outline->contours[outline->n_contours - 1];

    /* if the last point falls on the same location than the first one */
    /* we need to delete it                                            */
    if ( last > first )
    {
      FT_Vector*  p1 = outline->points + first;
      FT_Vector*  p2 = outline->points + last;


      if ( p1->x == p2->x && p1->y == p2->y )
      {
        outline->n_points--;
        last--;
      }
    }

    /* don't add empty contours */
    if ( last >= first )
      outline->contours[outline->n_contours++] = (short)last;

    glyph->path_begun = 0;
  }


  /* reset glyph to start the loading of a new glyph */
  static void
  pfr_glyph_start( PFR_Glyph  glyph )
  {
    glyph->path_begun = 0;
  }


  static FT_Error
  pfr_glyph_line_to( PFR_Glyph   glyph,
                     FT_Vector*  to )
  {
    FT_GlyphLoader  loader  = glyph->loader;
    FT_Outline*     outline = &loader->current.outline;
    FT_Error        error;


    /* check that we have begun a new path */
    if ( !glyph->path_begun )
    {
      error = FT_THROW( Invalid_Table );
      FT_ERROR(( "pfr_glyph_line_to: invalid glyph data\n" ));
      goto Exit;
    }

    error = FT_GLYPHLOADER_CHECK_POINTS( loader, 1, 0 );
    if ( !error )
    {
      FT_Int  n = outline->n_points;


      outline->points[n] = *to;
      outline->tags  [n] = FT_CURVE_TAG_ON;

      outline->n_points++;
    }

  Exit:
    return error;
  }


  static FT_Error
  pfr_glyph_curve_to( PFR_Glyph   glyph,
                      FT_Vector*  control1,
                      FT_Vector*  control2,
                      FT_Vector*  to )
  {
    FT_GlyphLoader  loader  = glyph->loader;
    FT_Outline*     outline = &loader->current.outline;
    FT_Error        error;


    /* check that we have begun a new path */
    if ( !glyph->path_begun )
    {
      error = FT_THROW( Invalid_Table );
      FT_ERROR(( "pfr_glyph_line_to: invalid glyph data\n" ));
      goto Exit;
    }

    error = FT_GLYPHLOADER_CHECK_POINTS( loader, 3, 0 );
    if ( !error )
    {
      FT_Vector*  vec = outline->points         + outline->n_points;
      FT_Byte*    tag = (FT_Byte*)outline->tags + outline->n_points;


      vec[0] = *control1;
      vec[1] = *control2;
      vec[2] = *to;
      tag[0] = FT_CURVE_TAG_CUBIC;
      tag[1] = FT_CURVE_TAG_CUBIC;
      tag[2] = FT_CURVE_TAG_ON;

      outline->n_points = (FT_Short)( outline->n_points + 3 );
    }

  Exit:
    return error;
  }


  static FT_Error
  pfr_glyph_move_to( PFR_Glyph   glyph,
                     FT_Vector*  to )
  {
    FT_GlyphLoader  loader  = glyph->loader;
    FT_Error        error;


    /* close current contour if any */
    pfr_glyph_close_contour( glyph );

    /* indicate that a new contour has started */
    glyph->path_begun = 1;

    /* check that there is space for a new contour and a new point */
    error = FT_GLYPHLOADER_CHECK_POINTS( loader, 1, 1 );
    if ( !error )
      /* add new start point */
      error = pfr_glyph_line_to( glyph, to );

    return error;
  }


  static void
  pfr_glyph_end( PFR_Glyph  glyph )
  {
    /* close current contour if any */
    pfr_glyph_close_contour( glyph );

    /* merge the current glyph into the stack */
    FT_GlyphLoader_Add( glyph->loader );
  }


  /*************************************************************************/
  /*************************************************************************/
  /*****                                                               *****/
  /*****                      PFR GLYPH LOADER                         *****/
  /*****                                                               *****/
  /*************************************************************************/
  /*************************************************************************/


  /* load a simple glyph */
  static FT_Error
  pfr_glyph_load_simple( PFR_Glyph  glyph,
                         FT_Byte*   p,
                         FT_Byte*   limit )
  {
    FT_Error   error  = FT_Err_Ok;
    FT_Memory  memory = glyph->loader->memory;
    FT_UInt    flags, x_count, y_count, i, count, mask;
    FT_Int     x;


    PFR_CHECK( 1 );
    flags = PFR_NEXT_BYTE( p );

    /* test for composite glyphs */
    if ( flags & PFR_GLYPH_IS_COMPOUND )
      goto Failure;

    x_count = 0;
    y_count = 0;

    if ( flags & PFR_GLYPH_1BYTE_XYCOUNT )
    {
      PFR_CHECK( 1 );
      count   = PFR_NEXT_BYTE( p );
      x_count = count & 15;
      y_count = count >> 4;
    }
    else
    {
      if ( flags & PFR_GLYPH_XCOUNT )
      {
        PFR_CHECK( 1 );
        x_count = PFR_NEXT_BYTE( p );
      }

      if ( flags & PFR_GLYPH_YCOUNT )
      {
        PFR_CHECK( 1 );
        y_count = PFR_NEXT_BYTE( p );
      }
    }

    count = x_count + y_count;

    /* re-allocate array when necessary */
    if ( count > glyph->max_xy_control )
    {
      FT_UInt  new_max = FT_PAD_CEIL( count, 8 );


      if ( FT_RENEW_ARRAY( glyph->x_control,
                           glyph->max_xy_control,
                           new_max ) )
        goto Exit;

      glyph->max_xy_control = new_max;
    }

    glyph->y_control = glyph->x_control + x_count;

    mask  = 0;
    x     = 0;

    for ( i = 0; i < count; i++ )
    {
      if ( ( i & 7 ) == 0 )
      {
        PFR_CHECK( 1 );
        mask = PFR_NEXT_BYTE( p );
      }

      if ( mask & 1 )
      {
        PFR_CHECK( 2 );
        x = PFR_NEXT_SHORT( p );
      }
      else
      {
        PFR_CHECK( 1 );
        x += PFR_NEXT_BYTE( p );
      }

      glyph->x_control[i] = x;

      mask >>= 1;
    }

    /* XXX: for now we ignore the secondary stroke and edge definitions */
    /*      since we don't want to support native PFR hinting           */
    /*                                                                  */
    if ( flags & PFR_GLYPH_EXTRA_ITEMS )
    {
      error = pfr_extra_items_skip( &p, limit );
      if ( error )
        goto Exit;
    }

    pfr_glyph_start( glyph );

    /* now load a simple glyph */
    {
      FT_Vector   pos[4];
      FT_Vector*  cur;


      pos[0].x = pos[0].y = 0;
      pos[3]   = pos[0];

      for (;;)
      {
        FT_UInt  format, format_low, args_format = 0, args_count, n;


        /***************************************************************/
        /*  read instruction                                           */
        /*                                                             */
        PFR_CHECK( 1 );
        format     = PFR_NEXT_BYTE( p );
        format_low = format & 15;

        switch ( format >> 4 )
        {
        case 0:                             /* end glyph */
          FT_TRACE6(( "- end glyph" ));
          args_count = 0;
          break;

        case 1:                             /* general line operation */
          FT_TRACE6(( "- general line" ));
          goto Line1;

        case 4:                             /* move to inside contour  */
          FT_TRACE6(( "- move to inside" ));
          goto Line1;

        case 5:                             /* move to outside contour */
          FT_TRACE6(( "- move to outside" ));
        Line1:
          args_format = format_low;
          args_count  = 1;
          break;

        case 2:                             /* horizontal line to */
          FT_TRACE6(( "- horizontal line to cx.%d", format_low ));
          if ( format_low >= x_count )
            goto Failure;
          pos[0].x   = glyph->x_control[format_low];
          pos[0].y   = pos[3].y;
          pos[3]     = pos[0];
          args_count = 0;
          break;

        case 3:                             /* vertical line to */
          FT_TRACE6(( "- vertical line to cy.%d", format_low ));
          if ( format_low >= y_count )
            goto Failure;
          pos[0].x   = pos[3].x;
          pos[0].y   = glyph->y_control[format_low];
          pos[3]     = pos[0];
          args_count = 0;
          break;

        case 6:                             /* horizontal to vertical curve */
          FT_TRACE6(( "- hv curve " ));
          args_format = 0xB8E;
          args_count  = 3;
          break;

        case 7:                             /* vertical to horizontal curve */
          FT_TRACE6(( "- vh curve" ));
          args_format = 0xE2B;
          args_count  = 3;
          break;

        default:                            /* general curve to */
          FT_TRACE6(( "- general curve" ));
          args_count  = 4;
          args_format = format_low;
        }

        /***********************************************************/
        /*  now read arguments                                     */
        /*                                                         */
        cur = pos;
        for ( n = 0; n < args_count; n++ )
        {
          FT_UInt  idx;
          FT_Int   delta;


          /* read the X argument */
          switch ( args_format & 3 )
          {
          case 0:                           /* 8-bit index */
            PFR_CHECK( 1 );
            idx  = PFR_NEXT_BYTE( p );
            if ( idx >= x_count )
              goto Failure;
            cur->x = glyph->x_control[idx];
            FT_TRACE7(( " cx#%d", idx ));
            break;

          case 1:                           /* 16-bit value */
            PFR_CHECK( 2 );
            cur->x = PFR_NEXT_SHORT( p );
            FT_TRACE7(( " x.%d", cur->x ));
            break;

          case 2:                           /* 8-bit delta */
            PFR_CHECK( 1 );
            delta  = PFR_NEXT_INT8( p );
            cur->x = pos[3].x + delta;
            FT_TRACE7(( " dx.%d", delta ));
            break;

          default:
            FT_TRACE7(( " |" ));
            cur->x = pos[3].x;
          }

          /* read the Y argument */
          switch ( ( args_format >> 2 ) & 3 )
          {
          case 0:                           /* 8-bit index */
            PFR_CHECK( 1 );
            idx  = PFR_NEXT_BYTE( p );
            if ( idx >= y_count )
              goto Failure;
            cur->y = glyph->y_control[idx];
            FT_TRACE7(( " cy#%d", idx ));
            break;

          case 1:                           /* 16-bit absolute value */
            PFR_CHECK( 2 );
            cur->y = PFR_NEXT_SHORT( p );
            FT_TRACE7(( " y.%d", cur->y ));
            break;

          case 2:                           /* 8-bit delta */
            PFR_CHECK( 1 );
            delta  = PFR_NEXT_INT8( p );
            cur->y = pos[3].y + delta;
            FT_TRACE7(( " dy.%d", delta ));
            break;

          default:
            FT_TRACE7(( " -" ));
            cur->y = pos[3].y;
          }

          /* read the additional format flag for the general curve */
          if ( n == 0 && args_count == 4 )
          {
            PFR_CHECK( 1 );
            args_format = PFR_NEXT_BYTE( p );
            args_count--;
          }
          else
            args_format >>= 4;

          /* save the previous point */
          pos[3] = cur[0];
          cur++;
        }

        FT_TRACE7(( "\n" ));

        /***********************************************************/
        /*  finally, execute instruction                           */
        /*                                                         */
        switch ( format >> 4 )
        {
        case 0:                             /* end glyph => EXIT */
          pfr_glyph_end( glyph );
          goto Exit;

        case 1:                             /* line operations */
        case 2:
        case 3:
          error = pfr_glyph_line_to( glyph, pos );
          goto Test_Error;

        case 4:                             /* move to inside contour  */
        case 5:                             /* move to outside contour */
          error = pfr_glyph_move_to( glyph, pos );
          goto Test_Error;

        default:                            /* curve operations */
          error = pfr_glyph_curve_to( glyph, pos, pos + 1, pos + 2 );

        Test_Error:  /* test error condition */
          if ( error )
            goto Exit;
        }
      } /* for (;;) */
    }

  Exit:
    return error;

  Failure:
  Too_Short:
    error = FT_THROW( Invalid_Table );
    FT_ERROR(( "pfr_glyph_load_simple: invalid glyph data\n" ));
    goto Exit;
  }


  /* load a composite/compound glyph */
  static FT_Error
  pfr_glyph_load_compound( PFR_Glyph  glyph,
                           FT_Byte*   p,
                           FT_Byte*   limit )
  {
    FT_Error        error  = FT_Err_Ok;
    FT_GlyphLoader  loader = glyph->loader;
    FT_Memory       memory = loader->memory;
    PFR_SubGlyph    subglyph;
    FT_UInt         flags, i, count, org_count;
    FT_Int          x_pos, y_pos;


    PFR_CHECK( 1 );
    flags = PFR_NEXT_BYTE( p );

    /* test for composite glyphs */
    if ( !( flags & PFR_GLYPH_IS_COMPOUND ) )
      goto Failure;

    count = flags & 0x3F;

    /* ignore extra items when present */
    /*                                 */
    if ( flags & PFR_GLYPH_EXTRA_ITEMS )
    {
      error = pfr_extra_items_skip( &p, limit );
      if (error) goto Exit;
    }

    /* we can't rely on the FT_GlyphLoader to load sub-glyphs, because   */
    /* the PFR format is dumb, using direct file offsets to point to the */
    /* sub-glyphs (instead of glyph indices).  Sigh.                     */
    /*                                                                   */
    /* For now, we load the list of sub-glyphs into a different array    */
    /* but this will prevent us from using the auto-hinter at its best   */
    /* quality.                                                          */
    /*                                                                   */
    org_count = glyph->num_subs;

    if ( org_count + count > glyph->max_subs )
    {
      FT_UInt  new_max = ( org_count + count + 3 ) & (FT_UInt)-4;


      /* we arbitrarily limit the number of subglyphs */
      /* to avoid endless recursion                   */
      if ( new_max > 64 )
      {
        error = FT_THROW( Invalid_Table );
        FT_ERROR(( "pfr_glyph_load_compound:"
                   " too many compound glyphs components\n" ));
        goto Exit;
      }

      if ( FT_RENEW_ARRAY( glyph->subs, glyph->max_subs, new_max ) )
        goto Exit;

      glyph->max_subs = new_max;
    }

    subglyph = glyph->subs + org_count;

    for ( i = 0; i < count; i++, subglyph++ )
    {
      FT_UInt  format;


      x_pos = 0;
      y_pos = 0;

      PFR_CHECK( 1 );
      format = PFR_NEXT_BYTE( p );

      /* read scale when available */
      subglyph->x_scale = 0x10000L;
      if ( format & PFR_SUBGLYPH_XSCALE )
      {
        PFR_CHECK( 2 );
        subglyph->x_scale = PFR_NEXT_SHORT( p ) << 4;
      }

      subglyph->y_scale = 0x10000L;
      if ( format & PFR_SUBGLYPH_YSCALE )
      {
        PFR_CHECK( 2 );
        subglyph->y_scale = PFR_NEXT_SHORT( p ) << 4;
      }

      /* read offset */
      switch ( format & 3 )
      {
      case 1:
        PFR_CHECK( 2 );
        x_pos = PFR_NEXT_SHORT( p );
        break;

      case 2:
        PFR_CHECK( 1 );
        x_pos += PFR_NEXT_INT8( p );
        break;

      default:
        ;
      }

      switch ( ( format >> 2 ) & 3 )
      {
      case 1:
        PFR_CHECK( 2 );
        y_pos = PFR_NEXT_SHORT( p );
        break;

      case 2:
        PFR_CHECK( 1 );
        y_pos += PFR_NEXT_INT8( p );
        break;

      default:
        ;
      }

      subglyph->x_delta = x_pos;
      subglyph->y_delta = y_pos;

      /* read glyph position and size now */
      if ( format & PFR_SUBGLYPH_2BYTE_SIZE )
      {
        PFR_CHECK( 2 );
        subglyph->gps_size = PFR_NEXT_USHORT( p );
      }
      else
      {
        PFR_CHECK( 1 );
        subglyph->gps_size = PFR_NEXT_BYTE( p );
      }

      if ( format & PFR_SUBGLYPH_3BYTE_OFFSET )
      {
        PFR_CHECK( 3 );
        subglyph->gps_offset = PFR_NEXT_ULONG( p );
      }
      else
      {
        PFR_CHECK( 2 );
        subglyph->gps_offset = PFR_NEXT_USHORT( p );
      }

      glyph->num_subs++;
    }

  Exit:
    return error;

  Failure:
  Too_Short:
    error = FT_THROW( Invalid_Table );
    FT_ERROR(( "pfr_glyph_load_compound: invalid glyph data\n" ));
    goto Exit;
  }


  static FT_Error
  pfr_glyph_load_rec( PFR_Glyph  glyph,
                      FT_Stream  stream,
                      FT_ULong   gps_offset,
                      FT_ULong   offset,
                      FT_ULong   size )
  {
    FT_Error  error;
    FT_Byte*  p;
    FT_Byte*  limit;


    if ( FT_STREAM_SEEK( gps_offset + offset ) ||
         FT_FRAME_ENTER( size )                )
      goto Exit;

    p     = (FT_Byte*)stream->cursor;
    limit = p + size;

    if ( size > 0 && *p & PFR_GLYPH_IS_COMPOUND )
    {
      FT_UInt         n, old_count, count;
      FT_GlyphLoader  loader = glyph->loader;
      FT_Outline*     base   = &loader->base.outline;


      old_count = glyph->num_subs;

      /* this is a compound glyph - load it */
      error = pfr_glyph_load_compound( glyph, p, limit );

      FT_FRAME_EXIT();

      if ( error )
        goto Exit;

      count = glyph->num_subs - old_count;

      FT_TRACE4(( "compound glyph with %d elements (offset %lu):\n",
                  count, offset ));

      /* now, load each individual glyph */
      for ( n = 0; n < count; n++ )
      {
        FT_Int        i, old_points, num_points;
        PFR_SubGlyph  subglyph;


        FT_TRACE4(( "  subglyph %d:\n", n ));

        subglyph   = glyph->subs + old_count + n;
        old_points = base->n_points;

        error = pfr_glyph_load_rec( glyph, stream, gps_offset,
                                    subglyph->gps_offset,
                                    subglyph->gps_size );
        if ( error )
          break;

        /* note that `glyph->subs' might have been re-allocated */
        subglyph   = glyph->subs + old_count + n;
        num_points = base->n_points - old_points;

        /* translate and eventually scale the new glyph points */
        if ( subglyph->x_scale != 0x10000L || subglyph->y_scale != 0x10000L )
        {
          FT_Vector*  vec = base->points + old_points;


          for ( i = 0; i < num_points; i++, vec++ )
          {
            vec->x = FT_MulFix( vec->x, subglyph->x_scale ) +
                       subglyph->x_delta;
            vec->y = FT_MulFix( vec->y, subglyph->y_scale ) +
                       subglyph->y_delta;
          }
        }
        else
        {
          FT_Vector*  vec = loader->base.outline.points + old_points;


          for ( i = 0; i < num_points; i++, vec++ )
          {
            vec->x += subglyph->x_delta;
            vec->y += subglyph->y_delta;
          }
        }

        /* proceed to next sub-glyph */
      }

      FT_TRACE4(( "end compound glyph with %d elements\n", count ));
    }
    else
    {
      FT_TRACE4(( "simple glyph (offset %lu)\n", offset ));

      /* load a simple glyph */
      error = pfr_glyph_load_simple( glyph, p, limit );

      FT_FRAME_EXIT();
    }

  Exit:
    return error;
  }


  FT_LOCAL_DEF( FT_Error )
  pfr_glyph_load( PFR_Glyph  glyph,
                  FT_Stream  stream,
                  FT_ULong   gps_offset,
                  FT_ULong   offset,
                  FT_ULong   size )
  {
    /* initialize glyph loader */
    FT_GlyphLoader_Rewind( glyph->loader );

    glyph->num_subs = 0;

    /* load the glyph, recursively when needed */
    return pfr_glyph_load_rec( glyph, stream, gps_offset, offset, size );
  }


/* END */
