added FT_Sqrt64 to ensure that all bytecode operations are
strictly equivalent to the ones in FT 1.4 when compiling with the configuration macro FT_CONFIG_OPTION_OLD_CALCS defined..
This commit is contained in:
parent
a8bcdf8ef6
commit
271106133a
@ -35,6 +35,25 @@
|
||||
#include <ftobjs.h> /* for ABS() */
|
||||
|
||||
|
||||
#ifdef FT_CONFIG_OPTION_OLD_CALCS
|
||||
|
||||
static const FT_Long ft_square_roots[63] =
|
||||
{
|
||||
1, 1, 2, 3, 4, 5, 8, 11,
|
||||
16, 22, 32, 45, 64, 90, 128, 181,
|
||||
256, 362, 512, 724, 1024, 1448, 2048, 2896,
|
||||
4096, 5892, 8192, 11585, 16384, 23170, 32768, 46340,
|
||||
|
||||
65536, 92681, 131072, 185363, 262144, 370727,
|
||||
524288, 741455, 1048576, 1482910, 2097152, 2965820,
|
||||
4194304, 5931641, 8388608, 11863283, 16777216, 23726566,
|
||||
|
||||
33554432, 47453132, 67108864, 94906265,
|
||||
134217728, 189812531, 268435456, 379625062,
|
||||
536870912, 759250125, 1073741824, 1518500250,
|
||||
2147483647
|
||||
};
|
||||
#else
|
||||
/*************************************************************************/
|
||||
/* */
|
||||
/* <Function> */
|
||||
@ -50,7 +69,7 @@
|
||||
/* <Return> */
|
||||
/* The result of `sqrt(x)'. */
|
||||
/* */
|
||||
BASE_FUNC
|
||||
EXPORT_FUNC
|
||||
FT_Int32 FT_Sqrt32( FT_Int32 x )
|
||||
{
|
||||
FT_ULong val, root, newroot, mask;
|
||||
@ -76,7 +95,7 @@
|
||||
|
||||
return root;
|
||||
}
|
||||
|
||||
#endif /* OLD_CALCS */
|
||||
|
||||
#ifdef LONG64
|
||||
|
||||
@ -211,6 +230,60 @@
|
||||
}
|
||||
|
||||
|
||||
#ifdef FT_CONFIG_OPTION_OLD_CALCS
|
||||
/*************************************************************************/
|
||||
/* */
|
||||
/* <Function> */
|
||||
/* FT_Sqrt64 */
|
||||
/* */
|
||||
/* <Description> */
|
||||
/* Computes the square root of a 64-bits value ! Yeah, that sounds */
|
||||
/* stupid, but it's needed to obtain maximum accuracy in the */
|
||||
/* TrueType bytecode interpreter.. */
|
||||
/* */
|
||||
/* <Input> */
|
||||
/* l :: 64-bits integer */
|
||||
/* */
|
||||
/* <Return> */
|
||||
/* The 32-bit square-root. */
|
||||
/* */
|
||||
|
||||
static
|
||||
int ft_order64( FT_Int64 z )
|
||||
{
|
||||
int j = 0;
|
||||
|
||||
while ( z )
|
||||
{
|
||||
z = (unsigned INT64)z >> 1;
|
||||
j++;
|
||||
}
|
||||
return j - 1;
|
||||
}
|
||||
|
||||
|
||||
EXPORT_FUNC
|
||||
FT_Int32 FT_Sqrt64( FT_Int64 l )
|
||||
{
|
||||
FT_Int64 r, s;
|
||||
|
||||
if ( l <= 0 ) return 0;
|
||||
if ( l == 1 ) return 1;
|
||||
|
||||
r = ft_square_roots[ft_order64( l )];
|
||||
|
||||
do
|
||||
{
|
||||
s = r;
|
||||
r = ( r + l/r ) >> 1;
|
||||
}
|
||||
while ( r > s || r*r > l );
|
||||
|
||||
return r;
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
#else /* LONG64 */
|
||||
|
||||
|
||||
@ -437,7 +510,7 @@
|
||||
/* <Note> */
|
||||
/* Will be wrapped by the ADD_64() macro. */
|
||||
/* */
|
||||
BASE_FUNC
|
||||
EXPORT_FUNC
|
||||
void FT_Add64( FT_Int64* x,
|
||||
FT_Int64* y,
|
||||
FT_Int64* z )
|
||||
@ -470,7 +543,7 @@
|
||||
/* <Note> */
|
||||
/* Will be wrapped by the MUL_64() macro. */
|
||||
/* */
|
||||
BASE_FUNC
|
||||
EXPORT_FUNC
|
||||
void FT_MulTo64( FT_Int32 x,
|
||||
FT_Int32 y,
|
||||
FT_Int64* z )
|
||||
@ -536,7 +609,7 @@
|
||||
/* <Note> */
|
||||
/* Will be wrapped by the DIV_64() macro. */
|
||||
/* */
|
||||
BASE_FUNC
|
||||
EXPORT_FUNC
|
||||
FT_Int32 FT_Div64by32( FT_Int64* x,
|
||||
FT_Int32 y )
|
||||
{
|
||||
@ -585,6 +658,88 @@
|
||||
}
|
||||
|
||||
|
||||
#ifdef FT_CONFIG_OPTION_OLD_CALCS
|
||||
|
||||
static
|
||||
void FT_Sub64( FT_Int64* x, FT_Int64* y, FT_Int64* z )
|
||||
{
|
||||
register FT_Word32 lo, hi;
|
||||
|
||||
|
||||
lo = x->lo - y->lo;
|
||||
hi = x->hi - y->hi - ( (FT_Int32)lo < 0 );
|
||||
|
||||
z->lo = lo;
|
||||
z->hi = hi;
|
||||
}
|
||||
|
||||
/*************************************************************************/
|
||||
/* */
|
||||
/* <Function> */
|
||||
/* FT_Sqrt64 */
|
||||
/* */
|
||||
/* <Description> */
|
||||
/* Computes the square root of a 64-bits value ! Yeah, that sounds */
|
||||
/* stupid, but it's needed to obtain maximum accuracy in the */
|
||||
/* TrueType bytecode interpreter.. */
|
||||
/* */
|
||||
/* <Input> */
|
||||
/* z :: pointer to 64-bits integer */
|
||||
/* */
|
||||
/* <Return> */
|
||||
/* The 32-bit square-root. */
|
||||
/* */
|
||||
|
||||
static
|
||||
int ft_order64( FT_Int64* z )
|
||||
{
|
||||
FT_Word32 i;
|
||||
int j;
|
||||
|
||||
i = z->lo;
|
||||
j = 0;
|
||||
if ( z->hi )
|
||||
{
|
||||
i = z->hi;
|
||||
j = 32;
|
||||
}
|
||||
|
||||
while ( i > 0 )
|
||||
{
|
||||
i >>= 1;
|
||||
j++;
|
||||
}
|
||||
return j-1;
|
||||
}
|
||||
|
||||
EXPORT_FUNC
|
||||
FT_Int32 FT_Sqrt64( FT_Int64* l )
|
||||
{
|
||||
FT_Int64 l2;
|
||||
FT_Int32 r, s;
|
||||
|
||||
|
||||
if ( (FT_Int32)l->hi < 0 ||
|
||||
(l->hi == 0 && l->lo == 0) ) return 0;
|
||||
|
||||
s = ft_order64( l );
|
||||
if ( s == 0 ) return 1;
|
||||
|
||||
r = ft_square_roots[s];
|
||||
do
|
||||
{
|
||||
s = r;
|
||||
r = ( r + FT_Div64by32(l,r) ) >> 1;
|
||||
FT_MulTo64( r, r, &l2 );
|
||||
FT_Sub64 ( l, &l2, &l2 );
|
||||
}
|
||||
while ( r > s || (FT_Int32)l2.hi < 0 );
|
||||
|
||||
return r;
|
||||
}
|
||||
|
||||
#endif /* FT_CONFIG_OPTION_OLD_CALCS */
|
||||
|
||||
#endif /* LONG64 */
|
||||
|
||||
|
||||
|
@ -37,6 +37,15 @@
|
||||
|
||||
#define DIV_64( x, y ) ( (x) / (y) )
|
||||
|
||||
#ifdef FT_CONFIG_OPTION_OLD_CALCS
|
||||
|
||||
#define SQRT_64( z ) FT_Sqrt64( z )
|
||||
|
||||
EXPORT_DEF
|
||||
FT_Int32 FT_Sqrt64( FT_Int64 x );
|
||||
|
||||
#endif /* OLD_CALCS */
|
||||
|
||||
#else /* LONG64 */
|
||||
|
||||
typedef struct FT_Int64_
|
||||
@ -50,21 +59,34 @@
|
||||
#define MUL_64( x, y, z ) FT_MulTo64( x, y, &z )
|
||||
#define DIV_64( x, y ) FT_Div64by32( &x, y )
|
||||
|
||||
BASE_DEF
|
||||
EXPORT_DEF
|
||||
void FT_Add64 ( FT_Int64* x, FT_Int64* y, FT_Int64* z );
|
||||
BASE_DEF
|
||||
|
||||
EXPORT_DEF
|
||||
void FT_MulTo64 ( FT_Int32 x, FT_Int32 y, FT_Int64* z );
|
||||
BASE_DEF
|
||||
|
||||
EXPORT_DEF
|
||||
FT_Int32 FT_Div64by32( FT_Int64* x, FT_Int32 y );
|
||||
|
||||
#ifdef FT_CONFIG_OPTION_OLD_CALCS
|
||||
|
||||
#define SQRT_64( z ) FT_Sqrt64( &z )
|
||||
|
||||
EXPORT_DEF
|
||||
FT_Int32 FT_Sqrt64( FT_Int64* x );
|
||||
|
||||
#endif /* OLD_CALC */
|
||||
|
||||
#endif /* LONG64 */
|
||||
|
||||
|
||||
#ifndef FT_CONFIG_OPTION_OLD_CALCS
|
||||
|
||||
#define SQRT_32( x ) FT_Sqrt32( x )
|
||||
|
||||
BASE_DEF
|
||||
FT_Int32 FT_Sqrt32( FT_Int32 l );
|
||||
#endif
|
||||
|
||||
/*************************************************************************/
|
||||
/* */
|
||||
|
Loading…
Reference in New Issue
Block a user