Home | History | Annotate | Download | only in truetype
      1 /***************************************************************************/
      2 /*                                                                         */
      3 /*  ttobjs.c                                                               */
      4 /*                                                                         */
      5 /*    Objects manager (body).                                              */
      6 /*                                                                         */
      7 /*  Copyright 1996-2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009 by */
      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_STREAM_H
     22 #include FT_TRUETYPE_TAGS_H
     23 #include FT_INTERNAL_SFNT_H
     24 
     25 #include "ttgload.h"
     26 #include "ttpload.h"
     27 
     28 #include "tterrors.h"
     29 
     30 #ifdef TT_USE_BYTECODE_INTERPRETER
     31 #include "ttinterp.h"
     32 #endif
     33 
     34 #ifdef TT_CONFIG_OPTION_UNPATENTED_HINTING
     35 #include FT_TRUETYPE_UNPATENTED_H
     36 #endif
     37 
     38 #ifdef TT_CONFIG_OPTION_GX_VAR_SUPPORT
     39 #include "ttgxvar.h"
     40 #endif
     41 
     42   /*************************************************************************/
     43   /*                                                                       */
     44   /* The macro FT_COMPONENT is used in trace mode.  It is an implicit      */
     45   /* parameter of the FT_TRACE() and FT_ERROR() macros, used to print/log  */
     46   /* messages during execution.                                            */
     47   /*                                                                       */
     48 #undef  FT_COMPONENT
     49 #define FT_COMPONENT  trace_ttobjs
     50 
     51 
     52 #ifdef TT_USE_BYTECODE_INTERPRETER
     53 
     54   /*************************************************************************/
     55   /*                                                                       */
     56   /*                       GLYPH ZONE FUNCTIONS                            */
     57   /*                                                                       */
     58   /*************************************************************************/
     59 
     60 
     61   /*************************************************************************/
     62   /*                                                                       */
     63   /* <Function>                                                            */
     64   /*    tt_glyphzone_done                                                  */
     65   /*                                                                       */
     66   /* <Description>                                                         */
     67   /*    Deallocate a glyph zone.                                           */
     68   /*                                                                       */
     69   /* <Input>                                                               */
     70   /*    zone :: A pointer to the target glyph zone.                        */
     71   /*                                                                       */
     72   FT_LOCAL_DEF( void )
     73   tt_glyphzone_done( TT_GlyphZone  zone )
     74   {
     75     FT_Memory  memory = zone->memory;
     76 
     77 
     78     if ( memory )
     79     {
     80       FT_FREE( zone->contours );
     81       FT_FREE( zone->tags );
     82       FT_FREE( zone->cur );
     83       FT_FREE( zone->org );
     84       FT_FREE( zone->orus );
     85 
     86       zone->max_points   = zone->n_points   = 0;
     87       zone->max_contours = zone->n_contours = 0;
     88       zone->memory       = NULL;
     89     }
     90   }
     91 
     92 
     93   /*************************************************************************/
     94   /*                                                                       */
     95   /* <Function>                                                            */
     96   /*    tt_glyphzone_new                                                   */
     97   /*                                                                       */
     98   /* <Description>                                                         */
     99   /*    Allocate a new glyph zone.                                         */
    100   /*                                                                       */
    101   /* <Input>                                                               */
    102   /*    memory      :: A handle to the current memory object.              */
    103   /*                                                                       */
    104   /*    maxPoints   :: The capacity of glyph zone in points.               */
    105   /*                                                                       */
    106   /*    maxContours :: The capacity of glyph zone in contours.             */
    107   /*                                                                       */
    108   /* <Output>                                                              */
    109   /*    zone        :: A pointer to the target glyph zone record.          */
    110   /*                                                                       */
    111   /* <Return>                                                              */
    112   /*    FreeType error code.  0 means success.                             */
    113   /*                                                                       */
    114   FT_LOCAL_DEF( FT_Error )
    115   tt_glyphzone_new( FT_Memory     memory,
    116                     FT_UShort     maxPoints,
    117                     FT_Short      maxContours,
    118                     TT_GlyphZone  zone )
    119   {
    120     FT_Error  error;
    121 
    122 
    123     FT_MEM_ZERO( zone, sizeof ( *zone ) );
    124     zone->memory = memory;
    125 
    126     if ( FT_NEW_ARRAY( zone->org,      maxPoints   ) ||
    127          FT_NEW_ARRAY( zone->cur,      maxPoints   ) ||
    128          FT_NEW_ARRAY( zone->orus,     maxPoints   ) ||
    129          FT_NEW_ARRAY( zone->tags,     maxPoints   ) ||
    130          FT_NEW_ARRAY( zone->contours, maxContours ) )
    131     {
    132       tt_glyphzone_done( zone );
    133     }
    134     else
    135     {
    136       zone->max_points   = maxPoints;
    137       zone->max_contours = maxContours;
    138     }
    139 
    140     return error;
    141   }
    142 #endif /* TT_USE_BYTECODE_INTERPRETER */
    143 
    144 
    145   /* Compare the face with a list of well-known `tricky' fonts. */
    146   /* This list shall be expanded as we find more of them.       */
    147 
    148   static FT_Bool
    149   tt_check_trickyness( FT_String*  name )
    150   {
    151 #define TRICK_NAMES_MAX_CHARACTERS  16
    152 #define TRICK_NAMES_COUNT 7
    153     static const char trick_names[TRICK_NAMES_COUNT][TRICK_NAMES_MAX_CHARACTERS+1] =
    154     {
    155       "DFKaiSho-SB",     /* dfkaisb.ttf */
    156       "DFKaiShu",
    157       "DFKai-SB",        /* kaiu.ttf */
    158       "HuaTianSongTi?",  /* htst3.ttf */
    159       "MingLiU",         /* mingliu.ttf & mingliu.ttc */
    160       "PMingLiU",        /* mingliu.ttc */
    161       "MingLi43",        /* mingli.ttf */
    162     };
    163     int  nn;
    164 
    165 
    166     if ( !name )
    167       return FALSE;
    168 
    169     /* Note that we only check the face name at the moment; it might */
    170     /* be worth to do more checks for a few special cases.           */
    171     for ( nn = 0; nn < TRICK_NAMES_COUNT; nn++ )
    172       if ( ft_strstr( name, trick_names[nn] ) )
    173         return TRUE;
    174 
    175     return FALSE;
    176   }
    177 
    178 
    179   /*************************************************************************/
    180   /*                                                                       */
    181   /* <Function>                                                            */
    182   /*    tt_face_init                                                       */
    183   /*                                                                       */
    184   /* <Description>                                                         */
    185   /*    Initialize a given TrueType face object.                           */
    186   /*                                                                       */
    187   /* <Input>                                                               */
    188   /*    stream     :: The source font stream.                              */
    189   /*                                                                       */
    190   /*    face_index :: The index of the font face in the resource.          */
    191   /*                                                                       */
    192   /*    num_params :: Number of additional generic parameters.  Ignored.   */
    193   /*                                                                       */
    194   /*    params     :: Additional generic parameters.  Ignored.             */
    195   /*                                                                       */
    196   /* <InOut>                                                               */
    197   /*    face       :: The newly built face object.                         */
    198   /*                                                                       */
    199   /* <Return>                                                              */
    200   /*    FreeType error code.  0 means success.                             */
    201   /*                                                                       */
    202   FT_LOCAL_DEF( FT_Error )
    203   tt_face_init( FT_Stream      stream,
    204                 FT_Face        ttface,      /* TT_Face */
    205                 FT_Int         face_index,
    206                 FT_Int         num_params,
    207                 FT_Parameter*  params )
    208   {
    209     FT_Error      error;
    210     FT_Library    library;
    211     SFNT_Service  sfnt;
    212     TT_Face       face = (TT_Face)ttface;
    213 
    214 
    215     library = ttface->driver->root.library;
    216     sfnt    = (SFNT_Service)FT_Get_Module_Interface( library, "sfnt" );
    217     if ( !sfnt )
    218       goto Bad_Format;
    219 
    220     /* create input stream from resource */
    221     if ( FT_STREAM_SEEK( 0 ) )
    222       goto Exit;
    223 
    224     /* check that we have a valid TrueType file */
    225     error = sfnt->init_face( stream, face, face_index, num_params, params );
    226     if ( error )
    227       goto Exit;
    228 
    229     /* We must also be able to accept Mac/GX fonts, as well as OT ones. */
    230     /* The 0x00020000 tag is completely undocumented; some fonts from   */
    231     /* Arphic made for Chinese Windows 3.1 have this.                   */
    232     if ( face->format_tag != 0x00010000L &&    /* MS fonts  */
    233          face->format_tag != 0x00020000L &&    /* CJK fonts for Win 3.1 */
    234          face->format_tag != TTAG_true   )     /* Mac fonts */
    235     {
    236       FT_TRACE2(( "[not a valid TTF font]\n" ));
    237       goto Bad_Format;
    238     }
    239 
    240 #ifdef TT_USE_BYTECODE_INTERPRETER
    241     ttface->face_flags |= FT_FACE_FLAG_HINTER;
    242 #endif
    243 
    244     /* If we are performing a simple font format check, exit immediately. */
    245     if ( face_index < 0 )
    246       return TT_Err_Ok;
    247 
    248     /* Load font directory */
    249     error = sfnt->load_face( stream, face, face_index, num_params, params );
    250     if ( error )
    251       goto Exit;
    252 
    253     if ( tt_check_trickyness( ttface->family_name ) )
    254       ttface->face_flags |= FT_FACE_FLAG_TRICKY;
    255 
    256     error = tt_face_load_hdmx( face, stream );
    257     if ( error )
    258       goto Exit;
    259 
    260     if ( FT_IS_SCALABLE( ttface ) )
    261     {
    262 
    263 #ifdef FT_CONFIG_OPTION_INCREMENTAL
    264 
    265       if ( !ttface->internal->incremental_interface )
    266         error = tt_face_load_loca( face, stream );
    267       if ( !error )
    268         error = tt_face_load_cvt( face, stream );
    269       if ( !error )
    270         error = tt_face_load_fpgm( face, stream );
    271       if ( !error )
    272         error = tt_face_load_prep( face, stream );
    273 
    274 #else
    275 
    276       if ( !error )
    277         error = tt_face_load_loca( face, stream );
    278       if ( !error )
    279         error = tt_face_load_cvt( face, stream );
    280       if ( !error )
    281         error = tt_face_load_fpgm( face, stream );
    282       if ( !error )
    283         error = tt_face_load_prep( face, stream );
    284 
    285 #endif
    286 
    287     }
    288 
    289 #if defined( TT_CONFIG_OPTION_UNPATENTED_HINTING    ) && \
    290     !defined( TT_CONFIG_OPTION_BYTECODE_INTERPRETER )
    291 
    292     {
    293       FT_Bool  unpatented_hinting;
    294       int      i;
    295 
    296 
    297       /* Determine whether unpatented hinting is to be used for this face. */
    298       unpatented_hinting = FT_BOOL
    299         ( library->debug_hooks[FT_DEBUG_HOOK_UNPATENTED_HINTING] != NULL );
    300 
    301       for ( i = 0; i < num_params && !face->unpatented_hinting; i++ )
    302         if ( params[i].tag == FT_PARAM_TAG_UNPATENTED_HINTING )
    303           unpatented_hinting = TRUE;
    304 
    305       if ( !unpatented_hinting )
    306         ttface->internal->ignore_unpatented_hinter = TRUE;
    307     }
    308 
    309 #endif /* TT_CONFIG_OPTION_UNPATENTED_HINTING &&
    310           !TT_CONFIG_OPTION_BYTECODE_INTERPRETER */
    311 
    312     /* initialize standard glyph loading routines */
    313     TT_Init_Glyph_Loading( face );
    314 
    315   Exit:
    316     return error;
    317 
    318   Bad_Format:
    319     error = TT_Err_Unknown_File_Format;
    320     goto Exit;
    321   }
    322 
    323 
    324   /*************************************************************************/
    325   /*                                                                       */
    326   /* <Function>                                                            */
    327   /*    tt_face_done                                                       */
    328   /*                                                                       */
    329   /* <Description>                                                         */
    330   /*    Finalize a given face object.                                      */
    331   /*                                                                       */
    332   /* <Input>                                                               */
    333   /*    face :: A pointer to the face object to destroy.                   */
    334   /*                                                                       */
    335   FT_LOCAL_DEF( void )
    336   tt_face_done( FT_Face  ttface )           /* TT_Face */
    337   {
    338     TT_Face       face = (TT_Face)ttface;
    339     FT_Memory     memory;
    340     FT_Stream     stream;
    341     SFNT_Service  sfnt;
    342 
    343 
    344     if ( !face )
    345       return;
    346 
    347     memory = ttface->memory;
    348     stream = ttface->stream;
    349     sfnt   = (SFNT_Service)face->sfnt;
    350 
    351     /* for `extended TrueType formats' (i.e. compressed versions) */
    352     if ( face->extra.finalizer )
    353       face->extra.finalizer( face->extra.data );
    354 
    355     if ( sfnt )
    356       sfnt->done_face( face );
    357 
    358     /* freeing the locations table */
    359     tt_face_done_loca( face );
    360 
    361     tt_face_free_hdmx( face );
    362 
    363     /* freeing the CVT */
    364     FT_FREE( face->cvt );
    365     face->cvt_size = 0;
    366 
    367     /* freeing the programs */
    368     FT_FRAME_RELEASE( face->font_program );
    369     FT_FRAME_RELEASE( face->cvt_program );
    370     face->font_program_size = 0;
    371     face->cvt_program_size  = 0;
    372 
    373 #ifdef TT_CONFIG_OPTION_GX_VAR_SUPPORT
    374     tt_done_blend( memory, face->blend );
    375     face->blend = NULL;
    376 #endif
    377   }
    378 
    379 
    380   /*************************************************************************/
    381   /*                                                                       */
    382   /*                           SIZE  FUNCTIONS                             */
    383   /*                                                                       */
    384   /*************************************************************************/
    385 
    386 #ifdef TT_USE_BYTECODE_INTERPRETER
    387 
    388   /*************************************************************************/
    389   /*                                                                       */
    390   /* <Function>                                                            */
    391   /*    tt_size_run_fpgm                                                   */
    392   /*                                                                       */
    393   /* <Description>                                                         */
    394   /*    Run the font program.                                              */
    395   /*                                                                       */
    396   /* <Input>                                                               */
    397   /*    size :: A handle to the size object.                               */
    398   /*                                                                       */
    399   /* <Return>                                                              */
    400   /*    FreeType error code.  0 means success.                             */
    401   /*                                                                       */
    402   FT_LOCAL_DEF( FT_Error )
    403   tt_size_run_fpgm( TT_Size  size )
    404   {
    405     TT_Face         face = (TT_Face)size->root.face;
    406     TT_ExecContext  exec;
    407     FT_Error        error;
    408 
    409 
    410     /* debugging instances have their own context */
    411     if ( size->debug )
    412       exec = size->context;
    413     else
    414       exec = ( (TT_Driver)FT_FACE_DRIVER( face ) )->context;
    415 
    416     if ( !exec )
    417       return TT_Err_Could_Not_Find_Context;
    418 
    419     TT_Load_Context( exec, face, size );
    420 
    421     exec->callTop   = 0;
    422     exec->top       = 0;
    423 
    424     exec->period    = 64;
    425     exec->phase     = 0;
    426     exec->threshold = 0;
    427 
    428     exec->instruction_trap = FALSE;
    429     exec->F_dot_P = 0x10000L;
    430 
    431     {
    432       FT_Size_Metrics*  metrics    = &exec->metrics;
    433       TT_Size_Metrics*  tt_metrics = &exec->tt_metrics;
    434 
    435 
    436       metrics->x_ppem   = 0;
    437       metrics->y_ppem   = 0;
    438       metrics->x_scale  = 0;
    439       metrics->y_scale  = 0;
    440 
    441       tt_metrics->ppem  = 0;
    442       tt_metrics->scale = 0;
    443       tt_metrics->ratio = 0x10000L;
    444     }
    445 
    446     /* allow font program execution */
    447     TT_Set_CodeRange( exec,
    448                       tt_coderange_font,
    449                       face->font_program,
    450                       face->font_program_size );
    451 
    452     /* disable CVT and glyph programs coderange */
    453     TT_Clear_CodeRange( exec, tt_coderange_cvt );
    454     TT_Clear_CodeRange( exec, tt_coderange_glyph );
    455 
    456     if ( face->font_program_size > 0 )
    457     {
    458       error = TT_Goto_CodeRange( exec, tt_coderange_font, 0 );
    459 
    460       if ( !error )
    461         error = face->interpreter( exec );
    462     }
    463     else
    464       error = TT_Err_Ok;
    465 
    466     if ( !error )
    467       TT_Save_Context( exec, size );
    468 
    469     return error;
    470   }
    471 
    472 
    473   /*************************************************************************/
    474   /*                                                                       */
    475   /* <Function>                                                            */
    476   /*    tt_size_run_prep                                                   */
    477   /*                                                                       */
    478   /* <Description>                                                         */
    479   /*    Run the control value program.                                     */
    480   /*                                                                       */
    481   /* <Input>                                                               */
    482   /*    size :: A handle to the size object.                               */
    483   /*                                                                       */
    484   /* <Return>                                                              */
    485   /*    FreeType error code.  0 means success.                             */
    486   /*                                                                       */
    487   FT_LOCAL_DEF( FT_Error )
    488   tt_size_run_prep( TT_Size  size )
    489   {
    490     TT_Face         face = (TT_Face)size->root.face;
    491     TT_ExecContext  exec;
    492     FT_Error        error;
    493 
    494 
    495     /* debugging instances have their own context */
    496     if ( size->debug )
    497       exec = size->context;
    498     else
    499       exec = ( (TT_Driver)FT_FACE_DRIVER( face ) )->context;
    500 
    501     if ( !exec )
    502       return TT_Err_Could_Not_Find_Context;
    503 
    504     TT_Load_Context( exec, face, size );
    505 
    506     exec->callTop = 0;
    507     exec->top     = 0;
    508 
    509     exec->instruction_trap = FALSE;
    510 
    511     TT_Set_CodeRange( exec,
    512                       tt_coderange_cvt,
    513                       face->cvt_program,
    514                       face->cvt_program_size );
    515 
    516     TT_Clear_CodeRange( exec, tt_coderange_glyph );
    517 
    518     if ( face->cvt_program_size > 0 )
    519     {
    520       error = TT_Goto_CodeRange( exec, tt_coderange_cvt, 0 );
    521 
    522       if ( !error && !size->debug )
    523         error = face->interpreter( exec );
    524     }
    525     else
    526       error = TT_Err_Ok;
    527 
    528     /* save as default graphics state */
    529     size->GS = exec->GS;
    530 
    531     TT_Save_Context( exec, size );
    532 
    533     return error;
    534   }
    535 
    536 #endif /* TT_USE_BYTECODE_INTERPRETER */
    537 
    538 
    539 #ifdef TT_USE_BYTECODE_INTERPRETER
    540 
    541   static void
    542   tt_size_done_bytecode( FT_Size  ftsize )
    543   {
    544     TT_Size    size   = (TT_Size)ftsize;
    545     TT_Face    face   = (TT_Face)ftsize->face;
    546     FT_Memory  memory = face->root.memory;
    547 
    548 
    549     if ( size->debug )
    550     {
    551       /* the debug context must be deleted by the debugger itself */
    552       size->context = NULL;
    553       size->debug   = FALSE;
    554     }
    555 
    556     FT_FREE( size->cvt );
    557     size->cvt_size = 0;
    558 
    559     /* free storage area */
    560     FT_FREE( size->storage );
    561     size->storage_size = 0;
    562 
    563     /* twilight zone */
    564     tt_glyphzone_done( &size->twilight );
    565 
    566     FT_FREE( size->function_defs );
    567     FT_FREE( size->instruction_defs );
    568 
    569     size->num_function_defs    = 0;
    570     size->max_function_defs    = 0;
    571     size->num_instruction_defs = 0;
    572     size->max_instruction_defs = 0;
    573 
    574     size->max_func = 0;
    575     size->max_ins  = 0;
    576 
    577     size->bytecode_ready = 0;
    578     size->cvt_ready      = 0;
    579   }
    580 
    581 
    582   /* Initialize bytecode-related fields in the size object.       */
    583   /* We do this only if bytecode interpretation is really needed. */
    584   static FT_Error
    585   tt_size_init_bytecode( FT_Size  ftsize )
    586   {
    587     FT_Error   error;
    588     TT_Size    size = (TT_Size)ftsize;
    589     TT_Face    face = (TT_Face)ftsize->face;
    590     FT_Memory  memory = face->root.memory;
    591     FT_Int     i;
    592 
    593     FT_UShort       n_twilight;
    594     TT_MaxProfile*  maxp = &face->max_profile;
    595 
    596 
    597     size->bytecode_ready = 1;
    598     size->cvt_ready      = 0;
    599 
    600     size->max_function_defs    = maxp->maxFunctionDefs;
    601     size->max_instruction_defs = maxp->maxInstructionDefs;
    602 
    603     size->num_function_defs    = 0;
    604     size->num_instruction_defs = 0;
    605 
    606     size->max_func = 0;
    607     size->max_ins  = 0;
    608 
    609     size->cvt_size     = face->cvt_size;
    610     size->storage_size = maxp->maxStorage;
    611 
    612     /* Set default metrics */
    613     {
    614       TT_Size_Metrics*  metrics = &size->ttmetrics;
    615 
    616 
    617       metrics->rotated   = FALSE;
    618       metrics->stretched = FALSE;
    619 
    620       /* set default compensation (all 0) */
    621       for ( i = 0; i < 4; i++ )
    622         metrics->compensations[i] = 0;
    623     }
    624 
    625     /* allocate function defs, instruction defs, cvt, and storage area */
    626     if ( FT_NEW_ARRAY( size->function_defs,    size->max_function_defs    ) ||
    627          FT_NEW_ARRAY( size->instruction_defs, size->max_instruction_defs ) ||
    628          FT_NEW_ARRAY( size->cvt,              size->cvt_size             ) ||
    629          FT_NEW_ARRAY( size->storage,          size->storage_size         ) )
    630       goto Exit;
    631 
    632     /* reserve twilight zone */
    633     n_twilight = maxp->maxTwilightPoints;
    634 
    635     /* there are 4 phantom points (do we need this?) */
    636     n_twilight += 4;
    637 
    638     error = tt_glyphzone_new( memory, n_twilight, 0, &size->twilight );
    639     if ( error )
    640       goto Exit;
    641 
    642     size->twilight.n_points = n_twilight;
    643 
    644     size->GS = tt_default_graphics_state;
    645 
    646     /* set `face->interpreter' according to the debug hook present */
    647     {
    648       FT_Library  library = face->root.driver->root.library;
    649 
    650 
    651       face->interpreter = (TT_Interpreter)
    652                             library->debug_hooks[FT_DEBUG_HOOK_TRUETYPE];
    653       if ( !face->interpreter )
    654         face->interpreter = (TT_Interpreter)TT_RunIns;
    655     }
    656 
    657     /* Fine, now run the font program! */
    658     error = tt_size_run_fpgm( size );
    659 
    660   Exit:
    661     if ( error )
    662       tt_size_done_bytecode( ftsize );
    663 
    664     return error;
    665   }
    666 
    667 
    668   FT_LOCAL_DEF( FT_Error )
    669   tt_size_ready_bytecode( TT_Size  size )
    670   {
    671     FT_Error  error = TT_Err_Ok;
    672 
    673 
    674     if ( !size->bytecode_ready )
    675     {
    676       error = tt_size_init_bytecode( (FT_Size)size );
    677       if ( error )
    678         goto Exit;
    679     }
    680 
    681     /* rescale CVT when needed */
    682     if ( !size->cvt_ready )
    683     {
    684       FT_UInt  i;
    685       TT_Face  face = (TT_Face)size->root.face;
    686 
    687 
    688       /* Scale the cvt values to the new ppem.          */
    689       /* We use by default the y ppem to scale the CVT. */
    690       for ( i = 0; i < size->cvt_size; i++ )
    691         size->cvt[i] = FT_MulFix( face->cvt[i], size->ttmetrics.scale );
    692 
    693       /* all twilight points are originally zero */
    694       for ( i = 0; i < (FT_UInt)size->twilight.n_points; i++ )
    695       {
    696         size->twilight.org[i].x = 0;
    697         size->twilight.org[i].y = 0;
    698         size->twilight.cur[i].x = 0;
    699         size->twilight.cur[i].y = 0;
    700       }
    701 
    702       /* clear storage area */
    703       for ( i = 0; i < (FT_UInt)size->storage_size; i++ )
    704         size->storage[i] = 0;
    705 
    706       size->GS = tt_default_graphics_state;
    707 
    708       error = tt_size_run_prep( size );
    709       if ( !error )
    710         size->cvt_ready = 1;
    711     }
    712 
    713   Exit:
    714     return error;
    715   }
    716 
    717 #endif /* TT_USE_BYTECODE_INTERPRETER */
    718 
    719 
    720   /*************************************************************************/
    721   /*                                                                       */
    722   /* <Function>                                                            */
    723   /*    tt_size_init                                                       */
    724   /*                                                                       */
    725   /* <Description>                                                         */
    726   /*    Initialize a new TrueType size object.                             */
    727   /*                                                                       */
    728   /* <InOut>                                                               */
    729   /*    size :: A handle to the size object.                               */
    730   /*                                                                       */
    731   /* <Return>                                                              */
    732   /*    FreeType error code.  0 means success.                             */
    733   /*                                                                       */
    734   FT_LOCAL_DEF( FT_Error )
    735   tt_size_init( FT_Size  ttsize )           /* TT_Size */
    736   {
    737     TT_Size   size  = (TT_Size)ttsize;
    738     FT_Error  error = TT_Err_Ok;
    739 
    740 #ifdef TT_USE_BYTECODE_INTERPRETER
    741     size->bytecode_ready = 0;
    742     size->cvt_ready      = 0;
    743 #endif
    744 
    745     size->ttmetrics.valid = FALSE;
    746     size->strike_index    = 0xFFFFFFFFUL;
    747 
    748     return error;
    749   }
    750 
    751 
    752   /*************************************************************************/
    753   /*                                                                       */
    754   /* <Function>                                                            */
    755   /*    tt_size_done                                                       */
    756   /*                                                                       */
    757   /* <Description>                                                         */
    758   /*    The TrueType size object finalizer.                                */
    759   /*                                                                       */
    760   /* <Input>                                                               */
    761   /*    size :: A handle to the target size object.                        */
    762   /*                                                                       */
    763   FT_LOCAL_DEF( void )
    764   tt_size_done( FT_Size  ttsize )           /* TT_Size */
    765   {
    766     TT_Size  size = (TT_Size)ttsize;
    767 
    768 
    769 #ifdef TT_USE_BYTECODE_INTERPRETER
    770     if ( size->bytecode_ready )
    771       tt_size_done_bytecode( ttsize );
    772 #endif
    773 
    774     size->ttmetrics.valid = FALSE;
    775   }
    776 
    777 
    778   /*************************************************************************/
    779   /*                                                                       */
    780   /* <Function>                                                            */
    781   /*    tt_size_reset                                                      */
    782   /*                                                                       */
    783   /* <Description>                                                         */
    784   /*    Reset a TrueType size when resolutions and character dimensions    */
    785   /*    have been changed.                                                 */
    786   /*                                                                       */
    787   /* <Input>                                                               */
    788   /*    size :: A handle to the target size object.                        */
    789   /*                                                                       */
    790   FT_LOCAL_DEF( FT_Error )
    791   tt_size_reset( TT_Size  size )
    792   {
    793     TT_Face           face;
    794     FT_Error          error = TT_Err_Ok;
    795     FT_Size_Metrics*  metrics;
    796 
    797 
    798     size->ttmetrics.valid = FALSE;
    799 
    800     face = (TT_Face)size->root.face;
    801 
    802     metrics = &size->metrics;
    803 
    804     /* copy the result from base layer */
    805     *metrics = size->root.metrics;
    806 
    807     if ( metrics->x_ppem < 1 || metrics->y_ppem < 1 )
    808       return TT_Err_Invalid_PPem;
    809 
    810     /* This bit flag, if set, indicates that the ppems must be       */
    811     /* rounded to integers.  Nearly all TrueType fonts have this bit */
    812     /* set, as hinting won't work really well otherwise.             */
    813     /*                                                               */
    814     if ( face->header.Flags & 8 )
    815     {
    816       metrics->x_scale = FT_DivFix( metrics->x_ppem << 6,
    817                                     face->root.units_per_EM );
    818       metrics->y_scale = FT_DivFix( metrics->y_ppem << 6,
    819                                     face->root.units_per_EM );
    820 
    821       metrics->ascender =
    822         FT_PIX_ROUND( FT_MulFix( face->root.ascender, metrics->y_scale ) );
    823       metrics->descender =
    824         FT_PIX_ROUND( FT_MulFix( face->root.descender, metrics->y_scale ) );
    825       metrics->height =
    826         FT_PIX_ROUND( FT_MulFix( face->root.height, metrics->y_scale ) );
    827       metrics->max_advance =
    828         FT_PIX_ROUND( FT_MulFix( face->root.max_advance_width,
    829                                  metrics->x_scale ) );
    830     }
    831 
    832     /* compute new transformation */
    833     if ( metrics->x_ppem >= metrics->y_ppem )
    834     {
    835       size->ttmetrics.scale   = metrics->x_scale;
    836       size->ttmetrics.ppem    = metrics->x_ppem;
    837       size->ttmetrics.x_ratio = 0x10000L;
    838       size->ttmetrics.y_ratio = FT_MulDiv( metrics->y_ppem,
    839                                            0x10000L,
    840                                            metrics->x_ppem );
    841     }
    842     else
    843     {
    844       size->ttmetrics.scale   = metrics->y_scale;
    845       size->ttmetrics.ppem    = metrics->y_ppem;
    846       size->ttmetrics.x_ratio = FT_MulDiv( metrics->x_ppem,
    847                                            0x10000L,
    848                                            metrics->y_ppem );
    849       size->ttmetrics.y_ratio = 0x10000L;
    850     }
    851 
    852 #ifdef TT_USE_BYTECODE_INTERPRETER
    853     size->cvt_ready = 0;
    854 #endif /* TT_USE_BYTECODE_INTERPRETER */
    855 
    856     if ( !error )
    857       size->ttmetrics.valid = TRUE;
    858 
    859     return error;
    860   }
    861 
    862 
    863   /*************************************************************************/
    864   /*                                                                       */
    865   /* <Function>                                                            */
    866   /*    tt_driver_init                                                     */
    867   /*                                                                       */
    868   /* <Description>                                                         */
    869   /*    Initialize a given TrueType driver object.                         */
    870   /*                                                                       */
    871   /* <Input>                                                               */
    872   /*    driver :: A handle to the target driver object.                    */
    873   /*                                                                       */
    874   /* <Return>                                                              */
    875   /*    FreeType error code.  0 means success.                             */
    876   /*                                                                       */
    877   FT_LOCAL_DEF( FT_Error )
    878   tt_driver_init( FT_Module  ttdriver )     /* TT_Driver */
    879   {
    880 
    881 #ifdef TT_USE_BYTECODE_INTERPRETER
    882 
    883     TT_Driver  driver = (TT_Driver)ttdriver;
    884 
    885 
    886     if ( !TT_New_Context( driver ) )
    887       return TT_Err_Could_Not_Find_Context;
    888 
    889 #else
    890 
    891     FT_UNUSED( ttdriver );
    892 
    893 #endif
    894 
    895     return TT_Err_Ok;
    896   }
    897 
    898 
    899   /*************************************************************************/
    900   /*                                                                       */
    901   /* <Function>                                                            */
    902   /*    tt_driver_done                                                     */
    903   /*                                                                       */
    904   /* <Description>                                                         */
    905   /*    Finalize a given TrueType driver.                                  */
    906   /*                                                                       */
    907   /* <Input>                                                               */
    908   /*    driver :: A handle to the target TrueType driver.                  */
    909   /*                                                                       */
    910   FT_LOCAL_DEF( void )
    911   tt_driver_done( FT_Module  ttdriver )     /* TT_Driver */
    912   {
    913 #ifdef TT_USE_BYTECODE_INTERPRETER
    914     TT_Driver  driver = (TT_Driver)ttdriver;
    915 
    916 
    917     /* destroy the execution context */
    918     if ( driver->context )
    919     {
    920       TT_Done_Context( driver->context );
    921       driver->context = NULL;
    922     }
    923 #else
    924     FT_UNUSED( ttdriver );
    925 #endif
    926 
    927   }
    928 
    929 
    930   /*************************************************************************/
    931   /*                                                                       */
    932   /* <Function>                                                            */
    933   /*    tt_slot_init                                                       */
    934   /*                                                                       */
    935   /* <Description>                                                         */
    936   /*    Initialize a new slot object.                                      */
    937   /*                                                                       */
    938   /* <InOut>                                                               */
    939   /*    slot :: A handle to the slot object.                               */
    940   /*                                                                       */
    941   /* <Return>                                                              */
    942   /*    FreeType error code.  0 means success.                             */
    943   /*                                                                       */
    944   FT_LOCAL_DEF( FT_Error )
    945   tt_slot_init( FT_GlyphSlot  slot )
    946   {
    947     return FT_GlyphLoader_CreateExtra( slot->internal->loader );
    948   }
    949 
    950 
    951 /* END */
    952