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