/****************************************************************************
 *
 * 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_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. */
      error = TT_Vary_Apply_Glyph_Deltas( loader->face,
                                          loader->glyph_index,
                                          outline,
                                          (FT_UInt)n_points );

      /* 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 = outline->points[n_points - 3].x -
                         outline->points[n_points - 4].x;
      if ( !( loader->face->variation_support & TT_FACE_FLAG_VAR_VADVANCE ) )
        loader->vadvance = outline->points[n_points - 1].x -
                           outline->points[n_points - 2].x;

      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_Outline_EmboldenXY( outline,
                                   FT_MulFix( 1280 * ppem,
                                              1000 - x_scale_factor ),
                                   0 );
          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++ )
        {
          vec->x = FT_MulFix( vec->x, x_scale );
          vec->y = FT_MulFix( vec->y, y_scale );
        }
      }

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


        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,
                                            (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 = loader->pp2.x - loader->pp1.x;
        if ( !( loader->face->variation_support & TT_FACE_FLAG_VAR_VADVANCE ) )
          loader->vadvance = loader->pp4.x - loader->pp3.x;
      }

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


        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 ) )
          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,
                             (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 = loader->pp2.x - loader->pp1.x;
        if ( !( face->variation_support & TT_FACE_FLAG_VAR_VADVANCE ) )
          loader->vadvance = loader->pp4.x - loader->pp3.x;

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

        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 */
