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
;