1 /***************************************************************************/ 2 /* */ 3 /* ttobjs.c */ 4 /* */ 5 /* Objects manager (body). */ 6 /* */ 7 /* Copyright 1996-2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009 by */ 8 /* David Turner, Robert Wilhelm, and Werner Lemberg. */ 9 /* */ 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. */ 15 /* */ 16 /***************************************************************************/ 17 18 19 #include <ft2build.h> 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 27 #include "ttgload.h" 28 #include "ttpload.h" 29 30 #include "tterrors.h" 31 32 #ifdef TT_USE_BYTECODE_INTERPRETER 33 #include "ttinterp.h" 34 #endif 35 36 #ifdef TT_CONFIG_OPTION_UNPATENTED_HINTING 37 #include FT_TRUETYPE_UNPATENTED_H 38 #endif 39 40 #ifdef TT_CONFIG_OPTION_GX_VAR_SUPPORT 41 #include "ttgxvar.h" 42 #endif 43 44 /*************************************************************************/ 45 /* */ 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. */ 49 /* */ 50 #undef FT_COMPONENT 51 #define FT_COMPONENT trace_ttobjs 52 53 54 #ifdef TT_USE_BYTECODE_INTERPRETER 55 56 /*************************************************************************/ 57 /* */ 58 /* GLYPH ZONE FUNCTIONS */ 59 /* */ 60 /*************************************************************************/ 61 62 63 /*************************************************************************/ 64 /* */ 65 /* <Function> */ 66 /* tt_glyphzone_done */ 67 /* */ 68 /* <Description> */ 69 /* Deallocate a glyph zone. */ 70 /* */ 71 /* <Input> */ 72 /* zone :: A pointer to the target glyph zone. */ 73 /* */ 74 FT_LOCAL_DEF( void ) tt_glyphzone_done(TT_GlyphZone zone)75 tt_glyphzone_done( TT_GlyphZone zone ) 76 { 77 FT_Memory memory = zone->memory; 78 79 80 if ( memory ) 81 { 82 FT_FREE( zone->contours ); 83 FT_FREE( zone->tags ); 84 FT_FREE( zone->cur ); 85 FT_FREE( zone->org ); 86 FT_FREE( zone->orus ); 87 88 zone->max_points = zone->n_points = 0; 89 zone->max_contours = zone->n_contours = 0; 90 zone->memory = NULL; 91 } 92 } 93 94 95 /*************************************************************************/ 96 /* */ 97 /* <Function> */ 98 /* tt_glyphzone_new */ 99 /* */ 100 /* <Description> */ 101 /* Allocate a new glyph zone. */ 102 /* */ 103 /* <Input> */ 104 /* memory :: A handle to the current memory object. */ 105 /* */ 106 /* maxPoints :: The capacity of glyph zone in points. */ 107 /* */ 108 /* maxContours :: The capacity of glyph zone in contours. */ 109 /* */ 110 /* <Output> */ 111 /* zone :: A pointer to the target glyph zone record. */ 112 /* */ 113 /* <Return> */ 114 /* FreeType error code. 0 means success. */ 115 /* */ 116 FT_LOCAL_DEF( FT_Error ) tt_glyphzone_new(FT_Memory memory,FT_UShort maxPoints,FT_Short maxContours,TT_GlyphZone zone)117 tt_glyphzone_new( FT_Memory memory, 118 FT_UShort maxPoints, 119 FT_Short maxContours, 120 TT_GlyphZone zone ) 121 { 122 FT_Error error; 123 124 125 FT_MEM_ZERO( zone, sizeof ( *zone ) ); 126 zone->memory = memory; 127 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 ) ) 133 { 134 tt_glyphzone_done( zone ); 135 } 136 else 137 { 138 zone->max_points = maxPoints; 139 zone->max_contours = maxContours; 140 } 141 142 return error; 143 } 144 #endif /* TT_USE_BYTECODE_INTERPRETER */ 145 146 147 /* Compare the face with a list of well-known `tricky' fonts. */ 148 /* This list shall be expanded as we find more of them. */ 149 150 static FT_Bool tt_check_trickyness(FT_String * name)151 tt_check_trickyness( FT_String* name ) 152 { 153 static const char* const trick_names[] = 154 { 155 "DFKaiSho-SB", /* dfkaisb.ttf */ 156 "DFKaiShu", 157 "DFKai-SB", /* kaiu.ttf */ 158 "HuaTianSongTi?", /* htst3.ttf */ 159 "MingLiU", /* mingliu.ttf & mingliu.ttc */ 160 "PMingLiU", /* mingliu.ttc */ 161 "MingLi43", /* mingli.ttf */ 162 NULL 163 }; 164 int nn; 165 166 167 if ( !name ) 168 return FALSE; 169 170 /* Note that we only check the face name at the moment; it might */ 171 /* be worth to do more checks for a few special cases. */ 172 for ( nn = 0; trick_names[nn] != NULL; nn++ ) 173 if ( ft_strstr( name, trick_names[nn] ) ) 174 return TRUE; 175 176 return FALSE; 177 } 178 179 180 /*************************************************************************/ 181 /* */ 182 /* <Function> */ 183 /* tt_face_init */ 184 /* */ 185 /* <Description> */ 186 /* Initialize a given TrueType face object. */ 187 /* */ 188 /* <Input> */ 189 /* stream :: The source font stream. */ 190 /* */ 191 /* face_index :: The index of the font face in the resource. */ 192 /* */ 193 /* num_params :: Number of additional generic parameters. Ignored. */ 194 /* */ 195 /* params :: Additional generic parameters. Ignored. */ 196 /* */ 197 /* <InOut> */ 198 /* face :: The newly built face object. */ 199 /* */ 200 /* <Return> */ 201 /* FreeType error code. 0 means success. */ 202 /* */ 203 FT_LOCAL_DEF( FT_Error ) tt_face_init(FT_Stream stream,FT_Face ttface,FT_Int face_index,FT_Int num_params,FT_Parameter * params)204 tt_face_init( FT_Stream stream, 205 FT_Face ttface, /* TT_Face */ 206 FT_Int face_index, 207 FT_Int num_params, 208 FT_Parameter* params ) 209 { 210 FT_Error error; 211 FT_Library library; 212 SFNT_Service sfnt; 213 TT_Face face = (TT_Face)ttface; 214 215 216 library = ttface->driver->root.library; 217 sfnt = (SFNT_Service)FT_Get_Module_Interface( library, "sfnt" ); 218 if ( !sfnt ) 219 goto Bad_Format; 220 221 /* create input stream from resource */ 222 if ( FT_STREAM_SEEK( 0 ) ) 223 goto Exit; 224 225 /* check that we have a valid TrueType file */ 226 error = sfnt->init_face( stream, face, face_index, num_params, params ); 227 if ( error ) 228 goto Exit; 229 230 /* We must also be able to accept Mac/GX fonts, as well as OT ones. */ 231 /* The 0x00020000 tag is completely undocumented; some fonts from */ 232 /* Arphic made for Chinese Windows 3.1 have this. */ 233 if ( face->format_tag != 0x00010000L && /* MS fonts */ 234 face->format_tag != 0x00020000L && /* CJK fonts for Win 3.1 */ 235 face->format_tag != TTAG_true ) /* Mac fonts */ 236 { 237 FT_TRACE2(( "[not a valid TTF font]\n" )); 238 goto Bad_Format; 239 } 240 241 #ifdef TT_USE_BYTECODE_INTERPRETER 242 ttface->face_flags |= FT_FACE_FLAG_HINTER; 243 #endif 244 245 /* If we are performing a simple font format check, exit immediately. */ 246 if ( face_index < 0 ) 247 return TT_Err_Ok; 248 249 /* Load font directory */ 250 error = sfnt->load_face( stream, face, face_index, num_params, params ); 251 if ( error ) 252 goto Exit; 253 254 if ( tt_check_trickyness( ttface->family_name ) ) 255 ttface->face_flags |= FT_FACE_FLAG_TRICKY; 256 257 error = tt_face_load_hdmx( face, stream ); 258 if ( error ) 259 goto Exit; 260 261 if ( FT_IS_SCALABLE( ttface ) ) 262 { 263 264 #ifdef FT_CONFIG_OPTION_INCREMENTAL 265 266 if ( !ttface->internal->incremental_interface ) 267 error = tt_face_load_loca( face, stream ); 268 if ( !error ) 269 error = tt_face_load_cvt( face, stream ); 270 if ( !error ) 271 error = tt_face_load_fpgm( face, stream ); 272 if ( !error ) 273 error = tt_face_load_prep( face, stream ); 274 275 #else 276 277 if ( !error ) 278 error = tt_face_load_loca( face, stream ); 279 if ( !error ) 280 error = tt_face_load_cvt( face, stream ); 281 if ( !error ) 282 error = tt_face_load_fpgm( face, stream ); 283 if ( !error ) 284 error = tt_face_load_prep( face, stream ); 285 286 #endif 287 288 } 289 290 #if defined( TT_CONFIG_OPTION_UNPATENTED_HINTING ) && \ 291 !defined( TT_CONFIG_OPTION_BYTECODE_INTERPRETER ) 292 293 { 294 FT_Bool unpatented_hinting; 295 int i; 296 297 298 /* Determine whether unpatented hinting is to be used for this face. */ 299 unpatented_hinting = FT_BOOL 300 ( library->debug_hooks[FT_DEBUG_HOOK_UNPATENTED_HINTING] != NULL ); 301 302 for ( i = 0; i < num_params && !face->unpatented_hinting; i++ ) 303 if ( params[i].tag == FT_PARAM_TAG_UNPATENTED_HINTING ) 304 unpatented_hinting = TRUE; 305 306 if ( !unpatented_hinting ) 307 ttface->internal->ignore_unpatented_hinter = TRUE; 308 } 309 310 #endif /* TT_CONFIG_OPTION_UNPATENTED_HINTING && 311 !TT_CONFIG_OPTION_BYTECODE_INTERPRETER */ 312 313 /* initialize standard glyph loading routines */ 314 TT_Init_Glyph_Loading( face ); 315 316 Exit: 317 return error; 318 319 Bad_Format: 320 error = TT_Err_Unknown_File_Format; 321 goto Exit; 322 } 323 324 325 /*************************************************************************/ 326 /* */ 327 /* <Function> */ 328 /* tt_face_done */ 329 /* */ 330 /* <Description> */ 331 /* Finalize a given face object. */ 332 /* */ 333 /* <Input> */ 334 /* face :: A pointer to the face object to destroy. */ 335 /* */ 336 FT_LOCAL_DEF( void ) tt_face_done(FT_Face ttface)337 tt_face_done( FT_Face ttface ) /* TT_Face */ 338 { 339 TT_Face face = (TT_Face)ttface; 340 FT_Memory memory; 341 FT_Stream stream; 342 SFNT_Service sfnt; 343 344 345 if ( !face ) 346 return; 347 348 memory = ttface->memory; 349 stream = ttface->stream; 350 sfnt = (SFNT_Service)face->sfnt; 351 352 /* for `extended TrueType formats' (i.e. compressed versions) */ 353 if ( face->extra.finalizer ) 354 face->extra.finalizer( face->extra.data ); 355 356 if ( sfnt ) 357 sfnt->done_face( face ); 358 359 /* freeing the locations table */ 360 tt_face_done_loca( face ); 361 362 tt_face_free_hdmx( face ); 363 364 /* freeing the CVT */ 365 FT_FREE( face->cvt ); 366 face->cvt_size = 0; 367 368 /* freeing the programs */ 369 FT_FRAME_RELEASE( face->font_program ); 370 FT_FRAME_RELEASE( face->cvt_program ); 371 face->font_program_size = 0; 372 face->cvt_program_size = 0; 373 374 #ifdef TT_CONFIG_OPTION_GX_VAR_SUPPORT 375 tt_done_blend( memory, face->blend ); 376 face->blend = NULL; 377 #endif 378 } 379 380 381 /*************************************************************************/ 382 /* */ 383 /* SIZE FUNCTIONS */ 384 /* */ 385 /*************************************************************************/ 386 387 #ifdef TT_USE_BYTECODE_INTERPRETER 388 389 /*************************************************************************/ 390 /* */ 391 /* <Function> */ 392 /* tt_size_run_fpgm */ 393 /* */ 394 /* <Description> */ 395 /* Run the font program. */ 396 /* */ 397 /* <Input> */ 398 /* size :: A handle to the size object. */ 399 /* */ 400 /* <Return> */ 401 /* FreeType error code. 0 means success. */ 402 /* */ 403 FT_LOCAL_DEF( FT_Error ) tt_size_run_fpgm(TT_Size size)404 tt_size_run_fpgm( TT_Size size ) 405 { 406 TT_Face face = (TT_Face)size->root.face; 407 TT_ExecContext exec; 408 FT_Error error; 409 410 411 /* debugging instances have their own context */ 412 if ( size->debug ) 413 exec = size->context; 414 else 415 exec = ( (TT_Driver)FT_FACE_DRIVER( face ) )->context; 416 417 if ( !exec ) 418 return TT_Err_Could_Not_Find_Context; 419 420 TT_Load_Context( exec, face, size ); 421 422 exec->callTop = 0; 423 exec->top = 0; 424 425 exec->period = 64; 426 exec->phase = 0; 427 exec->threshold = 0; 428 429 exec->instruction_trap = FALSE; 430 exec->F_dot_P = 0x10000L; 431 432 { 433 FT_Size_Metrics* metrics = &exec->metrics; 434 TT_Size_Metrics* tt_metrics = &exec->tt_metrics; 435 436 437 metrics->x_ppem = 0; 438 metrics->y_ppem = 0; 439 metrics->x_scale = 0; 440 metrics->y_scale = 0; 441 442 tt_metrics->ppem = 0; 443 tt_metrics->scale = 0; 444 tt_metrics->ratio = 0x10000L; 445 } 446 447 /* allow font program execution */ 448 TT_Set_CodeRange( exec, 449 tt_coderange_font, 450 face->font_program, 451 face->font_program_size ); 452 453 /* disable CVT and glyph programs coderange */ 454 TT_Clear_CodeRange( exec, tt_coderange_cvt ); 455 TT_Clear_CodeRange( exec, tt_coderange_glyph ); 456 457 if ( face->font_program_size > 0 ) 458 { 459 error = TT_Goto_CodeRange( exec, tt_coderange_font, 0 ); 460 461 if ( !error ) 462 error = face->interpreter( exec ); 463 } 464 else 465 error = TT_Err_Ok; 466 467 if ( !error ) 468 TT_Save_Context( exec, size ); 469 470 return error; 471 } 472 473 474 /*************************************************************************/ 475 /* */ 476 /* <Function> */ 477 /* tt_size_run_prep */ 478 /* */ 479 /* <Description> */ 480 /* Run the control value program. */ 481 /* */ 482 /* <Input> */ 483 /* size :: A handle to the size object. */ 484 /* */ 485 /* <Return> */ 486 /* FreeType error code. 0 means success. */ 487 /* */ 488 FT_LOCAL_DEF( FT_Error ) tt_size_run_prep(TT_Size size)489 tt_size_run_prep( TT_Size size ) 490 { 491 TT_Face face = (TT_Face)size->root.face; 492 TT_ExecContext exec; 493 FT_Error error; 494 495 496 /* debugging instances have their own context */ 497 if ( size->debug ) 498 exec = size->context; 499 else 500 exec = ( (TT_Driver)FT_FACE_DRIVER( face ) )->context; 501 502 if ( !exec ) 503 return TT_Err_Could_Not_Find_Context; 504 505 TT_Load_Context( exec, face, size ); 506 507 exec->callTop = 0; 508 exec->top = 0; 509 510 exec->instruction_trap = FALSE; 511 512 TT_Set_CodeRange( exec, 513 tt_coderange_cvt, 514 face->cvt_program, 515 face->cvt_program_size ); 516 517 TT_Clear_CodeRange( exec, tt_coderange_glyph ); 518 519 if ( face->cvt_program_size > 0 ) 520 { 521 error = TT_Goto_CodeRange( exec, tt_coderange_cvt, 0 ); 522 523 if ( !error && !size->debug ) 524 error = face->interpreter( exec ); 525 } 526 else 527 error = TT_Err_Ok; 528 529 /* save as default graphics state */ 530 size->GS = exec->GS; 531 532 TT_Save_Context( exec, size ); 533 534 return error; 535 } 536 537 #endif /* TT_USE_BYTECODE_INTERPRETER */ 538 539 540 #ifdef TT_USE_BYTECODE_INTERPRETER 541 542 static void tt_size_done_bytecode(FT_Size ftsize)543 tt_size_done_bytecode( FT_Size ftsize ) 544 { 545 TT_Size size = (TT_Size)ftsize; 546 TT_Face face = (TT_Face)ftsize->face; 547 FT_Memory memory = face->root.memory; 548 549 550 if ( size->debug ) 551 { 552 /* the debug context must be deleted by the debugger itself */ 553 size->context = NULL; 554 size->debug = FALSE; 555 } 556 557 FT_FREE( size->cvt ); 558 size->cvt_size = 0; 559 560 /* free storage area */ 561 FT_FREE( size->storage ); 562 size->storage_size = 0; 563 564 /* twilight zone */ 565 tt_glyphzone_done( &size->twilight ); 566 567 FT_FREE( size->function_defs ); 568 FT_FREE( size->instruction_defs ); 569 570 size->num_function_defs = 0; 571 size->max_function_defs = 0; 572 size->num_instruction_defs = 0; 573 size->max_instruction_defs = 0; 574 575 size->max_func = 0; 576 size->max_ins = 0; 577 578 size->bytecode_ready = 0; 579 size->cvt_ready = 0; 580 } 581 582 583 /* Initialize bytecode-related fields in the size object. */ 584 /* We do this only if bytecode interpretation is really needed. */ 585 static FT_Error tt_size_init_bytecode(FT_Size ftsize)586 tt_size_init_bytecode( FT_Size ftsize ) 587 { 588 FT_Error error; 589 TT_Size size = (TT_Size)ftsize; 590 TT_Face face = (TT_Face)ftsize->face; 591 FT_Memory memory = face->root.memory; 592 FT_Int i; 593 594 FT_UShort n_twilight; 595 TT_MaxProfile* maxp = &face->max_profile; 596 597 598 size->bytecode_ready = 1; 599 size->cvt_ready = 0; 600 601 size->max_function_defs = maxp->maxFunctionDefs; 602 size->max_instruction_defs = maxp->maxInstructionDefs; 603 604 size->num_function_defs = 0; 605 size->num_instruction_defs = 0; 606 607 size->max_func = 0; 608 size->max_ins = 0; 609 610 size->cvt_size = face->cvt_size; 611 size->storage_size = maxp->maxStorage; 612 613 /* Set default metrics */ 614 { 615 FT_Size_Metrics* metrics = &size->metrics; 616 TT_Size_Metrics* metrics2 = &size->ttmetrics; 617 618 metrics->x_ppem = 0; 619 metrics->y_ppem = 0; 620 621 metrics2->rotated = FALSE; 622 metrics2->stretched = FALSE; 623 624 /* set default compensation (all 0) */ 625 for ( i = 0; i < 4; i++ ) 626 metrics2->compensations[i] = 0; 627 } 628 629 /* allocate function defs, instruction defs, cvt, and storage area */ 630 if ( FT_NEW_ARRAY( size->function_defs, size->max_function_defs ) || 631 FT_NEW_ARRAY( size->instruction_defs, size->max_instruction_defs ) || 632 FT_NEW_ARRAY( size->cvt, size->cvt_size ) || 633 FT_NEW_ARRAY( size->storage, size->storage_size ) ) 634 goto Exit; 635 636 /* reserve twilight zone */ 637 n_twilight = maxp->maxTwilightPoints; 638 639 /* there are 4 phantom points (do we need this?) */ 640 n_twilight += 4; 641 642 error = tt_glyphzone_new( memory, n_twilight, 0, &size->twilight ); 643 if ( error ) 644 goto Exit; 645 646 size->twilight.n_points = n_twilight; 647 648 size->GS = tt_default_graphics_state; 649 650 /* set `face->interpreter' according to the debug hook present */ 651 { 652 FT_Library library = face->root.driver->root.library; 653 654 655 face->interpreter = (TT_Interpreter) 656 library->debug_hooks[FT_DEBUG_HOOK_TRUETYPE]; 657 if ( !face->interpreter ) 658 face->interpreter = (TT_Interpreter)TT_RunIns; 659 } 660 661 /* Fine, now run the font program! */ 662 error = tt_size_run_fpgm( size ); 663 664 Exit: 665 if ( error ) 666 tt_size_done_bytecode( ftsize ); 667 668 return error; 669 } 670 671 672 FT_LOCAL_DEF( FT_Error ) tt_size_ready_bytecode(TT_Size size)673 tt_size_ready_bytecode( TT_Size size ) 674 { 675 FT_Error error = TT_Err_Ok; 676 677 678 if ( !size->bytecode_ready ) 679 { 680 error = tt_size_init_bytecode( (FT_Size)size ); 681 if ( error ) 682 goto Exit; 683 } 684 685 /* rescale CVT when needed */ 686 if ( !size->cvt_ready ) 687 { 688 FT_UInt i; 689 TT_Face face = (TT_Face)size->root.face; 690 691 692 /* Scale the cvt values to the new ppem. */ 693 /* We use by default the y ppem to scale the CVT. */ 694 for ( i = 0; i < size->cvt_size; i++ ) 695 size->cvt[i] = FT_MulFix( face->cvt[i], size->ttmetrics.scale ); 696 697 /* all twilight points are originally zero */ 698 for ( i = 0; i < (FT_UInt)size->twilight.n_points; i++ ) 699 { 700 size->twilight.org[i].x = 0; 701 size->twilight.org[i].y = 0; 702 size->twilight.cur[i].x = 0; 703 size->twilight.cur[i].y = 0; 704 } 705 706 /* clear storage area */ 707 for ( i = 0; i < (FT_UInt)size->storage_size; i++ ) 708 size->storage[i] = 0; 709 710 size->GS = tt_default_graphics_state; 711 712 error = tt_size_run_prep( size ); 713 if ( !error ) 714 size->cvt_ready = 1; 715 } 716 717 Exit: 718 return error; 719 } 720 721 #endif /* TT_USE_BYTECODE_INTERPRETER */ 722 723 724 /*************************************************************************/ 725 /* */ 726 /* <Function> */ 727 /* tt_size_init */ 728 /* */ 729 /* <Description> */ 730 /* Initialize a new TrueType size object. */ 731 /* */ 732 /* <InOut> */ 733 /* size :: A handle to the size object. */ 734 /* */ 735 /* <Return> */ 736 /* FreeType error code. 0 means success. */ 737 /* */ 738 FT_LOCAL_DEF( FT_Error ) tt_size_init(FT_Size ttsize)739 tt_size_init( FT_Size ttsize ) /* TT_Size */ 740 { 741 TT_Size size = (TT_Size)ttsize; 742 FT_Error error = TT_Err_Ok; 743 744 #ifdef TT_USE_BYTECODE_INTERPRETER 745 size->bytecode_ready = 0; 746 size->cvt_ready = 0; 747 #endif 748 749 size->ttmetrics.valid = FALSE; 750 size->strike_index = 0xFFFFFFFFUL; 751 752 return error; 753 } 754 755 756 /*************************************************************************/ 757 /* */ 758 /* <Function> */ 759 /* tt_size_done */ 760 /* */ 761 /* <Description> */ 762 /* The TrueType size object finalizer. */ 763 /* */ 764 /* <Input> */ 765 /* size :: A handle to the target size object. */ 766 /* */ 767 FT_LOCAL_DEF( void ) tt_size_done(FT_Size ttsize)768 tt_size_done( FT_Size ttsize ) /* TT_Size */ 769 { 770 TT_Size size = (TT_Size)ttsize; 771 772 773 #ifdef TT_USE_BYTECODE_INTERPRETER 774 if ( size->bytecode_ready ) 775 tt_size_done_bytecode( ttsize ); 776 #endif 777 778 size->ttmetrics.valid = FALSE; 779 } 780 781 782 /*************************************************************************/ 783 /* */ 784 /* <Function> */ 785 /* tt_size_reset */ 786 /* */ 787 /* <Description> */ 788 /* Reset a TrueType size when resolutions and character dimensions */ 789 /* have been changed. */ 790 /* */ 791 /* <Input> */ 792 /* size :: A handle to the target size object. */ 793 /* */ 794 FT_LOCAL_DEF( FT_Error ) tt_size_reset(TT_Size size)795 tt_size_reset( TT_Size size ) 796 { 797 TT_Face face; 798 FT_Error error = TT_Err_Ok; 799 FT_Size_Metrics* metrics; 800 801 802 size->ttmetrics.valid = FALSE; 803 804 face = (TT_Face)size->root.face; 805 806 metrics = &size->metrics; 807 808 /* copy the result from base layer */ 809 *metrics = size->root.metrics; 810 811 if ( metrics->x_ppem < 1 || metrics->y_ppem < 1 ) 812 return TT_Err_Invalid_PPem; 813 814 /* This bit flag, if set, indicates that the ppems must be */ 815 /* rounded to integers. Nearly all TrueType fonts have this bit */ 816 /* set, as hinting won't work really well otherwise. */ 817 /* */ 818 if ( face->header.Flags & 8 ) 819 { 820 metrics->x_scale = FT_DivFix( metrics->x_ppem << 6, 821 face->root.units_per_EM ); 822 metrics->y_scale = FT_DivFix( metrics->y_ppem << 6, 823 face->root.units_per_EM ); 824 825 metrics->ascender = 826 FT_PIX_ROUND( FT_MulFix( face->root.ascender, metrics->y_scale ) ); 827 metrics->descender = 828 FT_PIX_ROUND( FT_MulFix( face->root.descender, metrics->y_scale ) ); 829 metrics->height = 830 FT_PIX_ROUND( FT_MulFix( face->root.height, metrics->y_scale ) ); 831 metrics->max_advance = 832 FT_PIX_ROUND( FT_MulFix( face->root.max_advance_width, 833 metrics->x_scale ) ); 834 } 835 836 /* compute new transformation */ 837 if ( metrics->x_ppem >= metrics->y_ppem ) 838 { 839 size->ttmetrics.scale = metrics->x_scale; 840 size->ttmetrics.ppem = metrics->x_ppem; 841 size->ttmetrics.x_ratio = 0x10000L; 842 size->ttmetrics.y_ratio = FT_MulDiv( metrics->y_ppem, 843 0x10000L, 844 metrics->x_ppem ); 845 } 846 else 847 { 848 size->ttmetrics.scale = metrics->y_scale; 849 size->ttmetrics.ppem = metrics->y_ppem; 850 size->ttmetrics.x_ratio = FT_MulDiv( metrics->x_ppem, 851 0x10000L, 852 metrics->y_ppem ); 853 size->ttmetrics.y_ratio = 0x10000L; 854 } 855 856 #ifdef TT_USE_BYTECODE_INTERPRETER 857 size->cvt_ready = 0; 858 #endif /* TT_USE_BYTECODE_INTERPRETER */ 859 860 if ( !error ) 861 size->ttmetrics.valid = TRUE; 862 863 return error; 864 } 865 866 867 /*************************************************************************/ 868 /* */ 869 /* <Function> */ 870 /* tt_driver_init */ 871 /* */ 872 /* <Description> */ 873 /* Initialize a given TrueType driver object. */ 874 /* */ 875 /* <Input> */ 876 /* driver :: A handle to the target driver object. */ 877 /* */ 878 /* <Return> */ 879 /* FreeType error code. 0 means success. */ 880 /* */ 881 FT_LOCAL_DEF( FT_Error ) tt_driver_init(FT_Module ttdriver)882 tt_driver_init( FT_Module ttdriver ) /* TT_Driver */ 883 { 884 885 #ifdef TT_USE_BYTECODE_INTERPRETER 886 887 TT_Driver driver = (TT_Driver)ttdriver; 888 889 890 if ( !TT_New_Context( driver ) ) 891 return TT_Err_Could_Not_Find_Context; 892 893 #else 894 895 FT_UNUSED( ttdriver ); 896 897 #endif 898 899 return TT_Err_Ok; 900 } 901 902 903 /*************************************************************************/ 904 /* */ 905 /* <Function> */ 906 /* tt_driver_done */ 907 /* */ 908 /* <Description> */ 909 /* Finalize a given TrueType driver. */ 910 /* */ 911 /* <Input> */ 912 /* driver :: A handle to the target TrueType driver. */ 913 /* */ 914 FT_LOCAL_DEF( void ) tt_driver_done(FT_Module ttdriver)915 tt_driver_done( FT_Module ttdriver ) /* TT_Driver */ 916 { 917 #ifdef TT_USE_BYTECODE_INTERPRETER 918 TT_Driver driver = (TT_Driver)ttdriver; 919 920 921 /* destroy the execution context */ 922 if ( driver->context ) 923 { 924 TT_Done_Context( driver->context ); 925 driver->context = NULL; 926 } 927 #else 928 FT_UNUSED( ttdriver ); 929 #endif 930 931 } 932 933 934 /*************************************************************************/ 935 /* */ 936 /* <Function> */ 937 /* tt_slot_init */ 938 /* */ 939 /* <Description> */ 940 /* Initialize a new slot object. */ 941 /* */ 942 /* <InOut> */ 943 /* slot :: A handle to the slot object. */ 944 /* */ 945 /* <Return> */ 946 /* FreeType error code. 0 means success. */ 947 /* */ 948 FT_LOCAL_DEF( FT_Error ) tt_slot_init(FT_GlyphSlot slot)949 tt_slot_init( FT_GlyphSlot slot ) 950 { 951 return FT_GlyphLoader_CreateExtra( slot->internal->loader ); 952 } 953 954 955 /* END */ 956