24 #include FT_INTERNAL_DEBUG_H
25 #include FT_INTERNAL_CALC_H
26 #include FT_TRIGONOMETRY_H
34 #ifdef TT_USE_BYTECODE_INTERPRETER
37 #define TT_MULFIX FT_MulFix
38 #define TT_MULDIV FT_MulDiv
39 #define TT_MULDIV_NO_ROUND FT_MulDiv_No_Round
49 #define FT_COMPONENT trace_ttinterp
57 #define MAX_RUNNABLE_OPCODES 1000000L
97 #ifndef TT_CONFIG_OPTION_STATIC_INTERPRETER
106 #define FT_UNUSED_EXEC FT_UNUSED( exc )
112 #define FT_UNUSED_EXEC int __dummy = __dummy
128 #define INS_ARG EXEC_OP_ FT_Long* args
136 #define FT_UNUSED_ARG FT_UNUSED_EXEC; FT_UNUSED( args )
147 #define SKIP_Code() \
150 #define GET_ShortIns() \
151 GetShortIns( EXEC_ARG )
153 #define NORMalize( x, y, v ) \
154 Normalize( EXEC_ARG_ x, y, v )
156 #define SET_SuperRound( scale, flags ) \
157 SetSuperRound( EXEC_ARG_ scale, flags )
159 #define ROUND_None( d, c ) \
160 Round_None( EXEC_ARG_ d, c )
162 #define INS_Goto_CodeRange( range, ip ) \
163 Ins_Goto_CodeRange( EXEC_ARG_ range, ip )
165 #define CUR_Func_move( z, p, d ) \
166 CUR.func_move( EXEC_ARG_ z, p, d )
168 #define CUR_Func_move_orig( z, p, d ) \
169 CUR.func_move_orig( EXEC_ARG_ z, p, d )
171 #define CUR_Func_round( d, c ) \
172 CUR.func_round( EXEC_ARG_ d, c )
174 #define CUR_Func_read_cvt( index ) \
175 CUR.func_read_cvt( EXEC_ARG_ index )
177 #define CUR_Func_write_cvt( index, val ) \
178 CUR.func_write_cvt( EXEC_ARG_ index, val )
180 #define CUR_Func_move_cvt( index, val ) \
181 CUR.func_move_cvt( EXEC_ARG_ index, val )
183 #define CURRENT_Ratio() \
184 Current_Ratio( EXEC_ARG )
186 #define CURRENT_Ppem() \
187 Current_Ppem( EXEC_ARG )
192 #define INS_SxVTL( a, b, c, d ) \
193 Ins_SxVTL( EXEC_ARG_ a, b, c, d )
195 #define COMPUTE_Funcs() \
196 Compute_Funcs( EXEC_ARG )
198 #define COMPUTE_Round( a ) \
199 Compute_Round( EXEC_ARG_ a )
201 #define COMPUTE_Point_Displacement( a, b, c, d ) \
202 Compute_Point_Displacement( EXEC_ARG_ a, b, c, d )
204 #define MOVE_Zp2_Point( a, b, c, t ) \
205 Move_Zp2_Point( EXEC_ARG_ a, b, c, t )
208 #define CUR_Func_project( v1, v2 ) \
209 CUR.func_project( EXEC_ARG_ (v1)->x - (v2)->x, (v1)->y - (v2)->y )
211 #define CUR_Func_dualproj( v1, v2 ) \
212 CUR.func_dualproj( EXEC_ARG_ (v1)->x - (v2)->x, (v1)->y - (v2)->y )
214 #define CUR_fast_project( v ) \
215 CUR.func_project( EXEC_ARG_ (v)->x, (v)->y )
217 #define CUR_fast_dualproj( v ) \
218 CUR.func_dualproj( EXEC_ARG_ (v)->x, (v)->y )
225 typedef void (*TInstruction_Function)( INS_ARG );
232 #define BOUNDS( x, n ) ( (FT_UInt)(x) >= (FT_UInt)(n) )
233 #define BOUNDSL( x, n ) ( (FT_ULong)(x) >= (FT_ULong)(n) )
241 #ifdef TT_CONFIG_OPTION_UNPATENTED_HINTING
242 #define GUESS_VECTOR( V ) \
243 if ( CUR.face->unpatented_hinting ) \
245 CUR.GS.V.x = (FT_F2Dot14)( CUR.GS.both_x_axis ? 0x4000 : 0 ); \
246 CUR.GS.V.y = (FT_F2Dot14)( CUR.GS.both_x_axis ? 0 : 0x4000 ); \
249 #define GUESS_VECTOR( V )
289 coderange = &exec->codeRangeTable[range - 1];
299 exec->code = coderange->
base;
300 exec->codeSize = coderange->
size;
302 exec->curRange =
range;
337 exec->codeRangeTable[range - 1].base = (
FT_Byte*)base;
338 exec->codeRangeTable[range - 1].size =
length;
370 exec->codeRangeTable[range - 1].base =
NULL;
371 exec->codeRangeTable[range - 1].size = 0;
411 exec->maxContours = 0;
459 FT_TRACE1((
"Init_Context: new object at 0x%08p\n", exec ));
484 FT_ERROR((
"Init_Context: not enough memory for %p\n", exec ));
523 void** pbuff = (
void**)_pbuff;
526 if ( *size < new_max )
528 if (
FT_REALLOC( *pbuff, *size * multiplier, new_max * multiplier ) )
571 maxp = &face->max_profile;
576 exec->numFDefs = size->num_function_defs;
577 exec->maxFDefs = size->max_function_defs;
578 exec->numIDefs = size->num_instruction_defs;
579 exec->maxIDefs = size->max_instruction_defs;
580 exec->FDefs = size->function_defs;
581 exec->IDefs = size->instruction_defs;
582 exec->tt_metrics = size->ttmetrics;
583 exec->metrics = size->metrics;
585 exec->maxFunc = size->max_func;
586 exec->maxIns = size->max_ins;
589 exec->codeRangeTable[i] = size->codeRangeTable[i];
594 exec->cvtSize = size->cvt_size;
595 exec->cvt = size->cvt;
597 exec->storeSize = size->storage_size;
598 exec->storage = size->storage;
600 exec->twilight = size->twilight;
605 exec->zp1 = exec->zp0;
606 exec->zp2 = exec->zp0;
611 tmp = exec->stackSize;
617 exec->stackSize = (
FT_UInt)tmp;
621 tmp = exec->glyphSize;
625 (
void*)&exec->glyphIns,
631 exec->pts.n_points = 0;
632 exec->pts.n_contours = 0;
634 exec->zp1 = exec->pts;
635 exec->zp2 = exec->pts;
636 exec->zp0 = exec->pts;
638 exec->instruction_trap =
FALSE;
674 size->num_function_defs = exec->numFDefs;
675 size->num_instruction_defs = exec->numIDefs;
677 size->max_func = exec->maxFunc;
678 size->max_ins = exec->maxIns;
681 size->codeRangeTable[i] = exec->codeRangeTable[i];
722 exec->zp0 = exec->pts;
723 exec->zp1 = exec->pts;
724 exec->zp2 = exec->pts;
730 exec->GS.projVector.x = 0x4000;
731 exec->GS.projVector.y = 0x0000;
733 exec->GS.freeVector = exec->GS.projVector;
734 exec->GS.dualVector = exec->GS.projVector;
736 #ifdef TT_CONFIG_OPTION_UNPATENTED_HINTING
737 exec->GS.both_x_axis =
TRUE;
740 exec->GS.round_state = 1;
751 return exec->face->interpreter( exec );
775 #ifdef TT_CONFIG_OPTION_UNPATENTED_HINTING
780 TRUE, 68, 0, 0, 9, 3,
794 memory = driver->root.root.
memory;
795 exec = driver->context;
797 if ( !driver->context )
807 error = Init_Context( exec, memory );
812 driver->context = exec;
815 return driver->context;
841 #define PACK( x, y ) ( ( x << 4 ) | y )
845 const FT_Byte Pop_Push_Count[256] =
1124 #ifdef FT_DEBUG_LEVEL_TRACE
1127 const char*
const opcode_name[256] =
1406 const FT_Char opcode_length[256] =
1408 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
1409 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
1410 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
1411 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
1413 -1,-2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
1414 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
1415 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
1416 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
1418 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
1419 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
1420 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
1421 2, 3, 4, 5, 6, 7, 8, 9, 3, 5, 7, 9, 11,13,15,17,
1423 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
1424 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
1425 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
1426 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1
1434 TT_MulFix14( FT_Int32
a,
1438 FT_UInt32 ah, al, mid,
lo,
hi;
1448 ah = (FT_UInt32)( ( a >> 16 ) & 0xFFFFU );
1449 al = (FT_UInt32)( a & 0xFFFFU );
1454 mid = ( mid << 16 ) + ( 1 << 13 );
1459 mid = ( lo >> 14 ) | ( hi << 18 );
1461 return sign >= 0 ? (FT_Int32)mid : -(FT_Int32)mid;
1468 TT_MulFix14( FT_Int32 a,
1476 l = (FT_UInt32)( ( a & 0xFFFFU ) *
b );
1477 m = ( a >> 16 ) * b;
1479 lo = l + (FT_UInt32)( m << 16 );
1480 hi = ( m >> 16 ) + ( (FT_Int32)l >> 31 ) + ( lo < l );
1484 l = lo + (FT_UInt32)s;
1485 hi += s + ( l <
lo );
1491 return ( hi << 18 ) | ( l >> 14 );
1498 TT_DotFix14( FT_Int32 ax,
1503 FT_Int32
m,
s, hi1, hi2,
hi;
1504 FT_UInt32
l, lo1, lo2,
lo;
1508 l = (FT_UInt32)( ( ax & 0xFFFFU ) * bx );
1509 m = ( ax >> 16 ) * bx;
1511 lo1 = l + (FT_UInt32)( m << 16 );
1512 hi1 = ( m >> 16 ) + ( (FT_Int32)l >> 31 ) + ( lo1 < l );
1515 l = (FT_UInt32)( ( ay & 0xFFFFU ) *
by );
1516 m = ( ay >> 16 ) * by;
1518 lo2 = l + (FT_UInt32)( m << 16 );
1519 hi2 = ( m >> 16 ) + ( (FT_Int32)l >> 31 ) + ( lo2 < l );
1523 hi = hi1 + hi2 + ( lo < lo1 );
1527 l = lo + (FT_UInt32)s;
1528 hi += s + ( l <
lo );
1534 return ( hi << 18 ) | ( l >> 14 );
1543 TT_VecLen( FT_Int32
x,
1546 FT_Int32
m, hi1, hi2,
hi;
1547 FT_UInt32
l, lo1, lo2,
lo;
1551 lo = (FT_UInt32)( x & 0xFFFFU );
1558 lo1 = l + (FT_UInt32)( m << 17 );
1559 hi1 = hi + ( m >> 15 ) + ( lo1 < l );
1562 lo = (FT_UInt32)( y & 0xFFFFU );
1569 lo2 = l + (FT_UInt32)( m << 17 );
1570 hi2 = hi + ( m >> 15 ) + ( lo2 < l );
1574 hi = hi1 + hi2 + ( lo < lo1 );
1578 FT_UInt32 root, rem, test_div;
1589 rem = ( rem << 2 ) | ( (FT_UInt32)hi >> 30 );
1590 hi = ( hi << 2 ) | ( lo >> 30 );
1593 test_div = ( root << 1 ) + 1;
1595 if ( rem >= test_div )
1600 }
while ( --count );
1603 return (FT_Int32)root;
1643 if ( !CUR.tt_metrics.ratio )
1645 #ifdef TT_CONFIG_OPTION_UNPATENTED_HINTING
1646 if ( CUR.face->unpatented_hinting )
1648 if ( CUR.GS.both_x_axis )
1649 CUR.tt_metrics.ratio = CUR.tt_metrics.x_ratio;
1651 CUR.tt_metrics.ratio = CUR.tt_metrics.y_ratio;
1656 if ( CUR.GS.projVector.y == 0 )
1657 CUR.tt_metrics.ratio = CUR.tt_metrics.x_ratio;
1659 else if ( CUR.GS.projVector.x == 0 )
1660 CUR.tt_metrics.ratio = CUR.tt_metrics.y_ratio;
1667 x = TT_MULDIV( CUR.GS.projVector.x,
1668 CUR.tt_metrics.x_ratio, 0x4000 );
1669 y = TT_MULDIV( CUR.GS.projVector.y,
1670 CUR.tt_metrics.y_ratio, 0x4000 );
1671 CUR.tt_metrics.ratio = TT_VecLen( x, y );
1675 return CUR.tt_metrics.ratio;
1682 return TT_MULFIX( CUR.tt_metrics.ppem, CURRENT_Ratio() );
1696 return CUR.cvt[
idx];
1703 return TT_MULFIX( CUR.cvt[idx], CURRENT_Ratio() );
1759 return (
FT_Short)( ( CUR.code[CUR.IP - 2] << 8 ) +
1760 CUR.code[CUR.IP - 1] );
1787 if ( aRange < 1 || aRange > 3 )
1789 CUR.error = TT_Err_Bad_Argument;
1793 range = &CUR.codeRangeTable[aRange - 1];
1797 CUR.error = TT_Err_Invalid_CodeRange;
1805 if ( aIP > range->
size )
1807 CUR.error = TT_Err_Code_Overflow;
1811 CUR.code = range->
base;
1812 CUR.codeSize = range->
size;
1814 CUR.curRange = aRange;
1845 #ifdef TT_CONFIG_OPTION_UNPATENTED_HINTING
1846 FT_ASSERT( !CUR.face->unpatented_hinting );
1849 v = CUR.GS.freeVector.x;
1853 zone->cur[point].x += TT_MULDIV( distance,
1860 v = CUR.GS.freeVector.y;
1864 zone->cur[point].y += TT_MULDIV( distance,
1898 #ifdef TT_CONFIG_OPTION_UNPATENTED_HINTING
1899 FT_ASSERT( !CUR.face->unpatented_hinting );
1902 v = CUR.GS.freeVector.x;
1905 zone->org[point].x += TT_MULDIV( distance,
1909 v = CUR.GS.freeVector.y;
1912 zone->org[point].y += TT_MULDIV( distance,
2015 if ( distance >= 0 )
2017 val = distance + compensation;
2018 if ( distance && val < 0 )
2023 val = distance - compensation;
2056 if ( distance >= 0 )
2058 val = distance + compensation + 32;
2059 if ( distance && val > 0 )
2100 if ( distance >= 0 )
2103 if ( distance && val < 0 )
2108 val = -(
FT_PIX_FLOOR( compensation - distance ) + 32 );
2142 if ( distance >= 0 )
2144 val = distance + compensation;
2145 if ( distance && val > 0 )
2152 val = -( ( compensation -
distance ) & -64 );
2186 if ( distance >= 0 )
2188 val = distance + compensation + 63;
2189 if ( distance && val > 0 )
2230 if ( distance >= 0 )
2232 val = distance + compensation + 16;
2233 if ( distance && val > 0 )
2278 if ( distance >= 0 )
2280 val = ( distance - CUR.phase + CUR.threshold + compensation ) &
2282 if ( distance && val < 0 )
2288 val = -( ( CUR.threshold - CUR.phase - distance + compensation ) &
2326 if ( distance >= 0 )
2328 val = ( ( distance - CUR.phase + CUR.threshold + compensation ) /
2329 CUR.period ) * CUR.period;
2330 if ( distance && val < 0 )
2336 val = -( ( ( CUR.threshold - CUR.phase - distance + compensation ) /
2337 CUR.period ) * CUR.period );
2361 switch ( round_mode )
2414 switch ( (
FT_Int)( selector & 0xC0 ) )
2417 CUR.period = GridPeriod / 2;
2421 CUR.period = GridPeriod;
2425 CUR.period = GridPeriod * 2;
2431 CUR.period = GridPeriod;
2435 switch ( (
FT_Int)( selector & 0x30 ) )
2442 CUR.phase = CUR.period / 4;
2446 CUR.phase = CUR.period / 2;
2450 CUR.phase = CUR.period * 3 / 4;
2454 if ( ( selector & 0x0F ) == 0 )
2455 CUR.threshold = CUR.period - 1;
2457 CUR.threshold = ( (
FT_Int)( selector & 0x0F ) - 4 ) * CUR.period / 8;
2461 CUR.threshold /= 256;
2485 #ifdef TT_CONFIG_OPTION_UNPATENTED_HINTING
2486 FT_ASSERT( !CUR.face->unpatented_hinting );
2489 return TT_DotFix14( (FT_UInt32)dx, (FT_UInt32)dy,
2490 CUR.GS.projVector.x,
2491 CUR.GS.projVector.y );
2515 return TT_DotFix14( (FT_UInt32)dx, (FT_UInt32)dy,
2516 CUR.GS.dualVector.x,
2517 CUR.GS.dualVector.y );
2587 #ifdef TT_CONFIG_OPTION_UNPATENTED_HINTING
2588 if ( CUR.face->unpatented_hinting )
2594 CUR.GS.both_x_axis = (
FT_Bool)( CUR.GS.projVector.x == 0x4000 &&
2595 CUR.GS.freeVector.x == 0x4000 );
2600 CUR.GS.projVector.x = 0;
2601 CUR.GS.projVector.y = 0;
2602 CUR.GS.freeVector.x = 0;
2603 CUR.GS.freeVector.y = 0;
2605 if ( CUR.GS.both_x_axis )
2607 CUR.func_project = Project_x;
2608 CUR.func_move = Direct_Move_X;
2609 CUR.func_move_orig = Direct_Move_Orig_X;
2613 CUR.func_project = Project_y;
2614 CUR.func_move = Direct_Move_Y;
2615 CUR.func_move_orig = Direct_Move_Orig_Y;
2618 if ( CUR.GS.dualVector.x == 0x4000 )
2619 CUR.func_dualproj = Project_x;
2622 if ( CUR.GS.dualVector.y == 0x4000 )
2623 CUR.func_dualproj = Project_y;
2625 CUR.func_dualproj = Dual_Project;
2629 CUR.tt_metrics.ratio = 0;
2635 if ( CUR.GS.freeVector.x == 0x4000 )
2636 CUR.F_dot_P = CUR.GS.projVector.x * 0x10000L;
2639 if ( CUR.GS.freeVector.y == 0x4000 )
2640 CUR.F_dot_P = CUR.GS.projVector.y * 0x10000L;
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;
2646 if ( CUR.GS.projVector.x == 0x4000 )
2650 if ( CUR.GS.projVector.y == 0x4000 )
2656 if ( CUR.GS.dualVector.x == 0x4000 )
2660 if ( CUR.GS.dualVector.y == 0x4000 )
2669 if ( CUR.F_dot_P == 0x40000000L )
2671 if ( CUR.GS.freeVector.x == 0x4000 )
2678 if ( CUR.GS.freeVector.y == 0x4000 )
2689 if (
FT_ABS( CUR.F_dot_P ) < 0x4000000L )
2690 CUR.F_dot_P = 0x40000000L;
2693 CUR.tt_metrics.ratio = 0;
2732 if (
FT_ABS( Vx ) < 0x10000L &&
FT_ABS( Vy ) < 0x10000L )
2737 W = TT_VecLen( Vx, Vy );
2752 W = TT_VecLen( Vx, Vy );
2757 W = Vx * Vx + Vy * Vy;
2778 while ( W < 0x10000000L )
2786 W = Vx * Vx + Vy * Vy;
2789 while ( W >= 0x10004000L )
2797 W = Vx * Vx + Vy * Vy;
2834 if ( BOUNDS( aIdx1, CUR.zp2.n_points ) ||
2835 BOUNDS( aIdx2, CUR.zp1.n_points ) )
2837 if ( CUR.pedantic_hinting )
2838 CUR.error = TT_Err_Invalid_Reference;
2842 p1 = CUR.zp1.cur + aIdx2;
2843 p2 = CUR.zp2.cur + aIdx1;
2853 if ( A == 0 && B == 0 )
2859 if ( ( aOpc & 1 ) != 0 )
2866 NORMalize( A, B, Vec );
2883 A = (FT_Short)( CUR.opcode & 1 ) << 14; \
2884 B = A ^ (FT_Short)0x4000; \
2886 CUR.GS.freeVector.x = A; \
2887 CUR.GS.projVector.x = A; \
2888 CUR.GS.dualVector.x = A; \
2890 CUR.GS.freeVector.y = B; \
2891 CUR.GS.projVector.y = B; \
2892 CUR.GS.dualVector.y = B; \
2903 A = (FT_Short)( CUR.opcode & 1 ) << 14; \
2904 B = A ^ (FT_Short)0x4000; \
2906 CUR.GS.projVector.x = A; \
2907 CUR.GS.dualVector.x = A; \
2909 CUR.GS.projVector.y = B; \
2910 CUR.GS.dualVector.y = B; \
2912 GUESS_VECTOR( freeVector ); \
2923 A = (FT_Short)( CUR.opcode & 1 ) << 14; \
2924 B = A ^ (FT_Short)0x4000; \
2926 CUR.GS.freeVector.x = A; \
2927 CUR.GS.freeVector.y = B; \
2929 GUESS_VECTOR( projVector ); \
2936 if ( INS_SxVTL( (FT_UShort)args[1], \
2937 (FT_UShort)args[0], \
2939 &CUR.GS.projVector ) == SUCCESS ) \
2941 CUR.GS.dualVector = CUR.GS.projVector; \
2942 GUESS_VECTOR( freeVector ); \
2948 if ( INS_SxVTL( (FT_UShort)args[1], \
2949 (FT_UShort)args[0], \
2951 &CUR.GS.freeVector ) == SUCCESS ) \
2953 GUESS_VECTOR( projVector ); \
2959 GUESS_VECTOR( projVector ); \
2960 CUR.GS.freeVector = CUR.GS.projVector; \
2971 S = (FT_Short)args[1]; \
2973 S = (FT_Short)args[0]; \
2976 NORMalize( X, Y, &CUR.GS.projVector ); \
2978 CUR.GS.dualVector = CUR.GS.projVector; \
2979 GUESS_VECTOR( freeVector ); \
2991 S = (FT_Short)args[1]; \
2993 S = (FT_Short)args[0]; \
2996 NORMalize( X, Y, &CUR.GS.freeVector ); \
2997 GUESS_VECTOR( projVector ); \
3002 #ifdef TT_CONFIG_OPTION_UNPATENTED_HINTING
3004 if ( CUR.face->unpatented_hinting ) \
3006 args[0] = CUR.GS.both_x_axis ? 0x4000 : 0; \
3007 args[1] = CUR.GS.both_x_axis ? 0 : 0x4000; \
3011 args[0] = CUR.GS.projVector.x; \
3012 args[1] = CUR.GS.projVector.y; \
3016 args[0] = CUR.GS.projVector.x; \
3017 args[1] = CUR.GS.projVector.y;
3021 #ifdef TT_CONFIG_OPTION_UNPATENTED_HINTING
3023 if ( CUR.face->unpatented_hinting ) \
3025 args[0] = CUR.GS.both_x_axis ? 0x4000 : 0; \
3026 args[1] = CUR.GS.both_x_axis ? 0 : 0x4000; \
3030 args[0] = CUR.GS.freeVector.x; \
3031 args[1] = CUR.GS.freeVector.y; \
3035 args[0] = CUR.GS.freeVector.x; \
3036 args[1] = CUR.GS.freeVector.y;
3041 CUR.GS.rp0 = (FT_UShort)args[0];
3045 CUR.GS.rp1 = (FT_UShort)args[0];
3049 CUR.GS.rp2 = (FT_UShort)args[0];
3053 CUR.GS.round_state = TT_Round_To_Half_Grid; \
3054 CUR.func_round = (TT_Round_Func)Round_To_Half_Grid;
3058 CUR.GS.round_state = TT_Round_To_Grid; \
3059 CUR.func_round = (TT_Round_Func)Round_To_Grid;
3063 CUR.GS.round_state = TT_Round_To_Double_Grid; \
3064 CUR.func_round = (TT_Round_Func)Round_To_Double_Grid;
3068 CUR.GS.round_state = TT_Round_Up_To_Grid; \
3069 CUR.func_round = (TT_Round_Func)Round_Up_To_Grid;
3073 CUR.GS.round_state = TT_Round_Down_To_Grid; \
3074 CUR.func_round = (TT_Round_Func)Round_Down_To_Grid;
3078 CUR.GS.round_state = TT_Round_Off; \
3079 CUR.func_round = (TT_Round_Func)Round_None;
3083 SET_SuperRound( 0x4000, args[0] ); \
3084 CUR.GS.round_state = TT_Round_Super; \
3085 CUR.func_round = (TT_Round_Func)Round_Super;
3088 #define DO_S45ROUND \
3089 SET_SuperRound( 0x2D41, args[0] ); \
3090 CUR.GS.round_state = TT_Round_Super_45; \
3091 CUR.func_round = (TT_Round_Func)Round_Super_45;
3095 if ( args[0] < 0 ) \
3096 CUR.error = TT_Err_Bad_Argument; \
3098 CUR.GS.loop = args[0];
3102 CUR.GS.minimum_distance = args[0];
3106 CUR.GS.control_value_cutin = (FT_F26Dot6)args[0];
3110 CUR.GS.single_width_cutin = (FT_F26Dot6)args[0];
3120 CUR.GS.single_width_value = (FT_F26Dot6)( args[0] >> 10 );
3124 CUR.GS.auto_flip = TRUE;
3127 #define DO_FLIPOFF \
3128 CUR.GS.auto_flip = FALSE;
3132 CUR.GS.delta_base = (FT_Short)args[0];
3136 CUR.GS.delta_shift = (FT_Short)args[0];
3143 args[0] = CURRENT_Ppem();
3151 args[0] = CUR.metrics.pointSize;
3156 args[0] = CURRENT_Ppem();
3175 args[0] = args[1]; \
3191 if ( L <= 0 || L > CUR.args ) \
3193 if ( CUR.pedantic_hinting ) \
3194 CUR.error = TT_Err_Invalid_Reference; \
3198 args[0] = CUR.stack[CUR.args - L]; \
3203 if ( args[1] != 0 ) \
3205 if ( args[0] == 0 && CUR.args == 0 ) \
3206 CUR.error = TT_Err_Bad_Argument; \
3207 CUR.IP += args[0]; \
3208 if ( CUR.IP < 0 || \
3209 ( CUR.callTop > 0 && \
3210 CUR.IP > CUR.callStack[CUR.callTop - 1].Cur_End ) ) \
3211 CUR.error = TT_Err_Bad_Argument; \
3212 CUR.step_ins = FALSE; \
3217 if ( args[0] == 0 && CUR.args == 0 ) \
3218 CUR.error = TT_Err_Bad_Argument; \
3219 CUR.IP += args[0]; \
3220 if ( CUR.IP < 0 || \
3221 ( CUR.callTop > 0 && \
3222 CUR.IP > CUR.callStack[CUR.callTop - 1].Cur_End ) ) \
3223 CUR.error = TT_Err_Bad_Argument; \
3224 CUR.step_ins = FALSE;
3228 if ( args[1] == 0 ) \
3230 if ( args[0] == 0 && CUR.args == 0 ) \
3231 CUR.error = TT_Err_Bad_Argument; \
3232 CUR.IP += args[0]; \
3233 if ( CUR.IP < 0 || \
3234 ( CUR.callTop > 0 && \
3235 CUR.IP > CUR.callStack[CUR.callTop - 1].Cur_End ) ) \
3236 CUR.error = TT_Err_Bad_Argument; \
3237 CUR.step_ins = FALSE; \
3242 args[0] = ( args[0] < args[1] );
3246 args[0] = ( args[0] <= args[1] );
3250 args[0] = ( args[0] > args[1] );
3254 args[0] = ( args[0] >= args[1] );
3258 args[0] = ( args[0] == args[1] );
3262 args[0] = ( args[0] != args[1] );
3266 args[0] = ( ( CUR_Func_round( args[0], 0 ) & 127 ) == 64 );
3270 args[0] = ( ( CUR_Func_round( args[0], 0 ) & 127 ) == 0 );
3274 args[0] = ( args[0] && args[1] );
3278 args[0] = ( args[0] || args[1] );
3294 if ( args[1] == 0 ) \
3295 CUR.error = TT_Err_Divide_By_Zero; \
3297 args[0] = TT_MULDIV_NO_ROUND( args[0], 64L, args[1] );
3301 args[0] = TT_MULDIV( args[0], args[1], 64L );
3305 args[0] = FT_ABS( args[0] );
3313 args[0] = FT_PIX_FLOOR( args[0] );
3316 #define DO_CEILING \
3317 args[0] = FT_PIX_CEIL( args[0] );
3322 FT_ULong I = (FT_ULong)args[0]; \
3325 if ( BOUNDSL( I, CUR.storeSize ) ) \
3327 if ( CUR.pedantic_hinting ) \
3329 ARRAY_BOUND_ERROR; \
3335 args[0] = CUR.storage[I]; \
3341 FT_ULong I = (FT_ULong)args[0]; \
3344 if ( BOUNDSL( I, CUR.storeSize ) ) \
3346 if ( CUR.pedantic_hinting ) \
3348 ARRAY_BOUND_ERROR; \
3352 CUR.storage[I] = args[1]; \
3358 FT_ULong I = (FT_ULong)args[0]; \
3361 if ( BOUNDSL( I, CUR.cvtSize ) ) \
3363 if ( CUR.pedantic_hinting ) \
3365 ARRAY_BOUND_ERROR; \
3371 args[0] = CUR_Func_read_cvt( I ); \
3377 FT_ULong I = (FT_ULong)args[0]; \
3380 if ( BOUNDSL( I, CUR.cvtSize ) ) \
3382 if ( CUR.pedantic_hinting ) \
3384 ARRAY_BOUND_ERROR; \
3388 CUR_Func_write_cvt( I, args[1] ); \
3394 FT_ULong I = (FT_ULong)args[0]; \
3397 if ( BOUNDSL( I, CUR.cvtSize ) ) \
3399 if ( CUR.pedantic_hinting ) \
3401 ARRAY_BOUND_ERROR; \
3405 CUR.cvt[I] = TT_MULFIX( args[1], CUR.tt_metrics.scale ); \
3410 CUR.error = TT_Err_Debug_OpCode;
3414 args[0] = CUR_Func_round( \
3416 CUR.tt_metrics.compensations[CUR.opcode - 0x68] );
3420 args[0] = ROUND_None( args[0], \
3421 CUR.tt_metrics.compensations[CUR.opcode - 0x6C] );
3425 if ( args[1] > args[0] ) \
3430 if ( args[1] < args[0] ) \
3434 #ifndef TT_CONFIG_OPTION_INTERPRETER_SWITCH
3437 #undef ARRAY_BOUND_ERROR
3438 #define ARRAY_BOUND_ERROR \
3440 CUR.error = TT_Err_Invalid_Reference; \
3452 Ins_SVTCA( INS_ARG )
3465 Ins_SPVTCA( INS_ARG )
3478 Ins_SFVTCA( INS_ARG )
3491 Ins_SPVTL( INS_ARG )
3504 Ins_SFVTL( INS_ARG )
3517 Ins_SFVTPV( INS_ARG )
3530 Ins_SPVFS( INS_ARG )
3543 Ins_SFVFS( INS_ARG )
3696 Ins_SROUND( INS_ARG )
3709 Ins_S45ROUND( INS_ARG )
3722 Ins_SLOOP( INS_ARG )
3748 Ins_SCVTCI( INS_ARG )
3761 Ins_SSWCI( INS_ARG )
3787 Ins_FLIPON( INS_ARG )
3800 Ins_FLIPOFF( INS_ARG )
3813 Ins_SANGW( INS_ARG )
3852 Ins_MPPEM( INS_ARG )
3904 Ins_CLEAR( INS_ARG )
3930 Ins_DEPTH( INS_ARG )
3943 Ins_CINDEX( INS_ARG )
4229 Ins_FLOOR( INS_ARG )
4242 Ins_CEILING( INS_ARG )
4281 Ins_WCVTP( INS_ARG )
4294 Ins_WCVTF( INS_ARG )
4335 Ins_DEBUG( INS_ARG )
4348 Ins_ROUND( INS_ARG )
4361 Ins_NROUND( INS_ARG )
4410 Ins_MINDEX( INS_ARG )
4417 if ( L <= 0 || L > CUR.args )
4419 if ( CUR.pedantic_hinting )
4420 CUR.error = TT_Err_Invalid_Reference;
4424 K = CUR.stack[CUR.args - L];
4427 &CUR.stack[CUR.args - L + 1],
4430 CUR.stack[CUR.args - 1] = K;
4471 CUR.IP += CUR.length;
4473 if ( CUR.IP < CUR.codeSize )
4475 CUR.opcode = CUR.code[CUR.IP];
4477 CUR.length = opcode_length[CUR.opcode];
4478 if ( CUR.length < 0 )
4480 if ( CUR.IP + 1 >= CUR.codeSize )
4482 CUR.length = 2 - CUR.length * CUR.code[CUR.IP + 1];
4485 if ( CUR.IP + CUR.length <= CUR.codeSize )
4490 CUR.error = TT_Err_Code_Overflow;
4519 switch ( CUR.opcode )
4534 }
while ( Out == 0 );
4559 switch ( CUR.opcode )
4569 }
while ( nIfs != 0 );
4600 limit = rec + CUR.numFDefs;
4603 for ( ; rec <
limit; rec++ )
4605 if ( rec->
opc == n )
4612 if ( CUR.numFDefs >= CUR.maxFDefs )
4614 CUR.error = TT_Err_Too_Many_Function_Defs;
4624 CUR.error = TT_Err_Too_Many_Function_Defs;
4628 rec->
range = CUR.curRange;
4630 rec->
start = CUR.IP + 1;
4633 if ( n > CUR.maxFunc )
4639 while ( SKIP_Code() ==
SUCCESS )
4641 switch ( CUR.opcode )
4645 CUR.error = TT_Err_Nested_DEFS;
4670 if ( CUR.callTop <= 0 )
4672 CUR.error = TT_Err_ENDF_In_Exec_Stream;
4678 pRec = &CUR.callStack[CUR.callTop];
4682 CUR.step_ins =
FALSE;
4721 if ( BOUNDSL( F, CUR.maxFunc + 1 ) )
4733 def = CUR.FDefs +
F;
4734 if ( CUR.maxFunc + 1 != CUR.numFDefs || def->
opc != F )
4741 limit = def + CUR.numFDefs;
4743 while ( def < limit && def->opc != F )
4755 if ( CUR.callTop >= CUR.callSize )
4757 CUR.error = TT_Err_Stack_Overflow;
4761 pCrec = CUR.callStack + CUR.callTop;
4771 INS_Goto_CodeRange( def->
range,
4774 CUR.step_ins =
FALSE;
4778 CUR.error = TT_Err_Invalid_Reference;
4789 Ins_LOOPCALL( INS_ARG )
4798 if ( BOUNDSL( F, CUR.maxFunc + 1 ) )
4810 def = CUR.FDefs +
F;
4811 if ( CUR.maxFunc + 1 != CUR.numFDefs || def->
opc != F )
4818 limit = def + CUR.numFDefs;
4820 while ( def < limit && def->opc != F )
4832 if ( CUR.callTop >= CUR.callSize )
4834 CUR.error = TT_Err_Stack_Overflow;
4840 pCrec = CUR.callStack + CUR.callTop;
4850 INS_Goto_CodeRange( def->
range, def->
start );
4852 CUR.step_ins =
FALSE;
4857 CUR.error = TT_Err_Invalid_Reference;
4877 limit = def + CUR.numIDefs;
4879 for ( ; def <
limit; def++ )
4886 if ( CUR.numIDefs >= CUR.maxIDefs )
4888 CUR.error = TT_Err_Too_Many_Instruction_Defs;
4895 if ( 0 > args[0] || args[0] > 0x00FF )
4897 CUR.error = TT_Err_Too_Many_Instruction_Defs;
4902 def->
start = CUR.IP + 1;
4903 def->
range = CUR.curRange;
4906 if ( (
FT_ULong)args[0] > CUR.maxIns )
4907 CUR.maxIns = (
FT_Byte)args[0];
4912 while ( SKIP_Code() ==
SUCCESS )
4914 switch ( CUR.opcode )
4918 CUR.error = TT_Err_Nested_DEFS;
4943 Ins_NPUSHB( INS_ARG )
4950 if ( BOUNDS( L, CUR.stackSize + 1 - CUR.top ) )
4952 CUR.error = TT_Err_Stack_Overflow;
4956 for ( K = 1; K <= L; K++ )
4957 args[K - 1] = CUR.code[CUR.IP + K + 1];
4970 Ins_NPUSHW( INS_ARG )
4977 if ( BOUNDS( L, CUR.stackSize + 1 - CUR.top ) )
4979 CUR.error = TT_Err_Stack_Overflow;
4985 for ( K = 0; K < L; K++ )
4986 args[K] = GET_ShortIns();
4988 CUR.step_ins =
FALSE;
5000 Ins_PUSHB( INS_ARG )
5005 L = (
FT_UShort)( CUR.opcode - 0xB0 + 1 );
5007 if ( BOUNDS( L, CUR.stackSize + 1 - CUR.top ) )
5009 CUR.error = TT_Err_Stack_Overflow;
5013 for ( K = 1; K <= L; K++ )
5014 args[K - 1] = CUR.code[CUR.IP + K];
5025 Ins_PUSHW( INS_ARG )
5030 L = (
FT_UShort)( CUR.opcode - 0xB8 + 1 );
5032 if ( BOUNDS( L, CUR.stackSize + 1 - CUR.top ) )
5034 CUR.error = TT_Err_Stack_Overflow;
5040 for ( K = 0; K < L; K++ )
5041 args[K] = GET_ShortIns();
5043 CUR.step_ins =
FALSE;
5074 if ( BOUNDSL( L, CUR.zp2.n_points ) )
5076 if ( CUR.pedantic_hinting )
5077 CUR.error = TT_Err_Invalid_Reference;
5082 if ( CUR.opcode & 1 )
5083 R = CUR_fast_dualproj( &CUR.zp2.org[L] );
5085 R = CUR_fast_project( &CUR.zp2.cur[L] );
5111 if ( BOUNDS( L, CUR.zp2.n_points ) )
5113 if ( CUR.pedantic_hinting )
5114 CUR.error = TT_Err_Invalid_Reference;
5118 K = CUR_fast_project( &CUR.zp2.cur[L] );
5120 CUR_Func_move( &CUR.zp2, L, args[1] - K );
5124 if ( CUR.GS.gep2 == 0 )
5125 CUR.zp2.org[L] = CUR.zp2.cur[L];
5154 if ( BOUNDS( L, CUR.zp0.n_points ) ||
5155 BOUNDS( K, CUR.zp1.n_points ) )
5157 if ( CUR.pedantic_hinting )
5158 CUR.error = TT_Err_Invalid_Reference;
5163 if ( CUR.opcode & 1 )
5164 D = CUR_Func_project( CUR.zp0.cur + L, CUR.zp1.cur + K );
5169 if ( CUR.GS.gep0 == 0 || CUR.GS.gep1 == 0 )
5175 D = CUR_Func_dualproj( vec1, vec2 );
5183 if ( CUR.metrics.x_scale == CUR.metrics.y_scale )
5186 D = CUR_Func_dualproj( vec1, vec2 );
5187 D = TT_MULFIX( D, CUR.metrics.x_scale );
5194 vec.
x = TT_MULFIX( vec1->
x - vec2->
x, CUR.metrics.x_scale );
5195 vec.
y = TT_MULFIX( vec1->
y - vec2->
y, CUR.metrics.y_scale );
5197 D = CUR_fast_dualproj( &vec );
5214 Ins_SDPVTL( INS_ARG )
5218 FT_Int aOpc = CUR.opcode;
5224 if ( BOUNDS( p2, CUR.zp1.n_points ) ||
5225 BOUNDS( p1, CUR.zp2.n_points ) )
5227 if ( CUR.pedantic_hinting )
5228 CUR.error = TT_Err_Invalid_Reference;
5245 if ( A == 0 && B == 0 )
5252 if ( ( aOpc & 1 ) != 0 )
5259 NORMalize( A, B, &CUR.GS.dualVector );
5270 if ( ( aOpc & 1 ) != 0 )
5277 NORMalize( A, B, &CUR.GS.projVector );
5279 GUESS_VECTOR( freeVector );
5294 switch ( (
FT_Int)args[0] )
5297 CUR.zp0 = CUR.twilight;
5305 if ( CUR.pedantic_hinting )
5306 CUR.error = TT_Err_Invalid_Reference;
5323 switch ( (
FT_Int)args[0] )
5326 CUR.zp1 = CUR.twilight;
5334 if ( CUR.pedantic_hinting )
5335 CUR.error = TT_Err_Invalid_Reference;
5352 switch ( (
FT_Int)args[0] )
5355 CUR.zp2 = CUR.twilight;
5363 if ( CUR.pedantic_hinting )
5364 CUR.error = TT_Err_Invalid_Reference;
5381 switch ( (
FT_Int)args[0] )
5384 CUR.zp0 = CUR.twilight;
5392 if ( CUR.pedantic_hinting )
5393 CUR.error = TT_Err_Invalid_Reference;
5413 Ins_INSTCTRL( INS_ARG )
5421 if ( K < 1 || K > 2 )
5423 if ( CUR.pedantic_hinting )
5424 CUR.error = TT_Err_Invalid_Reference;
5431 CUR.GS.instruct_control =
FT_BOOL(
5443 Ins_SCANCTRL( INS_ARG )
5449 A = (
FT_Int)( args[0] & 0xFF );
5453 CUR.GS.scan_control =
TRUE;
5458 CUR.GS.scan_control =
FALSE;
5462 if ( ( args[0] & 0x100 ) != 0 && CUR.tt_metrics.ppem <= A )
5463 CUR.GS.scan_control =
TRUE;
5465 if ( ( args[0] & 0x200 ) != 0 && CUR.tt_metrics.rotated )
5466 CUR.GS.scan_control =
TRUE;
5468 if ( ( args[0] & 0x400 ) != 0 && CUR.tt_metrics.stretched )
5469 CUR.GS.scan_control =
TRUE;
5471 if ( ( args[0] & 0x800 ) != 0 && CUR.tt_metrics.ppem > A )
5472 CUR.GS.scan_control =
FALSE;
5474 if ( ( args[0] & 0x1000 ) != 0 && CUR.tt_metrics.rotated )
5475 CUR.GS.scan_control =
FALSE;
5477 if ( ( args[0] & 0x2000 ) != 0 && CUR.tt_metrics.stretched )
5478 CUR.GS.scan_control =
FALSE;
5489 Ins_SCANTYPE( INS_ARG )
5492 CUR.GS.scan_type = (
FT_Int)args[0];
5512 Ins_FLIPPT( INS_ARG )
5519 if ( CUR.top < CUR.GS.loop )
5521 if ( CUR.pedantic_hinting )
5522 CUR.error = TT_Err_Too_Few_Arguments;
5526 while ( CUR.GS.loop > 0 )
5532 if ( BOUNDS( point, CUR.pts.n_points ) )
5534 if ( CUR.pedantic_hinting )
5536 CUR.error = TT_Err_Invalid_Reference;
5548 CUR.new_top = CUR.args;
5559 Ins_FLIPRGON( INS_ARG )
5567 if ( BOUNDS( K, CUR.pts.n_points ) ||
5568 BOUNDS( L, CUR.pts.n_points ) )
5570 if ( CUR.pedantic_hinting )
5571 CUR.error = TT_Err_Invalid_Reference;
5575 for ( I = L; I <= K; I++ )
5587 Ins_FLIPRGOFF( INS_ARG )
5595 if ( BOUNDS( K, CUR.pts.n_points ) ||
5596 BOUNDS( L, CUR.pts.n_points ) )
5598 if ( CUR.pedantic_hinting )
5599 CUR.error = TT_Err_Invalid_Reference;
5603 for ( I = L; I <= K; I++ )
5619 if ( CUR.opcode & 1 )
5632 if ( CUR.pedantic_hinting )
5633 CUR.error = TT_Err_Invalid_Reference;
5641 d = CUR_Func_project( zp.
cur + p, zp.
org + p );
5643 #ifdef TT_CONFIG_OPTION_UNPATENTED_HINTING
5644 if ( CUR.face->unpatented_hinting )
5646 if ( CUR.GS.both_x_axis )
5661 (
FT_Long)CUR.GS.freeVector.x * 0x10000L,
5664 (
FT_Long)CUR.GS.freeVector.y * 0x10000L,
5678 #ifdef TT_CONFIG_OPTION_UNPATENTED_HINTING
5679 if ( CUR.face->unpatented_hinting )
5681 if ( CUR.GS.both_x_axis )
5683 CUR.zp2.cur[point].x += dx;
5689 CUR.zp2.cur[point].y += dy;
5697 if ( CUR.GS.freeVector.x != 0 )
5699 CUR.zp2.cur[point].x += dx;
5704 if ( CUR.GS.freeVector.y != 0 )
5706 CUR.zp2.cur[point].y += dy;
5732 if ( CUR.top < CUR.GS.loop )
5734 if ( CUR.pedantic_hinting )
5735 CUR.error = TT_Err_Invalid_Reference;
5739 if ( COMPUTE_Point_Displacement( &dx, &dy, &zp, &refp ) )
5742 while ( CUR.GS.loop > 0 )
5747 if ( BOUNDS( point, CUR.zp2.n_points ) )
5749 if ( CUR.pedantic_hinting )
5751 CUR.error = TT_Err_Invalid_Reference;
5756 MOVE_Zp2_Point( point, dx, dy,
TRUE );
5763 CUR.new_top = CUR.args;
5789 bounds = ( CUR.GS.gep2 == 0 ) ? 1 : CUR.zp2.n_contours;
5791 if ( BOUNDS( contour, bounds ) )
5793 if ( CUR.pedantic_hinting )
5794 CUR.error = TT_Err_Invalid_Reference;
5798 if ( COMPUTE_Point_Displacement( &dx, &dy, &zp, &refp ) )
5804 start = (
FT_UShort)( CUR.zp2.contours[contour - 1] + 1 -
5805 CUR.zp2.first_point );
5808 if ( CUR.GS.gep2 == 0 )
5809 limit = CUR.zp2.n_points;
5811 limit = (
FT_UShort)( CUR.zp2.contours[contour] -
5812 CUR.zp2.first_point + 1 );
5814 for ( i = start; i <
limit; i++ )
5816 if ( zp.
cur != CUR.zp2.cur || refp != i )
5817 MOVE_Zp2_Point( i, dx, dy,
TRUE );
5839 if ( BOUNDS( args[0], 2 ) )
5841 if ( CUR.pedantic_hinting )
5842 CUR.error = TT_Err_Invalid_Reference;
5846 if ( COMPUTE_Point_Displacement( &dx, &dy, &zp, &refp ) )
5853 if ( CUR.GS.gep2 == 0 )
5855 else if ( CUR.GS.gep2 == 1 && CUR.zp2.n_contours > 0 )
5856 limit = (
FT_UShort)( CUR.zp2.contours[CUR.zp2.n_contours - 1] + 1 );
5861 for ( i = 0; i <
limit; i++ )
5863 if ( zp.
cur != CUR.zp2.cur || refp != i )
5864 MOVE_Zp2_Point( i, dx, dy,
FALSE );
5876 Ins_SHPIX( INS_ARG )
5882 if ( CUR.top < CUR.GS.loop + 1 )
5884 if ( CUR.pedantic_hinting )
5885 CUR.error = TT_Err_Invalid_Reference;
5889 #ifdef TT_CONFIG_OPTION_UNPATENTED_HINTING
5890 if ( CUR.face->unpatented_hinting )
5892 if ( CUR.GS.both_x_axis )
5894 dx = TT_MulFix14( (FT_UInt32)args[0], 0x4000 );
5900 dy = TT_MulFix14( (FT_UInt32)args[0], 0x4000 );
5906 dx = TT_MulFix14( (FT_UInt32)args[0], CUR.GS.freeVector.x );
5907 dy = TT_MulFix14( (FT_UInt32)args[0], CUR.GS.freeVector.y );
5910 while ( CUR.GS.loop > 0 )
5916 if ( BOUNDS( point, CUR.zp2.n_points ) )
5918 if ( CUR.pedantic_hinting )
5920 CUR.error = TT_Err_Invalid_Reference;
5925 MOVE_Zp2_Point( point, dx, dy,
TRUE );
5932 CUR.new_top = CUR.args;
5943 Ins_MSIRP( INS_ARG )
5951 if ( BOUNDS( point, CUR.zp1.n_points ) ||
5952 BOUNDS( CUR.GS.rp0, CUR.zp0.n_points ) )
5954 if ( CUR.pedantic_hinting )
5955 CUR.error = TT_Err_Invalid_Reference;
5961 if ( CUR.GS.gep1 == 0 )
5963 CUR.zp1.org[point] = CUR.zp0.org[CUR.GS.rp0];
5964 CUR_Func_move_orig( &CUR.zp1, point, args[1] );
5965 CUR.zp1.cur[point] = CUR.zp1.org[point];
5968 distance = CUR_Func_project( CUR.zp1.cur + point,
5969 CUR.zp0.cur + CUR.GS.rp0 );
5971 CUR_Func_move( &CUR.zp1, point, args[1] - distance );
5973 CUR.GS.rp1 = CUR.GS.rp0;
5976 if ( ( CUR.opcode & 1 ) != 0 )
5997 if ( BOUNDS( point, CUR.zp0.n_points ) )
5999 if ( CUR.pedantic_hinting )
6000 CUR.error = TT_Err_Invalid_Reference;
6004 if ( ( CUR.opcode & 1 ) != 0 )
6006 cur_dist = CUR_fast_project( &CUR.zp0.cur[point] );
6007 distance = CUR_Func_round( cur_dist,
6008 CUR.tt_metrics.compensations[0] ) - cur_dist;
6013 CUR_Func_move( &CUR.zp0, point, distance );
6038 if ( BOUNDS( point, CUR.zp0.n_points ) ||
6039 BOUNDSL( cvtEntry, CUR.cvtSize ) )
6041 if ( CUR.pedantic_hinting )
6042 CUR.error = TT_Err_Invalid_Reference;
6066 distance = CUR_Func_read_cvt( cvtEntry );
6068 if ( CUR.GS.gep0 == 0 )
6070 CUR.zp0.org[point].x = TT_MulFix14( (FT_UInt32)distance,
6071 CUR.GS.freeVector.x );
6072 CUR.zp0.org[point].y = TT_MulFix14( (FT_UInt32)distance,
6073 CUR.GS.freeVector.y ),
6074 CUR.zp0.cur[point] = CUR.zp0.org[point];
6077 org_dist = CUR_fast_project( &CUR.zp0.cur[point] );
6079 if ( ( CUR.opcode & 1 ) != 0 )
6081 if (
FT_ABS( distance - org_dist ) > CUR.GS.control_value_cutin )
6082 distance = org_dist;
6084 distance = CUR_Func_round( distance, CUR.tt_metrics.compensations[0] );
6087 CUR_Func_move( &CUR.zp0, point, distance - org_dist );
6110 if ( BOUNDS( point, CUR.zp1.n_points ) ||
6111 BOUNDS( CUR.GS.rp0, CUR.zp0.n_points ) )
6113 if ( CUR.pedantic_hinting )
6114 CUR.error = TT_Err_Invalid_Reference;
6123 if ( CUR.GS.gep0 == 0 || CUR.GS.gep1 == 0 )
6126 FT_Vector* vec2 = &CUR.zp0.org[CUR.GS.rp0];
6129 org_dist = CUR_Func_dualproj( vec1, vec2 );
6134 FT_Vector* vec2 = &CUR.zp0.orus[CUR.GS.rp0];
6137 if ( CUR.metrics.x_scale == CUR.metrics.y_scale )
6140 org_dist = CUR_Func_dualproj( vec1, vec2 );
6141 org_dist = TT_MULFIX( org_dist, CUR.metrics.x_scale );
6148 vec.
x = TT_MULFIX( vec1->
x - vec2->
x, CUR.metrics.x_scale );
6149 vec.
y = TT_MULFIX( vec1->
y - vec2->
y, CUR.metrics.y_scale );
6151 org_dist = CUR_fast_dualproj( &vec );
6157 if (
FT_ABS( org_dist - CUR.GS.single_width_value ) <
6158 CUR.GS.single_width_cutin )
6160 if ( org_dist >= 0 )
6161 org_dist = CUR.GS.single_width_value;
6163 org_dist = -CUR.GS.single_width_value;
6168 if ( ( CUR.opcode & 4 ) != 0 )
6169 distance = CUR_Func_round(
6171 CUR.tt_metrics.compensations[CUR.opcode & 3] );
6173 distance = ROUND_None(
6175 CUR.tt_metrics.compensations[CUR.opcode & 3] );
6179 if ( ( CUR.opcode & 8 ) != 0 )
6181 if ( org_dist >= 0 )
6183 if ( distance < CUR.GS.minimum_distance )
6184 distance = CUR.GS.minimum_distance;
6188 if ( distance > -CUR.GS.minimum_distance )
6189 distance = -CUR.GS.minimum_distance;
6195 org_dist = CUR_Func_project( CUR.zp1.cur + point,
6196 CUR.zp0.cur + CUR.GS.rp0 );
6198 CUR_Func_move( &CUR.zp1, point, distance - org_dist );
6201 CUR.GS.rp1 = CUR.GS.rp0;
6204 if ( ( CUR.opcode & 16 ) != 0 )
6228 cvtEntry = (
FT_ULong)( args[1] + 1 );
6232 if ( BOUNDS( point, CUR.zp1.n_points ) ||
6233 BOUNDSL( cvtEntry, CUR.cvtSize + 1 ) ||
6234 BOUNDS( CUR.GS.rp0, CUR.zp0.n_points ) )
6236 if ( CUR.pedantic_hinting )
6237 CUR.error = TT_Err_Invalid_Reference;
6244 cvt_dist = CUR_Func_read_cvt( cvtEntry - 1 );
6248 if (
FT_ABS( cvt_dist - CUR.GS.single_width_value ) <
6249 CUR.GS.single_width_cutin )
6251 if ( cvt_dist >= 0 )
6252 cvt_dist = CUR.GS.single_width_value;
6254 cvt_dist = -CUR.GS.single_width_value;
6259 if ( CUR.GS.gep1 == 0 )
6261 CUR.zp1.org[point].x = CUR.zp0.org[CUR.GS.rp0].x +
6262 TT_MulFix14( (FT_UInt32)cvt_dist,
6263 CUR.GS.freeVector.x );
6264 CUR.zp1.org[point].y = CUR.zp0.org[CUR.GS.rp0].y +
6265 TT_MulFix14( (FT_UInt32)cvt_dist,
6266 CUR.GS.freeVector.y );
6267 CUR.zp1.cur[point] = CUR.zp1.org[point];
6270 org_dist = CUR_Func_dualproj( &CUR.zp1.org[point],
6271 &CUR.zp0.org[CUR.GS.rp0] );
6272 cur_dist = CUR_Func_project ( &CUR.zp1.cur[point],
6273 &CUR.zp0.cur[CUR.GS.rp0] );
6277 if ( CUR.GS.auto_flip )
6279 if ( ( org_dist ^ cvt_dist ) < 0 )
6280 cvt_dist = -cvt_dist;
6285 if ( ( CUR.opcode & 4 ) != 0 )
6290 if ( CUR.GS.gep0 == CUR.GS.gep1 )
6304 if (
FT_ABS( cvt_dist - org_dist ) > CUR.GS.control_value_cutin )
6305 cvt_dist = org_dist;
6308 distance = CUR_Func_round(
6310 CUR.tt_metrics.compensations[CUR.opcode & 3] );
6313 distance = ROUND_None(
6315 CUR.tt_metrics.compensations[CUR.opcode & 3] );
6319 if ( ( CUR.opcode & 8 ) != 0 )
6321 if ( org_dist >= 0 )
6323 if ( distance < CUR.GS.minimum_distance )
6324 distance = CUR.GS.minimum_distance;
6328 if ( distance > -CUR.GS.minimum_distance )
6329 distance = -CUR.GS.minimum_distance;
6333 CUR_Func_move( &CUR.zp1, point, distance - cur_dist );
6336 CUR.GS.rp1 = CUR.GS.rp0;
6338 if ( ( CUR.opcode & 16 ) != 0 )
6352 Ins_ALIGNRP( INS_ARG )
6360 if ( CUR.top < CUR.GS.loop ||
6361 BOUNDS( CUR.GS.rp0, CUR.zp0.n_points ) )
6363 if ( CUR.pedantic_hinting )
6364 CUR.error = TT_Err_Invalid_Reference;
6368 while ( CUR.GS.loop > 0 )
6374 if ( BOUNDS( point, CUR.zp1.n_points ) )
6376 if ( CUR.pedantic_hinting )
6378 CUR.error = TT_Err_Invalid_Reference;
6384 distance = CUR_Func_project( CUR.zp1.cur + point,
6385 CUR.zp0.cur + CUR.GS.rp0 );
6387 CUR_Func_move( &CUR.zp1, point, -distance );
6395 CUR.new_top = CUR.args;
6406 Ins_ISECT( INS_ARG )
6430 if ( BOUNDS( b0, CUR.zp0.n_points ) ||
6431 BOUNDS( b1, CUR.zp0.n_points ) ||
6432 BOUNDS( a0, CUR.zp1.n_points ) ||
6433 BOUNDS( a1, CUR.zp1.n_points ) ||
6434 BOUNDS( point, CUR.zp2.n_points ) )
6436 if ( CUR.pedantic_hinting )
6437 CUR.error = TT_Err_Invalid_Reference;
6441 dbx = CUR.zp0.cur[b1].x - CUR.zp0.cur[b0].x;
6442 dby = CUR.zp0.cur[b1].y - CUR.zp0.cur[b0].y;
6444 dax = CUR.zp1.cur[a1].x - CUR.zp1.cur[a0].x;
6445 day = CUR.zp1.cur[a1].y - CUR.zp1.cur[a0].y;
6447 dx = CUR.zp0.cur[b0].x - CUR.zp1.cur[a0].x;
6448 dy = CUR.zp0.cur[b0].y - CUR.zp1.cur[a0].y;
6452 discriminant = TT_MULDIV( dax, -dby, 0x40 ) +
6453 TT_MULDIV( day, dbx, 0x40 );
6455 if (
FT_ABS( discriminant ) >= 0x40 )
6457 val = TT_MULDIV( dx, -dby, 0x40 ) + TT_MULDIV( dy, dbx, 0x40 );
6459 R.
x = TT_MULDIV( val, dax, discriminant );
6460 R.
y = TT_MULDIV( val, day, discriminant );
6462 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;
6469 CUR.zp2.cur[point].x = ( CUR.zp1.cur[a0].x +
6472 CUR.zp0.cur[b1].x ) / 4;
6473 CUR.zp2.cur[point].y = ( CUR.zp1.cur[a0].y +
6476 CUR.zp0.cur[b1].y ) / 4;
6488 Ins_ALIGNPTS( INS_ARG )
6497 if ( BOUNDS( p1, CUR.zp1.n_points ) ||
6498 BOUNDS( p2, CUR.zp0.n_points ) )
6500 if ( CUR.pedantic_hinting )
6501 CUR.error = TT_Err_Invalid_Reference;
6505 distance = CUR_Func_project( CUR.zp0.cur + p2,
6506 CUR.zp1.cur + p1 ) / 2;
6508 CUR_Func_move( &CUR.zp1, p1, distance );
6509 CUR_Func_move( &CUR.zp0, p2, -distance );
6533 if ( CUR.top < CUR.GS.loop )
6535 if ( CUR.pedantic_hinting )
6536 CUR.error = TT_Err_Invalid_Reference;
6545 twilight = CUR.GS.gep0 == 0 || CUR.GS.gep1 == 0 || CUR.GS.gep2 == 0;
6547 if ( BOUNDS( CUR.GS.rp1, CUR.zp0.n_points ) )
6549 if ( CUR.pedantic_hinting )
6550 CUR.error = TT_Err_Invalid_Reference;
6555 orus_base = &CUR.zp0.org[CUR.GS.rp1];
6557 orus_base = &CUR.zp0.orus[CUR.GS.rp1];
6559 cur_base = &CUR.zp0.cur[CUR.GS.rp1];
6565 if ( BOUNDS( CUR.GS.rp1, CUR.zp0.n_points ) ||
6566 BOUNDS( CUR.GS.rp2, CUR.zp1.n_points ) )
6574 old_range = CUR_Func_dualproj( &CUR.zp1.org[CUR.GS.rp2],
6576 else if ( CUR.metrics.x_scale == CUR.metrics.y_scale )
6577 old_range = CUR_Func_dualproj( &CUR.zp1.orus[CUR.GS.rp2],
6584 vec.
x = TT_MULFIX( CUR.zp1.orus[CUR.GS.rp2].x - orus_base->
x,
6585 CUR.metrics.x_scale );
6586 vec.
y = TT_MULFIX( CUR.zp1.orus[CUR.GS.rp2].y - orus_base->
y,
6587 CUR.metrics.y_scale );
6589 old_range = CUR_fast_dualproj( &vec );
6592 cur_range = CUR_Func_project ( &CUR.zp1.cur[CUR.GS.rp2], cur_base );
6595 for ( ; CUR.GS.loop > 0; --CUR.GS.loop )
6602 if ( BOUNDS( point, CUR.zp2.n_points ) )
6604 if ( CUR.pedantic_hinting )
6606 CUR.error = TT_Err_Invalid_Reference;
6613 org_dist = CUR_Func_dualproj( &CUR.zp2.org[point], orus_base );
6614 else if ( CUR.metrics.x_scale == CUR.metrics.y_scale )
6615 org_dist = CUR_Func_dualproj( &CUR.zp2.orus[point], orus_base );
6621 vec.
x = TT_MULFIX( CUR.zp2.orus[point].x - orus_base->
x,
6622 CUR.metrics.x_scale );
6623 vec.
y = TT_MULFIX( CUR.zp2.orus[point].y - orus_base->
y,
6624 CUR.metrics.y_scale );
6626 org_dist = CUR_fast_dualproj( &vec );
6629 cur_dist = CUR_Func_project ( &CUR.zp2.cur[point], cur_base );
6632 new_dist = ( old_range != 0 )
6633 ? TT_MULDIV( org_dist, cur_range, old_range )
6638 CUR_Func_move( &CUR.zp2, (
FT_UShort)point, new_dist - cur_dist );
6643 CUR.new_top = CUR.args;
6662 if ( BOUNDS( point, CUR.zp0.n_points ) )
6664 if ( CUR.pedantic_hinting )
6665 CUR.error = TT_Err_Invalid_Reference;
6671 if ( CUR.GS.freeVector.x != 0 )
6674 if ( CUR.GS.freeVector.y != 0 )
6677 CUR.zp0.tags[point] &=
mask;
6682 typedef struct IUP_WorkerRec_
6689 } IUP_WorkerRec, *IUP_Worker;
6693 _iup_worker_shift( IUP_Worker worker,
6702 dx = worker->curs[
p].x - worker->orgs[
p].x;
6705 for ( i = p1; i <
p; i++ )
6706 worker->curs[i].x += dx;
6708 for ( i = p + 1; i <= p2; i++ )
6709 worker->curs[i].x += dx;
6715 _iup_worker_interpolate( IUP_Worker worker,
6722 FT_F26Dot6 orus1, orus2, org1, org2, delta1, delta2;
6728 if ( BOUNDS( ref1, worker->max_points ) ||
6729 BOUNDS( ref2, worker->max_points ) )
6732 orus1 = worker->orus[ref1].x;
6733 orus2 = worker->orus[ref2].x;
6735 if ( orus1 > orus2 )
6750 org1 = worker->orgs[ref1].x;
6751 org2 = worker->orgs[ref2].x;
6752 delta1 = worker->curs[ref1].x - org1;
6753 delta2 = worker->curs[ref2].x - org2;
6755 if ( orus1 == orus2 )
6758 for ( i = p1; i <= p2; i++ )
6768 worker->curs[
i].x =
x;
6778 for ( i = p1; i <= p2; i++ )
6786 else if ( x >= org2 )
6794 scale = TT_MULDIV( org2 + delta2 - ( org1 + delta1 ),
6795 0x10000L, orus2 - orus1 );
6798 x = ( org1 + delta1 ) +
6799 TT_MULFIX( worker->orus[i].x - orus1, scale );
6801 worker->curs[
i].x =
x;
6832 if ( CUR.pts.n_contours == 0 )
6835 if ( CUR.opcode & 1 )
6838 V.orgs = CUR.pts.org;
6839 V.curs = CUR.pts.cur;
6840 V.orus = CUR.pts.orus;
6849 V.max_points = CUR.pts.n_points;
6856 end_point = CUR.pts.contours[contour] - CUR.pts.first_point;
6857 first_point = point;
6859 if ( BOUNDS ( end_point, CUR.pts.n_points ) )
6860 end_point = CUR.pts.n_points - 1;
6862 while ( point <= end_point && ( CUR.pts.tags[point] & mask ) == 0 )
6865 if ( point <= end_point )
6867 first_touched = point;
6868 cur_touched = point;
6872 while ( point <= end_point )
6874 if ( ( CUR.pts.tags[point] & mask ) != 0 )
6876 _iup_worker_interpolate( &V,
6881 cur_touched = point;
6887 if ( cur_touched == first_touched )
6888 _iup_worker_shift( &V, first_point, end_point, cur_touched );
6891 _iup_worker_interpolate( &V,
6897 if ( first_touched > 0 )
6898 _iup_worker_interpolate( &V,
6906 }
while ( contour < CUR.pts.n_contours );
6917 Ins_DELTAP( INS_ARG )
6925 #ifdef TT_CONFIG_OPTION_UNPATENTED_HINTING
6927 if ( CUR.face->unpatented_hinting )
6934 if ( CUR.pedantic_hinting )
6935 CUR.error = TT_Err_Too_Few_Arguments;
6940 CUR.new_top = CUR.args;
6948 for ( k = 1; k <= nump; k++ )
6952 if ( CUR.pedantic_hinting )
6953 CUR.error = TT_Err_Too_Few_Arguments;
6961 B = CUR.stack[CUR.args];
6969 if ( !BOUNDS( A, CUR.zp0.n_points ) )
6973 switch ( CUR.opcode )
6987 C += CUR.GS.delta_base;
6989 if ( CURRENT_Ppem() == (
FT_Long)C )
6994 B = B * 64 / ( 1L << CUR.GS.delta_shift );
6996 CUR_Func_move( &CUR.zp0, A, B );
7000 if ( CUR.pedantic_hinting )
7001 CUR.error = TT_Err_Invalid_Reference;
7005 CUR.new_top = CUR.args;
7016 Ins_DELTAC( INS_ARG )
7023 #ifdef TT_CONFIG_OPTION_UNPATENTED_HINTING
7025 if ( CUR.face->unpatented_hinting )
7032 if ( CUR.pedantic_hinting )
7033 CUR.error = TT_Err_Too_Few_Arguments;
7038 CUR.new_top = CUR.args;
7045 for ( k = 1; k <= nump; k++ )
7049 if ( CUR.pedantic_hinting )
7050 CUR.error = TT_Err_Too_Few_Arguments;
7057 A = (
FT_ULong)CUR.stack[CUR.args + 1];
7058 B = CUR.stack[CUR.args];
7060 if ( BOUNDSL( A, CUR.cvtSize ) )
7062 if ( CUR.pedantic_hinting )
7064 CUR.error = TT_Err_Invalid_Reference;
7072 switch ( CUR.opcode )
7086 C += CUR.GS.delta_base;
7088 if ( CURRENT_Ppem() == (
FT_Long)C )
7093 B = B * 64 / ( 1L << CUR.GS.delta_shift );
7095 CUR_Func_move_cvt( A, B );
7101 CUR.new_top = CUR.args;
7119 Ins_GETINFO( INS_ARG )
7127 if ( ( args[0] & 1 ) != 0 )
7131 if ( ( args[0] & 2 ) != 0 && CUR.tt_metrics.rotated )
7135 if ( ( args[0] & 4 ) != 0 && CUR.tt_metrics.stretched )
7139 if ( ( args[0] & 32 ) != 0 && CUR.grayscale )
7147 Ins_UNKNOWN( INS_ARG )
7155 for ( ; def <
limit; def++ )
7162 if ( CUR.callTop >= CUR.callSize )
7164 CUR.error = TT_Err_Stack_Overflow;
7168 call = CUR.callStack + CUR.callTop++;