1 /***************************************************************************/
5 /* Objects manager (body). */
7 /* Copyright 1996-2000 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 /***************************************************************************/
19 #include <freetype/internal/ftdebug.h>
20 #include <freetype/internal/ftcalc.h>
21 #include <freetype/internal/ftstream.h>
22 #include <freetype/ttnameid.h>
23 #include <freetype/tttags.h>
25 #include <freetype/internal/sfnt.h>
26 #include <freetype/internal/psnames.h>
29 #ifdef FT_FLAT_COMPILE
34 #ifdef TT_CONFIG_OPTION_BYTECODE_INTERPRETER
38 #else /* FT_FLAT_COMPILE */
40 #include <truetype/ttgload.h>
41 #include <truetype/ttpload.h>
43 #ifdef TT_CONFIG_OPTION_BYTECODE_INTERPRETER
44 #include <truetype/ttinterp.h>
47 #endif /* FT_FLAT_COMPILE */
50 #include <freetype/internal/tterrors.h>
54 /*************************************************************************/
56 /* The macro FT_COMPONENT is used in trace mode. It is an implicit */
57 /* parameter of the FT_TRACE() and FT_ERROR() macros, used to print/log */
58 /* messages during execution. */
61 #define FT_COMPONENT trace_ttobjs
64 /*************************************************************************/
66 /* GLYPH ZONE FUNCTIONS */
68 /*************************************************************************/
70 /*************************************************************************/
73 /* TT_Done_GlyphZone */
76 /* Deallocates a glyph zone. */
79 /* zone :: A pointer to the target glyph zone. */
82 void TT_Done_GlyphZone( TT_GlyphZone
* zone
)
84 FT_Memory memory
= zone
->memory
;
87 FREE( zone
->contours
);
92 zone
->max_points
= zone
->n_points
= 0;
93 zone
->max_contours
= zone
->n_contours
= 0;
97 /*************************************************************************/
100 /* TT_New_GlyphZone */
103 /* Allocates a new glyph zone. */
106 /* memory :: A handle to the current memory object. */
108 /* maxPoints :: The capacity of glyph zone in points. */
110 /* maxContours :: The capacity of glyph zone in contours. */
113 /* zone :: A pointer to the target glyph zone record. */
116 /* FreeType error code. 0 means success. */
119 FT_Error
TT_New_GlyphZone( FT_Memory memory
,
121 FT_Short maxContours
,
130 MEM_Set( zone
, 0, sizeof ( *zone
) );
131 zone
->memory
= memory
;
133 if ( ALLOC_ARRAY( zone
->org
, maxPoints
* 2, FT_F26Dot6
) ||
134 ALLOC_ARRAY( zone
->cur
, maxPoints
* 2, FT_F26Dot6
) ||
135 ALLOC_ARRAY( zone
->tags
, maxPoints
, FT_Byte
) ||
136 ALLOC_ARRAY( zone
->contours
, maxContours
, FT_UShort
) )
138 TT_Done_GlyphZone( zone
);
145 /*************************************************************************/
151 /* Initializes a given TrueType face object. */
154 /* stream :: The source font stream. */
156 /* face_index :: The index of the font face in the resource. */
158 /* num_params :: Number of additional generic parameters. Ignored. */
160 /* params :: Additional generic parameters. Ignored. */
163 /* face :: The newly built face object. */
166 /* FreeType error code. 0 means success. */
169 FT_Error
TT_Init_Face( FT_Stream stream
,
173 FT_Parameter
* params
)
177 SFNT_Interface
* sfnt
;
180 library
= face
->root
.driver
->root
.library
;
181 sfnt
= (SFNT_Interface
*)FT_Get_Module_Interface( library
, "sfnt" );
185 /* create input stream from resource */
186 if ( FILE_Seek( 0 ) )
189 /* check that we have a valid TrueType file */
190 error
= sfnt
->init_face( stream
, face
, face_index
, num_params
, params
);
194 /* We must also be able to accept Mac/GX fonts, as well as OT ones */
195 if ( face
->format_tag
!= 0x00010000L
&& /* MS fonts */
196 face
->format_tag
!= TTAG_true
) /* Mac fonts */
198 FT_TRACE2(( "[not a valid TTF font]\n" ));
202 /* If we are performing a simple font format check, exit immediately */
203 if ( face_index
< 0 )
206 /* Load font directory */
207 error
= sfnt
->load_face( stream
, face
, face_index
, num_params
, params
);
211 error
= TT_Load_Locations( face
, stream
) ||
212 TT_Load_CVT ( face
, stream
) ||
213 TT_Load_Programs ( face
, stream
);
215 /* initialize standard glyph loading routines */
216 TT_Init_Glyph_Loading( face
);
222 error
= FT_Err_Unknown_File_Format
;
227 /*************************************************************************/
233 /* Finalizes a given face object. */
236 /* face :: A pointer to the face object to destroy. */
239 void TT_Done_Face( TT_Face face
)
241 FT_Memory memory
= face
->root
.memory
;
242 FT_Stream stream
= face
->root
.stream
;
244 SFNT_Interface
* sfnt
= (SFNT_Interface
*)face
->sfnt
;
247 /* for `extended TrueType formats' (i.e. compressed versions) */
248 if ( face
->extra
.finalizer
)
249 face
->extra
.finalizer( face
->extra
.data
);
252 sfnt
->done_face( face
);
254 /* freeing the locations table */
255 FREE( face
->glyph_locations
);
256 face
->num_locations
= 0;
258 /* freeing the CVT */
262 /* freeing the programs */
263 RELEASE_Frame( face
->font_program
);
264 RELEASE_Frame( face
->cvt_program
);
265 face
->font_program_size
= 0;
266 face
->cvt_program_size
= 0;
270 /*************************************************************************/
274 /*************************************************************************/
277 /*************************************************************************/
283 /* Initializes a new TrueType size object. */
286 /* size :: A handle to the size object. */
289 /* FreeType error code. 0 means success. */
292 FT_Error
TT_Init_Size( TT_Size size
)
294 FT_Error error
= TT_Err_Ok
;
297 #ifdef TT_CONFIG_OPTION_BYTECODE_INTERPRETER
299 TT_Face face
= (TT_Face
)size
->root
.face
;
300 FT_Memory memory
= face
->root
.memory
;
304 FT_UShort n_twilight
;
305 TT_MaxProfile
* maxp
= &face
->max_profile
;
308 size
->ttmetrics
.valid
= FALSE
;
310 size
->max_function_defs
= maxp
->maxFunctionDefs
;
311 size
->max_instruction_defs
= maxp
->maxInstructionDefs
;
313 size
->num_function_defs
= 0;
314 size
->num_instruction_defs
= 0;
319 size
->cvt_size
= face
->cvt_size
;
320 size
->storage_size
= maxp
->maxStorage
;
322 /* Set default metrics */
324 FT_Size_Metrics
* metrics
= &size
->root
.metrics
;
325 TT_Size_Metrics
* metrics2
= &size
->ttmetrics
;
331 metrics2
->rotated
= FALSE
;
332 metrics2
->stretched
= FALSE
;
334 /* set default compensation (all 0) */
335 for ( i
= 0; i
< 4; i
++ )
336 metrics2
->compensations
[i
] = 0;
339 /* allocate function defs, instruction defs, cvt, and storage area */
340 if ( ALLOC_ARRAY( size
->function_defs
,
341 size
->max_function_defs
,
344 ALLOC_ARRAY( size
->instruction_defs
,
345 size
->max_instruction_defs
,
348 ALLOC_ARRAY( size
->cvt
,
349 size
->cvt_size
, FT_Long
) ||
351 ALLOC_ARRAY( size
->storage
,
352 size
->storage_size
, FT_Long
) )
356 /* reserve twilight zone */
357 n_twilight
= maxp
->maxTwilightPoints
;
358 error
= TT_New_GlyphZone( memory
, n_twilight
, 0, &size
->twilight
);
362 size
->twilight
.n_points
= n_twilight
;
364 /* set `face->interpreter' according to the debug hook present */
366 FT_Library library
= face
->root
.driver
->root
.library
;
369 face
->interpreter
= (TT_Interpreter
)
370 library
->debug_hooks
[FT_DEBUG_HOOK_TRUETYPE
];
371 if ( !face
->interpreter
)
372 face
->interpreter
= (TT_Interpreter
)TT_RunIns
;
375 /* Fine, now execute the font program! */
376 exec
= size
->context
;
377 /* size objects used during debugging have their own context */
379 exec
= TT_New_Context( face
);
383 error
= TT_Err_Could_Not_Find_Context
;
387 size
->GS
= tt_default_graphics_state
;
388 TT_Load_Context( exec
, face
, size
);
398 FT_Size_Metrics
* metrics
= &exec
->metrics
;
399 TT_Size_Metrics
* tt_metrics
= &exec
->tt_metrics
;
404 metrics
->x_scale
= 0;
405 metrics
->y_scale
= 0;
407 tt_metrics
->ppem
= 0;
408 tt_metrics
->scale
= 0;
409 tt_metrics
->ratio
= 0x10000L
;
412 exec
->instruction_trap
= FALSE
;
414 exec
->cvtSize
= size
->cvt_size
;
415 exec
->cvt
= size
->cvt
;
417 exec
->F_dot_P
= 0x10000L
;
419 /* allow font program execution */
420 TT_Set_CodeRange( exec
,
423 face
->font_program_size
);
425 /* disable CVT and glyph programs coderange */
426 TT_Clear_CodeRange( exec
, tt_coderange_cvt
);
427 TT_Clear_CodeRange( exec
, tt_coderange_glyph
);
429 if ( face
->font_program_size
> 0 )
431 error
= TT_Goto_CodeRange( exec
, tt_coderange_font
, 0 );
433 error
= face
->interpreter( exec
);
441 TT_Save_Context( exec
, size
);
444 TT_Done_Context( exec
);
446 #endif /* TT_CONFIG_OPTION_BYTECODE_INTERPRETER */
448 size
->ttmetrics
.valid
= FALSE
;
451 #ifdef TT_CONFIG_OPTION_BYTECODE_INTERPRETER
455 TT_Done_Context( exec
);
461 TT_Done_Size( size
);
466 /*************************************************************************/
472 /* The TrueType size object finalizer. */
475 /* size :: A handle to the target size object. */
478 void TT_Done_Size( TT_Size size
)
481 #ifdef TT_CONFIG_OPTION_BYTECODE_INTERPRETER
483 FT_Memory memory
= size
->root
.face
->memory
;
488 /* the debug context must be deleted by the debugger itself */
489 size
->context
= NULL
;
496 /* free storage area */
497 FREE( size
->storage
);
498 size
->storage_size
= 0;
501 TT_Done_GlyphZone( &size
->twilight
);
503 FREE( size
->function_defs
);
504 FREE( size
->instruction_defs
);
506 size
->num_function_defs
= 0;
507 size
->max_function_defs
= 0;
508 size
->num_instruction_defs
= 0;
509 size
->max_instruction_defs
= 0;
516 size
->ttmetrics
.valid
= FALSE
;
520 /*************************************************************************/
526 /* Resets a TrueType size when resolutions and character dimensions */
527 /* have been changed. */
530 /* size :: A handle to the target size object. */
533 FT_Error
TT_Reset_Size( TT_Size size
)
536 FT_Error error
= TT_Err_Ok
;
538 FT_Size_Metrics
* metrics
;
541 if ( size
->ttmetrics
.valid
)
544 face
= (TT_Face
)size
->root
.face
;
546 metrics
= &size
->root
.metrics
;
548 if ( metrics
->x_ppem
< 1 || metrics
->y_ppem
< 1 )
549 return TT_Err_Invalid_PPem
;
551 /* compute new transformation */
552 if ( metrics
->x_ppem
>= metrics
->y_ppem
)
554 size
->ttmetrics
.scale
= metrics
->x_scale
;
555 size
->ttmetrics
.ppem
= metrics
->x_ppem
;
556 size
->ttmetrics
.x_ratio
= 0x10000L
;
557 size
->ttmetrics
.y_ratio
= FT_MulDiv( metrics
->y_ppem
,
563 size
->ttmetrics
.scale
= metrics
->y_scale
;
564 size
->ttmetrics
.ppem
= metrics
->y_ppem
;
565 size
->ttmetrics
.x_ratio
= FT_MulDiv( metrics
->x_ppem
,
568 size
->ttmetrics
.y_ratio
= 0x10000L
;
571 /* Compute root ascender, descender, test height, and max_advance */
572 metrics
->ascender
= ( FT_MulFix( face
->root
.ascender
,
573 metrics
->y_scale
) + 32 ) & -64;
574 metrics
->descender
= ( FT_MulFix( face
->root
.descender
,
575 metrics
->y_scale
) + 32 ) & -64;
576 metrics
->height
= ( FT_MulFix( face
->root
.height
,
577 metrics
->y_scale
) + 32 ) & -64;
578 metrics
->max_advance
= ( FT_MulFix( face
->root
.max_advance_width
,
579 metrics
->x_scale
) + 32 ) & -64;
581 #ifdef TT_CONFIG_OPTION_BYTECODE_INTERPRETER
588 /* Scale the cvt values to the new ppem. */
589 /* We use by default the y ppem to scale the CVT. */
590 for ( i
= 0; i
< size
->cvt_size
; i
++ )
591 size
->cvt
[i
] = FT_MulFix( face
->cvt
[i
], size
->ttmetrics
.scale
);
593 /* All twilight points are originally zero */
594 for ( j
= 0; j
< size
->twilight
.n_points
; j
++ )
596 size
->twilight
.org
[j
].x
= 0;
597 size
->twilight
.org
[j
].y
= 0;
598 size
->twilight
.cur
[j
].x
= 0;
599 size
->twilight
.cur
[j
].y
= 0;
602 /* clear storage area */
603 for ( i
= 0; i
< size
->storage_size
; i
++ )
604 size
->storage
[i
] = 0;
606 size
->GS
= tt_default_graphics_state
;
608 /* get execution context and run prep program */
610 exec
= size
->context
;
612 exec
= TT_New_Context( face
);
613 /* debugging instances have their own context */
616 return TT_Err_Could_Not_Find_Context
;
618 TT_Load_Context( exec
, face
, size
);
620 TT_Set_CodeRange( exec
,
623 face
->cvt_program_size
);
625 TT_Clear_CodeRange( exec
, tt_coderange_glyph
);
627 exec
->instruction_trap
= FALSE
;
632 if ( face
->cvt_program_size
> 0 )
634 error
= TT_Goto_CodeRange( exec
, tt_coderange_cvt
, 0 );
639 error
= face
->interpreter( exec
);
645 /* save default graphics state */
648 TT_Save_Context( exec
, size
);
651 TT_Done_Context( exec
);
652 /* debugging instances keep their context */
655 #endif /* TT_CONFIG_OPTION_BYTECODE_INTERPRETER */
658 size
->ttmetrics
.valid
= TRUE
;
664 /*************************************************************************/
670 /* Initializes a given TrueType driver object. */
673 /* driver :: A handle to the target driver object. */
676 /* FreeType error code. 0 means success. */
679 FT_Error
TT_Init_Driver( TT_Driver driver
)
684 /* set `extra' in glyph loader */
685 error
= FT_GlyphLoader_Create_Extra( FT_DRIVER( driver
)->glyph_loader
);
687 /* init extension registry if needed */
689 #ifdef TT_CONFIG_OPTION_EXTEND_ENGINE
691 return TT_Init_Extensions( driver
);
698 /*************************************************************************/
704 /* Finalizes a given TrueType driver. */
707 /* driver :: A handle to the target TrueType driver. */
710 void TT_Done_Driver( TT_Driver driver
)
712 /* destroy extensions registry if needed */
714 #ifdef TT_CONFIG_OPTION_EXTEND_ENGINE
716 TT_Done_Extensions( driver
);
720 #ifdef TT_CONFIG_OPTION_BYTECODE_INTERPRETER
722 /* destroy the execution context */
723 if ( driver
->context
)
725 TT_Destroy_Context( driver
->context
, driver
->root
.root
.memory
);
726 driver
->context
= NULL
;