shithub: freetype+ttf2subf

Download patch

ref: 8f43c714a5a74c63c2a6242392790510ac487f80
parent: 0360168a4d0decdeb2f9dfde9a3be887dcea3892
author: David Turner <[email protected]>
date: Wed Feb 2 07:16:19 EST 2000

A major refresh of the TrueType driver :

- some #ifdefs were included in order to _not_
  compile support for the bytecode interpreter
  when FT_CONFIG_OPTION_BYTECODE_INTERPRETER
  is not defined in "ttconfig.h"

- the glyph loader has been seriously re-designed. It is now
  smaller, simpler and should load composites a bit faster

- works with the TrueType debugger

git/fs: mount .git/fs: mount/attach disallowed
--- a/src/truetype/truetype.c
+++ b/src/truetype/truetype.c
@@ -44,7 +44,9 @@
 #include <ttdriver.c>    /* driver interface     */
 #include <ttpload.c>     /* tables loader        */
 #include <ttgload.c>     /* glyph loader         */
-#include <ttinterp.c>    /* bytecode interpreter */
 #include <ttobjs.c>      /* object manager       */
 
+#ifdef TT_CONFIG_OPTION_BYTECODE_INTERPRETER
+#include <ttinterp.c>    /* bytecode interpreter */
+#endif
 /* END */
--- a/src/truetype/ttconfig.h
+++ b/src/truetype/ttconfig.h
@@ -30,6 +30,17 @@
 
   /*************************************************************************/
   /*                                                                       */
+  /* Define TT_CONFIG_OPTION_BYTECODE_INTERPRETER if you want to compile   */
+  /* a bytecode interpreter in the TrueType driver. Note that there are    */
+  /* important patent issues related to the use of the interpreter.        */
+  /*                                                                       */
+  /* By undefining this, you'll only compile the code necessary to load    */
+  /* TrueType glyphs without hinting..                                     */
+  /*                                                                       */
+#undef  TT_CONFIG_OPTION_BYTECODE_INTERPRETER
+
+  /*************************************************************************/
+  /*                                                                       */
   /* Define TT_CONFIG_OPTION_INTERPRETER_SWITCH to compile the TrueType    */
   /* bytecode interpreter with a huge switch statement, rather than a      */
   /* call table.  This results in smaller and faster code for a number of  */
@@ -46,7 +57,7 @@
   /* Define TT_CONFIG_OPTION_EMBEDDED_BITMAPS if you want to support       */
   /* embedded bitmaps in the TrueType/OpenType driver.                     */
   /*                                                                       */
-#define TT_CONFIG_OPTION_EMBEDDED_BITMAPS
+#undef  TT_CONFIG_OPTION_EMBEDDED_BITMAPS
 
 
   /*************************************************************************/
@@ -55,8 +66,10 @@
   /* load and enumerate the glyph Postscript names in a TrueType or        */
   /* OpenType file.                                                        */
   /*                                                                       */
-#define TT_CONFIG_OPTION_POSTSCRIPT_NAMES
+#undef  TT_CONFIG_OPTION_POSTSCRIPT_NAMES
 
+  /* The maximum number of sub-glyphs in a TrueType composite glyph */
+#define TT_MAX_SUBGLYPHS  32
 
 #define  TT_USE_FIXED
 
--- a/src/truetype/ttdriver.c
+++ b/src/truetype/ttdriver.c
@@ -683,7 +683,7 @@
   EXPORT_FUNC
   FT_DriverInterface*  getDriverInterface( void )
   {
-    return &truetype_driver_interface;
+    return &tt_driver_interface;
   }
 
 #endif /* CONFIG_OPTION_DYNAMIC_DRIVERS */
--- a/src/truetype/ttdriver.h
+++ b/src/truetype/ttdriver.h
@@ -26,114 +26,9 @@
 #include <ttnameid.h>
 
 
-  /*************************************************************************/
-  /*                                                                       */
-  /* <FuncType>                                                            */
-  /*    TTDriver_getFontData                                               */
-  /*                                                                       */
-  /* <Description>                                                         */
-  /*    Returns either a single font table or the whole font file into     */
-  /*    caller's memory.  This function mimics the GetFontData() API       */
-  /*    function found in Windows.                                         */
-  /*                                                                       */
-  /* <Input>                                                               */
-  /*    face   :: A handle to the source TrueType face object.             */
-  /*                                                                       */
-  /*    tag    :: A 32-bit integer used to name the table you want to      */
-  /*              read.  Use the macro MAKE_TT_TAG (defined in freetype.h) */
-  /*              to create one.  Use the value 0 if you want to access    */
-  /*              the whole file instead.                                  */
-  /*                                                                       */
-  /*    offset :: The offset from the start of the table or file from      */
-  /*              which you want to read bytes.                            */
-  /*                                                                       */
-  /*    buffer :: The address of the target/read buffer where data will be */
-  /*              copied.                                                  */
-  /*                                                                       */
-  /* <InOut>                                                               */
-  /*    length :: The length in bytes of the data to read.  If it is set   */
-  /*              to 0 when this function is called, it will return        */
-  /*              immediately, setting the value of `length' to the        */
-  /*              requested table's size (or the whole font file if the    */
-  /*              tag is 0).  It is thus possible to allocate and read an  */
-  /*              arbitrary table in two successive calls.                 */
-  /* <Return>                                                              */
-  /*    TrueType error code.  0 means success.                             */
-  /*                                                                       */
-  typedef TT_Error  (*TTDriver_getFontData)( TT_Face   face,
-                                             TT_ULong  tag,
-                                             TT_ULong  offset,
-                                             void*     buffer,
-                                             TT_Long*  length );
-
-
-  /*************************************************************************/
-  /*                                                                       */
-  /* <FuncType>                                                            */
-  /*    TTDriver_getFaceWidths                                             */
-  /*                                                                       */
-  /* <Description>                                                         */
-  /*    Returns the widths and/or heights of a given range of glyph from   */
-  /*    a face.                                                            */
-  /*                                                                       */
-  /* <Input>                                                               */
-  /*    face        :: A handle to the source FreeType face object.        */
-  /*                                                                       */
-  /*    first_glyph :: The first glyph in the range.                       */
-  /*                                                                       */
-  /*    last_glyph  :: The last glyph in the range.                        */
-  /*                                                                       */
-  /* <Output>                                                              */
-  /*    widths      :: The address of the table receiving the widths       */
-  /*                   expressed in font units (UShorts).  Set this        */
-  /*                   parameter to NULL if you're not interested in these */
-  /*                   values.                                             */
-  /*                                                                       */
-  /*    heights     :: The address of the table receiving the heights      */
-  /*                   expressed in font units (UShorts).  Set this        */
-  /*                   parameter to NULL if you're not interested in these */
-  /*                   values.                                             */
-  /*                                                                       */
-  /* <Return>                                                              */
-  /*    Error code.  0 means success.                                      */
-  /*                                                                       */
-  typedef TT_Error  (*TTDriver_getFaceWidths)( TT_Face     face,
-                                               TT_UShort   first_glyph,
-                                               TT_UShort   last_glyph,
-                                               TT_UShort*  widths,
-                                               TT_UShort*  heights );
-
-
-
-  /*************************************************************************/
-  /*                                                                       */
-  /* <Struct>                                                              */
-  /*    TT_DriverInterface                                                 */
-  /*                                                                       */
-  /* <Description>                                                         */
-  /*    The TrueType-specific interface of this driver.  Note that some of */
-  /*    the methods defined here are optional, as they're only used for    */
-  /*    for specific tasks of the driver.                                  */
-  /*                                                                       */
-  /* <Fields>                                                              */
-  /*    get_font_data   :: See the declaration of TTDriver_getFontData().  */
-  /*    get_face_widths :: See the declaration of                          */
-  /*                       TTDriver_getFaceWidths().                       */
-  /*                                                                       */
-  typedef struct  TT_DriverInterface_
-  {
-    TTDriver_getFontData    get_font_data;
-    TTDriver_getFaceWidths  get_face_widths;
-
-  } TT_DriverInterface;
-
-
   EXPORT_DEF
-  const FT_DriverInterface  tt_driver_interface;
+  const FT_DriverInterface  ttz_driver_interface;
 
-
-  EXPORT_DEF
-  const TT_DriverInterface  tt_format_interface;
 
 #endif /* TTDRIVER_H */
 
--- a/src/truetype/ttgload.c
+++ b/src/truetype/ttgload.c
@@ -25,9 +25,11 @@
 #include <ttgload.h>
 
 #include <tttags.h>
+
+#ifdef TT_CONFIG_OPTION_BYTECODE_INTERPRETER
 #include <ttinterp.h>
+#endif
 
-
   /* required for the tracing mode */
 #undef  FT_COMPONENT
 #define FT_COMPONENT  trace_ttgload
@@ -49,41 +51,15 @@
 #define USE_MY_METRICS       0x200
 
 
-#undef  SCALE_X
-#define SCALE_X( distance )  FT_MulFix( distance, exec->metrics.x_scale )
 
-#undef  SCALE_Y
-#define SCALE_Y( distance )  FT_MulFix( distance, exec->metrics.y_scale )
-
-
   /*************************************************************************/
-  /*                                                                       */
-  /* <Function>                                                            */
-  /*    TT_Get_Metrics                                                     */
-  /*                                                                       */
-  /* <Description>                                                         */
   /*    Returns the horizontal or vertical metrics in font units for a     */
   /*    given glyph.  The metrics are the left side bearing (resp. top     */
   /*    side bearing) and advance width (resp. advance height).            */
   /*                                                                       */
