Subversion Repositories Kolibri OS

Rev

Blame | Last modification | View Log | RSS feed

  1. /***************************************************************************/
  2. /*                                                                         */
  3. /*  ttgload.c                                                              */
  4. /*                                                                         */
  5. /*    TrueType Glyph Loader (body).                                        */
  6. /*                                                                         */
  7. /*  Copyright 1996-2013                                                    */
  8. /*  David Turner, Robert Wilhelm, and Werner Lemberg.                      */
  9. /*                                                                         */
  10. /*  This file is part of the FreeType project, and may only be used,       */
  11. /*  modified, and distributed under the terms of the FreeType project      */
  12. /*  license, LICENSE.TXT.  By continuing to use, modify, or distribute     */
  13. /*  this file you indicate that you have read the license and              */
  14. /*  understand and accept it fully.                                        */
  15. /*                                                                         */
  16. /***************************************************************************/
  17.  
  18.  
  19. #include <ft2build.h>
  20. #include FT_INTERNAL_DEBUG_H
  21. #include FT_INTERNAL_CALC_H
  22. #include FT_INTERNAL_STREAM_H
  23. #include FT_INTERNAL_SFNT_H
  24. #include FT_TRUETYPE_TAGS_H
  25. #include FT_OUTLINE_H
  26. #include FT_TRUETYPE_DRIVER_H
  27.  
  28. #include "ttgload.h"
  29. #include "ttpload.h"
  30.  
  31. #ifdef TT_CONFIG_OPTION_GX_VAR_SUPPORT
  32. #include "ttgxvar.h"
  33. #endif
  34.  
  35. #include "tterrors.h"
  36. #include "ttsubpix.h"
  37.  
  38.  
  39.   /*************************************************************************/
  40.   /*                                                                       */
  41.   /* The macro FT_COMPONENT is used in trace mode.  It is an implicit      */
  42.   /* parameter of the FT_TRACE() and FT_ERROR() macros, used to print/log  */
  43.   /* messages during execution.                                            */
  44.   /*                                                                       */
  45. #undef  FT_COMPONENT
  46. #define FT_COMPONENT  trace_ttgload
  47.  
  48.  
  49.   /*************************************************************************/
  50.   /*                                                                       */
  51.   /* Composite glyph flags.                                                */
  52.   /*                                                                       */
  53. #define ARGS_ARE_WORDS             0x0001
  54. #define ARGS_ARE_XY_VALUES         0x0002
  55. #define ROUND_XY_TO_GRID           0x0004
  56. #define WE_HAVE_A_SCALE            0x0008
  57. /* reserved                        0x0010 */
  58. #define MORE_COMPONENTS            0x0020
  59. #define WE_HAVE_AN_XY_SCALE        0x0040
  60. #define WE_HAVE_A_2X2              0x0080
  61. #define WE_HAVE_INSTR              0x0100
  62. #define USE_MY_METRICS             0x0200
  63. #define OVERLAP_COMPOUND           0x0400
  64. #define SCALED_COMPONENT_OFFSET    0x0800
  65. #define UNSCALED_COMPONENT_OFFSET  0x1000
  66.  
  67.  
  68.   /*************************************************************************/
  69.   /*                                                                       */
  70.   /* Return the horizontal metrics in font units for a given glyph.        */
  71.   /*                                                                       */
  72.   FT_LOCAL_DEF( void )
  73.   TT_Get_HMetrics( TT_Face     face,
  74.                    FT_UInt     idx,
  75.                    FT_Short*   lsb,
  76.                    FT_UShort*  aw )
  77.   {
  78.     ( (SFNT_Service)face->sfnt )->get_metrics( face, 0, idx, lsb, aw );
  79.  
  80.     FT_TRACE5(( "  advance width (font units): %d\n", *aw ));
  81.     FT_TRACE5(( "  left side bearing (font units): %d\n", *lsb ));
  82.   }
  83.  
  84.  
  85.   /*************************************************************************/
  86.   /*                                                                       */
  87.   /* Return the vertical metrics in font units for a given glyph.          */
  88.   /* Greg Hitchcock from Microsoft told us that if there were no `vmtx'    */
  89.   /* table, typoAscender/Descender from the `OS/2' table would be used     */
  90.   /* instead, and if there were no `OS/2' table, use ascender/descender    */
  91.   /* from the `hhea' table.  But that is not what Microsoft's rasterizer   */
  92.   /* apparently does: It uses the ppem value as the advance height, and    */
  93.   /* sets the top side bearing to be zero.                                 */
  94.   /*                                                                       */
  95.   FT_LOCAL_DEF( void )
  96.   TT_Get_VMetrics( TT_Face     face,
  97.                    FT_UInt     idx,
  98.                    FT_Short*   tsb,
  99.                    FT_UShort*  ah )
  100.   {
  101.     if ( face->vertical_info )
  102.       ( (SFNT_Service)face->sfnt )->get_metrics( face, 1, idx, tsb, ah );
  103.  
  104. #if 1             /* Empirically determined, at variance with what MS said */
  105.  
  106.     else
  107.     {
  108.       *tsb = 0;
  109.       *ah  = face->root.units_per_EM;
  110.     }
  111.  
  112. #else      /* This is what MS said to do.  It isn't what they do, however. */
  113.  
  114.     else if ( face->os2.version != 0xFFFFU )
  115.     {
  116.       *tsb = face->os2.sTypoAscender;
  117.       *ah  = face->os2.sTypoAscender - face->os2.sTypoDescender;
  118.     }
  119.     else
  120.     {
  121.       *tsb = face->horizontal.Ascender;
  122.       *ah  = face->horizontal.Ascender - face->horizontal.Descender;
  123.     }
  124.  
  125. #endif
  126.  
  127.     FT_TRACE5(( "  advance height (font units): %d\n", *ah ));
  128.     FT_TRACE5(( "  top side bearing (font units): %d\n", *tsb ));
  129.   }
  130.  
  131.  
  132.   static void
  133.   tt_get_metrics( TT_Loader  loader,
  134.                   FT_UInt    glyph_index )
  135.   {
  136.     TT_Face    face   = (TT_Face)loader->face;
  137. #ifdef TT_CONFIG_OPTION_SUBPIXEL_HINTING
  138.     TT_Driver  driver = (TT_Driver)FT_FACE_DRIVER( face );
  139. #endif
  140.  
  141.     FT_Short   left_bearing = 0, top_bearing = 0;
  142.     FT_UShort  advance_width = 0, advance_height = 0;
  143.  
  144.  
  145.     TT_Get_HMetrics( face, glyph_index,
  146.                      &left_bearing,
  147.                      &advance_width );
  148.     TT_Get_VMetrics( face, glyph_index,
  149.                      &top_bearing,
  150.                      &advance_height );
  151.  
  152.     loader->left_bearing = left_bearing;
  153.     loader->advance      = advance_width;
  154.     loader->top_bearing  = top_bearing;
  155.     loader->vadvance     = advance_height;
  156.  
  157. #ifdef TT_CONFIG_OPTION_SUBPIXEL_HINTING
  158.     if ( driver->interpreter_version == TT_INTERPRETER_VERSION_38 )
  159.     {
  160.       if ( loader->exec )
  161.         loader->exec->sph_tweak_flags = 0;
  162.  
  163.       /* this may not be the right place for this, but it works */
  164.       if ( loader->exec && loader->exec->ignore_x_mode )
  165.         sph_set_tweaks( loader, glyph_index );
  166.     }
  167. #endif /* TT_CONFIG_OPTION_SUBPIXEL_HINTING */
  168.  
  169.     if ( !loader->linear_def )
  170.     {
  171.       loader->linear_def = 1;
  172.       loader->linear     = advance_width;
  173.     }
  174.   }
  175.  
  176.  
  177. #ifdef FT_CONFIG_OPTION_INCREMENTAL
  178.  
  179.   static void
  180.   tt_get_metrics_incr_overrides( TT_Loader  loader,
  181.                                  FT_UInt    glyph_index )
  182.   {
  183.     TT_Face  face = (TT_Face)loader->face;
  184.  
  185.     FT_Short   left_bearing = 0, top_bearing = 0;
  186.     FT_UShort  advance_width = 0, advance_height = 0;
  187.  
  188.  
  189.     /* If this is an incrementally loaded font check whether there are */
  190.     /* overriding metrics for this glyph.                              */
  191.     if ( face->root.internal->incremental_interface                           &&
  192.          face->root.internal->incremental_interface->funcs->get_glyph_metrics )
  193.     {
  194.       FT_Incremental_MetricsRec  metrics;
  195.       FT_Error                   error;
  196.  
  197.  
  198.       metrics.bearing_x = loader->left_bearing;
  199.       metrics.bearing_y = 0;
  200.       metrics.advance   = loader->advance;
  201.       metrics.advance_v = 0;
  202.  
  203.       error = face->root.internal->incremental_interface->funcs->get_glyph_metrics(
  204.                 face->root.internal->incremental_interface->object,
  205.                 glyph_index, FALSE, &metrics );
  206.       if ( error )
  207.         goto Exit;
  208.  
  209.       left_bearing  = (FT_Short)metrics.bearing_x;
  210.       advance_width = (FT_UShort)metrics.advance;
  211.  
  212. #if 0
  213.  
  214.       /* GWW: Do I do the same for vertical metrics? */
  215.       metrics.bearing_x = 0;
  216.       metrics.bearing_y = loader->top_bearing;
  217.       metrics.advance   = loader->vadvance;
  218.  
  219.       error = face->root.internal->incremental_interface->funcs->get_glyph_metrics(
  220.                 face->root.internal->incremental_interface->object,
  221.                 glyph_index, TRUE, &metrics );
  222.       if ( error )
  223.         goto Exit;
  224.  
  225.       top_bearing    = (FT_Short)metrics.bearing_y;
  226.       advance_height = (FT_UShort)metrics.advance;
  227.  
  228. #endif /* 0 */
  229.  
  230.       loader->left_bearing = left_bearing;
  231.       loader->advance      = advance_width;
  232.       loader->top_bearing  = top_bearing;
  233.       loader->vadvance     = advance_height;
  234.  
  235.       if ( !loader->linear_def )
  236.       {
  237.         loader->linear_def = 1;
  238.         loader->linear     = advance_width;
  239.       }
  240.     }
  241.  
  242.   Exit:
  243.     return;
  244.   }
  245.  
  246. #endif /* FT_CONFIG_OPTION_INCREMENTAL */
  247.  
  248.  
  249.   /*************************************************************************/
  250.   /*                                                                       */
  251.   /* Translates an array of coordinates.                                   */
  252.   /*                                                                       */
  253.   static void
  254.   translate_array( FT_UInt     n,
  255.                    FT_Vector*  coords,
  256.                    FT_Pos      delta_x,
  257.                    FT_Pos      delta_y )
  258.   {
  259.     FT_UInt  k;
  260.  
  261.  
  262.     if ( delta_x )
  263.       for ( k = 0; k < n; k++ )
  264.         coords[k].x += delta_x;
  265.  
  266.     if ( delta_y )
  267.       for ( k = 0; k < n; k++ )
  268.         coords[k].y += delta_y;
  269.   }
  270.  
  271.  
  272.   /*************************************************************************/
  273.   /*                                                                       */
  274.   /* The following functions are used by default with TrueType fonts.      */
  275.   /* However, they can be replaced by alternatives if we need to support   */
  276.   /* TrueType-compressed formats (like MicroType) in the future.           */
  277.   /*                                                                       */
  278.   /*************************************************************************/
  279.  
  280.   FT_CALLBACK_DEF( FT_Error )
  281.   TT_Access_Glyph_Frame( TT_Loader  loader,
  282.                          FT_UInt    glyph_index,
  283.                          FT_ULong   offset,
  284.                          FT_UInt    byte_count )
  285.   {
  286.     FT_Error   error;
  287.     FT_Stream  stream = loader->stream;
  288.  
  289.     /* for non-debug mode */
  290.     FT_UNUSED( glyph_index );
  291.  
  292.  
  293.     FT_TRACE4(( "Glyph %ld\n", glyph_index ));
  294.  
  295.     /* the following line sets the `error' variable through macros! */
  296.     if ( FT_STREAM_SEEK( offset ) || FT_FRAME_ENTER( byte_count ) )
  297.       return error;
  298.  
  299.     loader->cursor = stream->cursor;
  300.     loader->limit  = stream->limit;
  301.  
  302.     return FT_Err_Ok;
  303.   }
  304.  
  305.  
  306.   FT_CALLBACK_DEF( void )
  307.   TT_Forget_Glyph_Frame( TT_Loader  loader )
  308.   {
  309.     FT_Stream  stream = loader->stream;
  310.  
  311.  
  312.     FT_FRAME_EXIT();
  313.   }
  314.  
  315.  
  316.   FT_CALLBACK_DEF( FT_Error )
  317.   TT_Load_Glyph_Header( TT_Loader  loader )
  318.   {
  319.     FT_Byte*  p     = loader->cursor;
  320.     FT_Byte*  limit = loader->limit;
  321.  
  322.  
  323.     if ( p + 10 > limit )
  324.       return FT_THROW( Invalid_Outline );
  325.  
  326.     loader->n_contours = FT_NEXT_SHORT( p );
  327.  
  328.     loader->bbox.xMin = FT_NEXT_SHORT( p );
  329.     loader->bbox.yMin = FT_NEXT_SHORT( p );
  330.     loader->bbox.xMax = FT_NEXT_SHORT( p );
  331.     loader->bbox.yMax = FT_NEXT_SHORT( p );
  332.  
  333.     FT_TRACE5(( "  # of contours: %d\n", loader->n_contours ));
  334.     FT_TRACE5(( "  xMin: %4d  xMax: %4d\n", loader->bbox.xMin,
  335.                                             loader->bbox.xMax ));
  336.     FT_TRACE5(( "  yMin: %4d  yMax: %4d\n", loader->bbox.yMin,
  337.                                             loader->bbox.yMax ));
  338.     loader->cursor = p;
  339.  
  340.     return FT_Err_Ok;
  341.   }
  342.  
  343.  
  344.   FT_CALLBACK_DEF( FT_Error )
  345.   TT_Load_Simple_Glyph( TT_Loader  load )
  346.   {
  347.     FT_Error        error;
  348.     FT_Byte*        p          = load->cursor;
  349.     FT_Byte*        limit      = load->limit;
  350.     FT_GlyphLoader  gloader    = load->gloader;
  351.     FT_Int          n_contours = load->n_contours;
  352.     FT_Outline*     outline;
  353.     TT_Face         face       = (TT_Face)load->face;
  354.     FT_UShort       n_ins;
  355.     FT_Int          n_points;
  356.  
  357.     FT_Byte         *flag, *flag_limit;
  358.     FT_Byte         c, count;
  359.     FT_Vector       *vec, *vec_limit;
  360.     FT_Pos          x;
  361.     FT_Short        *cont, *cont_limit, prev_cont;
  362.     FT_Int          xy_size = 0;
  363.  
  364.  
  365.     /* check that we can add the contours to the glyph */
  366.     error = FT_GLYPHLOADER_CHECK_POINTS( gloader, 0, n_contours );
  367.     if ( error )
  368.       goto Fail;
  369.  
  370.     /* reading the contours' endpoints & number of points */
  371.     cont       = gloader->current.outline.contours;
  372.     cont_limit = cont + n_contours;
  373.  
  374.     /* check space for contours array + instructions count */
  375.     if ( n_contours >= 0xFFF || p + ( n_contours + 1 ) * 2 > limit )
  376.       goto Invalid_Outline;
  377.  
  378.     prev_cont = FT_NEXT_SHORT( p );
  379.  
  380.     if ( n_contours > 0 )
  381.       cont[0] = prev_cont;
  382.  
  383.     if ( prev_cont < 0 )
  384.       goto Invalid_Outline;
  385.  
  386.     for ( cont++; cont < cont_limit; cont++ )
  387.     {
  388.       cont[0] = FT_NEXT_SHORT( p );
  389.       if ( cont[0] <= prev_cont )
  390.       {
  391.         /* unordered contours: this is invalid */
  392.         goto Invalid_Outline;
  393.       }
  394.       prev_cont = cont[0];
  395.     }
  396.  
  397.     n_points = 0;
  398.     if ( n_contours > 0 )
  399.     {
  400.       n_points = cont[-1] + 1;
  401.       if ( n_points < 0 )
  402.         goto Invalid_Outline;
  403.     }
  404.  
  405.     /* note that we will add four phantom points later */
  406.     error = FT_GLYPHLOADER_CHECK_POINTS( gloader, n_points + 4, 0 );
  407.     if ( error )
  408.       goto Fail;
  409.  
  410.     /* reading the bytecode instructions */
  411.     load->glyph->control_len  = 0;
  412.     load->glyph->control_data = 0;
  413.  
  414.     if ( p + 2 > limit )
  415.       goto Invalid_Outline;
  416.  
  417.     n_ins = FT_NEXT_USHORT( p );
  418.  
  419.     FT_TRACE5(( "  Instructions size: %u\n", n_ins ));
  420.  
  421.     if ( n_ins > face->max_profile.maxSizeOfInstructions )
  422.     {
  423.       FT_TRACE0(( "TT_Load_Simple_Glyph: too many instructions (%d)\n",
  424.                   n_ins ));
  425.       error = FT_THROW( Too_Many_Hints );
  426.       goto Fail;
  427.     }
  428.  
  429.     if ( ( limit - p ) < n_ins )
  430.     {
  431.       FT_TRACE0(( "TT_Load_Simple_Glyph: instruction count mismatch\n" ));
  432.       error = FT_THROW( Too_Many_Hints );
  433.       goto Fail;
  434.     }
  435.  
  436. #ifdef TT_USE_BYTECODE_INTERPRETER
  437.  
  438.     if ( IS_HINTED( load->load_flags ) )
  439.     {
  440.       load->glyph->control_len  = n_ins;
  441.       load->glyph->control_data = load->exec->glyphIns;
  442.  
  443.       FT_MEM_COPY( load->exec->glyphIns, p, (FT_Long)n_ins );
  444.     }
  445.  
  446. #endif /* TT_USE_BYTECODE_INTERPRETER */
  447.  
  448.     p += n_ins;
  449.  
  450.     outline = &gloader->current.outline;
  451.  
  452.     /* reading the point tags */
  453.     flag       = (FT_Byte*)outline->tags;
  454.     flag_limit = flag + n_points;
  455.  
  456.     FT_ASSERT( flag != NULL );
  457.  
  458.     while ( flag < flag_limit )
  459.     {
  460.       if ( p + 1 > limit )
  461.         goto Invalid_Outline;
  462.  
  463.       *flag++ = c = FT_NEXT_BYTE( p );
  464.       if ( c & 8 )
  465.       {
  466.         if ( p + 1 > limit )
  467.           goto Invalid_Outline;
  468.  
  469.         count = FT_NEXT_BYTE( p );
  470.         if ( flag + (FT_Int)count > flag_limit )
  471.           goto Invalid_Outline;
  472.  
  473.         for ( ; count > 0; count-- )
  474.           *flag++ = c;
  475.       }
  476.     }
  477.  
  478.     /* reading the X coordinates */
  479.  
  480.     vec       = outline->points;
  481.     vec_limit = vec + n_points;
  482.     flag      = (FT_Byte*)outline->tags;
  483.     x         = 0;
  484.  
  485.     if ( p + xy_size > limit )
  486.       goto Invalid_Outline;
  487.  
  488.     for ( ; vec < vec_limit; vec++, flag++ )
  489.     {
  490.       FT_Pos   y = 0;
  491.       FT_Byte  f = *flag;
  492.  
  493.  
  494.       if ( f & 2 )
  495.       {
  496.         if ( p + 1 > limit )
  497.           goto Invalid_Outline;
  498.  
  499.         y = (FT_Pos)FT_NEXT_BYTE( p );
  500.         if ( ( f & 16 ) == 0 )
  501.           y = -y;
  502.       }
  503.       else if ( ( f & 16 ) == 0 )
  504.       {
  505.         if ( p + 2 > limit )
  506.           goto Invalid_Outline;
  507.  
  508.         y = (FT_Pos)FT_NEXT_SHORT( p );
  509.       }
  510.  
  511.       x     += y;
  512.       vec->x = x;
  513.       /* the cast is for stupid compilers */
  514.       *flag  = (FT_Byte)( f & ~( 2 | 16 ) );
  515.     }
  516.  
  517.     /* reading the Y coordinates */
  518.  
  519.     vec       = gloader->current.outline.points;
  520.     vec_limit = vec + n_points;
  521.     flag      = (FT_Byte*)outline->tags;
  522.     x         = 0;
  523.  
  524.     for ( ; vec < vec_limit; vec++, flag++ )
  525.     {
  526.       FT_Pos   y = 0;
  527.       FT_Byte  f = *flag;
  528.  
  529.  
  530.       if ( f & 4 )
  531.       {
  532.         if ( p + 1 > limit )
  533.           goto Invalid_Outline;
  534.  
  535.         y = (FT_Pos)FT_NEXT_BYTE( p );
  536.         if ( ( f & 32 ) == 0 )
  537.           y = -y;
  538.       }
  539.       else if ( ( f & 32 ) == 0 )
  540.       {
  541.         if ( p + 2 > limit )
  542.           goto Invalid_Outline;
  543.  
  544.         y = (FT_Pos)FT_NEXT_SHORT( p );
  545.       }
  546.  
  547.       x     += y;
  548.       vec->y = x;
  549.       /* the cast is for stupid compilers */
  550.       *flag  = (FT_Byte)( f & FT_CURVE_TAG_ON );
  551.     }
  552.  
  553.     outline->n_points   = (FT_UShort)n_points;
  554.     outline->n_contours = (FT_Short) n_contours;
  555.  
  556.     load->cursor = p;
  557.  
  558.   Fail:
  559.     return error;
  560.  
  561.   Invalid_Outline:
  562.     error = FT_THROW( Invalid_Outline );
  563.     goto Fail;
  564.   }
  565.  
  566.  
  567.   FT_CALLBACK_DEF( FT_Error )
  568.   TT_Load_Composite_Glyph( TT_Loader  loader )
  569.   {
  570.     FT_Error        error;
  571.     FT_Byte*        p       = loader->cursor;
  572.     FT_Byte*        limit   = loader->limit;
  573.     FT_GlyphLoader  gloader = loader->gloader;
  574.     FT_SubGlyph     subglyph;
  575.     FT_UInt         num_subglyphs;
  576.  
  577.  
  578.     num_subglyphs = 0;
  579.  
  580.     do
  581.     {
  582.       FT_Fixed  xx, xy, yy, yx;
  583.       FT_UInt   count;
  584.  
  585.  
  586.       /* check that we can load a new subglyph */
  587.       error = FT_GlyphLoader_CheckSubGlyphs( gloader, num_subglyphs + 1 );
  588.       if ( error )
  589.         goto Fail;
  590.  
  591.       /* check space */
  592.       if ( p + 4 > limit )
  593.         goto Invalid_Composite;
  594.  
  595.       subglyph = gloader->current.subglyphs + num_subglyphs;
  596.  
  597.       subglyph->arg1 = subglyph->arg2 = 0;
  598.  
  599.       subglyph->flags = FT_NEXT_USHORT( p );
  600.       subglyph->index = FT_NEXT_USHORT( p );
  601.  
  602.       /* check space */
  603.       count = 2;
  604.       if ( subglyph->flags & ARGS_ARE_WORDS )
  605.         count += 2;
  606.       if ( subglyph->flags & WE_HAVE_A_SCALE )
  607.         count += 2;
  608.       else if ( subglyph->flags & WE_HAVE_AN_XY_SCALE )
  609.         count += 4;
  610.       else if ( subglyph->flags & WE_HAVE_A_2X2 )
  611.         count += 8;
  612.  
  613.       if ( p + count > limit )
  614.         goto Invalid_Composite;
  615.  
  616.       /* read arguments */
  617.       if ( subglyph->flags & ARGS_ARE_WORDS )
  618.       {
  619.         subglyph->arg1 = FT_NEXT_SHORT( p );
  620.         subglyph->arg2 = FT_NEXT_SHORT( p );
  621.       }
  622.       else
  623.       {
  624.         subglyph->arg1 = FT_NEXT_CHAR( p );
  625.         subglyph->arg2 = FT_NEXT_CHAR( p );
  626.       }
  627.  
  628.       /* read transform */
  629.       xx = yy = 0x10000L;
  630.       xy = yx = 0;
  631.  
  632.       if ( subglyph->flags & WE_HAVE_A_SCALE )
  633.       {
  634.         xx = (FT_Fixed)FT_NEXT_SHORT( p ) << 2;
  635.         yy = xx;
  636.       }
  637.       else if ( subglyph->flags & WE_HAVE_AN_XY_SCALE )
  638.       {
  639.         xx = (FT_Fixed)FT_NEXT_SHORT( p ) << 2;
  640.         yy = (FT_Fixed)FT_NEXT_SHORT( p ) << 2;
  641.       }
  642.       else if ( subglyph->flags & WE_HAVE_A_2X2 )
  643.       {
  644.         xx = (FT_Fixed)FT_NEXT_SHORT( p ) << 2;
  645.         yx = (FT_Fixed)FT_NEXT_SHORT( p ) << 2;
  646.         xy = (FT_Fixed)FT_NEXT_SHORT( p ) << 2;
  647.         yy = (FT_Fixed)FT_NEXT_SHORT( p ) << 2;
  648.       }
  649.  
  650.       subglyph->transform.xx = xx;
  651.       subglyph->transform.xy = xy;
  652.       subglyph->transform.yx = yx;
  653.       subglyph->transform.yy = yy;
  654.  
  655.       num_subglyphs++;
  656.  
  657.     } while ( subglyph->flags & MORE_COMPONENTS );
  658.  
  659.     gloader->current.num_subglyphs = num_subglyphs;
  660.  
  661. #ifdef TT_USE_BYTECODE_INTERPRETER
  662.  
  663.     {
  664.       FT_Stream  stream = loader->stream;
  665.  
  666.  
  667.       /* we must undo the FT_FRAME_ENTER in order to point */
  668.       /* to the composite instructions, if we find some.   */
  669.       /* We will process them later.                       */
  670.       /*                                                   */
  671.       loader->ins_pos = (FT_ULong)( FT_STREAM_POS() +
  672.                                     p - limit );
  673.     }
  674.  
  675. #endif
  676.  
  677.     loader->cursor = p;
  678.  
  679.   Fail:
  680.     return error;
  681.  
  682.   Invalid_Composite:
  683.     error = FT_THROW( Invalid_Composite );
  684.     goto Fail;
  685.   }
  686.  
  687.  
  688.   FT_LOCAL_DEF( void )
  689.   TT_Init_Glyph_Loading( TT_Face  face )
  690.   {
  691.     face->access_glyph_frame   = TT_Access_Glyph_Frame;
  692.     face->read_glyph_header    = TT_Load_Glyph_Header;
  693.     face->read_simple_glyph    = TT_Load_Simple_Glyph;
  694.     face->read_composite_glyph = TT_Load_Composite_Glyph;
  695.     face->forget_glyph_frame   = TT_Forget_Glyph_Frame;
  696.   }
  697.  
  698.  
  699.   static void
  700.   tt_prepare_zone( TT_GlyphZone  zone,
  701.                    FT_GlyphLoad  load,
  702.                    FT_UInt       start_point,
  703.                    FT_UInt       start_contour )
  704.   {
  705.     zone->n_points    = (FT_UShort)( load->outline.n_points - start_point );
  706.     zone->n_contours  = (FT_Short) ( load->outline.n_contours -
  707.                                        start_contour );
  708.     zone->org         = load->extra_points + start_point;
  709.     zone->cur         = load->outline.points + start_point;
  710.     zone->orus        = load->extra_points2 + start_point;
  711.     zone->tags        = (FT_Byte*)load->outline.tags + start_point;
  712.     zone->contours    = (FT_UShort*)load->outline.contours + start_contour;
  713.     zone->first_point = (FT_UShort)start_point;
  714.   }
  715.  
  716.  
  717.   /*************************************************************************/
  718.   /*                                                                       */
  719.   /* <Function>                                                            */
  720.   /*    TT_Hint_Glyph                                                      */
  721.   /*                                                                       */
  722.   /* <Description>                                                         */
  723.   /*    Hint the glyph using the zone prepared by the caller.  Note that   */
  724.   /*    the zone is supposed to include four phantom points.               */
  725.   /*                                                                       */
  726.   static FT_Error
  727.   TT_Hint_Glyph( TT_Loader  loader,
  728.                  FT_Bool    is_composite )
  729.   {
  730. #ifdef TT_CONFIG_OPTION_SUBPIXEL_HINTING
  731.     TT_Face    face   = (TT_Face)loader->face;
  732.     TT_Driver  driver = (TT_Driver)FT_FACE_DRIVER( face );
  733. #endif
  734.  
  735.     TT_GlyphZone  zone = &loader->zone;
  736.     FT_Pos        origin;
  737.  
  738. #ifdef TT_USE_BYTECODE_INTERPRETER
  739.     FT_UInt       n_ins;
  740. #else
  741.     FT_UNUSED( is_composite );
  742. #endif
  743.  
  744.  
  745. #ifdef TT_USE_BYTECODE_INTERPRETER
  746.     if ( loader->glyph->control_len > 0xFFFFL )
  747.     {
  748.       FT_TRACE1(( "TT_Hint_Glyph: too long instructions " ));
  749.       FT_TRACE1(( "(0x%lx byte) is truncated\n",
  750.                  loader->glyph->control_len ));
  751.     }
  752.     n_ins = (FT_UInt)( loader->glyph->control_len );
  753. #endif
  754.  
  755.     origin = zone->cur[zone->n_points - 4].x;
  756.     origin = FT_PIX_ROUND( origin ) - origin;
  757.     if ( origin )
  758.       translate_array( zone->n_points, zone->cur, origin, 0 );
  759.  
  760. #ifdef TT_USE_BYTECODE_INTERPRETER
  761.     /* save original point position in org */
  762.     if ( n_ins > 0 )
  763.       FT_ARRAY_COPY( zone->org, zone->cur, zone->n_points );
  764.  
  765.     /* Reset graphics state. */
  766.     loader->exec->GS = ((TT_Size)loader->size)->GS;
  767.  
  768.     /* XXX: UNDOCUMENTED! Hinting instructions of a composite glyph */
  769.     /*      completely refer to the (already) hinted subglyphs.     */
  770.     if ( is_composite )
  771.     {
  772.       loader->exec->metrics.x_scale = 1 << 16;
  773.       loader->exec->metrics.y_scale = 1 << 16;
  774.  
  775.       FT_ARRAY_COPY( zone->orus, zone->cur, zone->n_points );
  776.     }
  777.     else
  778.     {
  779.       loader->exec->metrics.x_scale =
  780.         ((TT_Size)loader->size)->metrics.x_scale;
  781.       loader->exec->metrics.y_scale =
  782.         ((TT_Size)loader->size)->metrics.y_scale;
  783.     }
  784. #endif
  785.  
  786.     /* round pp2 and pp4 */
  787.     zone->cur[zone->n_points - 3].x =
  788.       FT_PIX_ROUND( zone->cur[zone->n_points - 3].x );
  789.     zone->cur[zone->n_points - 1].y =
  790.       FT_PIX_ROUND( zone->cur[zone->n_points - 1].y );
  791.  
  792. #ifdef TT_USE_BYTECODE_INTERPRETER
  793.  
  794.     if ( n_ins > 0 )
  795.     {
  796.       FT_Bool   debug;
  797.       FT_Error  error;
  798.  
  799.       FT_GlyphLoader  gloader         = loader->gloader;
  800.       FT_Outline      current_outline = gloader->current.outline;
  801.  
  802.  
  803.       error = TT_Set_CodeRange( loader->exec, tt_coderange_glyph,
  804.                                 loader->exec->glyphIns, n_ins );
  805.       if ( error )
  806.         return error;
  807.  
  808.       loader->exec->is_composite = is_composite;
  809.       loader->exec->pts          = *zone;
  810.  
  811.       debug = FT_BOOL( !( loader->load_flags & FT_LOAD_NO_SCALE ) &&
  812.                        ((TT_Size)loader->size)->debug             );
  813.  
  814.       error = TT_Run_Context( loader->exec, debug );
  815.       if ( error && loader->exec->pedantic_hinting )
  816.         return error;
  817.  
  818.       /* store drop-out mode in bits 5-7; set bit 2 also as a marker */
  819.       current_outline.tags[0] |=
  820.         ( loader->exec->GS.scan_type << 5 ) | FT_CURVE_TAG_HAS_SCANMODE;
  821.     }
  822.  
  823. #endif
  824.  
  825.     /* save glyph phantom points */
  826.     if ( !loader->preserve_pps )
  827.     {
  828.       loader->pp1 = zone->cur[zone->n_points - 4];
  829.       loader->pp2 = zone->cur[zone->n_points - 3];
  830.       loader->pp3 = zone->cur[zone->n_points - 2];
  831.       loader->pp4 = zone->cur[zone->n_points - 1];
  832.     }
  833.  
  834. #ifdef TT_CONFIG_OPTION_SUBPIXEL_HINTING
  835.     if ( driver->interpreter_version == TT_INTERPRETER_VERSION_38 )
  836.     {
  837.       if ( loader->exec->sph_tweak_flags & SPH_TWEAK_DEEMBOLDEN )
  838.         FT_Outline_EmboldenXY( &loader->gloader->current.outline, -24, 0 );
  839.  
  840.       else if ( loader->exec->sph_tweak_flags & SPH_TWEAK_EMBOLDEN )
  841.         FT_Outline_EmboldenXY( &loader->gloader->current.outline, 24, 0 );
  842.     }
  843. #endif /* TT_CONFIG_OPTION_SUBPIXEL_HINTING */
  844.  
  845.     return FT_Err_Ok;
  846.   }
  847.  
  848.  
  849.   /*************************************************************************/
  850.   /*                                                                       */
  851.   /* <Function>                                                            */
  852.   /*    TT_Process_Simple_Glyph                                            */
  853.   /*                                                                       */
  854.   /* <Description>                                                         */
  855.   /*    Once a simple glyph has been loaded, it needs to be processed.     */
  856.   /*    Usually, this means scaling and hinting through bytecode           */
  857.   /*    interpretation.                                                    */
  858.   /*                                                                       */
  859.   static FT_Error
  860.   TT_Process_Simple_Glyph( TT_Loader  loader )
  861.   {
  862.     FT_GlyphLoader  gloader = loader->gloader;
  863.     FT_Error        error   = FT_Err_Ok;
  864.     FT_Outline*     outline;
  865.     FT_Int          n_points;
  866.  
  867.  
  868.     outline  = &gloader->current.outline;
  869.     n_points = outline->n_points;
  870.  
  871.     /* set phantom points */
  872.  
  873.     outline->points[n_points    ] = loader->pp1;
  874.     outline->points[n_points + 1] = loader->pp2;
  875.     outline->points[n_points + 2] = loader->pp3;
  876.     outline->points[n_points + 3] = loader->pp4;
  877.  
  878.     outline->tags[n_points    ] = 0;
  879.     outline->tags[n_points + 1] = 0;
  880.     outline->tags[n_points + 2] = 0;
  881.     outline->tags[n_points + 3] = 0;
  882.  
  883.     n_points += 4;
  884.  
  885. #ifdef TT_CONFIG_OPTION_GX_VAR_SUPPORT
  886.  
  887.     if ( ((TT_Face)loader->face)->doblend )
  888.     {
  889.       /* Deltas apply to the unscaled data. */
  890.       FT_Vector*  deltas;
  891.       FT_Memory   memory = loader->face->memory;
  892.       FT_Int      i;
  893.  
  894.  
  895.       error = TT_Vary_Get_Glyph_Deltas( (TT_Face)(loader->face),
  896.                                         loader->glyph_index,
  897.                                         &deltas,
  898.                                         n_points );
  899.       if ( error )
  900.         return error;
  901.  
  902.       for ( i = 0; i < n_points; ++i )
  903.       {
  904.         outline->points[i].x += deltas[i].x;
  905.         outline->points[i].y += deltas[i].y;
  906.       }
  907.  
  908.       FT_FREE( deltas );
  909.     }
  910.  
  911. #endif /* TT_CONFIG_OPTION_GX_VAR_SUPPORT */
  912.  
  913.     if ( IS_HINTED( loader->load_flags ) )
  914.     {
  915.       tt_prepare_zone( &loader->zone, &gloader->current, 0, 0 );
  916.  
  917.       FT_ARRAY_COPY( loader->zone.orus, loader->zone.cur,
  918.                      loader->zone.n_points + 4 );
  919.     }
  920.  
  921.     {
  922. #ifdef TT_CONFIG_OPTION_SUBPIXEL_HINTING
  923.       TT_Face    face   = (TT_Face)loader->face;
  924.       TT_Driver  driver = (TT_Driver)FT_FACE_DRIVER( face );
  925.  
  926.       FT_String*  family         = face->root.family_name;
  927.       FT_Int      ppem           = loader->size->metrics.x_ppem;
  928.       FT_String*  style          = face->root.style_name;
  929.       FT_Int      x_scale_factor = 1000;
  930. #endif
  931.  
  932.       FT_Vector*  vec   = outline->points;
  933.       FT_Vector*  limit = outline->points + n_points;
  934.  
  935.       FT_Fixed  x_scale = 0; /* pacify compiler */
  936.       FT_Fixed  y_scale = 0;
  937.  
  938.       FT_Bool  do_scale = FALSE;
  939.  
  940.  
  941. #ifdef TT_CONFIG_OPTION_SUBPIXEL_HINTING
  942.  
  943.       if ( driver->interpreter_version == TT_INTERPRETER_VERSION_38 )
  944.       {
  945.         /* scale, but only if enabled and only if TT hinting is being used */
  946.         if ( IS_HINTED( loader->load_flags ) )
  947.           x_scale_factor = sph_test_tweak_x_scaling( face,
  948.                                                      family,
  949.                                                      ppem,
  950.                                                      style,
  951.                                                      loader->glyph_index );
  952.         /* scale the glyph */
  953.         if ( ( loader->load_flags & FT_LOAD_NO_SCALE ) == 0 ||
  954.              x_scale_factor != 1000                         )
  955.         {
  956.           x_scale = FT_MulDiv( ((TT_Size)loader->size)->metrics.x_scale,
  957.                                x_scale_factor, 1000 );
  958.           y_scale = ((TT_Size)loader->size)->metrics.y_scale;
  959.  
  960.           /* compensate for any scaling by de/emboldening; */
  961.           /* the amount was determined via experimentation */
  962.           if ( x_scale_factor != 1000 && ppem > 11 )
  963.             FT_Outline_EmboldenXY( outline,
  964.                                    FT_MulFix( 1280 * ppem,
  965.                                               1000 - x_scale_factor ),
  966.                                    0 );
  967.           do_scale = TRUE;
  968.         }
  969.       }
  970.       else
  971.  
  972. #endif /* TT_CONFIG_OPTION_SUBPIXEL_HINTING */
  973.  
  974.       {
  975.         /* scale the glyph */
  976.         if ( ( loader->load_flags & FT_LOAD_NO_SCALE ) == 0 )
  977.         {
  978.           x_scale = ((TT_Size)loader->size)->metrics.x_scale;
  979.           y_scale = ((TT_Size)loader->size)->metrics.y_scale;
  980.  
  981.           do_scale = TRUE;
  982.         }
  983.       }
  984.  
  985.       if ( do_scale )
  986.       {
  987.         for ( ; vec < limit; vec++ )
  988.         {
  989.           vec->x = FT_MulFix( vec->x, x_scale );
  990.           vec->y = FT_MulFix( vec->y, y_scale );
  991.         }
  992.  
  993.         loader->pp1 = outline->points[n_points - 4];
  994.         loader->pp2 = outline->points[n_points - 3];
  995.         loader->pp3 = outline->points[n_points - 2];
  996.         loader->pp4 = outline->points[n_points - 1];
  997.       }
  998.     }
  999.  
  1000.     if ( IS_HINTED( loader->load_flags ) )
  1001.     {
  1002.       loader->zone.n_points += 4;
  1003.  
  1004.       error = TT_Hint_Glyph( loader, 0 );
  1005.     }
  1006.  
  1007.     return error;
  1008.   }
  1009.  
  1010.  
  1011.   /*************************************************************************/
  1012.   /*                                                                       */
  1013.   /* <Function>                                                            */
  1014.   /*    TT_Process_Composite_Component                                     */
  1015.   /*                                                                       */
  1016.   /* <Description>                                                         */
  1017.   /*    Once a composite component has been loaded, it needs to be         */
  1018.   /*    processed.  Usually, this means transforming and translating.      */
  1019.   /*                                                                       */
  1020.   static FT_Error
  1021.   TT_Process_Composite_Component( TT_Loader    loader,
  1022.                                   FT_SubGlyph  subglyph,
  1023.                                   FT_UInt      start_point,
  1024.                                   FT_UInt      num_base_points )
  1025.   {
  1026.     FT_GlyphLoader  gloader    = loader->gloader;
  1027.     FT_Vector*      base_vec   = gloader->base.outline.points;
  1028.     FT_UInt         num_points = gloader->base.outline.n_points;
  1029.     FT_Bool         have_scale;
  1030.     FT_Pos          x, y;
  1031.  
  1032.  
  1033.     have_scale = FT_BOOL( subglyph->flags & ( WE_HAVE_A_SCALE     |
  1034.                                               WE_HAVE_AN_XY_SCALE |
  1035.                                               WE_HAVE_A_2X2       ) );
  1036.  
  1037.     /* perform the transform required for this subglyph */
  1038.     if ( have_scale )
  1039.     {
  1040.       FT_UInt  i;
  1041.  
  1042.  
  1043.       for ( i = num_base_points; i < num_points; i++ )
  1044.         FT_Vector_Transform( base_vec + i, &subglyph->transform );
  1045.     }
  1046.  
  1047.     /* get offset */
  1048.     if ( !( subglyph->flags & ARGS_ARE_XY_VALUES ) )
  1049.     {
  1050.       FT_UInt     k = subglyph->arg1;
  1051.       FT_UInt     l = subglyph->arg2;
  1052.       FT_Vector*  p1;
  1053.       FT_Vector*  p2;
  1054.  
  1055.  
  1056.       /* match l-th point of the newly loaded component to the k-th point */
  1057.       /* of the previously loaded components.                             */
  1058.  
  1059.       /* change to the point numbers used by our outline */
  1060.       k += start_point;
  1061.       l += num_base_points;
  1062.       if ( k >= num_base_points ||
  1063.            l >= num_points      )
  1064.         return FT_THROW( Invalid_Composite );
  1065.  
  1066.       p1 = gloader->base.outline.points + k;
  1067.       p2 = gloader->base.outline.points + l;
  1068.  
  1069.       x = p1->x - p2->x;
  1070.       y = p1->y - p2->y;
  1071.     }
  1072.     else
  1073.     {
  1074.       x = subglyph->arg1;
  1075.       y = subglyph->arg2;
  1076.  
  1077.       if ( !x && !y )
  1078.         return FT_Err_Ok;
  1079.  
  1080.   /* Use a default value dependent on                                     */
  1081.   /* TT_CONFIG_OPTION_COMPONENT_OFFSET_SCALED.  This is useful for old TT */
  1082.   /* fonts which don't set the xxx_COMPONENT_OFFSET bit.                  */
  1083.  
  1084.       if ( have_scale &&
  1085. #ifdef TT_CONFIG_OPTION_COMPONENT_OFFSET_SCALED
  1086.            !( subglyph->flags & UNSCALED_COMPONENT_OFFSET ) )
  1087. #else
  1088.             ( subglyph->flags & SCALED_COMPONENT_OFFSET ) )
  1089. #endif
  1090.       {
  1091.  
  1092. #if 0
  1093.  
  1094.   /*************************************************************************/
  1095.   /*                                                                       */
  1096.   /* This algorithm is what Apple documents.  But it doesn't work.         */
  1097.   /*                                                                       */
  1098.         int  a = subglyph->transform.xx > 0 ?  subglyph->transform.xx
  1099.                                             : -subglyph->transform.xx;
  1100.         int  b = subglyph->transform.yx > 0 ?  subglyph->transform.yx
  1101.                                             : -subglyph->transform.yx;
  1102.         int  c = subglyph->transform.xy > 0 ?  subglyph->transform.xy
  1103.                                             : -subglyph->transform.xy;
  1104.         int  d = subglyph->transform.yy > 0 ? subglyph->transform.yy
  1105.                                             : -subglyph->transform.yy;
  1106.         int  m = a > b ? a : b;
  1107.         int  n = c > d ? c : d;
  1108.  
  1109.  
  1110.         if ( a - b <= 33 && a - b >= -33 )
  1111.           m *= 2;
  1112.         if ( c - d <= 33 && c - d >= -33 )
  1113.           n *= 2;
  1114.         x = FT_MulFix( x, m );
  1115.         y = FT_MulFix( y, n );
  1116.  
  1117. #else /* 0 */
  1118.  
  1119.   /*************************************************************************/
  1120.   /*                                                                       */
  1121.   /* This algorithm is a guess and works much better than the above.       */
  1122.   /*                                                                       */
  1123.         FT_Fixed  mac_xscale = FT_Hypot( subglyph->transform.xx,
  1124.                                          subglyph->transform.xy );
  1125.         FT_Fixed  mac_yscale = FT_Hypot( subglyph->transform.yy,
  1126.                                          subglyph->transform.yx );
  1127.  
  1128.  
  1129.         x = FT_MulFix( x, mac_xscale );
  1130.         y = FT_MulFix( y, mac_yscale );
  1131.  
  1132. #endif /* 0 */
  1133.  
  1134.       }
  1135.  
  1136.       if ( !( loader->load_flags & FT_LOAD_NO_SCALE ) )
  1137.       {
  1138.         FT_Fixed  x_scale = ((TT_Size)loader->size)->metrics.x_scale;
  1139.         FT_Fixed  y_scale = ((TT_Size)loader->size)->metrics.y_scale;
  1140.  
  1141.  
  1142.         x = FT_MulFix( x, x_scale );
  1143.         y = FT_MulFix( y, y_scale );
  1144.  
  1145.         if ( subglyph->flags & ROUND_XY_TO_GRID )
  1146.         {
  1147.           x = FT_PIX_ROUND( x );
  1148.           y = FT_PIX_ROUND( y );
  1149.         }
  1150.       }
  1151.     }
  1152.  
  1153.     if ( x || y )
  1154.       translate_array( num_points - num_base_points,
  1155.                        base_vec + num_base_points,
  1156.                        x, y );
  1157.  
  1158.     return FT_Err_Ok;
  1159.   }
  1160.  
  1161.  
  1162.   /*************************************************************************/
  1163.   /*                                                                       */
  1164.   /* <Function>                                                            */
  1165.   /*    TT_Process_Composite_Glyph                                         */
  1166.   /*                                                                       */
  1167.   /* <Description>                                                         */
  1168.   /*    This is slightly different from TT_Process_Simple_Glyph, in that   */
  1169.   /*    its sole purpose is to hint the glyph.  Thus this function is      */
  1170.   /*    only available when bytecode interpreter is enabled.               */
  1171.   /*                                                                       */
  1172.   static FT_Error
  1173.   TT_Process_Composite_Glyph( TT_Loader  loader,
  1174.                               FT_UInt    start_point,
  1175.                               FT_UInt    start_contour )
  1176.   {
  1177.     FT_Error     error;
  1178.     FT_Outline*  outline;
  1179.     FT_UInt      i;
  1180.  
  1181.  
  1182.     outline = &loader->gloader->base.outline;
  1183.  
  1184.     /* make room for phantom points */
  1185.     error = FT_GLYPHLOADER_CHECK_POINTS( loader->gloader,
  1186.                                          outline->n_points + 4,
  1187.                                          0 );
  1188.     if ( error )
  1189.       return error;
  1190.  
  1191.     outline->points[outline->n_points    ] = loader->pp1;
  1192.     outline->points[outline->n_points + 1] = loader->pp2;
  1193.     outline->points[outline->n_points + 2] = loader->pp3;
  1194.     outline->points[outline->n_points + 3] = loader->pp4;
  1195.  
  1196.     outline->tags[outline->n_points    ] = 0;
  1197.     outline->tags[outline->n_points + 1] = 0;
  1198.     outline->tags[outline->n_points + 2] = 0;
  1199.     outline->tags[outline->n_points + 3] = 0;
  1200.  
  1201. #ifdef TT_USE_BYTECODE_INTERPRETER
  1202.  
  1203.     {
  1204.       FT_Stream  stream = loader->stream;
  1205.       FT_UShort  n_ins, max_ins;
  1206.       FT_ULong   tmp;
  1207.  
  1208.  
  1209.       /* TT_Load_Composite_Glyph only gives us the offset of instructions */
  1210.       /* so we read them here                                             */
  1211.       if ( FT_STREAM_SEEK( loader->ins_pos ) ||
  1212.            FT_READ_USHORT( n_ins )           )
  1213.         return error;
  1214.  
  1215.       FT_TRACE5(( "  Instructions size = %d\n", n_ins ));
  1216.  
  1217.       /* check it */
  1218.       max_ins = ((TT_Face)loader->face)->max_profile.maxSizeOfInstructions;
  1219.       if ( n_ins > max_ins )
  1220.       {
  1221.         /* acroread ignores this field, so we only do a rough safety check */
  1222.         if ( (FT_Int)n_ins > loader->byte_len )
  1223.         {
  1224.           FT_TRACE1(( "TT_Process_Composite_Glyph: "
  1225.                       "too many instructions (%d) for glyph with length %d\n",
  1226.                       n_ins, loader->byte_len ));
  1227.           return FT_THROW( Too_Many_Hints );
  1228.         }
  1229.  
  1230.         tmp = loader->exec->glyphSize;
  1231.         error = Update_Max( loader->exec->memory,
  1232.                             &tmp,
  1233.                             sizeof ( FT_Byte ),
  1234.                             (void*)&loader->exec->glyphIns,
  1235.                             n_ins );
  1236.         loader->exec->glyphSize = (FT_UShort)tmp;
  1237.         if ( error )
  1238.           return error;
  1239.       }
  1240.       else if ( n_ins == 0 )
  1241.         return FT_Err_Ok;
  1242.  
  1243.       if ( FT_STREAM_READ( loader->exec->glyphIns, n_ins ) )
  1244.         return error;
  1245.  
  1246.       loader->glyph->control_data = loader->exec->glyphIns;
  1247.       loader->glyph->control_len  = n_ins;
  1248.     }
  1249.  
  1250. #endif
  1251.  
  1252.     tt_prepare_zone( &loader->zone, &loader->gloader->base,
  1253.                      start_point, start_contour );
  1254.  
  1255.     /* Some points are likely touched during execution of  */
  1256.     /* instructions on components.  So let's untouch them. */
  1257.     for ( i = start_point; i < loader->zone.n_points; i++ )
  1258.       loader->zone.tags[i] &= ~FT_CURVE_TAG_TOUCH_BOTH;
  1259.  
  1260.     loader->zone.n_points += 4;
  1261.  
  1262.     return TT_Hint_Glyph( loader, 1 );
  1263.   }
  1264.  
  1265.  
  1266.   /* Calculate the four phantom points.                     */
  1267.   /* The first two stand for horizontal origin and advance. */
  1268.   /* The last two stand for vertical origin and advance.    */
  1269. #define TT_LOADER_SET_PP( loader )                                          \
  1270.           do {                                                              \
  1271.             (loader)->pp1.x = (loader)->bbox.xMin - (loader)->left_bearing; \
  1272.             (loader)->pp1.y = 0;                                            \
  1273.             (loader)->pp2.x = (loader)->pp1.x + (loader)->advance;          \
  1274.             (loader)->pp2.y = 0;                                            \
  1275.             (loader)->pp3.x = 0;                                            \
  1276.             (loader)->pp3.y = (loader)->top_bearing + (loader)->bbox.yMax;  \
  1277.             (loader)->pp4.x = 0;                                            \
  1278.             (loader)->pp4.y = (loader)->pp3.y - (loader)->vadvance;         \
  1279.           } while ( 0 )
  1280.  
  1281.  
  1282.   /*************************************************************************/
  1283.   /*                                                                       */
  1284.   /* <Function>                                                            */
  1285.   /*    load_truetype_glyph                                                */
  1286.   /*                                                                       */
  1287.   /* <Description>                                                         */
  1288.   /*    Loads a given truetype glyph.  Handles composites and uses a       */
  1289.   /*    TT_Loader object.                                                  */
  1290.   /*                                                                       */
  1291.   static FT_Error
  1292.   load_truetype_glyph( TT_Loader  loader,
  1293.                        FT_UInt    glyph_index,
  1294.                        FT_UInt    recurse_count,
  1295.                        FT_Bool    header_only )
  1296.   {
  1297.     FT_Error        error        = FT_Err_Ok;
  1298.     FT_Fixed        x_scale, y_scale;
  1299.     FT_ULong        offset;
  1300.     TT_Face         face         = (TT_Face)loader->face;
  1301.     FT_GlyphLoader  gloader      = loader->gloader;
  1302.     FT_Bool         opened_frame = 0;
  1303.  
  1304. #ifdef TT_CONFIG_OPTION_GX_VAR_SUPPORT
  1305.     FT_Vector*      deltas       = NULL;
  1306. #endif
  1307.  
  1308. #ifdef FT_CONFIG_OPTION_INCREMENTAL
  1309.     FT_StreamRec    inc_stream;
  1310.     FT_Data         glyph_data;
  1311.     FT_Bool         glyph_data_loaded = 0;
  1312. #endif
  1313.  
  1314.  
  1315.     /* some fonts have an incorrect value of `maxComponentDepth', */
  1316.     /* thus we allow depth 1 to catch the majority of them        */
  1317.     if ( recurse_count > 1                                   &&
  1318.          recurse_count > face->max_profile.maxComponentDepth )
  1319.     {
  1320.       error = FT_THROW( Invalid_Composite );
  1321.       goto Exit;
  1322.     }
  1323.  
  1324.     /* check glyph index */
  1325.     if ( glyph_index >= (FT_UInt)face->root.num_glyphs )
  1326.     {
  1327.       error = FT_THROW( Invalid_Glyph_Index );
  1328.       goto Exit;
  1329.     }
  1330.  
  1331.     loader->glyph_index = glyph_index;
  1332.  
  1333.     if ( ( loader->load_flags & FT_LOAD_NO_SCALE ) == 0 )
  1334.     {
  1335.       x_scale = ((TT_Size)loader->size)->metrics.x_scale;
  1336.       y_scale = ((TT_Size)loader->size)->metrics.y_scale;
  1337.     }
  1338.     else
  1339.     {
  1340.       x_scale = 0x10000L;
  1341.       y_scale = 0x10000L;
  1342.     }
  1343.  
  1344.     tt_get_metrics( loader, glyph_index );
  1345.  
  1346.     /* Set `offset' to the start of the glyph relative to the start of */
  1347.     /* the `glyf' table, and `byte_len' to the length of the glyph in  */
  1348.     /* bytes.                                                          */
  1349.  
  1350. #ifdef FT_CONFIG_OPTION_INCREMENTAL
  1351.  
  1352.     /* If we are loading glyph data via the incremental interface, set */
  1353.     /* the loader stream to a memory stream reading the data returned  */
  1354.     /* by the interface.                                               */
  1355.     if ( face->root.internal->incremental_interface )
  1356.     {
  1357.       error = face->root.internal->incremental_interface->funcs->get_glyph_data(
  1358.                 face->root.internal->incremental_interface->object,
  1359.                 glyph_index, &glyph_data );
  1360.       if ( error )
  1361.         goto Exit;
  1362.  
  1363.       glyph_data_loaded = 1;
  1364.       offset            = 0;
  1365.       loader->byte_len  = glyph_data.length;
  1366.  
  1367.       FT_MEM_ZERO( &inc_stream, sizeof ( inc_stream ) );
  1368.       FT_Stream_OpenMemory( &inc_stream,
  1369.                             glyph_data.pointer, glyph_data.length );
  1370.  
  1371.       loader->stream = &inc_stream;
  1372.     }
  1373.     else
  1374.  
  1375. #endif /* FT_CONFIG_OPTION_INCREMENTAL */
  1376.  
  1377.       offset = tt_face_get_location( face, glyph_index,
  1378.                                      (FT_UInt*)&loader->byte_len );
  1379.  
  1380.     if ( loader->byte_len > 0 )
  1381.     {
  1382. #ifdef FT_CONFIG_OPTION_INCREMENTAL
  1383.       /* for the incremental interface, `glyf_offset' is always zero */
  1384.       if ( !loader->glyf_offset                        &&
  1385.            !face->root.internal->incremental_interface )
  1386. #else
  1387.       if ( !loader->glyf_offset )
  1388. #endif /* FT_CONFIG_OPTION_INCREMENTAL */
  1389.       {
  1390.         FT_TRACE2(( "no `glyf' table but non-zero `loca' entry\n" ));
  1391.         error = FT_THROW( Invalid_Table );
  1392.         goto Exit;
  1393.       }
  1394.  
  1395.       error = face->access_glyph_frame( loader, glyph_index,
  1396.                                         loader->glyf_offset + offset,
  1397.                                         loader->byte_len );
  1398.       if ( error )
  1399.         goto Exit;
  1400.  
  1401.       opened_frame = 1;
  1402.  
  1403.       /* read glyph header first */
  1404.       error = face->read_glyph_header( loader );
  1405.       if ( error || header_only )
  1406.         goto Exit;
  1407.     }
  1408.  
  1409.     if ( loader->byte_len == 0 || loader->n_contours == 0 )
  1410.     {
  1411.       loader->bbox.xMin = 0;
  1412.       loader->bbox.xMax = 0;
  1413.       loader->bbox.yMin = 0;
  1414.       loader->bbox.yMax = 0;
  1415.  
  1416.       if ( header_only )
  1417.         goto Exit;
  1418.  
  1419.       /* must initialize points before (possibly) overriding */
  1420.       /* glyph metrics from the incremental interface        */
  1421.       TT_LOADER_SET_PP( loader );
  1422.  
  1423. #ifdef FT_CONFIG_OPTION_INCREMENTAL
  1424.       tt_get_metrics_incr_overrides( loader, glyph_index );
  1425. #endif
  1426.  
  1427. #ifdef TT_CONFIG_OPTION_GX_VAR_SUPPORT
  1428.  
  1429.       if ( ((TT_Face)(loader->face))->doblend )
  1430.       {
  1431.         /* this must be done before scaling */
  1432.         FT_Memory  memory = loader->face->memory;
  1433.  
  1434.  
  1435.         error = TT_Vary_Get_Glyph_Deltas( (TT_Face)(loader->face),
  1436.                                           glyph_index, &deltas, 4 );
  1437.         if ( error )
  1438.           goto Exit;
  1439.  
  1440.         loader->pp1.x += deltas[0].x; loader->pp1.y += deltas[0].y;
  1441.         loader->pp2.x += deltas[1].x; loader->pp2.y += deltas[1].y;
  1442.         loader->pp3.x += deltas[2].x; loader->pp3.y += deltas[2].y;
  1443.         loader->pp4.x += deltas[3].x; loader->pp4.y += deltas[3].y;
  1444.  
  1445.         FT_FREE( deltas );
  1446.       }
  1447.  
  1448. #endif
  1449.  
  1450.       if ( ( loader->load_flags & FT_LOAD_NO_SCALE ) == 0 )
  1451.       {
  1452.         loader->pp1.x = FT_MulFix( loader->pp1.x, x_scale );
  1453.         loader->pp2.x = FT_MulFix( loader->pp2.x, x_scale );
  1454.         loader->pp3.y = FT_MulFix( loader->pp3.y, y_scale );
  1455.         loader->pp4.y = FT_MulFix( loader->pp4.y, y_scale );
  1456.       }
  1457.  
  1458.       error = FT_Err_Ok;
  1459.       goto Exit;
  1460.     }
  1461.  
  1462.     /* must initialize points before (possibly) overriding */
  1463.     /* glyph metrics from the incremental interface        */
  1464.     TT_LOADER_SET_PP( loader );
  1465.  
  1466. #ifdef FT_CONFIG_OPTION_INCREMENTAL
  1467.     tt_get_metrics_incr_overrides( loader, glyph_index );
  1468. #endif
  1469.  
  1470.     /***********************************************************************/
  1471.     /***********************************************************************/
  1472.     /***********************************************************************/
  1473.  
  1474.     /* if it is a simple glyph, load it */
  1475.  
  1476.     if ( loader->n_contours > 0 )
  1477.     {
  1478.       error = face->read_simple_glyph( loader );
  1479.       if ( error )
  1480.         goto Exit;
  1481.  
  1482.       /* all data have been read */
  1483.       face->forget_glyph_frame( loader );
  1484.       opened_frame = 0;
  1485.  
  1486.       error = TT_Process_Simple_Glyph( loader );
  1487.       if ( error )
  1488.         goto Exit;
  1489.  
  1490.       FT_GlyphLoader_Add( gloader );
  1491.     }
  1492.  
  1493.     /***********************************************************************/
  1494.     /***********************************************************************/
  1495.     /***********************************************************************/
  1496.  
  1497.     /* otherwise, load a composite! */
  1498.     else if ( loader->n_contours == -1 )
  1499.     {
  1500.       FT_UInt   start_point;
  1501.       FT_UInt   start_contour;
  1502.       FT_ULong  ins_pos;  /* position of composite instructions, if any */
  1503.  
  1504.  
  1505.       start_point   = gloader->base.outline.n_points;
  1506.       start_contour = gloader->base.outline.n_contours;
  1507.  
  1508.       /* for each subglyph, read composite header */
  1509.       error = face->read_composite_glyph( loader );
  1510.       if ( error )
  1511.         goto Exit;
  1512.  
  1513.       /* store the offset of instructions */
  1514.       ins_pos = loader->ins_pos;
  1515.  
  1516.       /* all data we need are read */
  1517.       face->forget_glyph_frame( loader );
  1518.       opened_frame = 0;
  1519.  
  1520. #ifdef TT_CONFIG_OPTION_GX_VAR_SUPPORT
  1521.  
  1522.       if ( face->doblend )
  1523.       {
  1524.         FT_Int       i, limit;
  1525.         FT_SubGlyph  subglyph;
  1526.         FT_Memory    memory = face->root.memory;
  1527.  
  1528.  
  1529.         /* this provides additional offsets */
  1530.         /* for each component's translation */
  1531.  
  1532.         if ( ( error = TT_Vary_Get_Glyph_Deltas(
  1533.                          face,
  1534.                          glyph_index,
  1535.                          &deltas,
  1536.                          gloader->current.num_subglyphs + 4 )) != 0 )
  1537.           goto Exit;
  1538.  
  1539.         subglyph = gloader->current.subglyphs + gloader->base.num_subglyphs;
  1540.         limit    = gloader->current.num_subglyphs;
  1541.  
  1542.         for ( i = 0; i < limit; ++i, ++subglyph )
  1543.         {
  1544.           if ( subglyph->flags & ARGS_ARE_XY_VALUES )
  1545.           {
  1546.             /* XXX: overflow check for subglyph->{arg1,arg2}.   */
  1547.             /* deltas[i].{x,y} must be within signed 16-bit,    */
  1548.             /* but the restriction of summed delta is not clear */
  1549.             subglyph->arg1 += (FT_Int16)deltas[i].x;
  1550.             subglyph->arg2 += (FT_Int16)deltas[i].y;
  1551.           }
  1552.         }
  1553.  
  1554.         loader->pp1.x += deltas[i + 0].x; loader->pp1.y += deltas[i + 0].y;
  1555.         loader->pp2.x += deltas[i + 1].x; loader->pp2.y += deltas[i + 1].y;
  1556.         loader->pp3.x += deltas[i + 2].x; loader->pp3.y += deltas[i + 2].y;
  1557.         loader->pp4.x += deltas[i + 3].x; loader->pp4.y += deltas[i + 3].y;
  1558.  
  1559.         FT_FREE( deltas );
  1560.       }
  1561.  
  1562. #endif /* TT_CONFIG_OPTION_GX_VAR_SUPPORT */
  1563.  
  1564.       if ( ( loader->load_flags & FT_LOAD_NO_SCALE ) == 0 )
  1565.       {
  1566.         loader->pp1.x = FT_MulFix( loader->pp1.x, x_scale );
  1567.         loader->pp2.x = FT_MulFix( loader->pp2.x, x_scale );
  1568.         loader->pp3.y = FT_MulFix( loader->pp3.y, y_scale );
  1569.         loader->pp4.y = FT_MulFix( loader->pp4.y, y_scale );
  1570.       }
  1571.  
  1572.       /* if the flag FT_LOAD_NO_RECURSE is set, we return the subglyph */
  1573.       /* `as is' in the glyph slot (the client application will be     */
  1574.       /* responsible for interpreting these data)...                   */
  1575.       if ( loader->load_flags & FT_LOAD_NO_RECURSE )
  1576.       {
  1577.         FT_GlyphLoader_Add( gloader );
  1578.         loader->glyph->format = FT_GLYPH_FORMAT_COMPOSITE;
  1579.  
  1580.         goto Exit;
  1581.       }
  1582.  
  1583.       /*********************************************************************/
  1584.       /*********************************************************************/
  1585.       /*********************************************************************/
  1586.  
  1587.       {
  1588.         FT_UInt      n, num_base_points;
  1589.         FT_SubGlyph  subglyph       = 0;
  1590.  
  1591.         FT_UInt      num_points     = start_point;
  1592.         FT_UInt      num_subglyphs  = gloader->current.num_subglyphs;
  1593.         FT_UInt      num_base_subgs = gloader->base.num_subglyphs;
  1594.  
  1595.         FT_Stream    old_stream     = loader->stream;
  1596.         FT_Int       old_byte_len   = loader->byte_len;
  1597.  
  1598.  
  1599.         FT_GlyphLoader_Add( gloader );
  1600.  
  1601.         /* read each subglyph independently */
  1602.         for ( n = 0; n < num_subglyphs; n++ )
  1603.         {
  1604.           FT_Vector  pp[4];
  1605.  
  1606.  
  1607.           /* Each time we call load_truetype_glyph in this loop, the   */
  1608.           /* value of `gloader.base.subglyphs' can change due to table */
  1609.           /* reallocations.  We thus need to recompute the subglyph    */
  1610.           /* pointer on each iteration.                                */
  1611.           subglyph = gloader->base.subglyphs + num_base_subgs + n;
  1612.  
  1613.           pp[0] = loader->pp1;
  1614.           pp[1] = loader->pp2;
  1615.           pp[2] = loader->pp3;
  1616.           pp[3] = loader->pp4;
  1617.  
  1618.           num_base_points = gloader->base.outline.n_points;
  1619.  
  1620.           error = load_truetype_glyph( loader, subglyph->index,
  1621.                                        recurse_count + 1, FALSE );
  1622.           if ( error )
  1623.             goto Exit;
  1624.  
  1625.           /* restore subglyph pointer */
  1626.           subglyph = gloader->base.subglyphs + num_base_subgs + n;
  1627.  
  1628.           if ( !( subglyph->flags & USE_MY_METRICS ) )
  1629.           {
  1630.             loader->pp1 = pp[0];
  1631.             loader->pp2 = pp[1];
  1632.             loader->pp3 = pp[2];
  1633.             loader->pp4 = pp[3];
  1634.           }
  1635.  
  1636.           num_points = gloader->base.outline.n_points;
  1637.  
  1638.           if ( num_points == num_base_points )
  1639.             continue;
  1640.  
  1641.           /* gloader->base.outline consists of three parts:               */
  1642.           /* 0 -(1)-> start_point -(2)-> num_base_points -(3)-> n_points. */
  1643.           /*                                                              */
  1644.           /* (1): exists from the beginning                               */
  1645.           /* (2): components that have been loaded so far                 */
  1646.           /* (3): the newly loaded component                              */
  1647.           TT_Process_Composite_Component( loader, subglyph, start_point,
  1648.                                           num_base_points );
  1649.         }
  1650.  
  1651.         loader->stream   = old_stream;
  1652.         loader->byte_len = old_byte_len;
  1653.  
  1654.         /* process the glyph */
  1655.         loader->ins_pos = ins_pos;
  1656.         if ( IS_HINTED( loader->load_flags ) &&
  1657.  
  1658. #ifdef TT_USE_BYTECODE_INTERPRETER
  1659.  
  1660.              subglyph->flags & WE_HAVE_INSTR &&
  1661.  
  1662. #endif
  1663.  
  1664.              num_points > start_point )
  1665.           TT_Process_Composite_Glyph( loader, start_point, start_contour );
  1666.  
  1667.       }
  1668.     }
  1669.     else
  1670.     {
  1671.       /* invalid composite count (negative but not -1) */
  1672.       error = FT_THROW( Invalid_Outline );
  1673.       goto Exit;
  1674.     }
  1675.  
  1676.     /***********************************************************************/
  1677.     /***********************************************************************/
  1678.     /***********************************************************************/
  1679.  
  1680.   Exit:
  1681.  
  1682.     if ( opened_frame )
  1683.       face->forget_glyph_frame( loader );
  1684.  
  1685. #ifdef FT_CONFIG_OPTION_INCREMENTAL
  1686.  
  1687.     if ( glyph_data_loaded )
  1688.       face->root.internal->incremental_interface->funcs->free_glyph_data(
  1689.         face->root.internal->incremental_interface->object,
  1690.         &glyph_data );
  1691.  
  1692. #endif
  1693.  
  1694.     return error;
  1695.   }
  1696.  
  1697.  
  1698.   static FT_Error
  1699.   compute_glyph_metrics( TT_Loader  loader,
  1700.                          FT_UInt    glyph_index )
  1701.   {
  1702.     TT_Face    face   = (TT_Face)loader->face;
  1703. #ifdef TT_CONFIG_OPTION_SUBPIXEL_HINTING
  1704.     TT_Driver  driver = (TT_Driver)FT_FACE_DRIVER( face );
  1705. #endif
  1706.  
  1707.     FT_BBox       bbox;
  1708.     FT_Fixed      y_scale;
  1709.     TT_GlyphSlot  glyph = loader->glyph;
  1710.     TT_Size       size  = (TT_Size)loader->size;
  1711.  
  1712.  
  1713.     y_scale = 0x10000L;
  1714.     if ( ( loader->load_flags & FT_LOAD_NO_SCALE ) == 0 )
  1715.       y_scale = size->root.metrics.y_scale;
  1716.  
  1717.     if ( glyph->format != FT_GLYPH_FORMAT_COMPOSITE )
  1718.       FT_Outline_Get_CBox( &glyph->outline, &bbox );
  1719.     else
  1720.       bbox = loader->bbox;
  1721.  
  1722.     /* get the device-independent horizontal advance; it is scaled later */
  1723.     /* by the base layer.                                                */
  1724.     glyph->linearHoriAdvance = loader->linear;
  1725.  
  1726.     glyph->metrics.horiBearingX = bbox.xMin;
  1727.     glyph->metrics.horiBearingY = bbox.yMax;
  1728.     glyph->metrics.horiAdvance  = loader->pp2.x - loader->pp1.x;
  1729.  
  1730.     /* adjust advance width to the value contained in the hdmx table */
  1731.     if ( !face->postscript.isFixedPitch  &&
  1732.          IS_HINTED( loader->load_flags ) )
  1733.     {
  1734.       FT_Byte*  widthp;
  1735.  
  1736.  
  1737.       widthp = tt_face_get_device_metrics( face,
  1738.                                            size->root.metrics.x_ppem,
  1739.                                            glyph_index );
  1740.  
  1741. #ifdef TT_CONFIG_OPTION_SUBPIXEL_HINTING
  1742.  
  1743.       if ( driver->interpreter_version == TT_INTERPRETER_VERSION_38 )
  1744.       {
  1745.         FT_Bool  ignore_x_mode;
  1746.  
  1747.  
  1748.         ignore_x_mode = FT_BOOL( FT_LOAD_TARGET_MODE( loader->load_flags ) !=
  1749.                                  FT_RENDER_MODE_MONO );
  1750.  
  1751.         if ( widthp                                                   &&
  1752.              ( ( ignore_x_mode && loader->exec->compatible_widths ) ||
  1753.                 !ignore_x_mode                                      ||
  1754.                 SPH_OPTION_BITMAP_WIDTHS                            ) )
  1755.           glyph->metrics.horiAdvance = *widthp << 6;
  1756.       }
  1757.       else
  1758.  
  1759. #endif /* TT_CONFIG_OPTION_SUBPIXEL_HINTING */
  1760.  
  1761.       {
  1762.         if ( widthp )
  1763.           glyph->metrics.horiAdvance = *widthp << 6;
  1764.       }
  1765.     }
  1766.  
  1767.     /* set glyph dimensions */
  1768.     glyph->metrics.width  = bbox.xMax - bbox.xMin;
  1769.     glyph->metrics.height = bbox.yMax - bbox.yMin;
  1770.  
  1771.     /* Now take care of vertical metrics.  In the case where there is */
  1772.     /* no vertical information within the font (relatively common),   */
  1773.     /* create some metrics manually                                   */
  1774.     {
  1775.       FT_Pos  top;      /* scaled vertical top side bearing  */
  1776.       FT_Pos  advance;  /* scaled vertical advance height    */
  1777.  
  1778.  
  1779.       /* Get the unscaled top bearing and advance height. */
  1780.       if ( face->vertical_info                   &&
  1781.            face->vertical.number_Of_VMetrics > 0 )
  1782.       {
  1783.         top = (FT_Short)FT_DivFix( loader->pp3.y - bbox.yMax,
  1784.                                    y_scale );
  1785.  
  1786.         if ( loader->pp3.y <= loader->pp4.y )
  1787.           advance = 0;
  1788.         else
  1789.           advance = (FT_UShort)FT_DivFix( loader->pp3.y - loader->pp4.y,
  1790.                                           y_scale );
  1791.       }
  1792.       else
  1793.       {
  1794.         FT_Pos  height;
  1795.  
  1796.  
  1797.         /* XXX Compute top side bearing and advance height in  */
  1798.         /*     Get_VMetrics instead of here.                   */
  1799.  
  1800.         /* NOTE: The OS/2 values are the only `portable' ones, */
  1801.         /*       which is why we use them, if there is an OS/2 */
  1802.         /*       table in the font.  Otherwise, we use the     */
  1803.         /*       values defined in the horizontal header.      */
  1804.  
  1805.         height = (FT_Short)FT_DivFix( bbox.yMax - bbox.yMin,
  1806.                                       y_scale );
  1807.         if ( face->os2.version != 0xFFFFU )
  1808.           advance = (FT_Pos)( face->os2.sTypoAscender -
  1809.                               face->os2.sTypoDescender );
  1810.         else
  1811.           advance = (FT_Pos)( face->horizontal.Ascender -
  1812.                               face->horizontal.Descender );
  1813.  
  1814.         top = ( advance - height ) / 2;
  1815.       }
  1816.  
  1817. #ifdef FT_CONFIG_OPTION_INCREMENTAL
  1818.       {
  1819.         FT_Incremental_InterfaceRec*  incr;
  1820.         FT_Incremental_MetricsRec     metrics;
  1821.         FT_Error                      error;
  1822.  
  1823.  
  1824.         incr = face->root.internal->incremental_interface;
  1825.  
  1826.         /* If this is an incrementally loaded font see if there are */
  1827.         /* overriding metrics for this glyph.                       */
  1828.         if ( incr && incr->funcs->get_glyph_metrics )
  1829.         {
  1830.           metrics.bearing_x = 0;
  1831.           metrics.bearing_y = top;
  1832.           metrics.advance   = advance;
  1833.  
  1834.           error = incr->funcs->get_glyph_metrics( incr->object,
  1835.                                                   glyph_index,
  1836.                                                   TRUE,
  1837.                                                   &metrics );
  1838.           if ( error )
  1839.             return error;
  1840.  
  1841.           top     = metrics.bearing_y;
  1842.           advance = metrics.advance;
  1843.         }
  1844.       }
  1845.  
  1846.       /* GWW: Do vertical metrics get loaded incrementally too? */
  1847.  
  1848. #endif /* FT_CONFIG_OPTION_INCREMENTAL */
  1849.  
  1850.       glyph->linearVertAdvance = advance;
  1851.  
  1852.       /* scale the metrics */
  1853.       if ( !( loader->load_flags & FT_LOAD_NO_SCALE ) )
  1854.       {
  1855.         top     = FT_MulFix( top,     y_scale );
  1856.         advance = FT_MulFix( advance, y_scale );
  1857.       }
  1858.  
  1859.       /* XXX: for now, we have no better algorithm for the lsb, but it */
  1860.       /*      should work fine.                                        */
  1861.       /*                                                               */
  1862.       glyph->metrics.vertBearingX = glyph->metrics.horiBearingX -
  1863.                                       glyph->metrics.horiAdvance / 2;
  1864.       glyph->metrics.vertBearingY = top;
  1865.       glyph->metrics.vertAdvance  = advance;
  1866.     }
  1867.  
  1868.     return 0;
  1869.   }
  1870.  
  1871.  
  1872. #ifdef TT_CONFIG_OPTION_EMBEDDED_BITMAPS
  1873.  
  1874.   static FT_Error
  1875.   load_sbit_image( TT_Size       size,
  1876.                    TT_GlyphSlot  glyph,
  1877.                    FT_UInt       glyph_index,
  1878.                    FT_Int32      load_flags )
  1879.   {
  1880.     TT_Face             face;
  1881.     SFNT_Service        sfnt;
  1882.     FT_Stream           stream;
  1883.     FT_Error            error;
  1884.     TT_SBit_MetricsRec  metrics;
  1885.  
  1886.  
  1887.     face   = (TT_Face)glyph->face;
  1888.     sfnt   = (SFNT_Service)face->sfnt;
  1889.     stream = face->root.stream;
  1890.  
  1891.     error = sfnt->load_sbit_image( face,
  1892.                                    size->strike_index,
  1893.                                    glyph_index,
  1894.                                    (FT_Int)load_flags,
  1895.                                    stream,
  1896.                                    &glyph->bitmap,
  1897.                                    &metrics );
  1898.     if ( !error )
  1899.     {
  1900.       glyph->outline.n_points   = 0;
  1901.       glyph->outline.n_contours = 0;
  1902.  
  1903.       glyph->metrics.width  = (FT_Pos)metrics.width  << 6;
  1904.       glyph->metrics.height = (FT_Pos)metrics.height << 6;
  1905.  
  1906.       glyph->metrics.horiBearingX = (FT_Pos)metrics.horiBearingX << 6;
  1907.       glyph->metrics.horiBearingY = (FT_Pos)metrics.horiBearingY << 6;
  1908.       glyph->metrics.horiAdvance  = (FT_Pos)metrics.horiAdvance  << 6;
  1909.  
  1910.       glyph->metrics.vertBearingX = (FT_Pos)metrics.vertBearingX << 6;
  1911.       glyph->metrics.vertBearingY = (FT_Pos)metrics.vertBearingY << 6;
  1912.       glyph->metrics.vertAdvance  = (FT_Pos)metrics.vertAdvance  << 6;
  1913.  
  1914.       glyph->format = FT_GLYPH_FORMAT_BITMAP;
  1915.  
  1916.       if ( load_flags & FT_LOAD_VERTICAL_LAYOUT )
  1917.       {
  1918.         glyph->bitmap_left = metrics.vertBearingX;
  1919.         glyph->bitmap_top  = metrics.vertBearingY;
  1920.       }
  1921.       else
  1922.       {
  1923.         glyph->bitmap_left = metrics.horiBearingX;
  1924.         glyph->bitmap_top  = metrics.horiBearingY;
  1925.       }
  1926.     }
  1927.  
  1928.     return error;
  1929.   }
  1930.  
  1931. #endif /* TT_CONFIG_OPTION_EMBEDDED_BITMAPS */
  1932.  
  1933.  
  1934.   static FT_Error
  1935.   tt_loader_init( TT_Loader     loader,
  1936.                   TT_Size       size,
  1937.                   TT_GlyphSlot  glyph,
  1938.                   FT_Int32      load_flags,
  1939.                   FT_Bool       glyf_table_only )
  1940.   {
  1941.     TT_Face    face;
  1942.     FT_Stream  stream;
  1943. #ifdef TT_USE_BYTECODE_INTERPRETER
  1944.     FT_Bool    pedantic = FT_BOOL( load_flags & FT_LOAD_PEDANTIC );
  1945. #endif
  1946.  
  1947.  
  1948.     face   = (TT_Face)glyph->face;
  1949.     stream = face->root.stream;
  1950.  
  1951.     FT_MEM_ZERO( loader, sizeof ( TT_LoaderRec ) );
  1952.  
  1953. #ifdef TT_USE_BYTECODE_INTERPRETER
  1954.  
  1955.     /* load execution context */
  1956.     if ( IS_HINTED( load_flags ) && !glyf_table_only )
  1957.     {
  1958.       TT_ExecContext  exec;
  1959.       FT_Bool         grayscale;
  1960.  
  1961. #ifdef TT_CONFIG_OPTION_SUBPIXEL_HINTING
  1962.       TT_Driver  driver = (TT_Driver)FT_FACE_DRIVER( face );
  1963.  
  1964.       FT_Bool  subpixel_hinting  = FALSE;
  1965.       FT_Bool  grayscale_hinting = TRUE;
  1966.  
  1967. #if 0
  1968.       /* not used yet */
  1969.       FT_Bool  compatible_widths;
  1970.       FT_Bool  symmetrical_smoothing;
  1971.       FT_Bool  bgr;
  1972.       FT_Bool  subpixel_positioned;
  1973. #endif
  1974. #endif /* TT_CONFIG_OPTION_SUBPIXEL_HINTING */
  1975.  
  1976.       FT_Bool  reexecute = FALSE;
  1977.  
  1978.  
  1979.       if ( !size->cvt_ready )
  1980.       {
  1981.         FT_Error  error = tt_size_ready_bytecode( size, pedantic );
  1982.  
  1983.  
  1984.         if ( error )
  1985.           return error;
  1986.       }
  1987.  
  1988.       /* query new execution context */
  1989.       exec = size->debug ? size->context
  1990.                          : ( (TT_Driver)FT_FACE_DRIVER( face ) )->context;
  1991.       if ( !exec )
  1992.         return FT_THROW( Could_Not_Find_Context );
  1993.  
  1994. #ifdef TT_CONFIG_OPTION_SUBPIXEL_HINTING
  1995.  
  1996.       if ( driver->interpreter_version == TT_INTERPRETER_VERSION_38 )
  1997.       {
  1998.         subpixel_hinting = FT_BOOL( ( FT_LOAD_TARGET_MODE( load_flags )
  1999.                                       != FT_RENDER_MODE_MONO )          &&
  2000.                                     SPH_OPTION_SET_SUBPIXEL             );
  2001.  
  2002.         if ( subpixel_hinting )
  2003.           grayscale = grayscale_hinting = FALSE;
  2004.         else if ( SPH_OPTION_SET_GRAYSCALE )
  2005.         {
  2006.           grayscale = grayscale_hinting = TRUE;
  2007.           subpixel_hinting              = FALSE;
  2008.         }
  2009.         else
  2010.           grayscale = grayscale_hinting = FALSE;
  2011.  
  2012.         if ( FT_IS_TRICKY( glyph->face ) )
  2013.           subpixel_hinting = grayscale_hinting = FALSE;
  2014.  
  2015.         exec->ignore_x_mode      = subpixel_hinting || grayscale_hinting;
  2016.         exec->rasterizer_version = SPH_OPTION_SET_RASTERIZER_VERSION;
  2017.         if ( exec->sph_tweak_flags & SPH_TWEAK_RASTERIZER_35 )
  2018.           exec->rasterizer_version = TT_INTERPRETER_VERSION_35;
  2019.  
  2020. #if 1
  2021.         exec->compatible_widths     = SPH_OPTION_SET_COMPATIBLE_WIDTHS;
  2022.         exec->symmetrical_smoothing = FALSE;
  2023.         exec->bgr                   = FALSE;
  2024.         exec->subpixel_positioned   = TRUE;
  2025. #else /* 0 */
  2026.         exec->compatible_widths =
  2027.           FT_BOOL( FT_LOAD_TARGET_MODE( load_flags ) !=
  2028.                    TT_LOAD_COMPATIBLE_WIDTHS );
  2029.         exec->symmetrical_smoothing =
  2030.           FT_BOOL( FT_LOAD_TARGET_MODE( load_flags ) !=
  2031.                    TT_LOAD_SYMMETRICAL_SMOOTHING );
  2032.         exec->bgr =
  2033.           FT_BOOL( FT_LOAD_TARGET_MODE( load_flags ) !=
  2034.                    TT_LOAD_BGR );
  2035.         exec->subpixel_positioned =
  2036.           FT_BOOL( FT_LOAD_TARGET_MODE( load_flags ) !=
  2037.                    TT_LOAD_SUBPIXEL_POSITIONED );
  2038. #endif /* 0 */
  2039.  
  2040.       }
  2041.       else
  2042.  
  2043. #endif /* TT_CONFIG_OPTION_SUBPIXEL_HINTING */
  2044.  
  2045.       {
  2046.         grayscale = FT_BOOL( FT_LOAD_TARGET_MODE( load_flags ) !=
  2047.                              FT_RENDER_MODE_MONO );
  2048.       }
  2049.  
  2050.       TT_Load_Context( exec, face, size );
  2051.  
  2052. #ifdef TT_CONFIG_OPTION_SUBPIXEL_HINTING
  2053.  
  2054.       if ( driver->interpreter_version == TT_INTERPRETER_VERSION_38 )
  2055.       {
  2056.         /* a change from mono to subpixel rendering (and vice versa) */
  2057.         /* requires a re-execution of the CVT program                */
  2058.         if ( subpixel_hinting != exec->subpixel_hinting )
  2059.         {
  2060.           FT_TRACE4(( "tt_loader_init: subpixel hinting change,"
  2061.                       " re-executing `prep' table\n" ));
  2062.  
  2063.           exec->subpixel_hinting = subpixel_hinting;
  2064.           reexecute              = TRUE;
  2065.         }
  2066.  
  2067.         /* a change from mono to grayscale rendering (and vice versa) */
  2068.         /* requires a re-execution of the CVT program                 */
  2069.         if ( grayscale != exec->grayscale_hinting )
  2070.         {
  2071.           FT_TRACE4(( "tt_loader_init: grayscale hinting change,"
  2072.                       " re-executing `prep' table\n" ));
  2073.  
  2074.           exec->grayscale_hinting = grayscale_hinting;
  2075.           reexecute               = TRUE;
  2076.         }
  2077.       }
  2078.       else
  2079.  
  2080. #endif /* TT_CONFIG_OPTION_SUBPIXEL_HINTING */
  2081.  
  2082.       {
  2083.         /* a change from mono to grayscale rendering (and vice versa) */
  2084.         /* requires a re-execution of the CVT program                 */
  2085.         if ( grayscale != exec->grayscale )
  2086.         {
  2087.           FT_TRACE4(( "tt_loader_init: grayscale change,"
  2088.                       " re-executing `prep' table\n" ));
  2089.  
  2090.           exec->grayscale = grayscale;
  2091.           reexecute       = TRUE;
  2092.         }
  2093.       }
  2094.  
  2095.       if ( reexecute )
  2096.       {
  2097.         FT_UInt  i;
  2098.  
  2099.  
  2100.         for ( i = 0; i < size->cvt_size; i++ )
  2101.           size->cvt[i] = FT_MulFix( face->cvt[i], size->ttmetrics.scale );
  2102.         tt_size_run_prep( size, pedantic );
  2103.       }
  2104.  
  2105.       /* see whether the cvt program has disabled hinting */
  2106.       if ( exec->GS.instruct_control & 1 )
  2107.         load_flags |= FT_LOAD_NO_HINTING;
  2108.  
  2109.       /* load default graphics state -- if needed */
  2110.       if ( exec->GS.instruct_control & 2 )
  2111.         exec->GS = tt_default_graphics_state;
  2112.  
  2113.       exec->pedantic_hinting = FT_BOOL( load_flags & FT_LOAD_PEDANTIC );
  2114.       loader->exec = exec;
  2115.       loader->instructions = exec->glyphIns;
  2116.     }
  2117.  
  2118. #endif /* TT_USE_BYTECODE_INTERPRETER */
  2119.  
  2120.     /* seek to the beginning of the glyph table -- for Type 42 fonts     */
  2121.     /* the table might be accessed from a Postscript stream or something */
  2122.     /* else...                                                           */
  2123.  
  2124. #ifdef FT_CONFIG_OPTION_INCREMENTAL
  2125.  
  2126.     if ( face->root.internal->incremental_interface )
  2127.       loader->glyf_offset = 0;
  2128.     else
  2129.  
  2130. #endif
  2131.  
  2132.     {
  2133.       FT_Error  error = face->goto_table( face, TTAG_glyf, stream, 0 );
  2134.  
  2135.  
  2136.       if ( FT_ERR_EQ( error, Table_Missing ) )
  2137.         loader->glyf_offset = 0;
  2138.       else if ( error )
  2139.       {
  2140.         FT_ERROR(( "tt_loader_init: could not access glyph table\n" ));
  2141.         return error;
  2142.       }
  2143.       else
  2144.         loader->glyf_offset = FT_STREAM_POS();
  2145.     }
  2146.  
  2147.     /* get face's glyph loader */
  2148.     if ( !glyf_table_only )
  2149.     {
  2150.       FT_GlyphLoader  gloader = glyph->internal->loader;
  2151.  
  2152.  
  2153.       FT_GlyphLoader_Rewind( gloader );
  2154.       loader->gloader = gloader;
  2155.     }
  2156.  
  2157.     loader->load_flags = load_flags;
  2158.  
  2159.     loader->face   = (FT_Face)face;
  2160.     loader->size   = (FT_Size)size;
  2161.     loader->glyph  = (FT_GlyphSlot)glyph;
  2162.     loader->stream = stream;
  2163.  
  2164.     return FT_Err_Ok;
  2165.   }
  2166.  
  2167.  
  2168.   /*************************************************************************/
  2169.   /*                                                                       */
  2170.   /* <Function>                                                            */
  2171.   /*    TT_Load_Glyph                                                      */
  2172.   /*                                                                       */
  2173.   /* <Description>                                                         */
  2174.   /*    A function used to load a single glyph within a given glyph slot,  */
  2175.   /*    for a given size.                                                  */
  2176.   /*                                                                       */
  2177.   /* <Input>                                                               */
  2178.   /*    glyph       :: A handle to a target slot object where the glyph    */
  2179.   /*                   will be loaded.                                     */
  2180.   /*                                                                       */
  2181.   /*    size        :: A handle to the source face size at which the glyph */
  2182.   /*                   must be scaled/loaded.                              */
  2183.   /*                                                                       */
  2184.   /*    glyph_index :: The index of the glyph in the font file.            */
  2185.   /*                                                                       */
  2186.   /*    load_flags  :: A flag indicating what to load for this glyph.  The */
  2187.   /*                   FT_LOAD_XXX constants can be used to control the    */
  2188.   /*                   glyph loading process (e.g., whether the outline    */
  2189.   /*                   should be scaled, whether to load bitmaps or not,   */
  2190.   /*                   whether to hint the outline, etc).                  */
  2191.   /*                                                                       */
  2192.   /* <Return>                                                              */
  2193.   /*    FreeType error code.  0 means success.                             */
  2194.   /*                                                                       */
  2195.   FT_LOCAL_DEF( FT_Error )
  2196.   TT_Load_Glyph( TT_Size       size,
  2197.                  TT_GlyphSlot  glyph,
  2198.                  FT_UInt       glyph_index,
  2199.                  FT_Int32      load_flags )
  2200.   {
  2201.     FT_Error      error;
  2202.     TT_LoaderRec  loader;
  2203.  
  2204.  
  2205.     error = FT_Err_Ok;
  2206.  
  2207. #ifdef TT_CONFIG_OPTION_EMBEDDED_BITMAPS
  2208.  
  2209.     /* try to load embedded bitmap if any              */
  2210.     /*                                                 */
  2211.     /* XXX: The convention should be emphasized in     */
  2212.     /*      the documents because it can be confusing. */
  2213.     if ( size->strike_index != 0xFFFFFFFFUL      &&
  2214.          ( load_flags & FT_LOAD_NO_BITMAP ) == 0 )
  2215.     {
  2216.       error = load_sbit_image( size, glyph, glyph_index, load_flags );
  2217.       if ( !error )
  2218.       {
  2219.         if ( FT_IS_SCALABLE( glyph->face ) )
  2220.         {
  2221.           /* for the bbox we need the header only */
  2222.           (void)tt_loader_init( &loader, size, glyph, load_flags, TRUE );
  2223.           (void)load_truetype_glyph( &loader, glyph_index, 0, TRUE );
  2224.           glyph->linearHoriAdvance = loader.linear;
  2225.           glyph->linearVertAdvance = loader.top_bearing + loader.bbox.yMax -
  2226.                                        loader.vadvance;
  2227.  
  2228.           /* sanity check: if `horiAdvance' in the sbit metric */
  2229.           /* structure isn't set, use `linearHoriAdvance'      */
  2230.           if ( !glyph->metrics.horiAdvance && glyph->linearHoriAdvance )
  2231.             glyph->metrics.horiAdvance =
  2232.               FT_MulFix( glyph->linearHoriAdvance,
  2233.                          size->root.metrics.x_scale );
  2234.         }
  2235.  
  2236.         return FT_Err_Ok;
  2237.       }
  2238.     }
  2239.  
  2240. #endif /* TT_CONFIG_OPTION_EMBEDDED_BITMAPS */
  2241.  
  2242.     /* if FT_LOAD_NO_SCALE is not set, `ttmetrics' must be valid */
  2243.     if ( !( load_flags & FT_LOAD_NO_SCALE ) && !size->ttmetrics.valid )
  2244.       return FT_THROW( Invalid_Size_Handle );
  2245.  
  2246.     if ( load_flags & FT_LOAD_SBITS_ONLY )
  2247.       return FT_THROW( Invalid_Argument );
  2248.  
  2249.     error = tt_loader_init( &loader, size, glyph, load_flags, FALSE );
  2250.     if ( error )
  2251.       return error;
  2252.  
  2253.     glyph->format        = FT_GLYPH_FORMAT_OUTLINE;
  2254.     glyph->num_subglyphs = 0;
  2255.     glyph->outline.flags = 0;
  2256.  
  2257.     /* main loading loop */
  2258.     error = load_truetype_glyph( &loader, glyph_index, 0, FALSE );
  2259.     if ( !error )
  2260.     {
  2261.       if ( glyph->format == FT_GLYPH_FORMAT_COMPOSITE )
  2262.       {
  2263.         glyph->num_subglyphs = loader.gloader->base.num_subglyphs;
  2264.         glyph->subglyphs     = loader.gloader->base.subglyphs;
  2265.       }
  2266.       else
  2267.       {
  2268.         glyph->outline        = loader.gloader->base.outline;
  2269.         glyph->outline.flags &= ~FT_OUTLINE_SINGLE_PASS;
  2270.  
  2271.         /* Translate array so that (0,0) is the glyph's origin.  Note  */
  2272.         /* that this behaviour is independent on the value of bit 1 of */
  2273.         /* the `flags' field in the `head' table -- at least major     */
  2274.         /* applications like Acroread indicate that.                   */
  2275.         if ( loader.pp1.x )
  2276.           FT_Outline_Translate( &glyph->outline, -loader.pp1.x, 0 );
  2277.       }
  2278.  
  2279. #ifdef TT_USE_BYTECODE_INTERPRETER
  2280.  
  2281.       if ( IS_HINTED( load_flags ) )
  2282.       {
  2283.         if ( loader.exec->GS.scan_control )
  2284.         {
  2285.           /* convert scan conversion mode to FT_OUTLINE_XXX flags */
  2286.           switch ( loader.exec->GS.scan_type )
  2287.           {
  2288.           case 0: /* simple drop-outs including stubs */
  2289.             glyph->outline.flags |= FT_OUTLINE_INCLUDE_STUBS;
  2290.             break;
  2291.           case 1: /* simple drop-outs excluding stubs */
  2292.             /* nothing; it's the default rendering mode */
  2293.             break;
  2294.           case 4: /* smart drop-outs including stubs */
  2295.             glyph->outline.flags |= FT_OUTLINE_SMART_DROPOUTS |
  2296.                                     FT_OUTLINE_INCLUDE_STUBS;
  2297.             break;
  2298.           case 5: /* smart drop-outs excluding stubs  */
  2299.             glyph->outline.flags |= FT_OUTLINE_SMART_DROPOUTS;
  2300.             break;
  2301.  
  2302.           default: /* no drop-out control */
  2303.             glyph->outline.flags |= FT_OUTLINE_IGNORE_DROPOUTS;
  2304.             break;
  2305.           }
  2306.         }
  2307.         else
  2308.           glyph->outline.flags |= FT_OUTLINE_IGNORE_DROPOUTS;
  2309.       }
  2310.  
  2311. #endif /* TT_USE_BYTECODE_INTERPRETER */
  2312.  
  2313.       compute_glyph_metrics( &loader, glyph_index );
  2314.     }
  2315.  
  2316.     /* Set the `high precision' bit flag.                           */
  2317.     /* This is _critical_ to get correct output for monochrome      */
  2318.     /* TrueType glyphs at all sizes using the bytecode interpreter. */
  2319.     /*                                                              */
  2320.     if ( !( load_flags & FT_LOAD_NO_SCALE ) &&
  2321.          size->root.metrics.y_ppem < 24     )
  2322.       glyph->outline.flags |= FT_OUTLINE_HIGH_PRECISION;
  2323.  
  2324.     return error;
  2325.   }
  2326.  
  2327.  
  2328. /* END */
  2329.