/****************************************************************************
 *
 * ttgload.c
 *
 *   TrueType Glyph Loader (body).
 *
 * Copyright (C) 1996-2019 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 <ft2build.h>
#include FT_INTERNAL_DEBUG_H
#include FT_CONFIG_CONFIG_H
#include FT_INTERNAL_CALC_H
#include FT_INTERNAL_STREAM_H
#include FT_INTERNAL_SFNT_H
#include FT_TRUETYPE_TAGS_H
#include FT_OUTLINE_H
#include FT_DRIVER_H
#include FT_LIST_H

#include "ttgload.h"
#include "ttpload.h"

#ifdef TT_CONFIG_OPTION_GX_VAR_SUPPORT
#include "ttgxvar.h"
#endif

#include "tterrors.h"
#include "ttsubpix.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  ttgload


  /**************************************************************************
   *
   * Simple glyph flags.
   */
#define ON_CURVE_POINT  0x01  /* same value as FT_CURVE_TAG_ON            */
#define X_SHORT_VECTOR  0x02
#define Y_SHORT_VECTOR  0x04
#define REPEAT_FLAG     0x08
#define X_POSITIVE      0x10  /* two meanings depending on X_SHORT_VECTOR */
#define SAME_X          0x10
#define Y_POSITIVE      0x20  /* two meanings depending on Y_SHORT_VECTOR */
#define SAME_Y          0x20
#define OVERLAP_SIMPLE  0x40  /* we ignore this value                     */


  /**************************************************************************
   *
   * Composite glyph flags.
   */
#define ARGS_ARE_WORDS             0x0001
#define ARGS_ARE_XY_VALUES         0x0002
#define ROUND_XY_TO_GRID           0x0004
#define WE_HAVE_A_SCALE            0x0008
/* reserved                        0x0010 */
#define MORE_COMPONENTS            0x0020
#define WE_HAVE_AN_XY_SCALE        0x0040
#define WE_HAVE_A_2X2              0x0080
#define WE_HAVE_INSTR              0x0100
#define USE_MY_METRICS             0x0200
#define OVERLAP_COMPOUND           0x0400  /* we ignore this value */
#define SCALED_COMPONENT_OFFSET    0x0800
#define UNSCALED_COMPONENT_OFFSET  0x1000


  /**************************************************************************
   *
   * Return the horizontal metrics in font units for a given glyph.
   */
  FT_LOCAL_DEF( void )
  TT_Get_HMetrics( TT_Face     face,
                   FT_UInt     idx,
                   FT_Short*   lsb,
                   FT_UShort*  aw )
  {
    ( (SFNT_Service)face->sfnt )->get_metrics( face, 0, idx, lsb, aw );

    FT_TRACE5(( "  advance width (font units): %d\n", *aw ));
    FT_TRACE5(( "  left side bearing (font units): %d\n", *lsb ));
  }


  /**************************************************************************
   *
   * Return the vertical metrics in font units for a given glyph.
   * See function `tt_loader_set_pp' below for explanations.
   */
  FT_LOCAL_DEF( void )
  TT_Get_VMetrics( TT_Face     face,
                   FT_UInt     idx,
                   FT_Pos      yMax,
                   FT_Short*   tsb,
                   FT_UShort*  ah )
  {
    if ( face->vertical_info )
      ( (SFNT_Service)face->sfnt )->get_metrics( face, 1, idx, tsb, ah );

    else if ( face->os2.version != 0xFFFFU )
    {
      *tsb = (FT_Short)( face->os2.sTypoAscender - yMax );
      *ah  = (FT_UShort)FT_ABS( face->os2.sTypoAscender -
                                face->os2.sTypoDescender );
    }

    else
    {
      *tsb = (FT_Short)( face->horizontal.Ascender - yMax );
      *ah  = (FT_UShort)FT_ABS( face->horizontal.Ascender -
                                face->horizontal.Descender );
    }

    FT_TRACE5(( "  advance height (font units): %d\n", *ah ));
    FT_TRACE5(( "  top side bearing (font units): %d\n", *tsb ));
  }


  static FT_Error
  tt_get_metrics( TT_Loader  loader,
                  FT_UInt    glyph_index )
  {
    TT_Face    face   = loader->face;
#ifdef TT_SUPPORT_SUBPIXEL_HINTING_INFINALITY
    TT_Driver  driver = (TT_Driver)FT_FACE_DRIVER( face );
#endif

    FT_Error   error;
    FT_Stream  stream = loader->stream;

    FT_Short   left_bearing = 0, top_bearing = 0;
    FT_UShort  advance_width = 0, advance_height = 0;

    /* we must preserve the stream position          */
    /* (which gets altered by the metrics functions) */
    FT_ULong  pos = FT_STREAM_POS();


    TT_Get_HMetrics( face, glyph_index,
                     &left_bearing,
                     &advance_width );
    TT_Get_VMetrics( face, glyph_index,
                     loader->bbox.yMax,
                     &top_bearing,
                     &advance_height );

    if ( FT_STREAM_SEEK( pos ) )
      return error;

    loader->left_bearing = left_bearing;
    loader->advance      = advance_width;
    loader->top_bearing  = top_bearing;
    loader->vadvance     = advance_height;

#ifdef TT_SUPPORT_SUBPIXEL_HINTING_INFINALITY
    if ( driver->interpreter_version == TT_INTERPRETER_VERSION_38 &&
         loader->exec                                             )
    {
      loader->exec->sph_tweak_flags = 0;

      /* This may not be the right place for this, but it works...  */
      /* Note that we have to unconditionally load the tweaks since */
      /* it is possible that glyphs individually switch ClearType's */
      /* backward compatibility mode on and off.                    */
      sph_set_tweaks( loader, glyph_index );
    }
#endif /* TT_SUPPORT_SUBPIXEL_HINTING_INFINALITY */

    if ( !loader->linear_def )
    {
      loader->linear_def = 1;
      loader->linear     = advance_width;
    }

    return FT_Err_Ok;
  }


#ifdef FT_CONFIG_OPTION_INCREMENTAL

  static void
  tt_get_metrics_incr_overrides( TT_Loader  loader,
                                 FT_UInt    glyph_index )
  {
    TT_Face  face = loader->face;

    FT_Short   left_bearing = 0, top_bearing = 0;
    FT_UShort  advance_width = 0, advance_height = 0;


    /* If this is an incrementally loaded font check whether there are */
    /* overriding metrics for this glyph.                              */
    if ( face->root.internal->incremental_interface                           &&
         face->root.internal->incremental_interface->funcs->get_glyph_metrics )
    {
      FT_Incremental_MetricsRec  incr_metrics;
      FT_Error                   error;


      incr_metrics.bearing_x = loader->left_bearing;
      incr_metrics.bearing_y = 0;
      incr_metrics.advance   = loader->advance;
      incr_metrics.advance_v = 0;

      error = face->root.internal->incremental_interface->funcs->get_glyph_metrics(
                face->root.internal->incremental_interface->object,
                glyph_index, FALSE, &incr_metrics );
      if ( error )
        goto Exit;

      left_bearing  = (FT_Short)incr_metrics.bearing_x;
      advance_width = (FT_UShort)incr_metrics.advance;

#if 0

      /* GWW: Do I do the same for vertical metrics? */
      incr_metrics.bearing_x = 0;
      incr_metrics.bearing_y = loader->top_bearing;
      incr_metrics.advance   = loader->vadvance;

      error = face->root.internal->incremental_interface->funcs->get_glyph_metrics(
                face->root.internal->incremental_interface->object,
                glyph_index, TRUE, &incr_metrics );
      if ( error )
        goto Exit;

      top_bearing    = (FT_Short)incr_metrics.bearing_y;
      advance_height = (FT_UShort)incr_metrics.advance;

#endif /* 0 */

      loader->left_bearing = left_bearing;
      loader->advance      = advance_width;
      loader->top_bearing  = top_bearing;
      loader->vadvance     = advance_height;

      if ( !loader->linear_def )
      {
        loader->linear_def = 1;
        loader->linear     = advance_width;
      }
    }

  Exit:
    return;
  }