-  /* <Input>                                                               */
-  /*    header  :: A pointer to either the horizontal or vertical metrics  */
-  /*               structure.                                              */
-  /*                                                                       */
-  /*    index   :: The glyph index.                                        */
-  /*                                                                       */
-  /* <Output>                                                              */
-  /*    bearing :: The bearing, either left side or top side.              */
-  /*                                                                       */
-  /*    advance :: The advance width resp. advance height.                 */
-  /*                                                                       */
-  /* <Note>                                                                */
-  /*    This function will much probably move to another component in the  */
-  /*    near future, but I haven't decided which yet.                      */
-  /*                                                                       */
   LOCAL_FUNC
   void  TT_Get_Metrics( TT_HoriHeader*  header,
-                        TT_UShort       index,
+                        TT_UInt       index,
                         TT_Short*       bearing,
                         TT_UShort*      advance )
   {
@@ -106,30 +82,13 @@
 
 
   /*************************************************************************/
-  /*                                                                       */
-  /* <Function>                                                            */
-  /*    Get_HMetrics                                                       */
-  /*                                                                       */
-  /* <Description>                                                         */
   /*    Returns the horizontal metrics in font units for a given glyph.    */
   /*    If `check' is true, take care of monospaced fonts by returning the */
   /*    advance width maximum.                                             */
   /*                                                                       */
-  /* <Input>                                                               */
-  /*    face  :: A handle to the target source face.                       */
-  /*                                                                       */
-  /*    index :: The glyph index.                                          */
-  /*                                                                       */
-  /*    check :: If set, handle monospaced fonts.                          */
-  /*                                                                       */
-  /* <Output>                                                              */
-  /*    lsb   :: The left side bearing.                                    */
-  /*                                                                       */
-  /*    aw    :: The advance width.                                        */
-  /*                                                                       */
   static
   void Get_HMetrics( TT_Face     face,
-                     TT_UShort   index,
+                     TT_UInt     index,
                      TT_Bool     check,
                      TT_Short*   lsb,
                      TT_UShort*  aw )
@@ -142,22 +101,9 @@
 
 
   /*************************************************************************/
-  /*                                                                       */
-  /* <Function>                                                            */
-  /*    Get_Advance_Widths                                                 */
-  /*                                                                       */
-  /* <Description>                                                         */
   /*    Returns the advance width table for a given pixel size if it is    */
   /*    found in the font's `hdmx' table (if any).                         */
   /*                                                                       */
-  /* <Input>                                                               */
-  /*    face :: A handle to the target source face.                        */
-  /*                                                                       */
-  /*    ppem :: The pixel size.                                            */
-  /*                                                                       */
-  /* <Return>                                                              */
-  /*   A pointer to the advance with table.  NULL if it doesn't exist.     */
-  /*                                                                       */
   static
   TT_Byte*  Get_Advance_Widths( TT_Face    face,
                                 TT_UShort  ppem )
@@ -181,32 +127,16 @@
 
 
   /*************************************************************************/
-  /*                                                                       */
-  /* <Function>                                                            */
-  /*    translate_array                                                    */
-  /*                                                                       */
-  /* <Description>                                                         */
   /*    Translates an array of coordinates.                                */
   /*                                                                       */
-  /* <Input>                                                               */
-  /*    n       :: The number of points to translate.                      */
-  /*                                                                       */
-  /*    delta_x :: The horizontal coordinate of the shift vector.          */
-  /*                                                                       */
-  /*    delta_y :: The vertical coordinate of the shift vector.            */
-  /*                                                                       */
-  /* <InOut>                                                               */
-  /*    coords  :: The vector array to translate.                          */
-  /*                                                                       */
   static
-  void  translate_array( TT_UShort   n,
+  void  translate_array( TT_UInt     n,
                          TT_Vector*  coords,
                          TT_Pos      delta_x,
                          TT_Pos      delta_y )
   {
-    TT_UShort  k;
+    TT_UInt  k;
 
-
     if ( delta_x )
       for ( k = 0; k < n; k++ )
         coords[k].x += delta_x;
@@ -217,29 +147,18 @@
   }
 
 
+
   /*************************************************************************/
-  /*                                                                       */
-  /* <Function>                                                            */
-  /*    mount_zone                                                         */
-  /*                                                                       */
-  /* <Description>                                                         */
   /*    Mounts one glyph zone on top of another.  This is needed to        */
   /*    assemble composite glyphs.                                         */
   /*                                                                       */
-  /* <Input>                                                               */
-  /*    source :: The source glyph zone.                                   */
-  /*                                                                       */
-  /* <Output>                                                              */
-  /*    target :: The target glyph zone.                                   */
-  /*                                                                       */
   static
   void  mount_zone( TT_GlyphZone*  source,
                     TT_GlyphZone*  target )
   {
-    TT_UShort  np;
-    TT_Short   nc;
+    TT_UInt  np;
+    TT_Int   nc;
 
-
     np = source->n_points;
     nc = source->n_contours;
 
@@ -254,6 +173,9 @@
   }
 
 
+#undef  IS_HINTED
+#define IS_HINTED(flags)  ((flags & FT_LOAD_NO_HINTING) == 0)
+
   /*************************************************************************/
   /*                                                                       */
   /* <Function>                                                            */
@@ -265,35 +187,23 @@
   /*    glyphs elements will be loaded with routine.                       */
   /*                                                                       */
   static
-  TT_Error  Load_Simple_Glyph( TT_ExecContext   exec,
-                               FT_Stream        stream,
-                               TT_ULong         byte_count,
-                               TT_Short         n_contours,
-                               TT_Short         left_contours,
-                               TT_UShort        left_points,
-                               TT_UInt          load_flags,
-                               TT_SubGlyphRec*  subg,
-                               TT_Bool          debug )
+  TT_Error  Load_Simple( TT_Loader*       load,
+                         TT_UInt          byte_count,
+                         TT_Int           n_contours,
+                         TT_Bool          debug )
   {
     TT_Error       error;
-    TT_GlyphZone*  pts;
-    TT_Short       k;
-    TT_UShort      j;
-    TT_UShort      n_points, n_ins;
-    TT_Face        face;
-    TT_Byte*       flag;
-    TT_Vector*     vec;
-    TT_F26Dot6     x, y;
+    FT_Stream      stream = load->stream;
+    TT_GlyphZone*  zone   = &load->zone;
+    TT_Face        face = load->face;
 
-    TT_Vector      *pp1, *pp2;
+    TT_UShort      n_ins;
+    TT_Int         n, n_points;
         
-
-    face = exec->face;
-
     /*********************************************************************/
     /* simple check                                                      */
     
-    if ( n_contours > left_contours )
+    if ( n_contours > load->left_contours )
     {
       FT_TRACE0(( "ERROR: Glyph index %ld has %d contours > left %d\n",
                    subg->index,
@@ -303,9 +213,8 @@
     }
 
     /* preparing the execution context */
-    mount_zone( &subg->zone, &exec->pts );
+    mount_zone( &load->base, zone );
 
-
     /*********************************************************************/
     /* reading the contours endpoints                                    */
     
@@ -312,12 +221,12 @@
     if ( ACCESS_Frame( byte_count ) )
       return error;
 
-    for ( k = 0; k < n_contours; k++ )
-      exec->pts.contours[k] = GET_UShort();
+    for ( n = 0; n < n_contours; n++ )
+      zone->contours[n] = GET_UShort();
 
     n_points = 0;
     if ( n_contours > 0 )
-      n_points = exec->pts.contours[n_contours - 1] + 1;
+      n_points = zone->contours[n_contours - 1] + 1;
 
 
     /*********************************************************************/
@@ -325,7 +234,7 @@
     
     n_ins = GET_UShort();
 
-    if ( n_points > left_points )
+    if ( n_points > load->left_points )
     {
       FT_TRACE0(( "ERROR: Too many points in glyph %ld\n", subg->index ));
       error = TT_Err_Too_Many_Points;
@@ -347,34 +256,32 @@
       error = TT_Err_Too_Many_Ins;
       goto Fail;
     }
-    MEM_Copy( exec->glyphIns, stream->cursor, n_ins );
-    stream->cursor += n_ins;
 
-    error = TT_Set_CodeRange( exec, tt_coderange_glyph,
-                              exec->glyphIns, n_ins );
+#ifdef TT_CONFIG_OPTION_BYTECODE_INTERPRETER
+    MEM_Copy( load->exec->glyphIns, stream->cursor, n_ins );
+
+    error = TT_Set_CodeRange( load->exec, tt_coderange_glyph,
+                              load->exec->glyphIns, n_ins );
     if (error) goto Fail;
+#endif
 
+    stream->cursor += n_ins;
     
     /*********************************************************************/
     /* reading the point flags                                           */
-    
-    j    = 0;
-    flag = exec->pts.touch;
 
-    while ( j < n_points )
-    {
-      TT_Byte  c, cnt;
-
-      flag[j] = c = GET_Byte();
-      j++;
-
-      if ( c & 8 )
+    {    
+      TT_Byte*  flag  = load->zone.touch;
+      TT_Byte*  limit = flag + n_points;
+      TT_Byte   c, count;
+      
+      for (; flag < limit; flag++)
       {
-        cnt = GET_Byte();
-        while( cnt > 0 )
+        *flag = c = GET_Byte();
+        if ( c & 8 )
         {
-          flag[j++] = c;
-          cnt--;
+          for ( count = GET_Byte(); count > 0; count-- )
+            *++flag = c;
         }
       }
     }
@@ -382,49 +289,53 @@
     /*********************************************************************/
     /* reading the X coordinates                                         */
     
-    x    = 0;
-    vec  = exec->pts.org;
-
-    for ( j = 0; j < n_points; j++ )
     {
-      if ( flag[j] & 2 )
+      TT_Vector*  vec   = zone->org;
+      TT_Vector*  limit = vec + n_points;
+      TT_Byte*    flag  = zone->touch;
+      TT_Pos      x     = 0;
+      
+      for ( ; vec < limit; vec++, flag++ )
       {
-        if ( flag[j] & 16 )
-          x += GET_Byte();
-        else
-          x -= GET_Byte();
+        TT_Pos  y = 0;
+        
+        if ( *flag & 2 )
+        {
+          y = GET_Byte();
+          if ((*flag & 16) == 0) y = -y;
+        }
+        else if ((*flag & 16) == 0)
+          y = GET_Short();
+          
+        x     += y;
+        vec->x = x;
       }
-      else
-      {
-        if ( (flag[j] & 16) == 0 )
-          x += GET_Short();
-      }
-
-      vec[j].x = x;
     }
 
-
     /*********************************************************************/
     /* reading the YX coordinates                                         */
-    
-    y = 0;
 
-    for ( j = 0; j < n_points; j++ )
     {
-      if ( flag[j] & 4 )
+      TT_Vector*  vec   = zone->org;
+      TT_Vector*  limit = vec + n_points;
+      TT_Byte*    flag  = zone->touch;
+      TT_Pos      x     = 0;
+      
+      for ( ; vec < limit; vec++, flag++ )
       {
-        if ( flag[j] & 32 )
-          y += GET_Byte();
-        else
-          y -= GET_Byte();
+        TT_Pos  y = 0;
+        
+        if ( *flag & 4 )
+        {
+          y = GET_Byte();
+          if ((*flag & 32) == 0) y = -y;
+        }
+        else if ((*flag & 32) == 0)
+          y = GET_Short();
+          
+        x     += y;
+        vec->y = x;
       }
-      else
-      {
-        if ( (flag[j] & 32) == 0 )
-          y += GET_Short();
-      }
-
-      vec[j].y = y;
     }
 
     FORGET_Frame();
@@ -435,79 +346,93 @@
     /* Now add the two shadow points at n and n + 1.    */
     /* We need the left side bearing and advance width. */
 
-    /* pp1 = xMin - lsb */
-    pp1    = vec + n_points;
-    pp1->x = subg->bbox.xMin - subg->left_bearing;
-    pp1->y = 0;
-
-    /* pp2 = pp1 + aw */
-    pp2    = pp1 + 1;
-    pp2->x = pp1->x + subg->advance;
-    pp2->y = 0;
+    {
+      TT_Vector*  pp1;
+      TT_Vector*  pp2;
+      
+      /* pp1 = xMin - lsb */
+      pp1    = zone->org + n_points;
+      pp1->x = load->bbox.xMin - load->left_bearing;
+      pp1->y = 0;
+  
+      /* pp2 = pp1 + aw */
+      pp2    = pp1 + 1;
+      pp2->x = pp1->x + load->advance;
+      pp2->y = 0;
         
-    /* clear the touch flags */
-    for ( j = 0; j < n_points; j++ )
-      exec->pts.touch[j] &= FT_Curve_Tag_On;
+      /* clear the touch flags */
+      for ( n = 0; n < n_points; n++ )
+        zone->touch[n] &= FT_Curve_Tag_On;
 
-    exec->pts.touch[n_points    ] = 0;
-    exec->pts.touch[n_points + 1] = 0;
-
+      zone->touch[n_points    ] = 0;
+      zone->touch[n_points + 1] = 0;
+    }
     /* Note that we return two more points that are not */
     /* part of the glyph outline.                       */
 
-    n_points += 2;
+    zone->n_points   = n_points;
+    zone->n_contours = n_contours;
+    n_points        += 2;
 
+    /*******************************************/
     /* now eventually scale and hint the glyph */
 
-    pts = &exec->pts;
-    pts->n_points   = n_points;
-    pts->n_contours = n_contours;
-
-    if (load_flags & FT_LOAD_NO_SCALE)
+    if (load->load_flags & FT_LOAD_NO_SCALE)
     {
       /* no scaling, just copy the orig arrays into the cur ones */
-      org_to_cur( n_points, pts );
+      org_to_cur( n_points, zone );
     }
     else
     {
+      TT_Vector*  vec = zone->org;
+      TT_Vector*  limit = vec + n_points;
+      TT_Fixed    x_scale = load->size->root.metrics.x_scale;
+      TT_Fixed    y_scale = load->size->root.metrics.y_scale;
+
       /* first scale the glyph points */
-      for ( j = 0; j < n_points; j++ )
+      for (; vec < limit; vec++)
       {
-        pts->org[j].x = SCALE_X( pts->org[j].x );
-        pts->org[j].y = SCALE_Y( pts->org[j].y );
+        vec->x = FT_MulFix( vec->x, x_scale );
+        vec->y = FT_MulFix( vec->y, y_scale );
       }
 
       /* if hinting, round pp1, and shift the glyph accordingly */
-      if ( subg->is_hinted )
+      if ( !IS_HINTED(load->load_flags) )
       {
-        x = pts->org[n_points - 2].x;
+        org_to_cur( n_points, zone );
+      }
+      else
+      {
+        TT_Pos  x = zone->org[n_points-2].x;
         x = ((x + 32) & -64) - x;
-        translate_array( n_points, pts->org, x, 0 );
+        translate_array( n_points, zone->org, x, 0 );
 
-        org_to_cur( n_points, pts );
+        org_to_cur( n_points, zone );
 
-        pts->cur[n_points - 1].x = (pts->cur[n_points - 1].x + 32) & -64;
+        zone->cur[n_points-1].x = (zone->cur[n_points-1].x + 32) & -64;
 
+#ifdef TT_CONFIG_OPTION_BYTECODE_INTERPRETER
         /* now consider hinting */
         if ( n_ins > 0 )
         {
-          exec->is_composite     = FALSE;
-          exec->pedantic_hinting = load_flags & FT_LOAD_PEDANTIC;
+          load->exec->is_composite     = FALSE;
+          load->exec->pedantic_hinting = (TT_Bool)(load->load_flags & FT_LOAD_PEDANTIC);
+          load->exec->pts              = *zone;
+          load->exec->pts.n_points   += 2;
 
-          error = TT_Run_Context( exec, debug );
-          if ( error && exec->pedantic_hinting )
+          error = TT_Run_Context( load->exec, debug );
+          if ( error && load->exec->pedantic_hinting )
             return error;
         }
+#endif
       }
-      else
-        org_to_cur( n_points, pts );
     }
 
     /* save glyph phantom points */
-    if ( !subg->preserve_pps )
+    if ( !load->preserve_pps )
     {
-      subg->pp1 = pts->cur[n_points - 2];
-      subg->pp2 = pts->cur[n_points - 1];
+      load->pp1 = zone->cur[n_points - 2];
+      load->pp2 = zone->cur[n_points - 1];
     }
 
     return TT_Err_Ok;
@@ -518,683 +443,304 @@
   }
 
 
+
+
+
+
   /*************************************************************************/
   /*                                                                       */
   /* <Function>                                                            */
-  /*    Load_Composite_End                                                 */
+  /*    load_truetype_glyph                                                */
   /*                                                                       */
   /* <Description>                                                         */
-  /*    Finalizes the loading process of a composite glyph element.  This  */
-  /*    function is used for the `Load_End' state of TT_Load_Glyph().      */
+  /*    Loads a given truetype glyph. Handles composites and uses a        */
+  /*    TT_Loader object..                                                 */
   /*                                                                       */
   static
-  TT_Error  Load_Composite_End( TT_UShort        n_points,
-                                TT_Short         n_contours,
-                                TT_ExecContext   exec,
-                                TT_SubGlyphRec*  subg,
-                                FT_Stream        stream,
-                                TT_UInt          load_flags,
-                                TT_Bool          debug )
+  TT_Error  load_truetype_glyph( TT_Loader*  loader,
+                                 TT_UInt     glyph_index )
   {
-    TT_Error       error;
-
-    TT_UShort      k, n_ins;
-    TT_GlyphZone*  pts;
-
-    if ( subg->is_hinted                    &&
-         subg->element_flag & WE_HAVE_INSTR )
+    FT_Stream    stream = loader->stream;
+    TT_Error     error;
+    TT_Face      face   = loader->face;
+    TT_ULong     offset;
+    FT_SubGlyph  subglyphs[ TT_MAX_SUBGLYPHS ];
+    TT_Int       num_subglyphs = 0, contours_count;
+    TT_UInt      index, num_points, num_contours, count;
+    TT_Fixed     x_scale, y_scale;
+    TT_ULong     ins_offset;
+    
+    /* check glyph index */
+    index = (TT_UInt)glyph_index;
+    if ( index >= (TT_UInt)face->root.num_glyphs )
     {
-      if ( READ_UShort( n_ins ) )    /* read size of instructions */
-        return error;
-
-      FT_TRACE4(( "Instructions size = %d\n", n_ins ));
-
-      if ( n_ins > exec->face->max_profile.maxSizeOfInstructions )
-      {
-        FT_TRACE0(( "Too many instructions in composite glyph %ld\n",
-                  subg->index ));
-        return TT_Err_Too_Many_Ins;
-      }
-
-      if ( FILE_Read( exec->glyphIns, n_ins ) )
-        return error;
-
-      error = TT_Set_CodeRange( exec,
-                                tt_coderange_glyph,
-                                exec->glyphIns,
-                                n_ins );
-      if ( error )
-        return error;
+      error = TT_Err_Invalid_Glyph_Index;
+      goto Fail;
     }
-    else
-      n_ins = 0;
 
-
-    /* prepare the execution context */
-    n_points += 2;
-    exec->pts = subg->zone;
-    pts       = &exec->pts;
-
-    pts->n_points   = n_points;
-    pts->n_contours = n_contours;
-
-    /* add phantom points */
-    pts->cur[n_points - 2] = subg->pp1;
-    pts->cur[n_points - 1] = subg->pp2;
-
-    pts->touch[n_points - 1] = 0;
-    pts->touch[n_points - 2] = 0;
-
-    /* if hinting, round the phantom points */
-    if ( subg->is_hinted )
+    num_contours = 0;
+    num_points   = 0;
+    ins_offset   = 0;
+    
+    x_scale = 0x10000;
+    y_scale = 0x10000;
     {
-      pts->cur[n_points - 2].x = ((subg->pp1.x + 32) & -64);
-      pts->cur[n_points - 1].x = ((subg->pp2.x + 32) & -64);
+      x_scale = loader->size->root.metrics.x_scale;
+      y_scale = loader->size->root.metrics.y_scale;
     }
 
-    for ( k = 0; k < n_points; k++ )
-      pts->touch[k] &= FT_Curve_Tag_On;
-
-    cur_to_org( n_points, pts );
-
-    /* now consider hinting */
-    if ( subg->is_hinted && n_ins > 0 )
+    /* get horizontal metrics */
     {
-      exec->is_composite     = TRUE;
-      exec->pedantic_hinting = load_flags & FT_LOAD_PEDANTIC;
+      TT_Short   left_bearing;
+      TT_UShort  advance_width;
 
-      error = TT_Run_Context( exec, debug );
-      if ( error && exec->pedantic_hinting )
-        return error;
+      Get_HMetrics( face, index, TRUE,
+                    &left_bearing,
+                    &advance_width );
+
+      loader->left_bearing = left_bearing;
+      loader->advance      = advance_width;
     }
 
-    /* save glyph origin and advance points */
-    subg->pp1 = pts->cur[n_points - 2];
-    subg->pp2 = pts->cur[n_points - 1];
+    /* load glyph header */
+    offset = face->glyph_locations[index];
+    count  = 0;
+    if (index < (TT_UInt)face->num_locations-1)
+       count = face->glyph_locations[index+1] - offset;
+          
 
-    return TT_Err_Ok;
-  }
-
-
-  /*************************************************************************/
-  /*                                                                       */
-  /* <Function>                                                            */
-  /*    Init_Glyph_Component                                               */
-  /*                                                                       */
-  /* <Description>                                                         */
-  /*    Initializes a glyph component for further processing.              */
-  /*                                                                       */
-  static
-  void  Init_Glyph_Component( TT_SubGlyphRec*  element,
-                              TT_SubGlyphRec*  original,
-                              TT_ExecContext   exec )
-  {
-    element->index     = -1;
-    element->is_scaled = FALSE;
-    element->is_hinted = FALSE;
-
-    if ( original )
-      mount_zone( &original->zone, &element->zone );
-    else
-      element->zone = exec->pts;
-
-    element->zone.n_contours = 0;
-    element->zone.n_points   = 0;
-
-    element->arg1 = 0;
-    element->arg2 = 0;
-
-    element->element_flag = 0;
-    element->preserve_pps = FALSE;
-
-    element->transform.xx = 0x10000;
-    element->transform.xy = 0;
-    element->transform.yx = 0;
-    element->transform.yy = 0x10000;
-
-    element->transform.ox = 0;
-    element->transform.oy = 0;
-
-    element->left_bearing = 0;
-    element->advance      = 0;
-  }
-
-
-  /*************************************************************************/
-  /*                                                                       */
-  /* <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).                  */
-  /* <Output>                                                              */
-  /*    result      :: A set of bit flags indicating the type of data that */
-  /*                   was loaded in the glyph slot (outline or bitmap,    */
-  /*                   etc).                                               */
-  /*                                                                       */
-  /*                   You can set this field to 0 if you don't want this  */
-  /*                   information.                                        */
-  /*                                                                       */
-  /* <Return>                                                              */
-  /*    FreeType error code.  0 means success.                             */
-  /*                                                                       */
-  LOCAL_FUNC
-  TT_Error  TT_Load_Glyph( TT_Size       size,
-                           TT_GlyphSlot  glyph,
-                           TT_UShort     glyph_index,
-                           TT_UInt       load_flags )
-  {
-    typedef enum  TPhases_
+    if (count == 0)
     {
-      Load_Exit,
-      Load_Glyph,
-      Load_Header,
-      Load_Simple,
-      Load_Composite,
-      Load_End
+      /* as described by Frederic Loyer, these are spaces, and */
+      /* not the unknown glyph.                                */
+      loader->bbox.xMin = 0;
+      loader->bbox.xMax = 0;
+      loader->bbox.yMin = 0;
+      loader->bbox.yMax = 0;
 
-    } TPhases;
+      loader->pp1.x = 0;
+      loader->pp2.x = loader->advance;
 
-    TT_Error   error = 0;
-    FT_Stream  stream;
+      if ( (loader->load_flags & FT_LOAD_NO_SCALE)==0 )
+        loader->pp2.x = FT_MulFix( loader->pp2.x, x_scale );
 
-    TT_Face    face;
+#ifdef TT_CONFIG_OPTION_BYTECODE_INTERPRETER
+      loader->exec->glyphSize = 0;
+#endif
+      goto Load_End;
+    }
 
-    TT_UShort  num_points;
-    TT_Short   num_contours;
-    TT_UShort  left_points;
-    TT_Short   left_contours;
+    offset = loader->glyf_offset + offset;
 
-    TT_ULong   load_top;
-    TT_Long    k, l;
-    TT_Int     new_flags;
-    TT_UShort  index;
-    TT_UShort  u;
-    TT_Long    count;
+    /* read first glyph header */
+    if ( FILE_Seek( offset ) || ACCESS_Frame( 10L ) )
+      goto Fail;
 
-    TT_Long  glyph_offset, offset;
+    contours_count = GET_Short();
 
-    TT_F26Dot6  x, y, nx, ny;
+    loader->bbox.xMin = GET_Short();
+    loader->bbox.yMin = GET_Short();
+    loader->bbox.xMax = GET_Short();
+    loader->bbox.yMax = GET_Short();
 
-    TT_Fixed  xx, xy, yx, yy;
-    TT_BBox   bbox;
+    FORGET_Frame();
 
-    TT_ExecContext  exec;
+    FT_TRACE6(( "Glyph %ld\n", index ));
+    FT_TRACE6(( " # of contours : %d\n", num_contours ));
+    FT_TRACE6(( " xMin: %4d  xMax: %4d\n", loader->bbox.xMin,
+                                           loader->bbox.xMax ));
+    FT_TRACE6(( " yMin: %4d  yMax: %4d\n", loader->bbox.yMin,
+                                           loader->bbox.yMax ));
+    FT_TRACE6(( "-" ));
 
-    TT_SubGlyphRec *subglyph, *subglyph2;
+    count -= 10;
 
-    TT_GlyphZone base_pts;
-
-    TPhases   phase;
-    TT_Byte*  widths;
-    TT_Int    num_elem_points;
-
-    SFNT_Interface*  sfnt;
-    
-    /* first of all, check arguments */
-    if ( !glyph )
-      return TT_Err_Invalid_Glyph_Handle;
-
-    face = (TT_Face)glyph->face;
-    if ( !face )
-      return TT_Err_Invalid_Glyph_Handle;
-
-    sfnt   = (SFNT_Interface*)face->sfnt;
-    stream = face->root.stream;
-    count  = 0;
-    
-    if ( glyph_index >= face->root.num_glyphs )
-      return TT_Err_Invalid_Glyph_Index;
-
-    if ( !size || (load_flags & FT_LOAD_NO_SCALE) )
+    if ( contours_count > loader->left_contours )
     {
-      size        = NULL;
-      load_flags |= FT_LOAD_NO_SCALE   |
-                    FT_LOAD_NO_HINTING |
-                    FT_LOAD_NO_BITMAP;
+      FT_TRACE0(( "ERROR: Too many contours for glyph %ld\n", index ));
+      error = TT_Err_Too_Many_Contours;
+      goto Fail;
     }
 
-    /* Try to load embedded bitmap if any */
-    if ( size && (load_flags & FT_LOAD_NO_BITMAP) == 0 && sfnt->load_sbits )
+    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;
+    
+    if ((loader->load_flags & FT_LOAD_NO_SCALE)==0)
     {
-      TT_SBit_Metrics  metrics;
- 
-      error = sfnt->load_sbit_image( face,
-                                     size->root.metrics.x_ppem,
-                                     size->root.metrics.y_ppem,
-                                     glyph_index,
-                                     stream,
-                                     &glyph->bitmap,
-                                     &metrics );
-      if ( !error )
-      {
-        glyph->outline.n_points   = 0;
-        glyph->outline.n_contours = 0;
-
-        glyph->metrics.width  = (TT_Pos)metrics.width  << 6;
-        glyph->metrics.height = (TT_Pos)metrics.height << 6;
-
-        glyph->metrics.horiBearingX = (TT_Pos)metrics.horiBearingX << 6;
-        glyph->metrics.horiBearingY = (TT_Pos)metrics.horiBearingY << 6;
-        glyph->metrics.horiAdvance  = (TT_Pos)metrics.horiAdvance  << 6;
-
-        glyph->metrics.vertBearingX = (TT_Pos)metrics.vertBearingX << 6;
-        glyph->metrics.vertBearingY = (TT_Pos)metrics.vertBearingY << 6;
-        glyph->metrics.vertAdvance  = (TT_Pos)metrics.vertAdvance  << 6;
-
-        glyph->format = ft_glyph_format_bitmap;
-        return error;
-      }
+      loader->pp1.x = FT_MulFix( loader->pp1.x, x_scale );
+      loader->pp2.x = FT_MulFix( loader->pp2.x, x_scale );
     }
 
-    if ( load_flags & FT_LOAD_NO_OUTLINE )
-      return ( error ? error : TT_Err_Unavailable_Bitmap );
+    /*************************************************************************/
+    /*************************************************************************/
+    /*************************************************************************/
 
-    error = face->goto_table( face, TTAG_glyf, stream, 0 );
-    if (error)
+    /**********************************************************************/
+    /* if it is a simple glyph, load it                                   */
+    if (contours_count >= 0)
     {
-      FT_ERROR(( "TT.GLoad: could not access glyph table\n" ));
-      return error;
-    }
+      TT_UInt  num_base_points;
+      
+#ifdef TT_CONFIG_OPTION_BYTECODE_INTERPRETER
+      error = Load_Simple( loader,
+                           count,
+                           contours_count,
+                           (TT_Bool)( loader->size &&
+                                      loader->size->debug ) );
+#else
+      error = Load_Simple( loader, count, contours_count, 0 );
+#endif                                      
+      if ( error )
+        goto Fail;
 
-    glyph_offset = FILE_Pos();
+      /* Note: We could have put the simple loader source there */
+      /*       but the code is fat enough already :-)           */
+      num_points   = loader->zone.n_points;
+      num_contours = loader->zone.n_contours;
+      
+      num_base_points = loader->base.n_points;
+      {
+        TT_UInt  k;
+        for ( k = 0; k < num_contours; k++ )
+          loader->zone.contours[k] += num_base_points;
+      }
 
-    /* query new execution context */
+      loader->base.n_points   += num_points;
+      loader->base.n_contours += num_contours;
 
-    if ( size && size->debug )
-      exec = size->context;
-    else
-      exec = TT_New_Context( face );
+      loader->zone.n_points    = 0;
+      loader->zone.n_contours  = 0;
 
-    if ( !exec )
-      return TT_Err_Could_Not_Find_Context;
-
-    TT_Load_Context( exec, face, size );
-
-    if ( size )
-    {
-      /* load default graphics state - if needed */
-      if ( size->GS.instruct_control & 2 )
-        exec->GS = tt_default_graphics_state;
-
-      glyph->outline.high_precision = ( size->root.metrics.y_ppem < 24 );
+      loader->left_points   -= num_points;
+      loader->left_contours -= num_contours;
     }
+    /*************************************************************************/
+    /*************************************************************************/
+    /*************************************************************************/
 
-    /* save its critical pointers, as they'll be modified during load */
-    base_pts = exec->pts;
-
-    /* init variables */
-    left_points   = face->root.max_points;    /* remove phantom points */
-    left_contours = face->root.max_contours;
-
-    num_points   = 0;
-    num_contours = 0;
-
-    load_top = 0;
-    subglyph = exec->loadStack;
-
-    Init_Glyph_Component( subglyph, NULL, exec );
-
-    subglyph->index     = glyph_index;
-    subglyph->is_hinted = !(load_flags & FT_LOAD_NO_HINTING);
-
-    /* when the cvt program has disabled hinting, the argument */
-    /* is ignored.                                             */
-    if ( size && (size->GS.instruct_control & 1) )
-      subglyph->is_hinted = FALSE;
-
-    /* Main loading loop */
-
-    phase = Load_Glyph;
-    index = 0;
-
-    while ( phase != Load_Exit )
+    /************************************************************************/
+    else /* otherwise, load a composite !!                                  */
     {
-      subglyph = exec->loadStack + load_top;
-
-      switch ( phase )
+      /* for each subglyph, read composite header */
+      FT_SubGlyph*  subglyph = subglyphs;
+      
+      if (ACCESS_Frame(count)) goto Fail;
+      
+      num_subglyphs = 0;
+      do
       {
-
-        /************************************************************/
-        /*                                                          */
-        /* Load_Glyph state                                         */
-        /*                                                          */
-        /*   reading a glyph's generic data, checking whether the   */
-        /*   glyph is cached already (not implemented yet)          */
-        /*                                                          */
-        /* exit states: Load_Header and Load_End                    */
-        /*                                                          */
-      case Load_Glyph:
-        /* check glyph index and table */
-
-        index = (TT_UInt)subglyph->index;
-        if ( index >= face->root.num_glyphs )
-        {
-          error = TT_Err_Invalid_Glyph_Index;
-          goto Fail;
-        }
-
-        /* get horizontal metrics */
-        {
-          TT_Short   left_bearing;
-          TT_UShort  advance_width;
-
-          Get_HMetrics( face, index, TRUE,
-                        &left_bearing,
-                        &advance_width );
-
-          subglyph->left_bearing = left_bearing;
-          subglyph->advance      = advance_width;
-        }
-
-        phase = Load_Header;
-
-        /************************************************************/
-        /*                                                          */
-        /* Load_Header state                                        */
-        /*                                                          */
-        /*   reading a glyph's generic header to determine whether  */
-        /*   it is a simple or composite glyph                      */
-        /*                                                          */
-        /* exit states: Load_Simple and Load_Composite              */
-        /*                                                          */
-      case Load_Header:
-        /* load glyph */
-
-        offset = face->glyph_locations[index];
-        count  = 0;
-        if (index < face->num_locations-1)
-          count = face->glyph_locations[index+1] - offset;
-          
-        if (count == 0)
-        {
-          /* as described by Frederic Loyer, these are spaces, and */
-          /* not the unknown glyph.                                */
-
-          num_contours = 0;
-          num_points   = 0;
-
-          subglyph->bbox.xMin = 0;
-          subglyph->bbox.xMax = 0;
-          subglyph->bbox.yMin = 0;
-          subglyph->bbox.yMax = 0;
-
-          subglyph->pp1.x = 0;
-          subglyph->pp2.x = subglyph->advance;
-
-          if ( !(load_flags & FT_LOAD_NO_SCALE) )
-            subglyph->pp2.x = SCALE_X( subglyph->pp2.x );
-
-          exec->glyphSize = 0;
-          phase = Load_End;
-          break;
-        }
-
-        offset = glyph_offset + offset;
-
-        /* read first glyph header */
-        if ( FILE_Seek( offset ) ||
-             ACCESS_Frame( 10L ) )
-          goto Fail_File;
-
-        num_contours = GET_Short();
-
-        subglyph->bbox.xMin = GET_Short();
-        subglyph->bbox.yMin = GET_Short();
-        subglyph->bbox.xMax = GET_Short();
-        subglyph->bbox.yMax = GET_Short();
-
-        FORGET_Frame();
-
-        FT_TRACE6(( "Glyph %ld\n", index ));
-        FT_TRACE6(( " # of contours : %d\n", num_contours ));
-        FT_TRACE6(( " xMin: %4d  xMax: %4d\n",
-                     subglyph->bbox.xMin,
-                     subglyph->bbox.xMax ));
-        FT_TRACE6(( " yMin: %4d  yMax: %4d\n",
-                     subglyph->bbox.yMin,
-                     subglyph->bbox.yMax ));
-        FT_TRACE6(( "-" ));
-
-        count -= 10;
-
-        if ( num_contours > left_contours )
-        {
-          FT_TRACE0(( "ERROR: Too many contours for glyph %ld\n", index ));
-          error = TT_Err_Too_Many_Contours;
-          goto Fail;
-        }
-
-        subglyph->pp1.x = subglyph->bbox.xMin - subglyph->left_bearing;
-        subglyph->pp1.y = 0;
-        subglyph->pp2.x = subglyph->pp1.x + subglyph->advance;
-        if (!(load_flags & FT_LOAD_NO_SCALE))
-        {
-          subglyph->pp1.x = SCALE_X( subglyph->pp1.x );
-          subglyph->pp2.x = SCALE_X( subglyph->pp2.x );
-        }
-
-        /* is it a simple glyph ? */
-        if ( num_contours < 0 )
-        {
-          phase = Load_Composite;
-          break;
-        }
-
-        phase = Load_Simple;
+        TT_Fixed  xx, xy, yy, yx;
         
-        /************************************************************/
-        /*                                                          */
-        /* Load_Simple state                                        */
-        /*                                                          */
-        /*   reading a simple glyph (num_contours must be set to    */
-        /*   the glyph's number of contours.)                       */
-        /*                                                          */
-        /* exit state: Load_End                                     */
-        /*                                                          */
-      case Load_Simple:
-        new_flags = load_flags;
+        subglyph->arg1 = subglyph->arg2 = 0;
+        
+        subglyph->flags = GET_UShort();
+        subglyph->index = GET_UShort();
 
-        /* disable hinting when scaling */
-        if ( !subglyph->is_hinted )
-          new_flags |= FT_LOAD_NO_HINTING;
-
-        error = Load_Simple_Glyph( exec,
-                                   stream,
-                                   count,
-                                   num_contours,
-                                   left_contours,
-                                   left_points,
-                                   new_flags,
-                                   subglyph,
-                                   (TT_Bool)(size && size->debug &&
-                                             load_top == 0) );
-        if ( error )
-          goto Fail;
-
-        /* Note: We could have put the simple loader source there */
-        /*       but the code is fat enough already :-)           */
-
-        num_points = exec->pts.n_points - 2;
-
-        phase = Load_End;
-        break;
-
-        /************************************************************/
-        /*                                                          */
-        /* Load_Composite state                                     */
-        /*                                                          */
-        /*   reading a composite glyph header and pushing a new     */
-        /*   load element on the stack.                             */
-        /*                                                          */
-        /* exit state: Load_Glyph                                  */
-        /*                                                          */
-      case Load_Composite:
-
-        /* create a new element on the stack */
-        load_top++;
-
-        if ( load_top > face->max_components )
+        /* read arguments */
+        if (subglyph->flags & ARGS_ARE_WORDS)
         {
-          error = TT_Err_Invalid_Composite;
-          goto Fail;
+          subglyph->arg1 = GET_Short();
+          subglyph->arg2 = GET_Short();
         }
-
-        subglyph2 = exec->loadStack + load_top;
-
-        Init_Glyph_Component( subglyph2, subglyph, NULL );
-        subglyph2->is_hinted = subglyph->is_hinted;
-
-        /* now read composite header */
-
-        if ( ACCESS_Frame( 4L ) )
-          goto Fail_File;
-
-        subglyph->element_flag = new_flags = GET_UShort();
-
-        subglyph2->index = GET_UShort();
-
-        FORGET_Frame();
-
-        k = 1+1;
-
-        if ( new_flags & ARGS_ARE_WORDS )
-          k *= 2;
-
-        if ( new_flags & WE_HAVE_A_SCALE )
-          k += 2;
-
-        else if ( new_flags & WE_HAVE_AN_XY_SCALE )
-          k += 4;
-
-        else if ( new_flags & WE_HAVE_A_2X2 )
-          k += 8;
-
-        if ( ACCESS_Frame( k ) )
-          goto Fail_File;
-
-        if ( new_flags & ARGS_ARE_WORDS )
-        {
-          k = GET_Short();
-          l = GET_Short();
-        }
         else
         {
-          k = GET_Char();
-          l = GET_Char();
+          subglyph->arg1 = GET_Char();
+          subglyph->arg2 = GET_Char();
         }
-
-        subglyph->arg1 = k;
-        subglyph->arg2 = l;
-
-        if ( new_flags & ARGS_ARE_XY_VALUES )
+        
+        /* read transform */
+        xx = yy = 0x10000;
+        xy = yx = 0;
+        
+        if (subglyph->flags & WE_HAVE_A_SCALE)
         {
-          subglyph->transform.ox = k;
-          subglyph->transform.oy = l;
-        }
-
-        xx = 0x10000;
-        xy = 0;
-        yx = 0;
-        yy = 0x10000;
-
-        if ( new_flags & WE_HAVE_A_SCALE )
-        {
           xx = (TT_Fixed)GET_Short() << 2;
           yy = xx;
-          subglyph2->is_scaled = TRUE;
         }
-        else if ( new_flags & WE_HAVE_AN_XY_SCALE )
+        else if (subglyph->flags & WE_HAVE_AN_XY_SCALE)
         {
           xx = (TT_Fixed)GET_Short() << 2;
           yy = (TT_Fixed)GET_Short() << 2;
-          subglyph2->is_scaled = TRUE;
         }
-        else if ( new_flags & WE_HAVE_A_2X2 )
+        else if (subglyph->flags & WE_HAVE_A_2X2)
         {
           xx = (TT_Fixed)GET_Short() << 2;
           xy = (TT_Fixed)GET_Short() << 2;
           yx = (TT_Fixed)GET_Short() << 2;
           yy = (TT_Fixed)GET_Short() << 2;
-          subglyph2->is_scaled = TRUE;
         }
-
-        FORGET_Frame();
-
+        
         subglyph->transform.xx = xx;
         subglyph->transform.xy = xy;
         subglyph->transform.yx = yx;
         subglyph->transform.yy = yy;
+        
+        subglyph++;
+        num_subglyphs++;
+        if (num_subglyphs >= TT_MAX_SUBGLYPHS)
+          break;
+      }
+      while (subglyph[-1].flags & MORE_COMPONENTS);
 
-        k = FT_MulFix( xx, yy ) -  FT_MulFix( xy, yx );
+#ifdef TT_CONFIG_OPTION_BYTECODE_INTERPRETER
+      {
+        /* we must undo the ACCESS_Frame in order to point to the */
+        /* composite instructions, if we find some ..             */
+        /* we will process them later..                           */
+        ins_offset = FILE_Pos() + stream->cursor - stream->limit;
+        FORGET_Frame();
+      }
+#endif
 
-        /* disable hinting in case of scaling/slanting */
-        if ( ABS( k ) != 0x10000 )
-          subglyph2->is_hinted = FALSE;
+    /*************************************************************************/
+    /*************************************************************************/
+    /*************************************************************************/
 
-        subglyph->file_offset = FILE_Pos();
-
-        phase = Load_Glyph;
-        break;
-
-        /************************************************************/
-        /*                                                          */
-        /* Load_End state                                           */
-        /*                                                          */
-        /*   after loading a glyph, apply transformation and offset */
-        /*   where necessary, pop element and continue or stop      */
-        /*   process.                                               */
-        /*                                                          */
-        /* exit states: Load_Composite and Load_Exit                */
-        /*                                                          */
-      case Load_End:
-        if ( load_top > 0 )
+      /*********************************************************************/
+      /* Now, read each subglyph independently..                           */
+      {
+        TT_Int  n, num_base_points, num_new_points;
+        
+        subglyph = subglyphs;
+        for ( n = 0; n < num_subglyphs; n++, subglyph++ )
         {
-          subglyph2 = subglyph;
+          TT_Vector  pp1, pp2;
+          TT_Pos     x, y;
+          
+          pp1 = loader->pp1;
+          pp2 = loader->pp2;
 
-          load_top--;
-          subglyph = exec->loadStack + load_top;
-
-          /* check advance width and left side bearing */
-
-          if ( !subglyph->preserve_pps &&
-               subglyph->element_flag & USE_MY_METRICS )
+          num_base_points = loader->base.n_points;
+          
+          error = load_truetype_glyph( loader, subglyph->index );
+          if ((subglyph->flags & USE_MY_METRICS) == 0)
           {
-            subglyph->left_bearing = subglyph2->left_bearing;
-            subglyph->advance      = subglyph2->advance;
-
-            subglyph->pp1 = subglyph2->pp1;
-            subglyph->pp2 = subglyph2->pp2;
-
-            subglyph->preserve_pps = TRUE;
+            loader->pp1 = pp1;
+            loader->pp2 = pp2;
           }
-
-          /* apply scale */
-
-          if ( subglyph2->is_scaled )
+          
+          num_points   = loader->base.n_points;
+          num_contours = loader->base.n_contours;
+          
+          num_new_points = num_points - num_base_points;
+          
+          /********************************************************/
+          /* now perform the transform required for this subglyph */
+          
+          if ( subglyph->flags & ( WE_HAVE_A_SCALE     |
+                                   WE_HAVE_AN_XY_SCALE |
+                                   WE_HAVE_A_2X2       ) )
           {
-            TT_Vector*  cur = subglyph2->zone.cur;
-            TT_Vector*  org = subglyph2->zone.org;
+            TT_Vector*  cur = loader->zone.cur;
+            TT_Vector*  org = loader->zone.org;
+            TT_Vector*  limit = cur + num_new_points;
 
-
-            for ( u = 0; u < num_points; u++ )
+            for ( ; cur < limit; cur++, org++ )
             {
+              TT_Pos  nx, ny;
+              
               nx = FT_MulFix( cur->x, subglyph->transform.xx ) +
                    FT_MulFix( cur->y, subglyph->transform.yx );
 
@@ -1212,55 +758,39 @@
 
               org->x = nx;
               org->y = ny;
-
-              cur++;
-              org++;
             }
           }
 
-          /* adjust counts */
-
-          num_elem_points = subglyph->zone.n_points;
-          
-          for ( k = 0; k < num_contours; k++ )
-            subglyph2->zone.contours[k] += num_elem_points;
-
-          subglyph->zone.n_points   += num_points;
-          subglyph->zone.n_contours += num_contours;
-
-          left_points   -= num_points;
-          left_contours -= num_contours;
-
           /* apply offset */
 
-          if ( !(subglyph->element_flag & ARGS_ARE_XY_VALUES) )
+          if ( !(subglyph->flags & ARGS_ARE_XY_VALUES) )
           {
-            k = subglyph->arg1;
-            l = subglyph->arg2;
+            TT_Int   k = subglyph->arg1;
+            TT_UInt  l = subglyph->arg2;
 
-            if ( k >= num_elem_points ||
-                 l >= num_points )
+            if ( k >= num_base_points ||
+                 l >= (TT_UInt)num_new_points  )
             {
               error = TT_Err_Invalid_Composite;
               goto Fail;
             }
 
-            l += num_elem_points; 
+            l += num_base_points; 
 	    
-            x = subglyph->zone.cur[k].x - subglyph->zone.cur[l].x;
-            y = subglyph->zone.cur[k].y - subglyph->zone.cur[l].y;
+            x = loader->base.cur[k].x - loader->base.cur[l].x;
+            y = loader->base.cur[k].y - loader->base.cur[l].y;
           }
           else
           {
-            x = subglyph->transform.ox;
-            y = subglyph->transform.oy;
+            x = subglyph->arg1;
+            y = subglyph->arg2;
 
-            if (!(load_flags & FT_LOAD_NO_SCALE))
+            if (!(loader->load_flags & FT_LOAD_NO_SCALE))
             {
-              x = SCALE_X( x );
-              y = SCALE_Y( y );
+              x = FT_MulFix( x, x_scale );
+              y = FT_MulFix( y, y_scale );
               
-              if ( subglyph->element_flag & ROUND_XY_TO_GRID )
+              if ( subglyph->flags & ROUND_XY_TO_GRID )
 	          {
 	            x = (x + 32) & -64;
 	            y = (y + 32) & -64;
@@ -1268,58 +798,157 @@
             }
           }
 
-          translate_array( num_points, subglyph2->zone.cur, x, y );
+          translate_array( num_new_points, loader->zone.cur, x, y );
+          cur_to_org( num_new_points, &loader->zone );
+        }
+        
+    /*************************************************************************/
+    /*************************************************************************/
+    /*************************************************************************/
 
-          cur_to_org( num_points, &subglyph2->zone );
+        /* we have finished loading all sub-glyphs, now, look for */
+        /* instructions for this composite !!                     */
 
-          num_points   = subglyph->zone.n_points;
-          num_contours = subglyph->zone.n_contours;
-
-          /* check for last component */
-
-          if ( FILE_Seek( subglyph->file_offset ) )
-            goto Fail_File;
-
-          if ( subglyph->element_flag & MORE_COMPONENTS )
-            phase = Load_Composite;
-          else
+#ifdef TT_CONFIG_OPTION_BYTECODE_INTERPRETER
+        subglyph--;
+        if (num_subglyphs > 0 && subglyph->flags & WE_HAVE_INSTR)
+        {
+          TT_UShort       n_ins;
+          TT_ExecContext  exec = loader->exec;
+          TT_UInt         n_points = loader->base.n_points;
+          TT_GlyphZone*   pts;
+          TT_Vector*      pp1;
+          
+          /* read size of instructions */
+          if ( FILE_Seek( ins_offset ) ||
+               READ_UShort(n_ins)      ) goto Fail;
+          FT_TRACE4(( "Instructions size = %d\n", n_ins ));
+    
+          /* check it */
+          if ( n_ins > face->max_profile.maxSizeOfInstructions )
           {
-            error = Load_Composite_End( num_points,
-                                        num_contours,
-                                        exec,
-                                        subglyph,
-                                        stream,
-                                        load_flags,
-                                        (TT_Bool)(size && size->debug &&
-                                                  load_top == 0) );
-            if ( error )
+            FT_TRACE0(( "Too many instructions in composite glyph %ld\n",
+                        subglyph->index ));
+            return TT_Err_Too_Many_Ins;
+          }
+     
+          /* read the instructions */
+          if ( FILE_Read( exec->glyphIns, n_ins ) )
+            goto Fail;
+    
+          error = TT_Set_CodeRange( exec,
+                                    tt_coderange_glyph,
+                                    exec->glyphIns,
+                                    n_ins );
+          if ( error ) goto Fail;
+          
+          /* prepare the execution context */
+          exec->pts   = loader->base;
+          pts         = &exec->pts;
+      
+          pts->n_points   = num_points + 2;
+          pts->n_contours = num_contours;
+      
+          /* add phantom points */
+          pp1    = pts->cur + num_points;
+          pp1[0] = loader->pp1;
+          pp1[1] = loader->pp2;
+      
+          pts->touch[num_points - 1] = 0;
+          pts->touch[num_points - 2] = 0;
+      
+          /* if hinting, round the phantom points */
+          if ( IS_HINTED(loader->load_flags) )
+          {
+            pp1[0].x = ((loader->pp1.x + 32) & -64);
+            pp1[1].x = ((loader->pp2.x + 32) & -64);
+          }
+      
+          {
+            TT_UInt  k;
+            for ( k = 0; k < n_points; k++ )
+              pts->touch[k] &= FT_Curve_Tag_On;
+          }
+      
+          cur_to_org( n_points, pts );
+      
+          /* now consider hinting */
+          if ( IS_HINTED(loader->load_flags) && n_ins > 0 )
+          {
+            exec->is_composite     = TRUE;
+            exec->pedantic_hinting =
+                (TT_Bool)(loader->load_flags & FT_LOAD_PEDANTIC);
+      
+            error = TT_Run_Context( exec, loader->size->debug );
+            if ( error && exec->pedantic_hinting )
               goto Fail;
-
-            phase = Load_End;
           }
+          
+          /* save glyph origin and advance points */
+          loader->pp1 = pp1[0];
+          loader->pp2 = pp1[1];
         }
-        else
-          phase = Load_Exit;
-
-        break;
-
-      case Load_Exit:
-        break;
+#endif
+          
       }
     }
 
-    /* finally, copy the points arrays to the glyph object */
+    /*************************************************************************/
+    /*************************************************************************/
+    /*************************************************************************/
+    /*************************************************************************/
 
-    exec->pts = base_pts;
+  Load_End:
+    error = TT_Err_Ok;
 
-    for ( u = 0; u < num_points + 2; u++ )
+  Fail:
+    return error;    
+  }
+
+
+
+
+
+  static
+  void  compute_glyph_metrics( TT_Loader*    loader,
+                               TT_UInt       glyph_index )
+  {
+    TT_UInt       num_points   = loader->base.n_points;
+    TT_UInt       num_contours = loader->base.n_contours;
+    TT_BBox       bbox;
+    TT_Face       face = loader->face;
+    TT_Fixed      x_scale, y_scale;
+    TT_GlyphSlot  glyph = loader->glyph;
+    TT_Size       size = loader->size;
+    
+    /* when a simple glyph was loaded, the value of        */
+    /* "base.n_points" and "base.n_contours" is 0, we must */
+    /* take those in the "zone" instead..                  */
+    if ( num_points == 0 && num_contours == 0 )
     {
-      glyph->outline.points[u] = exec->pts.cur[u];
-      glyph->outline.flags [u] = exec->pts.touch[u];
+      num_points   = loader->zone.n_points;
+      num_contours = loader->zone.n_contours;
     }
+    
+    x_scale = 0x10000;
+    y_scale = 0x10000;
+    if ( (loader->load_flags & FT_LOAD_NO_SCALE) == 0)
+    {
+      x_scale = size->root.metrics.x_scale;
+      y_scale = size->root.metrics.y_scale;
+    }
+    
+    {
+      TT_UInt  u;
+      for ( u = 0; u < num_points + 2; u++ )
+      {
+        glyph->outline.points[u] = loader->base.cur[u];
+        glyph->outline.flags [u] = loader->base.touch[u];
+      }
 
-    for ( k = 0; k < num_contours; k++ )
-      glyph->outline.contours[k] = exec->pts.contours[k];
+      for ( u = 0; u < num_contours; u++ )
+        glyph->outline.contours[u] = loader->base.contours[u];
+    }
 
     glyph->outline.n_points    = num_points;
     glyph->outline.n_contours  = num_contours;
@@ -1328,12 +957,12 @@
     /* translate array so that (0,0) is the glyph's origin */
     translate_array( (TT_UShort)(num_points + 2),
                      glyph->outline.points,
-                     -subglyph->pp1.x,
+                     -loader->pp1.x,
                      0 );
 
     FT_Get_Outline_CBox( &glyph->outline, &bbox );
 
-    if ( subglyph->is_hinted )
+    if ( IS_HINTED(loader->load_flags) )
     {
       /* grid-fit the bounding box */
       bbox.xMin &= -64;
@@ -1348,17 +977,16 @@
       TT_Pos  left_bearing;
       TT_Pos  advance;
 
+      left_bearing = loader->left_bearing;
+      advance      = loader->advance;
 
-      left_bearing = subglyph->left_bearing;
-      advance      = subglyph->advance;
-
       if ( face->postscript.isFixedPitch )
         advance = face->horizontal.advance_Width_Max;
 
-      if ( !(load_flags & FT_LOAD_NO_SCALE) )
+      if ( !(loader->load_flags & FT_LOAD_NO_SCALE) )
       {
-        left_bearing = SCALE_X( left_bearing );
-        advance      = SCALE_X( advance );
+        left_bearing = FT_MulFix( left_bearing, x_scale );
+        advance      = FT_MulFix( advance, x_scale );
       }
 
       glyph->metrics2.horiBearingX = left_bearing;
@@ -1367,7 +995,7 @@
 
     glyph->metrics.horiBearingX = bbox.xMin;
     glyph->metrics.horiBearingY = bbox.yMax;
-    glyph->metrics.horiAdvance  = subglyph->pp2.x - subglyph->pp1.x;
+    glyph->metrics.horiAdvance  = loader->pp2.x - loader->pp1.x;
 
     /* Now take care of vertical metrics.  In the case where there is    */
     /* no vertical information within the font (relatively common), make */
@@ -1430,16 +1058,17 @@
          TT_Get_Outline_BBox()                                            */
 
       /* scale the metrics */
-      if ( !(load_flags & FT_LOAD_NO_SCALE) )
+      if ( !(loader->load_flags & FT_LOAD_NO_SCALE) )
       {
-        Top     = SCALE_Y( top_bearing );
-        top     = SCALE_Y( top_bearing + subglyph->bbox.yMax ) - bbox.yMax;
-        advance = SCALE_Y( advance_height );
+        Top     = FT_MulFix( top_bearing, y_scale );
+        top     = FT_MulFix( top_bearing + loader->bbox.yMax, y_scale )
+                    - bbox.yMax;
+        advance = FT_MulFix( advance_height, y_scale );
       }
       else
       {
         Top     = top_bearing;
-        top     = top_bearing + subglyph->bbox.yMax - bbox.yMax;
+        top     = top_bearing + loader->bbox.yMax - bbox.yMax;
         advance = advance_height;
       }
 
@@ -1452,7 +1081,7 @@
       left = ( bbox.xMin - bbox.xMax ) / 2;
 
       /* grid-fit them if necessary */
-      if ( subglyph->is_hinted )
+      if ( IS_HINTED(loader->load_flags) )
       {
         left   &= -64;
         top     = (top + 63) & -64;
@@ -1465,16 +1094,20 @@
     }
 
     /* Adjust advance width to the value contained in the hdmx table. */
-    if ( !exec->face->postscript.isFixedPitch && size &&
-         subglyph->is_hinted )
+    if ( !face->postscript.isFixedPitch && size &&
+         IS_HINTED(loader->load_flags) )
     {
-      widths = Get_Advance_Widths( exec->face,
-                                   exec->size->root.metrics.x_ppem );
+      TT_Byte* widths = Get_Advance_Widths( face,
+                                   size->root.metrics.x_ppem );
       if ( widths )
         glyph->metrics.horiAdvance = widths[glyph_index] << 6;
     }
 
-    glyph->outline.dropout_mode = (TT_Char)exec->GS.scan_type;
+#ifdef TT_CONFIG_OPTION_BYTECODE_INTERPRETER
+    glyph->outline.dropout_mode = (TT_Char)loader->exec->GS.scan_type;
+#else
+    glyph->outline.dropout_mode = 2;
+#endif
 
     /* set glyph dimensions */
     glyph->metrics.width  = bbox.xMax - bbox.xMin;
@@ -1481,20 +1114,178 @@
     glyph->metrics.height = bbox.yMax - bbox.yMin;
 
     glyph->format = ft_glyph_format_outline;
+  }
 
-    error = TT_Err_Ok;
 
-  Fail_File:
-  Fail:
 
-    /* reset the execution context */
-    exec->pts = base_pts;
 
+
+
+
+
+
+
+
+
+  LOCAL_FUNC
+  TT_Error  TT_Load_Glyph( TT_Size       size,
+                           TT_GlyphSlot  glyph,
+                           TT_UShort     glyph_index,
+                           TT_UInt       load_flags )
+  {
+    SFNT_Interface*  sfnt;
+    TT_Face          face;
+    FT_Stream        stream;
+    FT_Memory        memory;
+    TT_Error         error;
+    TT_Loader        loader;
+    
+    face   = (TT_Face)glyph->face;
+    sfnt   = (SFNT_Interface*)face->sfnt;
+    stream = face->root.stream;
+    memory = face->root.memory;
+    error  = 0;
+    
+    if ( !size || (load_flags & FT_LOAD_NO_SCALE) )
+    {
+      size        = NULL;
+      load_flags |= FT_LOAD_NO_SCALE   |
+                    FT_LOAD_NO_HINTING |
+                    FT_LOAD_NO_BITMAP;
+    }
+
+#ifdef TT_CONFIG_OPTION_EMBEDDED_BITMAPS
+    /*********************************************************************/
+    /* Try to load embedded bitmap if any                                */
+    if ( size && (load_flags & FT_LOAD_NO_BITMAP) == 0 && sfnt->load_sbits )
+    {
+      TT_SBit_Metrics  metrics;
+ 
+      error = sfnt->load_sbit_image( face,
+                                     size->root.metrics.x_ppem,
+                                     size->root.metrics.y_ppem,
+                                     glyph_index,
+                                     stream,
+                                     &glyph->bitmap,
+                                     &metrics );
+      if ( !error )
+      {
+        glyph->outline.n_points   = 0;
+        glyph->outline.n_contours = 0;
+
+        glyph->metrics.width  = (TT_Pos)metrics.width  << 6;
+        glyph->metrics.height = (TT_Pos)metrics.height << 6;
+
+        glyph->metrics.horiBearingX = (TT_Pos)metrics.horiBearingX << 6;
+        glyph->metrics.horiBearingY = (TT_Pos)metrics.horiBearingY << 6;
+        glyph->metrics.horiAdvance  = (TT_Pos)metrics.horiAdvance  << 6;
+
+        glyph->metrics.vertBearingX = (TT_Pos)metrics.vertBearingX << 6;
+        glyph->metrics.vertBearingY = (TT_Pos)metrics.vertBearingY << 6;
+        glyph->metrics.vertAdvance  = (TT_Pos)metrics.vertAdvance  << 6;
+
+        glyph->format = ft_glyph_format_bitmap;
+        return error;
+      }
+    }
+#endif /* TT_CONFIG_OPTION_EMBEDDED_BITMAPS */
+
+    if ( load_flags & FT_LOAD_NO_OUTLINE )
+      return ( error ? error : TT_Err_Unavailable_Bitmap );
+
+   /* seek to the beginning of the glyph table. For Type 43 fonts       */
+   /* the table might be accessed from a Postscript stream or something */
+   /* else...                                                           */
+    error = face->goto_table( face, TTAG_glyf, stream, 0 );
+    if (error)
+    {
+      FT_ERROR(( "TT.GLoad: could not access glyph table\n" ));
+      return error;
+    }
+
+    MEM_Set( &loader, 0, sizeof(loader) );
+
+#ifdef TT_CONFIG_OPTION_BYTECODE_INTERPRETER
+    if ( size )
+    {
+      /* query new execution context */
+      loader.exec = size->debug ? size->context : TT_New_Context(face);
+      if ( !loader.exec )
+        return TT_Err_Could_Not_Find_Context;
+        
+      TT_Load_Context( loader.exec, face, size );
+
+      /* load default graphics state - if needed */
+      if ( size->GS.instruct_control & 2 )
+        loader.exec->GS = tt_default_graphics_state;
+    }
+#endif /* TT_CONFIG_OPTION_BYTECODE_INTERPRETER */
+
+    if (size)
+      glyph->outline.high_precision = ( size->root.metrics.y_ppem < 24 );
+
+    /************************************************************************/
+    /* let's initialise our loader now                                      */
+    error = TT_New_GlyphZone( memory, &loader.base,
+                              face->root.max_points, face->root.max_contours );
+    if (error) return error;
+
+    loader.left_points   = face->root.max_points;
+    loader.left_contours = face->root.max_contours;
+    loader.load_flags    = load_flags;
+
+    loader.face   = face;
+    loader.size   = size;
+    loader.glyph  = glyph;
+    loader.stream = stream;
+    
+    loader.glyf_offset = FILE_Pos();
+
+#ifdef TT_CONFIG_OPTION_BYTECODE_INTERPRETER
+    /* when the cvt program has disabled hinting, the argument */
+    /* is ignored.                                             */
+    if ( size && (size->GS.instruct_control & 1) )
+      loader.load_flags |= FT_LOAD_NO_HINTING;
+#endif
+
+    /* Main loading loop */
+    error = load_truetype_glyph( &loader, glyph_index );
+    if (!error)
+      compute_glyph_metrics( &loader, glyph_index );
+
+#ifdef TT_CONFIG_OPTION_BYTECODE_INTERPRETER
     if ( !size || !size->debug )
-      TT_Done_Context( exec );
+      TT_Done_Context( loader.exec );
+#endif
 
+    TT_Done_GlyphZone( memory, &loader.base );
     return error;
   }
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
 
 
 /* END */
--- a/src/truetype/ttgload.h
+++ b/src/truetype/ttgload.h
@@ -21,11 +21,48 @@
 
 #include <ttobjs.h>
 
+#ifdef TT_CONFIG_OPTION_BYTECODE_INTERPRETER
+#include <ttinterp.h>
+#endif
+
 #ifdef __cplusplus
   extern "C" {
 #endif
 
+  typedef struct TT_Loader_
+  {
+    TT_Face         face;
+    TT_Size         size;
+    TT_GlyphSlot    glyph;
 
+    TT_ULong        load_flags;
+
+    FT_Stream       stream;
+    TT_Int          byte_len;
+    TT_Int          left_points;
+    TT_Int          left_contours;
+
+    TT_BBox         bbox;
+    TT_Int          left_bearing;
+    TT_Int          advance;
+    TT_Bool         preserve_pps;
+    TT_Vector       pp1;
+    TT_Vector       pp2;
+        
+    TT_ULong        glyf_offset;
+        
+    /* the zone where we load our glyphs */
+    TT_GlyphZone    base;
+    TT_GlyphZone    zone;
+    
+#ifdef TT_CONFIG_OPTION_BYTECODE_INTERPRETER
+    TT_ExecContext  exec;
+    TT_Byte*        instructions;
+#endif
+
+  } TT_Loader;
+
+
   /*************************************************************************/
   /*                                                                       */
   /* <Function>                                                            */
@@ -53,7 +90,7 @@
   /*                                                                       */
   LOCAL_DEF
   void  TT_Get_Metrics( TT_HoriHeader*  header,
-                        TT_UShort       index,
+                        TT_UInt         index,
                         TT_Short*       bearing,
                         TT_UShort*      advance );
 
--- a/src/truetype/ttobjs.c
+++ b/src/truetype/ttobjs.c
@@ -21,13 +21,18 @@
 #include <ftcalc.h>
 #include <ftstream.h>
 #include <ttnameid.h>
+#include <tttags.h>
 
 #include <sfnt.h>
+#include <ttobjs.h>
 
 #include <ttpload.h>
-#include <ttinterp.h>
 #include <tterrors.h>
 
+#ifdef TT_CONFIG_OPTION_BYTECODE_INTERPRETER
+#include <ttinterp.h>
+#endif
+
 /* required by tracing mode */
 #undef   FT_COMPONENT
 #define  FT_COMPONENT  trace_ttobjs
@@ -442,14 +447,16 @@
   LOCAL_DEF
   TT_Error  TT_Init_Size( TT_Size  size )
   {
+    TT_Error   error = 0;
+    
+#ifdef TT_CONFIG_OPTION_BYTECODE_INTERPRETER
     TT_Face    face   = (TT_Face)size->root.face;
     FT_Memory  memory = face->root.memory;
-    TT_Error   error;
     TT_Int     i;
-    TT_UShort  n_twilight;
 
-    TT_MaxProfile*  maxp = &face->max_profile;
     TT_ExecContext  exec;
+    TT_UShort       n_twilight;
+    TT_MaxProfile*  maxp = &face->max_profile;
 
     size->ttmetrics.valid = FALSE;
 
@@ -587,14 +594,19 @@
     if ( !size->debug )
       TT_Done_Context( exec );
 
+#endif /* TT_CONFIG_OPTION_BYTECODE_INTERPRETER */
+
     size->ttmetrics.valid = FALSE;
     return error;
 
+#ifdef TT_CONFIG_OPTION_BYTECODE_INTERPRETER
   Fail_Exec:
     if ( !size->debug )
       TT_Done_Context( exec );
 
   Fail_Memory:
+#endif
+
     TT_Done_Size( size );
     return error;
   }
@@ -614,9 +626,9 @@
   LOCAL_FUNC
   void  TT_Done_Size( TT_Size  size )
   {
+#ifdef TT_CONFIG_OPTION_BYTECODE_INTERPRETER
     FT_Memory  memory = size->root.face->memory;
 
-
     if ( size->debug )
     {
       /* the debug context must be deleted by the debugger itself */
@@ -643,6 +655,7 @@
 
     size->max_func = 0;
     size->max_ins  = 0;
+#endif
 
     size->ttmetrics.valid = FALSE;
   }
@@ -663,10 +676,8 @@
   LOCAL_DEF
   TT_Error  TT_Reset_Size( TT_Size  size )
   {
-    TT_ExecContext    exec;
-    TT_Error          error;
-    TT_UShort         i, j;
-    TT_Face           face;
+    TT_Face   face;
+    TT_Error  error = TT_Err_Ok;
 
     FT_Size_Metrics*  metrics;
 
@@ -713,73 +724,80 @@
     metrics->max_advance = ( FT_MulFix( face->root.max_advance_width,
                                         metrics->x_scale ) + 32 ) & -64;
 
-    /* Scale the cvt values to the new ppem.          */
-    /* We use by default the y ppem to scale the CVT. */
-
-    for ( i = 0; i < size->cvt_size; i++ )
-      size->cvt[i] = FT_MulFix( face->cvt[i], size->ttmetrics.scale );
-
-    /* All twilight points are originally zero */
-    for ( j = 0; j < size->twilight.n_points; j++ )
+#ifdef TT_CONFIG_OPTION_BYTECODE_INTERPRETER
     {
-      size->twilight.org[j].x = 0;
-      size->twilight.org[j].y = 0;
-      size->twilight.cur[j].x = 0;
-      size->twilight.cur[j].y = 0;
-    }
-
-    /* clear storage area */
-    for ( i = 0; i < size->storage_size; i++ )
-      size->storage[i] = 0;
-
-    size->GS = tt_default_graphics_state;
-
-    /* get execution context and run prep program */
-    if ( size->debug )
-      exec = size->context;
-    else
-      exec = TT_New_Context( face );
-    /* debugging instances have their own context */
-
-    if ( !exec )
-      return TT_Err_Could_Not_Find_Context;
-
-    TT_Load_Context( exec, face, size );
-
-    TT_Set_CodeRange( exec,
-                      tt_coderange_cvt,
-                      face->cvt_program,
-                      face->cvt_program_size );
-
-    TT_Clear_CodeRange( exec, tt_coderange_glyph );
-
-    exec->instruction_trap = FALSE;
-
-    exec->top     = 0;
-    exec->callTop = 0;
-
-    if ( face->cvt_program_size > 0 )
-    {
-      error = TT_Goto_CodeRange( exec, tt_coderange_cvt, 0 );
-      if ( error )
-        goto Fin;
-
+      TT_ExecContext    exec;
+      TT_UInt  i, j;
+      
+      /* Scale the cvt values to the new ppem.          */
+      /* We use by default the y ppem to scale the CVT. */
+  
+      for ( i = 0; i < size->cvt_size; i++ )
+        size->cvt[i] = FT_MulFix( face->cvt[i], size->ttmetrics.scale );
+  
+      /* All twilight points are originally zero */
+      for ( j = 0; j < size->twilight.n_points; j++ )
+      {
+        size->twilight.org[j].x = 0;
+        size->twilight.org[j].y = 0;
+        size->twilight.cur[j].x = 0;
+        size->twilight.cur[j].y = 0;
+      }
+  
+      /* clear storage area */
+      for ( i = 0; i < size->storage_size; i++ )
+        size->storage[i] = 0;
+  
+      size->GS = tt_default_graphics_state;
+  
+      /* get execution context and run prep program */
+      if ( size->debug )
+        exec = size->context;
+      else
+        exec = TT_New_Context( face );
+      /* debugging instances have their own context */
+  
+      if ( !exec )
+        return TT_Err_Could_Not_Find_Context;
+  
+      TT_Load_Context( exec, face, size );
+  
+      TT_Set_CodeRange( exec,
+                        tt_coderange_cvt,
+                        face->cvt_program,
+                        face->cvt_program_size );
+  
+      TT_Clear_CodeRange( exec, tt_coderange_glyph );
+  
+      exec->instruction_trap = FALSE;
+  
+      exec->top     = 0;
+      exec->callTop = 0;
+  
+      if ( face->cvt_program_size > 0 )
+      {
+        error = TT_Goto_CodeRange( exec, tt_coderange_cvt, 0 );
+        if ( error )
+          goto Fin;
+  
+        if ( !size->debug )
+          error = face->interpreter( exec );
+      }
+      else
+        error = TT_Err_Ok;
+  
+      size->GS = exec->GS;
+      /* save default graphics state */
+  
+    Fin:
+      TT_Save_Context( exec, size );
+  
       if ( !size->debug )
-        error = face->interpreter( exec );
+        TT_Done_Context( exec );
+      /* debugging instances keep their context */
     }
-    else
-      error = TT_Err_Ok;
+#endif /* TT_CONFIG_OPTION_BYTECODE_INTERPRETER */
 
-    size->GS = exec->GS;
-    /* save default graphics state */
-
-  Fin:
-    TT_Save_Context( exec, size );
-
-    if ( !size->debug )
-      TT_Done_Context( exec );
-    /* debugging instances keep their context */
-
     if ( !error )
       size->ttmetrics.valid = TRUE;
 
@@ -888,6 +906,7 @@
     TT_Done_Extensions( driver );
 #endif
 
+#ifdef TT_CONFIG_OPTION_BYTECODE_INTERPRETER
     /* destroy the execution context */
     if ( driver->context )
     {
@@ -894,6 +913,7 @@
       TT_Destroy_Context( driver->context, driver->root.memory );
       driver->context = NULL;
     }
+#endif
   }
 
 
--- a/src/truetype/ttobjs.h
+++ b/src/truetype/ttobjs.h
@@ -330,6 +330,7 @@
 
     TT_Size_Metrics    ttmetrics;
 
+#ifdef TT_CONFIG_OPTION_BYTECODE_INTERPRETER
     TT_UInt            num_function_defs; /* number of function definitions */
     TT_UInt            max_function_defs;
     TT_DefArray        function_defs;     /* table of function definitions  */
@@ -361,6 +362,8 @@
 
     TT_Bool            debug;
     TT_ExecContext     context;
+
+#endif /* TT_CONFIG_OPTION_BYTECODE_INTERPRETER */
 
   } TT_SizeRec;