Home | History | Annotate | Download | only in truetype
      1 /***************************************************************************/
      2 /*                                                                         */
      3 /*  ttobjs.c                                                               */
      4 /*                                                                         */
      5 /*    Objects manager (body).                                              */
      6 /*                                                                         */
      7 /*  Copyright 1996-2018 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 #include FT_DRIVER_H
     25 
     26 #include "ttgload.h"
     27 #include "ttpload.h"
     28 
     29 #include "tterrors.h"
     30 
     31 #ifdef TT_USE_BYTECODE_INTERPRETER
     32 #include "ttinterp.h"
     33 #endif
     34 
     35 #ifdef TT_CONFIG_OPTION_GX_VAR_SUPPORT
     36 #include "ttgxvar.h"
     37 #endif
     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_ttobjs
     47 
     48 
     49 #ifdef TT_USE_BYTECODE_INTERPRETER
     50 
     51   /*************************************************************************/
     52   /*                                                                       */
     53   /*                       GLYPH ZONE FUNCTIONS                            */
     54   /*                                                                       */
     55   /*************************************************************************/
     56 
     57 
     58   /*************************************************************************/
     59   /*                                                                       */
     60   /* <Function>                                                            */
     61   /*    tt_glyphzone_done                                                  */
     62   /*                                                                       */
     63   /* <Description>                                                         */
     64   /*    Deallocate a glyph zone.                                           */
     65   /*                                                                       */
     66   /* <Input>                                                               */
     67   /*    zone :: A pointer to the target glyph zone.                        */
     68   /*                                                                       */
     69   FT_LOCAL_DEF( void )
     70   tt_glyphzone_done( TT_GlyphZone  zone )
     71   {
     72     FT_Memory  memory = zone->memory;
     73 
     74 
     75     if ( memory )
     76     {
     77       FT_FREE( zone->contours );
     78       FT_FREE( zone->tags );
     79       FT_FREE( zone->cur );
     80       FT_FREE( zone->org );
     81       FT_FREE( zone->orus );
     82 
     83       zone->max_points   = zone->n_points   = 0;
     84       zone->max_contours = zone->n_contours = 0;
     85       zone->memory       = NULL;
     86     }
     87   }
     88 
     89 
     90   /*************************************************************************/
     91   /*                                                                       */
     92   /* <Function>                                                            */
     93   /*    tt_glyphzone_new                                                   */
     94   /*                                                                       */
     95   /* <Description>                                                         */
     96   /*    Allocate a new glyph zone.                                         */
     97   /*                                                                       */
     98   /* <Input>                                                               */
     99   /*    memory      :: A handle to the current memory object.              */
    100   /*                                                                       */
    101   /*    maxPoints   :: The capacity of glyph zone in points.               */
    102   /*                                                                       */
    103   /*    maxContours :: The capacity of glyph zone in contours.             */
    104   /*                                                                       */
    105   /* <Output>                                                              */
    106   /*    zone        :: A pointer to the target glyph zone record.          */
    107   /*                                                                       */
    108   /* <Return>                                                              */
    109   /*    FreeType error code.  0 means success.                             */
    110   /*                                                                       */
    111   FT_LOCAL_DEF( FT_Error )
    112   tt_glyphzone_new( FT_Memory     memory,
    113                     FT_UShort     maxPoints,
    114                     FT_Short      maxContours,
    115                     TT_GlyphZone  zone )
    116   {
    117     FT_Error  error;
    118 
    119 
    120     FT_ZERO( zone );
    121     zone->memory = memory;
    122 
    123     if ( FT_NEW_ARRAY( zone->org,      maxPoints   ) ||
    124          FT_NEW_ARRAY( zone->cur,      maxPoints   ) ||
    125          FT_NEW_ARRAY( zone->orus,     maxPoints   ) ||
    126          FT_NEW_ARRAY( zone->tags,     maxPoints   ) ||
    127          FT_NEW_ARRAY( zone->contours, maxContours ) )
    128     {
    129       tt_glyphzone_done( zone );
    130     }
    131     else
    132     {
    133       zone->max_points   = maxPoints;
    134       zone->max_contours = maxContours;
    135     }
    136 
    137     return error;
    138   }
    139 #endif /* TT_USE_BYTECODE_INTERPRETER */
    140 
    141 
    142   /* Compare the face with a list of well-known `tricky' fonts. */
    143   /* This list shall be expanded as we find more of them.       */
    144 
    145   static FT_Bool
    146   tt_check_trickyness_family( FT_String*  name )
    147   {
    148 
    149 #define TRICK_NAMES_MAX_CHARACTERS  19
    150 #define TRICK_NAMES_COUNT           23
    151 
    152     static const char trick_names[TRICK_NAMES_COUNT]
    153                                  [TRICK_NAMES_MAX_CHARACTERS + 1] =
    154     {
    155       /*
    156          PostScript names are given in brackets if they differ from the
    157          family name.  The version numbers, together with the copyright or
    158          release year data, are taken from fonts available to the
    159          developers.
    160 
    161          Note that later versions of the fonts might be no longer tricky;
    162          for example, `MingLiU' version 7.00 (file `mingliu.ttc' from
    163          Windows 7) is an ordinary TTC with non-tricky subfonts.
    164        */
    165 
    166       "cpop",               /* dftt-p7.ttf; version 1.00, 1992 [DLJGyShoMedium] */
    167       "DFGirl-W6-WIN-BF",   /* dftt-h6.ttf; version 1.00, 1993 */
    168       "DFGothic-EB",        /* DynaLab Inc. 1992-1995 */
    169       "DFGyoSho-Lt",        /* DynaLab Inc. 1992-1995 */
    170       "DFHSGothic-W5",      /* DynaLab Inc. 1992-1995 */
    171       "DFHSMincho-W3",      /* DynaLab Inc. 1992-1995 */
    172       "DFHSMincho-W7",      /* DynaLab Inc. 1992-1995 */
    173       "DFKaiSho-SB",        /* dfkaisb.ttf */
    174       "DFKaiShu",
    175       "DFKai-SB",           /* kaiu.ttf; version 3.00, 1998 [DFKaiShu-SB-Estd-BF] */
    176       "DLC",                /* dftt-m7.ttf; version 1.00, 1993 [DLCMingBold] */
    177                             /* dftt-f5.ttf; version 1.00, 1993 [DLCFongSung] */
    178       "DLCHayMedium",       /* dftt-b5.ttf; version 1.00, 1993 */
    179       "DLCHayBold",         /* dftt-b7.ttf; version 1.00, 1993 */
    180       "DLCKaiMedium",       /* dftt-k5.ttf; version 1.00, 1992 */
    181       "DLCLiShu",           /* dftt-l5.ttf; version 1.00, 1992 */
    182       "DLCRoundBold",       /* dftt-r7.ttf; version 1.00, 1993 */
    183       "HuaTianKaiTi?",      /* htkt2.ttf */
    184       "HuaTianSongTi?",     /* htst3.ttf */
    185       "Ming(for ISO10646)", /* hkscsiic.ttf; version 0.12, 2007 [Ming] */
    186                             /* iicore.ttf; version 0.07, 2007 [Ming] */
    187       "MingLiU",            /* mingliu.ttf */
    188                             /* mingliu.ttc; version 3.21, 2001 */
    189       "MingMedium",         /* dftt-m5.ttf; version 1.00, 1993 [DLCMingMedium] */
    190       "PMingLiU",           /* mingliu.ttc; version 3.21, 2001 */
    191       "MingLi43",           /* mingli.ttf; version 1.00, 1992 */
    192     };
    193 
    194     int  nn;
    195 
    196 
    197     for ( nn = 0; nn < TRICK_NAMES_COUNT; nn++ )
    198       if ( ft_strstr( name, trick_names[nn] ) )
    199         return TRUE;
    200 
    201     return FALSE;
    202   }
    203 
    204 
    205   /* XXX: This function should be in the `sfnt' module. */
    206 
    207   /* Some PDF generators clear the checksums in the TrueType header table. */
    208   /* For example, Quartz ContextPDF clears all entries, or Bullzip PDF     */
    209   /* Printer clears the entries for subsetted subtables.  We thus have to  */
    210   /* recalculate the checksums  where necessary.                           */
    211 
    212   static FT_UInt32
    213   tt_synth_sfnt_checksum( FT_Stream  stream,
    214                           FT_ULong   length )
    215   {
    216     FT_Error   error;
    217     FT_UInt32  checksum = 0;
    218     FT_UInt    i;
    219 
    220 
    221     if ( FT_FRAME_ENTER( length ) )
    222       return 0;
    223 
    224     for ( ; length > 3; length -= 4 )
    225       checksum += (FT_UInt32)FT_GET_ULONG();
    226 
    227     for ( i = 3; length > 0; length--, i-- )
    228       checksum += (FT_UInt32)FT_GET_BYTE() << ( i * 8 );
    229 
    230     FT_FRAME_EXIT();
    231 
    232     return checksum;
    233   }
    234 
    235 
    236   /* XXX: This function should be in the `sfnt' module. */
    237 
    238   static FT_ULong
    239   tt_get_sfnt_checksum( TT_Face    face,
    240                         FT_UShort  i )
    241   {
    242 #if 0 /* if we believe the written value, use following part. */
    243     if ( face->dir_tables[i].CheckSum )
    244       return face->dir_tables[i].CheckSum;
    245 #endif
    246 
    247     if ( !face->goto_table )
    248       return 0;
    249 
    250     if ( face->goto_table( face,
    251                            face->dir_tables[i].Tag,
    252                            face->root.stream,
    253                            NULL ) )
    254       return 0;
    255 
    256     return (FT_ULong)tt_synth_sfnt_checksum( face->root.stream,
    257                                              face->dir_tables[i].Length );
    258   }
    259 
    260 
    261   typedef struct tt_sfnt_id_rec_
    262   {
    263     FT_ULong  CheckSum;
    264     FT_ULong  Length;
    265 
    266   } tt_sfnt_id_rec;
    267 
    268 
    269   static FT_Bool
    270   tt_check_trickyness_sfnt_ids( TT_Face  face )
    271   {
    272 #define TRICK_SFNT_IDS_PER_FACE   3
    273 #define TRICK_SFNT_IDS_NUM_FACES  26
    274 
    275     static const tt_sfnt_id_rec sfnt_id[TRICK_SFNT_IDS_NUM_FACES]
    276                                        [TRICK_SFNT_IDS_PER_FACE] = {
    277 
    278 #define TRICK_SFNT_ID_cvt   0
    279 #define TRICK_SFNT_ID_fpgm  1
    280 #define TRICK_SFNT_ID_prep  2
    281 
    282       { /* MingLiU 1995 */
    283         { 0x05BCF058UL, 0x000002E4UL }, /* cvt  */
    284         { 0x28233BF1UL, 0x000087C4UL }, /* fpgm */
    285         { 0xA344A1EAUL, 0x000001E1UL }  /* prep */
    286       },
    287       { /* MingLiU 1996- */
    288         { 0x05BCF058UL, 0x000002E4UL }, /* cvt  */
    289         { 0x28233BF1UL, 0x000087C4UL }, /* fpgm */
    290         { 0xA344A1EBUL, 0x000001E1UL }  /* prep */
    291       },
    292       { /* DFGothic-EB */
    293         { 0x12C3EBB2UL, 0x00000350UL }, /* cvt  */
    294         { 0xB680EE64UL, 0x000087A7UL }, /* fpgm */
    295         { 0xCE939563UL, 0x00000758UL }  /* prep */
    296       },
    297       { /* DFGyoSho-Lt */
    298         { 0x11E5EAD4UL, 0x00000350UL }, /* cvt  */
    299         { 0xCE5956E9UL, 0x0000BC85UL }, /* fpgm */
    300         { 0x8272F416UL, 0x00000045UL }  /* prep */
    301       },
    302       { /* DFHSGothic-W5 */
    303         { 0x1262EB4EUL, 0x00000350UL }, /* cvt  */
    304         { 0xE86A5D64UL, 0x00007940UL }, /* fpgm */
    305         { 0x7850F729UL, 0x000005FFUL }  /* prep */
    306       },
    307       { /* DFHSMincho-W3 */
    308         { 0x122DEB0AUL, 0x00000350UL }, /* cvt  */
    309         { 0x3D16328AUL, 0x0000859BUL }, /* fpgm */
    310         { 0xA93FC33BUL, 0x000002CBUL }  /* prep */
    311       },
    312       { /* DFHSMincho-W7 */
    313         { 0x125FEB26UL, 0x00000350UL }, /* cvt  */
    314         { 0xA5ACC982UL, 0x00007EE1UL }, /* fpgm */
    315         { 0x90999196UL, 0x0000041FUL }  /* prep */
    316       },
    317       { /* DFKaiShu */
    318         { 0x11E5EAD4UL, 0x00000350UL }, /* cvt  */
    319         { 0x5A30CA3BUL, 0x00009063UL }, /* fpgm */
    320         { 0x13A42602UL, 0x0000007EUL }  /* prep */
    321       },
    322       { /* DFKaiShu, variant */
    323         { 0x11E5EAD4UL, 0x00000350UL }, /* cvt  */
    324         { 0xA6E78C01UL, 0x00008998UL }, /* fpgm */
    325         { 0x13A42602UL, 0x0000007EUL }  /* prep */
    326       },
    327       { /* DLCLiShu */
    328         { 0x07DCF546UL, 0x00000308UL }, /* cvt  */
    329         { 0x40FE7C90UL, 0x00008E2AUL }, /* fpgm */
    330         { 0x608174B5UL, 0x0000007AUL }  /* prep */
    331       },
    332       { /* DLCHayBold */
    333         { 0xEB891238UL, 0x00000308UL }, /* cvt  */
    334         { 0xD2E4DCD4UL, 0x0000676FUL }, /* fpgm */
    335         { 0x8EA5F293UL, 0x000003B8UL }  /* prep */
    336       },
    337       { /* HuaTianKaiTi */
    338         { 0xFFFBFFFCUL, 0x00000008UL }, /* cvt  */
    339         { 0x9C9E48B8UL, 0x0000BEA2UL }, /* fpgm */
    340         { 0x70020112UL, 0x00000008UL }  /* prep */
    341       },
    342       { /* HuaTianSongTi */
    343         { 0xFFFBFFFCUL, 0x00000008UL }, /* cvt  */
    344         { 0x0A5A0483UL, 0x00017C39UL }, /* fpgm */
    345         { 0x70020112UL, 0x00000008UL }  /* prep */
    346       },
    347       { /* NEC fadpop7.ttf */
    348         { 0x00000000UL, 0x00000000UL }, /* cvt  */
    349         { 0x40C92555UL, 0x000000E5UL }, /* fpgm */
    350         { 0xA39B58E3UL, 0x0000117CUL }  /* prep */
    351       },
    352       { /* NEC fadrei5.ttf */
    353         { 0x00000000UL, 0x00000000UL }, /* cvt  */
    354         { 0x33C41652UL, 0x000000E5UL }, /* fpgm */
    355         { 0x26D6C52AUL, 0x00000F6AUL }  /* prep */
    356       },
    357       { /* NEC fangot7.ttf */
    358         { 0x00000000UL, 0x00000000UL }, /* cvt  */
    359         { 0x6DB1651DUL, 0x0000019DUL }, /* fpgm */
    360         { 0x6C6E4B03UL, 0x00002492UL }  /* prep */
    361       },
    362       { /* NEC fangyo5.ttf */
    363         { 0x00000000UL, 0x00000000UL }, /* cvt  */
    364         { 0x40C92555UL, 0x000000E5UL }, /* fpgm */
    365         { 0xDE51FAD0UL, 0x0000117CUL }  /* prep */
    366       },
    367       { /* NEC fankyo5.ttf */
    368         { 0x00000000UL, 0x00000000UL }, /* cvt  */
    369         { 0x85E47664UL, 0x000000E5UL }, /* fpgm */
    370         { 0xA6C62831UL, 0x00001CAAUL }  /* prep */
    371       },
    372       { /* NEC fanrgo5.ttf */
    373         { 0x00000000UL, 0x00000000UL }, /* cvt  */
    374         { 0x2D891CFDUL, 0x0000019DUL }, /* fpgm */
    375         { 0xA0604633UL, 0x00001DE8UL }  /* prep */
    376       },
    377       { /* NEC fangot5.ttc */
    378         { 0x00000000UL, 0x00000000UL }, /* cvt  */
    379         { 0x40AA774CUL, 0x000001CBUL }, /* fpgm */
    380         { 0x9B5CAA96UL, 0x00001F9AUL }  /* prep */
    381       },
    382       { /* NEC fanmin3.ttc */
    383         { 0x00000000UL, 0x00000000UL }, /* cvt  */
    384         { 0x0D3DE9CBUL, 0x00000141UL }, /* fpgm */
    385         { 0xD4127766UL, 0x00002280UL }  /* prep */
    386       },
    387       { /* NEC FA-Gothic, 1996 */
    388         { 0x00000000UL, 0x00000000UL }, /* cvt  */
    389         { 0x4A692698UL, 0x000001F0UL }, /* fpgm */
    390         { 0x340D4346UL, 0x00001FCAUL }  /* prep */
    391       },
    392       { /* NEC FA-Minchou, 1996 */
    393         { 0x00000000UL, 0x00000000UL }, /* cvt  */
    394         { 0xCD34C604UL, 0x00000166UL }, /* fpgm */
    395         { 0x6CF31046UL, 0x000022B0UL }  /* prep */
    396       },
    397       { /* NEC FA-RoundGothicB, 1996 */
    398         { 0x00000000UL, 0x00000000UL }, /* cvt  */
    399         { 0x5DA75315UL, 0x0000019DUL }, /* fpgm */
    400         { 0x40745A5FUL, 0x000022E0UL }  /* prep */
    401       },
    402       { /* NEC FA-RoundGothicM, 1996 */
    403         { 0x00000000UL, 0x00000000UL }, /* cvt  */
    404         { 0xF055FC48UL, 0x000001C2UL }, /* fpgm */
    405         { 0x3900DED3UL, 0x00001E18UL }  /* prep */
    406       },
    407         { /* MINGLI.TTF, 1992 */
    408         { 0x00170003UL, 0x00000060UL }, /* cvt  */
    409         { 0xDBB4306EUL, 0x000058AAUL }, /* fpgm */
    410         { 0xD643482AUL, 0x00000035UL }  /* prep */
    411       }
    412     };
    413 
    414     FT_ULong   checksum;
    415     int        num_matched_ids[TRICK_SFNT_IDS_NUM_FACES];
    416     FT_Bool    has_cvt, has_fpgm, has_prep;
    417     FT_UShort  i;
    418     int        j, k;
    419 
    420 
    421     FT_MEM_SET( num_matched_ids, 0,
    422                 sizeof ( int ) * TRICK_SFNT_IDS_NUM_FACES );
    423     has_cvt  = FALSE;
    424     has_fpgm = FALSE;
    425     has_prep = FALSE;
    426 
    427     for ( i = 0; i < face->num_tables; i++ )
    428     {
    429       checksum = 0;
    430 
    431       switch( face->dir_tables[i].Tag )
    432       {
    433       case TTAG_cvt:
    434         k = TRICK_SFNT_ID_cvt;
    435         has_cvt  = TRUE;
    436         break;
    437 
    438       case TTAG_fpgm:
    439         k = TRICK_SFNT_ID_fpgm;
    440         has_fpgm = TRUE;
    441         break;
    442 
    443       case TTAG_prep:
    444         k = TRICK_SFNT_ID_prep;
    445         has_prep = TRUE;
    446         break;
    447 
    448       default:
    449         continue;
    450       }
    451 
    452       for ( j = 0; j < TRICK_SFNT_IDS_NUM_FACES; j++ )
    453         if ( face->dir_tables[i].Length == sfnt_id[j][k].Length )
    454         {
    455           if ( !checksum )
    456             checksum = tt_get_sfnt_checksum( face, i );
    457 
    458           if ( sfnt_id[j][k].CheckSum == checksum )
    459             num_matched_ids[j]++;
    460 
    461           if ( num_matched_ids[j] == TRICK_SFNT_IDS_PER_FACE )
    462             return TRUE;
    463         }
    464     }
    465 
    466     for ( j = 0; j < TRICK_SFNT_IDS_NUM_FACES; j++ )
    467     {
    468       if ( !has_cvt  && !sfnt_id[j][TRICK_SFNT_ID_cvt].Length )
    469         num_matched_ids[j]++;
    470       if ( !has_fpgm && !sfnt_id[j][TRICK_SFNT_ID_fpgm].Length )
    471         num_matched_ids[j]++;
    472       if ( !has_prep && !sfnt_id[j][TRICK_SFNT_ID_prep].Length )
    473         num_matched_ids[j]++;
    474       if ( num_matched_ids[j] == TRICK_SFNT_IDS_PER_FACE )
    475         return TRUE;
    476     }
    477 
    478     return FALSE;
    479   }
    480 
    481 
    482   static FT_Bool
    483   tt_check_trickyness( FT_Face  face )
    484   {
    485     if ( !face )
    486       return FALSE;
    487 
    488     /* For first, check the face name for quick check. */
    489     if ( face->family_name                               &&
    490          tt_check_trickyness_family( face->family_name ) )
    491       return TRUE;
    492 
    493     /* Type42 fonts may lack `name' tables, we thus try to identify */
    494     /* tricky fonts by checking the checksums of Type42-persistent  */
    495     /* sfnt tables (`cvt', `fpgm', and `prep').                     */
    496     if ( tt_check_trickyness_sfnt_ids( (TT_Face)face ) )
    497       return TRUE;
    498 
    499     return FALSE;
    500   }
    501 
    502 
    503   /* Check whether `.notdef' is the only glyph in the `loca' table. */
    504   static FT_Bool
    505   tt_check_single_notdef( FT_Face  ttface )
    506   {
    507     FT_Bool   result = FALSE;
    508 
    509     TT_Face   face = (TT_Face)ttface;
    510     FT_UInt   asize;
    511     FT_ULong  i;
    512     FT_ULong  glyph_index = 0;
    513     FT_UInt   count       = 0;
    514 
    515 
    516     for( i = 0; i < face->num_locations; i++ )
    517     {
    518       tt_face_get_location( face, i, &asize );
    519       if ( asize > 0 )
    520       {
    521         count += 1;
    522         if ( count > 1 )
    523           break;
    524         glyph_index = i;
    525       }
    526     }
    527 
    528     /* Only have a single outline. */
    529     if ( count == 1 )
    530     {
    531       if ( glyph_index == 0 )
    532         result = TRUE;
    533       else
    534       {
    535         /* FIXME: Need to test glyphname == .notdef ? */
    536         FT_Error error;
    537         char buf[8];
    538 
    539 
    540         error = FT_Get_Glyph_Name( ttface, glyph_index, buf, 8 );
    541         if ( !error                                            &&
    542              buf[0] == '.' && !ft_strncmp( buf, ".notdef", 8 ) )
    543           result = TRUE;
    544       }
    545     }
    546 
    547     return result;
    548   }
    549 
    550 
    551   /*************************************************************************/
    552   /*                                                                       */
    553   /* <Function>                                                            */
    554   /*    tt_face_init                                                       */
    555   /*                                                                       */
    556   /* <Description>                                                         */
    557   /*    Initialize a given TrueType face object.                           */
    558   /*                                                                       */
    559   /* <Input>                                                               */
    560   /*    stream     :: The source font stream.                              */
    561   /*                                                                       */
    562   /*    face_index :: The index of the TrueType font, if we are opening a  */
    563   /*                  collection, in bits 0-15.  The numbered instance     */
    564   /*                  index~+~1 of a GX (sub)font, if applicable, in bits  */
    565   /*                  16-30.                                               */
    566   /*                                                                       */
    567   /*    num_params :: Number of additional generic parameters.  Ignored.   */
    568   /*                                                                       */
    569   /*    params     :: Additional generic parameters.  Ignored.             */
    570   /*                                                                       */
    571   /* <InOut>                                                               */
    572   /*    face       :: The newly built face object.                         */
    573   /*                                                                       */
    574   /* <Return>                                                              */
    575   /*    FreeType error code.  0 means success.                             */
    576   /*                                                                       */
    577   FT_LOCAL_DEF( FT_Error )
    578   tt_face_init( FT_Stream      stream,
    579                 FT_Face        ttface,      /* TT_Face */
    580                 FT_Int         face_index,
    581                 FT_Int         num_params,
    582                 FT_Parameter*  params )
    583   {
    584     FT_Error      error;
    585     FT_Library    library;
    586     SFNT_Service  sfnt;
    587     TT_Face       face = (TT_Face)ttface;
    588 
    589 
    590     FT_TRACE2(( "TTF driver\n" ));
    591 
    592     library = ttface->driver->root.library;
    593 
    594     sfnt = (SFNT_Service)FT_Get_Module_Interface( library, "sfnt" );
    595     if ( !sfnt )
    596     {
    597       FT_ERROR(( "tt_face_init: cannot access `sfnt' module\n" ));
    598       error = FT_THROW( Missing_Module );
    599       goto Exit;
    600     }
    601 
    602     /* create input stream from resource */
    603     if ( FT_STREAM_SEEK( 0 ) )
    604       goto Exit;
    605 
    606     /* check that we have a valid TrueType file */
    607     FT_TRACE2(( "  " ));
    608     error = sfnt->init_face( stream, face, face_index, num_params, params );
    609 
    610     /* Stream may have changed. */
    611     stream = face->root.stream;
    612 
    613     if ( error )
    614       goto Exit;
    615 
    616     /* We must also be able to accept Mac/GX fonts, as well as OT ones. */
    617     /* The 0x00020000 tag is completely undocumented; some fonts from   */
    618     /* Arphic made for Chinese Windows 3.1 have this.                   */
    619     if ( face->format_tag != 0x00010000L  && /* MS fonts                             */
    620          face->format_tag != 0x00020000L  && /* CJK fonts for Win 3.1                */
    621          face->format_tag != TTAG_true    && /* Mac fonts                            */
    622          face->format_tag != TTAG_0xA5kbd && /* `Keyboard.dfont' (legacy Mac OS X)   */
    623          face->format_tag != TTAG_0xA5lst )  /* `LastResort.dfont' (legacy Mac OS X) */
    624     {
    625       FT_TRACE2(( "  not a TTF font\n" ));
    626       goto Bad_Format;
    627     }
    628 
    629 #ifdef TT_USE_BYTECODE_INTERPRETER
    630     ttface->face_flags |= FT_FACE_FLAG_HINTER;
    631 #endif
    632 
    633     /* If we are performing a simple font format check, exit immediately. */
    634     if ( face_index < 0 )
    635       return FT_Err_Ok;
    636 
    637     /* Load font directory */
    638     error = sfnt->load_face( stream, face, face_index, num_params, params );
    639     if ( error )
    640       goto Exit;
    641 
    642     if ( tt_check_trickyness( ttface ) )
    643       ttface->face_flags |= FT_FACE_FLAG_TRICKY;
    644 
    645     error = tt_face_load_hdmx( face, stream );
    646     if ( error )
    647       goto Exit;
    648 
    649     if ( FT_IS_SCALABLE( ttface ) )
    650     {
    651 #ifdef FT_CONFIG_OPTION_INCREMENTAL
    652       if ( !ttface->internal->incremental_interface )
    653 #endif
    654       {
    655         error = tt_face_load_loca( face, stream );
    656 
    657         /* having a (non-zero) `glyf' table without */
    658         /* a `loca' table is not valid              */
    659         if ( face->glyf_len && FT_ERR_EQ( error, Table_Missing ) )
    660           goto Exit;
    661         if ( error )
    662           goto Exit;
    663       }
    664 
    665       /* `fpgm', `cvt', and `prep' are optional */
    666       error = tt_face_load_cvt( face, stream );
    667       if ( error && FT_ERR_NEQ( error, Table_Missing ) )
    668         goto Exit;
    669 
    670       error = tt_face_load_fpgm( face, stream );
    671       if ( error && FT_ERR_NEQ( error, Table_Missing ) )
    672         goto Exit;
    673 
    674       error = tt_face_load_prep( face, stream );
    675       if ( error && FT_ERR_NEQ( error, Table_Missing ) )
    676         goto Exit;
    677 
    678       /* Check the scalable flag based on `loca'. */
    679 #ifdef FT_CONFIG_OPTION_INCREMENTAL
    680       if ( !ttface->internal->incremental_interface )
    681 #endif
    682       {
    683         if ( ttface->num_fixed_sizes          &&
    684              face->glyph_locations            &&
    685              tt_check_single_notdef( ttface ) )
    686         {
    687           FT_TRACE5(( "tt_face_init:"
    688                       " Only the `.notdef' glyph has an outline.\n"
    689                       "             "
    690                       " Resetting scalable flag to FALSE.\n" ));
    691 
    692           ttface->face_flags &= ~FT_FACE_FLAG_SCALABLE;
    693         }
    694       }
    695     }
    696 
    697 #ifdef TT_CONFIG_OPTION_GX_VAR_SUPPORT
    698 
    699     {
    700       FT_UInt  instance_index = (FT_UInt)face_index >> 16;
    701 
    702 
    703       if ( FT_HAS_MULTIPLE_MASTERS( ttface ) &&
    704            instance_index > 0                )
    705       {
    706         error = TT_Set_Named_Instance( face, instance_index );
    707         if ( error )
    708           goto Exit;
    709 
    710         tt_apply_mvar( face );
    711       }
    712     }
    713 
    714 #endif /* TT_CONFIG_OPTION_GX_VAR_SUPPORT */
    715 
    716     /* initialize standard glyph loading routines */
    717     TT_Init_Glyph_Loading( face );
    718 
    719   Exit:
    720     return error;
    721 
    722   Bad_Format:
    723     error = FT_THROW( Unknown_File_Format );
    724     goto Exit;
    725   }
    726 
    727 
    728   /*************************************************************************/
    729   /*                                                                       */
    730   /* <Function>                                                            */
    731   /*    tt_face_done                                                       */
    732   /*                                                                       */
    733   /* <Description>                                                         */
    734   /*    Finalize a given face object.                                      */
    735   /*                                                                       */
    736   /* <Input>                                                               */
    737   /*    face :: A pointer to the face object to destroy.                   */
    738   /*                                                                       */
    739   FT_LOCAL_DEF( void )
    740   tt_face_done( FT_Face  ttface )           /* TT_Face */
    741   {
    742     TT_Face       face = (TT_Face)ttface;
    743     FT_Memory     memory;
    744     FT_Stream     stream;
    745     SFNT_Service  sfnt;
    746 
    747 
    748     if ( !face )
    749       return;
    750 
    751     memory = ttface->memory;
    752     stream = ttface->stream;
    753     sfnt   = (SFNT_Service)face->sfnt;
    754 
    755     /* for `extended TrueType formats' (i.e. compressed versions) */
    756     if ( face->extra.finalizer )
    757       face->extra.finalizer( face->extra.data );
    758 
    759     if ( sfnt )
    760       sfnt->done_face( face );
    761 
    762     /* freeing the locations table */
    763     tt_face_done_loca( face );
    764 
    765     tt_face_free_hdmx( face );
    766 
    767     /* freeing the CVT */
    768     FT_FREE( face->cvt );
    769     face->cvt_size = 0;
    770 
    771     /* freeing the programs */
    772     FT_FRAME_RELEASE( face->font_program );
    773     FT_FRAME_RELEASE( face->cvt_program );
    774     face->font_program_size = 0;
    775     face->cvt_program_size  = 0;
    776 
    777 #ifdef TT_CONFIG_OPTION_GX_VAR_SUPPORT
    778     tt_done_blend( face );
    779     face->blend = NULL;
    780 #endif
    781   }
    782 
    783 
    784   /*************************************************************************/
    785   /*                                                                       */
    786   /*                           SIZE  FUNCTIONS                             */
    787   /*                                                                       */
    788   /*************************************************************************/
    789 
    790 #ifdef TT_USE_BYTECODE_INTERPRETER
    791 
    792   /*************************************************************************/
    793   /*                                                                       */
    794   /* <Function>                                                            */
    795   /*    tt_size_run_fpgm                                                   */
    796   /*                                                                       */
    797   /* <Description>                                                         */
    798   /*    Run the font program.                                              */
    799   /*                                                                       */
    800   /* <Input>                                                               */
    801   /*    size     :: A handle to the size object.                           */
    802   /*                                                                       */
    803   /*    pedantic :: Set if bytecode execution should be pedantic.          */
    804   /*                                                                       */
    805   /* <Return>                                                              */
    806   /*    FreeType error code.  0 means success.                             */
    807   /*                                                                       */
    808   FT_LOCAL_DEF( FT_Error )
    809   tt_size_run_fpgm( TT_Size  size,
    810                     FT_Bool  pedantic )
    811   {
    812     TT_Face         face = (TT_Face)size->root.face;
    813     TT_ExecContext  exec;
    814     FT_Error        error;
    815 
    816 
    817     exec = size->context;
    818 
    819     error = TT_Load_Context( exec, face, size );
    820     if ( error )
    821       return error;
    822 
    823     exec->callTop = 0;
    824     exec->top     = 0;
    825 
    826     exec->period    = 64;
    827     exec->phase     = 0;
    828     exec->threshold = 0;
    829 
    830     exec->instruction_trap = FALSE;
    831     exec->F_dot_P          = 0x4000L;
    832 
    833     exec->pedantic_hinting = pedantic;
    834 
    835     {
    836       FT_Size_Metrics*  size_metrics = &exec->metrics;
    837       TT_Size_Metrics*  tt_metrics   = &exec->tt_metrics;
    838 
    839 
    840       size_metrics->x_ppem   = 0;
    841       size_metrics->y_ppem   = 0;
    842       size_metrics->x_scale  = 0;
    843       size_metrics->y_scale  = 0;
    844 
    845       tt_metrics->ppem  = 0;
    846       tt_metrics->scale = 0;
    847       tt_metrics->ratio = 0x10000L;
    848     }
    849 
    850     /* allow font program execution */
    851     TT_Set_CodeRange( exec,
    852                       tt_coderange_font,
    853                       face->font_program,
    854                       (FT_Long)face->font_program_size );
    855 
    856     /* disable CVT and glyph programs coderange */
    857     TT_Clear_CodeRange( exec, tt_coderange_cvt );
    858     TT_Clear_CodeRange( exec, tt_coderange_glyph );
    859 
    860     if ( face->font_program_size > 0 )
    861     {
    862       TT_Goto_CodeRange( exec, tt_coderange_font, 0 );
    863 
    864       FT_TRACE4(( "Executing `fpgm' table.\n" ));
    865       error = face->interpreter( exec );
    866 #ifdef FT_DEBUG_LEVEL_TRACE
    867       if ( error )
    868         FT_TRACE4(( "  interpretation failed with error code 0x%x\n",
    869                     error ));
    870 #endif
    871     }
    872     else
    873       error = FT_Err_Ok;
    874 
    875     size->bytecode_ready = error;
    876 
    877     if ( !error )
    878       TT_Save_Context( exec, size );
    879 
    880     return error;
    881   }
    882 
    883 
    884   /*************************************************************************/
    885   /*                                                                       */
    886   /* <Function>                                                            */
    887   /*    tt_size_run_prep                                                   */
    888   /*                                                                       */
    889   /* <Description>                                                         */
    890   /*    Run the control value program.                                     */
    891   /*                                                                       */
    892   /* <Input>                                                               */
    893   /*    size     :: A handle to the size object.                           */
    894   /*                                                                       */
    895   /*    pedantic :: Set if bytecode execution should be pedantic.          */
    896   /*                                                                       */
    897   /* <Return>                                                              */
    898   /*    FreeType error code.  0 means success.                             */
    899   /*                                                                       */
    900   FT_LOCAL_DEF( FT_Error )
    901   tt_size_run_prep( TT_Size  size,
    902                     FT_Bool  pedantic )
    903   {
    904     TT_Face         face = (TT_Face)size->root.face;
    905     TT_ExecContext  exec;
    906     FT_Error        error;
    907 
    908 
    909     exec = size->context;
    910 
    911     error = TT_Load_Context( exec, face, size );
    912     if ( error )
    913       return error;
    914 
    915     exec->callTop = 0;
    916     exec->top     = 0;
    917 
    918     exec->instruction_trap = FALSE;
    919 
    920     exec->pedantic_hinting = pedantic;
    921 
    922     TT_Set_CodeRange( exec,
    923                       tt_coderange_cvt,
    924                       face->cvt_program,
    925                       (FT_Long)face->cvt_program_size );
    926 
    927     TT_Clear_CodeRange( exec, tt_coderange_glyph );
    928 
    929     if ( face->cvt_program_size > 0 )
    930     {
    931       TT_Goto_CodeRange( exec, tt_coderange_cvt, 0 );
    932 
    933       FT_TRACE4(( "Executing `prep' table.\n" ));
    934       error = face->interpreter( exec );
    935 #ifdef FT_DEBUG_LEVEL_TRACE
    936       if ( error )
    937         FT_TRACE4(( "  interpretation failed with error code 0x%x\n",
    938                     error ));
    939 #endif
    940     }
    941     else
    942       error = FT_Err_Ok;
    943 
    944     size->cvt_ready = error;
    945 
    946     /* UNDOCUMENTED!  The MS rasterizer doesn't allow the following */
    947     /* graphics state variables to be modified by the CVT program.  */
    948 
    949     exec->GS.dualVector.x = 0x4000;
    950     exec->GS.dualVector.y = 0;
    951     exec->GS.projVector.x = 0x4000;
    952     exec->GS.projVector.y = 0x0;
    953     exec->GS.freeVector.x = 0x4000;
    954     exec->GS.freeVector.y = 0x0;
    955 
    956     exec->GS.rp0 = 0;
    957     exec->GS.rp1 = 0;
    958     exec->GS.rp2 = 0;
    959 
    960     exec->GS.gep0 = 1;
    961     exec->GS.gep1 = 1;
    962     exec->GS.gep2 = 1;
    963 
    964     exec->GS.loop = 1;
    965 
    966     /* save as default graphics state */
    967     size->GS = exec->GS;
    968 
    969     TT_Save_Context( exec, size );
    970 
    971     return error;
    972   }
    973 
    974 
    975   static void
    976   tt_size_done_bytecode( FT_Size  ftsize )
    977   {
    978     TT_Size    size   = (TT_Size)ftsize;
    979     TT_Face    face   = (TT_Face)ftsize->face;
    980     FT_Memory  memory = face->root.memory;
    981 
    982     if ( size->context )
    983     {
    984       TT_Done_Context( size->context );
    985       size->context = NULL;
    986     }
    987 
    988     FT_FREE( size->cvt );
    989     size->cvt_size = 0;
    990 
    991     /* free storage area */
    992     FT_FREE( size->storage );
    993     size->storage_size = 0;
    994 
    995     /* twilight zone */
    996     tt_glyphzone_done( &size->twilight );
    997 
    998     FT_FREE( size->function_defs );
    999     FT_FREE( size->instruction_defs );
   1000 
   1001     size->num_function_defs    = 0;
   1002     size->max_function_defs    = 0;
   1003     size->num_instruction_defs = 0;
   1004     size->max_instruction_defs = 0;
   1005 
   1006     size->max_func = 0;
   1007     size->max_ins  = 0;
   1008 
   1009     size->bytecode_ready = -1;
   1010     size->cvt_ready      = -1;
   1011   }
   1012 
   1013 
   1014   /* Initialize bytecode-related fields in the size object.       */
   1015   /* We do this only if bytecode interpretation is really needed. */
   1016   static FT_Error
   1017   tt_size_init_bytecode( FT_Size  ftsize,
   1018                          FT_Bool  pedantic )
   1019   {
   1020     FT_Error   error;
   1021     TT_Size    size = (TT_Size)ftsize;
   1022     TT_Face    face = (TT_Face)ftsize->face;
   1023     FT_Memory  memory = face->root.memory;
   1024 
   1025     FT_UShort       n_twilight;
   1026     TT_MaxProfile*  maxp = &face->max_profile;
   1027 
   1028 
   1029     /* clean up bytecode related data */
   1030     FT_FREE( size->function_defs );
   1031     FT_FREE( size->instruction_defs );
   1032     FT_FREE( size->cvt );
   1033     FT_FREE( size->storage );
   1034 
   1035     if ( size->context )
   1036       TT_Done_Context( size->context );
   1037     tt_glyphzone_done( &size->twilight );
   1038 
   1039     size->bytecode_ready = -1;
   1040     size->cvt_ready      = -1;
   1041 
   1042     size->context = TT_New_Context( (TT_Driver)face->root.driver );
   1043 
   1044     size->max_function_defs    = maxp->maxFunctionDefs;
   1045     size->max_instruction_defs = maxp->maxInstructionDefs;
   1046 
   1047     size->num_function_defs    = 0;
   1048     size->num_instruction_defs = 0;
   1049 
   1050     size->max_func = 0;
   1051     size->max_ins  = 0;
   1052 
   1053     size->cvt_size     = face->cvt_size;
   1054     size->storage_size = maxp->maxStorage;
   1055 
   1056     /* Set default metrics */
   1057     {
   1058       TT_Size_Metrics*  tt_metrics = &size->ttmetrics;
   1059 
   1060 
   1061       tt_metrics->rotated   = FALSE;
   1062       tt_metrics->stretched = FALSE;
   1063 
   1064       /* set default engine compensation */
   1065       tt_metrics->compensations[0] = 0;   /* gray     */
   1066       tt_metrics->compensations[1] = 0;   /* black    */
   1067       tt_metrics->compensations[2] = 0;   /* white    */
   1068       tt_metrics->compensations[3] = 0;   /* reserved */
   1069     }
   1070 
   1071     /* allocate function defs, instruction defs, cvt, and storage area */
   1072     if ( FT_NEW_ARRAY( size->function_defs,    size->max_function_defs    ) ||
   1073          FT_NEW_ARRAY( size->instruction_defs, size->max_instruction_defs ) ||
   1074          FT_NEW_ARRAY( size->cvt,              size->cvt_size             ) ||
   1075          FT_NEW_ARRAY( size->storage,          size->storage_size         ) )
   1076       goto Exit;
   1077 
   1078     /* reserve twilight zone */
   1079     n_twilight = maxp->maxTwilightPoints;
   1080 
   1081     /* there are 4 phantom points (do we need this?) */
   1082     n_twilight += 4;
   1083 
   1084     error = tt_glyphzone_new( memory, n_twilight, 0, &size->twilight );
   1085     if ( error )
   1086       goto Exit;
   1087 
   1088     size->twilight.n_points = n_twilight;
   1089 
   1090     size->GS = tt_default_graphics_state;
   1091 
   1092     /* set `face->interpreter' according to the debug hook present */
   1093     {
   1094       FT_Library  library = face->root.driver->root.library;
   1095 
   1096 
   1097       face->interpreter = (TT_Interpreter)
   1098                             library->debug_hooks[FT_DEBUG_HOOK_TRUETYPE];
   1099       if ( !face->interpreter )
   1100         face->interpreter = (TT_Interpreter)TT_RunIns;
   1101     }
   1102 
   1103     /* Fine, now run the font program! */
   1104 
   1105     /* In case of an error while executing `fpgm', we intentionally don't */
   1106     /* clean up immediately  bugs in the `fpgm' are so fundamental that  */
   1107     /* all following hinting calls should fail.  Additionally, `fpgm' is  */
   1108     /* to be executed just once; calling it again is completely useless   */
   1109     /* and might even lead to extremely slow behaviour if it is malformed */
   1110     /* (containing an infinite loop, for example).                        */
   1111     error = tt_size_run_fpgm( size, pedantic );
   1112     return error;
   1113 
   1114   Exit:
   1115     if ( error )
   1116       tt_size_done_bytecode( ftsize );
   1117 
   1118     return error;
   1119   }
   1120 
   1121 
   1122   FT_LOCAL_DEF( FT_Error )
   1123   tt_size_ready_bytecode( TT_Size  size,
   1124                           FT_Bool  pedantic )
   1125   {
   1126     FT_Error  error = FT_Err_Ok;
   1127 
   1128 
   1129     if ( size->bytecode_ready < 0 )
   1130       error = tt_size_init_bytecode( (FT_Size)size, pedantic );
   1131     else
   1132       error = size->bytecode_ready;
   1133 
   1134     if ( error )
   1135       goto Exit;
   1136 
   1137     /* rescale CVT when needed */
   1138     if ( size->cvt_ready < 0 )
   1139     {
   1140       FT_UInt  i;
   1141       TT_Face  face = (TT_Face)size->root.face;
   1142 
   1143 
   1144       /* Scale the cvt values to the new ppem.          */
   1145       /* We use by default the y ppem to scale the CVT. */
   1146       for ( i = 0; i < size->cvt_size; i++ )
   1147         size->cvt[i] = FT_MulFix( face->cvt[i], size->ttmetrics.scale );
   1148 
   1149       /* all twilight points are originally zero */
   1150       for ( i = 0; i < (FT_UInt)size->twilight.n_points; i++ )
   1151       {
   1152         size->twilight.org[i].x = 0;
   1153         size->twilight.org[i].y = 0;
   1154         size->twilight.cur[i].x = 0;
   1155         size->twilight.cur[i].y = 0;
   1156       }
   1157 
   1158       /* clear storage area */
   1159       for ( i = 0; i < (FT_UInt)size->storage_size; i++ )
   1160         size->storage[i] = 0;
   1161 
   1162       size->GS = tt_default_graphics_state;
   1163 
   1164       error = tt_size_run_prep( size, pedantic );
   1165     }
   1166     else
   1167       error = size->cvt_ready;
   1168 
   1169   Exit:
   1170     return error;
   1171   }
   1172 
   1173 #endif /* TT_USE_BYTECODE_INTERPRETER */
   1174 
   1175 
   1176   /*************************************************************************/
   1177   /*                                                                       */
   1178   /* <Function>                                                            */
   1179   /*    tt_size_init                                                       */
   1180   /*                                                                       */
   1181   /* <Description>                                                         */
   1182   /*    Initialize a new TrueType size object.                             */
   1183   /*                                                                       */
   1184   /* <InOut>                                                               */
   1185   /*    size :: A handle to the size object.                               */
   1186   /*                                                                       */
   1187   /* <Return>                                                              */
   1188   /*    FreeType error code.  0 means success.                             */
   1189   /*                                                                       */
   1190   FT_LOCAL_DEF( FT_Error )
   1191   tt_size_init( FT_Size  ttsize )           /* TT_Size */
   1192   {
   1193     TT_Size   size  = (TT_Size)ttsize;
   1194     FT_Error  error = FT_Err_Ok;
   1195 
   1196 
   1197 #ifdef TT_USE_BYTECODE_INTERPRETER
   1198     size->bytecode_ready = -1;
   1199     size->cvt_ready      = -1;
   1200 #endif
   1201 
   1202     size->ttmetrics.valid = FALSE;
   1203     size->strike_index    = 0xFFFFFFFFUL;
   1204 
   1205     return error;
   1206   }
   1207 
   1208 
   1209   /*************************************************************************/
   1210   /*                                                                       */
   1211   /* <Function>                                                            */
   1212   /*    tt_size_done                                                       */
   1213   /*                                                                       */
   1214   /* <Description>                                                         */
   1215   /*    The TrueType size object finalizer.                                */
   1216   /*                                                                       */
   1217   /* <Input>                                                               */
   1218   /*    size :: A handle to the target size object.                        */
   1219   /*                                                                       */
   1220   FT_LOCAL_DEF( void )
   1221   tt_size_done( FT_Size  ttsize )           /* TT_Size */
   1222   {
   1223     TT_Size  size = (TT_Size)ttsize;
   1224 
   1225 
   1226 #ifdef TT_USE_BYTECODE_INTERPRETER
   1227     tt_size_done_bytecode( ttsize );
   1228 #endif
   1229 
   1230     size->ttmetrics.valid = FALSE;
   1231   }
   1232 
   1233 
   1234   /*************************************************************************/
   1235   /*                                                                       */
   1236   /* <Function>                                                            */
   1237   /*    tt_size_reset                                                      */
   1238   /*                                                                       */
   1239   /* <Description>                                                         */
   1240   /*    Reset a TrueType size when resolutions and character dimensions    */
   1241   /*    have been changed.                                                 */
   1242   /*                                                                       */
   1243   /* <Input>                                                               */
   1244   /*    size        :: A handle to the target size object.                 */
   1245   /*                                                                       */
   1246   /*    only_height :: Only recompute ascender, descender, and height;     */
   1247   /*                   this flag is used for variation fonts where         */
   1248   /*                   `tt_size_reset' is used as an iterator function.    */
   1249   /*                                                                       */
   1250   FT_LOCAL_DEF( FT_Error )
   1251   tt_size_reset( TT_Size  size,
   1252                  FT_Bool  only_height )
   1253   {
   1254     TT_Face           face;
   1255     FT_Size_Metrics*  size_metrics;
   1256 
   1257 
   1258     face = (TT_Face)size->root.face;
   1259 
   1260     /* nothing to do for CFF2 */
   1261     if ( face->is_cff2 )
   1262       return FT_Err_Ok;
   1263 
   1264     size->ttmetrics.valid = FALSE;
   1265 
   1266     size_metrics = &size->hinted_metrics;
   1267 
   1268     /* copy the result from base layer */
   1269     *size_metrics = size->root.metrics;
   1270 
   1271     if ( size_metrics->x_ppem < 1 || size_metrics->y_ppem < 1 )
   1272       return FT_THROW( Invalid_PPem );
   1273 
   1274     /* This bit flag, if set, indicates that the ppems must be       */
   1275     /* rounded to integers.  Nearly all TrueType fonts have this bit */
   1276     /* set, as hinting won't work really well otherwise.             */
   1277     /*                                                               */
   1278     if ( face->header.Flags & 8 )
   1279     {
   1280       /* the TT spec always asks for ROUND, not FLOOR or CEIL */
   1281       size_metrics->ascender = FT_PIX_ROUND(
   1282                                  FT_MulFix( face->root.ascender,
   1283                                             size_metrics->y_scale ) );
   1284       size_metrics->descender = FT_PIX_ROUND(
   1285                                  FT_MulFix( face->root.descender,
   1286                                             size_metrics->y_scale ) );
   1287       size_metrics->height = FT_PIX_ROUND(
   1288                                FT_MulFix( face->root.height,
   1289                                           size_metrics->y_scale ) );
   1290     }
   1291 
   1292     size->ttmetrics.valid = TRUE;
   1293 
   1294     if ( only_height )
   1295     {
   1296       /* we must not recompute the scaling values here since       */
   1297       /* `tt_size_reset' was already called (with only_height = 0) */
   1298       return FT_Err_Ok;
   1299     }
   1300 
   1301     if ( face->header.Flags & 8 )
   1302     {
   1303       /* base scaling values on integer ppem values, */
   1304       /* as mandated by the TrueType specification   */
   1305       size_metrics->x_scale = FT_DivFix( size_metrics->x_ppem << 6,
   1306                                          face->root.units_per_EM );
   1307       size_metrics->y_scale = FT_DivFix( size_metrics->y_ppem << 6,
   1308                                          face->root.units_per_EM );
   1309 
   1310       size_metrics->max_advance = FT_PIX_ROUND(
   1311                                     FT_MulFix( face->root.max_advance_width,
   1312                                                size_metrics->x_scale ) );
   1313     }
   1314 
   1315     /* compute new transformation */
   1316     if ( size_metrics->x_ppem >= size_metrics->y_ppem )
   1317     {
   1318       size->ttmetrics.scale   = size_metrics->x_scale;
   1319       size->ttmetrics.ppem    = size_metrics->x_ppem;
   1320       size->ttmetrics.x_ratio = 0x10000L;
   1321       size->ttmetrics.y_ratio = FT_DivFix( size_metrics->y_ppem,
   1322                                            size_metrics->x_ppem );
   1323     }
   1324     else
   1325     {
   1326       size->ttmetrics.scale   = size_metrics->y_scale;
   1327       size->ttmetrics.ppem    = size_metrics->y_ppem;
   1328       size->ttmetrics.x_ratio = FT_DivFix( size_metrics->x_ppem,
   1329                                            size_metrics->y_ppem );
   1330       size->ttmetrics.y_ratio = 0x10000L;
   1331     }
   1332 
   1333     size->metrics = size_metrics;
   1334 
   1335 #ifdef TT_USE_BYTECODE_INTERPRETER
   1336     size->cvt_ready = -1;
   1337 #endif /* TT_USE_BYTECODE_INTERPRETER */
   1338 
   1339     return FT_Err_Ok;
   1340   }
   1341 
   1342 
   1343   /*************************************************************************/
   1344   /*                                                                       */
   1345   /* <Function>                                                            */
   1346   /*    tt_driver_init                                                     */
   1347   /*                                                                       */
   1348   /* <Description>                                                         */
   1349   /*    Initialize a given TrueType driver object.                         */
   1350   /*                                                                       */
   1351   /* <Input>                                                               */
   1352   /*    driver :: A handle to the target driver object.                    */
   1353   /*                                                                       */
   1354   /* <Return>                                                              */
   1355   /*    FreeType error code.  0 means success.                             */
   1356   /*                                                                       */
   1357   FT_LOCAL_DEF( FT_Error )
   1358   tt_driver_init( FT_Module  ttdriver )     /* TT_Driver */
   1359   {
   1360 
   1361 #ifdef TT_USE_BYTECODE_INTERPRETER
   1362 
   1363     TT_Driver  driver = (TT_Driver)ttdriver;
   1364 
   1365     driver->interpreter_version = TT_INTERPRETER_VERSION_35;
   1366 #ifdef TT_SUPPORT_SUBPIXEL_HINTING_INFINALITY
   1367     driver->interpreter_version = TT_INTERPRETER_VERSION_38;
   1368 #endif
   1369 #ifdef TT_SUPPORT_SUBPIXEL_HINTING_MINIMAL
   1370     driver->interpreter_version = TT_INTERPRETER_VERSION_40;
   1371 #endif
   1372 
   1373 #else /* !TT_USE_BYTECODE_INTERPRETER */
   1374 
   1375     FT_UNUSED( ttdriver );
   1376 
   1377 #endif /* !TT_USE_BYTECODE_INTERPRETER */
   1378 
   1379     return FT_Err_Ok;
   1380   }
   1381 
   1382 
   1383   /*************************************************************************/
   1384   /*                                                                       */
   1385   /* <Function>                                                            */
   1386   /*    tt_driver_done                                                     */
   1387   /*                                                                       */
   1388   /* <Description>                                                         */
   1389   /*    Finalize a given TrueType driver.                                  */
   1390   /*                                                                       */
   1391   /* <Input>                                                               */
   1392   /*    driver :: A handle to the target TrueType driver.                  */
   1393   /*                                                                       */
   1394   FT_LOCAL_DEF( void )
   1395   tt_driver_done( FT_Module  ttdriver )     /* TT_Driver */
   1396   {
   1397     FT_UNUSED( ttdriver );
   1398   }
   1399 
   1400 
   1401   /*************************************************************************/
   1402   /*                                                                       */
   1403   /* <Function>                                                            */
   1404   /*    tt_slot_init                                                       */
   1405   /*                                                                       */
   1406   /* <Description>                                                         */
   1407   /*    Initialize a new slot object.                                      */
   1408   /*                                                                       */
   1409   /* <InOut>                                                               */
   1410   /*    slot :: A handle to the slot object.                               */
   1411   /*                                                                       */
   1412   /* <Return>                                                              */
   1413   /*    FreeType error code.  0 means success.                             */
   1414   /*                                                                       */
   1415   FT_LOCAL_DEF( FT_Error )
   1416   tt_slot_init( FT_GlyphSlot  slot )
   1417   {
   1418     return FT_GlyphLoader_CreateExtra( slot->internal->loader );
   1419   }
   1420 
   1421 
   1422 /* END */
   1423