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 |