Merge 25584, 25588.
[reactos.git] / reactos / dll / 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_strcmp( ttface->family_name, trick_names[nn] ) == 0 )
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->root.metrics;
599 TT_Size_Metrics* metrics2 = &size->ttmetrics;
600
601
602 metrics->x_ppem = 0;
603 metrics->y_ppem = 0;
604
605 metrics2->rotated = FALSE;
606 metrics2->stretched = FALSE;
607
608 /* set default compensation (all 0) */
609 for ( i = 0; i < 4; i++ )
610 metrics2->compensations[i] = 0;
611 }
612
613 /* allocate function defs, instruction defs, cvt, and storage area */
614 if ( FT_NEW_ARRAY( size->function_defs, size->max_function_defs ) ||
615 FT_NEW_ARRAY( size->instruction_defs, size->max_instruction_defs ) ||
616 FT_NEW_ARRAY( size->cvt, size->cvt_size ) ||
617 FT_NEW_ARRAY( size->storage, size->storage_size ) )
618 goto Exit;
619
620 /* reserve twilight zone */
621 n_twilight = maxp->maxTwilightPoints;
622
623 /* there are 4 phantom points (do we need this?) */
624 n_twilight += 4;
625
626 error = tt_glyphzone_new( memory, n_twilight, 0, &size->twilight );
627 if ( error )
628 goto Exit;
629
630 size->twilight.n_points = n_twilight;
631
632 size->GS = tt_default_graphics_state;
633
634 /* set `face->interpreter' according to the debug hook present */
635 {
636 FT_Library library = face->root.driver->root.library;
637
638
639 face->interpreter = (TT_Interpreter)
640 library->debug_hooks[FT_DEBUG_HOOK_TRUETYPE];
641 if ( !face->interpreter )
642 face->interpreter = (TT_Interpreter)TT_RunIns;
643 }
644
645 /* Fine, now run the font program! */
646 error = tt_size_run_fpgm( size );
647
648 Exit:
649 if ( error )
650 tt_size_done_bytecode( ftsize );
651
652 return error;
653 }
654
655
656 FT_LOCAL_DEF( FT_Error )
657 tt_size_ready_bytecode( TT_Size size )
658 {
659 FT_Error error = TT_Err_Ok;
660
661
662 if ( !size->bytecode_ready )
663 {
664 error = tt_size_init_bytecode( (FT_Size)size );
665 if ( error )
666 goto Exit;
667 }
668
669 /* rescale CVT when needed */
670 if ( !size->cvt_ready )
671 {
672 FT_UInt i;
673 TT_Face face = (TT_Face) size->root.face;
674
675
676 /* Scale the cvt values to the new ppem. */
677 /* We use by default the y ppem to scale the CVT. */
678 for ( i = 0; i < size->cvt_size; i++ )
679 size->cvt[i] = FT_MulFix( face->cvt[i], size->ttmetrics.scale );
680
681 /* all twilight points are originally zero */
682 for ( i = 0; i < (FT_UInt)size->twilight.n_points; i++ )
683 {
684 size->twilight.org[i].x = 0;
685 size->twilight.org[i].y = 0;
686 size->twilight.cur[i].x = 0;
687 size->twilight.cur[i].y = 0;
688 }
689
690 /* clear storage area */
691 for ( i = 0; i < (FT_UInt)size->storage_size; i++ )
692 size->storage[i] = 0;
693
694 size->GS = tt_default_graphics_state;
695
696 error = tt_size_run_prep( size );
697 }
698 Exit:
699 return error;
700 }
701
702 #else /* !TT_USE_BYTECODE_INTERPRETER */
703
704 FT_LOCAL_DEF( FT_Error )
705 tt_size_ready_bytecode( TT_Size size )
706 {
707 FT_UNUSED( ftsize );
708 return 0;
709 }
710
711 #endif /* !TT_USE_BYTECODE_INTERPRETER */
712
713
714 /*************************************************************************/
715 /* */
716 /* <Function> */
717 /* tt_size_init */
718 /* */
719 /* <Description> */
720 /* Initialize a new TrueType size object. */
721 /* */
722 /* <InOut> */
723 /* size :: A handle to the size object. */
724 /* */
725 /* <Return> */
726 /* FreeType error code. 0 means success. */
727 /* */
728 FT_LOCAL_DEF( FT_Error )
729 tt_size_init( FT_Size ttsize ) /* TT_Size */
730 {
731 TT_Size size = (TT_Size)ttsize;
732 FT_Error error = TT_Err_Ok;
733
734 #ifdef TT_USE_BYTECODE_INTERPRETER
735 size->bytecode_ready = 0;
736 size->cvt_ready = 0;
737 #endif
738
739 size->ttmetrics.valid = FALSE;
740 size->strike_index = 0xFFFFFFFFUL;
741
742 return error;
743 }
744
745
746 /*************************************************************************/
747 /* */
748 /* <Function> */
749 /* tt_size_done */
750 /* */
751 /* <Description> */
752 /* The TrueType size object finalizer. */
753 /* */
754 /* <Input> */
755 /* size :: A handle to the target size object. */
756 /* */
757 FT_LOCAL_DEF( void )
758 tt_size_done( FT_Size ttsize ) /* TT_Size */
759 {
760 TT_Size size = (TT_Size)ttsize;
761
762
763 #ifdef TT_USE_BYTECODE_INTERPRETER
764 if ( size->bytecode_ready )
765 tt_size_done_bytecode( ttsize );
766 #endif
767
768 size->ttmetrics.valid = FALSE;
769 }
770
771
772 /*************************************************************************/
773 /* */
774 /* <Function> */
775 /* tt_size_reset */
776 /* */
777 /* <Description> */
778 /* Reset a TrueType size when resolutions and character dimensions */
779 /* have been changed. */
780 /* */
781 /* <Input> */
782 /* size :: A handle to the target size object. */
783 /* */
784 FT_LOCAL_DEF( FT_Error )
785 tt_size_reset( TT_Size size )
786 {
787 TT_Face face;
788 FT_Error error = TT_Err_Ok;
789 FT_Size_Metrics* metrics;
790
791
792 size->ttmetrics.valid = FALSE;
793
794 face = (TT_Face)size->root.face;
795
796 metrics = &size->metrics;
797
798 /* copy the result from base layer */
799 *metrics = size->root.metrics;
800
801 if ( metrics->x_ppem < 1 || metrics->y_ppem < 1 )
802 return TT_Err_Invalid_PPem;
803
804 /* This bit flag, if set, indicates that the ppems must be */
805 /* rounded to integers. Nearly all TrueType fonts have this bit */
806 /* set, as hinting won't work really well otherwise. */
807 /* */
808 if ( face->header.Flags & 8 )
809 {
810 metrics->x_scale = FT_DivFix( metrics->x_ppem << 6,
811 face->root.units_per_EM );
812 metrics->y_scale = FT_DivFix( metrics->y_ppem << 6,
813 face->root.units_per_EM );
814
815 metrics->ascender =
816 FT_PIX_ROUND( FT_MulFix( face->root.ascender, metrics->y_scale ) );
817 metrics->descender =
818 FT_PIX_ROUND( FT_MulFix( face->root.descender, metrics->y_scale ) );
819 metrics->height =
820 FT_PIX_ROUND( FT_MulFix( face->root.height, metrics->y_scale ) );
821 metrics->max_advance =
822 FT_PIX_ROUND( FT_MulFix( face->root.max_advance_width,
823 metrics->x_scale ) );
824 }
825
826 /* compute new transformation */
827 if ( metrics->x_ppem >= metrics->y_ppem )
828 {
829 size->ttmetrics.scale = metrics->x_scale;
830 size->ttmetrics.ppem = metrics->x_ppem;
831 size->ttmetrics.x_ratio = 0x10000L;
832 size->ttmetrics.y_ratio = FT_MulDiv( metrics->y_ppem,
833 0x10000L,
834 metrics->x_ppem );
835 }
836 else
837 {
838 size->ttmetrics.scale = metrics->y_scale;
839 size->ttmetrics.ppem = metrics->y_ppem;
840 size->ttmetrics.x_ratio = FT_MulDiv( metrics->x_ppem,
841 0x10000L,
842 metrics->y_ppem );
843 size->ttmetrics.y_ratio = 0x10000L;
844 }
845
846 #ifdef TT_USE_BYTECODE_INTERPRETER
847 size->cvt_ready = 0;
848 #endif /* TT_USE_BYTECODE_INTERPRETER */
849
850 if ( !error )
851 size->ttmetrics.valid = TRUE;
852
853 return error;
854 }
855
856
857 /*************************************************************************/
858 /* */
859 /* <Function> */
860 /* tt_driver_init */
861 /* */
862 /* <Description> */
863 /* Initialize a given TrueType driver object. */
864 /* */
865 /* <Input> */
866 /* driver :: A handle to the target driver object. */
867 /* */
868 /* <Return> */
869 /* FreeType error code. 0 means success. */
870 /* */
871 FT_LOCAL_DEF( FT_Error )
872 tt_driver_init( FT_Module ttdriver ) /* TT_Driver */
873 {
874
875 #ifdef TT_USE_BYTECODE_INTERPRETER
876
877 TT_Driver driver = (TT_Driver)ttdriver;
878
879
880 if ( !TT_New_Context( driver ) )
881 return TT_Err_Could_Not_Find_Context;
882
883 #else
884
885 FT_UNUSED( ttdriver );
886
887 #endif
888
889 return TT_Err_Ok;
890 }
891
892
893 /*************************************************************************/
894 /* */
895 /* <Function> */
896 /* tt_driver_done */
897 /* */
898 /* <Description> */
899 /* Finalize a given TrueType driver. */
900 /* */
901 /* <Input> */
902 /* driver :: A handle to the target TrueType driver. */
903 /* */
904 FT_LOCAL_DEF( void )
905 tt_driver_done( FT_Module ttdriver ) /* TT_Driver */
906 {
907 #ifdef TT_USE_BYTECODE_INTERPRETER
908 TT_Driver driver = (TT_Driver)ttdriver;
909
910
911 /* destroy the execution context */
912 if ( driver->context )
913 {
914 TT_Done_Context( driver->context );
915 driver->context = NULL;
916 }
917 #else
918 FT_UNUSED( ttdriver );
919 #endif
920
921 }
922
923
924 /*************************************************************************/
925 /* */
926 /* <Function> */
927 /* tt_slot_init */
928 /* */
929 /* <Description> */
930 /* Initialize a new slot object. */
931 /* */
932 /* <InOut> */
933 /* slot :: A handle to the slot object. */
934 /* */
935 /* <Return> */
936 /* FreeType error code. 0 means success. */
937 /* */
938 FT_LOCAL_DEF( FT_Error )
939 tt_slot_init( FT_GlyphSlot slot )
940 {
941 return FT_GlyphLoader_CreateExtra( slot->internal->loader );
942 }
943
944
945 /* END */