1 /***************************************************************************/
5 /* Objects manager (body). */
7 /* Copyright 1996-2001, 2002, 2003, 2004, 2005, 2006, 2007 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_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
32 #ifdef TT_USE_BYTECODE_INTERPRETER
36 #ifdef TT_CONFIG_OPTION_UNPATENTED_HINTING
37 #include FT_TRUETYPE_UNPATENTED_H
40 #ifdef TT_CONFIG_OPTION_GX_VAR_SUPPORT
44 /*************************************************************************/
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. */
51 #define FT_COMPONENT trace_ttobjs
54 #ifdef TT_USE_BYTECODE_INTERPRETER
56 /*************************************************************************/
58 /* GLYPH ZONE FUNCTIONS */
60 /*************************************************************************/
63 /*************************************************************************/
66 /* tt_glyphzone_done */
69 /* Deallocate a glyph zone. */
72 /* zone :: A pointer to the target glyph zone. */
75 tt_glyphzone_done( TT_GlyphZone zone
)
77 FT_Memory memory
= zone
->memory
;
82 FT_FREE( zone
->contours
);
83 FT_FREE( zone
->tags
);
86 FT_FREE( zone
->orus
);
88 zone
->max_points
= zone
->n_points
= 0;
89 zone
->max_contours
= zone
->n_contours
= 0;
95 /*************************************************************************/
98 /* tt_glyphzone_new */
101 /* Allocate a new glyph zone. */
104 /* memory :: A handle to the current memory object. */
106 /* maxPoints :: The capacity of glyph zone in points. */
108 /* maxContours :: The capacity of glyph zone in contours. */
111 /* zone :: A pointer to the target glyph zone record. */
114 /* FreeType error code. 0 means success. */
116 FT_LOCAL_DEF( FT_Error
)
117 tt_glyphzone_new( FT_Memory memory
,
119 FT_Short maxContours
,
125 FT_MEM_ZERO( zone
, sizeof ( *zone
) );
126 zone
->memory
= memory
;
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
) )
134 tt_glyphzone_done( zone
);
138 zone
->max_points
= maxPoints
;
139 zone
->max_contours
= maxContours
;
144 #endif /* TT_USE_BYTECODE_INTERPRETER */
147 /*************************************************************************/
153 /* Initialize a given TrueType face object. */
156 /* stream :: The source font stream. */
158 /* face_index :: The index of the font face in the resource. */
160 /* num_params :: Number of additional generic parameters. Ignored. */
162 /* params :: Additional generic parameters. Ignored. */
165 /* face :: The newly built face object. */
168 /* FreeType error code. 0 means success. */
170 FT_LOCAL_DEF( FT_Error
)
171 tt_face_init( FT_Stream stream
,
172 FT_Face ttface
, /* TT_Face */
175 FT_Parameter
* params
)
180 TT_Face face
= (TT_Face
)ttface
;
183 library
= face
->root
.driver
->root
.library
;
184 sfnt
= (SFNT_Service
)FT_Get_Module_Interface( library
, "sfnt" );
188 /* create input stream from resource */
189 if ( FT_STREAM_SEEK( 0 ) )
192 /* check that we have a valid TrueType file */
193 error
= sfnt
->init_face( stream
, face
, face_index
, num_params
, params
);
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 */
204 FT_TRACE2(( "[not a valid TTF font]\n" ));
208 #ifdef TT_USE_BYTECODE_INTERPRETER
209 face
->root
.face_flags
|= FT_FACE_FLAG_HINTER
;
212 /* If we are performing a simple font format check, exit immediately. */
213 if ( face_index
< 0 )
216 /* Load font directory */
217 error
= sfnt
->load_face( stream
, face
, face_index
, num_params
, params
);
221 error
= tt_face_load_hdmx( face
, stream
);
225 if ( face
->root
.face_flags
& FT_FACE_FLAG_SCALABLE
)
228 #ifdef FT_CONFIG_OPTION_INCREMENTAL
230 if ( !face
->root
.internal
->incremental_interface
)
231 error
= tt_face_load_loca( face
, stream
);
233 error
= tt_face_load_cvt( face
, stream
) ||
234 tt_face_load_fpgm( face
, stream
) ||
235 tt_face_load_prep( face
, stream
);
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
);
249 #if defined( TT_CONFIG_OPTION_UNPATENTED_HINTING ) && \
250 !defined( TT_CONFIG_OPTION_BYTECODE_INTERPRETER )
253 FT_Bool unpatented_hinting
;
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
);
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
;
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
)
269 static const char* const trick_names
[] =
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 */
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
++ )
286 if ( ttface
->family_name
&&
287 ft_strcmp( ttface
->family_name
, trick_names
[nn
] ) == 0 )
289 unpatented_hinting
= 1;
295 ttface
->internal
->ignore_unpatented_hinter
=
296 FT_BOOL( !unpatented_hinting
);
299 #endif /* TT_CONFIG_OPTION_UNPATENTED_HINTING &&
300 !TT_CONFIG_OPTION_BYTECODE_INTERPRETER */
302 /* initialize standard glyph loading routines */
303 TT_Init_Glyph_Loading( face
);
309 error
= TT_Err_Unknown_File_Format
;
314 /*************************************************************************/
320 /* Finalize a given face object. */
323 /* face :: A pointer to the face object to destroy. */
326 tt_face_done( FT_Face ttface
) /* TT_Face */
328 TT_Face face
= (TT_Face
)ttface
;
329 FT_Memory memory
= face
->root
.memory
;
330 FT_Stream stream
= face
->root
.stream
;
332 SFNT_Service sfnt
= (SFNT_Service
)face
->sfnt
;
335 /* for `extended TrueType formats' (i.e. compressed versions) */
336 if ( face
->extra
.finalizer
)
337 face
->extra
.finalizer( face
->extra
.data
);
340 sfnt
->done_face( face
);
342 /* freeing the locations table */
343 tt_face_done_loca( face
);
345 tt_face_free_hdmx( face
);
347 /* freeing the CVT */
348 FT_FREE( face
->cvt
);
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;
357 #ifdef TT_CONFIG_OPTION_GX_VAR_SUPPORT
358 tt_done_blend( memory
, face
->blend
);
364 /*************************************************************************/
368 /*************************************************************************/
370 #ifdef TT_USE_BYTECODE_INTERPRETER
372 /*************************************************************************/
375 /* tt_size_run_fpgm */
378 /* Run the font program. */
381 /* size :: A handle to the size object. */
384 /* FreeType error code. 0 means success. */
386 FT_LOCAL_DEF( FT_Error
)
387 tt_size_run_fpgm( TT_Size size
)
389 TT_Face face
= (TT_Face
)size
->root
.face
;
394 /* debugging instances have their own context */
396 exec
= size
->context
;
398 exec
= ( (TT_Driver
)FT_FACE_DRIVER( face
) )->context
;
401 return TT_Err_Could_Not_Find_Context
;
403 TT_Load_Context( exec
, face
, size
);
412 exec
->instruction_trap
= FALSE
;
413 exec
->F_dot_P
= 0x10000L
;
416 FT_Size_Metrics
* metrics
= &exec
->metrics
;
417 TT_Size_Metrics
* tt_metrics
= &exec
->tt_metrics
;
422 metrics
->x_scale
= 0;
423 metrics
->y_scale
= 0;
425 tt_metrics
->ppem
= 0;
426 tt_metrics
->scale
= 0;
427 tt_metrics
->ratio
= 0x10000L
;
430 /* allow font program execution */
431 TT_Set_CodeRange( exec
,
434 face
->font_program_size
);
436 /* disable CVT and glyph programs coderange */
437 TT_Clear_CodeRange( exec
, tt_coderange_cvt
);
438 TT_Clear_CodeRange( exec
, tt_coderange_glyph
);
440 if ( face
->font_program_size
> 0 )
442 error
= TT_Goto_CodeRange( exec
, tt_coderange_font
, 0 );
445 error
= face
->interpreter( exec
);
451 TT_Save_Context( exec
, size
);
457 /*************************************************************************/
460 /* tt_size_run_prep */
463 /* Run the control value program. */
466 /* size :: A handle to the size object. */
469 /* FreeType error code. 0 means success. */
471 FT_LOCAL_DEF( FT_Error
)
472 tt_size_run_prep( TT_Size size
)
474 TT_Face face
= (TT_Face
)size
->root
.face
;
479 /* debugging instances have their own context */
481 exec
= size
->context
;
483 exec
= ( (TT_Driver
)FT_FACE_DRIVER( face
) )->context
;
486 return TT_Err_Could_Not_Find_Context
;
488 TT_Load_Context( exec
, face
, size
);
493 exec
->instruction_trap
= FALSE
;
495 TT_Set_CodeRange( exec
,
498 face
->cvt_program_size
);
500 TT_Clear_CodeRange( exec
, tt_coderange_glyph
);
502 if ( face
->cvt_program_size
> 0 )
504 error
= TT_Goto_CodeRange( exec
, tt_coderange_cvt
, 0 );
506 if ( !error
&& !size
->debug
)
507 error
= face
->interpreter( exec
);
512 /* save as default graphics state */
515 TT_Save_Context( exec
, size
);
520 #endif /* TT_USE_BYTECODE_INTERPRETER */
523 #ifdef TT_USE_BYTECODE_INTERPRETER
526 tt_size_done_bytecode( FT_Size ftsize
)
528 TT_Size size
= (TT_Size
)ftsize
;
529 TT_Face face
= (TT_Face
)ftsize
->face
;
530 FT_Memory memory
= face
->root
.memory
;
535 /* the debug context must be deleted by the debugger itself */
536 size
->context
= NULL
;
540 FT_FREE( size
->cvt
);
543 /* free storage area */
544 FT_FREE( size
->storage
);
545 size
->storage_size
= 0;
548 tt_glyphzone_done( &size
->twilight
);
550 FT_FREE( size
->function_defs
);
551 FT_FREE( size
->instruction_defs
);
553 size
->num_function_defs
= 0;
554 size
->max_function_defs
= 0;
555 size
->num_instruction_defs
= 0;
556 size
->max_instruction_defs
= 0;
561 size
->bytecode_ready
= 0;
566 /* Initialize bytecode-related fields in the size object. */
567 /* We do this only if bytecode interpretation is really needed. */
569 tt_size_init_bytecode( FT_Size ftsize
)
572 TT_Size size
= (TT_Size
)ftsize
;
573 TT_Face face
= (TT_Face
)ftsize
->face
;
574 FT_Memory memory
= face
->root
.memory
;
577 FT_UShort n_twilight
;
578 TT_MaxProfile
* maxp
= &face
->max_profile
;
581 size
->bytecode_ready
= 1;
584 size
->max_function_defs
= maxp
->maxFunctionDefs
;
585 size
->max_instruction_defs
= maxp
->maxInstructionDefs
;
587 size
->num_function_defs
= 0;
588 size
->num_instruction_defs
= 0;
593 size
->cvt_size
= face
->cvt_size
;
594 size
->storage_size
= maxp
->maxStorage
;
596 /* Set default metrics */
598 FT_Size_Metrics
* metrics
= &size
->root
.metrics
;
599 TT_Size_Metrics
* metrics2
= &size
->ttmetrics
;
605 metrics2
->rotated
= FALSE
;
606 metrics2
->stretched
= FALSE
;
608 /* set default compensation (all 0) */
609 for ( i
= 0; i
< 4; i
++ )
610 metrics2
->compensations
[i
] = 0;
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
) )
620 /* reserve twilight zone */
621 n_twilight
= maxp
->maxTwilightPoints
;
623 /* there are 4 phantom points (do we need this?) */
626 error
= tt_glyphzone_new( memory
, n_twilight
, 0, &size
->twilight
);
630 size
->twilight
.n_points
= n_twilight
;
632 size
->GS
= tt_default_graphics_state
;
634 /* set `face->interpreter' according to the debug hook present */
636 FT_Library library
= face
->root
.driver
->root
.library
;
639 face
->interpreter
= (TT_Interpreter
)
640 library
->debug_hooks
[FT_DEBUG_HOOK_TRUETYPE
];
641 if ( !face
->interpreter
)
642 face
->interpreter
= (TT_Interpreter
)TT_RunIns
;
645 /* Fine, now run the font program! */
646 error
= tt_size_run_fpgm( size
);
650 tt_size_done_bytecode( ftsize
);
656 FT_LOCAL_DEF( FT_Error
)
657 tt_size_ready_bytecode( TT_Size size
)
659 FT_Error error
= TT_Err_Ok
;
662 if ( !size
->bytecode_ready
)
664 error
= tt_size_init_bytecode( (FT_Size
)size
);
669 /* rescale CVT when needed */
670 if ( !size
->cvt_ready
)
673 TT_Face face
= (TT_Face
) size
->root
.face
;
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
);
681 /* all twilight points are originally zero */
682 for ( i
= 0; i
< (FT_UInt
)size
->twilight
.n_points
; i
++ )
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;
690 /* clear storage area */
691 for ( i
= 0; i
< (FT_UInt
)size
->storage_size
; i
++ )
692 size
->storage
[i
] = 0;
694 size
->GS
= tt_default_graphics_state
;
696 error
= tt_size_run_prep( size
);
702 #else /* !TT_USE_BYTECODE_INTERPRETER */
704 FT_LOCAL_DEF( FT_Error
)
705 tt_size_ready_bytecode( TT_Size size
)
711 #endif /* !TT_USE_BYTECODE_INTERPRETER */
714 /*************************************************************************/
720 /* Initialize a new TrueType size object. */
723 /* size :: A handle to the size object. */
726 /* FreeType error code. 0 means success. */
728 FT_LOCAL_DEF( FT_Error
)
729 tt_size_init( FT_Size ttsize
) /* TT_Size */
731 TT_Size size
= (TT_Size
)ttsize
;
732 FT_Error error
= TT_Err_Ok
;
734 #ifdef TT_USE_BYTECODE_INTERPRETER
735 size
->bytecode_ready
= 0;
739 size
->ttmetrics
.valid
= FALSE
;
740 size
->strike_index
= 0xFFFFFFFFUL
;
746 /*************************************************************************/
752 /* The TrueType size object finalizer. */
755 /* size :: A handle to the target size object. */
758 tt_size_done( FT_Size ttsize
) /* TT_Size */
760 TT_Size size
= (TT_Size
)ttsize
;
763 #ifdef TT_USE_BYTECODE_INTERPRETER
764 if ( size
->bytecode_ready
)
765 tt_size_done_bytecode( ttsize
);
768 size
->ttmetrics
.valid
= FALSE
;
772 /*************************************************************************/
778 /* Reset a TrueType size when resolutions and character dimensions */
779 /* have been changed. */
782 /* size :: A handle to the target size object. */
784 FT_LOCAL_DEF( FT_Error
)
785 tt_size_reset( TT_Size size
)
788 FT_Error error
= TT_Err_Ok
;
789 FT_Size_Metrics
* metrics
;
792 size
->ttmetrics
.valid
= FALSE
;
794 face
= (TT_Face
)size
->root
.face
;
796 metrics
= &size
->metrics
;
798 /* copy the result from base layer */
799 *metrics
= size
->root
.metrics
;
801 if ( metrics
->x_ppem
< 1 || metrics
->y_ppem
< 1 )
802 return TT_Err_Invalid_PPem
;
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. */
808 if ( face
->header
.Flags
& 8 )
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
);
816 FT_PIX_ROUND( FT_MulFix( face
->root
.ascender
, metrics
->y_scale
) );
818 FT_PIX_ROUND( FT_MulFix( face
->root
.descender
, metrics
->y_scale
) );
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
) );
826 /* compute new transformation */
827 if ( metrics
->x_ppem
>= metrics
->y_ppem
)
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
,
838 size
->ttmetrics
.scale
= metrics
->y_scale
;
839 size
->ttmetrics
.ppem
= metrics
->y_ppem
;
840 size
->ttmetrics
.x_ratio
= FT_MulDiv( metrics
->x_ppem
,
843 size
->ttmetrics
.y_ratio
= 0x10000L
;
846 #ifdef TT_USE_BYTECODE_INTERPRETER
848 #endif /* TT_USE_BYTECODE_INTERPRETER */
851 size
->ttmetrics
.valid
= TRUE
;
857 /*************************************************************************/
863 /* Initialize a given TrueType driver object. */
866 /* driver :: A handle to the target driver object. */
869 /* FreeType error code. 0 means success. */
871 FT_LOCAL_DEF( FT_Error
)
872 tt_driver_init( FT_Module ttdriver
) /* TT_Driver */
875 #ifdef TT_USE_BYTECODE_INTERPRETER
877 TT_Driver driver
= (TT_Driver
)ttdriver
;
880 if ( !TT_New_Context( driver
) )
881 return TT_Err_Could_Not_Find_Context
;
885 FT_UNUSED( ttdriver
);
893 /*************************************************************************/
899 /* Finalize a given TrueType driver. */
902 /* driver :: A handle to the target TrueType driver. */
905 tt_driver_done( FT_Module ttdriver
) /* TT_Driver */
907 #ifdef TT_USE_BYTECODE_INTERPRETER
908 TT_Driver driver
= (TT_Driver
)ttdriver
;
911 /* destroy the execution context */
912 if ( driver
->context
)
914 TT_Done_Context( driver
->context
);
915 driver
->context
= NULL
;
918 FT_UNUSED( ttdriver
);
924 /*************************************************************************/
930 /* Initialize a new slot object. */
933 /* slot :: A handle to the slot object. */
936 /* FreeType error code. 0 means success. */
938 FT_LOCAL_DEF( FT_Error
)
939 tt_slot_init( FT_GlyphSlot slot
)
941 return FT_GlyphLoader_CreateExtra( slot
->internal
->loader
);