📄 ttinterp.c
字号:
CUR.tt_metrics.ratio = CUR.tt_metrics.y_ratio;
}
else
#endif
{
if ( CUR.GS.projVector.y == 0 )
CUR.tt_metrics.ratio = CUR.tt_metrics.x_ratio;
else if ( CUR.GS.projVector.x == 0 )
CUR.tt_metrics.ratio = CUR.tt_metrics.y_ratio;
else
{
FT_Long x, y;
x = TT_MULDIV( CUR.GS.projVector.x,
CUR.tt_metrics.x_ratio, 0x4000 );
y = TT_MULDIV( CUR.GS.projVector.y,
CUR.tt_metrics.y_ratio, 0x4000 );
CUR.tt_metrics.ratio = TT_VecLen( x, y );
}
}
}
return CUR.tt_metrics.ratio;
}
static FT_Long
Current_Ppem( EXEC_OP )
{
return TT_MULFIX( CUR.tt_metrics.ppem, CURRENT_Ratio() );
}
/*************************************************************************/
/* */
/* Functions related to the control value table (CVT). */
/* */
/*************************************************************************/
FT_CALLBACK_DEF( FT_F26Dot6 )
Read_CVT( EXEC_OP_ FT_ULong idx )
{
return CUR.cvt[idx];
}
FT_CALLBACK_DEF( FT_F26Dot6 )
Read_CVT_Stretched( EXEC_OP_ FT_ULong idx )
{
return TT_MULFIX( CUR.cvt[idx], CURRENT_Ratio() );
}
FT_CALLBACK_DEF( void )
Write_CVT( EXEC_OP_ FT_ULong idx,
FT_F26Dot6 value )
{
CUR.cvt[idx] = value;
}
FT_CALLBACK_DEF( void )
Write_CVT_Stretched( EXEC_OP_ FT_ULong idx,
FT_F26Dot6 value )
{
CUR.cvt[idx] = FT_DivFix( value, CURRENT_Ratio() );
}
FT_CALLBACK_DEF( void )
Move_CVT( EXEC_OP_ FT_ULong idx,
FT_F26Dot6 value )
{
CUR.cvt[idx] += value;
}
FT_CALLBACK_DEF( void )
Move_CVT_Stretched( EXEC_OP_ FT_ULong idx,
FT_F26Dot6 value )
{
CUR.cvt[idx] += FT_DivFix( value, CURRENT_Ratio() );
}
/*************************************************************************/
/* */
/* <Function> */
/* GetShortIns */
/* */
/* <Description> */
/* Returns a short integer taken from the instruction stream at */
/* address IP. */
/* */
/* <Return> */
/* Short read at code[IP]. */
/* */
/* <Note> */
/* This one could become a macro. */
/* */
static FT_Short
GetShortIns( EXEC_OP )
{
/* Reading a byte stream so there is no endianess (DaveP) */
CUR.IP += 2;
return (FT_Short)( ( CUR.code[CUR.IP - 2] << 8 ) +
CUR.code[CUR.IP - 1] );
}
/*************************************************************************/
/* */
/* <Function> */
/* Ins_Goto_CodeRange */
/* */
/* <Description> */
/* Goes to a certain code range in the instruction stream. */
/* */
/* <Input> */
/* aRange :: The index of the code range. */
/* */
/* aIP :: The new IP address in the code range. */
/* */
/* <Return> */
/* SUCCESS or FAILURE. */
/* */
static FT_Bool
Ins_Goto_CodeRange( EXEC_OP_ FT_Int aRange,
FT_ULong aIP )
{
TT_CodeRange* range;
if ( aRange < 1 || aRange > 3 )
{
CUR.error = TT_Err_Bad_Argument;
return FAILURE;
}
range = &CUR.codeRangeTable[aRange - 1];
if ( range->base == NULL ) /* invalid coderange */
{
CUR.error = TT_Err_Invalid_CodeRange;
return FAILURE;
}
/* NOTE: Because the last instruction of a program may be a CALL */
/* which will return to the first byte *after* the code */
/* range, we test for AIP <= Size, instead of AIP < Size. */
if ( aIP > range->size )
{
CUR.error = TT_Err_Code_Overflow;
return FAILURE;
}
CUR.code = range->base;
CUR.codeSize = range->size;
CUR.IP = aIP;
CUR.curRange = aRange;
return SUCCESS;
}
/*************************************************************************/
/* */
/* <Function> */
/* Direct_Move */
/* */
/* <Description> */
/* Moves a point by a given distance along the freedom vector. The */
/* point will be `touched'. */
/* */
/* <Input> */
/* point :: The index of the point to move. */
/* */
/* distance :: The distance to apply. */
/* */
/* <InOut> */
/* zone :: The affected glyph zone. */
/* */
static void
Direct_Move( EXEC_OP_ TT_GlyphZone zone,
FT_UShort point,
FT_F26Dot6 distance )
{
FT_F26Dot6 v;
#ifdef TT_CONFIG_OPTION_UNPATENTED_HINTING
FT_ASSERT( !CUR.face->unpatented_hinting );
#endif
v = CUR.GS.freeVector.x;
if ( v != 0 )
{
zone->cur[point].x += TT_MULDIV( distance,
v * 0x10000L,
CUR.F_dot_P );
zone->tags[point] |= FT_CURVE_TAG_TOUCH_X;
}
v = CUR.GS.freeVector.y;
if ( v != 0 )
{
zone->cur[point].y += TT_MULDIV( distance,
v * 0x10000L,
CUR.F_dot_P );
zone->tags[point] |= FT_CURVE_TAG_TOUCH_Y;
}
}
/*************************************************************************/
/* */
/* <Function> */
/* Direct_Move_Orig */
/* */
/* <Description> */
/* Moves the *original* position of a point by a given distance along */
/* the freedom vector. Obviously, the point will not be `touched'. */
/* */
/* <Input> */
/* point :: The index of the point to move. */
/* */
/* distance :: The distance to apply. */
/* */
/* <InOut> */
/* zone :: The affected glyph zone. */
/* */
static void
Direct_Move_Orig( EXEC_OP_ TT_GlyphZone zone,
FT_UShort point,
FT_F26Dot6 distance )
{
FT_F26Dot6 v;
#ifdef TT_CONFIG_OPTION_UNPATENTED_HINTING
FT_ASSERT( !CUR.face->unpatented_hinting );
#endif
v = CUR.GS.freeVector.x;
if ( v != 0 )
zone->org[point].x += TT_MULDIV( distance,
v * 0x10000L,
CUR.F_dot_P );
v = CUR.GS.freeVector.y;
if ( v != 0 )
zone->org[point].y += TT_MULDIV( distance,
v * 0x10000L,
CUR.F_dot_P );
}
/*************************************************************************/
/* */
/* Special versions of Direct_Move() */
/* */
/* The following versions are used whenever both vectors are both */
/* along one of the coordinate unit vectors, i.e. in 90% of the cases. */
/* */
/*************************************************************************/
static void
Direct_Move_X( EXEC_OP_ TT_GlyphZone zone,
FT_UShort point,
FT_F26Dot6 distance )
{
FT_UNUSED_EXEC;
zone->cur[point].x += distance;
zone->tags[point] |= FT_CURVE_TAG_TOUCH_X;
}
static void
Direct_Move_Y( EXEC_OP_ TT_GlyphZone zone,
FT_UShort point,
FT_F26Dot6 distance )
{
FT_UNUSED_EXEC;
zone->cur[point].y += distance;
zone->tags[point] |= FT_CURVE_TAG_TOUCH_Y;
}
/*************************************************************************/
/* */
/* Special versions of Direct_Move_Orig() */
/* */
/* The following versions are used whenever both vectors are both */
/* along one of the coordinate unit vectors, i.e. in 90% of the cases. */
/* */
/*************************************************************************/
static void
Direct_Move_Orig_X( EXEC_OP_ TT_GlyphZone zone,
FT_UShort point,
FT_F26Dot6 distance )
{
FT_UNUSED_EXEC;
zone->org[point].x += distance;
}
static void
Direct_Move_Orig_Y( EXEC_OP_ TT_GlyphZone zone,
FT_UShort point,
FT_F26Dot6 distance )
{
FT_UNUSED_EXEC;
zone->org[point].y += distance;
}
/*************************************************************************/
/* */
/* <Function> */
/* Round_None */
/*
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -