[truetype] Kill very old vector normalization hacks.

Back in the days, vector length calculations were not very accurate
and the vector normalization function, Normalize, had to meticulously
correct the errors for long vectors [commit b7ef2b0968]. It was no
longer necessary after accurate CORDIC algorithms were adopted, but
the code remained. It is time to kill it.

* src/truetype/ttinterp.c (Normalize): Remove error compensation.
(TT_VecLen): Remove any mention of old less accurate implementation.
This commit is contained in:
Alexei Podtelezhnikov 2013-01-12 22:36:37 -05:00
parent a692170a23
commit 081aba390a
2 changed files with 16 additions and 141 deletions

View File

@ -1,3 +1,16 @@
2013-01-12 Alexei Podtelezhnikov <apodtele@gmail.com>
[truetype] Kill very old vector normalization hacks.
Back in the days, vector length calculations were not very accurate
and the vector normalization function, Normalize, had to meticulously
correct the errors for long vectors [commit b7ef2b096867]. It was no
longer necessary after accurate CORDIC algorithms were adopted, but
the code remained. It is time to kill it.
* src/truetype/ttinterp.c (Normalize): Remove error compensation.
(TT_VecLen): Remove any mention of old less accurate implementation.
2013-01-11 Werner Lemberg <wl@gnu.org>
Disable FT_CONFIG_OPTION_OLD_INTERNALS.

View File

@ -1543,79 +1543,6 @@
/* return length of given vector */
#if 0
static FT_Int32
TT_VecLen( FT_Int32 x,
FT_Int32 y )
{
FT_Int32 m, hi1, hi2, hi;
FT_UInt32 l, lo1, lo2, lo;
/* compute x*x as 64-bit value */
lo = (FT_UInt32)( x & 0xFFFFU );
hi = x >> 16;
l = lo * lo;
m = hi * lo;
hi = hi * hi;
lo1 = l + (FT_UInt32)( m << 17 );
hi1 = hi + ( m >> 15 ) + ( lo1 < l );
/* compute y*y as 64-bit value */
lo = (FT_UInt32)( y & 0xFFFFU );
hi = y >> 16;
l = lo * lo;
m = hi * lo;
hi = hi * hi;
lo2 = l + (FT_UInt32)( m << 17 );
hi2 = hi + ( m >> 15 ) + ( lo2 < l );
/* add them to get 'x*x+y*y' as 64-bit value */
lo = lo1 + lo2;
hi = hi1 + hi2 + ( lo < lo1 );
/* compute the square root of this value */
{
FT_UInt32 root, rem, test_div;
FT_Int count;
root = 0;
{
rem = 0;
count = 32;
do
{
rem = ( rem << 2 ) | ( (FT_UInt32)hi >> 30 );
hi = ( hi << 2 ) | ( lo >> 30 );
lo <<= 2;
root <<= 1;
test_div = ( root << 1 ) + 1;
if ( rem >= test_div )
{
rem -= test_div;
root += 1;
}
} while ( --count );
}
return (FT_Int32)root;
}
}
#else
/* this version uses FT_Vector_Length which computes the same value */
/* much, much faster.. */
/* */
static FT_F26Dot6
TT_VecLen( FT_F26Dot6 X,
FT_F26Dot6 Y )
@ -1629,8 +1556,6 @@
return FT_Vector_Length( &v );
}
#endif
/*************************************************************************/
/* */
@ -2718,7 +2643,6 @@
FT_UnitVector* R )
{
FT_F26Dot6 W;
FT_Bool S1, S2;
FT_UNUSED_EXEC;
@ -2728,80 +2652,18 @@
Vx *= 0x100;
Vy *= 0x100;
W = TT_VecLen( Vx, Vy );
if ( W == 0 )
if ( Vx == 0 && Vy == 0 )
{
/* XXX: UNDOCUMENTED! It seems that it is possible to try */
/* to normalize the vector (0,0). Return immediately. */
return SUCCESS;
}
R->x = (FT_F2Dot14)TT_DivFix14( Vx, W );
R->y = (FT_F2Dot14)TT_DivFix14( Vy, W );
return SUCCESS;
}
W = TT_VecLen( Vx, Vy );
Vx = TT_DivFix14( Vx, W );
Vy = TT_DivFix14( Vy, W );
W = Vx * Vx + Vy * Vy;
/* Now, we want that Sqrt( W ) = 0x4000 */
/* Or 0x10000000 <= W < 0x10004000 */
if ( Vx < 0 )
{
Vx = -Vx;
S1 = TRUE;
}
else
S1 = FALSE;
if ( Vy < 0 )
{
Vy = -Vy;
S2 = TRUE;
}
else
S2 = FALSE;
while ( W < 0x10000000L )
{
/* We need to increase W by a minimal amount */
if ( Vx < Vy )
Vx++;
else
Vy++;
W = Vx * Vx + Vy * Vy;
}
while ( W >= 0x10004000L )
{
/* 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 = (FT_F2Dot14)Vx; /* Type conversion */
R->y = (FT_F2Dot14)Vy; /* Type conversion */
R->x = (FT_F2Dot14)TT_DivFix14( Vx, W );
R->y = (FT_F2Dot14)TT_DivFix14( Vy, W );
return SUCCESS;
}