#endif /* FT_CONFIG_OPTION_INCREMENTAL */


  /**************************************************************************
   *
   * The following functions are used by default with TrueType fonts.
   * However, they can be replaced by alternatives if we need to support
   * TrueType-compressed formats (like MicroType) in the future.
   *
   */

  FT_CALLBACK_DEF( FT_Error )
  TT_Access_Glyph_Frame( TT_Loader  loader,
                         FT_UInt    glyph_index,
                         FT_ULong   offset,
                         FT_UInt    byte_count )
  {
    FT_Error   error;
    FT_Stream  stream = loader->stream;

    FT_UNUSED( glyph_index );


    /* the following line sets the `error' variable through macros! */
    if ( FT_STREAM_SEEK( offset ) || FT_FRAME_ENTER( byte_count ) )
      return error;

    loader->cursor = stream->cursor;
    loader->limit  = stream->limit;

    return FT_Err_Ok;
  }


  FT_CALLBACK_DEF( void )
  TT_Forget_Glyph_Frame( TT_Loader  loader )
  {
    FT_Stream  stream = loader->stream;


    FT_FRAME_EXIT();
  }


  FT_CALLBACK_DEF( FT_Error )
  TT_Load_Glyph_Header( TT_Loader  loader )
  {
    FT_Byte*  p     = loader->cursor;
    FT_Byte*  limit = loader->limit;


    if ( p + 10 > limit )
      return FT_THROW( Invalid_Outline );

    loader->n_contours = FT_NEXT_SHORT( p );

    loader->bbox.xMin = FT_NEXT_SHORT( p );
    loader->bbox.yMin = FT_NEXT_SHORT( p );
    loader->bbox.xMax = FT_NEXT_SHORT( p );
    loader->bbox.yMax = FT_NEXT_SHORT( p );

    FT_TRACE5(( "  # of contours: %d\n", loader->n_contours ));
    FT_TRACE5(( "  xMin: %4d  xMax: %4d\n", loader->bbox.xMin,
                                            loader->bbox.xMax ));
    FT_TRACE5(( "  yMin: %4d  yMax: %4d\n", loader->bbox.yMin,
                                            loader->bbox.yMax ));
    loader->cursor = p;

    return FT_Err_Ok;
  }


  FT_CALLBACK_DEF( FT_Error )
  TT_Load_Simple_Glyph( TT_Loader  load )
  {
    FT_Error        error;
    FT_Byte*        p          = load->cursor;
    FT_Byte*        limit      = load->limit;
    FT_GlyphLoader  gloader    = load->gloader;
    FT_Int          n_contours = load->n_contours;
    FT_Outline*     outline;
    FT_UShort       n_ins;
    FT_Int          n_points;

    FT_Byte         *flag, *flag_limit;
    FT_Byte         c, count;
    FT_Vector       *vec, *vec_limit;
    FT_Pos          x, y;
    FT_Short        *cont, *cont_limit, prev_cont;
    FT_Int          xy_size = 0;


    /* check that we can add the contours to the glyph */
    error = FT_GLYPHLOADER_CHECK_POINTS( gloader, 0, n_contours );
    if ( error )
      goto Fail;

    /* reading the contours' endpoints & number of points */
    cont       = gloader->current.outline.contours;
    cont_limit = cont + n_contours;

    /* check space for contours array + instructions count */
    if ( n_contours >= 0xFFF || p + ( n_contours + 1 ) * 2 > limit )
      goto Invalid_Outline;

    prev_cont = FT_NEXT_SHORT( p );

    if ( n_contours > 0 )
      cont[0] = prev_cont;

    if ( prev_cont < 0 )
      goto Invalid_Outline;

    for ( cont++; cont < cont_limit; cont++ )
    {
      cont[0] = FT_NEXT_SHORT( p );
      if ( cont[0] <= prev_cont )
      {
        /* unordered contours: this is invalid */
        goto Invalid_Outline;
      }
      prev_cont = cont[0];
    }

    n_points = 0;
    if ( n_contours > 0 )
    {
      n_points = cont[-1] + 1;
      if ( n_points < 0 )
        goto Invalid_Outline;
    }

    FT_TRACE5(( "  # of points: %d\n", n_points ));

    /* note that we will add four phantom points later */
    error = FT_GLYPHLOADER_CHECK_POINTS( gloader, n_points + 4, 0 );
    if ( error )
      goto Fail;

    /* reading the bytecode instructions */
    load->glyph->control_len  = 0;
    load->glyph->control_data = NULL;

    if ( p + 2 > limit )
      goto Invalid_Outline;

    n_ins = FT_NEXT_USHORT( p );

    FT_TRACE5(( "  Instructions size: %u\n", n_ins ));

#ifdef TT_USE_BYTECODE_INTERPRETER

    if ( IS_HINTED( load->load_flags ) )
    {
      FT_ULong  tmp;


      /* check instructions size */
      if ( ( limit - p ) < n_ins )
      {
        FT_TRACE1(( "TT_Load_Simple_Glyph: instruction count mismatch\n" ));
        error = FT_THROW( Too_Many_Hints );
        goto Fail;
      }

      /* we don't trust `maxSizeOfInstructions' in the `maxp' table */
      /* and thus update the bytecode array size by ourselves       */

      tmp   = load->exec->glyphSize;
      error = Update_Max( load->exec->memory,
                          &tmp,
                          sizeof ( FT_Byte ),
                          (void*)&load->exec->glyphIns,
                          n_ins );

      load->exec->glyphSize = (FT_UShort)tmp;
      if ( error )
        return error;

      load->glyph->control_len  = n_ins;
      load->glyph->control_data = load->exec->glyphIns;

      if ( n_ins )
        FT_MEM_COPY( load->exec->glyphIns, p, (FT_Long)n_ins );
    }

#endif /* TT_USE_BYTECODE_INTERPRETER */

    p += n_ins;

    outline = &gloader->current.outline;

    /* reading the point tags */
    flag       = (FT_Byte*)outline->tags;
    flag_limit = flag + n_points;

    FT_ASSERT( flag );

    while ( flag < flag_limit )
    {
      if ( p + 1 > limit )
        goto Invalid_Outline;

      *flag++ = c = FT_NEXT_BYTE( p );
      if ( c & REPEAT_FLAG )
      {
        if ( p + 1 > limit )
          goto Invalid_Outline;

        count = FT_NEXT_BYTE( p );
        if ( flag + (FT_Int)count > flag_limit )
          goto Invalid_Outline;

        for ( ; count > 0; count-- )
          *flag++ = c;
      }
    }

    /* reading the X coordinates */

    vec       = outline->points;
    vec_limit = vec + n_points;
    flag      = (FT_Byte*)outline->tags;
    x         = 0;

    if ( p + xy_size > limit )
      goto Invalid_Outline;

    for ( ; vec < vec_limit; vec++, flag++ )
    {
      FT_Pos   delta = 0;
      FT_Byte  f     = *flag;


      if ( f & X_SHORT_VECTOR )
      {
        if ( p + 1 > limit )
          goto Invalid_Outline;

        delta = (FT_Pos)FT_NEXT_BYTE( p );
        if ( !( f & X_POSITIVE ) )
          delta = -delta;
      }
      else if ( !( f & SAME_X ) )
      {
        if ( p + 2 > limit )
          goto Invalid_Outline;

        delta = (FT_Pos)FT_NEXT_SHORT( p );
      }

      x     += delta;
      vec->x = x;
    }

    /* reading the Y coordinates */

    vec       = gloader->current.outline.points;
    vec_limit = vec + n_points;
    flag      = (FT_Byte*)outline->tags;
    y         = 0;

    for ( ; vec < vec_limit; vec++, flag++ )
    {
      FT_Pos   delta = 0;
      FT_Byte  f     = *flag;


      if ( f & Y_SHORT_VECTOR )
      {
        if ( p + 1 > limit )
          goto Invalid_Outline;

        delta = (FT_Pos)FT_NEXT_BYTE( p );
        if ( !( f & Y_POSITIVE ) )
          delta = -delta;
      }
      else if ( !( f & SAME_Y ) )
      {
        if ( p + 2 > limit )
          goto Invalid_Outline;

        delta = (FT_Pos)FT_NEXT_SHORT( p );
      }

      y     += delta;
      vec->y = y;

      /* the cast is for stupid compilers */
      *flag  = (FT_Byte)( f & ON_CURVE_POINT );
    }

    outline->n_points   = (FT_Short)n_points;
    outline->n_contours = (FT_Short)n_contours;

    load->cursor = p;

  Fail:
    return error;

  Invalid_Outline:
    error = FT_THROW( Invalid_Outline );
    goto Fail;
  }


  FT_CALLBACK_DEF( FT_Error )
  TT_Load_Composite_Glyph( TT_Loader  loader )
  {
    FT_Error        error;
    FT_Byte*        p          = loader->cursor;
    FT_Byte*        limit      = loader->limit;
    FT_GlyphLoader  gloader    = loader->gloader;
    FT_Long         num_glyphs = loader->face->root.num_glyphs;
    FT_SubGlyph     subglyph;
    FT_UInt         num_subglyphs;


    num_subglyphs = 0;

    do
    {
      FT_Fixed  xx, xy, yy, yx;
      FT_UInt   count;


      /* check that we can load a new subglyph */
      error = FT_GlyphLoader_CheckSubGlyphs( gloader, num_subglyphs + 1 );
      if ( error )
        goto Fail;

      /* check space */
      if ( p + 4 > limit )
        goto Invalid_Composite;

      subglyph = gloader->current.subglyphs + num_subglyphs;

      subglyph->arg1 = subglyph->arg2 = 0;

      subglyph->flags = FT_NEXT_USHORT( p );
      subglyph->index = FT_NEXT_USHORT( p );

      /* we reject composites that have components */
      /* with invalid glyph indices                */
      if ( subglyph->index >= num_glyphs )
        goto Invalid_Composite;

      /* check space */
      count = 2;
      if ( subglyph->flags & ARGS_ARE_WORDS )
        count += 2;
      if ( subglyph->flags & WE_HAVE_A_SCALE )
        count += 2;
      else if ( subglyph->flags & WE_HAVE_AN_XY_SCALE )
        count += 4;
      else if ( subglyph->flags & WE_HAVE_A_2X2 )
        count += 8;

      if ( p + count > limit )
        goto Invalid_Composite;

      /* read arguments */
      if ( subglyph->flags & ARGS_ARE_XY_VALUES )
      {
        if ( subglyph->flags & ARGS_ARE_WORDS )
        {
          subglyph->arg1 = FT_NEXT_SHORT( p );
          subglyph->arg2 = FT_NEXT_SHORT( p );
        }
        else
        {
          subglyph->arg1 = FT_NEXT_CHAR( p );
          subglyph->arg2 = FT_NEXT_CHAR( p );
        }
      }
      else
      {
        if ( subglyph->flags & ARGS_ARE_WORDS )
        {
          subglyph->arg1 = (FT_Int)FT_NEXT_USHORT( p );
          subglyph->arg2 = (FT_Int)FT_NEXT_USHORT( p );
        }
        else
        {
          subglyph->arg1 = (FT_Int)FT_NEXT_BYTE( p );
          subglyph->arg2 = (FT_Int)FT_NEXT_BYTE( p );
        }
      }

      /* read transform */
      xx = yy = 0x10000L;
      xy = yx = 0;

      if ( subglyph->flags & WE_HAVE_A_SCALE )
      {
        xx = (FT_Fixed)FT_NEXT_SHORT( p ) * 4;
        yy = xx;
      }
      else if ( subglyph->flags & WE_HAVE_AN_XY_SCALE )
      {
        xx = (FT_Fixed)FT_NEXT_SHORT( p ) * 4;
        yy = (FT_Fixed)FT_NEXT_SHORT( p ) * 4;
      }
      else if ( subglyph->flags & WE_HAVE_A_2X2 )
      {
        xx = (FT_Fixed)FT_NEXT_SHORT( p ) * 4;
        yx = (FT_Fixed)FT_NEXT_SHORT( p ) * 4;
        xy = (FT_Fixed)FT_NEXT_SHORT( p ) * 4;
        yy = (FT_Fixed)FT_NEXT_SHORT( p ) * 4;
      }

      subglyph->transform.xx = xx;
      subglyph->transform.xy = xy;
      subglyph->transform.yx = yx;
      subglyph->transform.yy = yy;

      num_subglyphs++;

    } while ( subglyph->flags & MORE_COMPONENTS );

    gloader->current.num_subglyphs = num_subglyphs;
    FT_TRACE5(( "  %d component%s\n",
                num_subglyphs,
                num_subglyphs > 1 ? "s" : "" ));

#ifdef FT_DEBUG_LEVEL_TRACE
    {
      FT_UInt  i;


      subglyph = gloader->current.subglyphs;

      for ( i = 0; i < num_subglyphs; i++ )
      {
        if ( num_subglyphs > 1 )
          FT_TRACE7(( "    subglyph %d:\n", i ));

        FT_TRACE7(( "      glyph index: %d\n", subglyph->index ));

        if ( subglyph->flags & ARGS_ARE_XY_VALUES )
          FT_TRACE7(( "      offset: x=%d, y=%d\n",
                      subglyph->arg1,
                      subglyph->arg2 ));
        else
          FT_TRACE7(( "      matching points: base=%d, component=%d\n",
                      subglyph->arg1,
                      subglyph->arg2 ));

        if ( subglyph->flags & WE_HAVE_A_SCALE )
          FT_TRACE7(( "      scaling: %f\n",
                      subglyph->transform.xx / 65536.0 ));
        else if ( subglyph->flags & WE_HAVE_AN_XY_SCALE )
          FT_TRACE7(( "      scaling: x=%f, y=%f\n",
                      subglyph->transform.xx / 65536.0,
                      subglyph->transform.yy / 65536.0 ));
        else if ( subglyph->flags & WE_HAVE_A_2X2 )
          FT_TRACE7(( "      scaling: xx=%f, yx=%f\n"
                      "               xy=%f, yy=%f\n",
                      subglyph->transform.xx / 65536.0,
                      subglyph->transform.yx / 65536.0,
                      subglyph->transform.xy / 65536.0,
                      subglyph->transform.yy / 65536.0 ));

        subglyph++;
      }
    }
#endif /* FT_DEBUG_LEVEL_TRACE */

#ifdef TT_USE_BYTECODE_INTERPRETER

    {
      FT_Stream  stream = loader->stream;


      /* we must undo the FT_FRAME_ENTER in order to point */
      /* to the composite instructions, if we find some.   */
      /* We will process them later.                       */
      /*                                                   */
      loader->ins_pos = (FT_ULong)( FT_STREAM_POS() +
                                    p - limit );
    }

#endif

    loader->cursor = p;

  Fail:
    return error;

  Invalid_Composite:
    error = FT_THROW( Invalid_Composite );
    goto Fail;
  }


  FT_LOCAL_DEF( void )
  TT_Init_Glyph_Loading( TT_Face  face )
  {
    face->access_glyph_frame   = TT_Access_Glyph_Frame;
    face->read_glyph_header    = TT_Load_Glyph_Header;
    face->read_simple_glyph    = TT_Load_Simple_Glyph;
    face->read_composite_glyph = TT_Load_Composite_Glyph;
    face->forget_glyph_frame   = TT_Forget_Glyph_Frame;
  }


  static void
  tt_prepare_zone( TT_GlyphZone  zone,
                   FT_GlyphLoad  load,
                   FT_UInt       start_point,
                   FT_UInt       start_contour )
  {
    zone->n_points    = (FT_UShort)load->outline.n_points -
                          (FT_UShort)start_point;
    zone->n_contours  = load->outline.n_contours -
                          (FT_Short)start_contour;
    zone->org         = load->extra_points + start_point;
    zone->cur         = load->outline.points + start_point;
    zone->orus        = load->extra_points2 + start_point;
    zone->tags        = (FT_Byte*)load->outline.tags + start_point;
    zone->contours    = (FT_UShort*)load->outline.contours + start_contour;
    zone->first_point = (FT_UShort)start_point;
  }


  /**************************************************************************
   *
   * @Function:
   *   TT_Hint_Glyph
   *
   * @Description:
   *   Hint the glyph using the zone prepared by the caller.  Note that
   *   the zone is supposed to include four phantom points.
   */
  static FT_Error
  TT_Hint_Glyph( TT_Loader  loader,
                 FT_Bool    is_composite )
  {
#if defined TT_SUPPORT_SUBPIXEL_HINTING_INFINALITY || \
    defined TT_SUPPORT_SUBPIXEL_HINTING_MINIMAL
    TT_Face    face   = loader->face;
    TT_Driver  driver = (TT_Driver)FT_FACE_DRIVER( face );
#endif

    TT_GlyphZone  zone = &loader->zone;

#ifdef TT_USE_BYTECODE_INTERPRETER
    FT_Long       n_ins;
#else
    FT_UNUSED( is_composite );
#endif


#ifdef TT_USE_BYTECODE_INTERPRETER
    n_ins = loader->glyph->control_len;

    /* save original point positions in `org' array */
    if ( n_ins > 0 )
      FT_ARRAY_COPY( zone->org, zone->cur, zone->n_points );

    /* Reset graphics state. */
    loader->exec->GS = loader->size->GS;

    /* XXX: UNDOCUMENTED! Hinting instructions of a composite glyph */
    /*      completely refer to the (already) hinted subglyphs.     */
    if ( is_composite )
    {
      loader->exec->metrics.x_scale = 1 << 16;
      loader->exec->metrics.y_scale = 1 << 16;

      FT_ARRAY_COPY( zone->orus, zone->cur, zone->n_points );
    }
    else
    {
      loader->exec->metrics.x_scale = loader->size->metrics->x_scale;
      loader->exec->metrics.y_scale = loader->size->metrics->y_scale;
    }
#endif

    /* round phantom points */
    zone->cur[zone->n_points - 4].x =
      FT_PIX_ROUND( zone->cur[zone->n_points - 4].x );
    zone->cur[zone->n_points - 3].x =
      FT_PIX_ROUND( zone->cur[zone->n_points - 3].x );
    zone->cur[zone->n_points - 2].y =
      FT_PIX_ROUND( zone->cur[zone->n_points - 2].y );
    zone->cur[zone->n_points - 1].y =
      FT_PIX_ROUND( zone->cur[zone->n_points - 1].y );

#ifdef TT_USE_BYTECODE_INTERPRETER

    if ( n_ins > 0 )
    {
      FT_Error  error;

      FT_GlyphLoader  gloader         = loader->gloader;
      FT_Outline      current_outline = gloader->current.outline;


      TT_Set_CodeRange( loader->exec, tt_coderange_glyph,
                        loader->exec->glyphIns, n_ins );

      loader->exec->is_composite = is_composite;
      loader->exec->pts          = *zone;

      error = TT_Run_Context( loader->exec );
      if ( error && loader->exec->pedantic_hinting )
        return error;

      /* store drop-out mode in bits 5-7; set bit 2 also as a marker */
      current_outline.tags[0] |=
        ( loader->exec->GS.scan_type << 5 ) | FT_CURVE_TAG_HAS_SCANMODE;
    }

#endif

#ifdef TT_SUPPORT_SUBPIXEL_HINTING_MINIMAL
    /* Save possibly modified glyph phantom points unless in v40 backward  */
    /* compatibility mode, where no movement on the x axis means no reason */
    /* to change bearings or advance widths.                               */
    if ( !( driver->interpreter_version == TT_INTERPRETER_VERSION_40 &&
            loader->exec->backward_compatibility ) )
    {
#endif
      loader->pp1 = zone->cur[zone->n_points - 4];
      loader->pp2 = zone->cur[zone->n_points - 3];
      loader->pp3 = zone->cur[zone->n_points - 2];
      loader->pp4 = zone->cur[zone->n_points - 1];
#ifdef TT_SUPPORT_SUBPIXEL_HINTING_MINIMAL
    }
#endif

#ifdef TT_SUPPORT_SUBPIXEL_HINTING_INFINALITY
    if ( driver->interpreter_version == TT_INTERPRETER_VERSION_38 )
    {
      if ( loader->exec->sph_tweak_flags & SPH_TWEAK_DEEMBOLDEN )
        FT_Outline_EmboldenXY( &loader->gloader->current.outline, -24, 0 );

      else if ( loader->exec->sph_tweak_flags & SPH_TWEAK_EMBOLDEN )
        FT_Outline_EmboldenXY( &loader->gloader->current.outline, 24, 0 );
    }
#endif /* TT_SUPPORT_SUBPIXEL_HINTING_INFINALITY */

    return FT_Err_Ok;
  }


  /**************************************************************************
   *
   * @Function:
   *   TT_Process_Simple_Glyph
   *
   * @Description:
   *   Once a simple glyph has been loaded, it needs to be processed.
   *   Usually, this means scaling and hinting through bytecode
   *   interpretation.
   */
  static FT_Error
  TT_Process_Simple_Glyph( TT_Loader  loader )
  {
    FT_GlyphLoader  gloader = loader->gloader;
    FT_Error        error   = FT_Err_Ok;
    FT_Outline*     outline;
    FT_Vector*      unrounded;
    FT_Int          n_points;


    outline  = &gloader->current.outline;
    n_points = outline->n_points;

    /* set phantom points */

    outline->points[n_points    ] = loader->pp1;
    outline->points[n_points + 1] = loader->pp2;
    outline->points[n_points + 2] = loader->pp3;
    outline->points[n_points + 3] = loader->pp4;

    outline->tags[n_points    ] = 0;
    outline->tags[n_points + 1] = 0;
    outline->tags[n_points + 2] = 0;
    outline->tags[n_points + 3] = 0;

    n_points += 4;

#ifdef TT_CONFIG_OPTION_GX_VAR_SUPPORT

    if ( FT_IS_NAMED_INSTANCE( FT_FACE( loader->face ) ) ||
         FT_IS_VARIATION( FT_FACE( loader->face ) )      )
    {
      /* Deltas apply to the unscaled data.                           */
      /* We temporarily use `extra_points2' to hold unrounded values. */
      unrounded = gloader->current.extra_points2;
      error = TT_Vary_Apply_Glyph_Deltas( loader->face,
                                          loader->glyph_index,
                                          outline,
                                          unrounded,
                                          (FT_UInt)n_points );

      /* recalculate linear horizontal and vertical advances */
      /* if we don't have HVAR and VVAR, respectively        */

      /* XXX: change all FreeType modules to store `linear' and `vadvance' */
      /*      in 26.6 format before the `base' module scales them to 16.16 */
      if ( !( loader->face->variation_support & TT_FACE_FLAG_VAR_HADVANCE ) )
        loader->linear = FT_PIX_ROUND( unrounded[n_points - 3].x -
                                       unrounded[n_points - 4].x ) / 64;
      if ( !( loader->face->variation_support & TT_FACE_FLAG_VAR_VADVANCE ) )
        loader->vadvance = FT_PIX_ROUND( unrounded[n_points - 1].x -
                                         unrounded[n_points - 2].x ) / 64;

      if ( error )
        return error;
    }

#endif /* TT_CONFIG_OPTION_GX_VAR_SUPPORT */

    {
#ifdef TT_SUPPORT_SUBPIXEL_HINTING_INFINALITY
      TT_Face    face   = loader->face;
      TT_Driver  driver = (TT_Driver)FT_FACE_DRIVER( face );

      FT_String*  family         = face->root.family_name;
      FT_UInt     ppem           = loader->size->metrics->x_ppem;
      FT_String*  style          = face->root.style_name;
      FT_UInt     x_scale_factor = 1000;
#endif

      FT_Vector*  vec   = outline->points;
      FT_Vector*  limit = outline->points + n_points;

      FT_Fixed  x_scale = 0; /* pacify compiler */
      FT_Fixed  y_scale = 0;

      FT_Bool  do_scale = FALSE;


#ifdef TT_SUPPORT_SUBPIXEL_HINTING_INFINALITY

      if ( driver->interpreter_version == TT_INTERPRETER_VERSION_38 )
      {
        /* scale, but only if enabled and only if TT hinting is being used */
        if ( IS_HINTED( loader->load_flags ) )
          x_scale_factor = sph_test_tweak_x_scaling( face,
                                                     family,
                                                     ppem,
                                                     style,
                                                     loader->glyph_index );
        /* scale the glyph */
        if ( ( loader->load_flags & FT_LOAD_NO_SCALE ) == 0 ||
             x_scale_factor != 1000                         )
        {
          x_scale = FT_MulDiv( loader->size->metrics->x_scale,
                               (FT_Long)x_scale_factor, 1000 );
          y_scale = loader->size->metrics->y_scale;

          /* compensate for any scaling by de/emboldening; */
          /* the amount was determined via experimentation */
          if ( x_scale_factor != 1000 && ppem > 11 )
          {
            FT_Vector*  orig_points = outline->points;


            outline->points = unrounded;
            FT_Outline_EmboldenXY( outline,
                                   FT_MulFix( 1280 * ppem,
                                              1000 - x_scale_factor ),
                                   0 );
            outline->points = orig_points;
          }
          do_scale = TRUE;
        }
      }
      else

#endif /* TT_SUPPORT_SUBPIXEL_HINTING_INFINALITY */

      {
        /* scale the glyph */
        if ( ( loader->load_flags & FT_LOAD_NO_SCALE ) == 0 )
        {
          x_scale = loader->size->metrics->x_scale;
          y_scale = loader->size->metrics->y_scale;

          do_scale = TRUE;
        }
      }

      if ( do_scale )
      {
        for ( ; vec < limit; vec++, unrounded++ )
        {
          vec->x = FT_MulDiv( unrounded->x, x_scale, 0x10000L * 64 );
          vec->y = FT_MulDiv( unrounded->y, y_scale, 0x10000L * 64 );
        }
      }

#ifdef TT_CONFIG_OPTION_GX_VAR_SUPPORT
      /* if we have a HVAR table, `pp1' and/or `pp2' are already adjusted */
      if ( !( loader->face->variation_support & TT_FACE_FLAG_VAR_HADVANCE ) ||
           !IS_HINTED( loader->load_flags )                                 )
#endif
      {
        loader->pp1 = outline->points[n_points - 4];
        loader->pp2 = outline->points[n_points - 3];
      }

#ifdef TT_CONFIG_OPTION_GX_VAR_SUPPORT
      /* if we have a VVAR table, `pp3' and/or `pp4' are already adjusted */
      if ( !( loader->face->variation_support & TT_FACE_FLAG_VAR_VADVANCE ) ||
           !IS_HINTED( loader->load_flags )                                 )
#endif
      {
        loader->pp3 = outline->points[n_points - 2];
        loader->pp4 = outline->points[n_points - 1];
      }
    }

    if ( IS_HINTED( loader->load_flags ) )
    {
      tt_prepare_zone( &loader->zone, &gloader->current, 0, 0 );

      FT_ARRAY_COPY( loader->zone.orus, loader->zone.cur,
                     loader->zone.n_points + 4 );

      loader->zone.n_points += 4;

      error = TT_Hint_Glyph( loader, 0 );
    }

    return error;
  }


  /**************************************************************************
   *
   * @Function:
   *   TT_Process_Composite_Component
   *
   * @Description:
   *   Once a composite component has been loaded, it needs to be
   *   processed.  Usually, this means transforming and translating.
   */
  static FT_Error
  TT_Process_Composite_Component( TT_Loader    loader,
                                  FT_SubGlyph  subglyph,
                                  FT_UInt      start_point,
                                  FT_UInt      num_base_points )
  {
    FT_GlyphLoader  gloader = loader->gloader;
    FT_Outline      current;
    FT_Bool         have_scale;
    FT_Pos          x, y;


    current.points   = gloader->base.outline.points +
                         num_base_points;
    current.n_points = gloader->base.outline.n_points -
                         (short)num_base_points;

    have_scale = FT_BOOL( subglyph->flags & ( WE_HAVE_A_SCALE     |
                                              WE_HAVE_AN_XY_SCALE |
                                              WE_HAVE_A_2X2       ) );

    /* perform the transform required for this subglyph */
    if ( have_scale )
      FT_Outline_Transform( &current, &subglyph->transform );

    /* get offset */
    if ( !( subglyph->flags & ARGS_ARE_XY_VALUES ) )
    {
      FT_UInt     num_points = (FT_UInt)gloader->base.outline.n_points;
      FT_UInt     k = (FT_UInt)subglyph->arg1;
      FT_UInt     l = (FT_UInt)subglyph->arg2;
      FT_Vector*  p1;
      FT_Vector*  p2;


      /* match l-th point of the newly loaded component to the k-th point */
      /* of the previously loaded components.                             */

      /* change to the point numbers used by our outline */
      k += start_point;
      l += num_base_points;
      if ( k >= num_base_points ||
           l >= num_points      )
        return FT_THROW( Invalid_Composite );

      p1 = gloader->base.outline.points + k;
      p2 = gloader->base.outline.points + l;

      x = p1->x - p2->x;
      y = p1->y - p2->y;
    }
    else
    {
      x = subglyph->arg1;
      y = subglyph->arg2;

      if ( !x && !y )
        return FT_Err_Ok;

      /* Use a default value dependent on                                  */
      /* TT_CONFIG_OPTION_COMPONENT_OFFSET_SCALED.  This is useful for old */
      /* TT fonts which don't set the xxx_COMPONENT_OFFSET bit.            */

      if ( have_scale &&
#ifdef TT_CONFIG_OPTION_COMPONENT_OFFSET_SCALED
           !( subglyph->flags & UNSCALED_COMPONENT_OFFSET ) )
#else
            ( subglyph->flags & SCALED_COMPONENT_OFFSET ) )
#endif
      {

#if 0

        /********************************************************************
         *
         * This algorithm is what Apple documents.  But it doesn't work.
         */
        int  a = subglyph->transform.xx > 0 ?  subglyph->transform.xx
                                            : -subglyph->transform.xx;
        int  b = subglyph->transform.yx > 0 ?  subglyph->transform.yx
                                            : -subglyph->transform.yx;
        int  c = subglyph->transform.xy > 0 ?  subglyph->transform.xy
                                            : -subglyph->transform.xy;
        int  d = subglyph->transform.yy > 0 ?  subglyph->transform.yy
                                            : -subglyph->transform.yy;
        int  m = a > b ? a : b;
        int  n = c > d ? c : d;


        if ( a - b <= 33 && a - b >= -33 )
          m *= 2;
        if ( c - d <= 33 && c - d >= -33 )
          n *= 2;
        x = FT_MulFix( x, m );
        y = FT_MulFix( y, n );

#else /* 1 */

        /********************************************************************
         *
         * This algorithm is a guess and works much better than the above.
         */
        FT_Fixed  mac_xscale = FT_Hypot( subglyph->transform.xx,
                                         subglyph->transform.xy );
        FT_Fixed  mac_yscale = FT_Hypot( subglyph->transform.yy,
                                         subglyph->transform.yx );


        x = FT_MulFix( x, mac_xscale );
        y = FT_MulFix( y, mac_yscale );

#endif /* 1 */

      }

      if ( !( loader->load_flags & FT_LOAD_NO_SCALE ) )
      {
        FT_Fixed  x_scale = loader->size->metrics->x_scale;
        FT_Fixed  y_scale = loader->size->metrics->y_scale;


        x = FT_MulFix( x, x_scale );
        y = FT_MulFix( y, y_scale );

        if ( subglyph->flags & ROUND_XY_TO_GRID )
        {
          TT_Face    face   = loader->face;
          TT_Driver  driver = (TT_Driver)FT_FACE_DRIVER( face );


          if ( IS_HINTED( loader->load_flags ) )
          {
            /*
             * We round the horizontal offset only if there is hinting along
             * the x axis; this corresponds to integer advance width values.
             *
             * Theoretically, a glyph's bytecode can toggle ClearType's
             * `backward compatibility' mode, which would allow modification
             * of the advance width.  In reality, however, applications
             * neither allow nor expect modified advance widths if subpixel
             * rendering is active.
             *
             */
            if ( driver->interpreter_version == TT_INTERPRETER_VERSION_35 )
              x = FT_PIX_ROUND( x );

            y = FT_PIX_ROUND( y );
          }
        }
      }
    }

    if ( x || y )
      FT_Outline_Translate( &current, x, y );

    return FT_Err_Ok;
  }


  /**************************************************************************
   *
   * @Function:
   *   TT_Process_Composite_Glyph
   *
   * @Description:
   *   This is slightly different from TT_Process_Simple_Glyph, in that
   *   its sole purpose is to hint the glyph.  Thus this function is
   *   only available when bytecode interpreter is enabled.
   */
  static FT_Error
  TT_Process_Composite_Glyph( TT_Loader  loader,
                              FT_UInt    start_point,
                              FT_UInt    start_contour )
  {
    FT_Error     error;
    FT_Outline*  outline;
    FT_UInt      i;


    outline = &loader->gloader->base.outline;

    /* make room for phantom points */
    error = FT_GLYPHLOADER_CHECK_POINTS( loader->gloader,
                                         outline->n_points + 4,
                                         0 );
    if ( error )
      return error;

    outline->points[outline->n_points    ] = loader->pp1;
    outline->points[outline->n_points + 1] = loader->pp2;
    outline->points[outline->n_points + 2] = loader->pp3;
    outline->points[outline->n_points + 3] = loader->pp4;

    outline->tags[outline->n_points    ] = 0;
    outline->tags[outline->n_points + 1] = 0;
    outline->tags[outline->n_points + 2] = 0;
    outline->tags[outline->n_points + 3] = 0;

#ifdef TT_USE_BYTECODE_INTERPRETER

    {
      FT_Stream  stream = loader->stream;
      FT_UShort  n_ins, max_ins;
      FT_ULong   tmp;


      /* TT_Load_Composite_Glyph only gives us the offset of instructions */
      /* so we read them here                                             */
      if ( FT_STREAM_SEEK( loader->ins_pos ) ||
           FT_READ_USHORT( n_ins )           )
        return error;

      FT_TRACE5(( "  Instructions size = %d\n", n_ins ));

      /* check it */
      max_ins = loader->face->max_profile.maxSizeOfInstructions;
      if ( n_ins > max_ins )
      {
        /* don't trust `maxSizeOfInstructions'; */
        /* only do a rough safety check         */
        if ( (FT_Int)n_ins > loader->byte_len )
        {
          FT_TRACE1(( "TT_Process_Composite_Glyph:"
                      " too many instructions (%d) for glyph with length %d\n",
                      n_ins, loader->byte_len ));
          return FT_THROW( Too_Many_Hints );
        }

        tmp   = loader->exec->glyphSize;
        error = Update_Max( loader->exec->memory,
                            &tmp,
                            sizeof ( FT_Byte ),
                            (void*)&loader->exec->glyphIns,
                            n_ins );

        loader->exec->glyphSize = (FT_UShort)tmp;
        if ( error )
          return error;
      }
      else if ( n_ins == 0 )
        return FT_Err_Ok;

      if ( FT_STREAM_READ( loader->exec->glyphIns, n_ins ) )
        return error;

      loader->glyph->control_data = loader->exec->glyphIns;
      loader->glyph->control_len  = n_ins;
    }

#endif

    tt_prepare_zone( &loader->zone, &loader->gloader->base,
                     start_point, start_contour );

    /* Some points are likely touched during execution of  */
    /* instructions on components.  So let's untouch them. */
    for ( i = 0; i < loader->zone.n_points; i++ )
      loader->zone.tags[i] &= ~FT_CURVE_TAG_TOUCH_BOTH;

    loader->zone.n_points += 4;

    return TT_Hint_Glyph( loader, 1 );
  }


  /*
   * Calculate the phantom points
   *
   * Defining the right side bearing (rsb) as
   *
   *   rsb = aw - (lsb + xmax - xmin)
   *
   * (with `aw' the advance width, `lsb' the left side bearing, and `xmin'
   * and `xmax' the glyph's minimum and maximum x value), the OpenType
   * specification defines the initial position of horizontal phantom points
   * as
   *
   *   pp1 = (round(xmin - lsb), 0)      ,
   *   pp2 = (round(pp1 + aw), 0)        .
   *
   * Note that the rounding to the grid (in the device space) is not
   * documented currently in the specification.
   *
   * However, the specification lacks the precise definition of vertical
   * phantom points.  Greg Hitchcock provided the following explanation.
   *
   * - a `vmtx' table is present
   *
   *   For any glyph, the minimum and maximum y values (`ymin' and `ymax')
   *   are given in the `glyf' table, the top side bearing (tsb) and advance
   *   height (ah) are given in the `vmtx' table.  The bottom side bearing
   *   (bsb) is then calculated as
   *
   *     bsb = ah - (tsb + ymax - ymin)       ,
   *
   *   and the initial position of vertical phantom points is
   *
   *     pp3 = (x, round(ymax + tsb))       ,
   *     pp4 = (x, round(pp3 - ah))         .
   *
   *   See below for value `x'.
   *
   * - no `vmtx' table in the font
   *
   *   If there is an `OS/2' table, we set
   *
   *     DefaultAscender = sTypoAscender       ,
   *     DefaultDescender = sTypoDescender     ,
   *
   *   otherwise we use data from the `hhea' table:
   *
   *     DefaultAscender = Ascender         ,
   *     DefaultDescender = Descender       .
   *
   *   With these two variables we can now set
   *
   *     ah = DefaultAscender - sDefaultDescender    ,
   *     tsb = DefaultAscender - yMax                ,
   *
   *   and proceed as if a `vmtx' table was present.
   *
   * Usually we have
   *
   *   x = aw / 2      ,                                                (1)
   *
   * but there is one compatibility case where it can be set to
   *
   *   x = -DefaultDescender -
   *         ((DefaultAscender - DefaultDescender - aw) / 2)     .      (2)
   *
   * and another one with
   *
   *   x = 0     .                                                      (3)
   *
   * In Windows, the history of those values is quite complicated,
   * depending on the hinting engine (that is, the graphics framework).
   *
   *   framework        from                 to       formula
   *  ----------------------------------------------------------
   *    GDI       Windows 98               current      (1)
   *              (Windows 2000 for NT)
   *    GDI+      Windows XP               Windows 7    (2)
   *    GDI+      Windows 8                current      (3)
   *    DWrite    Windows 7                current      (3)
   *
   * For simplicity, FreeType uses (1) for grayscale subpixel hinting and
   * (3) for everything else.
   *
   */
  static void
  tt_loader_set_pp( TT_Loader  loader )
  {
    FT_Bool  subpixel_hinting = 0;
    FT_Bool  grayscale        = 0;
    FT_Bool  use_aw_2         = 0;

#ifdef TT_CONFIG_OPTION_SUBPIXEL_HINTING
    TT_Driver driver = (TT_Driver)FT_FACE_DRIVER( loader->face );
#endif


#ifdef TT_SUPPORT_SUBPIXEL_HINTING_INFINALITY
    if ( driver->interpreter_version == TT_INTERPRETER_VERSION_38 )
    {
      subpixel_hinting = loader->exec ? loader->exec->subpixel_hinting
                                      : 0;
      grayscale        = loader->exec ? loader->exec->grayscale
                                      : 0;
    }
#endif
#ifdef TT_SUPPORT_SUBPIXEL_HINTING_MINIMAL
    if ( driver->interpreter_version == TT_INTERPRETER_VERSION_40 )
    {
      subpixel_hinting = loader->exec ? loader->exec->subpixel_hinting_lean
                                      : 0;
      grayscale        = loader->exec ? loader->exec->grayscale_cleartype
                                      : 0;
    }
#endif

    use_aw_2 = FT_BOOL( subpixel_hinting && grayscale );

    loader->pp1.x = loader->bbox.xMin - loader->left_bearing;
    loader->pp1.y = 0;
    loader->pp2.x = loader->pp1.x + loader->advance;
    loader->pp2.y = 0;

    loader->pp3.x = use_aw_2 ? loader->advance / 2 : 0;
    loader->pp3.y = loader->bbox.yMax + loader->top_bearing;
    loader->pp4.x = use_aw_2 ? loader->advance / 2 : 0;
    loader->pp4.y = loader->pp3.y - loader->vadvance;
  }


  /* a utility function to retrieve i-th node from given FT_List */
  static FT_ListNode
  ft_list_get_node_at( FT_List  list,
                       FT_UInt  idx )
  {
    FT_ListNode  cur;


    if ( !list )
      return NULL;

    for ( cur = list->head; cur; cur = cur->next )
    {
      if ( !idx )
        return cur;

      idx--;
    }

    return NULL;
  }


  /**************************************************************************
   *
   * @Function:
   *   load_truetype_glyph
   *
   * @Description:
   *   Loads a given truetype glyph.  Handles composites and uses a
   *   TT_Loader object.
   */
  static FT_Error
  load_truetype_glyph( TT_Loader  loader,
                       FT_UInt    glyph_index,
                       FT_UInt    recurse_count,
                       FT_Bool    header_only )
  {
    FT_Error        error   = FT_Err_Ok;
    FT_Fixed        x_scale, y_scale;
    FT_ULong        offset;
    TT_Face         face    = loader->face;
    FT_GlyphLoader  gloader = loader->gloader;

    FT_Bool  opened_frame = 0;

#ifdef FT_CONFIG_OPTION_INCREMENTAL
    FT_StreamRec    inc_stream;
    FT_Data         glyph_data;
    FT_Bool         glyph_data_loaded = 0;
#endif


#ifdef FT_DEBUG_LEVEL_TRACE
    if ( recurse_count )
      FT_TRACE5(( "  nesting level: %d\n", recurse_count ));
#endif

    /* some fonts have an incorrect value of `maxComponentDepth' */
    if ( recurse_count > face->max_profile.maxComponentDepth )
    {
      FT_TRACE1(( "load_truetype_glyph: maxComponentDepth set to %d\n",
                  recurse_count ));
      face->max_profile.maxComponentDepth = (FT_UShort)recurse_count;
    }

#ifndef FT_CONFIG_OPTION_INCREMENTAL
    /* check glyph index */
    if ( glyph_index >= (FT_UInt)face->root.num_glyphs )
    {
      error = FT_THROW( Invalid_Glyph_Index );
      goto Exit;
    }
#endif

    loader->glyph_index = glyph_index;

    if ( loader->load_flags & FT_LOAD_NO_SCALE )
    {
      x_scale = 0x10000L;
      y_scale = 0x10000L;
    }
    else
    {
      x_scale = loader->size->metrics->x_scale;
      y_scale = loader->size->metrics->y_scale;
    }

    /* Set `offset' to the start of the glyph relative to the start of */
    /* the `glyf' table, and `byte_len' to the length of the glyph in  */
    /* bytes.                                                          */

#ifdef FT_CONFIG_OPTION_INCREMENTAL

    /* If we are loading glyph data via the incremental interface, set */
    /* the loader stream to a memory stream reading the data returned  */
    /* by the interface.                                               */
    if ( face->root.internal->incremental_interface )
    {
      error = face->root.internal->incremental_interface->funcs->get_glyph_data(
                face->root.internal->incremental_interface->object,
                glyph_index, &glyph_data );
      if ( error )
        goto Exit;

      glyph_data_loaded = 1;
      offset            = 0;
      loader->byte_len  = glyph_data.length;

      FT_ZERO( &inc_stream );
      FT_Stream_OpenMemory( &inc_stream,
                            glyph_data.pointer,
                            (FT_ULong)glyph_data.length );

      loader->stream = &inc_stream;
    }
    else

#endif /* FT_CONFIG_OPTION_INCREMENTAL */

      offset = tt_face_get_location( face, glyph_index,
                                     (FT_UInt*)&loader->byte_len );

    if ( loader->byte_len > 0 )
    {
#ifdef FT_CONFIG_OPTION_INCREMENTAL
      /* for the incremental interface, `glyf_offset' is always zero */
      if ( !face->glyf_offset                          &&
           !face->root.internal->incremental_interface )
#else
      if ( !face->glyf_offset )
#endif /* FT_CONFIG_OPTION_INCREMENTAL */
      {
        FT_TRACE2(( "no `glyf' table but non-zero `loca' entry\n" ));
        error = FT_THROW( Invalid_Table );
        goto Exit;
      }

      error = face->access_glyph_frame( loader, glyph_index,
                                        face->glyf_offset + offset,
                                        (FT_UInt)loader->byte_len );
      if ( error )
        goto Exit;

      /* read glyph header first */
      error = face->read_glyph_header( loader );

      face->forget_glyph_frame( loader );

      if ( error )
        goto Exit;
    }

    /* a space glyph */
    if ( loader->byte_len == 0 || loader->n_contours == 0 )
    {
      loader->bbox.xMin = 0;
      loader->bbox.xMax = 0;
      loader->bbox.yMin = 0;
      loader->bbox.yMax = 0;
    }

    /* the metrics must be computed after loading the glyph header */
    /* since we need the glyph's `yMax' value in case the vertical */
    /* metrics must be emulated                                    */
    error = tt_get_metrics( loader, glyph_index );
    if ( error )
      goto Exit;

    if ( header_only )
      goto Exit;

    if ( loader->byte_len == 0 || loader->n_contours == 0 )
    {
      /* must initialize points before (possibly) overriding */
      /* glyph metrics from the incremental interface        */
      tt_loader_set_pp( loader );

#ifdef FT_CONFIG_OPTION_INCREMENTAL
      tt_get_metrics_incr_overrides( loader, glyph_index );
#endif

#ifdef TT_CONFIG_OPTION_GX_VAR_SUPPORT

      if ( FT_IS_NAMED_INSTANCE( FT_FACE( face ) ) ||
           FT_IS_VARIATION( FT_FACE( face ) )      )
      {
        /* a small outline structure with four elements for */
        /* communication with `TT_Vary_Apply_Glyph_Deltas'  */
        FT_Vector   points[4];
        char        tags[4]     = { 1, 1, 1, 1 };
        short       contours[4] = { 0, 1, 2, 3 };
        FT_Outline  outline;

        /* unrounded values */
        FT_Vector  unrounded[4];


        points[0].x = loader->pp1.x;
        points[0].y = loader->pp1.y;
        points[1].x = loader->pp2.x;
        points[1].y = loader->pp2.y;

        points[2].x = loader->pp3.x;
        points[2].y = loader->pp3.y;
        points[3].x = loader->pp4.x;
        points[3].y = loader->pp4.y;

        outline.n_points   = 4;
        outline.n_contours = 4;
        outline.points     = points;
        outline.tags       = tags;
        outline.contours   = contours;

        /* this must be done before scaling */
        error = TT_Vary_Apply_Glyph_Deltas( loader->face,
                                            glyph_index,
                                            &outline,
                                            unrounded,
                                            (FT_UInt)outline.n_points );
        if ( error )
          goto Exit;

        loader->pp1.x = points[0].x;
        loader->pp1.y = points[0].y;
        loader->pp2.x = points[1].x;
        loader->pp2.y = points[1].y;

        loader->pp3.x = points[2].x;
        loader->pp3.y = points[2].y;
        loader->pp4.x = points[3].x;
        loader->pp4.y = points[3].y;

        /* recalculate linear horizontal and vertical advances */
        /* if we don't have HVAR and VVAR, respectively        */
        if ( !( loader->face->variation_support & TT_FACE_FLAG_VAR_HADVANCE ) )
          loader->linear = FT_PIX_ROUND( unrounded[1].x -
                                         unrounded[0].x ) / 64;
        if ( !( loader->face->variation_support & TT_FACE_FLAG_VAR_VADVANCE ) )
          loader->vadvance = FT_PIX_ROUND( unrounded[3].x -
                                           unrounded[2].x ) / 64;
      }

#endif /* TT_CONFIG_OPTION_GX_VAR_SUPPORT */

      /* scale phantom points, if necessary; */
      /* they get rounded in `TT_Hint_Glyph' */
      if ( ( loader->load_flags & FT_LOAD_NO_SCALE ) == 0 )
      {
        loader->pp1.x = FT_MulFix( loader->pp1.x, x_scale );
        loader->pp2.x = FT_MulFix( loader->pp2.x, x_scale );
        /* pp1.y and pp2.y are always zero */

        loader->pp3.x = FT_MulFix( loader->pp3.x, x_scale );
        loader->pp3.y = FT_MulFix( loader->pp3.y, y_scale );
        loader->pp4.x = FT_MulFix( loader->pp4.x, x_scale );
        loader->pp4.y = FT_MulFix( loader->pp4.y, y_scale );
      }

      error = FT_Err_Ok;
      goto Exit;
    }

    /* must initialize phantom points before (possibly) overriding */
    /* glyph metrics from the incremental interface                */
    tt_loader_set_pp( loader );

#ifdef FT_CONFIG_OPTION_INCREMENTAL
    tt_get_metrics_incr_overrides( loader, glyph_index );
#endif

    /***********************************************************************/
    /***********************************************************************/
    /***********************************************************************/

    /* we now open a frame again, right after the glyph header */
    /* (which consists of 10 bytes)                            */
    error = face->access_glyph_frame( loader, glyph_index,
                                      face->glyf_offset + offset + 10,
                                      (FT_UInt)loader->byte_len - 10 );
    if ( error )
      goto Exit;

    opened_frame = 1;

    /* if it is a simple glyph, load it */

    if ( loader->n_contours > 0 )
    {
      error = face->read_simple_glyph( loader );
      if ( error )
        goto Exit;

      /* all data have been read */
      face->forget_glyph_frame( loader );
      opened_frame = 0;

      error = TT_Process_Simple_Glyph( loader );
      if ( error )
        goto Exit;

      FT_GlyphLoader_Add( gloader );
    }

    /***********************************************************************/
    /***********************************************************************/
    /***********************************************************************/

    /* otherwise, load a composite! */
    else if ( loader->n_contours < 0 )
    {
      FT_Memory  memory = face->root.memory;

      FT_UInt   start_point;
      FT_UInt   start_contour;
      FT_ULong  ins_pos;  /* position of composite instructions, if any */

      FT_ListNode  node, node2;


      /* normalize the `n_contours' value */
      loader->n_contours = -1;

      /*
       * We store the glyph index directly in the `node->data' pointer,
       * following the glib solution (cf. macro `GUINT_TO_POINTER') with a
       * double cast to make this portable.  Note, however, that this needs
       * pointers with a width of at least 32 bits.
       */

      /* clear the nodes filled by sibling chains */
      node = ft_list_get_node_at( &loader->composites, recurse_count );
      for ( node2 = node; node2; node2 = node2->next )
        node2->data = (void*)FT_ULONG_MAX;

      /* check whether we already have a composite glyph with this index */
      if ( FT_List_Find( &loader->composites,
                         FT_UINT_TO_POINTER( glyph_index ) ) )
      {
        FT_TRACE1(( "TT_Load_Composite_Glyph:"
                    " infinite recursion detected\n" ));
        error = FT_THROW( Invalid_Composite );
        goto Exit;
      }

      else if ( node )
        node->data = FT_UINT_TO_POINTER( glyph_index );

      else
      {
        if ( FT_NEW( node ) )
          goto Exit;
        node->data = FT_UINT_TO_POINTER( glyph_index );
        FT_List_Add( &loader->composites, node );
      }

      start_point   = (FT_UInt)gloader->base.outline.n_points;
      start_contour = (FT_UInt)gloader->base.outline.n_contours;

      /* for each subglyph, read composite header */
      error = face->read_composite_glyph( loader );
      if ( error )
        goto Exit;

      /* store the offset of instructions */
      ins_pos = loader->ins_pos;

      /* all data we need are read */
      face->forget_glyph_frame( loader );
      opened_frame = 0;

#ifdef TT_CONFIG_OPTION_GX_VAR_SUPPORT

      if ( FT_IS_NAMED_INSTANCE( FT_FACE( face ) ) ||
           FT_IS_VARIATION( FT_FACE( face ) )      )
      {
        short        i, limit;
        FT_SubGlyph  subglyph;

        FT_Outline  outline;
        FT_Vector*  points    = NULL;
        char*       tags      = NULL;
        short*      contours  = NULL;
        FT_Vector*  unrounded = NULL;


        limit = (short)gloader->current.num_subglyphs;

        /* construct an outline structure for              */
        /* communication with `TT_Vary_Apply_Glyph_Deltas' */
        outline.n_points   = (short)( gloader->current.num_subglyphs + 4 );
        outline.n_contours = outline.n_points;

        outline.points   = NULL;
        outline.tags     = NULL;
        outline.contours = NULL;

        if ( FT_NEW_ARRAY( points, outline.n_points )    ||
             FT_NEW_ARRAY( tags, outline.n_points )      ||
             FT_NEW_ARRAY( contours, outline.n_points )  ||
             FT_NEW_ARRAY( unrounded, outline.n_points ) )
          goto Exit1;

        subglyph = gloader->current.subglyphs;

        for ( i = 0; i < limit; i++, subglyph++ )
        {
          /* applying deltas for anchor points doesn't make sense, */
          /* but we don't have to specially check this since       */
          /* unused delta values are zero anyways                  */
          points[i].x = subglyph->arg1;
          points[i].y = subglyph->arg2;
          tags[i]     = 1;
          contours[i] = i;
        }

        points[i].x = loader->pp1.x;
        points[i].y = loader->pp1.y;
        tags[i]     = 1;
        contours[i] = i;

        i++;
        points[i].x = loader->pp2.x;
        points[i].y = loader->pp2.y;
        tags[i]     = 1;
        contours[i] = i;

        i++;
        points[i].x = loader->pp3.x;
        points[i].y = loader->pp3.y;
        tags[i]     = 1;
        contours[i] = i;

        i++;
        points[i].x = loader->pp4.x;
        points[i].y = loader->pp4.y;
        tags[i]     = 1;
        contours[i] = i;

        outline.points   = points;
        outline.tags     = tags;
        outline.contours = contours;

        /* this call provides additional offsets */
        /* for each component's translation      */
        if ( FT_SET_ERROR( TT_Vary_Apply_Glyph_Deltas(
                             face,
                             glyph_index,
                             &outline,
                             unrounded,
                             (FT_UInt)outline.n_points ) ) )
          goto Exit1;

        subglyph = gloader->current.subglyphs;

        for ( i = 0; i < limit; i++, subglyph++ )
        {
          if ( subglyph->flags & ARGS_ARE_XY_VALUES )
          {
            subglyph->arg1 = (FT_Int16)points[i].x;
            subglyph->arg2 = (FT_Int16)points[i].y;
          }
        }

        loader->pp1.x = points[i + 0].x;
        loader->pp1.y = points[i + 0].y;
        loader->pp2.x = points[i + 1].x;
        loader->pp2.y = points[i + 1].y;

        loader->pp3.x = points[i + 2].x;
        loader->pp3.y = points[i + 2].y;
        loader->pp4.x = points[i + 3].x;
        loader->pp4.y = points[i + 3].y;

        /* recalculate linear horizontal and vertical advances */
        /* if we don't have HVAR and VVAR, respectively        */
        if ( !( face->variation_support & TT_FACE_FLAG_VAR_HADVANCE ) )
          loader->linear = FT_PIX_ROUND( unrounded[1].x -
                                         unrounded[0].x ) / 64;
        if ( !( face->variation_support & TT_FACE_FLAG_VAR_VADVANCE ) )
          loader->vadvance = FT_PIX_ROUND( unrounded[3].x -
                                           unrounded[2].x ) / 64;

      Exit1:
        FT_FREE( outline.points );
        FT_FREE( outline.tags );
        FT_FREE( outline.contours );
        FT_FREE( unrounded );

        if ( error )
          goto Exit;
      }

#endif /* TT_CONFIG_OPTION_GX_VAR_SUPPORT */

      /* scale phantom points, if necessary; */
      /* they get rounded in `TT_Hint_Glyph' */
      if ( ( loader->load_flags & FT_LOAD_NO_SCALE ) == 0 )
      {
        loader->pp1.x = FT_MulFix( loader->pp1.x, x_scale );
        loader->pp2.x = FT_MulFix( loader->pp2.x, x_scale );
        /* pp1.y and pp2.y are always zero */

        loader->pp3.x = FT_MulFix( loader->pp3.x, x_scale );
        loader->pp3.y = FT_MulFix( loader->pp3.y, y_scale );
        loader->pp4.x = FT_MulFix( loader->pp4.x, x_scale );
        loader->pp4.y = FT_MulFix( loader->pp4.y, y_scale );
      }

      /* if the flag FT_LOAD_NO_RECURSE is set, we return the subglyph */
      /* `as is' in the glyph slot (the client application will be     */
      /* responsible for interpreting these data)...                   */
      if ( loader->load_flags & FT_LOAD_NO_RECURSE )
      {
        FT_GlyphLoader_Add( gloader );
        loader->glyph->format = FT_GLYPH_FORMAT_COMPOSITE;

        goto Exit;
      }

      /*********************************************************************/
      /*********************************************************************/
      /*********************************************************************/

      {
        FT_UInt      n, num_base_points;
        FT_SubGlyph  subglyph       = NULL;

        FT_UInt      num_points     = start_point;
        FT_UInt      num_subglyphs  = gloader->current.num_subglyphs;
        FT_UInt      num_base_subgs = gloader->base.num_subglyphs;

        FT_Stream    old_stream     = loader->stream;
        FT_Int       old_byte_len   = loader->byte_len;


        FT_GlyphLoader_Add( gloader );

        /* read each subglyph independently */
        for ( n = 0; n < num_subglyphs; n++ )
        {
          FT_Vector  pp[4];

          FT_Int  linear_hadvance;
          FT_Int  linear_vadvance;


          /* Each time we call `load_truetype_glyph' in this loop, the */
          /* value of `gloader.base.subglyphs' can change due to table */
          /* reallocations.  We thus need to recompute the subglyph    */
          /* pointer on each iteration.                                */
          subglyph = gloader->base.subglyphs + num_base_subgs + n;

          pp[0] = loader->pp1;
          pp[1] = loader->pp2;
          pp[2] = loader->pp3;
          pp[3] = loader->pp4;

          linear_hadvance = loader->linear;
          linear_vadvance = loader->vadvance;

          num_base_points = (FT_UInt)gloader->base.outline.n_points;

          error = load_truetype_glyph( loader,
                                       (FT_UInt)subglyph->index,
                                       recurse_count + 1,
                                       FALSE );
          if ( error )
            goto Exit;

          /* restore subglyph pointer */
          subglyph = gloader->base.subglyphs + num_base_subgs + n;

          /* restore phantom points if necessary */
          if ( !( subglyph->flags & USE_MY_METRICS ) )
          {
            loader->pp1 = pp[0];
            loader->pp2 = pp[1];
            loader->pp3 = pp[2];
            loader->pp4 = pp[3];

            loader->linear   = linear_hadvance;
            loader->vadvance = linear_vadvance;
          }

          num_points = (FT_UInt)gloader->base.outline.n_points;

          if ( num_points == num_base_points )
            continue;

          /* gloader->base.outline consists of three parts:           */
          /*                                                          */
          /* 0 ----> start_point ----> num_base_points ----> n_points */
          /*    (1)               (2)                   (3)           */
          /*                                                          */
          /* (1) points that exist from the beginning                 */
          /* (2) component points that have been loaded so far        */
          /* (3) points of the newly loaded component                 */
          error = TT_Process_Composite_Component( loader,
                                                  subglyph,
                                                  start_point,
                                                  num_base_points );
          if ( error )
            goto Exit;
        }

        loader->stream   = old_stream;
        loader->byte_len = old_byte_len;

        /* process the glyph */
        loader->ins_pos = ins_pos;
        if ( IS_HINTED( loader->load_flags ) &&
#ifdef TT_USE_BYTECODE_INTERPRETER
             subglyph                        &&
             subglyph->flags & WE_HAVE_INSTR &&
#endif
             num_points > start_point )
        {
          error = TT_Process_Composite_Glyph( loader,
                                              start_point,
                                              start_contour );
          if ( error )
            goto Exit;
        }
      }
    }

    /***********************************************************************/
    /***********************************************************************/
    /***********************************************************************/

  Exit:

    if ( opened_frame )
      face->forget_glyph_frame( loader );

#ifdef FT_CONFIG_OPTION_INCREMENTAL

    if ( glyph_data_loaded )
      face->root.internal->incremental_interface->funcs->free_glyph_data(
        face->root.internal->incremental_interface->object,
        &glyph_data );

#endif

    return error;
  }


  static FT_Error
  compute_glyph_metrics( TT_Loader  loader,
                         FT_UInt    glyph_index )
  {
    TT_Face    face   = loader->face;
#if defined TT_SUPPORT_SUBPIXEL_HINTING_INFINALITY || \
    defined TT_SUPPORT_SUBPIXEL_HINTING_MINIMAL
    TT_Driver  driver = (TT_Driver)FT_FACE_DRIVER( face );
#endif

    FT_BBox       bbox;
    FT_Fixed      y_scale;
    TT_GlyphSlot  glyph = loader->glyph;
    TT_Size       size  = loader->size;


    y_scale = 0x10000L;
    if ( ( loader->load_flags & FT_LOAD_NO_SCALE ) == 0 )
      y_scale = size->metrics->y_scale;

    if ( glyph->format != FT_GLYPH_FORMAT_COMPOSITE )
      FT_Outline_Get_CBox( &glyph->outline, &bbox );
    else
      bbox = loader->bbox;

    /* get the device-independent horizontal advance; it is scaled later */
    /* by the base layer.                                                */
    glyph->linearHoriAdvance = loader->linear;

    glyph->metrics.horiBearingX = bbox.xMin;
    glyph->metrics.horiBearingY = bbox.yMax;
    glyph->metrics.horiAdvance  = SUB_LONG(loader->pp2.x, loader->pp1.x);

    /* Adjust advance width to the value contained in the hdmx table   */
    /* unless FT_LOAD_COMPUTE_METRICS is set or backward compatibility */
    /* mode of the v40 interpreter is active.  See `ttinterp.h' for    */
    /* details on backward compatibility mode.                         */
    if (
#ifdef TT_SUPPORT_SUBPIXEL_HINTING_MINIMAL
         !( driver->interpreter_version == TT_INTERPRETER_VERSION_40  &&
            ( loader->exec && loader->exec->backward_compatibility  ) ) &&
#endif
         !face->postscript.isFixedPitch                                 &&
         IS_HINTED( loader->load_flags )                                &&
         !( loader->load_flags & FT_LOAD_COMPUTE_METRICS )              )
    {
      FT_Byte*  widthp;


      widthp = tt_face_get_device_metrics( face,
                                           size->metrics->x_ppem,
                                           glyph_index );

#ifdef TT_SUPPORT_SUBPIXEL_HINTING_INFINALITY

      if ( driver->interpreter_version == TT_INTERPRETER_VERSION_38 )
      {
        FT_Bool  ignore_x_mode;


        ignore_x_mode = FT_BOOL( FT_LOAD_TARGET_MODE( loader->load_flags ) !=
                                 FT_RENDER_MODE_MONO );

        if ( widthp                                                   &&
             ( ( ignore_x_mode && loader->exec->compatible_widths ) ||
                !ignore_x_mode                                      ||
                SPH_OPTION_BITMAP_WIDTHS                            ) )
          glyph->metrics.horiAdvance = *widthp * 64;
      }
      else

#endif /* TT_SUPPORT_SUBPIXEL_HINTING_INFINALITY */

      {
        if ( widthp )
          glyph->metrics.horiAdvance = *widthp * 64;
      }
    }

    /* set glyph dimensions */
    glyph->metrics.width  = SUB_LONG( bbox.xMax, bbox.xMin );
    glyph->metrics.height = SUB_LONG( bbox.yMax, bbox.yMin );

    /* Now take care of vertical metrics.  In the case where there is */
    /* no vertical information within the font (relatively common),   */
    /* create some metrics manually                                   */
    {
      FT_Pos  top;      /* scaled vertical top side bearing  */
      FT_Pos  advance;  /* scaled vertical advance height    */


      /* Get the unscaled top bearing and advance height. */
      if ( face->vertical_info                   &&
           face->vertical.number_Of_VMetrics > 0 )
      {
        top = (FT_Short)FT_DivFix( loader->pp3.y - bbox.yMax,
                                   y_scale );

        if ( loader->pp3.y <= loader->pp4.y )
          advance = 0;
        else
          advance = (FT_UShort)FT_DivFix( loader->pp3.y - loader->pp4.y,
                                          y_scale );
      }
      else
      {
        FT_Pos  height;


        /* XXX Compute top side bearing and advance height in  */
        /*     Get_VMetrics instead of here.                   */

        /* NOTE: The OS/2 values are the only `portable' ones, */
        /*       which is why we use them, if there is an OS/2 */
        /*       table in the font.  Otherwise, we use the     */
        /*       values defined in the horizontal header.      */

        height = (FT_Short)FT_DivFix( SUB_LONG( bbox.yMax,
                                                bbox.yMin ),
                                      y_scale );
        if ( face->os2.version != 0xFFFFU )
          advance = (FT_Pos)( face->os2.sTypoAscender -
                              face->os2.sTypoDescender );
        else
          advance = (FT_Pos)( face->horizontal.Ascender -
                              face->horizontal.Descender );

        top = ( advance - height ) / 2;
      }

#ifdef FT_CONFIG_OPTION_INCREMENTAL
      {
        FT_Incremental_InterfaceRec*  incr;
        FT_Incremental_MetricsRec     incr_metrics;
        FT_Error                      error;


        incr = face->root.internal->incremental_interface;

        /* If this is an incrementally loaded font see if there are */
        /* overriding metrics for this glyph.                       */
        if ( incr && incr->funcs->get_glyph_metrics )
        {
          incr_metrics.bearing_x = 0;
          incr_metrics.bearing_y = top;
          incr_metrics.advance   = advance;

          error = incr->funcs->get_glyph_metrics( incr->object,
                                                  glyph_index,
                                                  TRUE,
                                                  &incr_metrics );
          if ( error )
            return error;

          top     = incr_metrics.bearing_y;
          advance = incr_metrics.advance;
        }
      }

      /* GWW: Do vertical metrics get loaded incrementally too? */

#endif /* FT_CONFIG_OPTION_INCREMENTAL */

      glyph->linearVertAdvance = advance;

      /* scale the metrics */
      if ( !( loader->load_flags & FT_LOAD_NO_SCALE ) )
      {
        top     = FT_MulFix( top,     y_scale );
        advance = FT_MulFix( advance, y_scale );
      }

      /* XXX: for now, we have no better algorithm for the lsb, but it */
      /*      should work fine.                                        */
      /*                                                               */
      glyph->metrics.vertBearingX = SUB_LONG( glyph->metrics.horiBearingX,
                                              glyph->metrics.horiAdvance / 2 );
      glyph->metrics.vertBearingY = top;
      glyph->metrics.vertAdvance  = advance;
    }

    return FT_Err_Ok;
  }


