| OLD | NEW |
| 1 /***************************************************************************/ | 1 /***************************************************************************/ |
| 2 /* */ | 2 /* */ |
| 3 /* ttinterp.c */ | 3 /* ttinterp.c */ |
| 4 /* */ | 4 /* */ |
| 5 /* TrueType bytecode interpreter (body). */ | 5 /* TrueType bytecode interpreter (body). */ |
| 6 /* */ | 6 /* */ |
| 7 /* Copyright 1996-2012 */ | 7 /* Copyright 1996-2013 */ |
| 8 /* by David Turner, Robert Wilhelm, and Werner Lemberg. */ | 8 /* by David Turner, Robert Wilhelm, and Werner Lemberg. */ |
| 9 /* */ | 9 /* */ |
| 10 /* This file is part of the FreeType project, and may only be used, */ | 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 */ | 11 /* modified, and distributed under the terms of the FreeType project */ |
| 12 /* license, LICENSE.TXT. By continuing to use, modify, or distribute */ | 12 /* license, LICENSE.TXT. By continuing to use, modify, or distribute */ |
| 13 /* this file you indicate that you have read the license and */ | 13 /* this file you indicate that you have read the license and */ |
| 14 /* understand and accept it fully. */ | 14 /* understand and accept it fully. */ |
| 15 /* */ | 15 /* */ |
| 16 /***************************************************************************/ | 16 /***************************************************************************/ |
| 17 | 17 |
| 18 | 18 |
| 19 /* Greg Hitchcock from Microsoft has helped a lot in resolving unclear */ | 19 /* Greg Hitchcock from Microsoft has helped a lot in resolving unclear */ |
| 20 /* issues; many thanks! */ | 20 /* issues; many thanks! */ |
| 21 | 21 |
| 22 | 22 |
| 23 #include <ft2build.h> | 23 #include <ft2build.h> |
| 24 #include FT_INTERNAL_DEBUG_H | 24 #include FT_INTERNAL_DEBUG_H |
| 25 #include FT_INTERNAL_CALC_H | 25 #include FT_INTERNAL_CALC_H |
| 26 #include FT_TRIGONOMETRY_H | 26 #include FT_TRIGONOMETRY_H |
| 27 #include FT_SYSTEM_H | 27 #include FT_SYSTEM_H |
| 28 #include FT_TRUETYPE_DRIVER_H |
| 28 | 29 |
| 29 #include "ttinterp.h" | 30 #include "ttinterp.h" |
| 30 | |
| 31 #include "tterrors.h" | 31 #include "tterrors.h" |
| 32 #include "ttsubpix.h" |
| 32 | 33 |
| 33 | 34 |
| 34 #ifdef TT_USE_BYTECODE_INTERPRETER | 35 #ifdef TT_USE_BYTECODE_INTERPRETER |
| 35 | 36 |
| 36 | 37 |
| 37 #define TT_MULFIX FT_MulFix | |
| 38 #define TT_MULDIV FT_MulDiv | |
| 39 #define TT_MULDIV_NO_ROUND FT_MulDiv_No_Round | |
| 40 | |
| 41 | |
| 42 /*************************************************************************/ | 38 /*************************************************************************/ |
| 43 /* */ | 39 /* */ |
| 44 /* The macro FT_COMPONENT is used in trace mode. It is an implicit */ | 40 /* The macro FT_COMPONENT is used in trace mode. It is an implicit */ |
| 45 /* parameter of the FT_TRACE() and FT_ERROR() macros, used to print/log */ | 41 /* parameter of the FT_TRACE() and FT_ERROR() macros, used to print/log */ |
| 46 /* messages during execution. */ | 42 /* messages during execution. */ |
| 47 /* */ | 43 /* */ |
| 48 #undef FT_COMPONENT | 44 #undef FT_COMPONENT |
| 49 #define FT_COMPONENT trace_ttinterp | 45 #define FT_COMPONENT trace_ttinterp |
| 50 | 46 |
| 51 /*************************************************************************/ | 47 /*************************************************************************/ |
| 52 /* */ | 48 /* */ |
| 53 /* In order to detect infinite loops in the code, we set up a counter */ | 49 /* In order to detect infinite loops in the code, we set up a counter */ |
| 54 /* within the run loop. A single stroke of interpretation is now */ | 50 /* within the run loop. A single stroke of interpretation is now */ |
| 55 /* limited to a maximal number of opcodes defined below. */ | 51 /* limited to a maximum number of opcodes defined below. */ |
| 56 /* */ | 52 /* */ |
| 57 #define MAX_RUNNABLE_OPCODES 1000000L | 53 #define MAX_RUNNABLE_OPCODES 1000000L |
| 58 | 54 |
| 59 | 55 |
| 60 /*************************************************************************/ | 56 /*************************************************************************/ |
| 61 /* */ | 57 /* */ |
| 62 /* There are two kinds of implementations: */ | 58 /* There are two kinds of implementations: */ |
| 63 /* */ | 59 /* */ |
| 64 /* a. static implementation */ | 60 /* a. static implementation */ |
| 65 /* */ | 61 /* */ |
| (...skipping 63 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 129 | 125 |
| 130 | 126 |
| 131 /*************************************************************************/ | 127 /*************************************************************************/ |
| 132 /* */ | 128 /* */ |
| 133 /* This macro is used whenever `args' is unused in a function, to avoid */ | 129 /* This macro is used whenever `args' is unused in a function, to avoid */ |
| 134 /* stupid warnings from pedantic compilers. */ | 130 /* stupid warnings from pedantic compilers. */ |
| 135 /* */ | 131 /* */ |
| 136 #define FT_UNUSED_ARG FT_UNUSED_EXEC; FT_UNUSED( args ) | 132 #define FT_UNUSED_ARG FT_UNUSED_EXEC; FT_UNUSED( args ) |
| 137 | 133 |
| 138 | 134 |
| 135 #define SUBPIXEL_HINTING \ |
| 136 ( ((TT_Driver)FT_FACE_DRIVER( CUR.face ))->interpreter_version == \ |
| 137 TT_INTERPRETER_VERSION_38 ) |
| 138 |
| 139 |
| 139 /*************************************************************************/ | 140 /*************************************************************************/ |
| 140 /* */ | 141 /* */ |
| 141 /* The following macros hide the use of EXEC_ARG and EXEC_ARG_ to */ | 142 /* The following macros hide the use of EXEC_ARG and EXEC_ARG_ to */ |
| 142 /* increase readability of the code. */ | 143 /* increase readability of the code. */ |
| 143 /* */ | 144 /* */ |
| 144 /*************************************************************************/ | 145 /*************************************************************************/ |
| 145 | 146 |
| 146 | 147 |
| 147 #define SKIP_Code() \ | 148 #define SKIP_Code() \ |
| 148 SkipCode( EXEC_ARG ) | 149 SkipCode( EXEC_ARG ) |
| (...skipping 76 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 225 typedef void (*TInstruction_Function)( INS_ARG ); | 226 typedef void (*TInstruction_Function)( INS_ARG ); |
| 226 | 227 |
| 227 | 228 |
| 228 /*************************************************************************/ | 229 /*************************************************************************/ |
| 229 /* */ | 230 /* */ |
| 230 /* Two simple bounds-checking macros. */ | 231 /* Two simple bounds-checking macros. */ |
| 231 /* */ | 232 /* */ |
| 232 #define BOUNDS( x, n ) ( (FT_UInt)(x) >= (FT_UInt)(n) ) | 233 #define BOUNDS( x, n ) ( (FT_UInt)(x) >= (FT_UInt)(n) ) |
| 233 #define BOUNDSL( x, n ) ( (FT_ULong)(x) >= (FT_ULong)(n) ) | 234 #define BOUNDSL( x, n ) ( (FT_ULong)(x) >= (FT_ULong)(n) ) |
| 234 | 235 |
| 236 /*************************************************************************/ |
| 237 /* */ |
| 238 /* This macro computes (a*2^14)/b and complements TT_MulFix14. */ |
| 239 /* */ |
| 240 #define TT_DivFix14( a, b ) \ |
| 241 FT_DivFix( a, (b) << 2 ) |
| 242 |
| 243 |
| 235 #undef SUCCESS | 244 #undef SUCCESS |
| 236 #define SUCCESS 0 | 245 #define SUCCESS 0 |
| 237 | 246 |
| 238 #undef FAILURE | 247 #undef FAILURE |
| 239 #define FAILURE 1 | 248 #define FAILURE 1 |
| 240 | 249 |
| 241 #ifdef TT_CONFIG_OPTION_UNPATENTED_HINTING | 250 #ifdef TT_CONFIG_OPTION_UNPATENTED_HINTING |
| 242 #define GUESS_VECTOR( V ) \ | 251 #define GUESS_VECTOR( V ) \ |
| 243 if ( CUR.face->unpatented_hinting ) \ | 252 if ( CUR.face->unpatented_hinting ) \ |
| 244 { \ | 253 { \ |
| (...skipping 49 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 294 /* which will return to the first byte *after* the code */ | 303 /* which will return to the first byte *after* the code */ |
| 295 /* range, we test for IP <= Size instead of IP < Size. */ | 304 /* range, we test for IP <= Size instead of IP < Size. */ |
| 296 /* */ | 305 /* */ |
| 297 FT_ASSERT( (FT_ULong)IP <= coderange->size ); | 306 FT_ASSERT( (FT_ULong)IP <= coderange->size ); |
| 298 | 307 |
| 299 exec->code = coderange->base; | 308 exec->code = coderange->base; |
| 300 exec->codeSize = coderange->size; | 309 exec->codeSize = coderange->size; |
| 301 exec->IP = IP; | 310 exec->IP = IP; |
| 302 exec->curRange = range; | 311 exec->curRange = range; |
| 303 | 312 |
| 304 return TT_Err_Ok; | 313 return FT_Err_Ok; |
| 305 } | 314 } |
| 306 | 315 |
| 307 | 316 |
| 308 /*************************************************************************/ | 317 /*************************************************************************/ |
| 309 /* */ | 318 /* */ |
| 310 /* <Function> */ | 319 /* <Function> */ |
| 311 /* TT_Set_CodeRange */ | 320 /* TT_Set_CodeRange */ |
| 312 /* */ | 321 /* */ |
| 313 /* <Description> */ | 322 /* <Description> */ |
| 314 /* Sets a code range. */ | 323 /* Sets a code range. */ |
| (...skipping 15 matching lines...) Expand all Loading... |
| 330 TT_Set_CodeRange( TT_ExecContext exec, | 339 TT_Set_CodeRange( TT_ExecContext exec, |
| 331 FT_Int range, | 340 FT_Int range, |
| 332 void* base, | 341 void* base, |
| 333 FT_Long length ) | 342 FT_Long length ) |
| 334 { | 343 { |
| 335 FT_ASSERT( range >= 1 && range <= 3 ); | 344 FT_ASSERT( range >= 1 && range <= 3 ); |
| 336 | 345 |
| 337 exec->codeRangeTable[range - 1].base = (FT_Byte*)base; | 346 exec->codeRangeTable[range - 1].base = (FT_Byte*)base; |
| 338 exec->codeRangeTable[range - 1].size = length; | 347 exec->codeRangeTable[range - 1].size = length; |
| 339 | 348 |
| 340 return TT_Err_Ok; | 349 return FT_Err_Ok; |
| 341 } | 350 } |
| 342 | 351 |
| 343 | 352 |
| 344 /*************************************************************************/ | 353 /*************************************************************************/ |
| 345 /* */ | 354 /* */ |
| 346 /* <Function> */ | 355 /* <Function> */ |
| 347 /* TT_Clear_CodeRange */ | 356 /* TT_Clear_CodeRange */ |
| 348 /* */ | 357 /* */ |
| 349 /* <Description> */ | 358 /* <Description> */ |
| 350 /* Clears a code range. */ | 359 /* Clears a code range. */ |
| (...skipping 12 matching lines...) Expand all Loading... |
| 363 /* */ | 372 /* */ |
| 364 FT_LOCAL_DEF( FT_Error ) | 373 FT_LOCAL_DEF( FT_Error ) |
| 365 TT_Clear_CodeRange( TT_ExecContext exec, | 374 TT_Clear_CodeRange( TT_ExecContext exec, |
| 366 FT_Int range ) | 375 FT_Int range ) |
| 367 { | 376 { |
| 368 FT_ASSERT( range >= 1 && range <= 3 ); | 377 FT_ASSERT( range >= 1 && range <= 3 ); |
| 369 | 378 |
| 370 exec->codeRangeTable[range - 1].base = NULL; | 379 exec->codeRangeTable[range - 1].base = NULL; |
| 371 exec->codeRangeTable[range - 1].size = 0; | 380 exec->codeRangeTable[range - 1].size = 0; |
| 372 | 381 |
| 373 return TT_Err_Ok; | 382 return FT_Err_Ok; |
| 374 } | 383 } |
| 375 | 384 |
| 376 | 385 |
| 377 /*************************************************************************/ | 386 /*************************************************************************/ |
| 378 /* */ | 387 /* */ |
| 379 /* EXECUTION CONTEXT ROUTINES */ | 388 /* EXECUTION CONTEXT ROUTINES */ |
| 380 /* */ | 389 /* */ |
| 381 /*************************************************************************/ | 390 /*************************************************************************/ |
| 382 | 391 |
| 383 | 392 |
| (...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 421 | 430 |
| 422 /* free glyph code range */ | 431 /* free glyph code range */ |
| 423 FT_FREE( exec->glyphIns ); | 432 FT_FREE( exec->glyphIns ); |
| 424 exec->glyphSize = 0; | 433 exec->glyphSize = 0; |
| 425 | 434 |
| 426 exec->size = NULL; | 435 exec->size = NULL; |
| 427 exec->face = NULL; | 436 exec->face = NULL; |
| 428 | 437 |
| 429 FT_FREE( exec ); | 438 FT_FREE( exec ); |
| 430 | 439 |
| 431 return TT_Err_Ok; | 440 return FT_Err_Ok; |
| 432 } | 441 } |
| 433 | 442 |
| 434 | 443 |
| 435 /*************************************************************************/ | 444 /*************************************************************************/ |
| 436 /* */ | 445 /* */ |
| 437 /* <Function> */ | 446 /* <Function> */ |
| 438 /* Init_Context */ | 447 /* Init_Context */ |
| 439 /* */ | 448 /* */ |
| 440 /* <Description> */ | 449 /* <Description> */ |
| 441 /* Initializes a context object. */ | 450 /* Initializes a context object. */ |
| (...skipping 29 matching lines...) Expand all Loading... |
| 471 | 480 |
| 472 exec->stackSize = 0; | 481 exec->stackSize = 0; |
| 473 exec->glyphSize = 0; | 482 exec->glyphSize = 0; |
| 474 | 483 |
| 475 exec->stack = NULL; | 484 exec->stack = NULL; |
| 476 exec->glyphIns = NULL; | 485 exec->glyphIns = NULL; |
| 477 | 486 |
| 478 exec->face = NULL; | 487 exec->face = NULL; |
| 479 exec->size = NULL; | 488 exec->size = NULL; |
| 480 | 489 |
| 481 return TT_Err_Ok; | 490 return FT_Err_Ok; |
| 482 | 491 |
| 483 Fail_Memory: | 492 Fail_Memory: |
| 484 FT_ERROR(( "Init_Context: not enough memory for %p\n", exec )); | 493 FT_ERROR(( "Init_Context: not enough memory for %p\n", exec )); |
| 485 TT_Done_Context( exec ); | 494 TT_Done_Context( exec ); |
| 486 | 495 |
| 487 return error; | 496 return error; |
| 488 } | 497 } |
| 489 | 498 |
| 490 | 499 |
| 491 /*************************************************************************/ | 500 /*************************************************************************/ |
| (...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 523 void** pbuff = (void**)_pbuff; | 532 void** pbuff = (void**)_pbuff; |
| 524 | 533 |
| 525 | 534 |
| 526 if ( *size < new_max ) | 535 if ( *size < new_max ) |
| 527 { | 536 { |
| 528 if ( FT_REALLOC( *pbuff, *size * multiplier, new_max * multiplier ) ) | 537 if ( FT_REALLOC( *pbuff, *size * multiplier, new_max * multiplier ) ) |
| 529 return error; | 538 return error; |
| 530 *size = new_max; | 539 *size = new_max; |
| 531 } | 540 } |
| 532 | 541 |
| 533 return TT_Err_Ok; | 542 return FT_Err_Ok; |
| 534 } | 543 } |
| 535 | 544 |
| 536 | 545 |
| 537 /*************************************************************************/ | 546 /*************************************************************************/ |
| 538 /* */ | 547 /* */ |
| 539 /* <Function> */ | 548 /* <Function> */ |
| 540 /* TT_Load_Context */ | 549 /* TT_Load_Context */ |
| 541 /* */ | 550 /* */ |
| 542 /* <Description> */ | 551 /* <Description> */ |
| 543 /* Prepare an execution context for glyph hinting. */ | 552 /* Prepare an execution context for glyph hinting. */ |
| (...skipping 86 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 630 | 639 |
| 631 exec->pts.n_points = 0; | 640 exec->pts.n_points = 0; |
| 632 exec->pts.n_contours = 0; | 641 exec->pts.n_contours = 0; |
| 633 | 642 |
| 634 exec->zp1 = exec->pts; | 643 exec->zp1 = exec->pts; |
| 635 exec->zp2 = exec->pts; | 644 exec->zp2 = exec->pts; |
| 636 exec->zp0 = exec->pts; | 645 exec->zp0 = exec->pts; |
| 637 | 646 |
| 638 exec->instruction_trap = FALSE; | 647 exec->instruction_trap = FALSE; |
| 639 | 648 |
| 640 return TT_Err_Ok; | 649 return FT_Err_Ok; |
| 641 } | 650 } |
| 642 | 651 |
| 643 | 652 |
| 644 /*************************************************************************/ | 653 /*************************************************************************/ |
| 645 /* */ | 654 /* */ |
| 646 /* <Function> */ | 655 /* <Function> */ |
| 647 /* TT_Save_Context */ | 656 /* TT_Save_Context */ |
| 648 /* */ | 657 /* */ |
| 649 /* <Description> */ | 658 /* <Description> */ |
| 650 /* Saves the code ranges in a `size' object. */ | 659 /* Saves the code ranges in a `size' object. */ |
| (...skipping 22 matching lines...) Expand all Loading... |
| 673 /* */ | 682 /* */ |
| 674 size->num_function_defs = exec->numFDefs; | 683 size->num_function_defs = exec->numFDefs; |
| 675 size->num_instruction_defs = exec->numIDefs; | 684 size->num_instruction_defs = exec->numIDefs; |
| 676 | 685 |
| 677 size->max_func = exec->maxFunc; | 686 size->max_func = exec->maxFunc; |
| 678 size->max_ins = exec->maxIns; | 687 size->max_ins = exec->maxIns; |
| 679 | 688 |
| 680 for ( i = 0; i < TT_MAX_CODE_RANGES; i++ ) | 689 for ( i = 0; i < TT_MAX_CODE_RANGES; i++ ) |
| 681 size->codeRangeTable[i] = exec->codeRangeTable[i]; | 690 size->codeRangeTable[i] = exec->codeRangeTable[i]; |
| 682 | 691 |
| 683 return TT_Err_Ok; | 692 return FT_Err_Ok; |
| 684 } | 693 } |
| 685 | 694 |
| 686 | 695 |
| 687 /*************************************************************************/ | 696 /*************************************************************************/ |
| 688 /* */ | 697 /* */ |
| 689 /* <Function> */ | 698 /* <Function> */ |
| 690 /* TT_Run_Context */ | 699 /* TT_Run_Context */ |
| 691 /* */ | 700 /* */ |
| 692 /* <Description> */ | 701 /* <Description> */ |
| 693 /* Executes one or more instructions in the execution context. */ | 702 /* Executes one or more instructions in the execution context. */ |
| (...skipping 15 matching lines...) Expand all Loading... |
| 709 /* Only the glyph loader and debugger should call this function. */ | 718 /* Only the glyph loader and debugger should call this function. */ |
| 710 /* */ | 719 /* */ |
| 711 FT_LOCAL_DEF( FT_Error ) | 720 FT_LOCAL_DEF( FT_Error ) |
| 712 TT_Run_Context( TT_ExecContext exec, | 721 TT_Run_Context( TT_ExecContext exec, |
| 713 FT_Bool debug ) | 722 FT_Bool debug ) |
| 714 { | 723 { |
| 715 FT_Error error; | 724 FT_Error error; |
| 716 | 725 |
| 717 | 726 |
| 718 if ( ( error = TT_Goto_CodeRange( exec, tt_coderange_glyph, 0 ) ) | 727 if ( ( error = TT_Goto_CodeRange( exec, tt_coderange_glyph, 0 ) ) |
| 719 != TT_Err_Ok ) | 728 != FT_Err_Ok ) |
| 720 return error; | 729 return error; |
| 721 | 730 |
| 722 exec->zp0 = exec->pts; | 731 exec->zp0 = exec->pts; |
| 723 exec->zp1 = exec->pts; | 732 exec->zp1 = exec->pts; |
| 724 exec->zp2 = exec->pts; | 733 exec->zp2 = exec->pts; |
| 725 | 734 |
| 726 exec->GS.gep0 = 1; | 735 exec->GS.gep0 = 1; |
| 727 exec->GS.gep1 = 1; | 736 exec->GS.gep1 = 1; |
| 728 exec->GS.gep2 = 1; | 737 exec->GS.gep2 = 1; |
| 729 | 738 |
| (...skipping 16 matching lines...) Expand all Loading... |
| 746 exec->callTop = 0; | 755 exec->callTop = 0; |
| 747 | 756 |
| 748 #if 1 | 757 #if 1 |
| 749 FT_UNUSED( debug ); | 758 FT_UNUSED( debug ); |
| 750 | 759 |
| 751 return exec->face->interpreter( exec ); | 760 return exec->face->interpreter( exec ); |
| 752 #else | 761 #else |
| 753 if ( !debug ) | 762 if ( !debug ) |
| 754 return TT_RunIns( exec ); | 763 return TT_RunIns( exec ); |
| 755 else | 764 else |
| 756 return TT_Err_Ok; | 765 return FT_Err_Ok; |
| 757 #endif | 766 #endif |
| 758 } | 767 } |
| 759 | 768 |
| 760 | 769 |
| 761 /* The default value for `scan_control' is documented as FALSE in the */ | 770 /* The default value for `scan_control' is documented as FALSE in the */ |
| 762 /* TrueType specification. This is confusing since it implies a */ | 771 /* TrueType specification. This is confusing since it implies a */ |
| 763 /* Boolean value. However, this is not the case, thus both the */ | 772 /* Boolean value. However, this is not the case, thus both the */ |
| 764 /* default values of our `scan_type' and `scan_control' fields (which */ | 773 /* default values of our `scan_type' and `scan_control' fields (which */ |
| 765 /* the documentation's `scan_control' variable is split into) are */ | 774 /* the documentation's `scan_control' variable is split into) are */ |
| 766 /* zero. */ | 775 /* zero. */ |
| (...skipping 689 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1456 if ( lo < mid ) | 1465 if ( lo < mid ) |
| 1457 hi += 1; | 1466 hi += 1; |
| 1458 | 1467 |
| 1459 mid = ( lo >> 14 ) | ( hi << 18 ); | 1468 mid = ( lo >> 14 ) | ( hi << 18 ); |
| 1460 | 1469 |
| 1461 return sign >= 0 ? (FT_Int32)mid : -(FT_Int32)mid; | 1470 return sign >= 0 ? (FT_Int32)mid : -(FT_Int32)mid; |
| 1462 } | 1471 } |
| 1463 | 1472 |
| 1464 #else | 1473 #else |
| 1465 | 1474 |
| 1466 /* compute (a*b)/2^14 with maximal accuracy and rounding */ | 1475 /* compute (a*b)/2^14 with maximum accuracy and rounding */ |
| 1467 static FT_Int32 | 1476 static FT_Int32 |
| 1468 TT_MulFix14( FT_Int32 a, | 1477 TT_MulFix14( FT_Int32 a, |
| 1469 FT_Int b ) | 1478 FT_Int b ) |
| 1470 { | 1479 { |
| 1471 FT_Int32 m, s, hi; | 1480 FT_Int32 m, s, hi; |
| 1472 FT_UInt32 l, lo; | 1481 FT_UInt32 l, lo; |
| 1473 | 1482 |
| 1474 | 1483 |
| 1475 /* compute ax*bx as 64-bit value */ | 1484 /* compute ax*bx as 64-bit value */ |
| 1476 l = (FT_UInt32)( ( a & 0xFFFFU ) * b ); | 1485 l = (FT_UInt32)( ( a & 0xFFFFU ) * b ); |
| 1477 m = ( a >> 16 ) * b; | 1486 m = ( a >> 16 ) * b; |
| 1478 | 1487 |
| 1479 lo = l + (FT_UInt32)( m << 16 ); | 1488 lo = l + ( (FT_UInt32)m << 16 ); |
| 1480 hi = ( m >> 16 ) + ( (FT_Int32)l >> 31 ) + ( lo < l ); | 1489 hi = ( m >> 16 ) + ( (FT_Int32)l >> 31 ) + ( lo < l ); |
| 1481 | 1490 |
| 1482 /* divide the result by 2^14 with rounding */ | 1491 /* divide the result by 2^14 with rounding */ |
| 1483 s = hi >> 31; | 1492 s = hi >> 31; |
| 1484 l = lo + (FT_UInt32)s; | 1493 l = lo + (FT_UInt32)s; |
| 1485 hi += s + ( l < lo ); | 1494 hi += s + ( l < lo ); |
| 1486 lo = l; | 1495 lo = l; |
| 1487 | 1496 |
| 1488 l = lo + 0x2000U; | 1497 l = lo + 0x2000U; |
| 1489 hi += l < lo; | 1498 hi += l < lo; |
| 1490 | 1499 |
| 1491 return ( hi << 18 ) | ( l >> 14 ); | 1500 return (FT_Int32)( ( (FT_UInt32)hi << 18 ) | ( l >> 14 ) ); |
| 1492 } | 1501 } |
| 1493 #endif | 1502 #endif |
| 1494 | 1503 |
| 1495 | 1504 |
| 1496 /* compute (ax*bx+ay*by)/2^14 with maximal accuracy and rounding */ | 1505 /* compute (ax*bx+ay*by)/2^14 with maximum accuracy and rounding */ |
| 1497 static FT_Int32 | 1506 static FT_Int32 |
| 1498 TT_DotFix14( FT_Int32 ax, | 1507 TT_DotFix14( FT_Int32 ax, |
| 1499 FT_Int32 ay, | 1508 FT_Int32 ay, |
| 1500 FT_Int bx, | 1509 FT_Int bx, |
| 1501 FT_Int by ) | 1510 FT_Int by ) |
| 1502 { | 1511 { |
| 1503 FT_Int32 m, s, hi1, hi2, hi; | 1512 FT_Int32 m, s, hi1, hi2, hi; |
| 1504 FT_UInt32 l, lo1, lo2, lo; | 1513 FT_UInt32 l, lo1, lo2, lo; |
| 1505 | 1514 |
| 1506 | 1515 |
| 1507 /* compute ax*bx as 64-bit value */ | 1516 /* compute ax*bx as 64-bit value */ |
| 1508 l = (FT_UInt32)( ( ax & 0xFFFFU ) * bx ); | 1517 l = (FT_UInt32)( ( ax & 0xFFFFU ) * bx ); |
| 1509 m = ( ax >> 16 ) * bx; | 1518 m = ( ax >> 16 ) * bx; |
| 1510 | 1519 |
| 1511 lo1 = l + (FT_UInt32)( m << 16 ); | 1520 lo1 = l + ( (FT_UInt32)m << 16 ); |
| 1512 hi1 = ( m >> 16 ) + ( (FT_Int32)l >> 31 ) + ( lo1 < l ); | 1521 hi1 = ( m >> 16 ) + ( (FT_Int32)l >> 31 ) + ( lo1 < l ); |
| 1513 | 1522 |
| 1514 /* compute ay*by as 64-bit value */ | 1523 /* compute ay*by as 64-bit value */ |
| 1515 l = (FT_UInt32)( ( ay & 0xFFFFU ) * by ); | 1524 l = (FT_UInt32)( ( ay & 0xFFFFU ) * by ); |
| 1516 m = ( ay >> 16 ) * by; | 1525 m = ( ay >> 16 ) * by; |
| 1517 | 1526 |
| 1518 lo2 = l + (FT_UInt32)( m << 16 ); | 1527 lo2 = l + ( (FT_UInt32)m << 16 ); |
| 1519 hi2 = ( m >> 16 ) + ( (FT_Int32)l >> 31 ) + ( lo2 < l ); | 1528 hi2 = ( m >> 16 ) + ( (FT_Int32)l >> 31 ) + ( lo2 < l ); |
| 1520 | 1529 |
| 1521 /* add them */ | 1530 /* add them */ |
| 1522 lo = lo1 + lo2; | 1531 lo = lo1 + lo2; |
| 1523 hi = hi1 + hi2 + ( lo < lo1 ); | 1532 hi = hi1 + hi2 + ( lo < lo1 ); |
| 1524 | 1533 |
| 1525 /* divide the result by 2^14 with rounding */ | 1534 /* divide the result by 2^14 with rounding */ |
| 1526 s = hi >> 31; | 1535 s = hi >> 31; |
| 1527 l = lo + (FT_UInt32)s; | 1536 l = lo + (FT_UInt32)s; |
| 1528 hi += s + ( l < lo ); | 1537 hi += s + ( l < lo ); |
| 1529 lo = l; | 1538 lo = l; |
| 1530 | 1539 |
| 1531 l = lo + 0x2000U; | 1540 l = lo + 0x2000U; |
| 1532 hi += ( l < lo ); | 1541 hi += ( l < lo ); |
| 1533 | 1542 |
| 1534 return ( hi << 18 ) | ( l >> 14 ); | 1543 return (FT_Int32)( ( (FT_UInt32)hi << 18 ) | ( l >> 14 ) ); |
| 1535 } | 1544 } |
| 1536 | 1545 |
| 1537 | 1546 |
| 1538 /* return length of given vector */ | |
| 1539 | |
| 1540 #if 0 | |
| 1541 | |
| 1542 static FT_Int32 | |
| 1543 TT_VecLen( FT_Int32 x, | |
| 1544 FT_Int32 y ) | |
| 1545 { | |
| 1546 FT_Int32 m, hi1, hi2, hi; | |
| 1547 FT_UInt32 l, lo1, lo2, lo; | |
| 1548 | |
| 1549 | |
| 1550 /* compute x*x as 64-bit value */ | |
| 1551 lo = (FT_UInt32)( x & 0xFFFFU ); | |
| 1552 hi = x >> 16; | |
| 1553 | |
| 1554 l = lo * lo; | |
| 1555 m = hi * lo; | |
| 1556 hi = hi * hi; | |
| 1557 | |
| 1558 lo1 = l + (FT_UInt32)( m << 17 ); | |
| 1559 hi1 = hi + ( m >> 15 ) + ( lo1 < l ); | |
| 1560 | |
| 1561 /* compute y*y as 64-bit value */ | |
| 1562 lo = (FT_UInt32)( y & 0xFFFFU ); | |
| 1563 hi = y >> 16; | |
| 1564 | |
| 1565 l = lo * lo; | |
| 1566 m = hi * lo; | |
| 1567 hi = hi * hi; | |
| 1568 | |
| 1569 lo2 = l + (FT_UInt32)( m << 17 ); | |
| 1570 hi2 = hi + ( m >> 15 ) + ( lo2 < l ); | |
| 1571 | |
| 1572 /* add them to get 'x*x+y*y' as 64-bit value */ | |
| 1573 lo = lo1 + lo2; | |
| 1574 hi = hi1 + hi2 + ( lo < lo1 ); | |
| 1575 | |
| 1576 /* compute the square root of this value */ | |
| 1577 { | |
| 1578 FT_UInt32 root, rem, test_div; | |
| 1579 FT_Int count; | |
| 1580 | |
| 1581 | |
| 1582 root = 0; | |
| 1583 | |
| 1584 { | |
| 1585 rem = 0; | |
| 1586 count = 32; | |
| 1587 do | |
| 1588 { | |
| 1589 rem = ( rem << 2 ) | ( (FT_UInt32)hi >> 30 ); | |
| 1590 hi = ( hi << 2 ) | ( lo >> 30 ); | |
| 1591 lo <<= 2; | |
| 1592 root <<= 1; | |
| 1593 test_div = ( root << 1 ) + 1; | |
| 1594 | |
| 1595 if ( rem >= test_div ) | |
| 1596 { | |
| 1597 rem -= test_div; | |
| 1598 root += 1; | |
| 1599 } | |
| 1600 } while ( --count ); | |
| 1601 } | |
| 1602 | |
| 1603 return (FT_Int32)root; | |
| 1604 } | |
| 1605 } | |
| 1606 | |
| 1607 #else | |
| 1608 | |
| 1609 /* this version uses FT_Vector_Length which computes the same value */ | |
| 1610 /* much, much faster.. */ | |
| 1611 /* */ | |
| 1612 static FT_F26Dot6 | |
| 1613 TT_VecLen( FT_F26Dot6 X, | |
| 1614 FT_F26Dot6 Y ) | |
| 1615 { | |
| 1616 FT_Vector v; | |
| 1617 | |
| 1618 | |
| 1619 v.x = X; | |
| 1620 v.y = Y; | |
| 1621 | |
| 1622 return FT_Vector_Length( &v ); | |
| 1623 } | |
| 1624 | |
| 1625 #endif | |
| 1626 | |
| 1627 | |
| 1628 /*************************************************************************/ | 1547 /*************************************************************************/ |
| 1629 /* */ | 1548 /* */ |
| 1630 /* <Function> */ | 1549 /* <Function> */ |
| 1631 /* Current_Ratio */ | 1550 /* Current_Ratio */ |
| 1632 /* */ | 1551 /* */ |
| 1633 /* <Description> */ | 1552 /* <Description> */ |
| 1634 /* Returns the current aspect ratio scaling factor depending on the */ | 1553 /* Returns the current aspect ratio scaling factor depending on the */ |
| 1635 /* projection vector's state and device resolutions. */ | 1554 /* projection vector's state and device resolutions. */ |
| 1636 /* */ | 1555 /* */ |
| 1637 /* <Return> */ | 1556 /* <Return> */ |
| (...skipping 16 matching lines...) Expand all Loading... |
| 1654 #endif | 1573 #endif |
| 1655 { | 1574 { |
| 1656 if ( CUR.GS.projVector.y == 0 ) | 1575 if ( CUR.GS.projVector.y == 0 ) |
| 1657 CUR.tt_metrics.ratio = CUR.tt_metrics.x_ratio; | 1576 CUR.tt_metrics.ratio = CUR.tt_metrics.x_ratio; |
| 1658 | 1577 |
| 1659 else if ( CUR.GS.projVector.x == 0 ) | 1578 else if ( CUR.GS.projVector.x == 0 ) |
| 1660 CUR.tt_metrics.ratio = CUR.tt_metrics.y_ratio; | 1579 CUR.tt_metrics.ratio = CUR.tt_metrics.y_ratio; |
| 1661 | 1580 |
| 1662 else | 1581 else |
| 1663 { | 1582 { |
| 1664 FT_Long x, y; | 1583 FT_F26Dot6 x, y; |
| 1665 | 1584 |
| 1666 | 1585 |
| 1667 x = TT_MULDIV( CUR.GS.projVector.x, | 1586 x = TT_MulFix14( CUR.tt_metrics.x_ratio, |
| 1668 CUR.tt_metrics.x_ratio, 0x4000 ); | 1587 CUR.GS.projVector.x ); |
| 1669 y = TT_MULDIV( CUR.GS.projVector.y, | 1588 y = TT_MulFix14( CUR.tt_metrics.y_ratio, |
| 1670 CUR.tt_metrics.y_ratio, 0x4000 ); | 1589 CUR.GS.projVector.y ); |
| 1671 CUR.tt_metrics.ratio = TT_VecLen( x, y ); | 1590 CUR.tt_metrics.ratio = FT_Hypot( x, y ); |
| 1672 } | 1591 } |
| 1673 } | 1592 } |
| 1674 } | 1593 } |
| 1675 return CUR.tt_metrics.ratio; | 1594 return CUR.tt_metrics.ratio; |
| 1676 } | 1595 } |
| 1677 | 1596 |
| 1678 | 1597 |
| 1679 static FT_Long | 1598 static FT_Long |
| 1680 Current_Ppem( EXEC_OP ) | 1599 Current_Ppem( EXEC_OP ) |
| 1681 { | 1600 { |
| 1682 return TT_MULFIX( CUR.tt_metrics.ppem, CURRENT_Ratio() ); | 1601 return FT_MulFix( CUR.tt_metrics.ppem, CURRENT_Ratio() ); |
| 1683 } | 1602 } |
| 1684 | 1603 |
| 1685 | 1604 |
| 1686 /*************************************************************************/ | 1605 /*************************************************************************/ |
| 1687 /* */ | 1606 /* */ |
| 1688 /* Functions related to the control value table (CVT). */ | 1607 /* Functions related to the control value table (CVT). */ |
| 1689 /* */ | 1608 /* */ |
| 1690 /*************************************************************************/ | 1609 /*************************************************************************/ |
| 1691 | 1610 |
| 1692 | 1611 |
| 1693 FT_CALLBACK_DEF( FT_F26Dot6 ) | 1612 FT_CALLBACK_DEF( FT_F26Dot6 ) |
| 1694 Read_CVT( EXEC_OP_ FT_ULong idx ) | 1613 Read_CVT( EXEC_OP_ FT_ULong idx ) |
| 1695 { | 1614 { |
| 1696 return CUR.cvt[idx]; | 1615 return CUR.cvt[idx]; |
| 1697 } | 1616 } |
| 1698 | 1617 |
| 1699 | 1618 |
| 1700 FT_CALLBACK_DEF( FT_F26Dot6 ) | 1619 FT_CALLBACK_DEF( FT_F26Dot6 ) |
| 1701 Read_CVT_Stretched( EXEC_OP_ FT_ULong idx ) | 1620 Read_CVT_Stretched( EXEC_OP_ FT_ULong idx ) |
| 1702 { | 1621 { |
| 1703 return TT_MULFIX( CUR.cvt[idx], CURRENT_Ratio() ); | 1622 return FT_MulFix( CUR.cvt[idx], CURRENT_Ratio() ); |
| 1704 } | 1623 } |
| 1705 | 1624 |
| 1706 | 1625 |
| 1707 FT_CALLBACK_DEF( void ) | 1626 FT_CALLBACK_DEF( void ) |
| 1708 Write_CVT( EXEC_OP_ FT_ULong idx, | 1627 Write_CVT( EXEC_OP_ FT_ULong idx, |
| 1709 FT_F26Dot6 value ) | 1628 FT_F26Dot6 value ) |
| 1710 { | 1629 { |
| 1711 CUR.cvt[idx] = value; | 1630 CUR.cvt[idx] = value; |
| 1712 } | 1631 } |
| 1713 | 1632 |
| (...skipping 65 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1779 /* */ | 1698 /* */ |
| 1780 static FT_Bool | 1699 static FT_Bool |
| 1781 Ins_Goto_CodeRange( EXEC_OP_ FT_Int aRange, | 1700 Ins_Goto_CodeRange( EXEC_OP_ FT_Int aRange, |
| 1782 FT_ULong aIP ) | 1701 FT_ULong aIP ) |
| 1783 { | 1702 { |
| 1784 TT_CodeRange* range; | 1703 TT_CodeRange* range; |
| 1785 | 1704 |
| 1786 | 1705 |
| 1787 if ( aRange < 1 || aRange > 3 ) | 1706 if ( aRange < 1 || aRange > 3 ) |
| 1788 { | 1707 { |
| 1789 CUR.error = TT_Err_Bad_Argument; | 1708 CUR.error = FT_THROW( Bad_Argument ); |
| 1790 return FAILURE; | 1709 return FAILURE; |
| 1791 } | 1710 } |
| 1792 | 1711 |
| 1793 range = &CUR.codeRangeTable[aRange - 1]; | 1712 range = &CUR.codeRangeTable[aRange - 1]; |
| 1794 | 1713 |
| 1795 if ( range->base == NULL ) /* invalid coderange */ | 1714 if ( range->base == NULL ) /* invalid coderange */ |
| 1796 { | 1715 { |
| 1797 CUR.error = TT_Err_Invalid_CodeRange; | 1716 CUR.error = FT_THROW( Invalid_CodeRange ); |
| 1798 return FAILURE; | 1717 return FAILURE; |
| 1799 } | 1718 } |
| 1800 | 1719 |
| 1801 /* NOTE: Because the last instruction of a program may be a CALL */ | 1720 /* NOTE: Because the last instruction of a program may be a CALL */ |
| 1802 /* which will return to the first byte *after* the code */ | 1721 /* which will return to the first byte *after* the code */ |
| 1803 /* range, we test for aIP <= Size, instead of aIP < Size. */ | 1722 /* range, we test for aIP <= Size, instead of aIP < Size. */ |
| 1804 | 1723 |
| 1805 if ( aIP > range->size ) | 1724 if ( aIP > range->size ) |
| 1806 { | 1725 { |
| 1807 CUR.error = TT_Err_Code_Overflow; | 1726 CUR.error = FT_THROW( Code_Overflow ); |
| 1808 return FAILURE; | 1727 return FAILURE; |
| 1809 } | 1728 } |
| 1810 | 1729 |
| 1811 CUR.code = range->base; | 1730 CUR.code = range->base; |
| 1812 CUR.codeSize = range->size; | 1731 CUR.codeSize = range->size; |
| 1813 CUR.IP = aIP; | 1732 CUR.IP = aIP; |
| 1814 CUR.curRange = aRange; | 1733 CUR.curRange = aRange; |
| 1815 | 1734 |
| 1816 return SUCCESS; | 1735 return SUCCESS; |
| 1817 } | 1736 } |
| (...skipping 25 matching lines...) Expand all Loading... |
| 1843 | 1762 |
| 1844 | 1763 |
| 1845 #ifdef TT_CONFIG_OPTION_UNPATENTED_HINTING | 1764 #ifdef TT_CONFIG_OPTION_UNPATENTED_HINTING |
| 1846 FT_ASSERT( !CUR.face->unpatented_hinting ); | 1765 FT_ASSERT( !CUR.face->unpatented_hinting ); |
| 1847 #endif | 1766 #endif |
| 1848 | 1767 |
| 1849 v = CUR.GS.freeVector.x; | 1768 v = CUR.GS.freeVector.x; |
| 1850 | 1769 |
| 1851 if ( v != 0 ) | 1770 if ( v != 0 ) |
| 1852 { | 1771 { |
| 1853 zone->cur[point].x += TT_MULDIV( distance, | 1772 #ifdef TT_CONFIG_OPTION_SUBPIXEL_HINTING |
| 1854 v * 0x10000L, | 1773 if ( !SUBPIXEL_HINTING || |
| 1855 CUR.F_dot_P ); | 1774 ( !CUR.ignore_x_mode || |
| 1775 ( CUR.sph_tweak_flags & SPH_TWEAK_ALLOW_X_DMOVE ) ) ) |
| 1776 #endif /* TT_CONFIG_OPTION_SUBPIXEL_HINTING */ |
| 1777 zone->cur[point].x += FT_MulDiv( distance, v, CUR.F_dot_P ); |
| 1856 | 1778 |
| 1857 zone->tags[point] |= FT_CURVE_TAG_TOUCH_X; | 1779 zone->tags[point] |= FT_CURVE_TAG_TOUCH_X; |
| 1858 } | 1780 } |
| 1859 | 1781 |
| 1860 v = CUR.GS.freeVector.y; | 1782 v = CUR.GS.freeVector.y; |
| 1861 | 1783 |
| 1862 if ( v != 0 ) | 1784 if ( v != 0 ) |
| 1863 { | 1785 { |
| 1864 zone->cur[point].y += TT_MULDIV( distance, | 1786 zone->cur[point].y += FT_MulDiv( distance, v, CUR.F_dot_P ); |
| 1865 v * 0x10000L, | |
| 1866 CUR.F_dot_P ); | |
| 1867 | 1787 |
| 1868 zone->tags[point] |= FT_CURVE_TAG_TOUCH_Y; | 1788 zone->tags[point] |= FT_CURVE_TAG_TOUCH_Y; |
| 1869 } | 1789 } |
| 1870 } | 1790 } |
| 1871 | 1791 |
| 1872 | 1792 |
| 1873 /*************************************************************************/ | 1793 /*************************************************************************/ |
| 1874 /* */ | 1794 /* */ |
| 1875 /* <Function> */ | 1795 /* <Function> */ |
| 1876 /* Direct_Move_Orig */ | 1796 /* Direct_Move_Orig */ |
| (...skipping 18 matching lines...) Expand all Loading... |
| 1895 FT_F26Dot6 v; | 1815 FT_F26Dot6 v; |
| 1896 | 1816 |
| 1897 | 1817 |
| 1898 #ifdef TT_CONFIG_OPTION_UNPATENTED_HINTING | 1818 #ifdef TT_CONFIG_OPTION_UNPATENTED_HINTING |
| 1899 FT_ASSERT( !CUR.face->unpatented_hinting ); | 1819 FT_ASSERT( !CUR.face->unpatented_hinting ); |
| 1900 #endif | 1820 #endif |
| 1901 | 1821 |
| 1902 v = CUR.GS.freeVector.x; | 1822 v = CUR.GS.freeVector.x; |
| 1903 | 1823 |
| 1904 if ( v != 0 ) | 1824 if ( v != 0 ) |
| 1905 zone->org[point].x += TT_MULDIV( distance, | 1825 zone->org[point].x += FT_MulDiv( distance, v, CUR.F_dot_P ); |
| 1906 v * 0x10000L, | |
| 1907 CUR.F_dot_P ); | |
| 1908 | 1826 |
| 1909 v = CUR.GS.freeVector.y; | 1827 v = CUR.GS.freeVector.y; |
| 1910 | 1828 |
| 1911 if ( v != 0 ) | 1829 if ( v != 0 ) |
| 1912 zone->org[point].y += TT_MULDIV( distance, | 1830 zone->org[point].y += FT_MulDiv( distance, v, CUR.F_dot_P ); |
| 1913 v * 0x10000L, | |
| 1914 CUR.F_dot_P ); | |
| 1915 } | 1831 } |
| 1916 | 1832 |
| 1917 | 1833 |
| 1918 /*************************************************************************/ | 1834 /*************************************************************************/ |
| 1919 /* */ | 1835 /* */ |
| 1920 /* Special versions of Direct_Move() */ | 1836 /* Special versions of Direct_Move() */ |
| 1921 /* */ | 1837 /* */ |
| 1922 /* The following versions are used whenever both vectors are both */ | 1838 /* The following versions are used whenever both vectors are both */ |
| 1923 /* along one of the coordinate unit vectors, i.e. in 90% of the cases. */ | 1839 /* along one of the coordinate unit vectors, i.e. in 90% of the cases. */ |
| 1924 /* */ | 1840 /* */ |
| 1925 /*************************************************************************/ | 1841 /*************************************************************************/ |
| 1926 | 1842 |
| 1927 | 1843 |
| 1928 static void | 1844 static void |
| 1929 Direct_Move_X( EXEC_OP_ TT_GlyphZone zone, | 1845 Direct_Move_X( EXEC_OP_ TT_GlyphZone zone, |
| 1930 FT_UShort point, | 1846 FT_UShort point, |
| 1931 FT_F26Dot6 distance ) | 1847 FT_F26Dot6 distance ) |
| 1932 { | 1848 { |
| 1933 FT_UNUSED_EXEC; | 1849 FT_UNUSED_EXEC; |
| 1934 | 1850 |
| 1935 zone->cur[point].x += distance; | 1851 #ifdef TT_CONFIG_OPTION_SUBPIXEL_HINTING |
| 1852 if ( !SUBPIXEL_HINTING || |
| 1853 !CUR.ignore_x_mode ) |
| 1854 #endif /* TT_CONFIG_OPTION_SUBPIXEL_HINTING */ |
| 1855 zone->cur[point].x += distance; |
| 1856 |
| 1936 zone->tags[point] |= FT_CURVE_TAG_TOUCH_X; | 1857 zone->tags[point] |= FT_CURVE_TAG_TOUCH_X; |
| 1937 } | 1858 } |
| 1938 | 1859 |
| 1939 | 1860 |
| 1940 static void | 1861 static void |
| 1941 Direct_Move_Y( EXEC_OP_ TT_GlyphZone zone, | 1862 Direct_Move_Y( EXEC_OP_ TT_GlyphZone zone, |
| 1942 FT_UShort point, | 1863 FT_UShort point, |
| 1943 FT_F26Dot6 distance ) | 1864 FT_F26Dot6 distance ) |
| 1944 { | 1865 { |
| 1945 FT_UNUSED_EXEC; | 1866 FT_UNUSED_EXEC; |
| (...skipping 240 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2186 if ( distance >= 0 ) | 2107 if ( distance >= 0 ) |
| 2187 { | 2108 { |
| 2188 val = distance + compensation + 63; | 2109 val = distance + compensation + 63; |
| 2189 if ( distance && val > 0 ) | 2110 if ( distance && val > 0 ) |
| 2190 val &= ~63; | 2111 val &= ~63; |
| 2191 else | 2112 else |
| 2192 val = 0; | 2113 val = 0; |
| 2193 } | 2114 } |
| 2194 else | 2115 else |
| 2195 { | 2116 { |
| 2196 val = - FT_PIX_CEIL( compensation - distance ); | 2117 val = -FT_PIX_CEIL( compensation - distance ); |
| 2197 if ( val > 0 ) | 2118 if ( val > 0 ) |
| 2198 val = 0; | 2119 val = 0; |
| 2199 } | 2120 } |
| 2200 | 2121 |
| 2201 return val; | 2122 return val; |
| 2202 } | 2123 } |
| 2203 | 2124 |
| 2204 | 2125 |
| 2205 /*************************************************************************/ | 2126 /*************************************************************************/ |
| 2206 /* */ | 2127 /* */ |
| (...skipping 190 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2397 | 2318 |
| 2398 /*************************************************************************/ | 2319 /*************************************************************************/ |
| 2399 /* */ | 2320 /* */ |
| 2400 /* <Function> */ | 2321 /* <Function> */ |
| 2401 /* SetSuperRound */ | 2322 /* SetSuperRound */ |
| 2402 /* */ | 2323 /* */ |
| 2403 /* <Description> */ | 2324 /* <Description> */ |
| 2404 /* Sets Super Round parameters. */ | 2325 /* Sets Super Round parameters. */ |
| 2405 /* */ | 2326 /* */ |
| 2406 /* <Input> */ | 2327 /* <Input> */ |
| 2407 /* GridPeriod :: Grid period */ | 2328 /* GridPeriod :: The grid period. */ |
| 2408 /* selector :: SROUND opcode */ | 2329 /* */ |
| 2330 /* selector :: The SROUND opcode. */ |
| 2409 /* */ | 2331 /* */ |
| 2410 static void | 2332 static void |
| 2411 SetSuperRound( EXEC_OP_ FT_F26Dot6 GridPeriod, | 2333 SetSuperRound( EXEC_OP_ FT_F26Dot6 GridPeriod, |
| 2412 FT_Long selector ) | 2334 FT_Long selector ) |
| 2413 { | 2335 { |
| 2414 switch ( (FT_Int)( selector & 0xC0 ) ) | 2336 switch ( (FT_Int)( selector & 0xC0 ) ) |
| 2415 { | 2337 { |
| 2416 case 0: | 2338 case 0: |
| 2417 CUR.period = GridPeriod / 2; | 2339 CUR.period = GridPeriod / 2; |
| 2418 break; | 2340 break; |
| (...skipping 191 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2610 } | 2532 } |
| 2611 else | 2533 else |
| 2612 { | 2534 { |
| 2613 CUR.func_project = Project_y; | 2535 CUR.func_project = Project_y; |
| 2614 CUR.func_move = Direct_Move_Y; | 2536 CUR.func_move = Direct_Move_Y; |
| 2615 CUR.func_move_orig = Direct_Move_Orig_Y; | 2537 CUR.func_move_orig = Direct_Move_Orig_Y; |
| 2616 } | 2538 } |
| 2617 | 2539 |
| 2618 if ( CUR.GS.dualVector.x == 0x4000 ) | 2540 if ( CUR.GS.dualVector.x == 0x4000 ) |
| 2619 CUR.func_dualproj = Project_x; | 2541 CUR.func_dualproj = Project_x; |
| 2542 else if ( CUR.GS.dualVector.y == 0x4000 ) |
| 2543 CUR.func_dualproj = Project_y; |
| 2620 else | 2544 else |
| 2621 { | 2545 CUR.func_dualproj = Dual_Project; |
| 2622 if ( CUR.GS.dualVector.y == 0x4000 ) | |
| 2623 CUR.func_dualproj = Project_y; | |
| 2624 else | |
| 2625 CUR.func_dualproj = Dual_Project; | |
| 2626 } | |
| 2627 | 2546 |
| 2628 /* Force recalculation of cached aspect ratio */ | 2547 /* Force recalculation of cached aspect ratio */ |
| 2629 CUR.tt_metrics.ratio = 0; | 2548 CUR.tt_metrics.ratio = 0; |
| 2630 | 2549 |
| 2631 return; | 2550 return; |
| 2632 } | 2551 } |
| 2633 #endif /* TT_CONFIG_OPTION_UNPATENTED_HINTING */ | 2552 #endif /* TT_CONFIG_OPTION_UNPATENTED_HINTING */ |
| 2634 | 2553 |
| 2635 if ( CUR.GS.freeVector.x == 0x4000 ) | 2554 if ( CUR.GS.freeVector.x == 0x4000 ) |
| 2636 CUR.F_dot_P = CUR.GS.projVector.x * 0x10000L; | 2555 CUR.F_dot_P = CUR.GS.projVector.x; |
| 2556 else if ( CUR.GS.freeVector.y == 0x4000 ) |
| 2557 CUR.F_dot_P = CUR.GS.projVector.y; |
| 2637 else | 2558 else |
| 2638 { | 2559 CUR.F_dot_P = ( (FT_Long)CUR.GS.projVector.x * CUR.GS.freeVector.x + |
| 2639 if ( CUR.GS.freeVector.y == 0x4000 ) | 2560 (FT_Long)CUR.GS.projVector.y * CUR.GS.freeVector.y ) >> |
| 2640 CUR.F_dot_P = CUR.GS.projVector.y * 0x10000L; | 2561 14; |
| 2641 else | |
| 2642 CUR.F_dot_P = (FT_Long)CUR.GS.projVector.x * CUR.GS.freeVector.x * 4 + | |
| 2643 (FT_Long)CUR.GS.projVector.y * CUR.GS.freeVector.y * 4; | |
| 2644 } | |
| 2645 | 2562 |
| 2646 if ( CUR.GS.projVector.x == 0x4000 ) | 2563 if ( CUR.GS.projVector.x == 0x4000 ) |
| 2647 CUR.func_project = (TT_Project_Func)Project_x; | 2564 CUR.func_project = (TT_Project_Func)Project_x; |
| 2565 else if ( CUR.GS.projVector.y == 0x4000 ) |
| 2566 CUR.func_project = (TT_Project_Func)Project_y; |
| 2648 else | 2567 else |
| 2649 { | 2568 CUR.func_project = (TT_Project_Func)Project; |
| 2650 if ( CUR.GS.projVector.y == 0x4000 ) | |
| 2651 CUR.func_project = (TT_Project_Func)Project_y; | |
| 2652 else | |
| 2653 CUR.func_project = (TT_Project_Func)Project; | |
| 2654 } | |
| 2655 | 2569 |
| 2656 if ( CUR.GS.dualVector.x == 0x4000 ) | 2570 if ( CUR.GS.dualVector.x == 0x4000 ) |
| 2657 CUR.func_dualproj = (TT_Project_Func)Project_x; | 2571 CUR.func_dualproj = (TT_Project_Func)Project_x; |
| 2572 else if ( CUR.GS.dualVector.y == 0x4000 ) |
| 2573 CUR.func_dualproj = (TT_Project_Func)Project_y; |
| 2658 else | 2574 else |
| 2659 { | 2575 CUR.func_dualproj = (TT_Project_Func)Dual_Project; |
| 2660 if ( CUR.GS.dualVector.y == 0x4000 ) | |
| 2661 CUR.func_dualproj = (TT_Project_Func)Project_y; | |
| 2662 else | |
| 2663 CUR.func_dualproj = (TT_Project_Func)Dual_Project; | |
| 2664 } | |
| 2665 | 2576 |
| 2666 CUR.func_move = (TT_Move_Func)Direct_Move; | 2577 CUR.func_move = (TT_Move_Func)Direct_Move; |
| 2667 CUR.func_move_orig = (TT_Move_Func)Direct_Move_Orig; | 2578 CUR.func_move_orig = (TT_Move_Func)Direct_Move_Orig; |
| 2668 | 2579 |
| 2669 if ( CUR.F_dot_P == 0x40000000L ) | 2580 if ( CUR.F_dot_P == 0x4000L ) |
| 2670 { | 2581 { |
| 2671 if ( CUR.GS.freeVector.x == 0x4000 ) | 2582 if ( CUR.GS.freeVector.x == 0x4000 ) |
| 2672 { | 2583 { |
| 2673 CUR.func_move = (TT_Move_Func)Direct_Move_X; | 2584 CUR.func_move = (TT_Move_Func)Direct_Move_X; |
| 2674 CUR.func_move_orig = (TT_Move_Func)Direct_Move_Orig_X; | 2585 CUR.func_move_orig = (TT_Move_Func)Direct_Move_Orig_X; |
| 2675 } | 2586 } |
| 2676 else | 2587 else if ( CUR.GS.freeVector.y == 0x4000 ) |
| 2677 { | 2588 { |
| 2678 if ( CUR.GS.freeVector.y == 0x4000 ) | 2589 CUR.func_move = (TT_Move_Func)Direct_Move_Y; |
| 2679 { | 2590 CUR.func_move_orig = (TT_Move_Func)Direct_Move_Orig_Y; |
| 2680 CUR.func_move = (TT_Move_Func)Direct_Move_Y; | |
| 2681 CUR.func_move_orig = (TT_Move_Func)Direct_Move_Orig_Y; | |
| 2682 } | |
| 2683 } | 2591 } |
| 2684 } | 2592 } |
| 2685 | 2593 |
| 2686 /* at small sizes, F_dot_P can become too small, resulting */ | 2594 /* at small sizes, F_dot_P can become too small, resulting */ |
| 2687 /* in overflows and `spikes' in a number of glyphs like `w'. */ | 2595 /* in overflows and `spikes' in a number of glyphs like `w'. */ |
| 2688 | 2596 |
| 2689 if ( FT_ABS( CUR.F_dot_P ) < 0x4000000L ) | 2597 if ( FT_ABS( CUR.F_dot_P ) < 0x400L ) |
| 2690 CUR.F_dot_P = 0x40000000L; | 2598 CUR.F_dot_P = 0x4000L; |
| 2691 | 2599 |
| 2692 /* Disable cached aspect ratio */ | 2600 /* Disable cached aspect ratio */ |
| 2693 CUR.tt_metrics.ratio = 0; | 2601 CUR.tt_metrics.ratio = 0; |
| 2694 } | 2602 } |
| 2695 | 2603 |
| 2696 | 2604 |
| 2697 /*************************************************************************/ | 2605 /*************************************************************************/ |
| 2698 /* */ | 2606 /* */ |
| 2699 /* <Function> */ | 2607 /* <Function> */ |
| 2700 /* Normalize */ | 2608 /* Normalize */ |
| 2701 /* */ | 2609 /* */ |
| 2702 /* <Description> */ | 2610 /* <Description> */ |
| 2703 /* Norms a vector. */ | 2611 /* Norms a vector. */ |
| 2704 /* */ | 2612 /* */ |
| 2705 /* <Input> */ | 2613 /* <Input> */ |
| 2706 /* Vx :: The horizontal input vector coordinate. */ | 2614 /* Vx :: The horizontal input vector coordinate. */ |
| 2707 /* Vy :: The vertical input vector coordinate. */ | 2615 /* Vy :: The vertical input vector coordinate. */ |
| 2708 /* */ | 2616 /* */ |
| 2709 /* <Output> */ | 2617 /* <Output> */ |
| 2710 /* R :: The normed unit vector. */ | 2618 /* R :: The normed unit vector. */ |
| 2711 /* */ | 2619 /* */ |
| 2712 /* <Return> */ | 2620 /* <Return> */ |
| 2713 /* Returns FAILURE if a vector parameter is zero. */ | 2621 /* Returns FAILURE if a vector parameter is zero. */ |
| 2714 /* */ | 2622 /* */ |
| 2715 /* <Note> */ | 2623 /* <Note> */ |
| 2716 /* In case Vx and Vy are both zero, Normalize() returns SUCCESS, and */ | 2624 /* In case Vx and Vy are both zero, Normalize() returns SUCCESS, and */ |
| 2717 /* R is undefined. */ | 2625 /* R is undefined. */ |
| 2718 /* */ | 2626 /* */ |
| 2719 | |
| 2720 | |
| 2721 static FT_Bool | 2627 static FT_Bool |
| 2722 Normalize( EXEC_OP_ FT_F26Dot6 Vx, | 2628 Normalize( EXEC_OP_ FT_F26Dot6 Vx, |
| 2723 FT_F26Dot6 Vy, | 2629 FT_F26Dot6 Vy, |
| 2724 FT_UnitVector* R ) | 2630 FT_UnitVector* R ) |
| 2725 { | 2631 { |
| 2726 FT_F26Dot6 W; | 2632 FT_F26Dot6 W; |
| 2727 FT_Bool S1, S2; | |
| 2728 | 2633 |
| 2729 FT_UNUSED_EXEC; | 2634 FT_UNUSED_EXEC; |
| 2730 | 2635 |
| 2731 | 2636 |
| 2732 if ( FT_ABS( Vx ) < 0x10000L && FT_ABS( Vy ) < 0x10000L ) | 2637 if ( FT_ABS( Vx ) < 0x4000L && FT_ABS( Vy ) < 0x4000L ) |
| 2733 { | 2638 { |
| 2734 Vx *= 0x100; | 2639 if ( Vx == 0 && Vy == 0 ) |
| 2735 Vy *= 0x100; | |
| 2736 | |
| 2737 W = TT_VecLen( Vx, Vy ); | |
| 2738 | |
| 2739 if ( W == 0 ) | |
| 2740 { | 2640 { |
| 2741 /* XXX: UNDOCUMENTED! It seems that it is possible to try */ | 2641 /* XXX: UNDOCUMENTED! It seems that it is possible to try */ |
| 2742 /* to normalize the vector (0,0). Return immediately. */ | 2642 /* to normalize the vector (0,0). Return immediately. */ |
| 2743 return SUCCESS; | 2643 return SUCCESS; |
| 2744 } | 2644 } |
| 2745 | 2645 |
| 2746 R->x = (FT_F2Dot14)FT_MulDiv( Vx, 0x4000L, W ); | 2646 Vx *= 0x4000; |
| 2747 R->y = (FT_F2Dot14)FT_MulDiv( Vy, 0x4000L, W ); | 2647 Vy *= 0x4000; |
| 2748 | |
| 2749 return SUCCESS; | |
| 2750 } | 2648 } |
| 2751 | 2649 |
| 2752 W = TT_VecLen( Vx, Vy ); | 2650 W = FT_Hypot( Vx, Vy ); |
| 2753 | 2651 |
| 2754 Vx = FT_MulDiv( Vx, 0x4000L, W ); | 2652 R->x = (FT_F2Dot14)TT_DivFix14( Vx, W ); |
| 2755 Vy = FT_MulDiv( Vy, 0x4000L, W ); | 2653 R->y = (FT_F2Dot14)TT_DivFix14( Vy, W ); |
| 2756 | |
| 2757 W = Vx * Vx + Vy * Vy; | |
| 2758 | |
| 2759 /* Now, we want that Sqrt( W ) = 0x4000 */ | |
| 2760 /* Or 0x10000000 <= W < 0x10004000 */ | |
| 2761 | |
| 2762 if ( Vx < 0 ) | |
| 2763 { | |
| 2764 Vx = -Vx; | |
| 2765 S1 = TRUE; | |
| 2766 } | |
| 2767 else | |
| 2768 S1 = FALSE; | |
| 2769 | |
| 2770 if ( Vy < 0 ) | |
| 2771 { | |
| 2772 Vy = -Vy; | |
| 2773 S2 = TRUE; | |
| 2774 } | |
| 2775 else | |
| 2776 S2 = FALSE; | |
| 2777 | |
| 2778 while ( W < 0x10000000L ) | |
| 2779 { | |
| 2780 /* We need to increase W by a minimal amount */ | |
| 2781 if ( Vx < Vy ) | |
| 2782 Vx++; | |
| 2783 else | |
| 2784 Vy++; | |
| 2785 | |
| 2786 W = Vx * Vx + Vy * Vy; | |
| 2787 } | |
| 2788 | |
| 2789 while ( W >= 0x10004000L ) | |
| 2790 { | |
| 2791 /* We need to decrease W by a minimal amount */ | |
| 2792 if ( Vx < Vy ) | |
| 2793 Vx--; | |
| 2794 else | |
| 2795 Vy--; | |
| 2796 | |
| 2797 W = Vx * Vx + Vy * Vy; | |
| 2798 } | |
| 2799 | |
| 2800 /* Note that in various cases, we can only */ | |
| 2801 /* compute a Sqrt(W) of 0x3FFF, eg. Vx = Vy */ | |
| 2802 | |
| 2803 if ( S1 ) | |
| 2804 Vx = -Vx; | |
| 2805 | |
| 2806 if ( S2 ) | |
| 2807 Vy = -Vy; | |
| 2808 | |
| 2809 R->x = (FT_F2Dot14)Vx; /* Type conversion */ | |
| 2810 R->y = (FT_F2Dot14)Vy; /* Type conversion */ | |
| 2811 | 2654 |
| 2812 return SUCCESS; | 2655 return SUCCESS; |
| 2813 } | 2656 } |
| 2814 | 2657 |
| 2815 | 2658 |
| 2816 /*************************************************************************/ | 2659 /*************************************************************************/ |
| 2817 /* */ | 2660 /* */ |
| 2818 /* Here we start with the implementation of the various opcodes. */ | 2661 /* Here we start with the implementation of the various opcodes. */ |
| 2819 /* */ | 2662 /* */ |
| 2820 /*************************************************************************/ | 2663 /*************************************************************************/ |
| 2821 | 2664 |
| 2822 | 2665 |
| 2823 static FT_Bool | 2666 static FT_Bool |
| 2824 Ins_SxVTL( EXEC_OP_ FT_UShort aIdx1, | 2667 Ins_SxVTL( EXEC_OP_ FT_UShort aIdx1, |
| 2825 FT_UShort aIdx2, | 2668 FT_UShort aIdx2, |
| 2826 FT_Int aOpc, | 2669 FT_Int aOpc, |
| 2827 FT_UnitVector* Vec ) | 2670 FT_UnitVector* Vec ) |
| 2828 { | 2671 { |
| 2829 FT_Long A, B, C; | 2672 FT_Long A, B, C; |
| 2830 FT_Vector* p1; | 2673 FT_Vector* p1; |
| 2831 FT_Vector* p2; | 2674 FT_Vector* p2; |
| 2832 | 2675 |
| 2833 | 2676 |
| 2834 if ( BOUNDS( aIdx1, CUR.zp2.n_points ) || | 2677 if ( BOUNDS( aIdx1, CUR.zp2.n_points ) || |
| 2835 BOUNDS( aIdx2, CUR.zp1.n_points ) ) | 2678 BOUNDS( aIdx2, CUR.zp1.n_points ) ) |
| 2836 { | 2679 { |
| 2837 if ( CUR.pedantic_hinting ) | 2680 if ( CUR.pedantic_hinting ) |
| 2838 CUR.error = TT_Err_Invalid_Reference; | 2681 CUR.error = FT_THROW( Invalid_Reference ); |
| 2839 return FAILURE; | 2682 return FAILURE; |
| 2840 } | 2683 } |
| 2841 | 2684 |
| 2842 p1 = CUR.zp1.cur + aIdx2; | 2685 p1 = CUR.zp1.cur + aIdx2; |
| 2843 p2 = CUR.zp2.cur + aIdx1; | 2686 p2 = CUR.zp2.cur + aIdx1; |
| 2844 | 2687 |
| 2845 A = p1->x - p2->x; | 2688 A = p1->x - p2->x; |
| 2846 B = p1->y - p2->y; | 2689 B = p1->y - p2->y; |
| 2847 | 2690 |
| 2848 /* If p1 == p2, SPVTL and SFVTL behave the same as */ | 2691 /* If p1 == p2, SPVTL and SFVTL behave the same as */ |
| (...skipping 235 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3084 CUR.GS.round_state = TT_Round_Super; \ | 2927 CUR.GS.round_state = TT_Round_Super; \ |
| 3085 CUR.func_round = (TT_Round_Func)Round_Super; | 2928 CUR.func_round = (TT_Round_Func)Round_Super; |
| 3086 | 2929 |
| 3087 | 2930 |
| 3088 #define DO_S45ROUND \ | 2931 #define DO_S45ROUND \ |
| 3089 SET_SuperRound( 0x2D41, args[0] ); \ | 2932 SET_SuperRound( 0x2D41, args[0] ); \ |
| 3090 CUR.GS.round_state = TT_Round_Super_45; \ | 2933 CUR.GS.round_state = TT_Round_Super_45; \ |
| 3091 CUR.func_round = (TT_Round_Func)Round_Super_45; | 2934 CUR.func_round = (TT_Round_Func)Round_Super_45; |
| 3092 | 2935 |
| 3093 | 2936 |
| 3094 #define DO_SLOOP \ | 2937 #define DO_SLOOP \ |
| 3095 if ( args[0] < 0 ) \ | 2938 if ( args[0] < 0 ) \ |
| 3096 CUR.error = TT_Err_Bad_Argument; \ | 2939 CUR.error = FT_THROW( Bad_Argument ); \ |
| 3097 else \ | 2940 else \ |
| 3098 CUR.GS.loop = args[0]; | 2941 CUR.GS.loop = args[0]; |
| 3099 | 2942 |
| 3100 | 2943 |
| 3101 #define DO_SMD \ | 2944 #define DO_SMD \ |
| 3102 CUR.GS.minimum_distance = args[0]; | 2945 CUR.GS.minimum_distance = args[0]; |
| 3103 | 2946 |
| 3104 | 2947 |
| 3105 #define DO_SCVTCI \ | 2948 #define DO_SCVTCI \ |
| 3106 CUR.GS.control_value_cutin = (FT_F26Dot6)args[0]; | 2949 CUR.GS.control_value_cutin = (FT_F26Dot6)args[0]; |
| 3107 | 2950 |
| 3108 | 2951 |
| 3109 #define DO_SSWCI \ | 2952 #define DO_SSWCI \ |
| 3110 CUR.GS.single_width_cutin = (FT_F26Dot6)args[0]; | 2953 CUR.GS.single_width_cutin = (FT_F26Dot6)args[0]; |
| 3111 | 2954 |
| 3112 | 2955 |
| 3113 /* XXX: UNDOCUMENTED! or bug in the Windows engine? */ | 2956 #define DO_SSW \ |
| 3114 /* */ | 2957 CUR.GS.single_width_value = FT_MulFix( args[0], \ |
| 3115 /* It seems that the value that is read here is */ | 2958 CUR.tt_metrics.scale ); |
| 3116 /* expressed in 16.16 format rather than in font */ | |
| 3117 /* units. */ | |
| 3118 /* */ | |
| 3119 #define DO_SSW \ | |
| 3120 CUR.GS.single_width_value = (FT_F26Dot6)( args[0] >> 10 ); | |
| 3121 | 2959 |
| 3122 | 2960 |
| 3123 #define DO_FLIPON \ | 2961 #define DO_FLIPON \ |
| 3124 CUR.GS.auto_flip = TRUE; | 2962 CUR.GS.auto_flip = TRUE; |
| 3125 | 2963 |
| 3126 | 2964 |
| 3127 #define DO_FLIPOFF \ | 2965 #define DO_FLIPOFF \ |
| 3128 CUR.GS.auto_flip = FALSE; | 2966 CUR.GS.auto_flip = FALSE; |
| 3129 | 2967 |
| 3130 | 2968 |
| (...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3174 L = args[0]; \ | 3012 L = args[0]; \ |
| 3175 args[0] = args[1]; \ | 3013 args[0] = args[1]; \ |
| 3176 args[1] = L; \ | 3014 args[1] = L; \ |
| 3177 } | 3015 } |
| 3178 | 3016 |
| 3179 | 3017 |
| 3180 #define DO_DEPTH \ | 3018 #define DO_DEPTH \ |
| 3181 args[0] = CUR.top; | 3019 args[0] = CUR.top; |
| 3182 | 3020 |
| 3183 | 3021 |
| 3184 #define DO_CINDEX \ | 3022 #define DO_CINDEX \ |
| 3185 { \ | 3023 { \ |
| 3186 FT_Long L; \ | 3024 FT_Long L; \ |
| 3187 \ | 3025 \ |
| 3188 \ | 3026 \ |
| 3189 L = args[0]; \ | 3027 L = args[0]; \ |
| 3190 \ | 3028 \ |
| 3191 if ( L <= 0 || L > CUR.args ) \ | 3029 if ( L <= 0 || L > CUR.args ) \ |
| 3192 { \ | 3030 { \ |
| 3193 if ( CUR.pedantic_hinting ) \ | 3031 if ( CUR.pedantic_hinting ) \ |
| 3194 CUR.error = TT_Err_Invalid_Reference; \ | 3032 CUR.error = FT_THROW( Invalid_Reference ); \ |
| 3195 args[0] = 0; \ | 3033 args[0] = 0; \ |
| 3196 } \ | 3034 } \ |
| 3197 else \ | 3035 else \ |
| 3198 args[0] = CUR.stack[CUR.args - L]; \ | 3036 args[0] = CUR.stack[CUR.args - L]; \ |
| 3199 } | 3037 } |
| 3200 | 3038 |
| 3201 | 3039 |
| 3202 #define DO_JROT \ | 3040 #define DO_JROT \ |
| 3203 if ( args[1] != 0 ) \ | 3041 if ( args[1] != 0 ) \ |
| 3204 { \ | 3042 { \ |
| 3205 if ( args[0] == 0 && CUR.args == 0 ) \ | 3043 if ( args[0] == 0 && CUR.args == 0 ) \ |
| 3206 CUR.error = TT_Err_Bad_Argument; \ | 3044 CUR.error = FT_THROW( Bad_Argument ); \ |
| 3207 CUR.IP += args[0]; \ | 3045 CUR.IP += args[0]; \ |
| 3208 if ( CUR.IP < 0 || \ | 3046 if ( CUR.IP < 0 || \ |
| 3209 ( CUR.callTop > 0 && \ | 3047 ( CUR.callTop > 0 && \ |
| 3210 CUR.IP > CUR.callStack[CUR.callTop - 1].Cur_End ) ) \ | 3048 CUR.IP > CUR.callStack[CUR.callTop - 1].Cur_End ) ) \ |
| 3211 CUR.error = TT_Err_Bad_Argument; \ | 3049 CUR.error = FT_THROW( Bad_Argument ); \ |
| 3212 CUR.step_ins = FALSE; \ | 3050 CUR.step_ins = FALSE; \ |
| 3213 } | 3051 } |
| 3214 | 3052 |
| 3215 | 3053 |
| 3216 #define DO_JMPR \ | 3054 #define DO_JMPR \ |
| 3217 if ( args[0] == 0 && CUR.args == 0 ) \ | 3055 if ( args[0] == 0 && CUR.args == 0 ) \ |
| 3218 CUR.error = TT_Err_Bad_Argument; \ | 3056 CUR.error = FT_THROW( Bad_Argument ); \ |
| 3219 CUR.IP += args[0]; \ | 3057 CUR.IP += args[0]; \ |
| 3220 if ( CUR.IP < 0 || \ | 3058 if ( CUR.IP < 0 || \ |
| 3221 ( CUR.callTop > 0 && \ | 3059 ( CUR.callTop > 0 && \ |
| 3222 CUR.IP > CUR.callStack[CUR.callTop - 1].Cur_End ) ) \ | 3060 CUR.IP > CUR.callStack[CUR.callTop - 1].Cur_End ) ) \ |
| 3223 CUR.error = TT_Err_Bad_Argument; \ | 3061 CUR.error = FT_THROW( Bad_Argument ); \ |
| 3224 CUR.step_ins = FALSE; | 3062 CUR.step_ins = FALSE; |
| 3225 | 3063 |
| 3226 | 3064 |
| 3227 #define DO_JROF \ | 3065 #define DO_JROF \ |
| 3228 if ( args[1] == 0 ) \ | 3066 if ( args[1] == 0 ) \ |
| 3229 { \ | 3067 { \ |
| 3230 if ( args[0] == 0 && CUR.args == 0 ) \ | 3068 if ( args[0] == 0 && CUR.args == 0 ) \ |
| 3231 CUR.error = TT_Err_Bad_Argument; \ | 3069 CUR.error = FT_THROW( Bad_Argument ); \ |
| 3232 CUR.IP += args[0]; \ | 3070 CUR.IP += args[0]; \ |
| 3233 if ( CUR.IP < 0 || \ | 3071 if ( CUR.IP < 0 || \ |
| 3234 ( CUR.callTop > 0 && \ | 3072 ( CUR.callTop > 0 && \ |
| 3235 CUR.IP > CUR.callStack[CUR.callTop - 1].Cur_End ) ) \ | 3073 CUR.IP > CUR.callStack[CUR.callTop - 1].Cur_End ) ) \ |
| 3236 CUR.error = TT_Err_Bad_Argument; \ | 3074 CUR.error = FT_THROW( Bad_Argument ); \ |
| 3237 CUR.step_ins = FALSE; \ | 3075 CUR.step_ins = FALSE; \ |
| 3238 } | 3076 } |
| 3239 | 3077 |
| 3240 | 3078 |
| 3241 #define DO_LT \ | 3079 #define DO_LT \ |
| 3242 args[0] = ( args[0] < args[1] ); | 3080 args[0] = ( args[0] < args[1] ); |
| 3243 | 3081 |
| 3244 | 3082 |
| 3245 #define DO_LTEQ \ | 3083 #define DO_LTEQ \ |
| 3246 args[0] = ( args[0] <= args[1] ); | 3084 args[0] = ( args[0] <= args[1] ); |
| (...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3285 #define DO_ADD \ | 3123 #define DO_ADD \ |
| 3286 args[0] += args[1]; | 3124 args[0] += args[1]; |
| 3287 | 3125 |
| 3288 | 3126 |
| 3289 #define DO_SUB \ | 3127 #define DO_SUB \ |
| 3290 args[0] -= args[1]; | 3128 args[0] -= args[1]; |
| 3291 | 3129 |
| 3292 | 3130 |
| 3293 #define DO_DIV \ | 3131 #define DO_DIV \ |
| 3294 if ( args[1] == 0 ) \ | 3132 if ( args[1] == 0 ) \ |
| 3295 CUR.error = TT_Err_Divide_By_Zero; \ | 3133 CUR.error = FT_THROW( Divide_By_Zero ); \ |
| 3296 else \ | 3134 else \ |
| 3297 args[0] = TT_MULDIV_NO_ROUND( args[0], 64L, args[1] ); | 3135 args[0] = FT_MulDiv_No_Round( args[0], 64L, args[1] ); |
| 3298 | 3136 |
| 3299 | 3137 |
| 3300 #define DO_MUL \ | 3138 #define DO_MUL \ |
| 3301 args[0] = TT_MULDIV( args[0], args[1], 64L ); | 3139 args[0] = FT_MulDiv( args[0], args[1], 64L ); |
| 3302 | 3140 |
| 3303 | 3141 |
| 3304 #define DO_ABS \ | 3142 #define DO_ABS \ |
| 3305 args[0] = FT_ABS( args[0] ); | 3143 args[0] = FT_ABS( args[0] ); |
| 3306 | 3144 |
| 3307 | 3145 |
| 3308 #define DO_NEG \ | 3146 #define DO_NEG \ |
| 3309 args[0] = -args[0]; | 3147 args[0] = -args[0]; |
| 3310 | 3148 |
| 3311 | 3149 |
| 3312 #define DO_FLOOR \ | 3150 #define DO_FLOOR \ |
| 3313 args[0] = FT_PIX_FLOOR( args[0] ); | 3151 args[0] = FT_PIX_FLOOR( args[0] ); |
| 3314 | 3152 |
| 3315 | 3153 |
| 3316 #define DO_CEILING \ | 3154 #define DO_CEILING \ |
| 3317 args[0] = FT_PIX_CEIL( args[0] ); | 3155 args[0] = FT_PIX_CEIL( args[0] ); |
| 3318 | 3156 |
| 3157 #ifdef TT_CONFIG_OPTION_SUBPIXEL_HINTING |
| 3158 |
| 3159 #define DO_RS \ |
| 3160 { \ |
| 3161 FT_ULong I = (FT_ULong)args[0]; \ |
| 3162 \ |
| 3163 \ |
| 3164 if ( BOUNDSL( I, CUR.storeSize ) ) \ |
| 3165 { \ |
| 3166 if ( CUR.pedantic_hinting ) \ |
| 3167 ARRAY_BOUND_ERROR; \ |
| 3168 else \ |
| 3169 args[0] = 0; \ |
| 3170 } \ |
| 3171 else \ |
| 3172 { \ |
| 3173 /* subpixel hinting - avoid Typeman Dstroke and */ \ |
| 3174 /* IStroke and Vacuform rounds */ \ |
| 3175 \ |
| 3176 if ( SUBPIXEL_HINTING && \ |
| 3177 CUR.ignore_x_mode && \ |
| 3178 ( ( I == 24 && \ |
| 3179 ( CUR.face->sph_found_func_flags & \ |
| 3180 ( SPH_FDEF_SPACING_1 | \ |
| 3181 SPH_FDEF_SPACING_2 ) ) ) || \ |
| 3182 ( I == 22 && \ |
| 3183 ( CUR.sph_in_func_flags & \ |
| 3184 SPH_FDEF_TYPEMAN_STROKES ) ) || \ |
| 3185 ( I == 8 && \ |
| 3186 ( CUR.face->sph_found_func_flags & \ |
| 3187 SPH_FDEF_VACUFORM_ROUND_1 ) && \ |
| 3188 CUR.iup_called ) ) ) \ |
| 3189 args[0] = 0; \ |
| 3190 else \ |
| 3191 args[0] = CUR.storage[I]; \ |
| 3192 } \ |
| 3193 } |
| 3194 |
| 3195 #else /* !TT_CONFIG_OPTION_SUBPIXEL_HINTING */ |
| 3319 | 3196 |
| 3320 #define DO_RS \ | 3197 #define DO_RS \ |
| 3321 { \ | 3198 { \ |
| 3322 FT_ULong I = (FT_ULong)args[0]; \ | 3199 FT_ULong I = (FT_ULong)args[0]; \ |
| 3323 \ | 3200 \ |
| 3324 \ | 3201 \ |
| 3325 if ( BOUNDSL( I, CUR.storeSize ) ) \ | 3202 if ( BOUNDSL( I, CUR.storeSize ) ) \ |
| 3326 { \ | 3203 { \ |
| 3327 if ( CUR.pedantic_hinting ) \ | 3204 if ( CUR.pedantic_hinting ) \ |
| 3328 { \ | 3205 { \ |
| 3329 ARRAY_BOUND_ERROR; \ | 3206 ARRAY_BOUND_ERROR; \ |
| 3330 } \ | 3207 } \ |
| 3331 else \ | 3208 else \ |
| 3332 args[0] = 0; \ | 3209 args[0] = 0; \ |
| 3333 } \ | 3210 } \ |
| 3334 else \ | 3211 else \ |
| 3335 args[0] = CUR.storage[I]; \ | 3212 args[0] = CUR.storage[I]; \ |
| 3336 } | 3213 } |
| 3337 | 3214 |
| 3215 #endif /* !TT_CONFIG_OPTION_SUBPIXEL_HINTING */ |
| 3216 |
| 3338 | 3217 |
| 3339 #define DO_WS \ | 3218 #define DO_WS \ |
| 3340 { \ | 3219 { \ |
| 3341 FT_ULong I = (FT_ULong)args[0]; \ | 3220 FT_ULong I = (FT_ULong)args[0]; \ |
| 3342 \ | 3221 \ |
| 3343 \ | 3222 \ |
| 3344 if ( BOUNDSL( I, CUR.storeSize ) ) \ | 3223 if ( BOUNDSL( I, CUR.storeSize ) ) \ |
| 3345 { \ | 3224 { \ |
| 3346 if ( CUR.pedantic_hinting ) \ | 3225 if ( CUR.pedantic_hinting ) \ |
| 3347 { \ | 3226 { \ |
| (...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3395 \ | 3274 \ |
| 3396 \ | 3275 \ |
| 3397 if ( BOUNDSL( I, CUR.cvtSize ) ) \ | 3276 if ( BOUNDSL( I, CUR.cvtSize ) ) \ |
| 3398 { \ | 3277 { \ |
| 3399 if ( CUR.pedantic_hinting ) \ | 3278 if ( CUR.pedantic_hinting ) \ |
| 3400 { \ | 3279 { \ |
| 3401 ARRAY_BOUND_ERROR; \ | 3280 ARRAY_BOUND_ERROR; \ |
| 3402 } \ | 3281 } \ |
| 3403 } \ | 3282 } \ |
| 3404 else \ | 3283 else \ |
| 3405 CUR.cvt[I] = TT_MULFIX( args[1], CUR.tt_metrics.scale ); \ | 3284 CUR.cvt[I] = FT_MulFix( args[1], CUR.tt_metrics.scale ); \ |
| 3406 } | 3285 } |
| 3407 | 3286 |
| 3408 | 3287 |
| 3409 #define DO_DEBUG \ | 3288 #define DO_DEBUG \ |
| 3410 CUR.error = TT_Err_Debug_OpCode; | 3289 CUR.error = FT_THROW( Debug_OpCode ); |
| 3411 | 3290 |
| 3412 | 3291 |
| 3413 #define DO_ROUND \ | 3292 #define DO_ROUND \ |
| 3414 args[0] = CUR_Func_round( \ | 3293 args[0] = CUR_Func_round( \ |
| 3415 args[0], \ | 3294 args[0], \ |
| 3416 CUR.tt_metrics.compensations[CUR.opcode - 0x68] ); | 3295 CUR.tt_metrics.compensations[CUR.opcode - 0x68] ); |
| 3417 | 3296 |
| 3418 | 3297 |
| 3419 #define DO_NROUND \ | 3298 #define DO_NROUND \ |
| 3420 args[0] = ROUND_None( args[0], \ | 3299 args[0] = ROUND_None( args[0], \ |
| 3421 CUR.tt_metrics.compensations[CUR.opcode - 0x6C] ); | 3300 CUR.tt_metrics.compensations[CUR.opcode - 0x6C] ); |
| 3422 | 3301 |
| 3423 | 3302 |
| 3424 #define DO_MAX \ | 3303 #define DO_MAX \ |
| 3425 if ( args[1] > args[0] ) \ | 3304 if ( args[1] > args[0] ) \ |
| 3426 args[0] = args[1]; | 3305 args[0] = args[1]; |
| 3427 | 3306 |
| 3428 | 3307 |
| 3429 #define DO_MIN \ | 3308 #define DO_MIN \ |
| 3430 if ( args[1] < args[0] ) \ | 3309 if ( args[1] < args[0] ) \ |
| 3431 args[0] = args[1]; | 3310 args[0] = args[1]; |
| 3432 | 3311 |
| 3433 | 3312 |
| 3434 #ifndef TT_CONFIG_OPTION_INTERPRETER_SWITCH | 3313 #ifndef TT_CONFIG_OPTION_INTERPRETER_SWITCH |
| 3435 | 3314 |
| 3436 | 3315 |
| 3437 #undef ARRAY_BOUND_ERROR | 3316 #undef ARRAY_BOUND_ERROR |
| 3438 #define ARRAY_BOUND_ERROR \ | 3317 #define ARRAY_BOUND_ERROR \ |
| 3439 { \ | 3318 { \ |
| 3440 CUR.error = TT_Err_Invalid_Reference; \ | 3319 CUR.error = FT_THROW( Invalid_Reference ); \ |
| 3441 return; \ | 3320 return; \ |
| 3442 } | 3321 } |
| 3443 | 3322 |
| 3444 | 3323 |
| 3445 /*************************************************************************/ | 3324 /*************************************************************************/ |
| 3446 /* */ | 3325 /* */ |
| 3447 /* SVTCA[a]: Set (F and P) Vectors to Coordinate Axis */ | 3326 /* SVTCA[a]: Set (F and P) Vectors to Coordinate Axis */ |
| 3448 /* Opcode range: 0x00-0x01 */ | 3327 /* Opcode range: 0x00-0x01 */ |
| 3449 /* Stack: --> */ | 3328 /* Stack: --> */ |
| 3450 /* */ | 3329 /* */ |
| 3451 static void | 3330 static void |
| (...skipping 958 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4410 Ins_MINDEX( INS_ARG ) | 4289 Ins_MINDEX( INS_ARG ) |
| 4411 { | 4290 { |
| 4412 FT_Long L, K; | 4291 FT_Long L, K; |
| 4413 | 4292 |
| 4414 | 4293 |
| 4415 L = args[0]; | 4294 L = args[0]; |
| 4416 | 4295 |
| 4417 if ( L <= 0 || L > CUR.args ) | 4296 if ( L <= 0 || L > CUR.args ) |
| 4418 { | 4297 { |
| 4419 if ( CUR.pedantic_hinting ) | 4298 if ( CUR.pedantic_hinting ) |
| 4420 CUR.error = TT_Err_Invalid_Reference; | 4299 CUR.error = FT_THROW( Invalid_Reference ); |
| 4421 } | 4300 } |
| 4422 else | 4301 else |
| 4423 { | 4302 { |
| 4424 K = CUR.stack[CUR.args - L]; | 4303 K = CUR.stack[CUR.args - L]; |
| 4425 | 4304 |
| 4426 FT_ARRAY_MOVE( &CUR.stack[CUR.args - L ], | 4305 FT_ARRAY_MOVE( &CUR.stack[CUR.args - L ], |
| 4427 &CUR.stack[CUR.args - L + 1], | 4306 &CUR.stack[CUR.args - L + 1], |
| 4428 ( L - 1 ) ); | 4307 ( L - 1 ) ); |
| 4429 | 4308 |
| 4430 CUR.stack[CUR.args - 1] = K; | 4309 CUR.stack[CUR.args - 1] = K; |
| (...skipping 49 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4480 if ( CUR.IP + 1 >= CUR.codeSize ) | 4359 if ( CUR.IP + 1 >= CUR.codeSize ) |
| 4481 goto Fail_Overflow; | 4360 goto Fail_Overflow; |
| 4482 CUR.length = 2 - CUR.length * CUR.code[CUR.IP + 1]; | 4361 CUR.length = 2 - CUR.length * CUR.code[CUR.IP + 1]; |
| 4483 } | 4362 } |
| 4484 | 4363 |
| 4485 if ( CUR.IP + CUR.length <= CUR.codeSize ) | 4364 if ( CUR.IP + CUR.length <= CUR.codeSize ) |
| 4486 return SUCCESS; | 4365 return SUCCESS; |
| 4487 } | 4366 } |
| 4488 | 4367 |
| 4489 Fail_Overflow: | 4368 Fail_Overflow: |
| 4490 CUR.error = TT_Err_Code_Overflow; | 4369 CUR.error = FT_THROW( Code_Overflow ); |
| 4491 return FAILURE; | 4370 return FAILURE; |
| 4492 } | 4371 } |
| 4493 | 4372 |
| 4494 | 4373 |
| 4495 /*************************************************************************/ | 4374 /*************************************************************************/ |
| 4496 /* */ | 4375 /* */ |
| 4497 /* IF[]: IF test */ | 4376 /* IF[]: IF test */ |
| 4498 /* Opcode range: 0x58 */ | 4377 /* Opcode range: 0x58 */ |
| 4499 /* Stack: StkElt --> */ | 4378 /* Stack: StkElt --> */ |
| 4500 /* */ | 4379 /* */ |
| (...skipping 84 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4585 /* Opcode range: 0x2C */ | 4464 /* Opcode range: 0x2C */ |
| 4586 /* Stack: uint32 --> */ | 4465 /* Stack: uint32 --> */ |
| 4587 /* */ | 4466 /* */ |
| 4588 static void | 4467 static void |
| 4589 Ins_FDEF( INS_ARG ) | 4468 Ins_FDEF( INS_ARG ) |
| 4590 { | 4469 { |
| 4591 FT_ULong n; | 4470 FT_ULong n; |
| 4592 TT_DefRecord* rec; | 4471 TT_DefRecord* rec; |
| 4593 TT_DefRecord* limit; | 4472 TT_DefRecord* limit; |
| 4594 | 4473 |
| 4474 #ifdef TT_CONFIG_OPTION_SUBPIXEL_HINTING |
| 4475 /* arguments to opcodes are skipped by `SKIP_Code' */ |
| 4476 FT_Byte opcode_pattern[9][12] = { |
| 4477 /* #0 inline delta function 1 */ |
| 4478 { |
| 4479 0x4B, /* PPEM */ |
| 4480 0x53, /* GTEQ */ |
| 4481 0x23, /* SWAP */ |
| 4482 0x4B, /* PPEM */ |
| 4483 0x51, /* LTEQ */ |
| 4484 0x5A, /* AND */ |
| 4485 0x58, /* IF */ |
| 4486 0x38, /* SHPIX */ |
| 4487 0x1B, /* ELSE */ |
| 4488 0x21, /* POP */ |
| 4489 0x21, /* POP */ |
| 4490 0x59 /* EIF */ |
| 4491 }, |
| 4492 /* #1 inline delta function 2 */ |
| 4493 { |
| 4494 0x4B, /* PPEM */ |
| 4495 0x54, /* EQ */ |
| 4496 0x58, /* IF */ |
| 4497 0x38, /* SHPIX */ |
| 4498 0x1B, /* ELSE */ |
| 4499 0x21, /* POP */ |
| 4500 0x21, /* POP */ |
| 4501 0x59 /* EIF */ |
| 4502 }, |
| 4503 /* #2 diagonal stroke function */ |
| 4504 { |
| 4505 0x20, /* DUP */ |
| 4506 0x20, /* DUP */ |
| 4507 0xB0, /* PUSHB_1 */ |
| 4508 /* 1 */ |
| 4509 0x60, /* ADD */ |
| 4510 0x46, /* GC_cur */ |
| 4511 0xB0, /* PUSHB_1 */ |
| 4512 /* 64 */ |
| 4513 0x23, /* SWAP */ |
| 4514 0x42 /* WS */ |
| 4515 }, |
| 4516 /* #3 VacuFormRound function */ |
| 4517 { |
| 4518 0x45, /* RCVT */ |
| 4519 0x23, /* SWAP */ |
| 4520 0x46, /* GC_cur */ |
| 4521 0x60, /* ADD */ |
| 4522 0x20, /* DUP */ |
| 4523 0xB0 /* PUSHB_1 */ |
| 4524 /* 38 */ |
| 4525 }, |
| 4526 /* #4 TTFautohint bytecode (old) */ |
| 4527 { |
| 4528 0x20, /* DUP */ |
| 4529 0x64, /* ABS */ |
| 4530 0xB0, /* PUSHB_1 */ |
| 4531 /* 32 */ |
| 4532 0x60, /* ADD */ |
| 4533 0x66, /* FLOOR */ |
| 4534 0x23, /* SWAP */ |
| 4535 0xB0 /* PUSHB_1 */ |
| 4536 }, |
| 4537 /* #5 spacing function 1 */ |
| 4538 { |
| 4539 0x01, /* SVTCA_x */ |
| 4540 0xB0, /* PUSHB_1 */ |
| 4541 /* 24 */ |
| 4542 0x43, /* RS */ |
| 4543 0x58 /* IF */ |
| 4544 }, |
| 4545 /* #6 spacing function 2 */ |
| 4546 { |
| 4547 0x01, /* SVTCA_x */ |
| 4548 0x18, /* RTG */ |
| 4549 0xB0, /* PUSHB_1 */ |
| 4550 /* 24 */ |
| 4551 0x43, /* RS */ |
| 4552 0x58 /* IF */ |
| 4553 }, |
| 4554 /* #7 TypeMan Talk DiagEndCtrl function */ |
| 4555 { |
| 4556 0x01, /* SVTCA_x */ |
| 4557 0x20, /* DUP */ |
| 4558 0xB0, /* PUSHB_1 */ |
| 4559 /* 3 */ |
| 4560 0x25, /* CINDEX */ |
| 4561 }, |
| 4562 /* #8 TypeMan Talk Align */ |
| 4563 { |
| 4564 0x06, /* SPVTL */ |
| 4565 0x7D, /* RDTG */ |
| 4566 }, |
| 4567 }; |
| 4568 FT_UShort opcode_patterns = 9; |
| 4569 FT_UShort opcode_pointer[9] = { 0, 0, 0, 0, 0, 0, 0, 0, 0 }; |
| 4570 FT_UShort opcode_size[9] = { 12, 8, 8, 6, 7, 4, 5, 4, 2 }; |
| 4571 FT_UShort i; |
| 4572 #endif /* TT_CONFIG_OPTION_SUBPIXEL_HINTING */ |
| 4573 |
| 4595 | 4574 |
| 4596 /* some font programs are broken enough to redefine functions! */ | 4575 /* some font programs are broken enough to redefine functions! */ |
| 4597 /* We will then parse the current table. */ | 4576 /* We will then parse the current table. */ |
| 4598 | 4577 |
| 4599 rec = CUR.FDefs; | 4578 rec = CUR.FDefs; |
| 4600 limit = rec + CUR.numFDefs; | 4579 limit = rec + CUR.numFDefs; |
| 4601 n = args[0]; | 4580 n = args[0]; |
| 4602 | 4581 |
| 4603 for ( ; rec < limit; rec++ ) | 4582 for ( ; rec < limit; rec++ ) |
| 4604 { | 4583 { |
| 4605 if ( rec->opc == n ) | 4584 if ( rec->opc == n ) |
| 4606 break; | 4585 break; |
| 4607 } | 4586 } |
| 4608 | 4587 |
| 4609 if ( rec == limit ) | 4588 if ( rec == limit ) |
| 4610 { | 4589 { |
| 4611 /* check that there is enough room for new functions */ | 4590 /* check that there is enough room for new functions */ |
| 4612 if ( CUR.numFDefs >= CUR.maxFDefs ) | 4591 if ( CUR.numFDefs >= CUR.maxFDefs ) |
| 4613 { | 4592 { |
| 4614 CUR.error = TT_Err_Too_Many_Function_Defs; | 4593 CUR.error = FT_THROW( Too_Many_Function_Defs ); |
| 4615 return; | 4594 return; |
| 4616 } | 4595 } |
| 4617 CUR.numFDefs++; | 4596 CUR.numFDefs++; |
| 4618 } | 4597 } |
| 4619 | 4598 |
| 4620 /* Although FDEF takes unsigned 32-bit integer, */ | 4599 /* Although FDEF takes unsigned 32-bit integer, */ |
| 4621 /* func # must be within unsigned 16-bit integer */ | 4600 /* func # must be within unsigned 16-bit integer */ |
| 4622 if ( n > 0xFFFFU ) | 4601 if ( n > 0xFFFFU ) |
| 4623 { | 4602 { |
| 4624 CUR.error = TT_Err_Too_Many_Function_Defs; | 4603 CUR.error = FT_THROW( Too_Many_Function_Defs ); |
| 4625 return; | 4604 return; |
| 4626 } | 4605 } |
| 4627 | 4606 |
| 4628 rec->range = CUR.curRange; | 4607 rec->range = CUR.curRange; |
| 4629 rec->opc = (FT_UInt16)n; | 4608 rec->opc = (FT_UInt16)n; |
| 4630 rec->start = CUR.IP + 1; | 4609 rec->start = CUR.IP + 1; |
| 4631 rec->active = TRUE; | 4610 rec->active = TRUE; |
| 4611 rec->inline_delta = FALSE; |
| 4612 rec->sph_fdef_flags = 0x0000; |
| 4632 | 4613 |
| 4633 if ( n > CUR.maxFunc ) | 4614 if ( n > CUR.maxFunc ) |
| 4634 CUR.maxFunc = (FT_UInt16)n; | 4615 CUR.maxFunc = (FT_UInt16)n; |
| 4635 | 4616 |
| 4617 #ifdef TT_CONFIG_OPTION_SUBPIXEL_HINTING |
| 4618 /* We don't know for sure these are typeman functions, */ |
| 4619 /* however they are only active when RS 22 is called */ |
| 4620 if ( n >= 64 && n <= 66 ) |
| 4621 rec->sph_fdef_flags |= SPH_FDEF_TYPEMAN_STROKES; |
| 4622 #endif |
| 4623 |
| 4636 /* Now skip the whole function definition. */ | 4624 /* Now skip the whole function definition. */ |
| 4637 /* We don't allow nested IDEFS & FDEFs. */ | 4625 /* We don't allow nested IDEFS & FDEFs. */ |
| 4638 | 4626 |
| 4639 while ( SKIP_Code() == SUCCESS ) | 4627 while ( SKIP_Code() == SUCCESS ) |
| 4640 { | 4628 { |
| 4629 |
| 4630 #ifdef TT_CONFIG_OPTION_SUBPIXEL_HINTING |
| 4631 |
| 4632 if ( SUBPIXEL_HINTING ) |
| 4633 { |
| 4634 for ( i = 0; i < opcode_patterns; i++ ) |
| 4635 { |
| 4636 if ( opcode_pointer[i] < opcode_size[i] && |
| 4637 CUR.opcode == opcode_pattern[i][opcode_pointer[i]] ) |
| 4638 { |
| 4639 opcode_pointer[i] += 1; |
| 4640 |
| 4641 if ( opcode_pointer[i] == opcode_size[i] ) |
| 4642 { |
| 4643 FT_TRACE7(( "sph: Function %d, opcode ptrn: %d, %s %s\n", |
| 4644 i, n, |
| 4645 CUR.face->root.family_name, |
| 4646 CUR.face->root.style_name )); |
| 4647 |
| 4648 switch ( i ) |
| 4649 { |
| 4650 case 0: |
| 4651 rec->sph_fdef_flags |= SPH_FDEF_INLINE_DELTA_1; |
| 4652 CUR.face->sph_found_func_flags |= SPH_FDEF_INLINE_DELTA_1; |
| 4653 break; |
| 4654 |
| 4655 case 1: |
| 4656 rec->sph_fdef_flags |= SPH_FDEF_INLINE_DELTA_2; |
| 4657 CUR.face->sph_found_func_flags |= SPH_FDEF_INLINE_DELTA_2; |
| 4658 break; |
| 4659 |
| 4660 case 2: |
| 4661 switch ( n ) |
| 4662 { |
| 4663 /* needs to be implemented still */ |
| 4664 case 58: |
| 4665 rec->sph_fdef_flags |= SPH_FDEF_DIAGONAL_STROKE; |
| 4666 CUR.face->sph_found_func_flags |= SPH_FDEF_DIAGONAL_STROKE; |
| 4667 } |
| 4668 break; |
| 4669 |
| 4670 case 3: |
| 4671 switch ( n ) |
| 4672 { |
| 4673 case 0: |
| 4674 rec->sph_fdef_flags |= SPH_FDEF_VACUFORM_ROUND_1; |
| 4675 CUR.face->sph_found_func_flags |= SPH_FDEF_VACUFORM_ROUND_1; |
| 4676 } |
| 4677 break; |
| 4678 |
| 4679 case 4: |
| 4680 /* probably not necessary to detect anymore */ |
| 4681 rec->sph_fdef_flags |= SPH_FDEF_TTFAUTOHINT_1; |
| 4682 CUR.face->sph_found_func_flags |= SPH_FDEF_TTFAUTOHINT_1; |
| 4683 break; |
| 4684 |
| 4685 case 5: |
| 4686 switch ( n ) |
| 4687 { |
| 4688 case 0: |
| 4689 case 1: |
| 4690 case 2: |
| 4691 case 4: |
| 4692 case 7: |
| 4693 case 8: |
| 4694 rec->sph_fdef_flags |= SPH_FDEF_SPACING_1; |
| 4695 CUR.face->sph_found_func_flags |= SPH_FDEF_SPACING_1; |
| 4696 } |
| 4697 break; |
| 4698 |
| 4699 case 6: |
| 4700 switch ( n ) |
| 4701 { |
| 4702 case 0: |
| 4703 case 1: |
| 4704 case 2: |
| 4705 case 4: |
| 4706 case 7: |
| 4707 case 8: |
| 4708 rec->sph_fdef_flags |= SPH_FDEF_SPACING_2; |
| 4709 CUR.face->sph_found_func_flags |= SPH_FDEF_SPACING_2; |
| 4710 } |
| 4711 break; |
| 4712 |
| 4713 case 7: |
| 4714 rec->sph_fdef_flags |= SPH_FDEF_TYPEMAN_DIAGENDCTRL; |
| 4715 CUR.face->sph_found_func_flags |= SPH_FDEF_TYPEMAN_DIAGENDCTRL; |
| 4716 break; |
| 4717 |
| 4718 case 8: |
| 4719 #if 0 |
| 4720 rec->sph_fdef_flags |= SPH_FDEF_TYPEMAN_DIAGENDCTRL; |
| 4721 CUR.face->sph_found_func_flags |= SPH_FDEF_TYPEMAN_DIAGENDCTRL; |
| 4722 #endif |
| 4723 break; |
| 4724 } |
| 4725 opcode_pointer[i] = 0; |
| 4726 } |
| 4727 } |
| 4728 |
| 4729 else |
| 4730 opcode_pointer[i] = 0; |
| 4731 } |
| 4732 |
| 4733 /* Set sph_compatibility_mode only when deltas are detected */ |
| 4734 CUR.face->sph_compatibility_mode = |
| 4735 ( ( CUR.face->sph_found_func_flags & SPH_FDEF_INLINE_DELTA_1 ) | |
| 4736 ( CUR.face->sph_found_func_flags & SPH_FDEF_INLINE_DELTA_2 ) ); |
| 4737 } |
| 4738 |
| 4739 #endif /* TT_CONFIG_OPTION_SUBPIXEL_HINTING */ |
| 4740 |
| 4641 switch ( CUR.opcode ) | 4741 switch ( CUR.opcode ) |
| 4642 { | 4742 { |
| 4643 case 0x89: /* IDEF */ | 4743 case 0x89: /* IDEF */ |
| 4644 case 0x2C: /* FDEF */ | 4744 case 0x2C: /* FDEF */ |
| 4645 CUR.error = TT_Err_Nested_DEFS; | 4745 CUR.error = FT_THROW( Nested_DEFS ); |
| 4646 return; | 4746 return; |
| 4647 | 4747 |
| 4648 case 0x2D: /* ENDF */ | 4748 case 0x2D: /* ENDF */ |
| 4649 rec->end = CUR.IP; | 4749 rec->end = CUR.IP; |
| 4650 return; | 4750 return; |
| 4651 } | 4751 } |
| 4652 } | 4752 } |
| 4653 } | 4753 } |
| 4654 | 4754 |
| 4655 | 4755 |
| 4656 /*************************************************************************/ | 4756 /*************************************************************************/ |
| 4657 /* */ | 4757 /* */ |
| 4658 /* ENDF[]: END Function definition */ | 4758 /* ENDF[]: END Function definition */ |
| 4659 /* Opcode range: 0x2D */ | 4759 /* Opcode range: 0x2D */ |
| 4660 /* Stack: --> */ | 4760 /* Stack: --> */ |
| 4661 /* */ | 4761 /* */ |
| 4662 static void | 4762 static void |
| 4663 Ins_ENDF( INS_ARG ) | 4763 Ins_ENDF( INS_ARG ) |
| 4664 { | 4764 { |
| 4665 TT_CallRec* pRec; | 4765 TT_CallRec* pRec; |
| 4666 | 4766 |
| 4667 FT_UNUSED_ARG; | 4767 FT_UNUSED_ARG; |
| 4668 | 4768 |
| 4669 | 4769 |
| 4770 #ifdef TT_CONFIG_OPTION_SUBPIXEL_HINTING |
| 4771 CUR.sph_in_func_flags = 0x0000; |
| 4772 #endif /* TT_CONFIG_OPTION_SUBPIXEL_HINTING */ |
| 4773 |
| 4670 if ( CUR.callTop <= 0 ) /* We encountered an ENDF without a call */ | 4774 if ( CUR.callTop <= 0 ) /* We encountered an ENDF without a call */ |
| 4671 { | 4775 { |
| 4672 CUR.error = TT_Err_ENDF_In_Exec_Stream; | 4776 CUR.error = FT_THROW( ENDF_In_Exec_Stream ); |
| 4673 return; | 4777 return; |
| 4674 } | 4778 } |
| 4675 | 4779 |
| 4676 CUR.callTop--; | 4780 CUR.callTop--; |
| 4677 | 4781 |
| 4678 pRec = &CUR.callStack[CUR.callTop]; | 4782 pRec = &CUR.callStack[CUR.callTop]; |
| 4679 | 4783 |
| 4680 pRec->Cur_Count--; | 4784 pRec->Cur_Count--; |
| 4681 | 4785 |
| 4682 CUR.step_ins = FALSE; | 4786 CUR.step_ins = FALSE; |
| (...skipping 61 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4744 def++; | 4848 def++; |
| 4745 | 4849 |
| 4746 if ( def == limit ) | 4850 if ( def == limit ) |
| 4747 goto Fail; | 4851 goto Fail; |
| 4748 } | 4852 } |
| 4749 | 4853 |
| 4750 /* check that the function is active */ | 4854 /* check that the function is active */ |
| 4751 if ( !def->active ) | 4855 if ( !def->active ) |
| 4752 goto Fail; | 4856 goto Fail; |
| 4753 | 4857 |
| 4858 #ifdef TT_CONFIG_OPTION_SUBPIXEL_HINTING |
| 4859 if ( SUBPIXEL_HINTING && |
| 4860 CUR.ignore_x_mode && |
| 4861 ( ( CUR.iup_called && |
| 4862 ( CUR.sph_tweak_flags & SPH_TWEAK_NO_CALL_AFTER_IUP ) ) || |
| 4863 ( def->sph_fdef_flags & SPH_FDEF_VACUFORM_ROUND_1 ) ) ) |
| 4864 goto Fail; |
| 4865 else |
| 4866 CUR.sph_in_func_flags = def->sph_fdef_flags; |
| 4867 #endif /* TT_CONFIG_OPTION_SUBPIXEL_HINTING */ |
| 4868 |
| 4754 /* check the call stack */ | 4869 /* check the call stack */ |
| 4755 if ( CUR.callTop >= CUR.callSize ) | 4870 if ( CUR.callTop >= CUR.callSize ) |
| 4756 { | 4871 { |
| 4757 CUR.error = TT_Err_Stack_Overflow; | 4872 CUR.error = FT_THROW( Stack_Overflow ); |
| 4758 return; | 4873 return; |
| 4759 } | 4874 } |
| 4760 | 4875 |
| 4761 pCrec = CUR.callStack + CUR.callTop; | 4876 pCrec = CUR.callStack + CUR.callTop; |
| 4762 | 4877 |
| 4763 pCrec->Caller_Range = CUR.curRange; | 4878 pCrec->Caller_Range = CUR.curRange; |
| 4764 pCrec->Caller_IP = CUR.IP + 1; | 4879 pCrec->Caller_IP = CUR.IP + 1; |
| 4765 pCrec->Cur_Count = 1; | 4880 pCrec->Cur_Count = 1; |
| 4766 pCrec->Cur_Restart = def->start; | 4881 pCrec->Cur_Restart = def->start; |
| 4767 pCrec->Cur_End = def->end; | 4882 pCrec->Cur_End = def->end; |
| 4768 | 4883 |
| 4769 CUR.callTop++; | 4884 CUR.callTop++; |
| 4770 | 4885 |
| 4771 INS_Goto_CodeRange( def->range, | 4886 INS_Goto_CodeRange( def->range, |
| 4772 def->start ); | 4887 def->start ); |
| 4773 | 4888 |
| 4774 CUR.step_ins = FALSE; | 4889 CUR.step_ins = FALSE; |
| 4890 |
| 4775 return; | 4891 return; |
| 4776 | 4892 |
| 4777 Fail: | 4893 Fail: |
| 4778 CUR.error = TT_Err_Invalid_Reference; | 4894 CUR.error = FT_THROW( Invalid_Reference ); |
| 4779 } | 4895 } |
| 4780 | 4896 |
| 4781 | 4897 |
| 4782 /*************************************************************************/ | 4898 /*************************************************************************/ |
| 4783 /* */ | 4899 /* */ |
| 4784 /* LOOPCALL[]: LOOP and CALL function */ | 4900 /* LOOPCALL[]: LOOP and CALL function */ |
| 4785 /* Opcode range: 0x2A */ | 4901 /* Opcode range: 0x2A */ |
| 4786 /* Stack: uint32? Eint16? --> */ | 4902 /* Stack: uint32? Eint16? --> */ |
| 4787 /* */ | 4903 /* */ |
| 4788 static void | 4904 static void |
| (...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4821 def++; | 4937 def++; |
| 4822 | 4938 |
| 4823 if ( def == limit ) | 4939 if ( def == limit ) |
| 4824 goto Fail; | 4940 goto Fail; |
| 4825 } | 4941 } |
| 4826 | 4942 |
| 4827 /* check that the function is active */ | 4943 /* check that the function is active */ |
| 4828 if ( !def->active ) | 4944 if ( !def->active ) |
| 4829 goto Fail; | 4945 goto Fail; |
| 4830 | 4946 |
| 4947 #ifdef TT_CONFIG_OPTION_SUBPIXEL_HINTING |
| 4948 if ( SUBPIXEL_HINTING && |
| 4949 CUR.ignore_x_mode && |
| 4950 ( def->sph_fdef_flags & SPH_FDEF_VACUFORM_ROUND_1 ) ) |
| 4951 goto Fail; |
| 4952 else |
| 4953 CUR.sph_in_func_flags = def->sph_fdef_flags; |
| 4954 #endif /* TT_CONFIG_OPTION_SUBPIXEL_HINTING */ |
| 4955 |
| 4831 /* check stack */ | 4956 /* check stack */ |
| 4832 if ( CUR.callTop >= CUR.callSize ) | 4957 if ( CUR.callTop >= CUR.callSize ) |
| 4833 { | 4958 { |
| 4834 CUR.error = TT_Err_Stack_Overflow; | 4959 CUR.error = FT_THROW( Stack_Overflow ); |
| 4835 return; | 4960 return; |
| 4836 } | 4961 } |
| 4837 | 4962 |
| 4838 if ( args[0] > 0 ) | 4963 if ( args[0] > 0 ) |
| 4839 { | 4964 { |
| 4840 pCrec = CUR.callStack + CUR.callTop; | 4965 pCrec = CUR.callStack + CUR.callTop; |
| 4841 | 4966 |
| 4842 pCrec->Caller_Range = CUR.curRange; | 4967 pCrec->Caller_Range = CUR.curRange; |
| 4843 pCrec->Caller_IP = CUR.IP + 1; | 4968 pCrec->Caller_IP = CUR.IP + 1; |
| 4844 pCrec->Cur_Count = (FT_Int)args[0]; | 4969 pCrec->Cur_Count = (FT_Int)args[0]; |
| 4845 pCrec->Cur_Restart = def->start; | 4970 pCrec->Cur_Restart = def->start; |
| 4846 pCrec->Cur_End = def->end; | 4971 pCrec->Cur_End = def->end; |
| 4847 | 4972 |
| 4848 CUR.callTop++; | 4973 CUR.callTop++; |
| 4849 | 4974 |
| 4850 INS_Goto_CodeRange( def->range, def->start ); | 4975 INS_Goto_CodeRange( def->range, def->start ); |
| 4851 | 4976 |
| 4852 CUR.step_ins = FALSE; | 4977 CUR.step_ins = FALSE; |
| 4853 } | 4978 } |
| 4979 |
| 4854 return; | 4980 return; |
| 4855 | 4981 |
| 4856 Fail: | 4982 Fail: |
| 4857 CUR.error = TT_Err_Invalid_Reference; | 4983 CUR.error = FT_THROW( Invalid_Reference ); |
| 4858 } | 4984 } |
| 4859 | 4985 |
| 4860 | 4986 |
| 4861 /*************************************************************************/ | 4987 /*************************************************************************/ |
| 4862 /* */ | 4988 /* */ |
| 4863 /* IDEF[]: Instruction DEFinition */ | 4989 /* IDEF[]: Instruction DEFinition */ |
| 4864 /* Opcode range: 0x89 */ | 4990 /* Opcode range: 0x89 */ |
| 4865 /* Stack: Eint8 --> */ | 4991 /* Stack: Eint8 --> */ |
| 4866 /* */ | 4992 /* */ |
| 4867 static void | 4993 static void |
| (...skipping 10 matching lines...) Expand all Loading... |
| 4878 | 5004 |
| 4879 for ( ; def < limit; def++ ) | 5005 for ( ; def < limit; def++ ) |
| 4880 if ( def->opc == (FT_ULong)args[0] ) | 5006 if ( def->opc == (FT_ULong)args[0] ) |
| 4881 break; | 5007 break; |
| 4882 | 5008 |
| 4883 if ( def == limit ) | 5009 if ( def == limit ) |
| 4884 { | 5010 { |
| 4885 /* check that there is enough room for a new instruction */ | 5011 /* check that there is enough room for a new instruction */ |
| 4886 if ( CUR.numIDefs >= CUR.maxIDefs ) | 5012 if ( CUR.numIDefs >= CUR.maxIDefs ) |
| 4887 { | 5013 { |
| 4888 CUR.error = TT_Err_Too_Many_Instruction_Defs; | 5014 CUR.error = FT_THROW( Too_Many_Instruction_Defs ); |
| 4889 return; | 5015 return; |
| 4890 } | 5016 } |
| 4891 CUR.numIDefs++; | 5017 CUR.numIDefs++; |
| 4892 } | 5018 } |
| 4893 | 5019 |
| 4894 /* opcode must be unsigned 8-bit integer */ | 5020 /* opcode must be unsigned 8-bit integer */ |
| 4895 if ( 0 > args[0] || args[0] > 0x00FF ) | 5021 if ( 0 > args[0] || args[0] > 0x00FF ) |
| 4896 { | 5022 { |
| 4897 CUR.error = TT_Err_Too_Many_Instruction_Defs; | 5023 CUR.error = FT_THROW( Too_Many_Instruction_Defs ); |
| 4898 return; | 5024 return; |
| 4899 } | 5025 } |
| 4900 | 5026 |
| 4901 def->opc = (FT_Byte)args[0]; | 5027 def->opc = (FT_Byte)args[0]; |
| 4902 def->start = CUR.IP + 1; | 5028 def->start = CUR.IP + 1; |
| 4903 def->range = CUR.curRange; | 5029 def->range = CUR.curRange; |
| 4904 def->active = TRUE; | 5030 def->active = TRUE; |
| 4905 | 5031 |
| 4906 if ( (FT_ULong)args[0] > CUR.maxIns ) | 5032 if ( (FT_ULong)args[0] > CUR.maxIns ) |
| 4907 CUR.maxIns = (FT_Byte)args[0]; | 5033 CUR.maxIns = (FT_Byte)args[0]; |
| 4908 | 5034 |
| 4909 /* Now skip the whole function definition. */ | 5035 /* Now skip the whole function definition. */ |
| 4910 /* We don't allow nested IDEFs & FDEFs. */ | 5036 /* We don't allow nested IDEFs & FDEFs. */ |
| 4911 | 5037 |
| 4912 while ( SKIP_Code() == SUCCESS ) | 5038 while ( SKIP_Code() == SUCCESS ) |
| 4913 { | 5039 { |
| 4914 switch ( CUR.opcode ) | 5040 switch ( CUR.opcode ) |
| 4915 { | 5041 { |
| 4916 case 0x89: /* IDEF */ | 5042 case 0x89: /* IDEF */ |
| 4917 case 0x2C: /* FDEF */ | 5043 case 0x2C: /* FDEF */ |
| 4918 CUR.error = TT_Err_Nested_DEFS; | 5044 CUR.error = FT_THROW( Nested_DEFS ); |
| 4919 return; | 5045 return; |
| 4920 case 0x2D: /* ENDF */ | 5046 case 0x2D: /* ENDF */ |
| 4921 return; | 5047 return; |
| 4922 } | 5048 } |
| 4923 } | 5049 } |
| 4924 } | 5050 } |
| 4925 | 5051 |
| 4926 | 5052 |
| 4927 /*************************************************************************/ | 5053 /*************************************************************************/ |
| 4928 /* */ | 5054 /* */ |
| (...skipping 13 matching lines...) Expand all Loading... |
| 4942 static void | 5068 static void |
| 4943 Ins_NPUSHB( INS_ARG ) | 5069 Ins_NPUSHB( INS_ARG ) |
| 4944 { | 5070 { |
| 4945 FT_UShort L, K; | 5071 FT_UShort L, K; |
| 4946 | 5072 |
| 4947 | 5073 |
| 4948 L = (FT_UShort)CUR.code[CUR.IP + 1]; | 5074 L = (FT_UShort)CUR.code[CUR.IP + 1]; |
| 4949 | 5075 |
| 4950 if ( BOUNDS( L, CUR.stackSize + 1 - CUR.top ) ) | 5076 if ( BOUNDS( L, CUR.stackSize + 1 - CUR.top ) ) |
| 4951 { | 5077 { |
| 4952 CUR.error = TT_Err_Stack_Overflow; | 5078 CUR.error = FT_THROW( Stack_Overflow ); |
| 4953 return; | 5079 return; |
| 4954 } | 5080 } |
| 4955 | 5081 |
| 4956 for ( K = 1; K <= L; K++ ) | 5082 for ( K = 1; K <= L; K++ ) |
| 4957 args[K - 1] = CUR.code[CUR.IP + K + 1]; | 5083 args[K - 1] = CUR.code[CUR.IP + K + 1]; |
| 4958 | 5084 |
| 4959 CUR.new_top += L; | 5085 CUR.new_top += L; |
| 4960 } | 5086 } |
| 4961 | 5087 |
| 4962 | 5088 |
| 4963 /*************************************************************************/ | 5089 /*************************************************************************/ |
| 4964 /* */ | 5090 /* */ |
| 4965 /* NPUSHW[]: PUSH N Words */ | 5091 /* NPUSHW[]: PUSH N Words */ |
| 4966 /* Opcode range: 0x41 */ | 5092 /* Opcode range: 0x41 */ |
| 4967 /* Stack: --> int32... */ | 5093 /* Stack: --> int32... */ |
| 4968 /* */ | 5094 /* */ |
| 4969 static void | 5095 static void |
| 4970 Ins_NPUSHW( INS_ARG ) | 5096 Ins_NPUSHW( INS_ARG ) |
| 4971 { | 5097 { |
| 4972 FT_UShort L, K; | 5098 FT_UShort L, K; |
| 4973 | 5099 |
| 4974 | 5100 |
| 4975 L = (FT_UShort)CUR.code[CUR.IP + 1]; | 5101 L = (FT_UShort)CUR.code[CUR.IP + 1]; |
| 4976 | 5102 |
| 4977 if ( BOUNDS( L, CUR.stackSize + 1 - CUR.top ) ) | 5103 if ( BOUNDS( L, CUR.stackSize + 1 - CUR.top ) ) |
| 4978 { | 5104 { |
| 4979 CUR.error = TT_Err_Stack_Overflow; | 5105 CUR.error = FT_THROW( Stack_Overflow ); |
| 4980 return; | 5106 return; |
| 4981 } | 5107 } |
| 4982 | 5108 |
| 4983 CUR.IP += 2; | 5109 CUR.IP += 2; |
| 4984 | 5110 |
| 4985 for ( K = 0; K < L; K++ ) | 5111 for ( K = 0; K < L; K++ ) |
| 4986 args[K] = GET_ShortIns(); | 5112 args[K] = GET_ShortIns(); |
| 4987 | 5113 |
| 4988 CUR.step_ins = FALSE; | 5114 CUR.step_ins = FALSE; |
| 4989 CUR.new_top += L; | 5115 CUR.new_top += L; |
| 4990 } | 5116 } |
| 4991 | 5117 |
| 4992 | 5118 |
| 4993 /*************************************************************************/ | 5119 /*************************************************************************/ |
| 4994 /* */ | 5120 /* */ |
| 4995 /* PUSHB[abc]: PUSH Bytes */ | 5121 /* PUSHB[abc]: PUSH Bytes */ |
| 4996 /* Opcode range: 0xB0-0xB7 */ | 5122 /* Opcode range: 0xB0-0xB7 */ |
| 4997 /* Stack: --> uint32... */ | 5123 /* Stack: --> uint32... */ |
| 4998 /* */ | 5124 /* */ |
| 4999 static void | 5125 static void |
| 5000 Ins_PUSHB( INS_ARG ) | 5126 Ins_PUSHB( INS_ARG ) |
| 5001 { | 5127 { |
| 5002 FT_UShort L, K; | 5128 FT_UShort L, K; |
| 5003 | 5129 |
| 5004 | 5130 |
| 5005 L = (FT_UShort)( CUR.opcode - 0xB0 + 1 ); | 5131 L = (FT_UShort)( CUR.opcode - 0xB0 + 1 ); |
| 5006 | 5132 |
| 5007 if ( BOUNDS( L, CUR.stackSize + 1 - CUR.top ) ) | 5133 if ( BOUNDS( L, CUR.stackSize + 1 - CUR.top ) ) |
| 5008 { | 5134 { |
| 5009 CUR.error = TT_Err_Stack_Overflow; | 5135 CUR.error = FT_THROW( Stack_Overflow ); |
| 5010 return; | 5136 return; |
| 5011 } | 5137 } |
| 5012 | 5138 |
| 5013 for ( K = 1; K <= L; K++ ) | 5139 for ( K = 1; K <= L; K++ ) |
| 5014 args[K - 1] = CUR.code[CUR.IP + K]; | 5140 args[K - 1] = CUR.code[CUR.IP + K]; |
| 5015 } | 5141 } |
| 5016 | 5142 |
| 5017 | 5143 |
| 5018 /*************************************************************************/ | 5144 /*************************************************************************/ |
| 5019 /* */ | 5145 /* */ |
| 5020 /* PUSHW[abc]: PUSH Words */ | 5146 /* PUSHW[abc]: PUSH Words */ |
| 5021 /* Opcode range: 0xB8-0xBF */ | 5147 /* Opcode range: 0xB8-0xBF */ |
| 5022 /* Stack: --> int32... */ | 5148 /* Stack: --> int32... */ |
| 5023 /* */ | 5149 /* */ |
| 5024 static void | 5150 static void |
| 5025 Ins_PUSHW( INS_ARG ) | 5151 Ins_PUSHW( INS_ARG ) |
| 5026 { | 5152 { |
| 5027 FT_UShort L, K; | 5153 FT_UShort L, K; |
| 5028 | 5154 |
| 5029 | 5155 |
| 5030 L = (FT_UShort)( CUR.opcode - 0xB8 + 1 ); | 5156 L = (FT_UShort)( CUR.opcode - 0xB8 + 1 ); |
| 5031 | 5157 |
| 5032 if ( BOUNDS( L, CUR.stackSize + 1 - CUR.top ) ) | 5158 if ( BOUNDS( L, CUR.stackSize + 1 - CUR.top ) ) |
| 5033 { | 5159 { |
| 5034 CUR.error = TT_Err_Stack_Overflow; | 5160 CUR.error = FT_THROW( Stack_Overflow ); |
| 5035 return; | 5161 return; |
| 5036 } | 5162 } |
| 5037 | 5163 |
| 5038 CUR.IP++; | 5164 CUR.IP++; |
| 5039 | 5165 |
| 5040 for ( K = 0; K < L; K++ ) | 5166 for ( K = 0; K < L; K++ ) |
| 5041 args[K] = GET_ShortIns(); | 5167 args[K] = GET_ShortIns(); |
| 5042 | 5168 |
| 5043 CUR.step_ins = FALSE; | 5169 CUR.step_ins = FALSE; |
| 5044 } | 5170 } |
| (...skipping 22 matching lines...) Expand all Loading... |
| 5067 { | 5193 { |
| 5068 FT_ULong L; | 5194 FT_ULong L; |
| 5069 FT_F26Dot6 R; | 5195 FT_F26Dot6 R; |
| 5070 | 5196 |
| 5071 | 5197 |
| 5072 L = (FT_ULong)args[0]; | 5198 L = (FT_ULong)args[0]; |
| 5073 | 5199 |
| 5074 if ( BOUNDSL( L, CUR.zp2.n_points ) ) | 5200 if ( BOUNDSL( L, CUR.zp2.n_points ) ) |
| 5075 { | 5201 { |
| 5076 if ( CUR.pedantic_hinting ) | 5202 if ( CUR.pedantic_hinting ) |
| 5077 CUR.error = TT_Err_Invalid_Reference; | 5203 CUR.error = FT_THROW( Invalid_Reference ); |
| 5078 R = 0; | 5204 R = 0; |
| 5079 } | 5205 } |
| 5080 else | 5206 else |
| 5081 { | 5207 { |
| 5082 if ( CUR.opcode & 1 ) | 5208 if ( CUR.opcode & 1 ) |
| 5083 R = CUR_fast_dualproj( &CUR.zp2.org[L] ); | 5209 R = CUR_fast_dualproj( &CUR.zp2.org[L] ); |
| 5084 else | 5210 else |
| 5085 R = CUR_fast_project( &CUR.zp2.cur[L] ); | 5211 R = CUR_fast_project( &CUR.zp2.cur[L] ); |
| 5086 } | 5212 } |
| 5087 | 5213 |
| (...skipping 16 matching lines...) Expand all Loading... |
| 5104 { | 5230 { |
| 5105 FT_Long K; | 5231 FT_Long K; |
| 5106 FT_UShort L; | 5232 FT_UShort L; |
| 5107 | 5233 |
| 5108 | 5234 |
| 5109 L = (FT_UShort)args[0]; | 5235 L = (FT_UShort)args[0]; |
| 5110 | 5236 |
| 5111 if ( BOUNDS( L, CUR.zp2.n_points ) ) | 5237 if ( BOUNDS( L, CUR.zp2.n_points ) ) |
| 5112 { | 5238 { |
| 5113 if ( CUR.pedantic_hinting ) | 5239 if ( CUR.pedantic_hinting ) |
| 5114 CUR.error = TT_Err_Invalid_Reference; | 5240 CUR.error = FT_THROW( Invalid_Reference ); |
| 5115 return; | 5241 return; |
| 5116 } | 5242 } |
| 5117 | 5243 |
| 5118 K = CUR_fast_project( &CUR.zp2.cur[L] ); | 5244 K = CUR_fast_project( &CUR.zp2.cur[L] ); |
| 5119 | 5245 |
| 5120 CUR_Func_move( &CUR.zp2, L, args[1] - K ); | 5246 CUR_Func_move( &CUR.zp2, L, args[1] - K ); |
| 5121 | 5247 |
| 5122 /* UNDOCUMENTED! The MS rasterizer does that with */ | 5248 /* UNDOCUMENTED! The MS rasterizer does that with */ |
| 5123 /* twilight points (confirmed by Greg Hitchcock) */ | 5249 /* twilight points (confirmed by Greg Hitchcock) */ |
| 5124 if ( CUR.GS.gep2 == 0 ) | 5250 if ( CUR.GS.gep2 == 0 ) |
| (...skipping 23 matching lines...) Expand all Loading... |
| 5148 FT_F26Dot6 D; | 5274 FT_F26Dot6 D; |
| 5149 | 5275 |
| 5150 | 5276 |
| 5151 K = (FT_UShort)args[1]; | 5277 K = (FT_UShort)args[1]; |
| 5152 L = (FT_UShort)args[0]; | 5278 L = (FT_UShort)args[0]; |
| 5153 | 5279 |
| 5154 if ( BOUNDS( L, CUR.zp0.n_points ) || | 5280 if ( BOUNDS( L, CUR.zp0.n_points ) || |
| 5155 BOUNDS( K, CUR.zp1.n_points ) ) | 5281 BOUNDS( K, CUR.zp1.n_points ) ) |
| 5156 { | 5282 { |
| 5157 if ( CUR.pedantic_hinting ) | 5283 if ( CUR.pedantic_hinting ) |
| 5158 CUR.error = TT_Err_Invalid_Reference; | 5284 CUR.error = FT_THROW( Invalid_Reference ); |
| 5159 D = 0; | 5285 D = 0; |
| 5160 } | 5286 } |
| 5161 else | 5287 else |
| 5162 { | 5288 { |
| 5163 if ( CUR.opcode & 1 ) | 5289 if ( CUR.opcode & 1 ) |
| 5164 D = CUR_Func_project( CUR.zp0.cur + L, CUR.zp1.cur + K ); | 5290 D = CUR_Func_project( CUR.zp0.cur + L, CUR.zp1.cur + K ); |
| 5165 else | 5291 else |
| 5166 { | 5292 { |
| 5167 /* XXX: UNDOCUMENTED: twilight zone special case */ | 5293 /* XXX: UNDOCUMENTED: twilight zone special case */ |
| 5168 | 5294 |
| 5169 if ( CUR.GS.gep0 == 0 || CUR.GS.gep1 == 0 ) | 5295 if ( CUR.GS.gep0 == 0 || CUR.GS.gep1 == 0 ) |
| 5170 { | 5296 { |
| 5171 FT_Vector* vec1 = CUR.zp0.org + L; | 5297 FT_Vector* vec1 = CUR.zp0.org + L; |
| 5172 FT_Vector* vec2 = CUR.zp1.org + K; | 5298 FT_Vector* vec2 = CUR.zp1.org + K; |
| 5173 | 5299 |
| 5174 | 5300 |
| 5175 D = CUR_Func_dualproj( vec1, vec2 ); | 5301 D = CUR_Func_dualproj( vec1, vec2 ); |
| 5176 } | 5302 } |
| 5177 else | 5303 else |
| 5178 { | 5304 { |
| 5179 FT_Vector* vec1 = CUR.zp0.orus + L; | 5305 FT_Vector* vec1 = CUR.zp0.orus + L; |
| 5180 FT_Vector* vec2 = CUR.zp1.orus + K; | 5306 FT_Vector* vec2 = CUR.zp1.orus + K; |
| 5181 | 5307 |
| 5182 | 5308 |
| 5183 if ( CUR.metrics.x_scale == CUR.metrics.y_scale ) | 5309 if ( CUR.metrics.x_scale == CUR.metrics.y_scale ) |
| 5184 { | 5310 { |
| 5185 /* this should be faster */ | 5311 /* this should be faster */ |
| 5186 D = CUR_Func_dualproj( vec1, vec2 ); | 5312 D = CUR_Func_dualproj( vec1, vec2 ); |
| 5187 D = TT_MULFIX( D, CUR.metrics.x_scale ); | 5313 D = FT_MulFix( D, CUR.metrics.x_scale ); |
| 5188 } | 5314 } |
| 5189 else | 5315 else |
| 5190 { | 5316 { |
| 5191 FT_Vector vec; | 5317 FT_Vector vec; |
| 5192 | 5318 |
| 5193 | 5319 |
| 5194 vec.x = TT_MULFIX( vec1->x - vec2->x, CUR.metrics.x_scale ); | 5320 vec.x = FT_MulFix( vec1->x - vec2->x, CUR.metrics.x_scale ); |
| 5195 vec.y = TT_MULFIX( vec1->y - vec2->y, CUR.metrics.y_scale ); | 5321 vec.y = FT_MulFix( vec1->y - vec2->y, CUR.metrics.y_scale ); |
| 5196 | 5322 |
| 5197 D = CUR_fast_dualproj( &vec ); | 5323 D = CUR_fast_dualproj( &vec ); |
| 5198 } | 5324 } |
| 5199 } | 5325 } |
| 5200 } | 5326 } |
| 5201 } | 5327 } |
| 5202 | 5328 |
| 5329 #ifdef TT_CONFIG_OPTION_SUBPIXEL_HINTING |
| 5330 /* Disable Type 2 Vacuform Rounds - e.g. Arial Narrow */ |
| 5331 if ( SUBPIXEL_HINTING && |
| 5332 CUR.ignore_x_mode && FT_ABS( D ) == 64 ) |
| 5333 D += 1; |
| 5334 #endif /* TT_CONFIG_OPTION_SUBPIXEL_HINTING */ |
| 5335 |
| 5203 args[0] = D; | 5336 args[0] = D; |
| 5204 } | 5337 } |
| 5205 | 5338 |
| 5206 | 5339 |
| 5207 /*************************************************************************/ | 5340 /*************************************************************************/ |
| 5208 /* */ | 5341 /* */ |
| 5209 /* SDPVTL[a]: Set Dual PVector to Line */ | 5342 /* SDPVTL[a]: Set Dual PVector to Line */ |
| 5210 /* Opcode range: 0x86-0x87 */ | 5343 /* Opcode range: 0x86-0x87 */ |
| 5211 /* Stack: uint32 uint32 --> */ | 5344 /* Stack: uint32 uint32 --> */ |
| 5212 /* */ | 5345 /* */ |
| 5213 static void | 5346 static void |
| 5214 Ins_SDPVTL( INS_ARG ) | 5347 Ins_SDPVTL( INS_ARG ) |
| 5215 { | 5348 { |
| 5216 FT_Long A, B, C; | 5349 FT_Long A, B, C; |
| 5217 FT_UShort p1, p2; /* was FT_Int in pas type ERROR */ | 5350 FT_UShort p1, p2; /* was FT_Int in pas type ERROR */ |
| 5218 FT_Int aOpc = CUR.opcode; | 5351 FT_Int aOpc = CUR.opcode; |
| 5219 | 5352 |
| 5220 | 5353 |
| 5221 p1 = (FT_UShort)args[1]; | 5354 p1 = (FT_UShort)args[1]; |
| 5222 p2 = (FT_UShort)args[0]; | 5355 p2 = (FT_UShort)args[0]; |
| 5223 | 5356 |
| 5224 if ( BOUNDS( p2, CUR.zp1.n_points ) || | 5357 if ( BOUNDS( p2, CUR.zp1.n_points ) || |
| 5225 BOUNDS( p1, CUR.zp2.n_points ) ) | 5358 BOUNDS( p1, CUR.zp2.n_points ) ) |
| 5226 { | 5359 { |
| 5227 if ( CUR.pedantic_hinting ) | 5360 if ( CUR.pedantic_hinting ) |
| 5228 CUR.error = TT_Err_Invalid_Reference; | 5361 CUR.error = FT_THROW( Invalid_Reference ); |
| 5229 return; | 5362 return; |
| 5230 } | 5363 } |
| 5231 | 5364 |
| 5232 { | 5365 { |
| 5233 FT_Vector* v1 = CUR.zp1.org + p2; | 5366 FT_Vector* v1 = CUR.zp1.org + p2; |
| 5234 FT_Vector* v2 = CUR.zp2.org + p1; | 5367 FT_Vector* v2 = CUR.zp2.org + p1; |
| 5235 | 5368 |
| 5236 | 5369 |
| 5237 A = v1->x - v2->x; | 5370 A = v1->x - v2->x; |
| 5238 B = v1->y - v2->y; | 5371 B = v1->y - v2->y; |
| (...skipping 19 matching lines...) Expand all Loading... |
| 5258 | 5391 |
| 5259 NORMalize( A, B, &CUR.GS.dualVector ); | 5392 NORMalize( A, B, &CUR.GS.dualVector ); |
| 5260 | 5393 |
| 5261 { | 5394 { |
| 5262 FT_Vector* v1 = CUR.zp1.cur + p2; | 5395 FT_Vector* v1 = CUR.zp1.cur + p2; |
| 5263 FT_Vector* v2 = CUR.zp2.cur + p1; | 5396 FT_Vector* v2 = CUR.zp2.cur + p1; |
| 5264 | 5397 |
| 5265 | 5398 |
| 5266 A = v1->x - v2->x; | 5399 A = v1->x - v2->x; |
| 5267 B = v1->y - v2->y; | 5400 B = v1->y - v2->y; |
| 5401 |
| 5402 if ( A == 0 && B == 0 ) |
| 5403 { |
| 5404 A = 0x4000; |
| 5405 aOpc = 0; |
| 5406 } |
| 5268 } | 5407 } |
| 5269 | 5408 |
| 5270 if ( ( aOpc & 1 ) != 0 ) | 5409 if ( ( aOpc & 1 ) != 0 ) |
| 5271 { | 5410 { |
| 5272 C = B; /* counter clockwise rotation */ | 5411 C = B; /* counter clockwise rotation */ |
| 5273 B = A; | 5412 B = A; |
| 5274 A = -C; | 5413 A = -C; |
| 5275 } | 5414 } |
| 5276 | 5415 |
| 5277 NORMalize( A, B, &CUR.GS.projVector ); | 5416 NORMalize( A, B, &CUR.GS.projVector ); |
| (...skipping 18 matching lines...) Expand all Loading... |
| 5296 case 0: | 5435 case 0: |
| 5297 CUR.zp0 = CUR.twilight; | 5436 CUR.zp0 = CUR.twilight; |
| 5298 break; | 5437 break; |
| 5299 | 5438 |
| 5300 case 1: | 5439 case 1: |
| 5301 CUR.zp0 = CUR.pts; | 5440 CUR.zp0 = CUR.pts; |
| 5302 break; | 5441 break; |
| 5303 | 5442 |
| 5304 default: | 5443 default: |
| 5305 if ( CUR.pedantic_hinting ) | 5444 if ( CUR.pedantic_hinting ) |
| 5306 CUR.error = TT_Err_Invalid_Reference; | 5445 CUR.error = FT_THROW( Invalid_Reference ); |
| 5307 return; | 5446 return; |
| 5308 } | 5447 } |
| 5309 | 5448 |
| 5310 CUR.GS.gep0 = (FT_UShort)args[0]; | 5449 CUR.GS.gep0 = (FT_UShort)args[0]; |
| 5311 } | 5450 } |
| 5312 | 5451 |
| 5313 | 5452 |
| 5314 /*************************************************************************/ | 5453 /*************************************************************************/ |
| 5315 /* */ | 5454 /* */ |
| 5316 /* SZP1[]: Set Zone Pointer 1 */ | 5455 /* SZP1[]: Set Zone Pointer 1 */ |
| 5317 /* Opcode range: 0x14 */ | 5456 /* Opcode range: 0x14 */ |
| 5318 /* Stack: uint32 --> */ | 5457 /* Stack: uint32 --> */ |
| 5319 /* */ | 5458 /* */ |
| 5320 static void | 5459 static void |
| 5321 Ins_SZP1( INS_ARG ) | 5460 Ins_SZP1( INS_ARG ) |
| 5322 { | 5461 { |
| 5323 switch ( (FT_Int)args[0] ) | 5462 switch ( (FT_Int)args[0] ) |
| 5324 { | 5463 { |
| 5325 case 0: | 5464 case 0: |
| 5326 CUR.zp1 = CUR.twilight; | 5465 CUR.zp1 = CUR.twilight; |
| 5327 break; | 5466 break; |
| 5328 | 5467 |
| 5329 case 1: | 5468 case 1: |
| 5330 CUR.zp1 = CUR.pts; | 5469 CUR.zp1 = CUR.pts; |
| 5331 break; | 5470 break; |
| 5332 | 5471 |
| 5333 default: | 5472 default: |
| 5334 if ( CUR.pedantic_hinting ) | 5473 if ( CUR.pedantic_hinting ) |
| 5335 CUR.error = TT_Err_Invalid_Reference; | 5474 CUR.error = FT_THROW( Invalid_Reference ); |
| 5336 return; | 5475 return; |
| 5337 } | 5476 } |
| 5338 | 5477 |
| 5339 CUR.GS.gep1 = (FT_UShort)args[0]; | 5478 CUR.GS.gep1 = (FT_UShort)args[0]; |
| 5340 } | 5479 } |
| 5341 | 5480 |
| 5342 | 5481 |
| 5343 /*************************************************************************/ | 5482 /*************************************************************************/ |
| 5344 /* */ | 5483 /* */ |
| 5345 /* SZP2[]: Set Zone Pointer 2 */ | 5484 /* SZP2[]: Set Zone Pointer 2 */ |
| 5346 /* Opcode range: 0x15 */ | 5485 /* Opcode range: 0x15 */ |
| 5347 /* Stack: uint32 --> */ | 5486 /* Stack: uint32 --> */ |
| 5348 /* */ | 5487 /* */ |
| 5349 static void | 5488 static void |
| 5350 Ins_SZP2( INS_ARG ) | 5489 Ins_SZP2( INS_ARG ) |
| 5351 { | 5490 { |
| 5352 switch ( (FT_Int)args[0] ) | 5491 switch ( (FT_Int)args[0] ) |
| 5353 { | 5492 { |
| 5354 case 0: | 5493 case 0: |
| 5355 CUR.zp2 = CUR.twilight; | 5494 CUR.zp2 = CUR.twilight; |
| 5356 break; | 5495 break; |
| 5357 | 5496 |
| 5358 case 1: | 5497 case 1: |
| 5359 CUR.zp2 = CUR.pts; | 5498 CUR.zp2 = CUR.pts; |
| 5360 break; | 5499 break; |
| 5361 | 5500 |
| 5362 default: | 5501 default: |
| 5363 if ( CUR.pedantic_hinting ) | 5502 if ( CUR.pedantic_hinting ) |
| 5364 CUR.error = TT_Err_Invalid_Reference; | 5503 CUR.error = FT_THROW( Invalid_Reference ); |
| 5365 return; | 5504 return; |
| 5366 } | 5505 } |
| 5367 | 5506 |
| 5368 CUR.GS.gep2 = (FT_UShort)args[0]; | 5507 CUR.GS.gep2 = (FT_UShort)args[0]; |
| 5369 } | 5508 } |
| 5370 | 5509 |
| 5371 | 5510 |
| 5372 /*************************************************************************/ | 5511 /*************************************************************************/ |
| 5373 /* */ | 5512 /* */ |
| 5374 /* SZPS[]: Set Zone PointerS */ | 5513 /* SZPS[]: Set Zone PointerS */ |
| 5375 /* Opcode range: 0x16 */ | 5514 /* Opcode range: 0x16 */ |
| 5376 /* Stack: uint32 --> */ | 5515 /* Stack: uint32 --> */ |
| 5377 /* */ | 5516 /* */ |
| 5378 static void | 5517 static void |
| 5379 Ins_SZPS( INS_ARG ) | 5518 Ins_SZPS( INS_ARG ) |
| 5380 { | 5519 { |
| 5381 switch ( (FT_Int)args[0] ) | 5520 switch ( (FT_Int)args[0] ) |
| 5382 { | 5521 { |
| 5383 case 0: | 5522 case 0: |
| 5384 CUR.zp0 = CUR.twilight; | 5523 CUR.zp0 = CUR.twilight; |
| 5385 break; | 5524 break; |
| 5386 | 5525 |
| 5387 case 1: | 5526 case 1: |
| 5388 CUR.zp0 = CUR.pts; | 5527 CUR.zp0 = CUR.pts; |
| 5389 break; | 5528 break; |
| 5390 | 5529 |
| 5391 default: | 5530 default: |
| 5392 if ( CUR.pedantic_hinting ) | 5531 if ( CUR.pedantic_hinting ) |
| 5393 CUR.error = TT_Err_Invalid_Reference; | 5532 CUR.error = FT_THROW( Invalid_Reference ); |
| 5394 return; | 5533 return; |
| 5395 } | 5534 } |
| 5396 | 5535 |
| 5397 CUR.zp1 = CUR.zp0; | 5536 CUR.zp1 = CUR.zp0; |
| 5398 CUR.zp2 = CUR.zp0; | 5537 CUR.zp2 = CUR.zp0; |
| 5399 | 5538 |
| 5400 CUR.GS.gep0 = (FT_UShort)args[0]; | 5539 CUR.GS.gep0 = (FT_UShort)args[0]; |
| 5401 CUR.GS.gep1 = (FT_UShort)args[0]; | 5540 CUR.GS.gep1 = (FT_UShort)args[0]; |
| 5402 CUR.GS.gep2 = (FT_UShort)args[0]; | 5541 CUR.GS.gep2 = (FT_UShort)args[0]; |
| 5403 } | 5542 } |
| (...skipping 10 matching lines...) Expand all Loading... |
| 5414 { | 5553 { |
| 5415 FT_Long K, L; | 5554 FT_Long K, L; |
| 5416 | 5555 |
| 5417 | 5556 |
| 5418 K = args[1]; | 5557 K = args[1]; |
| 5419 L = args[0]; | 5558 L = args[0]; |
| 5420 | 5559 |
| 5421 if ( K < 1 || K > 2 ) | 5560 if ( K < 1 || K > 2 ) |
| 5422 { | 5561 { |
| 5423 if ( CUR.pedantic_hinting ) | 5562 if ( CUR.pedantic_hinting ) |
| 5424 CUR.error = TT_Err_Invalid_Reference; | 5563 CUR.error = FT_THROW( Invalid_Reference ); |
| 5425 return; | 5564 return; |
| 5426 } | 5565 } |
| 5427 | 5566 |
| 5428 if ( L != 0 ) | 5567 if ( L != 0 ) |
| 5429 L = K; | 5568 L = K; |
| 5430 | 5569 |
| 5431 CUR.GS.instruct_control = FT_BOOL( | 5570 CUR.GS.instruct_control = FT_BOOL( |
| 5432 ( (FT_Byte)CUR.GS.instruct_control & ~(FT_Byte)K ) | (FT_Byte)L ); | 5571 ( (FT_Byte)CUR.GS.instruct_control & ~(FT_Byte)K ) | (FT_Byte)L ); |
| 5433 } | 5572 } |
| 5434 | 5573 |
| (...skipping 77 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 5512 Ins_FLIPPT( INS_ARG ) | 5651 Ins_FLIPPT( INS_ARG ) |
| 5513 { | 5652 { |
| 5514 FT_UShort point; | 5653 FT_UShort point; |
| 5515 | 5654 |
| 5516 FT_UNUSED_ARG; | 5655 FT_UNUSED_ARG; |
| 5517 | 5656 |
| 5518 | 5657 |
| 5519 if ( CUR.top < CUR.GS.loop ) | 5658 if ( CUR.top < CUR.GS.loop ) |
| 5520 { | 5659 { |
| 5521 if ( CUR.pedantic_hinting ) | 5660 if ( CUR.pedantic_hinting ) |
| 5522 CUR.error = TT_Err_Too_Few_Arguments; | 5661 CUR.error = FT_THROW( Too_Few_Arguments ); |
| 5523 goto Fail; | 5662 goto Fail; |
| 5524 } | 5663 } |
| 5525 | 5664 |
| 5526 while ( CUR.GS.loop > 0 ) | 5665 while ( CUR.GS.loop > 0 ) |
| 5527 { | 5666 { |
| 5528 CUR.args--; | 5667 CUR.args--; |
| 5529 | 5668 |
| 5530 point = (FT_UShort)CUR.stack[CUR.args]; | 5669 point = (FT_UShort)CUR.stack[CUR.args]; |
| 5531 | 5670 |
| 5532 if ( BOUNDS( point, CUR.pts.n_points ) ) | 5671 if ( BOUNDS( point, CUR.pts.n_points ) ) |
| 5533 { | 5672 { |
| 5534 if ( CUR.pedantic_hinting ) | 5673 if ( CUR.pedantic_hinting ) |
| 5535 { | 5674 { |
| 5536 CUR.error = TT_Err_Invalid_Reference; | 5675 CUR.error = FT_THROW( Invalid_Reference ); |
| 5537 return; | 5676 return; |
| 5538 } | 5677 } |
| 5539 } | 5678 } |
| 5540 else | 5679 else |
| 5541 CUR.pts.tags[point] ^= FT_CURVE_TAG_ON; | 5680 CUR.pts.tags[point] ^= FT_CURVE_TAG_ON; |
| 5542 | 5681 |
| 5543 CUR.GS.loop--; | 5682 CUR.GS.loop--; |
| 5544 } | 5683 } |
| 5545 | 5684 |
| 5546 Fail: | 5685 Fail: |
| (...skipping 14 matching lines...) Expand all Loading... |
| 5561 FT_UShort I, K, L; | 5700 FT_UShort I, K, L; |
| 5562 | 5701 |
| 5563 | 5702 |
| 5564 K = (FT_UShort)args[1]; | 5703 K = (FT_UShort)args[1]; |
| 5565 L = (FT_UShort)args[0]; | 5704 L = (FT_UShort)args[0]; |
| 5566 | 5705 |
| 5567 if ( BOUNDS( K, CUR.pts.n_points ) || | 5706 if ( BOUNDS( K, CUR.pts.n_points ) || |
| 5568 BOUNDS( L, CUR.pts.n_points ) ) | 5707 BOUNDS( L, CUR.pts.n_points ) ) |
| 5569 { | 5708 { |
| 5570 if ( CUR.pedantic_hinting ) | 5709 if ( CUR.pedantic_hinting ) |
| 5571 CUR.error = TT_Err_Invalid_Reference; | 5710 CUR.error = FT_THROW( Invalid_Reference ); |
| 5572 return; | 5711 return; |
| 5573 } | 5712 } |
| 5574 | 5713 |
| 5575 for ( I = L; I <= K; I++ ) | 5714 for ( I = L; I <= K; I++ ) |
| 5576 CUR.pts.tags[I] |= FT_CURVE_TAG_ON; | 5715 CUR.pts.tags[I] |= FT_CURVE_TAG_ON; |
| 5577 } | 5716 } |
| 5578 | 5717 |
| 5579 | 5718 |
| 5580 /*************************************************************************/ | 5719 /*************************************************************************/ |
| 5581 /* */ | 5720 /* */ |
| 5582 /* FLIPRGOFF: FLIP RanGe OFF */ | 5721 /* FLIPRGOFF: FLIP RanGe OFF */ |
| 5583 /* Opcode range: 0x82 */ | 5722 /* Opcode range: 0x82 */ |
| 5584 /* Stack: uint32 uint32 --> */ | 5723 /* Stack: uint32 uint32 --> */ |
| 5585 /* */ | 5724 /* */ |
| 5586 static void | 5725 static void |
| 5587 Ins_FLIPRGOFF( INS_ARG ) | 5726 Ins_FLIPRGOFF( INS_ARG ) |
| 5588 { | 5727 { |
| 5589 FT_UShort I, K, L; | 5728 FT_UShort I, K, L; |
| 5590 | 5729 |
| 5591 | 5730 |
| 5592 K = (FT_UShort)args[1]; | 5731 K = (FT_UShort)args[1]; |
| 5593 L = (FT_UShort)args[0]; | 5732 L = (FT_UShort)args[0]; |
| 5594 | 5733 |
| 5595 if ( BOUNDS( K, CUR.pts.n_points ) || | 5734 if ( BOUNDS( K, CUR.pts.n_points ) || |
| 5596 BOUNDS( L, CUR.pts.n_points ) ) | 5735 BOUNDS( L, CUR.pts.n_points ) ) |
| 5597 { | 5736 { |
| 5598 if ( CUR.pedantic_hinting ) | 5737 if ( CUR.pedantic_hinting ) |
| 5599 CUR.error = TT_Err_Invalid_Reference; | 5738 CUR.error = FT_THROW( Invalid_Reference ); |
| 5600 return; | 5739 return; |
| 5601 } | 5740 } |
| 5602 | 5741 |
| 5603 for ( I = L; I <= K; I++ ) | 5742 for ( I = L; I <= K; I++ ) |
| 5604 CUR.pts.tags[I] &= ~FT_CURVE_TAG_ON; | 5743 CUR.pts.tags[I] &= ~FT_CURVE_TAG_ON; |
| 5605 } | 5744 } |
| 5606 | 5745 |
| 5607 | 5746 |
| 5608 static FT_Bool | 5747 static FT_Bool |
| 5609 Compute_Point_Displacement( EXEC_OP_ FT_F26Dot6* x, | 5748 Compute_Point_Displacement( EXEC_OP_ FT_F26Dot6* x, |
| (...skipping 13 matching lines...) Expand all Loading... |
| 5623 } | 5762 } |
| 5624 else | 5763 else |
| 5625 { | 5764 { |
| 5626 zp = CUR.zp1; | 5765 zp = CUR.zp1; |
| 5627 p = CUR.GS.rp2; | 5766 p = CUR.GS.rp2; |
| 5628 } | 5767 } |
| 5629 | 5768 |
| 5630 if ( BOUNDS( p, zp.n_points ) ) | 5769 if ( BOUNDS( p, zp.n_points ) ) |
| 5631 { | 5770 { |
| 5632 if ( CUR.pedantic_hinting ) | 5771 if ( CUR.pedantic_hinting ) |
| 5633 CUR.error = TT_Err_Invalid_Reference; | 5772 CUR.error = FT_THROW( Invalid_Reference ); |
| 5634 *refp = 0; | 5773 *refp = 0; |
| 5635 return FAILURE; | 5774 return FAILURE; |
| 5636 } | 5775 } |
| 5637 | 5776 |
| 5638 *zone = zp; | 5777 *zone = zp; |
| 5639 *refp = p; | 5778 *refp = p; |
| 5640 | 5779 |
| 5641 d = CUR_Func_project( zp.cur + p, zp.org + p ); | 5780 d = CUR_Func_project( zp.cur + p, zp.org + p ); |
| 5642 | 5781 |
| 5643 #ifdef TT_CONFIG_OPTION_UNPATENTED_HINTING | 5782 #ifdef TT_CONFIG_OPTION_UNPATENTED_HINTING |
| 5644 if ( CUR.face->unpatented_hinting ) | 5783 if ( CUR.face->unpatented_hinting ) |
| 5645 { | 5784 { |
| 5646 if ( CUR.GS.both_x_axis ) | 5785 if ( CUR.GS.both_x_axis ) |
| 5647 { | 5786 { |
| 5648 *x = d; | 5787 *x = d; |
| 5649 *y = 0; | 5788 *y = 0; |
| 5650 } | 5789 } |
| 5651 else | 5790 else |
| 5652 { | 5791 { |
| 5653 *x = 0; | 5792 *x = 0; |
| 5654 *y = d; | 5793 *y = d; |
| 5655 } | 5794 } |
| 5656 } | 5795 } |
| 5657 else | 5796 else |
| 5658 #endif | 5797 #endif |
| 5659 { | 5798 { |
| 5660 *x = TT_MULDIV( d, | 5799 *x = FT_MulDiv( d, (FT_Long)CUR.GS.freeVector.x, CUR.F_dot_P ); |
| 5661 (FT_Long)CUR.GS.freeVector.x * 0x10000L, | 5800 *y = FT_MulDiv( d, (FT_Long)CUR.GS.freeVector.y, CUR.F_dot_P ); |
| 5662 CUR.F_dot_P ); | |
| 5663 *y = TT_MULDIV( d, | |
| 5664 (FT_Long)CUR.GS.freeVector.y * 0x10000L, | |
| 5665 CUR.F_dot_P ); | |
| 5666 } | 5801 } |
| 5667 | 5802 |
| 5668 return SUCCESS; | 5803 return SUCCESS; |
| 5669 } | 5804 } |
| 5670 | 5805 |
| 5671 | 5806 |
| 5672 static void | 5807 static void |
| 5673 Move_Zp2_Point( EXEC_OP_ FT_UShort point, | 5808 Move_Zp2_Point( EXEC_OP_ FT_UShort point, |
| 5674 FT_F26Dot6 dx, | 5809 FT_F26Dot6 dx, |
| 5675 FT_F26Dot6 dy, | 5810 FT_F26Dot6 dy, |
| (...skipping 49 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 5725 FT_F26Dot6 dx, | 5860 FT_F26Dot6 dx, |
| 5726 dy; | 5861 dy; |
| 5727 FT_UShort point; | 5862 FT_UShort point; |
| 5728 | 5863 |
| 5729 FT_UNUSED_ARG; | 5864 FT_UNUSED_ARG; |
| 5730 | 5865 |
| 5731 | 5866 |
| 5732 if ( CUR.top < CUR.GS.loop ) | 5867 if ( CUR.top < CUR.GS.loop ) |
| 5733 { | 5868 { |
| 5734 if ( CUR.pedantic_hinting ) | 5869 if ( CUR.pedantic_hinting ) |
| 5735 CUR.error = TT_Err_Invalid_Reference; | 5870 CUR.error = FT_THROW( Invalid_Reference ); |
| 5736 goto Fail; | 5871 goto Fail; |
| 5737 } | 5872 } |
| 5738 | 5873 |
| 5739 if ( COMPUTE_Point_Displacement( &dx, &dy, &zp, &refp ) ) | 5874 if ( COMPUTE_Point_Displacement( &dx, &dy, &zp, &refp ) ) |
| 5740 return; | 5875 return; |
| 5741 | 5876 |
| 5742 while ( CUR.GS.loop > 0 ) | 5877 while ( CUR.GS.loop > 0 ) |
| 5743 { | 5878 { |
| 5744 CUR.args--; | 5879 CUR.args--; |
| 5745 point = (FT_UShort)CUR.stack[CUR.args]; | 5880 point = (FT_UShort)CUR.stack[CUR.args]; |
| 5746 | 5881 |
| 5747 if ( BOUNDS( point, CUR.zp2.n_points ) ) | 5882 if ( BOUNDS( point, CUR.zp2.n_points ) ) |
| 5748 { | 5883 { |
| 5749 if ( CUR.pedantic_hinting ) | 5884 if ( CUR.pedantic_hinting ) |
| 5750 { | 5885 { |
| 5751 CUR.error = TT_Err_Invalid_Reference; | 5886 CUR.error = FT_THROW( Invalid_Reference ); |
| 5752 return; | 5887 return; |
| 5753 } | 5888 } |
| 5754 } | 5889 } |
| 5755 else | 5890 else |
| 5891 #ifdef TT_CONFIG_OPTION_SUBPIXEL_HINTING |
| 5892 /* doesn't follow Cleartype spec but produces better result */ |
| 5893 if ( SUBPIXEL_HINTING && |
| 5894 CUR.ignore_x_mode ) |
| 5895 MOVE_Zp2_Point( point, 0, dy, TRUE ); |
| 5896 else |
| 5897 #endif /* TT_CONFIG_OPTION_SUBPIXEL_HINTING */ |
| 5756 MOVE_Zp2_Point( point, dx, dy, TRUE ); | 5898 MOVE_Zp2_Point( point, dx, dy, TRUE ); |
| 5757 | 5899 |
| 5758 CUR.GS.loop--; | 5900 CUR.GS.loop--; |
| 5759 } | 5901 } |
| 5760 | 5902 |
| 5761 Fail: | 5903 Fail: |
| 5762 CUR.GS.loop = 1; | 5904 CUR.GS.loop = 1; |
| 5763 CUR.new_top = CUR.args; | 5905 CUR.new_top = CUR.args; |
| 5764 } | 5906 } |
| 5765 | 5907 |
| 5766 | 5908 |
| 5767 /*************************************************************************/ | 5909 /*************************************************************************/ |
| 5768 /* */ | 5910 /* */ |
| 5769 /* SHC[a]: SHift Contour */ | 5911 /* SHC[a]: SHift Contour */ |
| 5770 /* Opcode range: 0x34-35 */ | 5912 /* Opcode range: 0x34-35 */ |
| 5771 /* Stack: uint32 --> */ | 5913 /* Stack: uint32 --> */ |
| 5772 /* */ | 5914 /* */ |
| 5773 /* UNDOCUMENTED: According to Greg Hitchcock, there is one (virtual) */ | 5915 /* UNDOCUMENTED: According to Greg Hitchcock, there is one (virtual) */ |
| 5774 /* contour in the twilight zone, namely contour number */ | 5916 /* contour in the twilight zone, namely contour number */ |
| 5775 /* zero. */ | 5917 /* zero which includes all points of it. */ |
| 5776 /* */ | 5918 /* */ |
| 5777 static void | 5919 static void |
| 5778 Ins_SHC( INS_ARG ) | 5920 Ins_SHC( INS_ARG ) |
| 5779 { | 5921 { |
| 5780 TT_GlyphZoneRec zp; | 5922 TT_GlyphZoneRec zp; |
| 5781 FT_UShort refp; | 5923 FT_UShort refp; |
| 5782 FT_F26Dot6 dx, dy; | 5924 FT_F26Dot6 dx, dy; |
| 5783 | 5925 |
| 5784 FT_Short contour, bounds; | 5926 FT_Short contour, bounds; |
| 5785 FT_UShort start, limit, i; | 5927 FT_UShort start, limit, i; |
| 5786 | 5928 |
| 5787 | 5929 |
| 5788 contour = (FT_UShort)args[0]; | 5930 contour = (FT_UShort)args[0]; |
| 5789 bounds = ( CUR.GS.gep2 == 0 ) ? 1 : CUR.zp2.n_contours; | 5931 bounds = ( CUR.GS.gep2 == 0 ) ? 1 : CUR.zp2.n_contours; |
| 5790 | 5932 |
| 5791 if ( BOUNDS( contour, bounds ) ) | 5933 if ( BOUNDS( contour, bounds ) ) |
| 5792 { | 5934 { |
| 5793 if ( CUR.pedantic_hinting ) | 5935 if ( CUR.pedantic_hinting ) |
| 5794 CUR.error = TT_Err_Invalid_Reference; | 5936 CUR.error = FT_THROW( Invalid_Reference ); |
| 5795 return; | 5937 return; |
| 5796 } | 5938 } |
| 5797 | 5939 |
| 5798 if ( COMPUTE_Point_Displacement( &dx, &dy, &zp, &refp ) ) | 5940 if ( COMPUTE_Point_Displacement( &dx, &dy, &zp, &refp ) ) |
| 5799 return; | 5941 return; |
| 5800 | 5942 |
| 5801 if ( contour == 0 ) | 5943 if ( contour == 0 ) |
| 5802 start = 0; | 5944 start = 0; |
| 5803 else | 5945 else |
| 5804 start = (FT_UShort)( CUR.zp2.contours[contour - 1] + 1 - | 5946 start = (FT_UShort)( CUR.zp2.contours[contour - 1] + 1 - |
| (...skipping 27 matching lines...) Expand all Loading... |
| 5832 FT_UShort refp; | 5974 FT_UShort refp; |
| 5833 FT_F26Dot6 dx, | 5975 FT_F26Dot6 dx, |
| 5834 dy; | 5976 dy; |
| 5835 | 5977 |
| 5836 FT_UShort limit, i; | 5978 FT_UShort limit, i; |
| 5837 | 5979 |
| 5838 | 5980 |
| 5839 if ( BOUNDS( args[0], 2 ) ) | 5981 if ( BOUNDS( args[0], 2 ) ) |
| 5840 { | 5982 { |
| 5841 if ( CUR.pedantic_hinting ) | 5983 if ( CUR.pedantic_hinting ) |
| 5842 CUR.error = TT_Err_Invalid_Reference; | 5984 CUR.error = FT_THROW( Invalid_Reference ); |
| 5843 return; | 5985 return; |
| 5844 } | 5986 } |
| 5845 | 5987 |
| 5846 if ( COMPUTE_Point_Displacement( &dx, &dy, &zp, &refp ) ) | 5988 if ( COMPUTE_Point_Displacement( &dx, &dy, &zp, &refp ) ) |
| 5847 return; | 5989 return; |
| 5848 | 5990 |
| 5849 /* XXX: UNDOCUMENTED! SHZ doesn't move the phantom points. */ | 5991 /* XXX: UNDOCUMENTED! SHZ doesn't move the phantom points. */ |
| 5850 /* Twilight zone has no real contours, so use `n_points'. */ | 5992 /* Twilight zone has no real contours, so use `n_points'. */ |
| 5851 /* Normal zone's `n_points' includes phantoms, so must */ | 5993 /* Normal zone's `n_points' includes phantoms, so must */ |
| 5852 /* use end of last contour. */ | 5994 /* use end of last contour. */ |
| (...skipping 17 matching lines...) Expand all Loading... |
| 5870 /* */ | 6012 /* */ |
| 5871 /* SHPIX[]: SHift points by a PIXel amount */ | 6013 /* SHPIX[]: SHift points by a PIXel amount */ |
| 5872 /* Opcode range: 0x38 */ | 6014 /* Opcode range: 0x38 */ |
| 5873 /* Stack: f26.6 uint32... --> */ | 6015 /* Stack: f26.6 uint32... --> */ |
| 5874 /* */ | 6016 /* */ |
| 5875 static void | 6017 static void |
| 5876 Ins_SHPIX( INS_ARG ) | 6018 Ins_SHPIX( INS_ARG ) |
| 5877 { | 6019 { |
| 5878 FT_F26Dot6 dx, dy; | 6020 FT_F26Dot6 dx, dy; |
| 5879 FT_UShort point; | 6021 FT_UShort point; |
| 6022 #ifdef TT_CONFIG_OPTION_SUBPIXEL_HINTING |
| 6023 FT_Int B1, B2; |
| 6024 #endif |
| 5880 | 6025 |
| 5881 | 6026 |
| 5882 if ( CUR.top < CUR.GS.loop + 1 ) | 6027 if ( CUR.top < CUR.GS.loop + 1 ) |
| 5883 { | 6028 { |
| 5884 if ( CUR.pedantic_hinting ) | 6029 if ( CUR.pedantic_hinting ) |
| 5885 CUR.error = TT_Err_Invalid_Reference; | 6030 CUR.error = FT_THROW( Invalid_Reference ); |
| 5886 goto Fail; | 6031 goto Fail; |
| 5887 } | 6032 } |
| 5888 | 6033 |
| 5889 #ifdef TT_CONFIG_OPTION_UNPATENTED_HINTING | 6034 #ifdef TT_CONFIG_OPTION_UNPATENTED_HINTING |
| 5890 if ( CUR.face->unpatented_hinting ) | 6035 if ( CUR.face->unpatented_hinting ) |
| 5891 { | 6036 { |
| 5892 if ( CUR.GS.both_x_axis ) | 6037 if ( CUR.GS.both_x_axis ) |
| 5893 { | 6038 { |
| 5894 dx = TT_MulFix14( (FT_UInt32)args[0], 0x4000 ); | 6039 dx = (FT_UInt32)args[0]; |
| 5895 dy = 0; | 6040 dy = 0; |
| 5896 } | 6041 } |
| 5897 else | 6042 else |
| 5898 { | 6043 { |
| 5899 dx = 0; | 6044 dx = 0; |
| 5900 dy = TT_MulFix14( (FT_UInt32)args[0], 0x4000 ); | 6045 dy = (FT_UInt32)args[0]; |
| 5901 } | 6046 } |
| 5902 } | 6047 } |
| 5903 else | 6048 else |
| 5904 #endif | 6049 #endif |
| 5905 { | 6050 { |
| 5906 dx = TT_MulFix14( (FT_UInt32)args[0], CUR.GS.freeVector.x ); | 6051 dx = TT_MulFix14( (FT_UInt32)args[0], CUR.GS.freeVector.x ); |
| 5907 dy = TT_MulFix14( (FT_UInt32)args[0], CUR.GS.freeVector.y ); | 6052 dy = TT_MulFix14( (FT_UInt32)args[0], CUR.GS.freeVector.y ); |
| 5908 } | 6053 } |
| 5909 | 6054 |
| 5910 while ( CUR.GS.loop > 0 ) | 6055 while ( CUR.GS.loop > 0 ) |
| 5911 { | 6056 { |
| 5912 CUR.args--; | 6057 CUR.args--; |
| 5913 | 6058 |
| 5914 point = (FT_UShort)CUR.stack[CUR.args]; | 6059 point = (FT_UShort)CUR.stack[CUR.args]; |
| 5915 | 6060 |
| 5916 if ( BOUNDS( point, CUR.zp2.n_points ) ) | 6061 if ( BOUNDS( point, CUR.zp2.n_points ) ) |
| 5917 { | 6062 { |
| 5918 if ( CUR.pedantic_hinting ) | 6063 if ( CUR.pedantic_hinting ) |
| 5919 { | 6064 { |
| 5920 CUR.error = TT_Err_Invalid_Reference; | 6065 CUR.error = FT_THROW( Invalid_Reference ); |
| 5921 return; | 6066 return; |
| 5922 } | 6067 } |
| 5923 } | 6068 } |
| 5924 else | 6069 else |
| 6070 #ifdef TT_CONFIG_OPTION_SUBPIXEL_HINTING |
| 6071 { |
| 6072 /* If not using ignore_x_mode rendering, allow ZP2 move. */ |
| 6073 /* If inline deltas aren't allowed, skip ZP2 move. */ |
| 6074 /* If using ignore_x_mode rendering, allow ZP2 point move if: */ |
| 6075 /* - freedom vector is y and sph_compatibility_mode is off */ |
| 6076 /* - the glyph is composite and the move is in the Y direction */ |
| 6077 /* - the glyph is specifically set to allow SHPIX moves */ |
| 6078 /* - the move is on a previously Y-touched point */ |
| 6079 |
| 6080 if ( SUBPIXEL_HINTING && |
| 6081 CUR.ignore_x_mode ) |
| 6082 { |
| 6083 /* save point for later comparison */ |
| 6084 if ( CUR.GS.freeVector.y != 0 ) |
| 6085 B1 = CUR.zp2.cur[point].y; |
| 6086 else |
| 6087 B1 = CUR.zp2.cur[point].x; |
| 6088 |
| 6089 if ( !CUR.face->sph_compatibility_mode && |
| 6090 CUR.GS.freeVector.y != 0 ) |
| 6091 { |
| 6092 MOVE_Zp2_Point( point, dx, dy, TRUE ); |
| 6093 |
| 6094 /* save new point */ |
| 6095 if ( CUR.GS.freeVector.y != 0 ) |
| 6096 { |
| 6097 B2 = CUR.zp2.cur[point].y; |
| 6098 |
| 6099 /* reverse any disallowed moves */ |
| 6100 if ( ( CUR.sph_tweak_flags & SPH_TWEAK_SKIP_NONPIXEL_Y_MOVES ) && |
| 6101 ( B1 & 63 ) != 0 && |
| 6102 ( B2 & 63 ) != 0 && |
| 6103 B1 != B2 ) |
| 6104 MOVE_Zp2_Point( point, -dx, -dy, TRUE ); |
| 6105 } |
| 6106 } |
| 6107 else if ( CUR.face->sph_compatibility_mode ) |
| 6108 { |
| 6109 if ( CUR.sph_tweak_flags & SPH_TWEAK_ROUND_NONPIXEL_Y_MOVES ) |
| 6110 { |
| 6111 dx = FT_PIX_ROUND( B1 + dx ) - B1; |
| 6112 dy = FT_PIX_ROUND( B1 + dy ) - B1; |
| 6113 } |
| 6114 |
| 6115 /* skip post-iup deltas */ |
| 6116 if ( CUR.iup_called && |
| 6117 ( ( CUR.sph_in_func_flags & SPH_FDEF_INLINE_DELTA_1 ) || |
| 6118 ( CUR.sph_in_func_flags & SPH_FDEF_INLINE_DELTA_2 ) ) ) |
| 6119 goto Skip; |
| 6120 |
| 6121 if ( !( CUR.sph_tweak_flags & SPH_TWEAK_ALWAYS_SKIP_DELTAP ) && |
| 6122 ( ( CUR.is_composite && CUR.GS.freeVector.y != 0 ) || |
| 6123 ( CUR.zp2.tags[point] & FT_CURVE_TAG_TOUCH_Y ) || |
| 6124 ( CUR.sph_tweak_flags & SPH_TWEAK_DO_SHPIX ) ) ) |
| 6125 MOVE_Zp2_Point( point, 0, dy, TRUE ); |
| 6126 |
| 6127 /* save new point */ |
| 6128 if ( CUR.GS.freeVector.y != 0 ) |
| 6129 { |
| 6130 B2 = CUR.zp2.cur[point].y; |
| 6131 |
| 6132 /* reverse any disallowed moves */ |
| 6133 if ( ( B1 & 63 ) == 0 && |
| 6134 ( B2 & 63 ) != 0 && |
| 6135 B1 != B2 ) |
| 6136 MOVE_Zp2_Point( point, 0, -dy, TRUE ); |
| 6137 } |
| 6138 } |
| 6139 else if ( CUR.sph_in_func_flags & SPH_FDEF_TYPEMAN_DIAGENDCTRL ) |
| 6140 MOVE_Zp2_Point( point, dx, dy, TRUE ); |
| 6141 } |
| 6142 else |
| 6143 MOVE_Zp2_Point( point, dx, dy, TRUE ); |
| 6144 } |
| 6145 |
| 6146 Skip: |
| 6147 |
| 6148 #else /* !TT_CONFIG_OPTION_SUBPIXEL_HINTING */ |
| 6149 |
| 5925 MOVE_Zp2_Point( point, dx, dy, TRUE ); | 6150 MOVE_Zp2_Point( point, dx, dy, TRUE ); |
| 5926 | 6151 |
| 6152 #endif /* !TT_CONFIG_OPTION_SUBPIXEL_HINTING */ |
| 6153 |
| 5927 CUR.GS.loop--; | 6154 CUR.GS.loop--; |
| 5928 } | 6155 } |
| 5929 | 6156 |
| 5930 Fail: | 6157 Fail: |
| 5931 CUR.GS.loop = 1; | 6158 CUR.GS.loop = 1; |
| 5932 CUR.new_top = CUR.args; | 6159 CUR.new_top = CUR.args; |
| 5933 } | 6160 } |
| 5934 | 6161 |
| 5935 | 6162 |
| 5936 /*************************************************************************/ | 6163 /*************************************************************************/ |
| 5937 /* */ | 6164 /* */ |
| 5938 /* MSIRP[a]: Move Stack Indirect Relative Position */ | 6165 /* MSIRP[a]: Move Stack Indirect Relative Position */ |
| 5939 /* Opcode range: 0x3A-0x3B */ | 6166 /* Opcode range: 0x3A-0x3B */ |
| 5940 /* Stack: f26.6 uint32 --> */ | 6167 /* Stack: f26.6 uint32 --> */ |
| 5941 /* */ | 6168 /* */ |
| 5942 static void | 6169 static void |
| 5943 Ins_MSIRP( INS_ARG ) | 6170 Ins_MSIRP( INS_ARG ) |
| 5944 { | 6171 { |
| 5945 FT_UShort point; | 6172 FT_UShort point; |
| 5946 FT_F26Dot6 distance; | 6173 FT_F26Dot6 distance; |
| 5947 | 6174 |
| 6175 #ifdef TT_CONFIG_OPTION_SUBPIXEL_HINTING |
| 6176 FT_F26Dot6 control_value_cutin; |
| 6177 |
| 6178 |
| 6179 if ( SUBPIXEL_HINTING ) |
| 6180 { |
| 6181 control_value_cutin = CUR.GS.control_value_cutin; |
| 6182 |
| 6183 if ( CUR.ignore_x_mode && |
| 6184 CUR.GS.freeVector.x != 0 && |
| 6185 !( CUR.sph_tweak_flags & SPH_TWEAK_NORMAL_ROUND ) ) |
| 6186 control_value_cutin = 0; |
| 6187 } |
| 6188 |
| 6189 #endif /* TT_CONFIG_OPTION_SUBPIXEL_HINTING */ |
| 5948 | 6190 |
| 5949 point = (FT_UShort)args[0]; | 6191 point = (FT_UShort)args[0]; |
| 5950 | 6192 |
| 5951 if ( BOUNDS( point, CUR.zp1.n_points ) || | 6193 if ( BOUNDS( point, CUR.zp1.n_points ) || |
| 5952 BOUNDS( CUR.GS.rp0, CUR.zp0.n_points ) ) | 6194 BOUNDS( CUR.GS.rp0, CUR.zp0.n_points ) ) |
| 5953 { | 6195 { |
| 5954 if ( CUR.pedantic_hinting ) | 6196 if ( CUR.pedantic_hinting ) |
| 5955 CUR.error = TT_Err_Invalid_Reference; | 6197 CUR.error = FT_THROW( Invalid_Reference ); |
| 5956 return; | 6198 return; |
| 5957 } | 6199 } |
| 5958 | 6200 |
| 5959 /* UNDOCUMENTED! The MS rasterizer does that with */ | 6201 /* UNDOCUMENTED! The MS rasterizer does that with */ |
| 5960 /* twilight points (confirmed by Greg Hitchcock) */ | 6202 /* twilight points (confirmed by Greg Hitchcock) */ |
| 5961 if ( CUR.GS.gep1 == 0 ) | 6203 if ( CUR.GS.gep1 == 0 ) |
| 5962 { | 6204 { |
| 5963 CUR.zp1.org[point] = CUR.zp0.org[CUR.GS.rp0]; | 6205 CUR.zp1.org[point] = CUR.zp0.org[CUR.GS.rp0]; |
| 5964 CUR_Func_move_orig( &CUR.zp1, point, args[1] ); | 6206 CUR_Func_move_orig( &CUR.zp1, point, args[1] ); |
| 5965 CUR.zp1.cur[point] = CUR.zp1.org[point]; | 6207 CUR.zp1.cur[point] = CUR.zp1.org[point]; |
| 5966 } | 6208 } |
| 5967 | 6209 |
| 5968 distance = CUR_Func_project( CUR.zp1.cur + point, | 6210 distance = CUR_Func_project( CUR.zp1.cur + point, |
| 5969 CUR.zp0.cur + CUR.GS.rp0 ); | 6211 CUR.zp0.cur + CUR.GS.rp0 ); |
| 5970 | 6212 |
| 6213 #ifdef TT_CONFIG_OPTION_SUBPIXEL_HINTING |
| 6214 /* subpixel hinting - make MSIRP respect CVT cut-in; */ |
| 6215 if ( SUBPIXEL_HINTING && |
| 6216 CUR.ignore_x_mode && |
| 6217 CUR.GS.freeVector.x != 0 && |
| 6218 FT_ABS( distance - args[1] ) >= control_value_cutin ) |
| 6219 distance = args[1]; |
| 6220 #endif /* TT_CONFIG_OPTION_SUBPIXEL_HINTING */ |
| 6221 |
| 5971 CUR_Func_move( &CUR.zp1, point, args[1] - distance ); | 6222 CUR_Func_move( &CUR.zp1, point, args[1] - distance ); |
| 5972 | 6223 |
| 5973 CUR.GS.rp1 = CUR.GS.rp0; | 6224 CUR.GS.rp1 = CUR.GS.rp0; |
| 5974 CUR.GS.rp2 = point; | 6225 CUR.GS.rp2 = point; |
| 5975 | 6226 |
| 5976 if ( ( CUR.opcode & 1 ) != 0 ) | 6227 if ( ( CUR.opcode & 1 ) != 0 ) |
| 5977 CUR.GS.rp0 = point; | 6228 CUR.GS.rp0 = point; |
| 5978 } | 6229 } |
| 5979 | 6230 |
| 5980 | 6231 |
| 5981 /*************************************************************************/ | 6232 /*************************************************************************/ |
| 5982 /* */ | 6233 /* */ |
| 5983 /* MDAP[a]: Move Direct Absolute Point */ | 6234 /* MDAP[a]: Move Direct Absolute Point */ |
| 5984 /* Opcode range: 0x2E-0x2F */ | 6235 /* Opcode range: 0x2E-0x2F */ |
| 5985 /* Stack: uint32 --> */ | 6236 /* Stack: uint32 --> */ |
| 5986 /* */ | 6237 /* */ |
| 5987 static void | 6238 static void |
| 5988 Ins_MDAP( INS_ARG ) | 6239 Ins_MDAP( INS_ARG ) |
| 5989 { | 6240 { |
| 5990 FT_UShort point; | 6241 FT_UShort point; |
| 5991 FT_F26Dot6 cur_dist, | 6242 FT_F26Dot6 cur_dist; |
| 5992 distance; | 6243 FT_F26Dot6 distance; |
| 5993 | 6244 |
| 5994 | 6245 |
| 5995 point = (FT_UShort)args[0]; | 6246 point = (FT_UShort)args[0]; |
| 5996 | 6247 |
| 5997 if ( BOUNDS( point, CUR.zp0.n_points ) ) | 6248 if ( BOUNDS( point, CUR.zp0.n_points ) ) |
| 5998 { | 6249 { |
| 5999 if ( CUR.pedantic_hinting ) | 6250 if ( CUR.pedantic_hinting ) |
| 6000 CUR.error = TT_Err_Invalid_Reference; | 6251 CUR.error = FT_THROW( Invalid_Reference ); |
| 6001 return; | 6252 return; |
| 6002 } | 6253 } |
| 6003 | 6254 |
| 6004 if ( ( CUR.opcode & 1 ) != 0 ) | 6255 if ( ( CUR.opcode & 1 ) != 0 ) |
| 6005 { | 6256 { |
| 6006 cur_dist = CUR_fast_project( &CUR.zp0.cur[point] ); | 6257 cur_dist = CUR_fast_project( &CUR.zp0.cur[point] ); |
| 6007 distance = CUR_Func_round( cur_dist, | 6258 #ifdef TT_CONFIG_OPTION_SUBPIXEL_HINTING |
| 6008 CUR.tt_metrics.compensations[0] ) - cur_dist; | 6259 if ( SUBPIXEL_HINTING && |
| 6260 CUR.ignore_x_mode && |
| 6261 CUR.GS.freeVector.x != 0 ) |
| 6262 distance = ROUND_None( |
| 6263 cur_dist, |
| 6264 CUR.tt_metrics.compensations[0] ) - cur_dist; |
| 6265 else |
| 6266 #endif |
| 6267 distance = CUR_Func_round( |
| 6268 cur_dist, |
| 6269 CUR.tt_metrics.compensations[0] ) - cur_dist; |
| 6009 } | 6270 } |
| 6010 else | 6271 else |
| 6011 distance = 0; | 6272 distance = 0; |
| 6012 | 6273 |
| 6013 CUR_Func_move( &CUR.zp0, point, distance ); | 6274 CUR_Func_move( &CUR.zp0, point, distance ); |
| 6014 | 6275 |
| 6015 CUR.GS.rp0 = point; | 6276 CUR.GS.rp0 = point; |
| 6016 CUR.GS.rp1 = point; | 6277 CUR.GS.rp1 = point; |
| 6017 } | 6278 } |
| 6018 | 6279 |
| 6019 | 6280 |
| 6020 /*************************************************************************/ | 6281 /*************************************************************************/ |
| 6021 /* */ | 6282 /* */ |
| 6022 /* MIAP[a]: Move Indirect Absolute Point */ | 6283 /* MIAP[a]: Move Indirect Absolute Point */ |
| 6023 /* Opcode range: 0x3E-0x3F */ | 6284 /* Opcode range: 0x3E-0x3F */ |
| 6024 /* Stack: uint32 uint32 --> */ | 6285 /* Stack: uint32 uint32 --> */ |
| 6025 /* */ | 6286 /* */ |
| 6026 static void | 6287 static void |
| 6027 Ins_MIAP( INS_ARG ) | 6288 Ins_MIAP( INS_ARG ) |
| 6028 { | 6289 { |
| 6029 FT_ULong cvtEntry; | 6290 FT_ULong cvtEntry; |
| 6030 FT_UShort point; | 6291 FT_UShort point; |
| 6031 FT_F26Dot6 distance, | 6292 FT_F26Dot6 distance; |
| 6032 org_dist; | 6293 FT_F26Dot6 org_dist; |
| 6294 FT_F26Dot6 control_value_cutin; |
| 6033 | 6295 |
| 6034 | 6296 |
| 6035 cvtEntry = (FT_ULong)args[1]; | 6297 control_value_cutin = CUR.GS.control_value_cutin; |
| 6036 point = (FT_UShort)args[0]; | 6298 cvtEntry = (FT_ULong)args[1]; |
| 6299 point = (FT_UShort)args[0]; |
| 6300 |
| 6301 #ifdef TT_CONFIG_OPTION_SUBPIXEL_HINTING |
| 6302 if ( SUBPIXEL_HINTING && |
| 6303 CUR.ignore_x_mode && |
| 6304 CUR.GS.freeVector.x != 0 && |
| 6305 CUR.GS.freeVector.y == 0 && |
| 6306 !( CUR.sph_tweak_flags & SPH_TWEAK_NORMAL_ROUND ) ) |
| 6307 control_value_cutin = 0; |
| 6308 #endif /* TT_CONFIG_OPTION_SUBPIXEL_HINTING */ |
| 6037 | 6309 |
| 6038 if ( BOUNDS( point, CUR.zp0.n_points ) || | 6310 if ( BOUNDS( point, CUR.zp0.n_points ) || |
| 6039 BOUNDSL( cvtEntry, CUR.cvtSize ) ) | 6311 BOUNDSL( cvtEntry, CUR.cvtSize ) ) |
| 6040 { | 6312 { |
| 6041 if ( CUR.pedantic_hinting ) | 6313 if ( CUR.pedantic_hinting ) |
| 6042 CUR.error = TT_Err_Invalid_Reference; | 6314 CUR.error = FT_THROW( Invalid_Reference ); |
| 6043 goto Fail; | 6315 goto Fail; |
| 6044 } | 6316 } |
| 6045 | 6317 |
| 6046 /* UNDOCUMENTED! */ | 6318 /* UNDOCUMENTED! */ |
| 6047 /* */ | 6319 /* */ |
| 6048 /* The behaviour of an MIAP instruction is quite different when used */ | 6320 /* The behaviour of an MIAP instruction is quite different when used */ |
| 6049 /* in the twilight zone. */ | 6321 /* in the twilight zone. */ |
| 6050 /* */ | 6322 /* */ |
| 6051 /* First, no control value cut-in test is performed as it would fail */ | 6323 /* First, no control value cut-in test is performed as it would fail */ |
| 6052 /* anyway. Second, the original point, i.e. (org_x,org_y) of */ | 6324 /* anyway. Second, the original point, i.e. (org_x,org_y) of */ |
| 6053 /* zp0.point, is set to the absolute, unrounded distance found in the */ | 6325 /* zp0.point, is set to the absolute, unrounded distance found in the */ |
| 6054 /* CVT. */ | 6326 /* CVT. */ |
| 6055 /* */ | 6327 /* */ |
| 6056 /* This is used in the CVT programs of the Microsoft fonts Arial, */ | 6328 /* This is used in the CVT programs of the Microsoft fonts Arial, */ |
| 6057 /* Times, etc., in order to re-adjust some key font heights. It */ | 6329 /* Times, etc., in order to re-adjust some key font heights. It */ |
| 6058 /* allows the use of the IP instruction in the twilight zone, which */ | 6330 /* allows the use of the IP instruction in the twilight zone, which */ |
| 6059 /* otherwise would be invalid according to the specification. */ | 6331 /* otherwise would be invalid according to the specification. */ |
| 6060 /* */ | 6332 /* */ |
| 6061 /* We implement it with a special sequence for the twilight zone. */ | 6333 /* We implement it with a special sequence for the twilight zone. */ |
| 6062 /* This is a bad hack, but it seems to work. */ | 6334 /* This is a bad hack, but it seems to work. */ |
| 6063 /* */ | 6335 /* */ |
| 6064 /* Confirmed by Greg Hitchcock. */ | 6336 /* Confirmed by Greg Hitchcock. */ |
| 6065 | 6337 |
| 6066 distance = CUR_Func_read_cvt( cvtEntry ); | 6338 distance = CUR_Func_read_cvt( cvtEntry ); |
| 6067 | 6339 |
| 6068 if ( CUR.GS.gep0 == 0 ) /* If in twilight zone */ | 6340 if ( CUR.GS.gep0 == 0 ) /* If in twilight zone */ |
| 6069 { | 6341 { |
| 6070 CUR.zp0.org[point].x = TT_MulFix14( (FT_UInt32)distance, | 6342 #ifdef TT_CONFIG_OPTION_SUBPIXEL_HINTING |
| 6071 CUR.GS.freeVector.x ); | 6343 /* Only adjust if not in sph_compatibility_mode or ignore_x_mode. */ |
| 6344 /* Determined via experimentation and may be incorrect... */ |
| 6345 if ( !SUBPIXEL_HINTING || |
| 6346 ( !CUR.ignore_x_mode || |
| 6347 !CUR.face->sph_compatibility_mode ) ) |
| 6348 #endif /* TT_CONFIG_OPTION_SUBPIXEL_HINTING */ |
| 6349 CUR.zp0.org[point].x = TT_MulFix14( (FT_UInt32)distance, |
| 6350 CUR.GS.freeVector.x ); |
| 6072 CUR.zp0.org[point].y = TT_MulFix14( (FT_UInt32)distance, | 6351 CUR.zp0.org[point].y = TT_MulFix14( (FT_UInt32)distance, |
| 6073 CUR.GS.freeVector.y ), | 6352 CUR.GS.freeVector.y ), |
| 6074 CUR.zp0.cur[point] = CUR.zp0.org[point]; | 6353 CUR.zp0.cur[point] = CUR.zp0.org[point]; |
| 6075 } | 6354 } |
| 6355 #ifdef TT_CONFIG_OPTION_SUBPIXEL_HINTING |
| 6356 if ( SUBPIXEL_HINTING && |
| 6357 CUR.ignore_x_mode && |
| 6358 ( CUR.sph_tweak_flags & SPH_TWEAK_MIAP_HACK ) && |
| 6359 distance > 0 && |
| 6360 CUR.GS.freeVector.y != 0 ) |
| 6361 distance = 0; |
| 6362 #endif /* TT_CONFIG_OPTION_SUBPIXEL_HINTING */ |
| 6076 | 6363 |
| 6077 org_dist = CUR_fast_project( &CUR.zp0.cur[point] ); | 6364 org_dist = CUR_fast_project( &CUR.zp0.cur[point] ); |
| 6078 | 6365 |
| 6079 if ( ( CUR.opcode & 1 ) != 0 ) /* rounding and control cutin flag */ | 6366 if ( ( CUR.opcode & 1 ) != 0 ) /* rounding and control cut-in flag */ |
| 6080 { | 6367 { |
| 6081 if ( FT_ABS( distance - org_dist ) > CUR.GS.control_value_cutin ) | 6368 if ( FT_ABS( distance - org_dist ) > control_value_cutin ) |
| 6082 distance = org_dist; | 6369 distance = org_dist; |
| 6083 | 6370 |
| 6084 distance = CUR_Func_round( distance, CUR.tt_metrics.compensations[0] ); | 6371 #ifdef TT_CONFIG_OPTION_SUBPIXEL_HINTING |
| 6372 if ( SUBPIXEL_HINTING && |
| 6373 CUR.ignore_x_mode && |
| 6374 CUR.GS.freeVector.x != 0 ) |
| 6375 distance = ROUND_None( distance, |
| 6376 CUR.tt_metrics.compensations[0] ); |
| 6377 else |
| 6378 #endif |
| 6379 distance = CUR_Func_round( distance, |
| 6380 CUR.tt_metrics.compensations[0] ); |
| 6085 } | 6381 } |
| 6086 | 6382 |
| 6087 CUR_Func_move( &CUR.zp0, point, distance - org_dist ); | 6383 CUR_Func_move( &CUR.zp0, point, distance - org_dist ); |
| 6088 | 6384 |
| 6089 Fail: | 6385 Fail: |
| 6090 CUR.GS.rp0 = point; | 6386 CUR.GS.rp0 = point; |
| 6091 CUR.GS.rp1 = point; | 6387 CUR.GS.rp1 = point; |
| 6092 } | 6388 } |
| 6093 | 6389 |
| 6094 | 6390 |
| 6095 /*************************************************************************/ | 6391 /*************************************************************************/ |
| 6096 /* */ | 6392 /* */ |
| 6097 /* MDRP[abcde]: Move Direct Relative Point */ | 6393 /* MDRP[abcde]: Move Direct Relative Point */ |
| 6098 /* Opcode range: 0xC0-0xDF */ | 6394 /* Opcode range: 0xC0-0xDF */ |
| 6099 /* Stack: uint32 --> */ | 6395 /* Stack: uint32 --> */ |
| 6100 /* */ | 6396 /* */ |
| 6101 static void | 6397 static void |
| 6102 Ins_MDRP( INS_ARG ) | 6398 Ins_MDRP( INS_ARG ) |
| 6103 { | 6399 { |
| 6104 FT_UShort point; | 6400 FT_UShort point; |
| 6105 FT_F26Dot6 org_dist, distance; | 6401 FT_F26Dot6 org_dist, distance, minimum_distance; |
| 6106 | 6402 |
| 6107 | 6403 |
| 6404 minimum_distance = CUR.GS.minimum_distance; |
| 6405 |
| 6406 #ifdef TT_CONFIG_OPTION_SUBPIXEL_HINTING |
| 6407 if ( SUBPIXEL_HINTING && |
| 6408 CUR.ignore_x_mode && |
| 6409 CUR.GS.freeVector.x != 0 && |
| 6410 !( CUR.sph_tweak_flags & SPH_TWEAK_NORMAL_ROUND ) ) |
| 6411 minimum_distance = 0; |
| 6412 #endif /* TT_CONFIG_OPTION_SUBPIXEL_HINTING */ |
| 6413 |
| 6108 point = (FT_UShort)args[0]; | 6414 point = (FT_UShort)args[0]; |
| 6109 | 6415 |
| 6110 if ( BOUNDS( point, CUR.zp1.n_points ) || | 6416 if ( BOUNDS( point, CUR.zp1.n_points ) || |
| 6111 BOUNDS( CUR.GS.rp0, CUR.zp0.n_points ) ) | 6417 BOUNDS( CUR.GS.rp0, CUR.zp0.n_points ) ) |
| 6112 { | 6418 { |
| 6113 if ( CUR.pedantic_hinting ) | 6419 if ( CUR.pedantic_hinting ) |
| 6114 CUR.error = TT_Err_Invalid_Reference; | 6420 CUR.error = FT_THROW( Invalid_Reference ); |
| 6115 goto Fail; | 6421 goto Fail; |
| 6116 } | 6422 } |
| 6117 | 6423 |
| 6118 /* XXX: Is there some undocumented feature while in the */ | 6424 /* XXX: Is there some undocumented feature while in the */ |
| 6119 /* twilight zone? */ | 6425 /* twilight zone? */ |
| 6120 | 6426 |
| 6121 /* XXX: UNDOCUMENTED: twilight zone special case */ | 6427 /* XXX: UNDOCUMENTED: twilight zone special case */ |
| 6122 | 6428 |
| 6123 if ( CUR.GS.gep0 == 0 || CUR.GS.gep1 == 0 ) | 6429 if ( CUR.GS.gep0 == 0 || CUR.GS.gep1 == 0 ) |
| 6124 { | 6430 { |
| 6125 FT_Vector* vec1 = &CUR.zp1.org[point]; | 6431 FT_Vector* vec1 = &CUR.zp1.org[point]; |
| 6126 FT_Vector* vec2 = &CUR.zp0.org[CUR.GS.rp0]; | 6432 FT_Vector* vec2 = &CUR.zp0.org[CUR.GS.rp0]; |
| 6127 | 6433 |
| 6128 | 6434 |
| 6129 org_dist = CUR_Func_dualproj( vec1, vec2 ); | 6435 org_dist = CUR_Func_dualproj( vec1, vec2 ); |
| 6130 } | 6436 } |
| 6131 else | 6437 else |
| 6132 { | 6438 { |
| 6133 FT_Vector* vec1 = &CUR.zp1.orus[point]; | 6439 FT_Vector* vec1 = &CUR.zp1.orus[point]; |
| 6134 FT_Vector* vec2 = &CUR.zp0.orus[CUR.GS.rp0]; | 6440 FT_Vector* vec2 = &CUR.zp0.orus[CUR.GS.rp0]; |
| 6135 | 6441 |
| 6136 | 6442 |
| 6137 if ( CUR.metrics.x_scale == CUR.metrics.y_scale ) | 6443 if ( CUR.metrics.x_scale == CUR.metrics.y_scale ) |
| 6138 { | 6444 { |
| 6139 /* this should be faster */ | 6445 /* this should be faster */ |
| 6140 org_dist = CUR_Func_dualproj( vec1, vec2 ); | 6446 org_dist = CUR_Func_dualproj( vec1, vec2 ); |
| 6141 org_dist = TT_MULFIX( org_dist, CUR.metrics.x_scale ); | 6447 org_dist = FT_MulFix( org_dist, CUR.metrics.x_scale ); |
| 6142 } | 6448 } |
| 6143 else | 6449 else |
| 6144 { | 6450 { |
| 6145 FT_Vector vec; | 6451 FT_Vector vec; |
| 6146 | 6452 |
| 6147 | 6453 |
| 6148 vec.x = TT_MULFIX( vec1->x - vec2->x, CUR.metrics.x_scale ); | 6454 vec.x = FT_MulFix( vec1->x - vec2->x, CUR.metrics.x_scale ); |
| 6149 vec.y = TT_MULFIX( vec1->y - vec2->y, CUR.metrics.y_scale ); | 6455 vec.y = FT_MulFix( vec1->y - vec2->y, CUR.metrics.y_scale ); |
| 6150 | 6456 |
| 6151 org_dist = CUR_fast_dualproj( &vec ); | 6457 org_dist = CUR_fast_dualproj( &vec ); |
| 6152 } | 6458 } |
| 6153 } | 6459 } |
| 6154 | 6460 |
| 6155 /* single width cut-in test */ | 6461 /* single width cut-in test */ |
| 6156 | 6462 |
| 6157 if ( FT_ABS( org_dist - CUR.GS.single_width_value ) < | 6463 if ( FT_ABS( org_dist - CUR.GS.single_width_value ) < |
| 6158 CUR.GS.single_width_cutin ) | 6464 CUR.GS.single_width_cutin ) |
| 6159 { | 6465 { |
| 6160 if ( org_dist >= 0 ) | 6466 if ( org_dist >= 0 ) |
| 6161 org_dist = CUR.GS.single_width_value; | 6467 org_dist = CUR.GS.single_width_value; |
| 6162 else | 6468 else |
| 6163 org_dist = -CUR.GS.single_width_value; | 6469 org_dist = -CUR.GS.single_width_value; |
| 6164 } | 6470 } |
| 6165 | 6471 |
| 6166 /* round flag */ | 6472 /* round flag */ |
| 6167 | 6473 |
| 6168 if ( ( CUR.opcode & 4 ) != 0 ) | 6474 if ( ( CUR.opcode & 4 ) != 0 ) |
| 6475 { |
| 6476 #ifdef TT_CONFIG_OPTION_SUBPIXEL_HINTING |
| 6477 if ( SUBPIXEL_HINTING && |
| 6478 CUR.ignore_x_mode && |
| 6479 CUR.GS.freeVector.x != 0 ) |
| 6480 distance = ROUND_None( |
| 6481 org_dist, |
| 6482 CUR.tt_metrics.compensations[CUR.opcode & 3] ); |
| 6483 else |
| 6484 #endif |
| 6169 distance = CUR_Func_round( | 6485 distance = CUR_Func_round( |
| 6170 org_dist, | 6486 org_dist, |
| 6171 CUR.tt_metrics.compensations[CUR.opcode & 3] ); | 6487 CUR.tt_metrics.compensations[CUR.opcode & 3] ); |
| 6488 } |
| 6172 else | 6489 else |
| 6173 distance = ROUND_None( | 6490 distance = ROUND_None( |
| 6174 org_dist, | 6491 org_dist, |
| 6175 CUR.tt_metrics.compensations[CUR.opcode & 3] ); | 6492 CUR.tt_metrics.compensations[CUR.opcode & 3] ); |
| 6176 | 6493 |
| 6177 /* minimum distance flag */ | 6494 /* minimum distance flag */ |
| 6178 | 6495 |
| 6179 if ( ( CUR.opcode & 8 ) != 0 ) | 6496 if ( ( CUR.opcode & 8 ) != 0 ) |
| 6180 { | 6497 { |
| 6181 if ( org_dist >= 0 ) | 6498 if ( org_dist >= 0 ) |
| 6182 { | 6499 { |
| 6183 if ( distance < CUR.GS.minimum_distance ) | 6500 if ( distance < minimum_distance ) |
| 6184 distance = CUR.GS.minimum_distance; | 6501 distance = minimum_distance; |
| 6185 } | 6502 } |
| 6186 else | 6503 else |
| 6187 { | 6504 { |
| 6188 if ( distance > -CUR.GS.minimum_distance ) | 6505 if ( distance > -minimum_distance ) |
| 6189 distance = -CUR.GS.minimum_distance; | 6506 distance = -minimum_distance; |
| 6190 } | 6507 } |
| 6191 } | 6508 } |
| 6192 | 6509 |
| 6193 /* now move the point */ | 6510 /* now move the point */ |
| 6194 | 6511 |
| 6195 org_dist = CUR_Func_project( CUR.zp1.cur + point, | 6512 org_dist = CUR_Func_project( CUR.zp1.cur + point, |
| 6196 CUR.zp0.cur + CUR.GS.rp0 ); | 6513 CUR.zp0.cur + CUR.GS.rp0 ); |
| 6197 | 6514 |
| 6198 CUR_Func_move( &CUR.zp1, point, distance - org_dist ); | 6515 CUR_Func_move( &CUR.zp1, point, distance - org_dist ); |
| 6199 | 6516 |
| (...skipping 14 matching lines...) Expand all Loading... |
| 6214 /* */ | 6531 /* */ |
| 6215 static void | 6532 static void |
| 6216 Ins_MIRP( INS_ARG ) | 6533 Ins_MIRP( INS_ARG ) |
| 6217 { | 6534 { |
| 6218 FT_UShort point; | 6535 FT_UShort point; |
| 6219 FT_ULong cvtEntry; | 6536 FT_ULong cvtEntry; |
| 6220 | 6537 |
| 6221 FT_F26Dot6 cvt_dist, | 6538 FT_F26Dot6 cvt_dist, |
| 6222 distance, | 6539 distance, |
| 6223 cur_dist, | 6540 cur_dist, |
| 6224 org_dist; | 6541 org_dist, |
| 6542 control_value_cutin, |
| 6543 minimum_distance; |
| 6544 #ifdef TT_CONFIG_OPTION_SUBPIXEL_HINTING |
| 6545 FT_Int B1; |
| 6546 FT_Int B2; |
| 6547 FT_Bool reverse_move = FALSE; |
| 6548 #endif /* TT_CONFIG_OPTION_SUBPIXEL_HINTING */ |
| 6225 | 6549 |
| 6226 | 6550 |
| 6227 point = (FT_UShort)args[0]; | 6551 minimum_distance = CUR.GS.minimum_distance; |
| 6228 cvtEntry = (FT_ULong)( args[1] + 1 ); | 6552 control_value_cutin = CUR.GS.control_value_cutin; |
| 6553 point = (FT_UShort)args[0]; |
| 6554 cvtEntry = (FT_ULong)( args[1] + 1 ); |
| 6555 |
| 6556 #ifdef TT_CONFIG_OPTION_SUBPIXEL_HINTING |
| 6557 if ( SUBPIXEL_HINTING && |
| 6558 CUR.ignore_x_mode && |
| 6559 CUR.GS.freeVector.x != 0 && |
| 6560 !( CUR.sph_tweak_flags & SPH_TWEAK_NORMAL_ROUND ) ) |
| 6561 control_value_cutin = minimum_distance = 0; |
| 6562 #endif /* TT_CONFIG_OPTION_SUBPIXEL_HINTING */ |
| 6229 | 6563 |
| 6230 /* XXX: UNDOCUMENTED! cvt[-1] = 0 always */ | 6564 /* XXX: UNDOCUMENTED! cvt[-1] = 0 always */ |
| 6231 | 6565 |
| 6232 if ( BOUNDS( point, CUR.zp1.n_points ) || | 6566 if ( BOUNDS( point, CUR.zp1.n_points ) || |
| 6233 BOUNDSL( cvtEntry, CUR.cvtSize + 1 ) || | 6567 BOUNDSL( cvtEntry, CUR.cvtSize + 1 ) || |
| 6234 BOUNDS( CUR.GS.rp0, CUR.zp0.n_points ) ) | 6568 BOUNDS( CUR.GS.rp0, CUR.zp0.n_points ) ) |
| 6235 { | 6569 { |
| 6236 if ( CUR.pedantic_hinting ) | 6570 if ( CUR.pedantic_hinting ) |
| 6237 CUR.error = TT_Err_Invalid_Reference; | 6571 CUR.error = FT_THROW( Invalid_Reference ); |
| 6238 goto Fail; | 6572 goto Fail; |
| 6239 } | 6573 } |
| 6240 | 6574 |
| 6241 if ( !cvtEntry ) | 6575 if ( !cvtEntry ) |
| 6242 cvt_dist = 0; | 6576 cvt_dist = 0; |
| 6243 else | 6577 else |
| 6244 cvt_dist = CUR_Func_read_cvt( cvtEntry - 1 ); | 6578 cvt_dist = CUR_Func_read_cvt( cvtEntry - 1 ); |
| 6245 | 6579 |
| 6246 /* single width test */ | 6580 /* single width test */ |
| 6247 | 6581 |
| (...skipping 25 matching lines...) Expand all Loading... |
| 6273 &CUR.zp0.cur[CUR.GS.rp0] ); | 6607 &CUR.zp0.cur[CUR.GS.rp0] ); |
| 6274 | 6608 |
| 6275 /* auto-flip test */ | 6609 /* auto-flip test */ |
| 6276 | 6610 |
| 6277 if ( CUR.GS.auto_flip ) | 6611 if ( CUR.GS.auto_flip ) |
| 6278 { | 6612 { |
| 6279 if ( ( org_dist ^ cvt_dist ) < 0 ) | 6613 if ( ( org_dist ^ cvt_dist ) < 0 ) |
| 6280 cvt_dist = -cvt_dist; | 6614 cvt_dist = -cvt_dist; |
| 6281 } | 6615 } |
| 6282 | 6616 |
| 6283 /* control value cutin and round */ | 6617 #ifdef TT_CONFIG_OPTION_SUBPIXEL_HINTING |
| 6618 if ( SUBPIXEL_HINTING && |
| 6619 CUR.ignore_x_mode && |
| 6620 CUR.GS.freeVector.y != 0 && |
| 6621 ( CUR.sph_tweak_flags & SPH_TWEAK_TIMES_NEW_ROMAN_HACK ) ) |
| 6622 { |
| 6623 if ( cur_dist < -64 ) |
| 6624 cvt_dist -= 16; |
| 6625 else if ( cur_dist > 64 && cur_dist < 84 ) |
| 6626 cvt_dist += 32; |
| 6627 } |
| 6628 #endif /* TT_CONFIG_OPTION_SUBPIXEL_HINTING */ |
| 6629 |
| 6630 /* control value cut-in and round */ |
| 6284 | 6631 |
| 6285 if ( ( CUR.opcode & 4 ) != 0 ) | 6632 if ( ( CUR.opcode & 4 ) != 0 ) |
| 6286 { | 6633 { |
| 6287 /* XXX: UNDOCUMENTED! Only perform cut-in test when both points */ | 6634 /* XXX: UNDOCUMENTED! Only perform cut-in test when both points */ |
| 6288 /* refer to the same zone. */ | 6635 /* refer to the same zone. */ |
| 6289 | 6636 |
| 6290 if ( CUR.GS.gep0 == CUR.GS.gep1 ) | 6637 if ( CUR.GS.gep0 == CUR.GS.gep1 ) |
| 6291 { | 6638 { |
| 6292 /* XXX: According to Greg Hitchcock, the following wording is */ | 6639 /* XXX: According to Greg Hitchcock, the following wording is */ |
| 6293 /* the right one: */ | 6640 /* the right one: */ |
| 6294 /* */ | 6641 /* */ |
| 6295 /* When the absolute difference between the value in */ | 6642 /* When the absolute difference between the value in */ |
| 6296 /* the table [CVT] and the measurement directly from */ | 6643 /* the table [CVT] and the measurement directly from */ |
| 6297 /* the outline is _greater_ than the cut_in value, the */ | 6644 /* the outline is _greater_ than the cut_in value, the */ |
| 6298 /* outline measurement is used. */ | 6645 /* outline measurement is used. */ |
| 6299 /* */ | 6646 /* */ |
| 6300 /* This is from `instgly.doc'. The description in */ | 6647 /* This is from `instgly.doc'. The description in */ |
| 6301 /* `ttinst2.doc', version 1.66, is thus incorrect since */ | 6648 /* `ttinst2.doc', version 1.66, is thus incorrect since */ |
| 6302 /* it implies `>=' instead of `>'. */ | 6649 /* it implies `>=' instead of `>'. */ |
| 6303 | 6650 |
| 6304 if ( FT_ABS( cvt_dist - org_dist ) > CUR.GS.control_value_cutin ) | 6651 if ( FT_ABS( cvt_dist - org_dist ) > control_value_cutin ) |
| 6305 cvt_dist = org_dist; | 6652 cvt_dist = org_dist; |
| 6306 } | 6653 } |
| 6307 | 6654 |
| 6308 distance = CUR_Func_round( | 6655 distance = CUR_Func_round( |
| 6309 cvt_dist, | 6656 cvt_dist, |
| 6310 CUR.tt_metrics.compensations[CUR.opcode & 3] ); | 6657 CUR.tt_metrics.compensations[CUR.opcode & 3] ); |
| 6311 } | 6658 } |
| 6312 else | 6659 else |
| 6660 { |
| 6661 |
| 6662 #ifdef TT_CONFIG_OPTION_SUBPIXEL_HINTING |
| 6663 /* do cvt cut-in always in MIRP for sph */ |
| 6664 if ( SUBPIXEL_HINTING && |
| 6665 CUR.ignore_x_mode && |
| 6666 CUR.GS.gep0 == CUR.GS.gep1 ) |
| 6667 { |
| 6668 if ( FT_ABS( cvt_dist - org_dist ) > control_value_cutin ) |
| 6669 cvt_dist = org_dist; |
| 6670 } |
| 6671 #endif /* TT_CONFIG_OPTION_SUBPIXEL_HINTING */ |
| 6672 |
| 6313 distance = ROUND_None( | 6673 distance = ROUND_None( |
| 6314 cvt_dist, | 6674 cvt_dist, |
| 6315 CUR.tt_metrics.compensations[CUR.opcode & 3] ); | 6675 CUR.tt_metrics.compensations[CUR.opcode & 3] ); |
| 6676 } |
| 6316 | 6677 |
| 6317 /* minimum distance test */ | 6678 /* minimum distance test */ |
| 6318 | 6679 |
| 6319 if ( ( CUR.opcode & 8 ) != 0 ) | 6680 if ( ( CUR.opcode & 8 ) != 0 ) |
| 6320 { | 6681 { |
| 6321 if ( org_dist >= 0 ) | 6682 if ( org_dist >= 0 ) |
| 6322 { | 6683 { |
| 6323 if ( distance < CUR.GS.minimum_distance ) | 6684 if ( distance < minimum_distance ) |
| 6324 distance = CUR.GS.minimum_distance; | 6685 distance = minimum_distance; |
| 6325 } | 6686 } |
| 6326 else | 6687 else |
| 6327 { | 6688 { |
| 6328 if ( distance > -CUR.GS.minimum_distance ) | 6689 if ( distance > -minimum_distance ) |
| 6329 distance = -CUR.GS.minimum_distance; | 6690 distance = -minimum_distance; |
| 6330 } | 6691 } |
| 6331 } | 6692 } |
| 6332 | 6693 |
| 6694 #ifdef TT_CONFIG_OPTION_SUBPIXEL_HINTING |
| 6695 if ( SUBPIXEL_HINTING ) |
| 6696 { |
| 6697 B1 = CUR.zp1.cur[point].y; |
| 6698 |
| 6699 /* Round moves if necessary */ |
| 6700 if ( CUR.ignore_x_mode && |
| 6701 CUR.GS.freeVector.y != 0 && |
| 6702 ( CUR.sph_tweak_flags & SPH_TWEAK_ROUND_NONPIXEL_Y_MOVES ) ) |
| 6703 distance = FT_PIX_ROUND( B1 + distance - cur_dist ) - B1 + cur_dist; |
| 6704 |
| 6705 if ( CUR.ignore_x_mode && |
| 6706 CUR.GS.freeVector.y != 0 && |
| 6707 ( CUR.opcode & 16 ) == 0 && |
| 6708 ( CUR.opcode & 8 ) == 0 && |
| 6709 ( CUR.sph_tweak_flags & SPH_TWEAK_COURIER_NEW_2_HACK ) ) |
| 6710 distance += 64; |
| 6711 } |
| 6712 #endif /* TT_CONFIG_OPTION_SUBPIXEL_HINTING */ |
| 6713 |
| 6333 CUR_Func_move( &CUR.zp1, point, distance - cur_dist ); | 6714 CUR_Func_move( &CUR.zp1, point, distance - cur_dist ); |
| 6334 | 6715 |
| 6716 #ifdef TT_CONFIG_OPTION_SUBPIXEL_HINTING |
| 6717 if ( SUBPIXEL_HINTING ) |
| 6718 { |
| 6719 B2 = CUR.zp1.cur[point].y; |
| 6720 |
| 6721 /* Reverse move if necessary */ |
| 6722 if ( CUR.ignore_x_mode ) |
| 6723 { |
| 6724 if ( CUR.face->sph_compatibility_mode && |
| 6725 CUR.GS.freeVector.y != 0 && |
| 6726 ( B1 & 63 ) == 0 && |
| 6727 ( B2 & 63 ) != 0 ) |
| 6728 reverse_move = TRUE; |
| 6729 |
| 6730 if ( ( CUR.sph_tweak_flags & SPH_TWEAK_SKIP_NONPIXEL_Y_MOVES ) && |
| 6731 CUR.GS.freeVector.y != 0 && |
| 6732 ( B2 & 63 ) != 0 && |
| 6733 ( B1 & 63 ) != 0 ) |
| 6734 reverse_move = TRUE; |
| 6735 } |
| 6736 |
| 6737 if ( reverse_move ) |
| 6738 CUR_Func_move( &CUR.zp1, point, -( distance - cur_dist ) ); |
| 6739 } |
| 6740 |
| 6741 #endif /* TT_CONFIG_OPTION_SUBPIXEL_HINTING */ |
| 6742 |
| 6335 Fail: | 6743 Fail: |
| 6336 CUR.GS.rp1 = CUR.GS.rp0; | 6744 CUR.GS.rp1 = CUR.GS.rp0; |
| 6337 | 6745 |
| 6338 if ( ( CUR.opcode & 16 ) != 0 ) | 6746 if ( ( CUR.opcode & 16 ) != 0 ) |
| 6339 CUR.GS.rp0 = point; | 6747 CUR.GS.rp0 = point; |
| 6340 | 6748 |
| 6341 CUR.GS.rp2 = point; | 6749 CUR.GS.rp2 = point; |
| 6342 } | 6750 } |
| 6343 | 6751 |
| 6344 | 6752 |
| 6345 /*************************************************************************/ | 6753 /*************************************************************************/ |
| 6346 /* */ | 6754 /* */ |
| 6347 /* ALIGNRP[]: ALIGN Relative Point */ | 6755 /* ALIGNRP[]: ALIGN Relative Point */ |
| 6348 /* Opcode range: 0x3C */ | 6756 /* Opcode range: 0x3C */ |
| 6349 /* Stack: uint32 uint32... --> */ | 6757 /* Stack: uint32 uint32... --> */ |
| 6350 /* */ | 6758 /* */ |
| 6351 static void | 6759 static void |
| 6352 Ins_ALIGNRP( INS_ARG ) | 6760 Ins_ALIGNRP( INS_ARG ) |
| 6353 { | 6761 { |
| 6354 FT_UShort point; | 6762 FT_UShort point; |
| 6355 FT_F26Dot6 distance; | 6763 FT_F26Dot6 distance; |
| 6356 | 6764 |
| 6357 FT_UNUSED_ARG; | 6765 FT_UNUSED_ARG; |
| 6358 | 6766 |
| 6359 | 6767 |
| 6768 #ifdef TT_CONFIG_OPTION_SUBPIXEL_HINTING |
| 6769 if ( SUBPIXEL_HINTING && |
| 6770 CUR.ignore_x_mode && |
| 6771 CUR.iup_called && |
| 6772 ( CUR.sph_tweak_flags & SPH_TWEAK_NO_ALIGNRP_AFTER_IUP ) ) |
| 6773 { |
| 6774 CUR.error = FT_THROW( Invalid_Reference ); |
| 6775 goto Fail; |
| 6776 } |
| 6777 #endif /* TT_CONFIG_OPTION_SUBPIXEL_HINTING */ |
| 6778 |
| 6360 if ( CUR.top < CUR.GS.loop || | 6779 if ( CUR.top < CUR.GS.loop || |
| 6361 BOUNDS( CUR.GS.rp0, CUR.zp0.n_points ) ) | 6780 BOUNDS( CUR.GS.rp0, CUR.zp0.n_points ) ) |
| 6362 { | 6781 { |
| 6363 if ( CUR.pedantic_hinting ) | 6782 if ( CUR.pedantic_hinting ) |
| 6364 CUR.error = TT_Err_Invalid_Reference; | 6783 CUR.error = FT_THROW( Invalid_Reference ); |
| 6365 goto Fail; | 6784 goto Fail; |
| 6366 } | 6785 } |
| 6367 | 6786 |
| 6368 while ( CUR.GS.loop > 0 ) | 6787 while ( CUR.GS.loop > 0 ) |
| 6369 { | 6788 { |
| 6370 CUR.args--; | 6789 CUR.args--; |
| 6371 | 6790 |
| 6372 point = (FT_UShort)CUR.stack[CUR.args]; | 6791 point = (FT_UShort)CUR.stack[CUR.args]; |
| 6373 | 6792 |
| 6374 if ( BOUNDS( point, CUR.zp1.n_points ) ) | 6793 if ( BOUNDS( point, CUR.zp1.n_points ) ) |
| 6375 { | 6794 { |
| 6376 if ( CUR.pedantic_hinting ) | 6795 if ( CUR.pedantic_hinting ) |
| 6377 { | 6796 { |
| 6378 CUR.error = TT_Err_Invalid_Reference; | 6797 CUR.error = FT_THROW( Invalid_Reference ); |
| 6379 return; | 6798 return; |
| 6380 } | 6799 } |
| 6381 } | 6800 } |
| 6382 else | 6801 else |
| 6383 { | 6802 { |
| 6384 distance = CUR_Func_project( CUR.zp1.cur + point, | 6803 distance = CUR_Func_project( CUR.zp1.cur + point, |
| 6385 CUR.zp0.cur + CUR.GS.rp0 ); | 6804 CUR.zp0.cur + CUR.GS.rp0 ); |
| 6386 | 6805 |
| 6387 CUR_Func_move( &CUR.zp1, point, -distance ); | 6806 CUR_Func_move( &CUR.zp1, point, -distance ); |
| 6388 } | 6807 } |
| (...skipping 13 matching lines...) Expand all Loading... |
| 6402 /* Opcode range: 0x0F */ | 6821 /* Opcode range: 0x0F */ |
| 6403 /* Stack: 5 * uint32 --> */ | 6822 /* Stack: 5 * uint32 --> */ |
| 6404 /* */ | 6823 /* */ |
| 6405 static void | 6824 static void |
| 6406 Ins_ISECT( INS_ARG ) | 6825 Ins_ISECT( INS_ARG ) |
| 6407 { | 6826 { |
| 6408 FT_UShort point, | 6827 FT_UShort point, |
| 6409 a0, a1, | 6828 a0, a1, |
| 6410 b0, b1; | 6829 b0, b1; |
| 6411 | 6830 |
| 6412 FT_F26Dot6 discriminant; | 6831 FT_F26Dot6 discriminant, dotproduct; |
| 6413 | 6832 |
| 6414 FT_F26Dot6 dx, dy, | 6833 FT_F26Dot6 dx, dy, |
| 6415 dax, day, | 6834 dax, day, |
| 6416 dbx, dby; | 6835 dbx, dby; |
| 6417 | 6836 |
| 6418 FT_F26Dot6 val; | 6837 FT_F26Dot6 val; |
| 6419 | 6838 |
| 6420 FT_Vector R; | 6839 FT_Vector R; |
| 6421 | 6840 |
| 6422 | 6841 |
| 6423 point = (FT_UShort)args[0]; | 6842 point = (FT_UShort)args[0]; |
| 6424 | 6843 |
| 6425 a0 = (FT_UShort)args[1]; | 6844 a0 = (FT_UShort)args[1]; |
| 6426 a1 = (FT_UShort)args[2]; | 6845 a1 = (FT_UShort)args[2]; |
| 6427 b0 = (FT_UShort)args[3]; | 6846 b0 = (FT_UShort)args[3]; |
| 6428 b1 = (FT_UShort)args[4]; | 6847 b1 = (FT_UShort)args[4]; |
| 6429 | 6848 |
| 6430 if ( BOUNDS( b0, CUR.zp0.n_points ) || | 6849 if ( BOUNDS( b0, CUR.zp0.n_points ) || |
| 6431 BOUNDS( b1, CUR.zp0.n_points ) || | 6850 BOUNDS( b1, CUR.zp0.n_points ) || |
| 6432 BOUNDS( a0, CUR.zp1.n_points ) || | 6851 BOUNDS( a0, CUR.zp1.n_points ) || |
| 6433 BOUNDS( a1, CUR.zp1.n_points ) || | 6852 BOUNDS( a1, CUR.zp1.n_points ) || |
| 6434 BOUNDS( point, CUR.zp2.n_points ) ) | 6853 BOUNDS( point, CUR.zp2.n_points ) ) |
| 6435 { | 6854 { |
| 6436 if ( CUR.pedantic_hinting ) | 6855 if ( CUR.pedantic_hinting ) |
| 6437 CUR.error = TT_Err_Invalid_Reference; | 6856 CUR.error = FT_THROW( Invalid_Reference ); |
| 6438 return; | 6857 return; |
| 6439 } | 6858 } |
| 6440 | 6859 |
| 6860 /* Cramer's rule */ |
| 6861 |
| 6441 dbx = CUR.zp0.cur[b1].x - CUR.zp0.cur[b0].x; | 6862 dbx = CUR.zp0.cur[b1].x - CUR.zp0.cur[b0].x; |
| 6442 dby = CUR.zp0.cur[b1].y - CUR.zp0.cur[b0].y; | 6863 dby = CUR.zp0.cur[b1].y - CUR.zp0.cur[b0].y; |
| 6443 | 6864 |
| 6444 dax = CUR.zp1.cur[a1].x - CUR.zp1.cur[a0].x; | 6865 dax = CUR.zp1.cur[a1].x - CUR.zp1.cur[a0].x; |
| 6445 day = CUR.zp1.cur[a1].y - CUR.zp1.cur[a0].y; | 6866 day = CUR.zp1.cur[a1].y - CUR.zp1.cur[a0].y; |
| 6446 | 6867 |
| 6447 dx = CUR.zp0.cur[b0].x - CUR.zp1.cur[a0].x; | 6868 dx = CUR.zp0.cur[b0].x - CUR.zp1.cur[a0].x; |
| 6448 dy = CUR.zp0.cur[b0].y - CUR.zp1.cur[a0].y; | 6869 dy = CUR.zp0.cur[b0].y - CUR.zp1.cur[a0].y; |
| 6449 | 6870 |
| 6450 CUR.zp2.tags[point] |= FT_CURVE_TAG_TOUCH_BOTH; | 6871 CUR.zp2.tags[point] |= FT_CURVE_TAG_TOUCH_BOTH; |
| 6451 | 6872 |
| 6452 discriminant = TT_MULDIV( dax, -dby, 0x40 ) + | 6873 discriminant = FT_MulDiv( dax, -dby, 0x40 ) + |
| 6453 TT_MULDIV( day, dbx, 0x40 ); | 6874 FT_MulDiv( day, dbx, 0x40 ); |
| 6875 dotproduct = FT_MulDiv( dax, dbx, 0x40 ) + |
| 6876 FT_MulDiv( day, dby, 0x40 ); |
| 6454 | 6877 |
| 6455 if ( FT_ABS( discriminant ) >= 0x40 ) | 6878 /* The discriminant above is actually a cross product of vectors */ |
| 6879 /* da and db. Together with the dot product, they can be used as */ |
| 6880 /* surrogates for sine and cosine of the angle between the vectors. */ |
| 6881 /* Indeed, */ |
| 6882 /* dotproduct = |da||db|cos(angle) */ |
| 6883 /* discriminant = |da||db|sin(angle) . */ |
| 6884 /* We use these equations to reject grazing intersections by */ |
| 6885 /* thresholding abs(tan(angle)) at 1/19, corresponding to 3 degrees. */ |
| 6886 if ( 19 * FT_ABS( discriminant ) > FT_ABS( dotproduct ) ) |
| 6456 { | 6887 { |
| 6457 val = TT_MULDIV( dx, -dby, 0x40 ) + TT_MULDIV( dy, dbx, 0x40 ); | 6888 val = FT_MulDiv( dx, -dby, 0x40 ) + FT_MulDiv( dy, dbx, 0x40 ); |
| 6458 | 6889 |
| 6459 R.x = TT_MULDIV( val, dax, discriminant ); | 6890 R.x = FT_MulDiv( val, dax, discriminant ); |
| 6460 R.y = TT_MULDIV( val, day, discriminant ); | 6891 R.y = FT_MulDiv( val, day, discriminant ); |
| 6461 | 6892 |
| 6462 CUR.zp2.cur[point].x = CUR.zp1.cur[a0].x + R.x; | 6893 CUR.zp2.cur[point].x = CUR.zp1.cur[a0].x + R.x; |
| 6463 CUR.zp2.cur[point].y = CUR.zp1.cur[a0].y + R.y; | 6894 CUR.zp2.cur[point].y = CUR.zp1.cur[a0].y + R.y; |
| 6464 } | 6895 } |
| 6465 else | 6896 else |
| 6466 { | 6897 { |
| 6467 /* else, take the middle of the middles of A and B */ | 6898 /* else, take the middle of the middles of A and B */ |
| 6468 | 6899 |
| 6469 CUR.zp2.cur[point].x = ( CUR.zp1.cur[a0].x + | 6900 CUR.zp2.cur[point].x = ( CUR.zp1.cur[a0].x + |
| 6470 CUR.zp1.cur[a1].x + | 6901 CUR.zp1.cur[a1].x + |
| (...skipping 20 matching lines...) Expand all Loading... |
| 6491 FT_F26Dot6 distance; | 6922 FT_F26Dot6 distance; |
| 6492 | 6923 |
| 6493 | 6924 |
| 6494 p1 = (FT_UShort)args[0]; | 6925 p1 = (FT_UShort)args[0]; |
| 6495 p2 = (FT_UShort)args[1]; | 6926 p2 = (FT_UShort)args[1]; |
| 6496 | 6927 |
| 6497 if ( BOUNDS( p1, CUR.zp1.n_points ) || | 6928 if ( BOUNDS( p1, CUR.zp1.n_points ) || |
| 6498 BOUNDS( p2, CUR.zp0.n_points ) ) | 6929 BOUNDS( p2, CUR.zp0.n_points ) ) |
| 6499 { | 6930 { |
| 6500 if ( CUR.pedantic_hinting ) | 6931 if ( CUR.pedantic_hinting ) |
| 6501 CUR.error = TT_Err_Invalid_Reference; | 6932 CUR.error = FT_THROW( Invalid_Reference ); |
| 6502 return; | 6933 return; |
| 6503 } | 6934 } |
| 6504 | 6935 |
| 6505 distance = CUR_Func_project( CUR.zp0.cur + p2, | 6936 distance = CUR_Func_project( CUR.zp0.cur + p2, |
| 6506 CUR.zp1.cur + p1 ) / 2; | 6937 CUR.zp1.cur + p1 ) / 2; |
| 6507 | 6938 |
| 6508 CUR_Func_move( &CUR.zp1, p1, distance ); | 6939 CUR_Func_move( &CUR.zp1, p1, distance ); |
| 6509 CUR_Func_move( &CUR.zp0, p2, -distance ); | 6940 CUR_Func_move( &CUR.zp0, p2, -distance ); |
| 6510 } | 6941 } |
| 6511 | 6942 |
| (...skipping 14 matching lines...) Expand all Loading... |
| 6526 FT_Vector* orus_base; | 6957 FT_Vector* orus_base; |
| 6527 FT_Vector* cur_base; | 6958 FT_Vector* cur_base; |
| 6528 FT_Int twilight; | 6959 FT_Int twilight; |
| 6529 | 6960 |
| 6530 FT_UNUSED_ARG; | 6961 FT_UNUSED_ARG; |
| 6531 | 6962 |
| 6532 | 6963 |
| 6533 if ( CUR.top < CUR.GS.loop ) | 6964 if ( CUR.top < CUR.GS.loop ) |
| 6534 { | 6965 { |
| 6535 if ( CUR.pedantic_hinting ) | 6966 if ( CUR.pedantic_hinting ) |
| 6536 CUR.error = TT_Err_Invalid_Reference; | 6967 CUR.error = FT_THROW( Invalid_Reference ); |
| 6537 goto Fail; | 6968 goto Fail; |
| 6538 } | 6969 } |
| 6539 | 6970 |
| 6540 /* | 6971 /* |
| 6541 * We need to deal in a special way with the twilight zone. | 6972 * We need to deal in a special way with the twilight zone. |
| 6542 * Otherwise, by definition, the value of CUR.twilight.orus[n] is (0,0), | 6973 * Otherwise, by definition, the value of CUR.twilight.orus[n] is (0,0), |
| 6543 * for every n. | 6974 * for every n. |
| 6544 */ | 6975 */ |
| 6545 twilight = CUR.GS.gep0 == 0 || CUR.GS.gep1 == 0 || CUR.GS.gep2 == 0; | 6976 twilight = CUR.GS.gep0 == 0 || CUR.GS.gep1 == 0 || CUR.GS.gep2 == 0; |
| 6546 | 6977 |
| 6547 if ( BOUNDS( CUR.GS.rp1, CUR.zp0.n_points ) ) | 6978 if ( BOUNDS( CUR.GS.rp1, CUR.zp0.n_points ) ) |
| 6548 { | 6979 { |
| 6549 if ( CUR.pedantic_hinting ) | 6980 if ( CUR.pedantic_hinting ) |
| 6550 CUR.error = TT_Err_Invalid_Reference; | 6981 CUR.error = FT_THROW( Invalid_Reference ); |
| 6551 goto Fail; | 6982 goto Fail; |
| 6552 } | 6983 } |
| 6553 | 6984 |
| 6554 if ( twilight ) | 6985 if ( twilight ) |
| 6555 orus_base = &CUR.zp0.org[CUR.GS.rp1]; | 6986 orus_base = &CUR.zp0.org[CUR.GS.rp1]; |
| 6556 else | 6987 else |
| 6557 orus_base = &CUR.zp0.orus[CUR.GS.rp1]; | 6988 orus_base = &CUR.zp0.orus[CUR.GS.rp1]; |
| 6558 | 6989 |
| 6559 cur_base = &CUR.zp0.cur[CUR.GS.rp1]; | 6990 cur_base = &CUR.zp0.cur[CUR.GS.rp1]; |
| 6560 | 6991 |
| (...skipping 13 matching lines...) Expand all Loading... |
| 6574 old_range = CUR_Func_dualproj( &CUR.zp1.org[CUR.GS.rp2], | 7005 old_range = CUR_Func_dualproj( &CUR.zp1.org[CUR.GS.rp2], |
| 6575 orus_base ); | 7006 orus_base ); |
| 6576 else if ( CUR.metrics.x_scale == CUR.metrics.y_scale ) | 7007 else if ( CUR.metrics.x_scale == CUR.metrics.y_scale ) |
| 6577 old_range = CUR_Func_dualproj( &CUR.zp1.orus[CUR.GS.rp2], | 7008 old_range = CUR_Func_dualproj( &CUR.zp1.orus[CUR.GS.rp2], |
| 6578 orus_base ); | 7009 orus_base ); |
| 6579 else | 7010 else |
| 6580 { | 7011 { |
| 6581 FT_Vector vec; | 7012 FT_Vector vec; |
| 6582 | 7013 |
| 6583 | 7014 |
| 6584 vec.x = TT_MULFIX( CUR.zp1.orus[CUR.GS.rp2].x - orus_base->x, | 7015 vec.x = FT_MulFix( CUR.zp1.orus[CUR.GS.rp2].x - orus_base->x, |
| 6585 CUR.metrics.x_scale ); | 7016 CUR.metrics.x_scale ); |
| 6586 vec.y = TT_MULFIX( CUR.zp1.orus[CUR.GS.rp2].y - orus_base->y, | 7017 vec.y = FT_MulFix( CUR.zp1.orus[CUR.GS.rp2].y - orus_base->y, |
| 6587 CUR.metrics.y_scale ); | 7018 CUR.metrics.y_scale ); |
| 6588 | 7019 |
| 6589 old_range = CUR_fast_dualproj( &vec ); | 7020 old_range = CUR_fast_dualproj( &vec ); |
| 6590 } | 7021 } |
| 6591 | 7022 |
| 6592 cur_range = CUR_Func_project ( &CUR.zp1.cur[CUR.GS.rp2], cur_base ); | 7023 cur_range = CUR_Func_project ( &CUR.zp1.cur[CUR.GS.rp2], cur_base ); |
| 6593 } | 7024 } |
| 6594 | 7025 |
| 6595 for ( ; CUR.GS.loop > 0; --CUR.GS.loop ) | 7026 for ( ; CUR.GS.loop > 0; --CUR.GS.loop ) |
| 6596 { | 7027 { |
| 6597 FT_UInt point = (FT_UInt)CUR.stack[--CUR.args]; | 7028 FT_UInt point = (FT_UInt)CUR.stack[--CUR.args]; |
| 6598 FT_F26Dot6 org_dist, cur_dist, new_dist; | 7029 FT_F26Dot6 org_dist, cur_dist, new_dist; |
| 6599 | 7030 |
| 6600 | 7031 |
| 6601 /* check point bounds */ | 7032 /* check point bounds */ |
| 6602 if ( BOUNDS( point, CUR.zp2.n_points ) ) | 7033 if ( BOUNDS( point, CUR.zp2.n_points ) ) |
| 6603 { | 7034 { |
| 6604 if ( CUR.pedantic_hinting ) | 7035 if ( CUR.pedantic_hinting ) |
| 6605 { | 7036 { |
| 6606 CUR.error = TT_Err_Invalid_Reference; | 7037 CUR.error = FT_THROW( Invalid_Reference ); |
| 6607 return; | 7038 return; |
| 6608 } | 7039 } |
| 6609 continue; | 7040 continue; |
| 6610 } | 7041 } |
| 6611 | 7042 |
| 6612 if ( twilight ) | 7043 if ( twilight ) |
| 6613 org_dist = CUR_Func_dualproj( &CUR.zp2.org[point], orus_base ); | 7044 org_dist = CUR_Func_dualproj( &CUR.zp2.org[point], orus_base ); |
| 6614 else if ( CUR.metrics.x_scale == CUR.metrics.y_scale ) | 7045 else if ( CUR.metrics.x_scale == CUR.metrics.y_scale ) |
| 6615 org_dist = CUR_Func_dualproj( &CUR.zp2.orus[point], orus_base ); | 7046 org_dist = CUR_Func_dualproj( &CUR.zp2.orus[point], orus_base ); |
| 6616 else | 7047 else |
| 6617 { | 7048 { |
| 6618 FT_Vector vec; | 7049 FT_Vector vec; |
| 6619 | 7050 |
| 6620 | 7051 |
| 6621 vec.x = TT_MULFIX( CUR.zp2.orus[point].x - orus_base->x, | 7052 vec.x = FT_MulFix( CUR.zp2.orus[point].x - orus_base->x, |
| 6622 CUR.metrics.x_scale ); | 7053 CUR.metrics.x_scale ); |
| 6623 vec.y = TT_MULFIX( CUR.zp2.orus[point].y - orus_base->y, | 7054 vec.y = FT_MulFix( CUR.zp2.orus[point].y - orus_base->y, |
| 6624 CUR.metrics.y_scale ); | 7055 CUR.metrics.y_scale ); |
| 6625 | 7056 |
| 6626 org_dist = CUR_fast_dualproj( &vec ); | 7057 org_dist = CUR_fast_dualproj( &vec ); |
| 6627 } | 7058 } |
| 6628 | 7059 |
| 6629 cur_dist = CUR_Func_project ( &CUR.zp2.cur[point], cur_base ); | 7060 cur_dist = CUR_Func_project ( &CUR.zp2.cur[point], cur_base ); |
| 6630 | 7061 |
| 6631 if ( org_dist ) | 7062 if ( org_dist ) |
| 6632 new_dist = ( old_range != 0 ) | 7063 { |
| 6633 ? TT_MULDIV( org_dist, cur_range, old_range ) | 7064 if ( old_range ) |
| 6634 : cur_dist; | 7065 new_dist = FT_MulDiv( org_dist, cur_range, old_range ); |
| 7066 else |
| 7067 { |
| 7068 /* This is the same as what MS does for the invalid case: */ |
| 7069 /* */ |
| 7070 /* delta = (Original_Pt - Original_RP1) - */ |
| 7071 /* (Current_Pt - Current_RP1) */ |
| 7072 /* */ |
| 7073 /* In FreeType speak: */ |
| 7074 /* */ |
| 7075 /* new_dist = cur_dist - */ |
| 7076 /* org_dist - cur_dist; */ |
| 7077 |
| 7078 new_dist = -org_dist; |
| 7079 } |
| 7080 } |
| 6635 else | 7081 else |
| 6636 new_dist = 0; | 7082 new_dist = 0; |
| 6637 | 7083 |
| 6638 CUR_Func_move( &CUR.zp2, (FT_UShort)point, new_dist - cur_dist ); | 7084 CUR_Func_move( &CUR.zp2, (FT_UShort)point, new_dist - cur_dist ); |
| 6639 } | 7085 } |
| 6640 | 7086 |
| 6641 Fail: | 7087 Fail: |
| 6642 CUR.GS.loop = 1; | 7088 CUR.GS.loop = 1; |
| 6643 CUR.new_top = CUR.args; | 7089 CUR.new_top = CUR.args; |
| 6644 } | 7090 } |
| (...skipping 10 matching lines...) Expand all Loading... |
| 6655 { | 7101 { |
| 6656 FT_UShort point; | 7102 FT_UShort point; |
| 6657 FT_Byte mask; | 7103 FT_Byte mask; |
| 6658 | 7104 |
| 6659 | 7105 |
| 6660 point = (FT_UShort)args[0]; | 7106 point = (FT_UShort)args[0]; |
| 6661 | 7107 |
| 6662 if ( BOUNDS( point, CUR.zp0.n_points ) ) | 7108 if ( BOUNDS( point, CUR.zp0.n_points ) ) |
| 6663 { | 7109 { |
| 6664 if ( CUR.pedantic_hinting ) | 7110 if ( CUR.pedantic_hinting ) |
| 6665 CUR.error = TT_Err_Invalid_Reference; | 7111 CUR.error = FT_THROW( Invalid_Reference ); |
| 6666 return; | 7112 return; |
| 6667 } | 7113 } |
| 6668 | 7114 |
| 6669 mask = 0xFF; | 7115 mask = 0xFF; |
| 6670 | 7116 |
| 6671 if ( CUR.GS.freeVector.x != 0 ) | 7117 if ( CUR.GS.freeVector.x != 0 ) |
| 6672 mask &= ~FT_CURVE_TAG_TOUCH_X; | 7118 mask &= ~FT_CURVE_TAG_TOUCH_X; |
| 6673 | 7119 |
| 6674 if ( CUR.GS.freeVector.y != 0 ) | 7120 if ( CUR.GS.freeVector.y != 0 ) |
| 6675 mask &= ~FT_CURVE_TAG_TOUCH_Y; | 7121 mask &= ~FT_CURVE_TAG_TOUCH_Y; |
| (...skipping 108 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 6784 x += delta1; | 7230 x += delta1; |
| 6785 | 7231 |
| 6786 else if ( x >= org2 ) | 7232 else if ( x >= org2 ) |
| 6787 x += delta2; | 7233 x += delta2; |
| 6788 | 7234 |
| 6789 else | 7235 else |
| 6790 { | 7236 { |
| 6791 if ( !scale_valid ) | 7237 if ( !scale_valid ) |
| 6792 { | 7238 { |
| 6793 scale_valid = 1; | 7239 scale_valid = 1; |
| 6794 scale = TT_MULDIV( org2 + delta2 - ( org1 + delta1 ), | 7240 scale = FT_DivFix( org2 + delta2 - ( org1 + delta1 ), |
| 6795 0x10000L, orus2 - orus1 ); | 7241 orus2 - orus1 ); |
| 6796 } | 7242 } |
| 6797 | 7243 |
| 6798 x = ( org1 + delta1 ) + | 7244 x = ( org1 + delta1 ) + |
| 6799 TT_MULFIX( worker->orus[i].x - orus1, scale ); | 7245 FT_MulFix( worker->orus[i].x - orus1, scale ); |
| 6800 } | 7246 } |
| 6801 worker->curs[i].x = x; | 7247 worker->curs[i].x = x; |
| 6802 } | 7248 } |
| 6803 } | 7249 } |
| 6804 } | 7250 } |
| 6805 | 7251 |
| 6806 | 7252 |
| 6807 /*************************************************************************/ | 7253 /*************************************************************************/ |
| 6808 /* */ | 7254 /* */ |
| 6809 /* IUP[a]: Interpolate Untouched Points */ | 7255 /* IUP[a]: Interpolate Untouched Points */ |
| (...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 6844 mask = FT_CURVE_TAG_TOUCH_Y; | 7290 mask = FT_CURVE_TAG_TOUCH_Y; |
| 6845 V.orgs = (FT_Vector*)( (FT_Pos*)CUR.pts.org + 1 ); | 7291 V.orgs = (FT_Vector*)( (FT_Pos*)CUR.pts.org + 1 ); |
| 6846 V.curs = (FT_Vector*)( (FT_Pos*)CUR.pts.cur + 1 ); | 7292 V.curs = (FT_Vector*)( (FT_Pos*)CUR.pts.cur + 1 ); |
| 6847 V.orus = (FT_Vector*)( (FT_Pos*)CUR.pts.orus + 1 ); | 7293 V.orus = (FT_Vector*)( (FT_Pos*)CUR.pts.orus + 1 ); |
| 6848 } | 7294 } |
| 6849 V.max_points = CUR.pts.n_points; | 7295 V.max_points = CUR.pts.n_points; |
| 6850 | 7296 |
| 6851 contour = 0; | 7297 contour = 0; |
| 6852 point = 0; | 7298 point = 0; |
| 6853 | 7299 |
| 7300 #ifdef TT_CONFIG_OPTION_SUBPIXEL_HINTING |
| 7301 if ( SUBPIXEL_HINTING && |
| 7302 CUR.ignore_x_mode ) |
| 7303 { |
| 7304 CUR.iup_called = TRUE; |
| 7305 if ( CUR.sph_tweak_flags & SPH_TWEAK_SKIP_IUP ) |
| 7306 return; |
| 7307 } |
| 7308 #endif /* TT_CONFIG_OPTION_SUBPIXEL_HINTING */ |
| 7309 |
| 6854 do | 7310 do |
| 6855 { | 7311 { |
| 6856 end_point = CUR.pts.contours[contour] - CUR.pts.first_point; | 7312 end_point = CUR.pts.contours[contour] - CUR.pts.first_point; |
| 6857 first_point = point; | 7313 first_point = point; |
| 6858 | 7314 |
| 6859 if ( BOUNDS ( end_point, CUR.pts.n_points ) ) | 7315 if ( BOUNDS ( end_point, CUR.pts.n_points ) ) |
| 6860 end_point = CUR.pts.n_points - 1; | 7316 end_point = CUR.pts.n_points - 1; |
| 6861 | 7317 |
| 6862 while ( point <= end_point && ( CUR.pts.tags[point] & mask ) == 0 ) | 7318 while ( point <= end_point && ( CUR.pts.tags[point] & mask ) == 0 ) |
| 6863 point++; | 7319 point++; |
| (...skipping 49 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 6913 /* Opcode range: 0x5D,0x71,0x72 */ | 7369 /* Opcode range: 0x5D,0x71,0x72 */ |
| 6914 /* Stack: uint32 (2 * uint32)... --> */ | 7370 /* Stack: uint32 (2 * uint32)... --> */ |
| 6915 /* */ | 7371 /* */ |
| 6916 static void | 7372 static void |
| 6917 Ins_DELTAP( INS_ARG ) | 7373 Ins_DELTAP( INS_ARG ) |
| 6918 { | 7374 { |
| 6919 FT_ULong k, nump; | 7375 FT_ULong k, nump; |
| 6920 FT_UShort A; | 7376 FT_UShort A; |
| 6921 FT_ULong C; | 7377 FT_ULong C; |
| 6922 FT_Long B; | 7378 FT_Long B; |
| 7379 #ifdef TT_CONFIG_OPTION_SUBPIXEL_HINTING |
| 7380 FT_UShort B1, B2; |
| 7381 |
| 7382 |
| 7383 if ( SUBPIXEL_HINTING && |
| 7384 CUR.ignore_x_mode && |
| 7385 CUR.iup_called && |
| 7386 ( CUR.sph_tweak_flags & SPH_TWEAK_NO_DELTAP_AFTER_IUP ) ) |
| 7387 goto Fail; |
| 7388 #endif /* TT_CONFIG_OPTION_SUBPIXEL_HINTING */ |
| 6923 | 7389 |
| 6924 | 7390 |
| 6925 #ifdef TT_CONFIG_OPTION_UNPATENTED_HINTING | 7391 #ifdef TT_CONFIG_OPTION_UNPATENTED_HINTING |
| 6926 /* Delta hinting is covered by US Patent 5159668. */ | 7392 /* Delta hinting is covered by US Patent 5159668. */ |
| 6927 if ( CUR.face->unpatented_hinting ) | 7393 if ( CUR.face->unpatented_hinting ) |
| 6928 { | 7394 { |
| 6929 FT_Long n = args[0] * 2; | 7395 FT_Long n = args[0] * 2; |
| 6930 | 7396 |
| 6931 | 7397 |
| 6932 if ( CUR.args < n ) | 7398 if ( CUR.args < n ) |
| 6933 { | 7399 { |
| 6934 if ( CUR.pedantic_hinting ) | 7400 if ( CUR.pedantic_hinting ) |
| 6935 CUR.error = TT_Err_Too_Few_Arguments; | 7401 CUR.error = FT_THROW( Too_Few_Arguments ); |
| 6936 n = CUR.args; | 7402 n = CUR.args; |
| 6937 } | 7403 } |
| 6938 | 7404 |
| 6939 CUR.args -= n; | 7405 CUR.args -= n; |
| 6940 CUR.new_top = CUR.args; | 7406 CUR.new_top = CUR.args; |
| 6941 return; | 7407 return; |
| 6942 } | 7408 } |
| 6943 #endif | 7409 #endif |
| 6944 | 7410 |
| 6945 nump = (FT_ULong)args[0]; /* some points theoretically may occur more | 7411 nump = (FT_ULong)args[0]; /* some points theoretically may occur more |
| 6946 than once, thus UShort isn't enough */ | 7412 than once, thus UShort isn't enough */ |
| 6947 | 7413 |
| 6948 for ( k = 1; k <= nump; k++ ) | 7414 for ( k = 1; k <= nump; k++ ) |
| 6949 { | 7415 { |
| 6950 if ( CUR.args < 2 ) | 7416 if ( CUR.args < 2 ) |
| 6951 { | 7417 { |
| 6952 if ( CUR.pedantic_hinting ) | 7418 if ( CUR.pedantic_hinting ) |
| 6953 CUR.error = TT_Err_Too_Few_Arguments; | 7419 CUR.error = FT_THROW( Too_Few_Arguments ); |
| 6954 CUR.args = 0; | 7420 CUR.args = 0; |
| 6955 goto Fail; | 7421 goto Fail; |
| 6956 } | 7422 } |
| 6957 | 7423 |
| 6958 CUR.args -= 2; | 7424 CUR.args -= 2; |
| 6959 | 7425 |
| 6960 A = (FT_UShort)CUR.stack[CUR.args + 1]; | 7426 A = (FT_UShort)CUR.stack[CUR.args + 1]; |
| 6961 B = CUR.stack[CUR.args]; | 7427 B = CUR.stack[CUR.args]; |
| 6962 | 7428 |
| 6963 /* XXX: Because some popular fonts contain some invalid DeltaP */ | 7429 /* XXX: Because some popular fonts contain some invalid DeltaP */ |
| (...skipping 22 matching lines...) Expand all Loading... |
| 6986 | 7452 |
| 6987 C += CUR.GS.delta_base; | 7453 C += CUR.GS.delta_base; |
| 6988 | 7454 |
| 6989 if ( CURRENT_Ppem() == (FT_Long)C ) | 7455 if ( CURRENT_Ppem() == (FT_Long)C ) |
| 6990 { | 7456 { |
| 6991 B = ( (FT_ULong)B & 0xF ) - 8; | 7457 B = ( (FT_ULong)B & 0xF ) - 8; |
| 6992 if ( B >= 0 ) | 7458 if ( B >= 0 ) |
| 6993 B++; | 7459 B++; |
| 6994 B = B * 64 / ( 1L << CUR.GS.delta_shift ); | 7460 B = B * 64 / ( 1L << CUR.GS.delta_shift ); |
| 6995 | 7461 |
| 6996 CUR_Func_move( &CUR.zp0, A, B ); | 7462 #ifdef TT_CONFIG_OPTION_SUBPIXEL_HINTING |
| 7463 |
| 7464 if ( SUBPIXEL_HINTING ) |
| 7465 { |
| 7466 /* |
| 7467 * Allow delta move if |
| 7468 * |
| 7469 * - not using ignore_x_mode rendering |
| 7470 * - glyph is specifically set to allow it |
| 7471 * - glyph is composite and freedom vector is not subpixel |
| 7472 * vector |
| 7473 */ |
| 7474 if ( !CUR.ignore_x_mode || |
| 7475 ( CUR.sph_tweak_flags & SPH_TWEAK_ALWAYS_DO_DELTAP ) || |
| 7476 ( CUR.is_composite && CUR.GS.freeVector.y != 0 ) ) |
| 7477 CUR_Func_move( &CUR.zp0, A, B ); |
| 7478 |
| 7479 /* Otherwise apply subpixel hinting and */ |
| 7480 /* compatibility mode rules */ |
| 7481 else if ( CUR.ignore_x_mode ) |
| 7482 { |
| 7483 if ( CUR.GS.freeVector.y != 0 ) |
| 7484 B1 = CUR.zp0.cur[A].y; |
| 7485 else |
| 7486 B1 = CUR.zp0.cur[A].x; |
| 7487 |
| 7488 #if 0 |
| 7489 /* Standard Subpixel Hinting: Allow y move. */ |
| 7490 /* This messes up dejavu and may not be needed... */ |
| 7491 if ( !CUR.face->sph_compatibility_mode && |
| 7492 CUR.GS.freeVector.y != 0 ) |
| 7493 CUR_Func_move( &CUR.zp0, A, B ); |
| 7494 else |
| 7495 #endif /* 0 */ |
| 7496 |
| 7497 /* Compatibility Mode: Allow x or y move if point touched in */ |
| 7498 /* Y direction. */ |
| 7499 if ( CUR.face->sph_compatibility_mode && |
| 7500 !( CUR.sph_tweak_flags & SPH_TWEAK_ALWAYS_SKIP_DELTAP ) ) |
| 7501 { |
| 7502 /* save the y value of the point now; compare after move */ |
| 7503 B1 = CUR.zp0.cur[A].y; |
| 7504 |
| 7505 if ( CUR.sph_tweak_flags & SPH_TWEAK_ROUND_NONPIXEL_Y_MOVES ) |
| 7506 B = FT_PIX_ROUND( B1 + B ) - B1; |
| 7507 |
| 7508 /* Allow delta move if using sph_compatibility_mode, */ |
| 7509 /* IUP has not been called, and point is touched on Y. */ |
| 7510 if ( !CUR.iup_called && |
| 7511 ( CUR.zp0.tags[A] & FT_CURVE_TAG_TOUCH_Y ) ) |
| 7512 CUR_Func_move( &CUR.zp0, A, B ); |
| 7513 } |
| 7514 |
| 7515 B2 = CUR.zp0.cur[A].y; |
| 7516 |
| 7517 /* Reverse this move if it results in a disallowed move */ |
| 7518 if ( CUR.GS.freeVector.y != 0 && |
| 7519 ( ( CUR.face->sph_compatibility_mode && |
| 7520 ( B1 & 63 ) == 0 && |
| 7521 ( B2 & 63 ) != 0 ) || |
| 7522 ( ( CUR.sph_tweak_flags & |
| 7523 SPH_TWEAK_SKIP_NONPIXEL_Y_MOVES_DELTAP ) && |
| 7524 ( B1 & 63 ) != 0 && |
| 7525 ( B2 & 63 ) != 0 ) ) ) |
| 7526 CUR_Func_move( &CUR.zp0, A, -B ); |
| 7527 } |
| 7528 } |
| 7529 else |
| 7530 #endif /* TT_CONFIG_OPTION_SUBPIXEL_HINTING */ |
| 7531 |
| 7532 CUR_Func_move( &CUR.zp0, A, B ); |
| 6997 } | 7533 } |
| 6998 } | 7534 } |
| 6999 else | 7535 else |
| 7000 if ( CUR.pedantic_hinting ) | 7536 if ( CUR.pedantic_hinting ) |
| 7001 CUR.error = TT_Err_Invalid_Reference; | 7537 CUR.error = FT_THROW( Invalid_Reference ); |
| 7002 } | 7538 } |
| 7003 | 7539 |
| 7004 Fail: | 7540 Fail: |
| 7005 CUR.new_top = CUR.args; | 7541 CUR.new_top = CUR.args; |
| 7006 } | 7542 } |
| 7007 | 7543 |
| 7008 | 7544 |
| 7009 /*************************************************************************/ | 7545 /*************************************************************************/ |
| 7010 /* */ | 7546 /* */ |
| 7011 /* DELTACn[]: DELTA exceptions C1, C2, C3 */ | 7547 /* DELTACn[]: DELTA exceptions C1, C2, C3 */ |
| (...skipping 11 matching lines...) Expand all Loading... |
| 7023 #ifdef TT_CONFIG_OPTION_UNPATENTED_HINTING | 7559 #ifdef TT_CONFIG_OPTION_UNPATENTED_HINTING |
| 7024 /* Delta hinting is covered by US Patent 5159668. */ | 7560 /* Delta hinting is covered by US Patent 5159668. */ |
| 7025 if ( CUR.face->unpatented_hinting ) | 7561 if ( CUR.face->unpatented_hinting ) |
| 7026 { | 7562 { |
| 7027 FT_Long n = args[0] * 2; | 7563 FT_Long n = args[0] * 2; |
| 7028 | 7564 |
| 7029 | 7565 |
| 7030 if ( CUR.args < n ) | 7566 if ( CUR.args < n ) |
| 7031 { | 7567 { |
| 7032 if ( CUR.pedantic_hinting ) | 7568 if ( CUR.pedantic_hinting ) |
| 7033 CUR.error = TT_Err_Too_Few_Arguments; | 7569 CUR.error = FT_THROW( Too_Few_Arguments ); |
| 7034 n = CUR.args; | 7570 n = CUR.args; |
| 7035 } | 7571 } |
| 7036 | 7572 |
| 7037 CUR.args -= n; | 7573 CUR.args -= n; |
| 7038 CUR.new_top = CUR.args; | 7574 CUR.new_top = CUR.args; |
| 7039 return; | 7575 return; |
| 7040 } | 7576 } |
| 7041 #endif | 7577 #endif |
| 7042 | 7578 |
| 7043 nump = (FT_ULong)args[0]; | 7579 nump = (FT_ULong)args[0]; |
| 7044 | 7580 |
| 7045 for ( k = 1; k <= nump; k++ ) | 7581 for ( k = 1; k <= nump; k++ ) |
| 7046 { | 7582 { |
| 7047 if ( CUR.args < 2 ) | 7583 if ( CUR.args < 2 ) |
| 7048 { | 7584 { |
| 7049 if ( CUR.pedantic_hinting ) | 7585 if ( CUR.pedantic_hinting ) |
| 7050 CUR.error = TT_Err_Too_Few_Arguments; | 7586 CUR.error = FT_THROW( Too_Few_Arguments ); |
| 7051 CUR.args = 0; | 7587 CUR.args = 0; |
| 7052 goto Fail; | 7588 goto Fail; |
| 7053 } | 7589 } |
| 7054 | 7590 |
| 7055 CUR.args -= 2; | 7591 CUR.args -= 2; |
| 7056 | 7592 |
| 7057 A = (FT_ULong)CUR.stack[CUR.args + 1]; | 7593 A = (FT_ULong)CUR.stack[CUR.args + 1]; |
| 7058 B = CUR.stack[CUR.args]; | 7594 B = CUR.stack[CUR.args]; |
| 7059 | 7595 |
| 7060 if ( BOUNDSL( A, CUR.cvtSize ) ) | 7596 if ( BOUNDSL( A, CUR.cvtSize ) ) |
| 7061 { | 7597 { |
| 7062 if ( CUR.pedantic_hinting ) | 7598 if ( CUR.pedantic_hinting ) |
| 7063 { | 7599 { |
| 7064 CUR.error = TT_Err_Invalid_Reference; | 7600 CUR.error = FT_THROW( Invalid_Reference ); |
| 7065 return; | 7601 return; |
| 7066 } | 7602 } |
| 7067 } | 7603 } |
| 7068 else | 7604 else |
| 7069 { | 7605 { |
| 7070 C = ( (FT_ULong)B & 0xF0 ) >> 4; | 7606 C = ( (FT_ULong)B & 0xF0 ) >> 4; |
| 7071 | 7607 |
| 7072 switch ( CUR.opcode ) | 7608 switch ( CUR.opcode ) |
| 7073 { | 7609 { |
| 7074 case 0x73: | 7610 case 0x73: |
| (...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 7116 /* Stack: uint32 --> uint32 */ | 7652 /* Stack: uint32 --> uint32 */ |
| 7117 /* */ | 7653 /* */ |
| 7118 static void | 7654 static void |
| 7119 Ins_GETINFO( INS_ARG ) | 7655 Ins_GETINFO( INS_ARG ) |
| 7120 { | 7656 { |
| 7121 FT_Long K; | 7657 FT_Long K; |
| 7122 | 7658 |
| 7123 | 7659 |
| 7124 K = 0; | 7660 K = 0; |
| 7125 | 7661 |
| 7126 /* We return MS rasterizer version 1.7 for the font scaler. */ | 7662 #ifdef TT_CONFIG_OPTION_SUBPIXEL_HINTING |
| 7127 if ( ( args[0] & 1 ) != 0 ) | 7663 /********************************/ |
| 7128 K = 35; | 7664 /* RASTERIZER VERSION */ |
| 7665 /* Selector Bit: 0 */ |
| 7666 /* Return Bit(s): 0-7 */ |
| 7667 /* */ |
| 7668 if ( SUBPIXEL_HINTING && |
| 7669 ( args[0] & 1 ) != 0 && |
| 7670 CUR.ignore_x_mode ) |
| 7671 { |
| 7672 K = CUR.rasterizer_version; |
| 7673 FT_TRACE7(( "Setting rasterizer version %d\n", |
| 7674 CUR.rasterizer_version )); |
| 7675 } |
| 7676 else |
| 7677 #endif /* TT_CONFIG_OPTION_SUBPIXEL_HINTING */ |
| 7678 if ( ( args[0] & 1 ) != 0 ) |
| 7679 K = TT_INTERPRETER_VERSION_35; |
| 7129 | 7680 |
| 7130 /* Has the glyph been rotated? */ | 7681 /********************************/ |
| 7682 /* GLYPH ROTATED */ |
| 7683 /* Selector Bit: 1 */ |
| 7684 /* Return Bit(s): 8 */ |
| 7685 /* */ |
| 7131 if ( ( args[0] & 2 ) != 0 && CUR.tt_metrics.rotated ) | 7686 if ( ( args[0] & 2 ) != 0 && CUR.tt_metrics.rotated ) |
| 7132 K |= 0x80; | 7687 K |= 0x80; |
| 7133 | 7688 |
| 7134 /* Has the glyph been stretched? */ | 7689 /********************************/ |
| 7690 /* GLYPH STRETCHED */ |
| 7691 /* Selector Bit: 2 */ |
| 7692 /* Return Bit(s): 9 */ |
| 7693 /* */ |
| 7135 if ( ( args[0] & 4 ) != 0 && CUR.tt_metrics.stretched ) | 7694 if ( ( args[0] & 4 ) != 0 && CUR.tt_metrics.stretched ) |
| 7136 K |= 1 << 8; | 7695 K |= 1 << 8; |
| 7137 | 7696 |
| 7138 /* Are we hinting for grayscale? */ | 7697 /********************************/ |
| 7698 /* HINTING FOR GRAYSCALE */ |
| 7699 /* Selector Bit: 5 */ |
| 7700 /* Return Bit(s): 12 */ |
| 7701 /* */ |
| 7139 if ( ( args[0] & 32 ) != 0 && CUR.grayscale ) | 7702 if ( ( args[0] & 32 ) != 0 && CUR.grayscale ) |
| 7140 K |= 1 << 12; | 7703 K |= 1 << 12; |
| 7141 | 7704 |
| 7705 #ifdef TT_CONFIG_OPTION_SUBPIXEL_HINTING |
| 7706 |
| 7707 if ( SUBPIXEL_HINTING && |
| 7708 CUR.ignore_x_mode && |
| 7709 CUR.rasterizer_version >= TT_INTERPRETER_VERSION_35 ) |
| 7710 { |
| 7711 /********************************/ |
| 7712 /* HINTING FOR GRAYSCALE */ |
| 7713 /* Selector Bit: 5 */ |
| 7714 /* Return Bit(s): 12 */ |
| 7715 /* */ |
| 7716 if ( ( args[0] & 32 ) != 0 && CUR.grayscale_hinting ) |
| 7717 K |= 1 << 12; |
| 7718 |
| 7719 /********************************/ |
| 7720 /* HINTING FOR SUBPIXEL */ |
| 7721 /* Selector Bit: 6 */ |
| 7722 /* Return Bit(s): 13 */ |
| 7723 /* */ |
| 7724 if ( ( args[0] & 64 ) != 0 && |
| 7725 CUR.subpixel_hinting && |
| 7726 CUR.rasterizer_version >= 37 ) |
| 7727 { |
| 7728 K |= 1 << 13; |
| 7729 |
| 7730 /* the stuff below is irrelevant if subpixel_hinting is not set */ |
| 7731 |
| 7732 /********************************/ |
| 7733 /* COMPATIBLE WIDTHS ENABLED */ |
| 7734 /* Selector Bit: 7 */ |
| 7735 /* Return Bit(s): 14 */ |
| 7736 /* */ |
| 7737 /* Functionality still needs to be added */ |
| 7738 if ( ( args[0] & 128 ) != 0 && CUR.compatible_widths ) |
| 7739 K |= 1 << 14; |
| 7740 |
| 7741 /********************************/ |
| 7742 /* SYMMETRICAL SMOOTHING */ |
| 7743 /* Selector Bit: 8 */ |
| 7744 /* Return Bit(s): 15 */ |
| 7745 /* */ |
| 7746 /* Functionality still needs to be added */ |
| 7747 if ( ( args[0] & 256 ) != 0 && CUR.symmetrical_smoothing ) |
| 7748 K |= 1 << 15; |
| 7749 |
| 7750 /********************************/ |
| 7751 /* HINTING FOR BGR? */ |
| 7752 /* Selector Bit: 9 */ |
| 7753 /* Return Bit(s): 16 */ |
| 7754 /* */ |
| 7755 /* Functionality still needs to be added */ |
| 7756 if ( ( args[0] & 512 ) != 0 && CUR.bgr ) |
| 7757 K |= 1 << 16; |
| 7758 |
| 7759 if ( CUR.rasterizer_version >= 38 ) |
| 7760 { |
| 7761 /********************************/ |
| 7762 /* SUBPIXEL POSITIONED? */ |
| 7763 /* Selector Bit: 10 */ |
| 7764 /* Return Bit(s): 17 */ |
| 7765 /* */ |
| 7766 /* Functionality still needs to be added */ |
| 7767 if ( ( args[0] & 1024 ) != 0 && CUR.subpixel_positioned ) |
| 7768 K |= 1 << 17; |
| 7769 } |
| 7770 } |
| 7771 } |
| 7772 |
| 7773 #endif /* TT_CONFIG_OPTION_SUBPIXEL_HINTING */ |
| 7774 |
| 7142 args[0] = K; | 7775 args[0] = K; |
| 7143 } | 7776 } |
| 7144 | 7777 |
| 7145 | 7778 |
| 7146 static void | 7779 static void |
| 7147 Ins_UNKNOWN( INS_ARG ) | 7780 Ins_UNKNOWN( INS_ARG ) |
| 7148 { | 7781 { |
| 7149 TT_DefRecord* def = CUR.IDefs; | 7782 TT_DefRecord* def = CUR.IDefs; |
| 7150 TT_DefRecord* limit = def + CUR.numIDefs; | 7783 TT_DefRecord* limit = def + CUR.numIDefs; |
| 7151 | 7784 |
| 7152 FT_UNUSED_ARG; | 7785 FT_UNUSED_ARG; |
| 7153 | 7786 |
| 7154 | 7787 |
| 7155 for ( ; def < limit; def++ ) | 7788 for ( ; def < limit; def++ ) |
| 7156 { | 7789 { |
| 7157 if ( (FT_Byte)def->opc == CUR.opcode && def->active ) | 7790 if ( (FT_Byte)def->opc == CUR.opcode && def->active ) |
| 7158 { | 7791 { |
| 7159 TT_CallRec* call; | 7792 TT_CallRec* call; |
| 7160 | 7793 |
| 7161 | 7794 |
| 7162 if ( CUR.callTop >= CUR.callSize ) | 7795 if ( CUR.callTop >= CUR.callSize ) |
| 7163 { | 7796 { |
| 7164 CUR.error = TT_Err_Stack_Overflow; | 7797 CUR.error = FT_THROW( Stack_Overflow ); |
| 7165 return; | 7798 return; |
| 7166 } | 7799 } |
| 7167 | 7800 |
| 7168 call = CUR.callStack + CUR.callTop++; | 7801 call = CUR.callStack + CUR.callTop++; |
| 7169 | 7802 |
| 7170 call->Caller_Range = CUR.curRange; | 7803 call->Caller_Range = CUR.curRange; |
| 7171 call->Caller_IP = CUR.IP + 1; | 7804 call->Caller_IP = CUR.IP + 1; |
| 7172 call->Cur_Count = 1; | 7805 call->Cur_Count = 1; |
| 7173 call->Cur_Restart = def->start; | 7806 call->Cur_Restart = def->start; |
| 7174 call->Cur_End = def->end; | 7807 call->Cur_End = def->end; |
| 7175 | 7808 |
| 7176 INS_Goto_CodeRange( def->range, def->start ); | 7809 INS_Goto_CodeRange( def->range, def->start ); |
| 7177 | 7810 |
| 7178 CUR.step_ins = FALSE; | 7811 CUR.step_ins = FALSE; |
| 7179 return; | 7812 return; |
| 7180 } | 7813 } |
| 7181 } | 7814 } |
| 7182 | 7815 |
| 7183 CUR.error = TT_Err_Invalid_Opcode; | 7816 CUR.error = FT_THROW( Invalid_Opcode ); |
| 7184 } | 7817 } |
| 7185 | 7818 |
| 7186 | 7819 |
| 7187 #ifndef TT_CONFIG_OPTION_INTERPRETER_SWITCH | 7820 #ifndef TT_CONFIG_OPTION_INTERPRETER_SWITCH |
| 7188 | 7821 |
| 7189 | 7822 |
| 7190 static | 7823 static |
| 7191 TInstruction_Function Instruct_Dispatch[256] = | 7824 TInstruction_Function Instruct_Dispatch[256] = |
| 7192 { | 7825 { |
| 7193 /* Opcodes are gathered in groups of 16. */ | 7826 /* Opcodes are gathered in groups of 16. */ |
| (...skipping 306 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 7500 /* Instructions appear in the specification's order. */ | 8133 /* Instructions appear in the specification's order. */ |
| 7501 /* */ | 8134 /* */ |
| 7502 /*************************************************************************/ | 8135 /*************************************************************************/ |
| 7503 | 8136 |
| 7504 | 8137 |
| 7505 /* documentation is in ttinterp.h */ | 8138 /* documentation is in ttinterp.h */ |
| 7506 | 8139 |
| 7507 FT_EXPORT_DEF( FT_Error ) | 8140 FT_EXPORT_DEF( FT_Error ) |
| 7508 TT_RunIns( TT_ExecContext exc ) | 8141 TT_RunIns( TT_ExecContext exc ) |
| 7509 { | 8142 { |
| 7510 FT_Long ins_counter = 0; /* executed instructions counter */ | 8143 FT_Long ins_counter = 0; /* executed instructions counter */ |
| 8144 FT_UShort i; |
| 8145 |
| 8146 #ifdef TT_CONFIG_OPTION_SUBPIXEL_HINTING |
| 8147 FT_Byte opcode_pattern[1][2] = { |
| 8148 /* #8 TypeMan Talk Align */ |
| 8149 { |
| 8150 0x06, /* SPVTL */ |
| 8151 0x7D, /* RDTG */ |
| 8152 }, |
| 8153 }; |
| 8154 FT_UShort opcode_patterns = 1; |
| 8155 FT_UShort opcode_pointer[1] = { 0 }; |
| 8156 FT_UShort opcode_size[1] = { 1 }; |
| 8157 #endif /* TT_CONFIG_OPTION_SUBPIXEL_HINTING */ |
| 7511 | 8158 |
| 7512 | 8159 |
| 7513 #ifdef TT_CONFIG_OPTION_STATIC_RASTER | 8160 #ifdef TT_CONFIG_OPTION_STATIC_RASTER |
| 7514 cur = *exc; | 8161 cur = *exc; |
| 7515 #endif | 8162 #endif |
| 7516 | 8163 |
| 8164 #ifdef TT_CONFIG_OPTION_SUBPIXEL_HINTING |
| 8165 CUR.iup_called = FALSE; |
| 8166 #endif /* TT_CONFIG_OPTION_SUBPIXEL_HINTING */ |
| 8167 |
| 7517 /* set CVT functions */ | 8168 /* set CVT functions */ |
| 7518 CUR.tt_metrics.ratio = 0; | 8169 CUR.tt_metrics.ratio = 0; |
| 7519 if ( CUR.metrics.x_ppem != CUR.metrics.y_ppem ) | 8170 if ( CUR.metrics.x_ppem != CUR.metrics.y_ppem ) |
| 7520 { | 8171 { |
| 7521 /* non-square pixels, use the stretched routines */ | 8172 /* non-square pixels, use the stretched routines */ |
| 7522 CUR.func_read_cvt = Read_CVT_Stretched; | 8173 CUR.func_read_cvt = Read_CVT_Stretched; |
| 7523 CUR.func_write_cvt = Write_CVT_Stretched; | 8174 CUR.func_write_cvt = Write_CVT_Stretched; |
| 7524 CUR.func_move_cvt = Move_CVT_Stretched; | 8175 CUR.func_move_cvt = Move_CVT_Stretched; |
| 7525 } | 8176 } |
| 7526 else | 8177 else |
| (...skipping 26 matching lines...) Expand all Loading... |
| 7553 if ( CUR.IP + CUR.length > CUR.codeSize ) | 8204 if ( CUR.IP + CUR.length > CUR.codeSize ) |
| 7554 goto LErrorCodeOverflow_; | 8205 goto LErrorCodeOverflow_; |
| 7555 | 8206 |
| 7556 /* First, let's check for empty stack and overflow */ | 8207 /* First, let's check for empty stack and overflow */ |
| 7557 CUR.args = CUR.top - ( Pop_Push_Count[CUR.opcode] >> 4 ); | 8208 CUR.args = CUR.top - ( Pop_Push_Count[CUR.opcode] >> 4 ); |
| 7558 | 8209 |
| 7559 /* `args' is the top of the stack once arguments have been popped. */ | 8210 /* `args' is the top of the stack once arguments have been popped. */ |
| 7560 /* One can also interpret it as the index of the last argument. */ | 8211 /* One can also interpret it as the index of the last argument. */ |
| 7561 if ( CUR.args < 0 ) | 8212 if ( CUR.args < 0 ) |
| 7562 { | 8213 { |
| 7563 FT_UShort i; | |
| 7564 | |
| 7565 | |
| 7566 if ( CUR.pedantic_hinting ) | 8214 if ( CUR.pedantic_hinting ) |
| 7567 { | 8215 { |
| 7568 CUR.error = TT_Err_Too_Few_Arguments; | 8216 CUR.error = FT_THROW( Too_Few_Arguments ); |
| 7569 goto LErrorLabel_; | 8217 goto LErrorLabel_; |
| 7570 } | 8218 } |
| 7571 | 8219 |
| 7572 /* push zeroes onto the stack */ | 8220 /* push zeroes onto the stack */ |
| 7573 for ( i = 0; i < Pop_Push_Count[CUR.opcode] >> 4; i++ ) | 8221 for ( i = 0; i < Pop_Push_Count[CUR.opcode] >> 4; i++ ) |
| 7574 CUR.stack[i] = 0; | 8222 CUR.stack[i] = 0; |
| 7575 CUR.args = 0; | 8223 CUR.args = 0; |
| 7576 } | 8224 } |
| 7577 | 8225 |
| 7578 CUR.new_top = CUR.args + ( Pop_Push_Count[CUR.opcode] & 15 ); | 8226 CUR.new_top = CUR.args + ( Pop_Push_Count[CUR.opcode] & 15 ); |
| 7579 | 8227 |
| 7580 /* `new_top' is the new top of the stack, after the instruction's */ | 8228 /* `new_top' is the new top of the stack, after the instruction's */ |
| 7581 /* execution. `top' will be set to `new_top' after the `switch' */ | 8229 /* execution. `top' will be set to `new_top' after the `switch' */ |
| 7582 /* statement. */ | 8230 /* statement. */ |
| 7583 if ( CUR.new_top > CUR.stackSize ) | 8231 if ( CUR.new_top > CUR.stackSize ) |
| 7584 { | 8232 { |
| 7585 CUR.error = TT_Err_Stack_Overflow; | 8233 CUR.error = FT_THROW( Stack_Overflow ); |
| 7586 goto LErrorLabel_; | 8234 goto LErrorLabel_; |
| 7587 } | 8235 } |
| 7588 | 8236 |
| 7589 CUR.step_ins = TRUE; | 8237 CUR.step_ins = TRUE; |
| 7590 CUR.error = TT_Err_Ok; | 8238 CUR.error = FT_Err_Ok; |
| 8239 |
| 8240 #ifdef TT_CONFIG_OPTION_SUBPIXEL_HINTING |
| 8241 |
| 8242 if ( SUBPIXEL_HINTING ) |
| 8243 { |
| 8244 for ( i = 0; i < opcode_patterns; i++ ) |
| 8245 { |
| 8246 if ( opcode_pointer[i] < opcode_size[i] && |
| 8247 CUR.opcode == opcode_pattern[i][opcode_pointer[i]] ) |
| 8248 { |
| 8249 opcode_pointer[i] += 1; |
| 8250 |
| 8251 if ( opcode_pointer[i] == opcode_size[i] ) |
| 8252 { |
| 8253 FT_TRACE7(( "sph: opcode ptrn: %d, %s %s\n", |
| 8254 i, |
| 8255 CUR.face->root.family_name, |
| 8256 CUR.face->root.style_name )); |
| 8257 |
| 8258 switch ( i ) |
| 8259 { |
| 8260 case 0: |
| 8261 break; |
| 8262 } |
| 8263 opcode_pointer[i] = 0; |
| 8264 } |
| 8265 } |
| 8266 else |
| 8267 opcode_pointer[i] = 0; |
| 8268 } |
| 8269 } |
| 8270 |
| 8271 #endif /* TT_CONFIG_OPTION_SUBPIXEL_HINTING */ |
| 7591 | 8272 |
| 7592 #ifdef TT_CONFIG_OPTION_INTERPRETER_SWITCH | 8273 #ifdef TT_CONFIG_OPTION_INTERPRETER_SWITCH |
| 7593 | 8274 |
| 7594 { | 8275 { |
| 7595 FT_Long* args = CUR.stack + CUR.args; | 8276 FT_Long* args = CUR.stack + CUR.args; |
| 7596 FT_Byte opcode = CUR.opcode; | 8277 FT_Byte opcode = CUR.opcode; |
| 7597 | 8278 |
| 7598 | 8279 |
| 7599 #undef ARRAY_BOUND_ERROR | 8280 #undef ARRAY_BOUND_ERROR |
| 7600 #define ARRAY_BOUND_ERROR goto Set_Invalid_Ref | 8281 #define ARRAY_BOUND_ERROR goto Set_Invalid_Ref |
| (...skipping 193 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 7794 | 8475 |
| 7795 case 0x2D: /* ENDF */ | 8476 case 0x2D: /* ENDF */ |
| 7796 Ins_ENDF( EXEC_ARG_ args ); | 8477 Ins_ENDF( EXEC_ARG_ args ); |
| 7797 break; | 8478 break; |
| 7798 | 8479 |
| 7799 case 0x2E: /* MDAP */ | 8480 case 0x2E: /* MDAP */ |
| 7800 case 0x2F: /* MDAP */ | 8481 case 0x2F: /* MDAP */ |
| 7801 Ins_MDAP( EXEC_ARG_ args ); | 8482 Ins_MDAP( EXEC_ARG_ args ); |
| 7802 break; | 8483 break; |
| 7803 | 8484 |
| 7804 | |
| 7805 case 0x30: /* IUP */ | 8485 case 0x30: /* IUP */ |
| 7806 case 0x31: /* IUP */ | 8486 case 0x31: /* IUP */ |
| 7807 Ins_IUP( EXEC_ARG_ args ); | 8487 Ins_IUP( EXEC_ARG_ args ); |
| 7808 break; | 8488 break; |
| 7809 | 8489 |
| 7810 case 0x32: /* SHP */ | 8490 case 0x32: /* SHP */ |
| 7811 case 0x33: /* SHP */ | 8491 case 0x33: /* SHP */ |
| 7812 Ins_SHP( EXEC_ARG_ args ); | 8492 Ins_SHP( EXEC_ARG_ args ); |
| 7813 break; | 8493 break; |
| 7814 | 8494 |
| (...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 7854 | 8534 |
| 7855 case 0x41: /* NPUSHW */ | 8535 case 0x41: /* NPUSHW */ |
| 7856 Ins_NPUSHW( EXEC_ARG_ args ); | 8536 Ins_NPUSHW( EXEC_ARG_ args ); |
| 7857 break; | 8537 break; |
| 7858 | 8538 |
| 7859 case 0x42: /* WS */ | 8539 case 0x42: /* WS */ |
| 7860 DO_WS | 8540 DO_WS |
| 7861 break; | 8541 break; |
| 7862 | 8542 |
| 7863 Set_Invalid_Ref: | 8543 Set_Invalid_Ref: |
| 7864 CUR.error = TT_Err_Invalid_Reference; | 8544 CUR.error = FT_THROW( Invalid_Reference ); |
| 7865 break; | 8545 break; |
| 7866 | 8546 |
| 7867 case 0x43: /* RS */ | 8547 case 0x43: /* RS */ |
| 7868 DO_RS | 8548 DO_RS |
| 7869 break; | 8549 break; |
| 7870 | 8550 |
| 7871 case 0x44: /* WCVTP */ | 8551 case 0x44: /* WCVTP */ |
| 7872 DO_WCVTP | 8552 DO_WCVTP |
| 7873 break; | 8553 break; |
| 7874 | 8554 |
| (...skipping 269 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 8144 } | 8824 } |
| 8145 | 8825 |
| 8146 } | 8826 } |
| 8147 | 8827 |
| 8148 #else | 8828 #else |
| 8149 | 8829 |
| 8150 Instruct_Dispatch[CUR.opcode]( EXEC_ARG_ &CUR.stack[CUR.args] ); | 8830 Instruct_Dispatch[CUR.opcode]( EXEC_ARG_ &CUR.stack[CUR.args] ); |
| 8151 | 8831 |
| 8152 #endif /* TT_CONFIG_OPTION_INTERPRETER_SWITCH */ | 8832 #endif /* TT_CONFIG_OPTION_INTERPRETER_SWITCH */ |
| 8153 | 8833 |
| 8154 if ( CUR.error != TT_Err_Ok ) | 8834 if ( CUR.error ) |
| 8155 { | 8835 { |
| 8156 switch ( CUR.error ) | 8836 switch ( CUR.error ) |
| 8157 { | 8837 { |
| 8158 case TT_Err_Invalid_Opcode: /* looking for redefined instructions */ | 8838 /* looking for redefined instructions */ |
| 8839 case FT_ERR( Invalid_Opcode ): |
| 8159 { | 8840 { |
| 8160 TT_DefRecord* def = CUR.IDefs; | 8841 TT_DefRecord* def = CUR.IDefs; |
| 8161 TT_DefRecord* limit = def + CUR.numIDefs; | 8842 TT_DefRecord* limit = def + CUR.numIDefs; |
| 8162 | 8843 |
| 8163 | 8844 |
| 8164 for ( ; def < limit; def++ ) | 8845 for ( ; def < limit; def++ ) |
| 8165 { | 8846 { |
| 8166 if ( def->active && CUR.opcode == (FT_Byte)def->opc ) | 8847 if ( def->active && CUR.opcode == (FT_Byte)def->opc ) |
| 8167 { | 8848 { |
| 8168 TT_CallRec* callrec; | 8849 TT_CallRec* callrec; |
| 8169 | 8850 |
| 8170 | 8851 |
| 8171 if ( CUR.callTop >= CUR.callSize ) | 8852 if ( CUR.callTop >= CUR.callSize ) |
| 8172 { | 8853 { |
| 8173 CUR.error = TT_Err_Invalid_Reference; | 8854 CUR.error = FT_THROW( Invalid_Reference ); |
| 8174 goto LErrorLabel_; | 8855 goto LErrorLabel_; |
| 8175 } | 8856 } |
| 8176 | 8857 |
| 8177 callrec = &CUR.callStack[CUR.callTop]; | 8858 callrec = &CUR.callStack[CUR.callTop]; |
| 8178 | 8859 |
| 8179 callrec->Caller_Range = CUR.curRange; | 8860 callrec->Caller_Range = CUR.curRange; |
| 8180 callrec->Caller_IP = CUR.IP + 1; | 8861 callrec->Caller_IP = CUR.IP + 1; |
| 8181 callrec->Cur_Count = 1; | 8862 callrec->Cur_Count = 1; |
| 8182 callrec->Cur_Restart = def->start; | 8863 callrec->Cur_Restart = def->start; |
| 8183 callrec->Cur_End = def->end; | 8864 callrec->Cur_End = def->end; |
| 8184 | 8865 |
| 8185 if ( INS_Goto_CodeRange( def->range, def->start ) == FAILURE ) | 8866 if ( INS_Goto_CodeRange( def->range, def->start ) == FAILURE ) |
| 8186 goto LErrorLabel_; | 8867 goto LErrorLabel_; |
| 8187 | 8868 |
| 8188 goto LSuiteLabel_; | 8869 goto LSuiteLabel_; |
| 8189 } | 8870 } |
| 8190 } | 8871 } |
| 8191 } | 8872 } |
| 8192 | 8873 |
| 8193 CUR.error = TT_Err_Invalid_Opcode; | 8874 CUR.error = FT_THROW( Invalid_Opcode ); |
| 8194 goto LErrorLabel_; | 8875 goto LErrorLabel_; |
| 8195 | 8876 |
| 8196 #if 0 | 8877 #if 0 |
| 8197 break; /* Unreachable code warning suppression. */ | 8878 break; /* Unreachable code warning suppression. */ |
| 8198 /* Leave to remind in case a later change the editor */ | 8879 /* Leave to remind in case a later change the editor */ |
| 8199 /* to consider break; */ | 8880 /* to consider break; */ |
| 8200 #endif | 8881 #endif |
| 8201 | 8882 |
| 8202 default: | 8883 default: |
| 8203 goto LErrorLabel_; | 8884 goto LErrorLabel_; |
| 8204 | 8885 |
| 8205 #if 0 | 8886 #if 0 |
| 8206 break; | 8887 break; |
| 8207 #endif | 8888 #endif |
| 8208 } | 8889 } |
| 8209 } | 8890 } |
| 8210 | 8891 |
| 8211 CUR.top = CUR.new_top; | 8892 CUR.top = CUR.new_top; |
| 8212 | 8893 |
| 8213 if ( CUR.step_ins ) | 8894 if ( CUR.step_ins ) |
| 8214 CUR.IP += CUR.length; | 8895 CUR.IP += CUR.length; |
| 8215 | 8896 |
| 8216 /* increment instruction counter and check if we didn't */ | 8897 /* increment instruction counter and check if we didn't */ |
| 8217 /* run this program for too long (e.g. infinite loops). */ | 8898 /* run this program for too long (e.g. infinite loops). */ |
| 8218 if ( ++ins_counter > MAX_RUNNABLE_OPCODES ) | 8899 if ( ++ins_counter > MAX_RUNNABLE_OPCODES ) |
| 8219 return TT_Err_Execution_Too_Long; | 8900 return FT_THROW( Execution_Too_Long ); |
| 8220 | 8901 |
| 8221 LSuiteLabel_: | 8902 LSuiteLabel_: |
| 8222 if ( CUR.IP >= CUR.codeSize ) | 8903 if ( CUR.IP >= CUR.codeSize ) |
| 8223 { | 8904 { |
| 8224 if ( CUR.callTop > 0 ) | 8905 if ( CUR.callTop > 0 ) |
| 8225 { | 8906 { |
| 8226 CUR.error = TT_Err_Code_Overflow; | 8907 CUR.error = FT_THROW( Code_Overflow ); |
| 8227 goto LErrorLabel_; | 8908 goto LErrorLabel_; |
| 8228 } | 8909 } |
| 8229 else | 8910 else |
| 8230 goto LNo_Error_; | 8911 goto LNo_Error_; |
| 8231 } | 8912 } |
| 8232 } while ( !CUR.instruction_trap ); | 8913 } while ( !CUR.instruction_trap ); |
| 8233 | 8914 |
| 8234 LNo_Error_: | 8915 LNo_Error_: |
| 8235 | 8916 |
| 8236 #ifdef TT_CONFIG_OPTION_STATIC_RASTER | 8917 #ifdef TT_CONFIG_OPTION_STATIC_RASTER |
| 8237 *exc = cur; | 8918 *exc = cur; |
| 8238 #endif | 8919 #endif |
| 8239 | 8920 |
| 8240 return TT_Err_Ok; | 8921 return FT_Err_Ok; |
| 8241 | 8922 |
| 8242 LErrorCodeOverflow_: | 8923 LErrorCodeOverflow_: |
| 8243 CUR.error = TT_Err_Code_Overflow; | 8924 CUR.error = FT_THROW( Code_Overflow ); |
| 8244 | 8925 |
| 8245 LErrorLabel_: | 8926 LErrorLabel_: |
| 8246 | 8927 |
| 8247 #ifdef TT_CONFIG_OPTION_STATIC_RASTER | 8928 #ifdef TT_CONFIG_OPTION_STATIC_RASTER |
| 8248 *exc = cur; | 8929 *exc = cur; |
| 8249 #endif | 8930 #endif |
| 8250 | 8931 |
| 8251 /* If any errors have occurred, function tables may be broken. */ | 8932 /* If any errors have occurred, function tables may be broken. */ |
| 8252 /* Force a re-execution of `prep' and `fpgm' tables if no */ | 8933 /* Force a re-execution of `prep' and `fpgm' tables if no */ |
| 8253 /* bytecode debugger is run. */ | 8934 /* bytecode debugger is run. */ |
| 8254 if ( CUR.error && !CUR.instruction_trap ) | 8935 if ( CUR.error && !CUR.instruction_trap ) |
| 8255 { | 8936 { |
| 8256 FT_TRACE1(( " The interpreter returned error 0x%x\n", CUR.error )); | 8937 FT_TRACE1(( " The interpreter returned error 0x%x\n", CUR.error )); |
| 8257 exc->size->cvt_ready = FALSE; | 8938 exc->size->cvt_ready = FALSE; |
| 8258 } | 8939 } |
| 8259 | 8940 |
| 8260 return CUR.error; | 8941 return CUR.error; |
| 8261 } | 8942 } |
| 8262 | 8943 |
| 8263 | 8944 |
| 8264 #endif /* TT_USE_BYTECODE_INTERPRETER */ | 8945 #endif /* TT_USE_BYTECODE_INTERPRETER */ |
| 8265 | 8946 |
| 8266 | 8947 |
| 8267 /* END */ | 8948 /* END */ |
| OLD | NEW |