diff --git a/ChangeLog b/ChangeLog index 6ac14e0f7..7f4ec4841 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,12 @@ +2014-10-25 Alexei Podtelezhnikov + + Improve flat corner definition. + + * include/internal/ftcalc.h (FT_HYPOT): Macro to approximate Euclidean + distance with the alpha max plus beta min algorithm. + * src/base/ftcalc.c (ft_corner_is_flat): Use it instead of Taxicab + metric. + 2014-10-23 David Weiß [build] Improve property file for vc2010. diff --git a/include/internal/ftcalc.h b/include/internal/ftcalc.h index 8b3bd7f37..e6bee341f 100644 --- a/include/internal/ftcalc.h +++ b/include/internal/ftcalc.h @@ -311,10 +311,11 @@ FT_BEGIN_HEADER FT_Pos out_x, FT_Pos out_y ); + /* * Return TRUE if a corner is flat or nearly flat. This is equivalent to - * saying that the angle difference between the `in' and `out' vectors is - * very small. + * 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 ) ft_corner_is_flat( FT_Pos in_x, @@ -361,6 +362,15 @@ FT_BEGIN_HEADER FT_Fixed y ); + /* + * Approximate sqrt(x*x+y*y) using alpha max plus beta min algorithm. + */ +#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/src/base/ftcalc.c b/src/base/ftcalc.c index d0c43e02c..23c43a779 100644 --- a/src/base/ftcalc.c +++ b/src/base/ftcalc.c @@ -858,6 +858,8 @@ FT_Pos out_x, FT_Pos out_y ) { +#if 0 + FT_Pos ax = in_x; FT_Pos ay = in_y; @@ -902,6 +904,27 @@ ay = -ay; d_corner = ax + ay; /* d_corner = || in + out || */ +#else + + FT_Pos ax = in_x + out_x; + FT_Pos ay = in_y + out_y; + + FT_Pos d_in, d_out, d_corner; + + /* The original implementation always returned TRUE */ + /* for vectors from the same quadrant dues to additivity */ + /* of Taxicab metric there. The alpha max plus beta min */ + /* algorithm used here is additive within each octant, */ + /* so we now reject some near 90-degree corners within */ + /* quadrants, consistently with eliptic definition of */ + /* flat corner. */ + + d_in = FT_HYPOT( in_x, in_y ); + d_out = FT_HYPOT( out_x, out_y ); + d_corner = FT_HYPOT( ax, ay ); + +#endif + /* now do a simple length comparison: */ /* */ /* d_in + d_out < 17/16 d_corner */