#ifdef TT_CONFIG_OPTION_EMBEDDED_BITMAPS

  static FT_Error
  load_sbit_image( TT_Size       size,
                   TT_GlyphSlot  glyph,
                   FT_UInt       glyph_index,
                   FT_Int32      load_flags )
  {
    TT_Face             face;
    SFNT_Service        sfnt;
    FT_Stream           stream;
    FT_Error            error;
    TT_SBit_MetricsRec  sbit_metrics;


    face   = (TT_Face)glyph->face;
    sfnt   = (SFNT_Service)face->sfnt;
    stream = face->root.stream;

    error = sfnt->load_sbit_image( face,
                                   size->strike_index,
                                   glyph_index,
                                   (FT_UInt)load_flags,
                                   stream,
                                   &glyph->bitmap,
                                   &sbit_metrics );
    if ( !error )
    {
      glyph->outline.n_points   = 0;
      glyph->outline.n_contours = 0;

      glyph->metrics.width  = (FT_Pos)sbit_metrics.width  * 64;
      glyph->metrics.height = (FT_Pos)sbit_metrics.height * 64;

      glyph->metrics.horiBearingX = (FT_Pos)sbit_metrics.horiBearingX * 64;
      glyph->metrics.horiBearingY = (FT_Pos)sbit_metrics.horiBearingY * 64;
      glyph->metrics.horiAdvance  = (FT_Pos)sbit_metrics.horiAdvance  * 64;

      glyph->metrics.vertBearingX = (FT_Pos)sbit_metrics.vertBearingX * 64;
      glyph->metrics.vertBearingY = (FT_Pos)sbit_metrics.vertBearingY * 64;
      glyph->metrics.vertAdvance  = (FT_Pos)sbit_metrics.vertAdvance  * 64;

      glyph->format = FT_GLYPH_FORMAT_BITMAP;

      if ( load_flags & FT_LOAD_VERTICAL_LAYOUT )
      {
        glyph->bitmap_left = sbit_metrics.vertBearingX;
        glyph->bitmap_top  = sbit_metrics.vertBearingY;
      }
      else
      {
        glyph->bitmap_left = sbit_metrics.horiBearingX;
        glyph->bitmap_top  = sbit_metrics.horiBearingY;
      }
    }

    return error;
  }

