Alexei Podtelezhnikov pushed to branch master at FreeType / FreeType
Commits:
-
95b0fe2a
by Alexei Podtelezhnikov at 2023-09-19T22:26:32-04:00
-
c4073d82
by Alexei Podtelezhnikov at 2023-09-19T22:29:14-04:00
4 changed files:
Changes:
... | ... | @@ -489,8 +489,6 @@ FT_BEGIN_HEADER |
489 | 489 | FT_Fixed y );
|
490 | 490 | |
491 | 491 | |
492 | -#if 0
|
|
493 | - |
|
494 | 492 | /**************************************************************************
|
495 | 493 | *
|
496 | 494 | * @function:
|
... | ... | @@ -507,13 +505,12 @@ FT_BEGIN_HEADER |
507 | 505 | * The result of 'sqrt(x)'.
|
508 | 506 | *
|
509 | 507 | * @note:
|
510 | - * This function is not very fast.
|
|
508 | + * This function is slow and should be avoided. Consider `FT_Hypot` or
|
|
509 | + * `FT_Vector_NormLen' instead.
|
|
511 | 510 | */
|
512 | 511 | FT_BASE( FT_UInt32 )
|
513 | 512 | FT_SqrtFixed( FT_UInt32 x );
|
514 | 513 | |
515 | -#endif /* 0 */
|
|
516 | - |
|
517 | 514 | |
518 | 515 | #define INT_TO_F26DOT6( x ) ( (FT_Long)(x) * 64 ) /* << 6 */
|
519 | 516 | #define INT_TO_F2DOT14( x ) ( (FT_Long)(x) * 16384 ) /* << 14 */
|
... | ... | @@ -913,38 +913,71 @@ |
913 | 913 | }
|
914 | 914 | |
915 | 915 | |
916 | -#if 0
|
|
917 | - |
|
918 | 916 | /* documentation is in ftcalc.h */
|
919 | 917 | |
920 | - /* Algorithm and code by Christophe Meessen (1993) */
|
|
921 | - /* with overflow fixed. */
|
|
922 | 918 | FT_BASE_DEF( FT_UInt32 )
|
923 | 919 | FT_SqrtFixed( FT_UInt32 v )
|
924 | 920 | {
|
925 | - FT_UInt32 r = v >> 1;
|
|
926 | - FT_UInt32 q = ( v & 1 ) << 15;
|
|
927 | - FT_UInt32 b = 0x20000000;
|
|
928 | - FT_UInt32 t;
|
|
921 | + if ( v == 0 )
|
|
922 | + return 0;
|
|
929 | 923 | |
924 | +#ifndef FT_INT64
|
|
930 | 925 | |
931 | - do
|
|
926 | + /* Algorithm by Christophe Meessen (1993) with overflow fixed and */
|
|
927 | + /* rounding added. Any unsigned fixed 16.16 argument is acceptable. */
|
|
928 | + /* However, this algorithm is slower than the Babylonian method with */
|
|
929 | + /* a good initial guess. We only use it for large 32-bit values when */
|
|
930 | + /* 64-bit computations are not desirable. */
|
|
931 | + else if ( v > 0x10000U )
|
|
932 | 932 | {
|
933 | - t = q + b;
|
|
934 | - if ( r >= t )
|
|
933 | + FT_UInt32 r = v >> 1;
|
|
934 | + FT_UInt32 q = ( v & 1 ) << 15;
|
|
935 | + FT_UInt32 b = 0x20000000;
|
|
936 | + FT_UInt32 t;
|
|
937 | + |
|
938 | + |
|
939 | + do
|
|
935 | 940 | {
|
936 | - r -= t;
|
|
937 | - q = t + b; /* equivalent to q += 2*b */
|
|
941 | + t = q + b;
|
|
942 | + if ( r >= t )
|
|
943 | + {
|
|
944 | + r -= t;
|
|
945 | + q = t + b; /* equivalent to q += 2*b */
|
|
946 | + }
|
|
947 | + r <<= 1;
|
|
948 | + b >>= 1;
|
|
938 | 949 | }
|
939 | - r <<= 1;
|
|
940 | - b >>= 1;
|
|
950 | + while ( b > 0x10 ); /* exactly 25 cycles */
|
|
951 | + |
|
952 | + return ( q + 0x40 ) >> 7;
|
|
941 | 953 | }
|
942 | - while ( b > 0x20 );
|
|
954 | + else
|
|
955 | + {
|
|
956 | + FT_UInt32 r = ( v << 16 ) - 1;
|
|
943 | 957 | |
944 | - return q >> 7;
|
|
945 | - }
|
|
958 | +#else /* FT_INT64 */
|
|
946 | 959 | |
947 | -#endif /* 0 */
|
|
960 | + else
|
|
961 | + {
|
|
962 | + FT_UInt64 r = ( (FT_UInt64)v << 16 ) - 1;
|
|
963 | + |
|
964 | +#endif /* FT_INT64 */
|
|
965 | + |
|
966 | + FT_UInt32 q = 1 << ( ( 17 + FT_MSB( v ) ) >> 1 );
|
|
967 | + FT_UInt32 t;
|
|
968 | + |
|
969 | + |
|
970 | + /* Babylonian method with rounded-up division */
|
|
971 | + do
|
|
972 | + {
|
|
973 | + t = q;
|
|
974 | + q = ( t + (FT_UInt32)( r / t ) + 1 ) >> 1;
|
|
975 | + }
|
|
976 | + while ( q != t ); /* less than 6 cycles */
|
|
977 | + |
|
978 | + return q;
|
|
979 | + }
|
|
980 | + }
|
|
948 | 981 | |
949 | 982 | |
950 | 983 | /* documentation is in ftcalc.h */
|
... | ... | @@ -1753,22 +1753,9 @@ |
1753 | 1753 | |
1754 | 1754 | /* without upper limit the loop below might not finish */
|
1755 | 1755 | if ( args[0] > 0x7FFFFFFFL )
|
1756 | - args[0] = 0xB504F3L; /* sqrt( 32768.0 ) */
|
|
1756 | + args[0] = 0xB504F4L; /* sqrt( 32768.0044 ) */
|
|
1757 | 1757 | else if ( args[0] > 0 )
|
1758 | - {
|
|
1759 | - FT_Fixed root = 1 << ( ( 17 + FT_MSB( args[0] ) ) >> 1 );
|
|
1760 | - FT_Fixed new_root;
|
|
1761 | - |
|
1762 | - |
|
1763 | - for (;;)
|
|
1764 | - {
|
|
1765 | - new_root = ( root + FT_DivFix( args[0], root ) + 1 ) >> 1;
|
|
1766 | - if ( new_root == root )
|
|
1767 | - break;
|
|
1768 | - root = new_root;
|
|
1769 | - }
|
|
1770 | - args[0] = new_root;
|
|
1771 | - }
|
|
1758 | + args[0] = (FT_Fixed)FT_SqrtFixed( args[0] );
|
|
1772 | 1759 | else
|
1773 | 1760 | args[0] = 0;
|
1774 | 1761 | args++;
|
... | ... | @@ -2276,22 +2276,7 @@ |
2276 | 2276 | |
2277 | 2277 | arg = cf2_stack_popFixed( opStack );
|
2278 | 2278 | if ( arg > 0 )
|
2279 | - {
|
|
2280 | - /* initial guess based on the most significant bit */
|
|
2281 | - FT_Fixed root = 1 << ( ( 17 + FT_MSB( arg ) ) >> 1 );
|
|
2282 | - FT_Fixed new_root;
|
|
2283 | - |
|
2284 | - |
|
2285 | - /* Babylonian method */
|
|
2286 | - for (;;)
|
|
2287 | - {
|
|
2288 | - new_root = ( root + FT_DivFix( arg, root ) + 1 ) >> 1;
|
|
2289 | - if ( new_root == root )
|
|
2290 | - break;
|
|
2291 | - root = new_root;
|
|
2292 | - }
|
|
2293 | - arg = new_root;
|
|
2294 | - }
|
|
2279 | + arg = (CF2_F16Dot16)FT_SqrtFixed( arg );
|
|
2295 | 2280 | else
|
2296 | 2281 | arg = 0;
|
2297 | 2282 |