1 /***************************************************************************/
5 /* Objects manager (body). */
7 /* Copyright 1996-2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009 by */
8 /* David Turner, Robert Wilhelm, and Werner Lemberg. */
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. */
16 /***************************************************************************/
20 #include FT_INTERNAL_DEBUG_H
21 #include FT_INTERNAL_STREAM_H
22 #include FT_TRUETYPE_TAGS_H
23 #include FT_INTERNAL_SFNT_H
30 #ifdef TT_USE_BYTECODE_INTERPRETER
34 #ifdef TT_CONFIG_OPTION_UNPATENTED_HINTING
35 #include FT_TRUETYPE_UNPATENTED_H
38 #ifdef TT_CONFIG_OPTION_GX_VAR_SUPPORT
42 /*************************************************************************/
44 /* The macro FT_COMPONENT is used in trace mode. It is an implicit */
45 /* parameter of the FT_TRACE() and FT_ERROR() macros, used to print/log */
46 /* messages during execution. */
49 #define FT_COMPONENT trace_ttobjs
52 #ifdef TT_USE_BYTECODE_INTERPRETER
54 /*************************************************************************/
56 /* GLYPH ZONE FUNCTIONS */
58 /*************************************************************************/
61 /*************************************************************************/
64 /* tt_glyphzone_done */
67 /* Deallocate a glyph zone. */
70 /* zone :: A pointer to the target glyph zone. */
73 tt_glyphzone_done( TT_GlyphZone zone
)
75 FT_Memory memory
= zone
->memory
;
80 FT_FREE( zone
->contours
);
81 FT_FREE( zone
->tags
);
84 FT_FREE( zone
->orus
);
86 zone
->max_points
= zone
->n_points
= 0;
87 zone
->max_contours
= zone
->n_contours
= 0;
93 /*************************************************************************/
96 /* tt_glyphzone_new */
99 /* Allocate a new glyph zone. */
102 /* memory :: A handle to the current memory object. */
104 /* maxPoints :: The capacity of glyph zone in points. */
106 /* maxContours :: The capacity of glyph zone in contours. */
109 /* zone :: A pointer to the target glyph zone record. */
112 /* FreeType error code. 0 means success. */
114 FT_LOCAL_DEF( FT_Error
)
115 tt_glyphzone_new( FT_Memory memory
,
117 FT_Short maxContours
,
123 FT_MEM_ZERO( zone
, sizeof ( *zone
) );
124 zone
->memory
= memory
;
126 if ( FT_NEW_ARRAY( zone
->org
, maxPoints
) ||
127 FT_NEW_ARRAY( zone
->cur
, maxPoints
) ||
128 FT_NEW_ARRAY( zone
->orus
, maxPoints
) ||
129 FT_NEW_ARRAY( zone
->tags
, maxPoints
) ||
130 FT_NEW_ARRAY( zone
->contours
, maxContours
) )
132 tt_glyphzone_done( zone
);
136 zone
->max_points
= maxPoints
;
137 zone
->max_contours
= maxContours
;
142 #endif /* TT_USE_BYTECODE_INTERPRETER */
145 /* Compare the face with a list of well-known `tricky' fonts. */
146 /* This list shall be expanded as we find more of them. */
149 tt_check_trickyness( FT_String
* name
)
151 #define TRICK_NAMES_MAX_CHARACTERS 16
152 #define TRICK_NAMES_COUNT 7
153 static const char trick_names
[TRICK_NAMES_COUNT
][TRICK_NAMES_MAX_CHARACTERS
+1] =
155 "DFKaiSho-SB", /* dfkaisb.ttf */
157 "DFKai-SB", /* kaiu.ttf */
158 "HuaTianSongTi?", /* htst3.ttf */
159 "MingLiU", /* mingliu.ttf & mingliu.ttc */
160 "PMingLiU", /* mingliu.ttc */
161 "MingLi43", /* mingli.ttf */
169 /* Note that we only check the face name at the moment; it might */
170 /* be worth to do more checks for a few special cases. */
171 for ( nn
= 0; nn
< TRICK_NAMES_COUNT
; nn
++ )
172 if ( ft_strstr( name
, trick_names
[nn
] ) )
179 /*************************************************************************/
185 /* Initialize a given TrueType face object. */
188 /* stream :: The source font stream. */
190 /* face_index :: The index of the font face in the resource. */
192 /* num_params :: Number of additional generic parameters. Ignored. */
194 /* params :: Additional generic parameters. Ignored. */
197 /* face :: The newly built face object. */
200 /* FreeType error code. 0 means success. */
202 FT_LOCAL_DEF( FT_Error
)
203 tt_face_init( FT_Stream stream
,
204 FT_Face ttface
, /* TT_Face */
207 FT_Parameter
* params
)
212 TT_Face face
= (TT_Face
)ttface
;
215 library
= ttface
->driver
->root
.library
;
216 sfnt
= (SFNT_Service
)FT_Get_Module_Interface( library
, "sfnt" );
220 /* create input stream from resource */
221 if ( FT_STREAM_SEEK( 0 ) )
224 /* check that we have a valid TrueType file */
225 error
= sfnt
->init_face( stream
, face
, face_index
, num_params
, params
);
229 /* We must also be able to accept Mac/GX fonts, as well as OT ones. */
230 /* The 0x00020000 tag is completely undocumented; some fonts from */
231 /* Arphic made for Chinese Windows 3.1 have this. */
232 if ( face
->format_tag
!= 0x00010000L
&& /* MS fonts */
233 face
->format_tag
!= 0x00020000L
&& /* CJK fonts for Win 3.1 */
234 face
->format_tag
!= TTAG_true
) /* Mac fonts */
236 FT_TRACE2(( "[not a valid TTF font]\n" ));
240 #ifdef TT_USE_BYTECODE_INTERPRETER
241 ttface
->face_flags
|= FT_FACE_FLAG_HINTER
;
244 /* If we are performing a simple font format check, exit immediately. */
245 if ( face_index
< 0 )
248 /* Load font directory */
249 error
= sfnt
->load_face( stream
, face
, face_index
, num_params
, params
);
253 if ( tt_check_trickyness( ttface
->family_name
) )
254 ttface
->face_flags
|= FT_FACE_FLAG_TRICKY
;
256 error
= tt_face_load_hdmx( face
, stream
);
260 if ( FT_IS_SCALABLE( ttface
) )
263 #ifdef FT_CONFIG_OPTION_INCREMENTAL
265 if ( !ttface
->internal
->incremental_interface
)
266 error
= tt_face_load_loca( face
, stream
);
268 error
= tt_face_load_cvt( face
, stream
);
270 error
= tt_face_load_fpgm( face
, stream
);
272 error
= tt_face_load_prep( face
, stream
);
277 error
= tt_face_load_loca( face
, stream
);
279 error
= tt_face_load_cvt( face
, stream
);
281 error
= tt_face_load_fpgm( face
, stream
);
283 error
= tt_face_load_prep( face
, stream
);
289 #if defined( TT_CONFIG_OPTION_UNPATENTED_HINTING ) && \
290 !defined( TT_CONFIG_OPTION_BYTECODE_INTERPRETER )
293 FT_Bool unpatented_hinting
;
297 /* Determine whether unpatented hinting is to be used for this face. */
298 unpatented_hinting
= FT_BOOL
299 ( library
->debug_hooks
[FT_DEBUG_HOOK_UNPATENTED_HINTING
] != NULL
);
301 for ( i
= 0; i
< num_params
&& !face
->unpatented_hinting
; i
++ )
302 if ( params
[i
].tag
== FT_PARAM_TAG_UNPATENTED_HINTING
)
303 unpatented_hinting
= TRUE
;
305 if ( !unpatented_hinting
)
306 ttface
->internal
->ignore_unpatented_hinter
= TRUE
;
309 #endif /* TT_CONFIG_OPTION_UNPATENTED_HINTING &&
310 !TT_CONFIG_OPTION_BYTECODE_INTERPRETER */
312 /* initialize standard glyph loading routines */
313 TT_Init_Glyph_Loading( face
);
319 error
= TT_Err_Unknown_File_Format
;
324 /*************************************************************************/
330 /* Finalize a given face object. */
333 /* face :: A pointer to the face object to destroy. */
336 tt_face_done( FT_Face ttface
) /* TT_Face */
338 TT_Face face
= (TT_Face
)ttface
;
347 memory
= ttface
->memory
;
348 stream
= ttface
->stream
;
349 sfnt
= (SFNT_Service
)face
->sfnt
;
351 /* for `extended TrueType formats' (i.e. compressed versions) */
352 if ( face
->extra
.finalizer
)
353 face
->extra
.finalizer( face
->extra
.data
);
356 sfnt
->done_face( face
);
358 /* freeing the locations table */
359 tt_face_done_loca( face
);
361 tt_face_free_hdmx( face
);
363 /* freeing the CVT */
364 FT_FREE( face
->cvt
);
367 /* freeing the programs */
368 FT_FRAME_RELEASE( face
->font_program
);
369 FT_FRAME_RELEASE( face
->cvt_program
);
370 face
->font_program_size
= 0;
371 face
->cvt_program_size
= 0;
373 #ifdef TT_CONFIG_OPTION_GX_VAR_SUPPORT
374 tt_done_blend( memory
, face
->blend
);
380 /*************************************************************************/
384 /*************************************************************************/
386 #ifdef TT_USE_BYTECODE_INTERPRETER
388 /*************************************************************************/
391 /* tt_size_run_fpgm */
394 /* Run the font program. */
397 /* size :: A handle to the size object. */
400 /* FreeType error code. 0 means success. */
402 FT_LOCAL_DEF( FT_Error
)
403 tt_size_run_fpgm( TT_Size size
)
405 TT_Face face
= (TT_Face
)size
->root
.face
;
410 /* debugging instances have their own context */
412 exec
= size
->context
;
414 exec
= ( (TT_Driver
)FT_FACE_DRIVER( face
) )->context
;
417 return TT_Err_Could_Not_Find_Context
;
419 TT_Load_Context( exec
, face
, size
);
428 exec
->instruction_trap
= FALSE
;
429 exec
->F_dot_P
= 0x10000L
;
432 FT_Size_Metrics
* metrics
= &exec
->metrics
;
433 TT_Size_Metrics
* tt_metrics
= &exec
->tt_metrics
;
438 metrics
->x_scale
= 0;
439 metrics
->y_scale
= 0;
441 tt_metrics
->ppem
= 0;
442 tt_metrics
->scale
= 0;
443 tt_metrics
->ratio
= 0x10000L
;
446 /* allow font program execution */
447 TT_Set_CodeRange( exec
,
450 face
->font_program_size
);
452 /* disable CVT and glyph programs coderange */
453 TT_Clear_CodeRange( exec
, tt_coderange_cvt
);
454 TT_Clear_CodeRange( exec
, tt_coderange_glyph
);
456 if ( face
->font_program_size
> 0 )
458 error
= TT_Goto_CodeRange( exec
, tt_coderange_font
, 0 );
461 error
= face
->interpreter( exec
);
467 TT_Save_Context( exec
, size
);
473 /*************************************************************************/
476 /* tt_size_run_prep */
479 /* Run the control value program. */
482 /* size :: A handle to the size object. */
485 /* FreeType error code. 0 means success. */
487 FT_LOCAL_DEF( FT_Error
)
488 tt_size_run_prep( TT_Size size
)
490 TT_Face face
= (TT_Face
)size
->root
.face
;
495 /* debugging instances have their own context */
497 exec
= size
->context
;
499 exec
= ( (TT_Driver
)FT_FACE_DRIVER( face
) )->context
;
502 return TT_Err_Could_Not_Find_Context
;
504 TT_Load_Context( exec
, face
, size
);
509 exec
->instruction_trap
= FALSE
;
511 TT_Set_CodeRange( exec
,
514 face
->cvt_program_size
);
516 TT_Clear_CodeRange( exec
, tt_coderange_glyph
);
518 if ( face
->cvt_program_size
> 0 )
520 error
= TT_Goto_CodeRange( exec
, tt_coderange_cvt
, 0 );
522 if ( !error
&& !size
->debug
)
523 error
= face
->interpreter( exec
);
528 /* save as default graphics state */
531 TT_Save_Context( exec
, size
);
536 #endif /* TT_USE_BYTECODE_INTERPRETER */
539 #ifdef TT_USE_BYTECODE_INTERPRETER
542 tt_size_done_bytecode( FT_Size ftsize
)
544 TT_Size size
= (TT_Size
)ftsize
;
545 TT_Face face
= (TT_Face
)ftsize
->face
;
546 FT_Memory memory
= face
->root
.memory
;
551 /* the debug context must be deleted by the debugger itself */
552 size
->context
= NULL
;
556 FT_FREE( size
->cvt
);
559 /* free storage area */
560 FT_FREE( size
->storage
);
561 size
->storage_size
= 0;
564 tt_glyphzone_done( &size
->twilight
);
566 FT_FREE( size
->function_defs
);
567 FT_FREE( size
->instruction_defs
);
569 size
->num_function_defs
= 0;
570 size
->max_function_defs
= 0;
571 size
->num_instruction_defs
= 0;
572 size
->max_instruction_defs
= 0;
577 size
->bytecode_ready
= 0;
582 /* Initialize bytecode-related fields in the size object. */
583 /* We do this only if bytecode interpretation is really needed. */
585 tt_size_init_bytecode( FT_Size ftsize
)
588 TT_Size size
= (TT_Size
)ftsize
;
589 TT_Face face
= (TT_Face
)ftsize
->face
;
590 FT_Memory memory
= face
->root
.memory
;
593 FT_UShort n_twilight
;
594 TT_MaxProfile
* maxp
= &face
->max_profile
;
597 size
->bytecode_ready
= 1;
600 size
->max_function_defs
= maxp
->maxFunctionDefs
;
601 size
->max_instruction_defs
= maxp
->maxInstructionDefs
;
603 size
->num_function_defs
= 0;
604 size
->num_instruction_defs
= 0;
609 size
->cvt_size
= face
->cvt_size
;
610 size
->storage_size
= maxp
->maxStorage
;
612 /* Set default metrics */
614 TT_Size_Metrics
* metrics
= &size
->ttmetrics
;
617 metrics
->rotated
= FALSE
;
618 metrics
->stretched
= FALSE
;
620 /* set default compensation (all 0) */
621 for ( i
= 0; i
< 4; i
++ )
622 metrics
->compensations
[i
] = 0;
625 /* allocate function defs, instruction defs, cvt, and storage area */
626 if ( FT_NEW_ARRAY( size
->function_defs
, size
->max_function_defs
) ||
627 FT_NEW_ARRAY( size
->instruction_defs
, size
->max_instruction_defs
) ||
628 FT_NEW_ARRAY( size
->cvt
, size
->cvt_size
) ||
629 FT_NEW_ARRAY( size
->storage
, size
->storage_size
) )
632 /* reserve twilight zone */
633 n_twilight
= maxp
->maxTwilightPoints
;
635 /* there are 4 phantom points (do we need this?) */
638 error
= tt_glyphzone_new( memory
, n_twilight
, 0, &size
->twilight
);
642 size
->twilight
.n_points
= n_twilight
;
644 size
->GS
= tt_default_graphics_state
;
646 /* set `face->interpreter' according to the debug hook present */
648 FT_Library library
= face
->root
.driver
->root
.library
;
651 face
->interpreter
= (TT_Interpreter
)
652 library
->debug_hooks
[FT_DEBUG_HOOK_TRUETYPE
];
653 if ( !face
->interpreter
)
654 face
->interpreter
= (TT_Interpreter
)TT_RunIns
;
657 /* Fine, now run the font program! */
658 error
= tt_size_run_fpgm( size
);
662 tt_size_done_bytecode( ftsize
);
668 FT_LOCAL_DEF( FT_Error
)
669 tt_size_ready_bytecode( TT_Size size
)
671 FT_Error error
= TT_Err_Ok
;
674 if ( !size
->bytecode_ready
)
676 error
= tt_size_init_bytecode( (FT_Size
)size
);
681 /* rescale CVT when needed */
682 if ( !size
->cvt_ready
)
685 TT_Face face
= (TT_Face
)size
->root
.face
;
688 /* Scale the cvt values to the new ppem. */
689 /* We use by default the y ppem to scale the CVT. */
690 for ( i
= 0; i
< size
->cvt_size
; i
++ )
691 size
->cvt
[i
] = FT_MulFix( face
->cvt
[i
], size
->ttmetrics
.scale
);
693 /* all twilight points are originally zero */
694 for ( i
= 0; i
< (FT_UInt
)size
->twilight
.n_points
; i
++ )
696 size
->twilight
.org
[i
].x
= 0;
697 size
->twilight
.org
[i
].y
= 0;
698 size
->twilight
.cur
[i
].x
= 0;
699 size
->twilight
.cur
[i
].y
= 0;
702 /* clear storage area */
703 for ( i
= 0; i
< (FT_UInt
)size
->storage_size
; i
++ )
704 size
->storage
[i
] = 0;
706 size
->GS
= tt_default_graphics_state
;
708 error
= tt_size_run_prep( size
);
717 #endif /* TT_USE_BYTECODE_INTERPRETER */
720 /*************************************************************************/
726 /* Initialize a new TrueType size object. */
729 /* size :: A handle to the size object. */
732 /* FreeType error code. 0 means success. */
734 FT_LOCAL_DEF( FT_Error
)
735 tt_size_init( FT_Size ttsize
) /* TT_Size */
737 TT_Size size
= (TT_Size
)ttsize
;
738 FT_Error error
= TT_Err_Ok
;
740 #ifdef TT_USE_BYTECODE_INTERPRETER
741 size
->bytecode_ready
= 0;
745 size
->ttmetrics
.valid
= FALSE
;
746 size
->strike_index
= 0xFFFFFFFFUL
;
752 /*************************************************************************/
758 /* The TrueType size object finalizer. */
761 /* size :: A handle to the target size object. */
764 tt_size_done( FT_Size ttsize
) /* TT_Size */
766 TT_Size size
= (TT_Size
)ttsize
;
769 #ifdef TT_USE_BYTECODE_INTERPRETER
770 if ( size
->bytecode_ready
)
771 tt_size_done_bytecode( ttsize
);
774 size
->ttmetrics
.valid
= FALSE
;
778 /*************************************************************************/
784 /* Reset a TrueType size when resolutions and character dimensions */
785 /* have been changed. */
788 /* size :: A handle to the target size object. */
790 FT_LOCAL_DEF( FT_Error
)
791 tt_size_reset( TT_Size size
)
794 FT_Error error
= TT_Err_Ok
;
795 FT_Size_Metrics
* metrics
;
798 size
->ttmetrics
.valid
= FALSE
;
800 face
= (TT_Face
)size
->root
.face
;
802 metrics
= &size
->metrics
;
804 /* copy the result from base layer */
805 *metrics
= size
->root
.metrics
;
807 if ( metrics
->x_ppem
< 1 || metrics
->y_ppem
< 1 )
808 return TT_Err_Invalid_PPem
;
810 /* This bit flag, if set, indicates that the ppems must be */
811 /* rounded to integers. Nearly all TrueType fonts have this bit */
812 /* set, as hinting won't work really well otherwise. */
814 if ( face
->header
.Flags
& 8 )
816 metrics
->x_scale
= FT_DivFix( metrics
->x_ppem
<< 6,
817 face
->root
.units_per_EM
);
818 metrics
->y_scale
= FT_DivFix( metrics
->y_ppem
<< 6,
819 face
->root
.units_per_EM
);
822 FT_PIX_ROUND( FT_MulFix( face
->root
.ascender
, metrics
->y_scale
) );
824 FT_PIX_ROUND( FT_MulFix( face
->root
.descender
, metrics
->y_scale
) );
826 FT_PIX_ROUND( FT_MulFix( face
->root
.height
, metrics
->y_scale
) );
827 metrics
->max_advance
=
828 FT_PIX_ROUND( FT_MulFix( face
->root
.max_advance_width
,
829 metrics
->x_scale
) );
832 /* compute new transformation */
833 if ( metrics
->x_ppem
>= metrics
->y_ppem
)
835 size
->ttmetrics
.scale
= metrics
->x_scale
;
836 size
->ttmetrics
.ppem
= metrics
->x_ppem
;
837 size
->ttmetrics
.x_ratio
= 0x10000L
;
838 size
->ttmetrics
.y_ratio
= FT_MulDiv( metrics
->y_ppem
,
844 size
->ttmetrics
.scale
= metrics
->y_scale
;
845 size
->ttmetrics
.ppem
= metrics
->y_ppem
;
846 size
->ttmetrics
.x_ratio
= FT_MulDiv( metrics
->x_ppem
,
849 size
->ttmetrics
.y_ratio
= 0x10000L
;
852 #ifdef TT_USE_BYTECODE_INTERPRETER
854 #endif /* TT_USE_BYTECODE_INTERPRETER */
857 size
->ttmetrics
.valid
= TRUE
;
863 /*************************************************************************/
869 /* Initialize a given TrueType driver object. */
872 /* driver :: A handle to the target driver object. */
875 /* FreeType error code. 0 means success. */
877 FT_LOCAL_DEF( FT_Error
)
878 tt_driver_init( FT_Module ttdriver
) /* TT_Driver */
881 #ifdef TT_USE_BYTECODE_INTERPRETER
883 TT_Driver driver
= (TT_Driver
)ttdriver
;
886 if ( !TT_New_Context( driver
) )
887 return TT_Err_Could_Not_Find_Context
;
891 FT_UNUSED( ttdriver
);
899 /*************************************************************************/
905 /* Finalize a given TrueType driver. */
908 /* driver :: A handle to the target TrueType driver. */
911 tt_driver_done( FT_Module ttdriver
) /* TT_Driver */
913 #ifdef TT_USE_BYTECODE_INTERPRETER
914 TT_Driver driver
= (TT_Driver
)ttdriver
;
917 /* destroy the execution context */
918 if ( driver
->context
)
920 TT_Done_Context( driver
->context
);
921 driver
->context
= NULL
;
924 FT_UNUSED( ttdriver
);
930 /*************************************************************************/
936 /* Initialize a new slot object. */
939 /* slot :: A handle to the slot object. */
942 /* FreeType error code. 0 means success. */
944 FT_LOCAL_DEF( FT_Error
)
945 tt_slot_init( FT_GlyphSlot slot
)
947 return FT_GlyphLoader_CreateExtra( slot
->internal
->loader
);