1 /***************************************************************************/
5 /* Objects manager (body). */
7 /* Copyright 1996-2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, */
9 /* David Turner, Robert Wilhelm, and Werner Lemberg. */
11 /* This file is part of the FreeType project, and may only be used, */
12 /* modified, and distributed under the terms of the FreeType project */
13 /* license, LICENSE.TXT. By continuing to use, modify, or distribute */
14 /* this file you indicate that you have read the license and */
15 /* understand and accept it fully. */
17 /***************************************************************************/
21 #include FT_INTERNAL_DEBUG_H
22 #include FT_INTERNAL_STREAM_H
23 #include FT_TRUETYPE_TAGS_H
24 #include FT_INTERNAL_SFNT_H
31 #ifdef TT_USE_BYTECODE_INTERPRETER
35 #ifdef TT_CONFIG_OPTION_UNPATENTED_HINTING
36 #include FT_TRUETYPE_UNPATENTED_H
39 #ifdef TT_CONFIG_OPTION_GX_VAR_SUPPORT
43 /*************************************************************************/
45 /* The macro FT_COMPONENT is used in trace mode. It is an implicit */
46 /* parameter of the FT_TRACE() and FT_ERROR() macros, used to print/log */
47 /* messages during execution. */
50 #define FT_COMPONENT trace_ttobjs
53 #ifdef TT_USE_BYTECODE_INTERPRETER
55 /*************************************************************************/
57 /* GLYPH ZONE FUNCTIONS */
59 /*************************************************************************/
62 /*************************************************************************/
65 /* tt_glyphzone_done */
68 /* Deallocate a glyph zone. */
71 /* zone :: A pointer to the target glyph zone. */
74 tt_glyphzone_done( TT_GlyphZone zone
)
76 FT_Memory memory
= zone
->memory
;
81 FT_FREE( zone
->contours
);
82 FT_FREE( zone
->tags
);
85 FT_FREE( zone
->orus
);
87 zone
->max_points
= zone
->n_points
= 0;
88 zone
->max_contours
= zone
->n_contours
= 0;
94 /*************************************************************************/
97 /* tt_glyphzone_new */
100 /* Allocate a new glyph zone. */
103 /* memory :: A handle to the current memory object. */
105 /* maxPoints :: The capacity of glyph zone in points. */
107 /* maxContours :: The capacity of glyph zone in contours. */
110 /* zone :: A pointer to the target glyph zone record. */
113 /* FreeType error code. 0 means success. */
115 FT_LOCAL_DEF( FT_Error
)
116 tt_glyphzone_new( FT_Memory memory
,
118 FT_Short maxContours
,
124 FT_MEM_ZERO( zone
, sizeof ( *zone
) );
125 zone
->memory
= memory
;
127 if ( FT_NEW_ARRAY( zone
->org
, maxPoints
) ||
128 FT_NEW_ARRAY( zone
->cur
, maxPoints
) ||
129 FT_NEW_ARRAY( zone
->orus
, maxPoints
) ||
130 FT_NEW_ARRAY( zone
->tags
, maxPoints
) ||
131 FT_NEW_ARRAY( zone
->contours
, maxContours
) )
133 tt_glyphzone_done( zone
);
137 zone
->max_points
= maxPoints
;
138 zone
->max_contours
= maxContours
;
143 #endif /* TT_USE_BYTECODE_INTERPRETER */
146 /* Compare the face with a list of well-known `tricky' fonts. */
147 /* This list shall be expanded as we find more of them. */
150 tt_check_trickyness_family( FT_String
* name
)
153 #define TRICK_NAMES_MAX_CHARACTERS 16
154 #define TRICK_NAMES_COUNT 8
156 static const char trick_names
[TRICK_NAMES_COUNT
]
157 [TRICK_NAMES_MAX_CHARACTERS
+ 1] =
159 "DFKaiSho-SB", /* dfkaisb.ttf */
161 "DFKai-SB", /* kaiu.ttf */
162 "HuaTianKaiTi?", /* htkt2.ttf */
163 "HuaTianSongTi?", /* htst3.ttf */
164 "MingLiU", /* mingliu.ttf & mingliu.ttc */
165 "PMingLiU", /* mingliu.ttc */
166 "MingLi43", /* mingli.ttf */
172 for ( nn
= 0; nn
< TRICK_NAMES_COUNT
; nn
++ )
173 if ( ft_strstr( name
, trick_names
[nn
] ) )
180 /* XXX: This function should be in the `sfnt' module. */
182 /* Some PDF generators clear the checksums in the TrueType header table. */
183 /* For example, Quartz ContextPDF clears all entries, or Bullzip PDF */
184 /* Printer clears the entries for subsetted subtables. We thus have to */
185 /* recalculate the checksums where necessary. */
188 tt_synth_sfnt_checksum( FT_Stream stream
,
192 FT_UInt32 checksum
= 0;
196 if ( FT_FRAME_ENTER( length
) )
199 for ( ; length
> 3; length
-= 4 )
200 checksum
+= (FT_UInt32
)FT_GET_ULONG();
202 for ( i
= 3; length
> 0; length
--, i
-- )
203 checksum
+= (FT_UInt32
)( FT_GET_BYTE() << ( i
* 8 ) );
211 /* XXX: This function should be in the `sfnt' module. */
214 tt_get_sfnt_checksum( TT_Face face
,
217 if ( face
->dir_tables
[i
].CheckSum
)
218 return face
->dir_tables
[i
].CheckSum
;
220 else if ( !face
->goto_table
)
223 else if ( !face
->goto_table( face
,
224 face
->dir_tables
[i
].Tag
,
229 return (FT_ULong
)tt_synth_sfnt_checksum( face
->root
.stream
,
230 face
->dir_tables
[i
].Length
);
234 typedef struct tt_sfnt_id_rec_
243 tt_check_trickyness_sfnt_ids( TT_Face face
)
245 #define TRICK_SFNT_IDS_PER_FACE 3
246 #define TRICK_SFNT_IDS_NUM_FACES 5
248 static const tt_sfnt_id_rec sfnt_id
[TRICK_SFNT_IDS_NUM_FACES
]
249 [TRICK_SFNT_IDS_PER_FACE
] = {
251 #define TRICK_SFNT_ID_cvt 0
252 #define TRICK_SFNT_ID_fpgm 1
253 #define TRICK_SFNT_ID_prep 2
256 { 0x05bcf058, 0x000002e4 }, /* cvt */
257 { 0x28233bf1, 0x000087c4 }, /* fpgm */
258 { 0xa344a1ea, 0x000001e1 } /* prep */
260 { /* MingLiU 1996- */
261 { 0x05bcf058, 0x000002e4 }, /* cvt */
262 { 0x28233bf1, 0x000087c4 }, /* fpgm */
263 { 0xa344a1eb, 0x000001e1 } /* prep */
266 { 0x11e5ead4, 0x00000350 }, /* cvt */
267 { 0x5a30ca3b, 0x00009063 }, /* fpgm */
268 { 0x13a42602, 0x0000007e } /* prep */
271 { 0xfffbfffc, 0x00000008 }, /* cvt */
272 { 0x9c9e48b8, 0x0000bea2 }, /* fpgm */
273 { 0x70020112, 0x00000008 } /* prep */
275 { /* HuaTianSongTi */
276 { 0xfffbfffc, 0x00000008 }, /* cvt */
277 { 0x0a5a0483, 0x00017c39 }, /* fpgm */
278 { 0x70020112, 0x00000008 } /* prep */
283 int num_matched_ids
[TRICK_SFNT_IDS_NUM_FACES
];
287 FT_MEM_SET( num_matched_ids
, 0,
288 sizeof( int ) * TRICK_SFNT_IDS_NUM_FACES
);
290 for ( i
= 0; i
< face
->num_tables
; i
++ )
294 switch( face
->dir_tables
[i
].Tag
)
297 k
= TRICK_SFNT_ID_cvt
;
301 k
= TRICK_SFNT_ID_fpgm
;
305 k
= TRICK_SFNT_ID_prep
;
312 for ( j
= 0; j
< TRICK_SFNT_IDS_NUM_FACES
; j
++ )
313 if ( face
->dir_tables
[i
].Length
== sfnt_id
[j
][k
].Length
)
316 checksum
= tt_get_sfnt_checksum( face
, i
);
318 if ( sfnt_id
[j
][k
].CheckSum
== checksum
)
319 num_matched_ids
[j
]++;
321 if ( num_matched_ids
[j
] == TRICK_SFNT_IDS_PER_FACE
)
331 tt_check_trickyness( FT_Face face
)
336 /* First, check the face name. */
337 if ( face
->family_name
)
339 if ( tt_check_trickyness_family( face
->family_name
) )
345 /* Type42 fonts may lack `name' tables, we thus try to identify */
346 /* tricky fonts by checking the checksums of Type42-persistent */
347 /* sfnt tables (`cvt', `fpgm', and `prep'). */
348 if ( tt_check_trickyness_sfnt_ids( (TT_Face
)face
) )
355 /*************************************************************************/
361 /* Initialize a given TrueType face object. */
364 /* stream :: The source font stream. */
366 /* face_index :: The index of the font face in the resource. */
368 /* num_params :: Number of additional generic parameters. Ignored. */
370 /* params :: Additional generic parameters. Ignored. */
373 /* face :: The newly built face object. */
376 /* FreeType error code. 0 means success. */
378 FT_LOCAL_DEF( FT_Error
)
379 tt_face_init( FT_Stream stream
,
380 FT_Face ttface
, /* TT_Face */
383 FT_Parameter
* params
)
388 TT_Face face
= (TT_Face
)ttface
;
391 library
= ttface
->driver
->root
.library
;
392 sfnt
= (SFNT_Service
)FT_Get_Module_Interface( library
, "sfnt" );
396 /* create input stream from resource */
397 if ( FT_STREAM_SEEK( 0 ) )
400 /* check that we have a valid TrueType file */
401 error
= sfnt
->init_face( stream
, face
, face_index
, num_params
, params
);
405 /* We must also be able to accept Mac/GX fonts, as well as OT ones. */
406 /* The 0x00020000 tag is completely undocumented; some fonts from */
407 /* Arphic made for Chinese Windows 3.1 have this. */
408 if ( face
->format_tag
!= 0x00010000L
&& /* MS fonts */
409 face
->format_tag
!= 0x00020000L
&& /* CJK fonts for Win 3.1 */
410 face
->format_tag
!= TTAG_true
) /* Mac fonts */
412 FT_TRACE2(( "[not a valid TTF font]\n" ));
416 #ifdef TT_USE_BYTECODE_INTERPRETER
417 ttface
->face_flags
|= FT_FACE_FLAG_HINTER
;
420 /* If we are performing a simple font format check, exit immediately. */
421 if ( face_index
< 0 )
424 /* Load font directory */
425 error
= sfnt
->load_face( stream
, face
, face_index
, num_params
, params
);
429 if ( tt_check_trickyness( ttface
) )
430 ttface
->face_flags
|= FT_FACE_FLAG_TRICKY
;
432 error
= tt_face_load_hdmx( face
, stream
);
436 if ( FT_IS_SCALABLE( ttface
) )
439 #ifdef FT_CONFIG_OPTION_INCREMENTAL
441 if ( !ttface
->internal
->incremental_interface
)
442 error
= tt_face_load_loca( face
, stream
);
444 error
= tt_face_load_cvt( face
, stream
);
446 error
= tt_face_load_fpgm( face
, stream
);
448 error
= tt_face_load_prep( face
, stream
);
453 error
= tt_face_load_loca( face
, stream
);
455 error
= tt_face_load_cvt( face
, stream
);
457 error
= tt_face_load_fpgm( face
, stream
);
459 error
= tt_face_load_prep( face
, stream
);
465 #if defined( TT_CONFIG_OPTION_UNPATENTED_HINTING ) && \
466 !defined( TT_CONFIG_OPTION_BYTECODE_INTERPRETER )
469 FT_Bool unpatented_hinting
;
473 /* Determine whether unpatented hinting is to be used for this face. */
474 unpatented_hinting
= FT_BOOL
475 ( library
->debug_hooks
[FT_DEBUG_HOOK_UNPATENTED_HINTING
] != NULL
);
477 for ( i
= 0; i
< num_params
&& !face
->unpatented_hinting
; i
++ )
478 if ( params
[i
].tag
== FT_PARAM_TAG_UNPATENTED_HINTING
)
479 unpatented_hinting
= TRUE
;
481 if ( !unpatented_hinting
)
482 ttface
->internal
->ignore_unpatented_hinter
= TRUE
;
485 #endif /* TT_CONFIG_OPTION_UNPATENTED_HINTING &&
486 !TT_CONFIG_OPTION_BYTECODE_INTERPRETER */
488 /* initialize standard glyph loading routines */
489 TT_Init_Glyph_Loading( face
);
495 error
= TT_Err_Unknown_File_Format
;
500 /*************************************************************************/
506 /* Finalize a given face object. */
509 /* face :: A pointer to the face object to destroy. */
512 tt_face_done( FT_Face ttface
) /* TT_Face */
514 TT_Face face
= (TT_Face
)ttface
;
523 memory
= ttface
->memory
;
524 stream
= ttface
->stream
;
525 sfnt
= (SFNT_Service
)face
->sfnt
;
527 /* for `extended TrueType formats' (i.e. compressed versions) */
528 if ( face
->extra
.finalizer
)
529 face
->extra
.finalizer( face
->extra
.data
);
532 sfnt
->done_face( face
);
534 /* freeing the locations table */
535 tt_face_done_loca( face
);
537 tt_face_free_hdmx( face
);
539 /* freeing the CVT */
540 FT_FREE( face
->cvt
);
543 /* freeing the programs */
544 FT_FRAME_RELEASE( face
->font_program
);
545 FT_FRAME_RELEASE( face
->cvt_program
);
546 face
->font_program_size
= 0;
547 face
->cvt_program_size
= 0;
549 #ifdef TT_CONFIG_OPTION_GX_VAR_SUPPORT
550 tt_done_blend( memory
, face
->blend
);
556 /*************************************************************************/
560 /*************************************************************************/
562 #ifdef TT_USE_BYTECODE_INTERPRETER
564 /*************************************************************************/
567 /* tt_size_run_fpgm */
570 /* Run the font program. */
573 /* size :: A handle to the size object. */
576 /* FreeType error code. 0 means success. */
578 FT_LOCAL_DEF( FT_Error
)
579 tt_size_run_fpgm( TT_Size size
)
581 TT_Face face
= (TT_Face
)size
->root
.face
;
586 /* debugging instances have their own context */
588 exec
= size
->context
;
590 exec
= ( (TT_Driver
)FT_FACE_DRIVER( face
) )->context
;
593 return TT_Err_Could_Not_Find_Context
;
595 TT_Load_Context( exec
, face
, size
);
604 exec
->instruction_trap
= FALSE
;
605 exec
->F_dot_P
= 0x10000L
;
608 FT_Size_Metrics
* metrics
= &exec
->metrics
;
609 TT_Size_Metrics
* tt_metrics
= &exec
->tt_metrics
;
614 metrics
->x_scale
= 0;
615 metrics
->y_scale
= 0;
617 tt_metrics
->ppem
= 0;
618 tt_metrics
->scale
= 0;
619 tt_metrics
->ratio
= 0x10000L
;
622 /* allow font program execution */
623 TT_Set_CodeRange( exec
,
626 face
->font_program_size
);
628 /* disable CVT and glyph programs coderange */
629 TT_Clear_CodeRange( exec
, tt_coderange_cvt
);
630 TT_Clear_CodeRange( exec
, tt_coderange_glyph
);
632 if ( face
->font_program_size
> 0 )
634 error
= TT_Goto_CodeRange( exec
, tt_coderange_font
, 0 );
638 FT_TRACE4(( "Executing `fpgm' table.\n" ));
640 error
= face
->interpreter( exec
);
647 TT_Save_Context( exec
, size
);
653 /*************************************************************************/
656 /* tt_size_run_prep */
659 /* Run the control value program. */
662 /* size :: A handle to the size object. */
665 /* FreeType error code. 0 means success. */
667 FT_LOCAL_DEF( FT_Error
)
668 tt_size_run_prep( TT_Size size
)
670 TT_Face face
= (TT_Face
)size
->root
.face
;
675 /* debugging instances have their own context */
677 exec
= size
->context
;
679 exec
= ( (TT_Driver
)FT_FACE_DRIVER( face
) )->context
;
682 return TT_Err_Could_Not_Find_Context
;
684 TT_Load_Context( exec
, face
, size
);
689 exec
->instruction_trap
= FALSE
;
691 TT_Set_CodeRange( exec
,
694 face
->cvt_program_size
);
696 TT_Clear_CodeRange( exec
, tt_coderange_glyph
);
698 if ( face
->cvt_program_size
> 0 )
700 error
= TT_Goto_CodeRange( exec
, tt_coderange_cvt
, 0 );
702 if ( !error
&& !size
->debug
)
704 FT_TRACE4(( "Executing `prep' table.\n" ));
706 error
= face
->interpreter( exec
);
712 /* save as default graphics state */
715 TT_Save_Context( exec
, size
);
720 #endif /* TT_USE_BYTECODE_INTERPRETER */
723 #ifdef TT_USE_BYTECODE_INTERPRETER
726 tt_size_done_bytecode( FT_Size ftsize
)
728 TT_Size size
= (TT_Size
)ftsize
;
729 TT_Face face
= (TT_Face
)ftsize
->face
;
730 FT_Memory memory
= face
->root
.memory
;
735 /* the debug context must be deleted by the debugger itself */
736 size
->context
= NULL
;
740 FT_FREE( size
->cvt
);
743 /* free storage area */
744 FT_FREE( size
->storage
);
745 size
->storage_size
= 0;
748 tt_glyphzone_done( &size
->twilight
);
750 FT_FREE( size
->function_defs
);
751 FT_FREE( size
->instruction_defs
);
753 size
->num_function_defs
= 0;
754 size
->max_function_defs
= 0;
755 size
->num_instruction_defs
= 0;
756 size
->max_instruction_defs
= 0;
761 size
->bytecode_ready
= 0;
766 /* Initialize bytecode-related fields in the size object. */
767 /* We do this only if bytecode interpretation is really needed. */
769 tt_size_init_bytecode( FT_Size ftsize
)
772 TT_Size size
= (TT_Size
)ftsize
;
773 TT_Face face
= (TT_Face
)ftsize
->face
;
774 FT_Memory memory
= face
->root
.memory
;
777 FT_UShort n_twilight
;
778 TT_MaxProfile
* maxp
= &face
->max_profile
;
781 size
->bytecode_ready
= 1;
784 size
->max_function_defs
= maxp
->maxFunctionDefs
;
785 size
->max_instruction_defs
= maxp
->maxInstructionDefs
;
787 size
->num_function_defs
= 0;
788 size
->num_instruction_defs
= 0;
793 size
->cvt_size
= face
->cvt_size
;
794 size
->storage_size
= maxp
->maxStorage
;
796 /* Set default metrics */
798 TT_Size_Metrics
* metrics
= &size
->ttmetrics
;
801 metrics
->rotated
= FALSE
;
802 metrics
->stretched
= FALSE
;
804 /* set default compensation (all 0) */
805 for ( i
= 0; i
< 4; i
++ )
806 metrics
->compensations
[i
] = 0;
809 /* allocate function defs, instruction defs, cvt, and storage area */
810 if ( FT_NEW_ARRAY( size
->function_defs
, size
->max_function_defs
) ||
811 FT_NEW_ARRAY( size
->instruction_defs
, size
->max_instruction_defs
) ||
812 FT_NEW_ARRAY( size
->cvt
, size
->cvt_size
) ||
813 FT_NEW_ARRAY( size
->storage
, size
->storage_size
) )
816 /* reserve twilight zone */
817 n_twilight
= maxp
->maxTwilightPoints
;
819 /* there are 4 phantom points (do we need this?) */
822 error
= tt_glyphzone_new( memory
, n_twilight
, 0, &size
->twilight
);
826 size
->twilight
.n_points
= n_twilight
;
828 size
->GS
= tt_default_graphics_state
;
830 /* set `face->interpreter' according to the debug hook present */
832 FT_Library library
= face
->root
.driver
->root
.library
;
835 face
->interpreter
= (TT_Interpreter
)
836 library
->debug_hooks
[FT_DEBUG_HOOK_TRUETYPE
];
837 if ( !face
->interpreter
)
838 face
->interpreter
= (TT_Interpreter
)TT_RunIns
;
841 /* Fine, now run the font program! */
842 error
= tt_size_run_fpgm( size
);
846 tt_size_done_bytecode( ftsize
);
852 FT_LOCAL_DEF( FT_Error
)
853 tt_size_ready_bytecode( TT_Size size
)
855 FT_Error error
= TT_Err_Ok
;
858 if ( !size
->bytecode_ready
)
860 error
= tt_size_init_bytecode( (FT_Size
)size
);
865 /* rescale CVT when needed */
866 if ( !size
->cvt_ready
)
869 TT_Face face
= (TT_Face
)size
->root
.face
;
872 /* Scale the cvt values to the new ppem. */
873 /* We use by default the y ppem to scale the CVT. */
874 for ( i
= 0; i
< size
->cvt_size
; i
++ )
875 size
->cvt
[i
] = FT_MulFix( face
->cvt
[i
], size
->ttmetrics
.scale
);
877 /* all twilight points are originally zero */
878 for ( i
= 0; i
< (FT_UInt
)size
->twilight
.n_points
; i
++ )
880 size
->twilight
.org
[i
].x
= 0;
881 size
->twilight
.org
[i
].y
= 0;
882 size
->twilight
.cur
[i
].x
= 0;
883 size
->twilight
.cur
[i
].y
= 0;
886 /* clear storage area */
887 for ( i
= 0; i
< (FT_UInt
)size
->storage_size
; i
++ )
888 size
->storage
[i
] = 0;
890 size
->GS
= tt_default_graphics_state
;
892 error
= tt_size_run_prep( size
);
901 #endif /* TT_USE_BYTECODE_INTERPRETER */
904 /*************************************************************************/
910 /* Initialize a new TrueType size object. */
913 /* size :: A handle to the size object. */
916 /* FreeType error code. 0 means success. */
918 FT_LOCAL_DEF( FT_Error
)
919 tt_size_init( FT_Size ttsize
) /* TT_Size */
921 TT_Size size
= (TT_Size
)ttsize
;
922 FT_Error error
= TT_Err_Ok
;
924 #ifdef TT_USE_BYTECODE_INTERPRETER
925 size
->bytecode_ready
= 0;
929 size
->ttmetrics
.valid
= FALSE
;
930 size
->strike_index
= 0xFFFFFFFFUL
;
936 /*************************************************************************/
942 /* The TrueType size object finalizer. */
945 /* size :: A handle to the target size object. */
948 tt_size_done( FT_Size ttsize
) /* TT_Size */
950 TT_Size size
= (TT_Size
)ttsize
;
953 #ifdef TT_USE_BYTECODE_INTERPRETER
954 if ( size
->bytecode_ready
)
955 tt_size_done_bytecode( ttsize
);
958 size
->ttmetrics
.valid
= FALSE
;
962 /*************************************************************************/
968 /* Reset a TrueType size when resolutions and character dimensions */
969 /* have been changed. */
972 /* size :: A handle to the target size object. */
974 FT_LOCAL_DEF( FT_Error
)
975 tt_size_reset( TT_Size size
)
978 FT_Error error
= TT_Err_Ok
;
979 FT_Size_Metrics
* metrics
;
982 size
->ttmetrics
.valid
= FALSE
;
984 face
= (TT_Face
)size
->root
.face
;
986 metrics
= &size
->metrics
;
988 /* copy the result from base layer */
989 *metrics
= size
->root
.metrics
;
991 if ( metrics
->x_ppem
< 1 || metrics
->y_ppem
< 1 )
992 return TT_Err_Invalid_PPem
;
994 /* This bit flag, if set, indicates that the ppems must be */
995 /* rounded to integers. Nearly all TrueType fonts have this bit */
996 /* set, as hinting won't work really well otherwise. */
998 if ( face
->header
.Flags
& 8 )
1000 metrics
->x_scale
= FT_DivFix( metrics
->x_ppem
<< 6,
1001 face
->root
.units_per_EM
);
1002 metrics
->y_scale
= FT_DivFix( metrics
->y_ppem
<< 6,
1003 face
->root
.units_per_EM
);
1006 FT_PIX_ROUND( FT_MulFix( face
->root
.ascender
, metrics
->y_scale
) );
1007 metrics
->descender
=
1008 FT_PIX_ROUND( FT_MulFix( face
->root
.descender
, metrics
->y_scale
) );
1010 FT_PIX_ROUND( FT_MulFix( face
->root
.height
, metrics
->y_scale
) );
1011 metrics
->max_advance
=
1012 FT_PIX_ROUND( FT_MulFix( face
->root
.max_advance_width
,
1013 metrics
->x_scale
) );
1016 /* compute new transformation */
1017 if ( metrics
->x_ppem
>= metrics
->y_ppem
)
1019 size
->ttmetrics
.scale
= metrics
->x_scale
;
1020 size
->ttmetrics
.ppem
= metrics
->x_ppem
;
1021 size
->ttmetrics
.x_ratio
= 0x10000L
;
1022 size
->ttmetrics
.y_ratio
= FT_MulDiv( metrics
->y_ppem
,
1028 size
->ttmetrics
.scale
= metrics
->y_scale
;
1029 size
->ttmetrics
.ppem
= metrics
->y_ppem
;
1030 size
->ttmetrics
.x_ratio
= FT_MulDiv( metrics
->x_ppem
,
1033 size
->ttmetrics
.y_ratio
= 0x10000L
;
1036 #ifdef TT_USE_BYTECODE_INTERPRETER
1037 size
->cvt_ready
= 0;
1038 #endif /* TT_USE_BYTECODE_INTERPRETER */
1041 size
->ttmetrics
.valid
= TRUE
;
1047 /*************************************************************************/
1050 /* tt_driver_init */
1053 /* Initialize a given TrueType driver object. */
1056 /* driver :: A handle to the target driver object. */
1059 /* FreeType error code. 0 means success. */
1061 FT_LOCAL_DEF( FT_Error
)
1062 tt_driver_init( FT_Module ttdriver
) /* TT_Driver */
1065 #ifdef TT_USE_BYTECODE_INTERPRETER
1067 TT_Driver driver
= (TT_Driver
)ttdriver
;
1070 if ( !TT_New_Context( driver
) )
1071 return TT_Err_Could_Not_Find_Context
;
1075 FT_UNUSED( ttdriver
);
1083 /*************************************************************************/
1086 /* tt_driver_done */
1089 /* Finalize a given TrueType driver. */
1092 /* driver :: A handle to the target TrueType driver. */
1094 FT_LOCAL_DEF( void )
1095 tt_driver_done( FT_Module ttdriver
) /* TT_Driver */
1097 #ifdef TT_USE_BYTECODE_INTERPRETER
1098 TT_Driver driver
= (TT_Driver
)ttdriver
;
1101 /* destroy the execution context */
1102 if ( driver
->context
)
1104 TT_Done_Context( driver
->context
);
1105 driver
->context
= NULL
;
1108 FT_UNUSED( ttdriver
);
1114 /*************************************************************************/
1120 /* Initialize a new slot object. */
1123 /* slot :: A handle to the slot object. */
1126 /* FreeType error code. 0 means success. */
1128 FT_LOCAL_DEF( FT_Error
)
1129 tt_slot_init( FT_GlyphSlot slot
)
1131 return FT_GlyphLoader_CreateExtra( slot
->internal
->loader
);