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