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