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 )
tt_glyphzone_done(TT_GlyphZone zone)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 )
tt_glyphzone_new(FT_Memory memory,FT_UShort maxPoints,FT_Short maxContours,TT_GlyphZone zone)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
tt_check_trickyness_family(FT_String * name)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
tt_synth_sfnt_checksum(FT_Stream stream,FT_ULong length)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
tt_get_sfnt_checksum(TT_Face face,FT_UShort i)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
tt_check_trickyness_sfnt_ids(TT_Face face)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
tt_check_trickyness(FT_Face face)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
tt_check_single_notdef(FT_Face ttface)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 )
tt_face_init(FT_Stream stream,FT_Face ttface,FT_Int face_index,FT_Int num_params,FT_Parameter * params)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 )
tt_face_done(FT_Face ttface)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 )
tt_size_run_fpgm(TT_Size size,FT_Bool pedantic)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 )
tt_size_run_prep(TT_Size size,FT_Bool pedantic)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
tt_size_done_bytecode(FT_Size ftsize)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
tt_size_init_bytecode(FT_Size ftsize,FT_Bool pedantic)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 )
tt_size_ready_bytecode(TT_Size size,FT_Bool pedantic)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 )
tt_size_init(FT_Size ttsize)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 )
tt_size_done(FT_Size ttsize)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 )
tt_size_reset(TT_Size size,FT_Bool only_height)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 )
tt_driver_init(FT_Module ttdriver)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 )
tt_driver_done(FT_Module ttdriver)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 )
tt_slot_init(FT_GlyphSlot slot)1416   tt_slot_init( FT_GlyphSlot  slot )
1417   {
1418     return FT_GlyphLoader_CreateExtra( slot->internal->loader );
1419   }
1420 
1421 
1422 /* END */
1423