[truetype] Scale F_dot_P down.
The dot product between freeVector and projVector or cosine of the angle between these FT_F2Dot14 unit vectors used to be scaled up by 4 and routinely occupied 32 bits in an FT_Long field F_dot_P. This patch scales the value down by 2^14 instead, which simplifies its use throughout the bytecode interpreter. This does not lead to the loss of precision because the lower bits are unreliable anyway. Consider two unit vectors (1,0) and (.6,.8) for which the true value of F_dot_P is .6 * 0x40000000 = 0x26666666. These vectors are stored as (0x4000,0) and (0x2666,0x3333) after rounding and F_dot_P is assigned 0x26660000. The lower bits were already lost while rounding the unit vector components. Besides code simplification, this change can lead to better performance when FT_MulDiv with the scaled-down F_dot_P is less likely to use the costly 64-bit path. We are not changing the type of F_dot_P to FT_F2Dot14 at this point. * src/truetype/ttinterp.c (Compute_Funcs): Scale F_dot_P down by 14 bits and modify its use accordingly. (Direct_Move, Direct_Move_Orig, Compute_Point_Displacement): Modify the use of F_dot_P field. * src/truetype/ttobjs.c (tt_size_run_fpgm): Change arbitrary assignment of F_dot_P to its theoretical maximum in case we decide to scale back its type later.
This commit is contained in:
parent
13e87e0426
commit
65d6572105
30
ChangeLog
30
ChangeLog
|
@ -1,3 +1,33 @@
|
|||
2012-12-10 Alexei Podtelezhnikov <apodtele@gmail.com>
|
||||
|
||||
[truetype] Scale F_dot_P down.
|
||||
|
||||
The dot product between freeVector and projVector or cosine of
|
||||
the angle between these FT_F2Dot14 unit vectors used to be scaled up
|
||||
by 4 and routinely occupied 32 bits in an FT_Long field F_dot_P.
|
||||
This patch scales the value down by 2^14 instead, which simplifies
|
||||
its use throughout the bytecode interpreter.
|
||||
|
||||
This does not lead to the loss of precision because the lower bits
|
||||
are unreliable anyway. Consider two unit vectors (1,0) and (.6,.8)
|
||||
for which the true value of F_dot_P is .6 * 0x40000000 = 0x26666666.
|
||||
These vectors are stored as (0x4000,0) and (0x2666,0x3333) after
|
||||
rounding and F_dot_P is assigned 0x26660000. The lower bits were
|
||||
already lost while rounding the unit vector components.
|
||||
|
||||
Besides code simplification, this change can lead to better
|
||||
performance when FT_MulDiv with the scaled-down F_dot_P is less
|
||||
likely to use the costly 64-bit path. We are not changing the type
|
||||
of F_dot_P to FT_F2Dot14 at this point.
|
||||
|
||||
* src/truetype/ttinterp.c (Compute_Funcs): Scale F_dot_P down by 14
|
||||
bits and modify its use accordingly.
|
||||
(Direct_Move, Direct_Move_Orig, Compute_Point_Displacement): Modify
|
||||
the use of F_dot_P field.
|
||||
* src/truetype/ttobjs.c (tt_size_run_fpgm): Change arbitrary
|
||||
assignment of F_dot_P to its theoretical maximum in case we decide
|
||||
to scale back its type later.
|
||||
|
||||
2012-12-09 Johnson Y. Yan <yinsen_yan@foxitsoftware.com>
|
||||
|
||||
[type1] Another fix for 2012-09-17 commit.
|
||||
|
|
|
@ -1861,9 +1861,7 @@
|
|||
if ( !CUR.ignore_x_mode ||
|
||||
( CUR.sph_tweak_flags & SPH_TWEAK_ALLOW_X_DMOVE ) )
|
||||
#endif /* TT_CONFIG_OPTION_SUBPIXEL_HINTING */
|
||||
zone->cur[point].x += FT_MulDiv( distance,
|
||||
v * 0x10000L,
|
||||
CUR.F_dot_P );
|
||||
zone->cur[point].x += FT_MulDiv( distance, v, CUR.F_dot_P );
|
||||
|
||||
zone->tags[point] |= FT_CURVE_TAG_TOUCH_X;
|
||||
}
|
||||
|
@ -1872,9 +1870,7 @@
|
|||
|
||||
if ( v != 0 )
|
||||
{
|
||||
zone->cur[point].y += FT_MulDiv( distance,
|
||||
v * 0x10000L,
|
||||
CUR.F_dot_P );
|
||||
zone->cur[point].y += FT_MulDiv( distance, v, CUR.F_dot_P );
|
||||
|
||||
zone->tags[point] |= FT_CURVE_TAG_TOUCH_Y;
|
||||
}
|
||||
|
@ -1913,16 +1909,12 @@
|
|||
v = CUR.GS.freeVector.x;
|
||||
|
||||
if ( v != 0 )
|
||||
zone->org[point].x += FT_MulDiv( distance,
|
||||
v * 0x10000L,
|
||||
CUR.F_dot_P );
|
||||
zone->org[point].x += FT_MulDiv( distance, v, CUR.F_dot_P );
|
||||
|
||||
v = CUR.GS.freeVector.y;
|
||||
|
||||
if ( v != 0 )
|
||||
zone->org[point].y += FT_MulDiv( distance,
|
||||
v * 0x10000L,
|
||||
CUR.F_dot_P );
|
||||
zone->org[point].y += FT_MulDiv( distance, v, CUR.F_dot_P );
|
||||
}
|
||||
|
||||
|
||||
|
@ -2646,12 +2638,13 @@
|
|||
#endif /* TT_CONFIG_OPTION_UNPATENTED_HINTING */
|
||||
|
||||
if ( CUR.GS.freeVector.x == 0x4000 )
|
||||
CUR.F_dot_P = CUR.GS.projVector.x * 0x10000L;
|
||||
CUR.F_dot_P = CUR.GS.projVector.x;
|
||||
else if ( CUR.GS.freeVector.y == 0x4000 )
|
||||
CUR.F_dot_P = CUR.GS.projVector.y * 0x10000L;
|
||||
CUR.F_dot_P = CUR.GS.projVector.y;
|
||||
else
|
||||
CUR.F_dot_P = (FT_Long)CUR.GS.projVector.x * CUR.GS.freeVector.x * 4 +
|
||||
(FT_Long)CUR.GS.projVector.y * CUR.GS.freeVector.y * 4;
|
||||
CUR.F_dot_P = ( (FT_Long)CUR.GS.projVector.x * CUR.GS.freeVector.x +
|
||||
(FT_Long)CUR.GS.projVector.y * CUR.GS.freeVector.y ) >>
|
||||
14;
|
||||
|
||||
if ( CUR.GS.projVector.x == 0x4000 )
|
||||
CUR.func_project = (TT_Project_Func)Project_x;
|
||||
|
@ -2670,7 +2663,7 @@
|
|||
CUR.func_move = (TT_Move_Func)Direct_Move;
|
||||
CUR.func_move_orig = (TT_Move_Func)Direct_Move_Orig;
|
||||
|
||||
if ( CUR.F_dot_P == 0x40000000L )
|
||||
if ( CUR.F_dot_P == 0x4000L )
|
||||
{
|
||||
if ( CUR.GS.freeVector.x == 0x4000 )
|
||||
{
|
||||
|
@ -2687,8 +2680,8 @@
|
|||
/* at small sizes, F_dot_P can become too small, resulting */
|
||||
/* in overflows and `spikes' in a number of glyphs like `w'. */
|
||||
|
||||
if ( FT_ABS( CUR.F_dot_P ) < 0x4000000L )
|
||||
CUR.F_dot_P = 0x40000000L;
|
||||
if ( FT_ABS( CUR.F_dot_P ) < 0x400L )
|
||||
CUR.F_dot_P = 0x4000L;
|
||||
|
||||
/* Disable cached aspect ratio */
|
||||
CUR.tt_metrics.ratio = 0;
|
||||
|
@ -5827,12 +5820,8 @@
|
|||
else
|
||||
#endif
|
||||
{
|
||||
*x = FT_MulDiv( d,
|
||||
(FT_Long)CUR.GS.freeVector.x * 0x10000L,
|
||||
CUR.F_dot_P );
|
||||
*y = FT_MulDiv( d,
|
||||
(FT_Long)CUR.GS.freeVector.y * 0x10000L,
|
||||
CUR.F_dot_P );
|
||||
*x = FT_MulDiv( d, (FT_Long)CUR.GS.freeVector.x, CUR.F_dot_P );
|
||||
*y = FT_MulDiv( d, (FT_Long)CUR.GS.freeVector.y, CUR.F_dot_P );
|
||||
}
|
||||
|
||||
return SUCCESS;
|
||||
|
|
|
@ -764,7 +764,7 @@
|
|||
exec->threshold = 0;
|
||||
|
||||
exec->instruction_trap = FALSE;
|
||||
exec->F_dot_P = 0x10000L;
|
||||
exec->F_dot_P = 0x4000L;
|
||||
|
||||
exec->pedantic_hinting = pedantic;
|
||||
|
||||
|
|
Loading…
Reference in New Issue