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