#endif /* TT_CONFIG_OPTION_EMBEDDED_BITMAPS */


  static FT_Error
  tt_loader_init( TT_Loader     loader,
                  TT_Size       size,
                  TT_GlyphSlot  glyph,
                  FT_Int32      load_flags,
                  FT_Bool       glyf_table_only )
  {
    TT_Face    face;
    FT_Stream  stream;

#ifdef TT_USE_BYTECODE_INTERPRETER
    FT_Error   error;
    FT_Bool    pedantic = FT_BOOL( load_flags & FT_LOAD_PEDANTIC );
#if defined TT_SUPPORT_SUBPIXEL_HINTING_INFINALITY || \
    defined TT_SUPPORT_SUBPIXEL_HINTING_MINIMAL
    TT_Driver  driver = (TT_Driver)FT_FACE_DRIVER( (TT_Face)glyph->face );
#endif
#endif


    face   = (TT_Face)glyph->face;
    stream = face->root.stream;

    FT_ZERO( loader );

#ifdef TT_USE_BYTECODE_INTERPRETER

    /* load execution context */
    if ( IS_HINTED( load_flags ) && !glyf_table_only )
    {
      TT_ExecContext  exec;
      FT_Bool         grayscale = TRUE;
#ifdef TT_SUPPORT_SUBPIXEL_HINTING_MINIMAL
      FT_Bool         subpixel_hinting_lean;
      FT_Bool         grayscale_cleartype;
#endif

#ifdef TT_SUPPORT_SUBPIXEL_HINTING_INFINALITY
      FT_Bool  subpixel_hinting = FALSE;

#if 0
      /* not used yet */
      FT_Bool  compatible_widths;
      FT_Bool  symmetrical_smoothing;
      FT_Bool  bgr;
      FT_Bool  vertical_lcd;
      FT_Bool  subpixel_positioned;
      FT_Bool  gray_cleartype;
#endif
#endif /* TT_SUPPORT_SUBPIXEL_HINTING_INFINALITY */

      FT_Bool  reexecute = FALSE;


      if ( size->bytecode_ready < 0 || size->cvt_ready < 0 )
      {
        error = tt_size_ready_bytecode( size, pedantic );
        if ( error )
          return error;
      }
      else if ( size->bytecode_ready )
        return size->bytecode_ready;
      else if ( size->cvt_ready )
        return size->cvt_ready;

      /* query new execution context */
      exec = size->context;
      if ( !exec )
        return FT_THROW( Could_Not_Find_Context );

#ifdef TT_SUPPORT_SUBPIXEL_HINTING_MINIMAL
      if ( driver->interpreter_version == TT_INTERPRETER_VERSION_40 )
      {
        subpixel_hinting_lean =
          FT_BOOL( FT_LOAD_TARGET_MODE( load_flags ) !=
                   FT_RENDER_MODE_MONO               );
        grayscale_cleartype =
          FT_BOOL( subpixel_hinting_lean         &&
                   !( ( load_flags         &
                        FT_LOAD_TARGET_LCD )   ||
                      ( load_flags           &
                        FT_LOAD_TARGET_LCD_V ) ) );
        exec->vertical_lcd_lean =
          FT_BOOL( subpixel_hinting_lean    &&
                   ( load_flags           &
                     FT_LOAD_TARGET_LCD_V ) );
      }
      else
      {
        subpixel_hinting_lean   = FALSE;
        grayscale_cleartype     = FALSE;
        exec->vertical_lcd_lean = FALSE;
      }
#endif

#ifdef TT_SUPPORT_SUBPIXEL_HINTING_INFINALITY

      if ( driver->interpreter_version == TT_INTERPRETER_VERSION_38 )
      {
        subpixel_hinting = FT_BOOL( ( FT_LOAD_TARGET_MODE( load_flags ) !=
                                      FT_RENDER_MODE_MONO               )  &&
                                    SPH_OPTION_SET_SUBPIXEL                );

        if ( subpixel_hinting )
          grayscale = FALSE;
        else if ( SPH_OPTION_SET_GRAYSCALE )
        {
          grayscale        = TRUE;
          subpixel_hinting = FALSE;
        }
        else
          grayscale = FALSE;

        if ( FT_IS_TRICKY( glyph->face ) )
          subpixel_hinting = FALSE;

        exec->ignore_x_mode      = subpixel_hinting || grayscale;
        exec->rasterizer_version = SPH_OPTION_SET_RASTERIZER_VERSION;
        if ( exec->sph_tweak_flags & SPH_TWEAK_RASTERIZER_35 )
          exec->rasterizer_version = TT_INTERPRETER_VERSION_35;

#if 1
        exec->compatible_widths     = SPH_OPTION_SET_COMPATIBLE_WIDTHS;
        exec->symmetrical_smoothing = TRUE;
        exec->bgr                   = FALSE;
        exec->vertical_lcd          = FALSE;
        exec->subpixel_positioned   = TRUE;
        exec->gray_cleartype        = FALSE;
#else /* 0 */
        exec->compatible_widths =
          FT_BOOL( FT_LOAD_TARGET_MODE( load_flags ) !=
                   TT_LOAD_COMPATIBLE_WIDTHS );
        exec->symmetrical_smoothing =
          FT_BOOL( FT_LOAD_TARGET_MODE( load_flags ) !=
                   TT_LOAD_SYMMETRICAL_SMOOTHING );
        exec->bgr =
          FT_BOOL( FT_LOAD_TARGET_MODE( load_flags ) !=
                   TT_LOAD_BGR );
        exec->vertical_lcd =
          FT_BOOL( FT_LOAD_TARGET_MODE( load_flags ) !=
                   TT_LOAD_VERTICAL_LCD );
        exec->subpixel_positioned =
          FT_BOOL( FT_LOAD_TARGET_MODE( load_flags ) !=
                   TT_LOAD_SUBPIXEL_POSITIONED );
        exec->gray_cleartype =
          FT_BOOL( FT_LOAD_TARGET_MODE( load_flags ) !=
                   TT_LOAD_GRAY_CLEARTYPE );
#endif /* 0 */

      }
      else

#endif /* TT_SUPPORT_SUBPIXEL_HINTING_INFINALITY */

#ifdef TT_SUPPORT_SUBPIXEL_HINTING_MINIMAL
      if ( driver->interpreter_version == TT_INTERPRETER_VERSION_40 )
        grayscale = FT_BOOL( !subpixel_hinting_lean               &&
                             FT_LOAD_TARGET_MODE( load_flags ) !=
                               FT_RENDER_MODE_MONO                );
      else
#endif
        grayscale = FT_BOOL( FT_LOAD_TARGET_MODE( load_flags ) !=
                               FT_RENDER_MODE_MONO             );

      error = TT_Load_Context( exec, face, size );
      if ( error )
        return error;

#ifdef TT_SUPPORT_SUBPIXEL_HINTING_INFINALITY

      if ( driver->interpreter_version == TT_INTERPRETER_VERSION_38 )
      {
        /* a change from mono to subpixel rendering (and vice versa) */
        /* requires a re-execution of the CVT program                */
        if ( subpixel_hinting != exec->subpixel_hinting )
        {
          FT_TRACE4(( "tt_loader_init: subpixel hinting change,"
                      " re-executing `prep' table\n" ));

          exec->subpixel_hinting = subpixel_hinting;
          reexecute              = TRUE;
        }

        /* a change from mono to grayscale rendering (and vice versa) */
        /* requires a re-execution of the CVT program                 */
        if ( grayscale != exec->grayscale )
        {
          FT_TRACE4(( "tt_loader_init: grayscale hinting change,"
                      " re-executing `prep' table\n" ));

          exec->grayscale = grayscale;
          reexecute       = TRUE;
        }
      }
      else

#endif /* TT_SUPPORT_SUBPIXEL_HINTING_INFINALITY */

      {

#ifdef TT_SUPPORT_SUBPIXEL_HINTING_MINIMAL
        if ( driver->interpreter_version == TT_INTERPRETER_VERSION_40 )
        {
          /* a change from mono to subpixel rendering (and vice versa) */
          /* requires a re-execution of the CVT program                */
          if ( subpixel_hinting_lean != exec->subpixel_hinting_lean )
          {
            FT_TRACE4(( "tt_loader_init: subpixel hinting change,"
                        " re-executing `prep' table\n" ));

            exec->subpixel_hinting_lean = subpixel_hinting_lean;
            reexecute                   = TRUE;
          }

          /* a change from colored to grayscale subpixel rendering (and */
          /* vice versa) requires a re-execution of the CVT program     */
          if ( grayscale_cleartype != exec->grayscale_cleartype )
          {
            FT_TRACE4(( "tt_loader_init: grayscale subpixel hinting change,"
                        " re-executing `prep' table\n" ));

            exec->grayscale_cleartype = grayscale_cleartype;
            reexecute                 = TRUE;
          }
        }
#endif

        /* a change from mono to grayscale rendering (and vice versa) */
        /* requires a re-execution of the CVT program                 */
        if ( grayscale != exec->grayscale )
        {
          FT_TRACE4(( "tt_loader_init: grayscale hinting change,"
                      " re-executing `prep' table\n" ));

          exec->grayscale = grayscale;
          reexecute       = TRUE;
        }
      }

      if ( reexecute )
      {
        FT_UInt  i;


        for ( i = 0; i < size->cvt_size; i++ )
          size->cvt[i] = FT_MulFix( face->cvt[i], size->ttmetrics.scale );
        error = tt_size_run_prep( size, pedantic );
        if ( error )
          return error;
      }

      /* check whether the cvt program has disabled hinting */
      if ( exec->GS.instruct_control & 1 )
        load_flags |= FT_LOAD_NO_HINTING;

      /* load default graphics state -- if needed */
      if ( exec->GS.instruct_control & 2 )
        exec->GS = tt_default_graphics_state;

#ifdef TT_SUPPORT_SUBPIXEL_HINTING_INFINALITY
      /* check whether we have a font hinted for ClearType --           */
      /* note that this flag can also be modified in a glyph's bytecode */
      if ( driver->interpreter_version == TT_INTERPRETER_VERSION_38 &&
           exec->GS.instruct_control & 4                            )
        exec->ignore_x_mode = 0;
#endif

      exec->pedantic_hinting = FT_BOOL( load_flags & FT_LOAD_PEDANTIC );
      loader->exec = exec;
      loader->instructions = exec->glyphIns;
    }

#endif /* TT_USE_BYTECODE_INTERPRETER */

    /* get face's glyph loader */
    if ( !glyf_table_only )
    {
      FT_GlyphLoader  gloader = glyph->internal->loader;


      FT_GlyphLoader_Rewind( gloader );
      loader->gloader = gloader;
    }

    loader->load_flags = (FT_ULong)load_flags;

    loader->face   = face;
    loader->size   = size;
    loader->glyph  = (FT_GlyphSlot)glyph;
    loader->stream = stream;

    loader->composites.head = NULL;
    loader->composites.tail = NULL;

    return FT_Err_Ok;
  }


  static void
  tt_loader_done( TT_Loader  loader )
  {
    FT_List_Finalize( &loader->composites,
                      NULL,
                      loader->face->root.memory,
                      NULL );
  }


  /**************************************************************************
   *
   * @Function:
   *   TT_Load_Glyph
   *
   * @Description:
   *   A function used to load a single glyph within a given glyph slot,
   *   for a given size.
   *
   * @Input:
   *   glyph ::
   *     A handle to a target slot object where the glyph
   *     will be loaded.
   *
   *   size ::
   *     A handle to the source face size at which the glyph
   *     must be scaled/loaded.
   *
   *   glyph_index ::
   *     The index of the glyph in the font file.
   *
   *   load_flags ::
   *     A flag indicating what to load for this glyph.  The
   *     FT_LOAD_XXX constants can be used to control the
   *     glyph loading process (e.g., whether the outline
   *     should be scaled, whether to load bitmaps or not,
   *     whether to hint the outline, etc).
   *
   * @Return:
   *   FreeType error code.  0 means success.
   */
  FT_LOCAL_DEF( FT_Error )
  TT_Load_Glyph( TT_Size       size,
                 TT_GlyphSlot  glyph,
                 FT_UInt       glyph_index,
                 FT_Int32      load_flags )
  {
    FT_Error      error;
    TT_LoaderRec  loader;

#ifdef TT_CONFIG_OPTION_GX_VAR_SUPPORT
#define IS_DEFAULT_INSTANCE  ( !( FT_IS_NAMED_INSTANCE( glyph->face ) ||  \
                                  FT_IS_VARIATION( glyph->face )      ) )
