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:
David Turner 2000-05-02 10:52:28 +00:00
parent a8bcdf8ef6
commit 271106133a
2 changed files with 185 additions and 8 deletions

View File

@ -35,6 +35,25 @@
#include <ftobjs.h> /* for ABS() */ #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> */ /* <Function> */
@ -50,7 +69,7 @@
/* <Return> */ /* <Return> */
/* The result of `sqrt(x)'. */ /* The result of `sqrt(x)'. */
/* */ /* */
BASE_FUNC EXPORT_FUNC
FT_Int32 FT_Sqrt32( FT_Int32 x ) FT_Int32 FT_Sqrt32( FT_Int32 x )
{ {
FT_ULong val, root, newroot, mask; FT_ULong val, root, newroot, mask;
@ -76,7 +95,7 @@
return root; return root;
} }
#endif /* OLD_CALCS */
#ifdef LONG64 #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 */ #else /* LONG64 */
@ -437,7 +510,7 @@
/* <Note> */ /* <Note> */
/* Will be wrapped by the ADD_64() macro. */ /* Will be wrapped by the ADD_64() macro. */
/* */ /* */
BASE_FUNC EXPORT_FUNC
void FT_Add64( FT_Int64* x, void FT_Add64( FT_Int64* x,
FT_Int64* y, FT_Int64* y,
FT_Int64* z ) FT_Int64* z )
@ -470,7 +543,7 @@
/* <Note> */ /* <Note> */
/* Will be wrapped by the MUL_64() macro. */ /* Will be wrapped by the MUL_64() macro. */
/* */ /* */
BASE_FUNC EXPORT_FUNC
void FT_MulTo64( FT_Int32 x, void FT_MulTo64( FT_Int32 x,
FT_Int32 y, FT_Int32 y,
FT_Int64* z ) FT_Int64* z )
@ -536,7 +609,7 @@
/* <Note> */ /* <Note> */
/* Will be wrapped by the DIV_64() macro. */ /* Will be wrapped by the DIV_64() macro. */
/* */ /* */
BASE_FUNC EXPORT_FUNC
FT_Int32 FT_Div64by32( FT_Int64* x, FT_Int32 FT_Div64by32( FT_Int64* x,
FT_Int32 y ) 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 */ #endif /* LONG64 */

View File

@ -37,6 +37,15 @@
#define DIV_64( x, y ) ( (x) / (y) ) #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 */ #else /* LONG64 */
typedef struct FT_Int64_ typedef struct FT_Int64_
@ -50,21 +59,34 @@
#define MUL_64( x, y, z ) FT_MulTo64( x, y, &z ) #define MUL_64( x, y, z ) FT_MulTo64( x, y, &z )
#define DIV_64( x, y ) FT_Div64by32( &x, y ) #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 ); 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 ); 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 ); 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 */ #endif /* LONG64 */
#ifndef FT_CONFIG_OPTION_OLD_CALCS
#define SQRT_32( x ) FT_Sqrt32( x ) #define SQRT_32( x ) FT_Sqrt32( x )
BASE_DEF BASE_DEF
FT_Int32 FT_Sqrt32( FT_Int32 l ); FT_Int32 FT_Sqrt32( FT_Int32 l );
#endif
/*************************************************************************/ /*************************************************************************/
/* */ /* */