diff --git a/ChangeLog b/ChangeLog index 069fe4fb5..78dd95e71 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,11 @@ +2014-10-29 Alexei Podtelezhnikov + + 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 [cff] Test valid darkening parameter macros in `ftoption.h'. diff --git a/include/internal/ftcalc.h b/include/internal/ftcalc.h index 1d83d50bd..d4023fa5b 100644 --- a/include/internal/ftcalc.h +++ b/include/internal/ftcalc.h @@ -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 /*************************************************************************/ diff --git a/include/internal/ftobjs.h b/include/internal/ftobjs.h index faa37f8f5..b45a5ed81 100644 --- a/include/internal/ftobjs.h +++ b/include/internal/ftobjs.h @@ -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 ) diff --git a/src/smooth/ftgrays.c b/src/smooth/ftgrays.c index 27be96679..94c546256 100644 --- a/src/smooth/ftgrays.c +++ b/src/smooth/ftgrays.c @@ -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 )