Unify hypotenuse approximations.

* include/internal/ftcalc.h (FT_HYPOT): Move macro from here...
* include/internal/ftobjs.h: ... to here, next to required `FT_ABS'.
* src/smooth/ftgrays.c (gray_render_cubic): Use it here.
This commit is contained in:
Alexei Podtelezhnikov 2014-10-29 22:24:24 -04:00
parent d8632a842e
commit 74916997de
4 changed files with 22 additions and 43 deletions

View File

@ -1,3 +1,11 @@
2014-10-29 Alexei Podtelezhnikov <apodtele@gmail.com>
Unify hypotenuse approximations.
* include/internal/ftcalc.h (FT_HYPOT): Move macro from here...
* include/internal/ftobjs.h: ... to here, next to required `FT_ABS'.
* src/smooth/ftgrays.c (gray_render_cubic): Use it here.
2014-10-25 Werner Lemberg <wl@gnu.org>
[cff] Test valid darkening parameter macros in `ftoption.h'.

View File

@ -314,7 +314,7 @@ FT_BEGIN_HEADER
/*
* Return TRUE if a corner is flat or nearly flat. This is equivalent to
* saying that the corner point is close to its neighbors, or inside an
* saying that the corner point is close to its neighbors, or inside an
* ellipse defined by the neighbor focal points to be more precise.
*/
FT_BASE( FT_Int )
@ -362,18 +362,6 @@ FT_BEGIN_HEADER
FT_Fixed y );
/*
* Approximate sqrt(x*x+y*y) using the `alpha max plus beta min'
* algorithm. We use alpha = 1, beta = 3/8, giving us results with a
* largest error less than 7% compared to the exact value.
*/
#define FT_HYPOT( x, y ) \
( x = FT_ABS( x ), \
y = FT_ABS( y ), \
x > y ? x + ( 3 * y >> 3 ) \
: y + ( 3 * x >> 3 ) )
#if 0
/*************************************************************************/

View File

@ -72,6 +72,16 @@ FT_BEGIN_HEADER
#define FT_ABS( a ) ( (a) < 0 ? -(a) : (a) )
/*
* Approximate sqrt(x*x+y*y) using the `alpha max plus beta min'
* algorithm. We use alpha = 1, beta = 3/8, giving us results with a
* largest error less than 7% compared to the exact value.
*/
#define FT_HYPOT( x, y ) \
( x = FT_ABS( x ), \
y = FT_ABS( y ), \
x > y ? x + ( 3 * y >> 3 ) \
: y + ( 3 * x >> 3 ) )
#define FT_PAD_FLOOR( x, n ) ( (x) & ~((n)-1) )
#define FT_PAD_ROUND( x, n ) FT_PAD_FLOOR( (x) + ((n)/2), n )

View File

@ -1091,37 +1091,10 @@ typedef ptrdiff_t FT_PtrDist;
/* dx and dy are x and y components of the P0-P3 chord vector. */
dx = arc[3].x - arc[0].x;
dy = arc[3].y - arc[0].y;
dx = dx_ = arc[3].x - arc[0].x;
dy = dy_ = arc[3].y - arc[0].y;
/* L is an (under)estimate of the Euclidean distance P0-P3. */
/* */
/* If dx >= dy, then r = sqrt(dx^2 + dy^2) can be overestimated */
/* with least maximum error by */
/* */
/* r_upperbound = dx + (sqrt(2) - 1) * dy , */
/* */
/* where sqrt(2) - 1 can be (over)estimated by 107/256, giving an */
/* error of no more than 8.4%. */
/* */
/* Similarly, some elementary calculus shows that r can be */
/* underestimated with least maximum error by */
/* */
/* r_lowerbound = sqrt(2 + sqrt(2)) / 2 * dx */
/* + sqrt(2 - sqrt(2)) / 2 * dy . */
/* */
/* 236/256 and 97/256 are (under)estimates of the two algebraic */
/* numbers, giving an error of no more than 8.1%. */
dx_ = FT_ABS( dx );
dy_ = FT_ABS( dy );
/* This is the same as */
/* */
/* L = ( 236 * FT_MAX( dx_, dy_ ) */
/* + 97 * FT_MIN( dx_, dy_ ) ) >> 8; */
L = ( dx_ > dy_ ? 236 * dx_ + 97 * dy_
: 97 * dx_ + 236 * dy_ ) >> 8;
L = FT_HYPOT( dx_, dy_ );
/* Avoid possible arithmetic overflow below by splitting. */
if ( L > 32767 )