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