1 /***************************************************************************/
5 /* Objects manager (body). */
7 /* Copyright 1996-2001 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
26 #include FT_INTERNAL_POSTSCRIPT_NAMES_H
33 #ifdef TT_CONFIG_OPTION_BYTECODE_INTERPRETER
38 /*************************************************************************/
40 /* The macro FT_COMPONENT is used in trace mode. It is an implicit */
41 /* parameter of the FT_TRACE() and FT_ERROR() macros, used to print/log */
42 /* messages during execution. */
45 #define FT_COMPONENT trace_ttobjs
48 #ifdef TT_CONFIG_OPTION_BYTECODE_INTERPRETER
50 /*************************************************************************/
52 /* GLYPH ZONE FUNCTIONS */
54 /*************************************************************************/
57 /*************************************************************************/
60 /* TT_Done_GlyphZone */
63 /* Deallocates a glyph zone. */
66 /* zone :: A pointer to the target glyph zone. */
69 TT_Done_GlyphZone( TT_GlyphZone* zone )
71 FT_Memory memory = zone->memory;
74 FREE( zone->contours );
79 zone->max_points = zone->n_points = 0;
80 zone->max_contours = zone->n_contours = 0;
84 /*************************************************************************/
87 /* TT_New_GlyphZone */
90 /* Allocates a new glyph zone. */
93 /* memory :: A handle to the current memory object. */
95 /* maxPoints :: The capacity of glyph zone in points. */
97 /* maxContours :: The capacity of glyph zone in contours. */
100 /* zone :: A pointer to the target glyph zone record. */
103 /* FreeType error code. 0 means success. */
105 FT_LOCAL_DEF FT_Error
106 TT_New_GlyphZone( FT_Memory memory,
108 FT_Short maxContours,
117 MEM_Set( zone, 0, sizeof ( *zone ) );
118 zone->memory = memory;
120 if ( ALLOC_ARRAY( zone->org, maxPoints * 2, FT_F26Dot6 ) ||
121 ALLOC_ARRAY( zone->cur, maxPoints * 2, FT_F26Dot6 ) ||
122 ALLOC_ARRAY( zone->tags, maxPoints, FT_Byte ) ||
123 ALLOC_ARRAY( zone->contours, maxContours, FT_UShort ) )
125 TT_Done_GlyphZone( zone );
130 #endif /* TT_CONFIG_OPTION_BYTECODE_INTERPRETER */
133 /*************************************************************************/
139 /* Initializes a given TrueType face object. */
142 /* stream :: The source font stream. */
144 /* face_index :: The index of the font face in the resource. */
146 /* num_params :: Number of additional generic parameters. Ignored. */
148 /* params :: Additional generic parameters. Ignored. */
151 /* face :: The newly built face object. */
154 /* FreeType error code. 0 means success. */
156 FT_LOCAL_DEF FT_Error
157 TT_Init_Face( FT_Stream stream,
161 FT_Parameter* params )
165 SFNT_Interface* sfnt;
168 library = face->root.driver->root.library;
169 sfnt = (SFNT_Interface*)FT_Get_Module_Interface( library, "sfnt" );
173 /* create input stream from resource */
174 if ( FILE_Seek( 0 ) )
177 /* check that we have a valid TrueType file */
178 error = sfnt->init_face( stream, face, face_index, num_params, params );
182 /* We must also be able to accept Mac/GX fonts, as well as OT ones */
183 if ( face->format_tag != 0x00010000L && /* MS fonts */
184 face->format_tag != TTAG_true ) /* Mac fonts */
186 FT_TRACE2(( "[not a valid TTF font]\n" ));
190 /* If we are performing a simple font format check, exit immediately */
191 if ( face_index < 0 )
194 /* Load font directory */
195 error = sfnt->load_face( stream, face, face_index, num_params, params );
199 if ( face->root.face_flags & FT_FACE_FLAG_SCALABLE )
200 error = TT_Load_Locations( face, stream ) ||
201 TT_Load_CVT ( face, stream ) ||
202 TT_Load_Programs ( face, stream );
204 /* initialize standard glyph loading routines */
205 TT_Init_Glyph_Loading( face );
211 error = TT_Err_Unknown_File_Format;
216 /*************************************************************************/
222 /* Finalizes a given face object. */
225 /* face :: A pointer to the face object to destroy. */
228 TT_Done_Face( TT_Face face )
230 FT_Memory memory = face->root.memory;
231 FT_Stream stream = face->root.stream;
233 SFNT_Interface* sfnt = (SFNT_Interface*)face->sfnt;
236 /* for `extended TrueType formats' (i.e. compressed versions) */
237 if ( face->extra.finalizer )
238 face->extra.finalizer( face->extra.data );
241 sfnt->done_face( face );
243 /* freeing the locations table */
244 FREE( face->glyph_locations );
245 face->num_locations = 0;
247 /* freeing the CVT */
251 /* freeing the programs */
252 RELEASE_Frame( face->font_program );
253 RELEASE_Frame( face->cvt_program );
254 face->font_program_size = 0;
255 face->cvt_program_size = 0;
259 /*************************************************************************/
263 /*************************************************************************/
266 /*************************************************************************/
272 /* Initializes a new TrueType size object. */
275 /* size :: A handle to the size object. */
278 /* FreeType error code. 0 means success. */
280 FT_LOCAL_DEF FT_Error
281 TT_Init_Size( TT_Size size )
283 FT_Error error = TT_Err_Ok;
286 #ifdef TT_CONFIG_OPTION_BYTECODE_INTERPRETER
288 TT_Face face = (TT_Face)size->root.face;
289 FT_Memory memory = face->root.memory;
293 FT_UShort n_twilight;
294 TT_MaxProfile* maxp = &face->max_profile;
297 size->ttmetrics.valid = FALSE;
299 size->max_function_defs = maxp->maxFunctionDefs;
300 size->max_instruction_defs = maxp->maxInstructionDefs;
302 size->num_function_defs = 0;
303 size->num_instruction_defs = 0;
308 size->cvt_size = face->cvt_size;
309 size->storage_size = maxp->maxStorage;
311 /* Set default metrics */
313 FT_Size_Metrics* metrics = &size->root.metrics;
314 TT_Size_Metrics* metrics2 = &size->ttmetrics;
320 metrics2->rotated = FALSE;
321 metrics2->stretched = FALSE;
323 /* set default compensation (all 0) */
324 for ( i = 0; i < 4; i++ )
325 metrics2->compensations[i] = 0;
328 /* allocate function defs, instruction defs, cvt, and storage area */
329 if ( ALLOC_ARRAY( size->function_defs,
330 size->max_function_defs,
333 ALLOC_ARRAY( size->instruction_defs,
334 size->max_instruction_defs,
337 ALLOC_ARRAY( size->cvt,
338 size->cvt_size, FT_Long ) ||
340 ALLOC_ARRAY( size->storage,
341 size->storage_size, FT_Long ) )
345 /* reserve twilight zone */
346 n_twilight = maxp->maxTwilightPoints;
347 error = TT_New_GlyphZone( memory, n_twilight, 0, &size->twilight );
351 size->twilight.n_points = n_twilight;
353 /* set `face->interpreter' according to the debug hook present */
355 FT_Library library = face->root.driver->root.library;
358 face->interpreter = (TT_Interpreter)
359 library->debug_hooks[FT_DEBUG_HOOK_TRUETYPE];
360 if ( !face->interpreter )
361 face->interpreter = (TT_Interpreter)TT_RunIns;
364 /* Fine, now execute the font program! */
365 exec = size->context;
366 /* size objects used during debugging have their own context */
368 exec = TT_New_Context( face );
372 error = TT_Err_Could_Not_Find_Context;
376 size->GS = tt_default_graphics_state;
377 TT_Load_Context( exec, face, size );
387 FT_Size_Metrics* metrics = &exec->metrics;
388 TT_Size_Metrics* tt_metrics = &exec->tt_metrics;
393 metrics->x_scale = 0;
394 metrics->y_scale = 0;
396 tt_metrics->ppem = 0;
397 tt_metrics->scale = 0;
398 tt_metrics->ratio = 0x10000L;
401 exec->instruction_trap = FALSE;
403 exec->cvtSize = size->cvt_size;
404 exec->cvt = size->cvt;
406 exec->F_dot_P = 0x10000L;
408 /* allow font program execution */
409 TT_Set_CodeRange( exec,
412 face->font_program_size );
414 /* disable CVT and glyph programs coderange */
415 TT_Clear_CodeRange( exec, tt_coderange_cvt );
416 TT_Clear_CodeRange( exec, tt_coderange_glyph );
418 if ( face->font_program_size > 0 )
420 error = TT_Goto_CodeRange( exec, tt_coderange_font, 0 );
422 error = face->interpreter( exec );
430 TT_Save_Context( exec, size );
433 TT_Done_Context( exec );
435 #endif /* TT_CONFIG_OPTION_BYTECODE_INTERPRETER */
437 size->ttmetrics.valid = FALSE;
440 #ifdef TT_CONFIG_OPTION_BYTECODE_INTERPRETER
444 TT_Done_Context( exec );
448 TT_Done_Size( size );
451 #endif /* TT_CONFIG_OPTION_BYTECODE_INTERPRETER */
456 /*************************************************************************/
462 /* The TrueType size object finalizer. */
465 /* size :: A handle to the target size object. */
468 TT_Done_Size( TT_Size size )
471 #ifdef TT_CONFIG_OPTION_BYTECODE_INTERPRETER
473 FT_Memory memory = size->root.face->memory;
478 /* the debug context must be deleted by the debugger itself */
479 size->context = NULL;
486 /* free storage area */
487 FREE( size->storage );
488 size->storage_size = 0;
491 TT_Done_GlyphZone( &size->twilight );
493 FREE( size->function_defs );
494 FREE( size->instruction_defs );
496 size->num_function_defs = 0;
497 size->max_function_defs = 0;
498 size->num_instruction_defs = 0;
499 size->max_instruction_defs = 0;
506 size->ttmetrics.valid = FALSE;
510 /*************************************************************************/
513 /* Reset_Outline_Size */
516 /* Resets a TrueType outline size when resolutions and character */
517 /* dimensions have been changed. */
520 /* size :: A handle to the target size object. */
523 Reset_Outline_Size( TT_Size size )
526 FT_Error error = TT_Err_Ok;
528 FT_Size_Metrics* metrics;
531 if ( size->ttmetrics.valid )
534 face = (TT_Face)size->root.face;
536 metrics = &size->root.metrics;
538 if ( metrics->x_ppem < 1 || metrics->y_ppem < 1 )
539 return TT_Err_Invalid_PPem;
541 /* compute new transformation */
542 if ( metrics->x_ppem >= metrics->y_ppem )
544 size->ttmetrics.scale = metrics->x_scale;
545 size->ttmetrics.ppem = metrics->x_ppem;
546 size->ttmetrics.x_ratio = 0x10000L;
547 size->ttmetrics.y_ratio = FT_MulDiv( metrics->y_ppem,
553 size->ttmetrics.scale = metrics->y_scale;
554 size->ttmetrics.ppem = metrics->y_ppem;
555 size->ttmetrics.x_ratio = FT_MulDiv( metrics->x_ppem,
558 size->ttmetrics.y_ratio = 0x10000L;
561 /* Compute root ascender, descender, test height, and max_advance */
562 metrics->ascender = ( FT_MulFix( face->root.ascender,
563 metrics->y_scale ) + 32 ) & -64;
564 metrics->descender = ( FT_MulFix( face->root.descender,
565 metrics->y_scale ) + 32 ) & -64;
566 metrics->height = ( FT_MulFix( face->root.height,
567 metrics->y_scale ) + 32 ) & -64;
568 metrics->max_advance = ( FT_MulFix( face->root.max_advance_width,
569 metrics->x_scale ) + 32 ) & -64;
571 #ifdef TT_CONFIG_OPTION_EMBEDDED_BITMAPS
572 /* set to `invalid' by default */
573 size->strike_index = 0xFFFF;
576 #ifdef TT_CONFIG_OPTION_BYTECODE_INTERPRETER
583 /* Scale the cvt values to the new ppem. */
584 /* We use by default the y ppem to scale the CVT. */
585 for ( i = 0; i < size->cvt_size; i++ )
586 size->cvt[i] = FT_MulFix( face->cvt[i], size->ttmetrics.scale );
588 /* All twilight points are originally zero */
589 for ( j = 0; j < (FT_UInt)size->twilight.n_points; j++ )
591 size->twilight.org[j].x = 0;
592 size->twilight.org[j].y = 0;
593 size->twilight.cur[j].x = 0;
594 size->twilight.cur[j].y = 0;
597 /* clear storage area */
598 for ( i = 0; i < (FT_UInt)size->storage_size; i++ )
599 size->storage[i] = 0;
601 size->GS = tt_default_graphics_state;
603 /* get execution context and run prep program */
605 exec = size->context;
607 exec = TT_New_Context( face );
608 /* debugging instances have their own context */
611 return TT_Err_Could_Not_Find_Context;
613 TT_Load_Context( exec, face, size );
615 TT_Set_CodeRange( exec,
618 face->cvt_program_size );
620 TT_Clear_CodeRange( exec, tt_coderange_glyph );
622 exec->instruction_trap = FALSE;
627 if ( face->cvt_program_size > 0 )
629 error = TT_Goto_CodeRange( exec, tt_coderange_cvt, 0 );
634 error = face->interpreter( exec );
640 /* save default graphics state */
643 TT_Save_Context( exec, size );
646 TT_Done_Context( exec );
647 /* debugging instances keep their context */
650 #endif /* TT_CONFIG_OPTION_BYTECODE_INTERPRETER */
653 size->ttmetrics.valid = TRUE;
659 #ifdef TT_CONFIG_OPTION_EMBEDDED_BITMAPS
661 /*************************************************************************/
664 /* Reset_SBit_Size */
667 /* Resets a TrueType sbit size when resolutions and character */
668 /* dimensions have been changed. */
671 /* size :: A handle to the target size object. */
674 Reset_SBit_Size( TT_Size size )
677 FT_Error error = TT_Err_Ok;
679 FT_ULong strike_index;
680 FT_Size_Metrics* metrics;
681 FT_Size_Metrics* sbit_metrics;
682 SFNT_Interface* sfnt;
685 metrics = &size->root.metrics;
687 if ( size->strike_index != 0xFFFF )
690 face = (TT_Face)size->root.face;
691 sfnt = (SFNT_Interface*)face->sfnt;
693 sbit_metrics = &size->strike_metrics;
695 error = sfnt->set_sbit_strike(face,
696 metrics->x_ppem, metrics->y_ppem,
701 TT_SBit_Strike* strike = face->sbit_strikes + strike_index;
704 sbit_metrics->x_ppem = metrics->x_ppem;
705 sbit_metrics->y_ppem = metrics->y_ppem;
708 * sbit_metrics->?_scale
711 sbit_metrics->x_scale = 1 << 16;
712 sbit_metrics->y_scale = 1 << 16;
715 sbit_metrics->ascender = strike->hori.ascender << 6;
716 sbit_metrics->descender = strike->hori.descender << 6;
718 /* XXX: Is this correct? */
719 sbit_metrics->height = sbit_metrics->ascender -
720 sbit_metrics->descender;
722 /* XXX: Is this correct? */
723 sbit_metrics->max_advance = ( strike->hori.min_origin_SB +
724 strike->hori.max_width +
725 strike->hori.min_advance_SB ) << 6;
727 size->strike_index = strike_index;
731 size->strike_index = 0xFFFF;
733 sbit_metrics->x_ppem = 0;
734 sbit_metrics->y_ppem = 0;
735 sbit_metrics->ascender = 0;
736 sbit_metrics->descender = 0;
737 sbit_metrics->height = 0;
738 sbit_metrics->max_advance = 0;
744 #endif /* TT_CONFIG_OPTION_EMBEDDED_BITMAPS */
747 /*************************************************************************/
753 /* Resets a TrueType size when resolutions and character dimensions */
754 /* have been changed. */
757 /* size :: A handle to the target size object. */
759 FT_LOCAL_DEF FT_Error
760 TT_Reset_Size( TT_Size size )
763 FT_Error error = TT_Err_Ok;
766 face = size->root.face;
768 if ( face->face_flags & FT_FACE_FLAG_SCALABLE )
770 if ( !size->ttmetrics.valid )
771 error = Reset_Outline_Size( size );
777 #ifdef TT_CONFIG_OPTION_EMBEDDED_BITMAPS
779 if ( face->face_flags & FT_FACE_FLAG_FIXED_SIZES )
781 if ( size->strike_index == 0xFFFF )
782 error = Reset_SBit_Size( size );
784 if ( !error && !( face->face_flags & FT_FACE_FLAG_SCALABLE ) )
785 size->root.metrics = size->strike_metrics;
788 #endif /* TT_CONFIG_OPTION_EMBEDDED_BITMAPS */
790 if ( face->face_flags & FT_FACE_FLAG_SCALABLE )
797 /*************************************************************************/
803 /* Initializes a given TrueType driver object. */
806 /* driver :: A handle to the target driver object. */
809 /* FreeType error code. 0 means success. */
811 FT_LOCAL_DEF FT_Error
812 TT_Init_Driver( TT_Driver driver )
817 /* set `extra' in glyph loader */
818 error = FT_GlyphLoader_Create_Extra( FT_DRIVER( driver )->glyph_loader );
820 /* init extension registry if needed */
822 #ifdef TT_CONFIG_OPTION_EXTEND_ENGINE
824 return TT_Init_Extensions( driver );
831 /*************************************************************************/
837 /* Finalizes a given TrueType driver. */
840 /* driver :: A handle to the target TrueType driver. */
843 TT_Done_Driver( TT_Driver driver )
845 /* destroy extensions registry if needed */
847 #ifdef TT_CONFIG_OPTION_EXTEND_ENGINE
849 TT_Done_Extensions( driver );
853 #ifdef TT_CONFIG_OPTION_BYTECODE_INTERPRETER
855 /* destroy the execution context */
856 if ( driver->context )
858 TT_Destroy_Context( driver->context, driver->root.root.memory );
859 driver->context = NULL;