⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 ttinterp.c

📁 神龙卡开发原代码
💻 C
📖 第 1 页 / 共 5 页
字号:
  {    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 + -