#else
#define IS_DEFAULT_INSTANCE  1
#endif


    FT_TRACE1(( "TT_Load_Glyph: glyph index %d\n", glyph_index ));

#ifdef TT_CONFIG_OPTION_EMBEDDED_BITMAPS

    /* try to load embedded bitmap (if any) */
    if ( size->strike_index != 0xFFFFFFFFUL      &&
         ( load_flags & FT_LOAD_NO_BITMAP ) == 0 &&
         IS_DEFAULT_INSTANCE                     )
    {
      FT_Fixed  x_scale = size->root.metrics.x_scale;
      FT_Fixed  y_scale = size->root.metrics.y_scale;


      error = load_sbit_image( size, glyph, glyph_index, load_flags );
      if ( FT_ERR_EQ( error, Missing_Bitmap ) )
      {
        /* the bitmap strike is incomplete and misses the requested glyph; */
        /* if we have a bitmap-only font, return an empty glyph            */
        if ( !FT_IS_SCALABLE( glyph->face ) )
        {
          TT_Face  face = (TT_Face)glyph->face;

          FT_Short  left_bearing = 0;
          FT_Short  top_bearing  = 0;

          FT_UShort  advance_width  = 0;
          FT_UShort  advance_height = 0;


          /* to return an empty glyph, however, we need metrics data   */
          /* from the `hmtx' (or `vmtx') table; the assumption is that */
          /* empty glyphs are missing intentionally, representing      */
          /* whitespace - not having at least horizontal metrics is    */
          /* thus considered an error                                  */
          if ( !face->horz_metrics_size )
            return error;

          /* we now construct an empty bitmap glyph */
          TT_Get_HMetrics( face, glyph_index,
                           &left_bearing,
                           &advance_width );
          TT_Get_VMetrics( face, glyph_index,
                           0,
                           &top_bearing,
                           &advance_height );

          glyph->outline.n_points   = 0;
          glyph->outline.n_contours = 0;

          glyph->metrics.width  = 0;
          glyph->metrics.height = 0;

          glyph->metrics.horiBearingX = FT_MulFix( left_bearing, x_scale );
          glyph->metrics.horiBearingY = 0;
          glyph->metrics.horiAdvance  = FT_MulFix( advance_width, x_scale );

          glyph->metrics.vertBearingX = 0;
          glyph->metrics.vertBearingY = FT_MulFix( top_bearing, y_scale );
          glyph->metrics.vertAdvance  = FT_MulFix( advance_height, y_scale );

          glyph->format            = FT_GLYPH_FORMAT_BITMAP;
          glyph->bitmap.pixel_mode = FT_PIXEL_MODE_MONO;

          glyph->bitmap_left = 0;
          glyph->bitmap_top  = 0;

          return FT_Err_Ok;
        }
      }
      else if ( error )
      {
        /* return error if font is not scalable */
        if ( !FT_IS_SCALABLE( glyph->face ) )
          return error;
      }
      else
      {
        if ( FT_IS_SCALABLE( glyph->face ) )
        {
          /* for the bbox we need the header only */
          (void)tt_loader_init( &loader, size, glyph, load_flags, TRUE );
          (void)load_truetype_glyph( &loader, glyph_index, 0, TRUE );
          tt_loader_done( &loader );
          glyph->linearHoriAdvance = loader.linear;
          glyph->linearVertAdvance = loader.vadvance;

          /* sanity checks: if `xxxAdvance' in the sbit metric */
          /* structure isn't set, use `linearXXXAdvance'      */
          if ( !glyph->metrics.horiAdvance && glyph->linearHoriAdvance )
            glyph->metrics.horiAdvance = FT_MulFix( glyph->linearHoriAdvance,
                                                    x_scale );
          if ( !glyph->metrics.vertAdvance && glyph->linearVertAdvance )
            glyph->metrics.vertAdvance = FT_MulFix( glyph->linearVertAdvance,
                                                    y_scale );
        }

        return FT_Err_Ok;
      }
    }

#endif /* TT_CONFIG_OPTION_EMBEDDED_BITMAPS */

    /* if FT_LOAD_NO_SCALE is not set, `ttmetrics' must be valid */
    if ( !( load_flags & FT_LOAD_NO_SCALE ) && !size->ttmetrics.valid )
    {
      error = FT_THROW( Invalid_Size_Handle );
      goto Exit;
    }

    if ( load_flags & FT_LOAD_SBITS_ONLY )
    {
      error = FT_THROW( Invalid_Argument );
      goto Exit;
    }

    error = tt_loader_init( &loader, size, glyph, load_flags, FALSE );
    if ( error )
      goto Exit;

    glyph->format        = FT_GLYPH_FORMAT_OUTLINE;
    glyph->num_subglyphs = 0;
    glyph->outline.flags = 0;

    /* main loading loop */
    error = load_truetype_glyph( &loader, glyph_index, 0, FALSE );
    if ( !error )
    {
      if ( glyph->format == FT_GLYPH_FORMAT_COMPOSITE )
      {
        glyph->num_subglyphs = loader.gloader->base.num_subglyphs;
        glyph->subglyphs     = loader.gloader->base.subglyphs;
      }
      else
      {
        glyph->outline        = loader.gloader->base.outline;
        glyph->outline.flags &= ~FT_OUTLINE_SINGLE_PASS;

        /* Translate array so that (0,0) is the glyph's origin.  Note  */
        /* that this behaviour is independent on the value of bit 1 of */
        /* the `flags' field in the `head' table -- at least major     */
        /* applications like Acroread indicate that.                   */
        if ( loader.pp1.x )
          FT_Outline_Translate( &glyph->outline, -loader.pp1.x, 0 );
      }

#ifdef TT_USE_BYTECODE_INTERPRETER

      if ( IS_HINTED( load_flags ) )
      {
        if ( loader.exec->GS.scan_control )
        {
          /* convert scan conversion mode to FT_OUTLINE_XXX flags */
          switch ( loader.exec->GS.scan_type )
          {
          case 0: /* simple drop-outs including stubs */
            glyph->outline.flags |= FT_OUTLINE_INCLUDE_STUBS;
            break;
          case 1: /* simple drop-outs excluding stubs */
            /* nothing; it's the default rendering mode */
            break;
          case 4: /* smart drop-outs including stubs */
            glyph->outline.flags |= FT_OUTLINE_SMART_DROPOUTS |
                                    FT_OUTLINE_INCLUDE_STUBS;
            break;
          case 5: /* smart drop-outs excluding stubs  */
            glyph->outline.flags |= FT_OUTLINE_SMART_DROPOUTS;
            break;

          default: /* no drop-out control */
            glyph->outline.flags |= FT_OUTLINE_IGNORE_DROPOUTS;
            break;
          }
        }
        else
          glyph->outline.flags |= FT_OUTLINE_IGNORE_DROPOUTS;
      }

#endif /* TT_USE_BYTECODE_INTERPRETER */

      error = compute_glyph_metrics( &loader, glyph_index );
    }

    tt_loader_done( &loader );

    /* Set the `high precision' bit flag.                           */
    /* This is _critical_ to get correct output for monochrome      */
    /* TrueType glyphs at all sizes using the bytecode interpreter. */
    /*                                                              */
    if ( !( load_flags & FT_LOAD_NO_SCALE ) &&
         size->metrics->y_ppem < 24         )
      glyph->outline.flags |= FT_OUTLINE_HIGH_PRECISION;

  Exit:
#ifdef FT_DEBUG_LEVEL_TRACE
    if ( error )
      FT_TRACE1(( "  failed (error code 0x%x)\n",
                  error ));
#endif

    return error;
  }


/* END */
