📄 ttinterp.c
字号:
{ return (v1->x - v2->x); }/******************************************************************* * * Function : Project_y * * Input : Vx, Vy input vector * * Output : Returns Vy. * * Note : Used as a dummy function. * *****************************************************************/ static TT_F26Dot6 Project_y( EXEC_OPS TT_Vector* v1, TT_Vector* v2 ) { return (v1->y - v2->y); }/******************************************************************* * * Function : Compute_Funcs * * Description : Computes the projections and movement function * pointers according to the current graphics state. * * Input : None * *****************************************************************/ static void Compute_Funcs( EXEC_OP ) { if ( CUR.GS.freeVector.x == 0x4000 ) { CUR.func_freeProj = (TProject_Function)Project_x; CUR.F_dot_P = CUR.GS.projVector.x * 0x10000L; } else { if ( CUR.GS.freeVector.y == 0x4000 ) { CUR.func_freeProj = (TProject_Function)Project_y; CUR.F_dot_P = CUR.GS.projVector.y * 0x10000L; } else { CUR.func_freeProj = (TProject_Function)Free_Project; CUR.F_dot_P = (Long)CUR.GS.projVector.x * CUR.GS.freeVector.x * 4 + (Long)CUR.GS.projVector.y * CUR.GS.freeVector.y * 4; } } CUR.cached_metrics = FALSE; if ( CUR.GS.projVector.x == 0x4000 ) CUR.func_project = (TProject_Function)Project_x; else { if ( CUR.GS.projVector.y == 0x4000 ) CUR.func_project = (TProject_Function)Project_y; else CUR.func_project = (TProject_Function)Project; } if ( CUR.GS.dualVector.x == 0x4000 ) CUR.func_dualproj = (TProject_Function)Project_x; else { if ( CUR.GS.dualVector.y == 0x4000 ) CUR.func_dualproj = (TProject_Function)Project_y; else CUR.func_dualproj = (TProject_Function)Dual_Project; } CUR.func_move = (TMove_Function)Direct_Move; if ( CUR.F_dot_P == 0x40000000L ) { if ( CUR.GS.freeVector.x == 0x4000 ) CUR.func_move = (TMove_Function)Direct_Move_X; else { if ( CUR.GS.freeVector.y == 0x4000 ) CUR.func_move = (TMove_Function)Direct_Move_Y; } } /* at small sizes, F_dot_P can become too small, resulting */ /* in overflows and 'spikes' in a number of glyphs like 'w'. */ if ( ABS( CUR.F_dot_P ) < 0x4000000L ) CUR.F_dot_P = 0x40000000L; /* Disable cached aspect ratio */ CUR.metrics.ratio = 0; }/******************************************************************* * * Function : Normalize * * Description : Norms a vector * * Input : Vx, Vy input vector * R normed unit vector * * Output : Returns FAILURE if a vector parameter is zero. * *****************************************************************/ static Bool Normalize( EXEC_OPS TT_F26Dot6 Vx, TT_F26Dot6 Vy, TT_UnitVector* R ) { TT_F26Dot6 W; Bool S1, S2; if ( ABS( Vx ) < 0x10000L && ABS( Vy ) < 0x10000L ) { Vx *= 0x100; Vy *= 0x100; W = Norm( Vx, Vy ); if ( W == 0 ) { /* XXX : UNDOCUMENTED! It seems that it's possible to try */ /* to normalize the vector (0,0). Return immediately */ return SUCCESS; } R->x = (TT_F2Dot14)TT_MulDiv( Vx, 0x4000L, W ); R->y = (TT_F2Dot14)TT_MulDiv( Vy, 0x4000L, W ); return SUCCESS; } W = Norm( Vx, Vy ); Vx = TT_MulDiv( Vx, 0x4000L, W ); Vy = TT_MulDiv( Vy, 0x4000L, W ); W = Vx * Vx + Vy * Vy; /* Now, we want that Sqrt( W ) = 0x4000 */ /* Or 0x1000000 <= W < 0x1004000 */ if ( Vx < 0 ) { Vx = -Vx; S1 = TRUE; } else S1 = FALSE; if ( Vy < 0 ) { Vy = -Vy; S2 = TRUE; } else S2 = FALSE; while ( W < 0x1000000L ) { /* We need to increase W, by a minimal amount */ if ( Vx < Vy ) Vx++; else Vy++; W = Vx * Vx + Vy * Vy; } while ( W >= 0x1004000L ) { /* We need to decrease W, by a minimal amount */ if ( Vx < Vy ) Vx--; else Vy--; W = Vx * Vx + Vy * Vy; } /* Note that in various cases, we can only */ /* compute a Sqrt(W) of 0x3FFF, eg. Vx = Vy */ if ( S1 ) Vx = -Vx; if ( S2 ) Vy = -Vy; R->x = (TT_F2Dot14)Vx; /* Type conversion */ R->y = (TT_F2Dot14)Vy; /* Type conversion */ return SUCCESS; }/**************************************************************** * * Opcodes * ****************************************************************/ static Bool Ins_SxVTL( EXEC_OPS UShort aIdx1, UShort aIdx2, Int aOpc, TT_UnitVector* Vec ) { Long A, B, C; TT_Vector* p1; TT_Vector* p2; if ( BOUNDS( aIdx1, CUR.zp2.n_points ) || BOUNDS( aIdx2, CUR.zp1.n_points ) ) { if ( CUR.pedantic_hinting ) CUR.error = TT_Err_Invalid_Reference; return FAILURE; } p1 = CUR.zp1.cur + aIdx2; p2 = CUR.zp2.cur + aIdx1; A = p1->x - p2->x; B = p1->y - p2->y; if ( (aOpc & 1) != 0 ) { C = B; /* CounterClockwise rotation */ B = A; A = -C; } NORMalize( A, B, Vec ); return SUCCESS; }/* When not using the big switch statements, the interpreter uses a *//* call table defined later below in this source. Each opcode must *//* thus have a corresponding function, even trivial ones. *//* *//* They're all defined there. */#define DO_SVTCA \ { \ Short A, B; \ \ \ A = (Short)(CUR.opcode & 1) << 14; \ B = A ^ (Short)0x4000; \ \ CUR.GS.freeVector.x = A; \ CUR.GS.projVector.x = A; \ CUR.GS.dualVector.x = A; \ \ CUR.GS.freeVector.y = B; \ CUR.GS.projVector.y = B; \ CUR.GS.dualVector.y = B; \ \ COMPUTE_Funcs(); \ }#define DO_SPVTCA \ { \ Short A, B; \ \ \ A = (Short)(CUR.opcode & 1) << 14; \ B = A ^ (Short)0x4000; \ \ CUR.GS.projVector.x = A; \ CUR.GS.dualVector.x = A; \ \ CUR.GS.projVector.y = B; \ CUR.GS.dualVector.y = B; \ \ COMPUTE_Funcs(); \ }#define DO_SFVTCA \ { \ Short A, B; \ \ \ A = (Short)(CUR.opcode & 1) << 14; \ B = A ^ (Short)0x4000; \ \ CUR.GS.freeVector.x = A; \ CUR.GS.freeVector.y = B; \ \ COMPUTE_Funcs(); \ }#define DO_SPVTL \ if ( INS_SxVTL( (UShort)args[1], \ (UShort)args[0], \ CUR.opcode, \ &CUR.GS.projVector) == SUCCESS ) \ { \ CUR.GS.dualVector = CUR.GS.projVector; \ COMPUTE_Funcs(); \ }#define DO_SFVTL \ if ( INS_SxVTL( (UShort)args[1], \ (UShort)args[0], \ CUR.opcode, \ &CUR.GS.freeVector) == SUCCESS ) \ COMPUTE_Funcs();#define DO_SFVTPV \ CUR.GS.freeVector = CUR.GS.projVector; \ COMPUTE_Funcs();#define DO_SPVFS \ { \ Short S; \ Long X, Y; \ \ \ /* Only use low 16bits, then sign extend */ \ S = (Short)args[1]; \ Y = (Long)S; \ S = (Short)args[0]; \ X = (Long)S; \ \ NORMalize( X, Y, &CUR.GS.projVector ); \ \ CUR.GS.dualVector = CUR.GS.projVector; \ COMPUTE_Funcs(); \ }#define DO_SFVFS \ { \ Short S; \ Long X, Y; \ \ \ /* Only use low 16bits, then sign extend */ \ S = (Short)args[1]; \ Y = (Long)S; \ S = (Short)args[0]; \ X = S; \ \ NORMalize( X, Y, &CUR.GS.freeVector ); \ COMPUTE_Funcs(); \ }#define DO_GPV \ args[0] = CUR.GS.projVector.x; \ args[1] = CUR.GS.projVector.y;#define DO_GFV \ args[0] = CUR.GS.freeVector.x; \ args[1] = CUR.GS.freeVector.y;#define DO_SRP0 \ CUR.GS.rp0 = (UShort)args[0];#define DO_SRP1 \ CUR.GS.rp1 = (UShort)args[0];#define DO_SRP2 \ CUR.GS.rp2 = (UShort)args[0];#define DO_RTHG \ CUR.GS.round_state = TT_Round_To_Half_Grid; \ CUR.func_round = (TRound_Function)Round_To_Half_Grid;#define DO_RTG \ CUR.GS.round_state = TT_Round_To_Grid; \ CUR.func_round = (TRound_Function)Round_To_Grid;#define DO_RTDG \ CUR.GS.round_state = TT_Round_To_Double_Grid; \ CUR.func_round = (TRound_Function)Round_To_Double_Grid;#define DO_RUTG \ CUR.GS.round_state = TT_Round_Up_To_Grid; \ CUR.func_round = (TRound_Function)Round_Up_To_Grid;#define DO_RDTG \ CUR.GS.round_state = TT_Round_Down_To_Grid; \ CUR.func_round = (TRound_Function)Round_Down_To_Grid;#define DO_ROFF \ CUR.GS.round_state = TT_Round_Off; \ CUR.func_round = (TRound_Function)Round_None;#define DO_SROUND \ SET_SuperRound( 0x4000L, args[0] ); \ CUR.GS.round_state = TT_Round_Super; \ CUR.func_round = (TRound_Function)Round_Super;#define DO_S45ROUND \ SET_SuperRound( 0x2D41L, args[0] ); \ CUR.GS.round_state = TT_Round_Super_45; \ CUR.func_round = (TRound_Function)Round_Super_45;#define DO_SLOOP \ if ( args[0] < 0 ) \ CUR.error = TT_Err_Bad_Argument; \ else \ CUR.GS.loop = args[0];#define DO_SMD \ CUR.GS.minimum_distance = (TT_F26Dot6)args[0];#define DO_SCVTCI \ CUR.GS.control_value_cutin = (TT_F26Dot6)args[0];#define DO_SSWCI \ CUR.GS.single_width_cutin = (TT_F26Dot6)args[0]; /* XXX : UNDOCUMENTED! or bug in the Windows engine? */ /* */ /* It seems that the value that is read here is */ /* expressed in 16.16 format, rather than in */ /* font units.. */ /* */#define DO_SSW \ CUR.GS.single_width_value = (TT_F26Dot6)(args[0] >> 10);#define DO_FLIPON \
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -