diff --git a/include/freetype/internal/ftcalc.h b/include/freetype/internal/ftcalc.h index e0e5c5588..fc1e3f965 100644 --- a/include/freetype/internal/ftcalc.h +++ b/include/freetype/internal/ftcalc.h @@ -110,6 +110,28 @@ FT_BEGIN_HEADER #endif /* TT_USE_BYTECODE_INTERPRETER */ + /* + * Return -1, 0, or +1, depending on the orientation of a given corner. + * We use the Cartesian coordinate system, with positive vertical values + * going upwards. The function returns +1 when the corner turns to the + * left, -1 to the right, and 0 for undecided. + */ + FT_BASE( FT_Int ) + ft_corner_orientation( FT_Pos in_x, + FT_Pos in_y, + 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. + */ + FT_BASE( FT_Int ) + ft_corner_is_flat( FT_Pos in_x, + FT_Pos in_y, + FT_Pos out_x, + FT_Pos out_y ); #define INT_TO_F26DOT6( x ) ( (FT_Long)(x) << 6 ) #define INT_TO_F2DOT14( x ) ( (FT_Long)(x) << 14 ) diff --git a/src/autofit/afangles.c b/src/autofit/afangles.c index d7841d3af..fac6dc3d0 100644 --- a/src/autofit/afangles.c +++ b/src/autofit/afangles.c @@ -19,7 +19,7 @@ #include "aftypes.h" - +#if 0 FT_LOCAL_DEF( FT_Int ) af_corner_is_flat( FT_Pos x_in, FT_Pos y_in, @@ -74,7 +74,7 @@ else return 1 - 2 * ( delta < 0 ); } - +#endif /* * We are not using `af_angle_atan' anymore, but we keep the source diff --git a/src/autofit/afhints.c b/src/autofit/afhints.c index 4539590a5..043ca181a 100644 --- a/src/autofit/afhints.c +++ b/src/autofit/afhints.c @@ -18,7 +18,7 @@ #include "afhints.h" #include "aferrors.h" - +#include FT_INTERNAL_CALC_H FT_LOCAL_DEF( FT_Error ) af_axis_hints_new_segment( AF_AxisHints axis, @@ -401,7 +401,7 @@ } while ( out_x == 0 && out_y == 0 ); - orient_prev = af_corner_orientation( in_x, in_y, out_x, out_y ); + orient_prev = ft_corner_orientation( in_x, in_y, out_x, out_y ); } while ( orient_prev == 0 ); @@ -429,7 +429,7 @@ } while ( out_x == 0 && out_y == 0 ); - orient_cur = af_corner_orientation( in_x, in_y, out_x, out_y ); + orient_cur = ft_corner_orientation( in_x, in_y, out_x, out_y ); } while ( orient_cur == 0 ); @@ -824,7 +824,7 @@ if ( point->out_dir != AF_DIR_NONE ) goto Is_Weak_Point; - if ( af_corner_is_flat( in_x, in_y, out_x, out_y ) ) + if ( ft_corner_is_flat( in_x, in_y, out_x, out_y ) ) goto Is_Weak_Point; #else /* old code */ diff --git a/src/autofit/afmodule.c b/src/autofit/afmodule.c index 892fb2a09..2d2f1a473 100644 --- a/src/autofit/afmodule.c +++ b/src/autofit/afmodule.c @@ -20,6 +20,7 @@ #include "afloader.h" #ifdef AF_DEBUG + int _af_debug; int _af_debug_disable_horz_hints; int _af_debug_disable_vert_hints; int _af_debug_disable_blue_hints; diff --git a/src/autofit/aftypes.h b/src/autofit/aftypes.h index 8f2170932..8ece3eab0 100644 --- a/src/autofit/aftypes.h +++ b/src/autofit/aftypes.h @@ -54,13 +54,14 @@ FT_BEGIN_HEADER /*************************************************************************/ #define xxAF_USE_WARPER /* only define to use warp hinting */ -#define xxAF_DEBUG +#define AF_DEBUG #ifdef AF_DEBUG # include -# define AF_LOG( x ) printf x +# define AF_LOG( x ) do { if (_af_debug) printf x ; } while (0) +extern int _af_debug; extern int _af_debug_disable_horz_hints; extern int _af_debug_disable_vert_hints; extern int _af_debug_disable_blue_hints; @@ -141,30 +142,6 @@ extern void* _af_debug_hints; #endif /* 0 */ - /* - * 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. - */ - FT_LOCAL( FT_Int ) - af_corner_is_flat( FT_Pos x_in, - FT_Pos y_in, - FT_Pos x_out, - FT_Pos y_out ); - - /* - * Return -1, 0, or +1, depending on the orientation of a given corner. - * We use the Cartesian coordinate system, with positive vertical values - * going upwards. The function returns +1 when the corner turns to the - * left, -1 to the right, and 0 for undecided. - */ - FT_LOCAL( FT_Int ) - af_corner_orientation( FT_Pos x_in, - FT_Pos y_in, - FT_Pos x_out, - FT_Pos y_out ); - - #define AF_ANGLE_DIFF( result, angle1, angle2 ) \ FT_BEGIN_STMNT \ AF_Angle _delta = (angle2) - (angle1); \ diff --git a/src/base/ftcalc.c b/src/base/ftcalc.c index 7cae98812..8795ea160 100644 --- a/src/base/ftcalc.c +++ b/src/base/ftcalc.c @@ -302,12 +302,11 @@ FT_Int64* y, FT_Int64 *z ) { - register FT_UInt32 lo, hi, max; + register FT_UInt32 lo, hi; - max = x->lo > y->lo ? x->lo : y->lo; lo = x->lo + y->lo; - hi = x->hi + y->hi + ( lo < max ); + hi = x->hi + y->hi + ( lo < x->lo ); z->lo = lo; z->hi = hi; @@ -685,4 +684,111 @@ } + + FT_BASE_DEF( FT_Int ) + ft_corner_orientation( FT_Pos in_x, + FT_Pos in_y, + FT_Pos out_x, + FT_Pos out_y ) + { + FT_Int result; + + + /* deal with the trivial cases quickly */ + if ( in_y == 0 ) + { + if ( in_x >= 0 ) + result = out_y; + else + result = -out_y; + } + else if ( in_x == 0 ) + { + if ( in_y >= 0 ) + result = -out_x; + else + result = out_x; + } + else if ( out_y == 0 ) + { + if ( out_x >= 0 ) + result = in_y; + else + result = -in_y; + } + else if ( out_x == 0 ) + { + if ( out_y >= 0 ) + result = -in_x; + else + result = in_x; + } + else /* general case */ + { +#ifdef FT_LONG64 + FT_Int64 delta = (long long)in_x * out_y - (long long)in_y * out_x; + + if ( delta == 0 ) + result = 0; + else + result = 1 - 2 * ( delta < 0 ); +#else + FT_Int64 z1, z2; + + ft_multo64( in_x, out_y, &z1 ); + ft_multo64( in_y, out_x, &z2 ); + + if ( z1.hi > z2.hi ) + result = +1; + else if ( z1.hi < z2.hi ) + result = -1; + else if ( z1.lo > z2.lo ) + result = +1; + else if ( z1.lo < z2.lo ) + result = -1; + else + result = 0; +#endif + } + + return result; + } + + + FT_BASE_DEF( FT_Int ) + ft_corner_is_flat( FT_Pos in_x, + FT_Pos in_y, + FT_Pos out_x, + FT_Pos out_y ) + { + FT_Pos ax = in_x; + FT_Pos ay = in_y; + + FT_Pos d_in, d_out, d_corner; + + + if ( ax < 0 ) + ax = -ax; + if ( ay < 0 ) + ay = -ay; + d_in = ax + ay; + + ax = out_x; + if ( ax < 0 ) + ax = -ax; + ay = out_y; + if ( ay < 0 ) + ay = -ay; + d_out = ax + ay; + + ax = out_x + in_x; + if ( ax < 0 ) + ax = -ax; + ay = out_y + in_y; + if ( ay < 0 ) + ay = -ay; + d_corner = ax + ay; + + return ( d_in + d_out - d_corner ) < ( d_corner >> 4 ); + } /* END */ diff --git a/src/pshinter/pshalgo.c b/src/pshinter/pshalgo.c index 8db05dec8..82771f470 100644 --- a/src/pshinter/pshalgo.c +++ b/src/pshinter/pshalgo.c @@ -19,6 +19,7 @@ #include #include FT_INTERNAL_OBJECTS_H #include FT_INTERNAL_DEBUG_H +#include FT_INTERNAL_CALC_H #include "pshalgo.h" #include "pshnterr.h" @@ -879,6 +880,12 @@ /*************************************************************************/ /*************************************************************************/ +#if 1 + +#define psh_corner_is_flat ft_corner_is_flat +#define psh_corner_orientation ft_corner_orientation + +#else FT_LOCAL_DEF( FT_Int ) psh_corner_is_flat( FT_Pos x_in, FT_Pos y_in, @@ -916,9 +923,6 @@ return ( d_in + d_out - d_corner ) < ( d_corner >> 4 ); } - -#ifdef COMPUTE_INFLEXS - static FT_Int psh_corner_orientation( FT_Pos in_x, FT_Pos in_y, @@ -970,6 +974,9 @@ return result; } +#endif + +#ifdef COMPUTE_INFLEXS /* compute all inflex points in a given glyph */ static void