diff --git a/ChangeLog b/ChangeLog index cd2521c00..f4eeb01cb 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,16 @@ +2004-11-23 Anders Kaseorg + + * src/base/ftoutln.c (FT_OrientationExtremumRec, + ft_orientation_extremum_compute): Removed. + (FT_Outline_Get_Orientation): Rewritten, simplified. + + * src/autohint/ahglyph.c: Include FT_OUTLINE_H. + (ah_test_extremum, ah_get_orientation): Removed. + (ah_outline_load): Use FT_Outline_Get_Orientation. + + * src/base/ftsynth.c (ft_test_extrama, ft_get_orientation): Removed. + (FT_GlyphSlot_Embolden): Use FT_Outline_Get_Orientation. + 2004-11-23 Fernando Papa * src/truetype/ttinterp.h: Fix typo. diff --git a/include/freetype/config/ftoption.h b/include/freetype/config/ftoption.h index 88dbe1d07..319c412ff 100644 --- a/include/freetype/config/ftoption.h +++ b/include/freetype/config/ftoption.h @@ -436,7 +436,7 @@ FT_BEGIN_HEADER /* Do not #undef this macro here, since the build system might */ /* define it for certain configurations only. */ /* */ -#define TT_CONFIG_OPTION_BYTECODE_INTERPRETER +#define TT_CONFIG_OPTION_BYTECODE_INTERPRETER /*************************************************************************/ @@ -448,7 +448,7 @@ FT_BEGIN_HEADER /* FT_PARAM_TAG_UNPATENTED_HINTING; or when the debug hook */ /* FT_DEBUG_HOOK_UNPATENTED_HINTING is globally actived. */ /* */ -/* #define TT_CONFIG_OPTION_UNPATENTED_HINTING */ +#define TT_CONFIG_OPTION_UNPATENTED_HINTING /*************************************************************************/ diff --git a/src/autohint/ahglyph.c b/src/autohint/ahglyph.c index 2a0390be4..5bf198830 100644 --- a/src/autohint/ahglyph.c +++ b/src/autohint/ahglyph.c @@ -21,6 +21,8 @@ #include +#include FT_OUTLINE_H + #include "ahglyph.h" #include "ahangles.h" #include "ahglobal.h" @@ -164,144 +166,6 @@ } - /* this function is used by ah_get_orientation (see below) to test */ - /* the fill direction of given bbox extremum */ - static FT_Int - ah_test_extremum( FT_Outline* outline, - FT_Int n ) - { - FT_Vector *prev, *cur, *next; - FT_Pos product; - FT_Int first, last, c; - FT_Int retval; - - - /* we need to compute the `previous' and `next' point */ - /* for this extremum; we check whether the extremum */ - /* is start or end of a contour and providing */ - /* appropriate values if so */ - cur = outline->points + n; - prev = cur - 1; - next = cur + 1; - - first = 0; - for ( c = 0; c < outline->n_contours; c++ ) - { - last = outline->contours[c]; - - if ( n == first ) - prev = outline->points + last; - - if ( n == last ) - next = outline->points + first; - - first = last + 1; - } - - /* compute the vectorial product -- since we know that the angle */ - /* is <= 180 degrees (otherwise it wouldn't be an extremum) we */ - /* can determine the filling orientation if the product is */ - /* either positive or negative */ - product = FT_MulDiv( cur->x - prev->x, /* in.x */ - next->y - cur->y, /* out.y */ - 0x40 ) - - - FT_MulDiv( cur->y - prev->y, /* in.y */ - next->x - cur->x, /* out.x */ - 0x40 ); - - retval = 0; - if ( product ) - retval = product > 0 ? 2 : 1; - - return retval; - } - - - /* Compute the orientation of path filling. It differs between TrueType */ - /* and Type1 formats. We could use the `FT_OUTLINE_REVERSE_FILL' flag, */ - /* but it is better to re-compute it directly (it seems that this flag */ - /* isn't correctly set for some weird composite glyphs currently). */ - /* */ - /* We do this by computing bounding box points, and computing their */ - /* curvature. */ - /* */ - /* The function returns either 1 or 2. */ - /* */ - static FT_Int - ah_get_orientation( FT_Outline* outline ) - { - FT_BBox box; - FT_Int indices_xMin, indices_yMin, indices_xMax, indices_yMax; - FT_Int n, last; - - - indices_xMin = -1; - indices_yMin = -1; - indices_xMax = -1; - indices_yMax = -1; - - box.xMin = box.yMin = 32767L; - box.xMax = box.yMax = -32768L; - - /* is it empty? */ - if ( outline->n_contours < 1 ) - return 1; - - last = outline->contours[outline->n_contours - 1]; - - for ( n = 0; n <= last; n++ ) - { - FT_Pos x, y; - - - x = outline->points[n].x; - if ( x < box.xMin ) - { - box.xMin = x; - indices_xMin = n; - } - if ( x > box.xMax ) - { - box.xMax = x; - indices_xMax = n; - } - - y = outline->points[n].y; - if ( y < box.yMin ) - { - box.yMin = y; - indices_yMin = n; - } - if ( y > box.yMax ) - { - box.yMax = y; - indices_yMax = n; - } - } - - /* test orientation of the extrema */ - n = ah_test_extremum( outline, indices_xMin ); - if ( n ) - goto Exit; - - n = ah_test_extremum( outline, indices_yMin ); - if ( n ) - goto Exit; - - n = ah_test_extremum( outline, indices_xMax ); - if ( n ) - goto Exit; - - n = ah_test_extremum( outline, indices_yMax ); - if ( !n ) - n = 1; - - Exit: - return n; - } - - /*************************************************************************/ /* */ /* */ @@ -465,7 +329,7 @@ outline->vert_major_dir = AH_DIR_UP; outline->horz_major_dir = AH_DIR_LEFT; - if ( ah_get_orientation( source ) > 1 ) + if ( FT_Outline_Get_Orientation( source ) == FT_ORIENTATION_POSTSCRIPT ) { outline->vert_major_dir = AH_DIR_DOWN; outline->horz_major_dir = AH_DIR_RIGHT; diff --git a/src/base/ftoutln.c b/src/base/ftoutln.c index 5cae931f6..8c6fdfd58 100644 --- a/src/base/ftoutln.c +++ b/src/base/ftoutln.c @@ -653,142 +653,64 @@ } - typedef struct FT_OrientationExtremumRec_ - { - FT_Int index; - FT_Long pos; - FT_Int first; - FT_Int last; - - } FT_OrientationExtremumRec; - - - static FT_Orientation - ft_orientation_extremum_compute( FT_OrientationExtremumRec* extremum, - FT_Outline* outline ) - { - FT_Vector *point, *first, *last, *prev, *next; - FT_Vector* points = outline->points; - FT_Angle angle_in, angle_out; - - - /* compute the previous and next points in the same contour */ - point = points + extremum->index; - first = points + extremum->first; - last = points + extremum->last; - - prev = point; - next = point; - - do - { - prev = ( prev == first ) ? last : prev - 1; - if ( prev == point ) - return FT_ORIENTATION_TRUETYPE; /* degenerate case */ - - } while ( prev->x != point->x || prev->y != point->y ); - - do - { - next = ( next == last ) ? first : next + 1; - if ( next == point ) - return FT_ORIENTATION_TRUETYPE; /* shouldn't happen */ - - } while ( next->x != point->x || next->y != point->y ); - - /* now compute the orientation of the `out' vector relative */ - /* to the `in' vector. */ - angle_in = FT_Atan2( point->x - prev->x, point->y - prev->y ); - angle_out = FT_Atan2( next->x - point->x, next->y - point->y ); - - return ( FT_Angle_Diff( angle_in, angle_out ) >= 0 ) - ? FT_ORIENTATION_TRUETYPE - : FT_ORIENTATION_POSTSCRIPT; - } - + /* documentation is in ftoutln.h */ FT_EXPORT_DEF( FT_Orientation ) FT_Outline_Get_Orientation( FT_Outline* outline ) { - FT_Orientation result = FT_ORIENTATION_TRUETYPE; + FT_Pos xmin = 32768L; + FT_Vector* xmin_point = NULL; + FT_Vector* xmin_first = NULL; + FT_Vector* xmin_last = NULL; + + short* contour; + + FT_Vector* first; + FT_Vector* last; + FT_Vector* prev; + FT_Vector* next; - if ( outline && outline->n_points > 0 ) + if ( !outline || outline->n_points <= 0 ) + return FT_ORIENTATION_TRUETYPE; + + first = outline->points; + for ( contour = outline->contours; + contour < outline->contours + outline->n_contours; + contour++, first = last + 1 ) { - FT_OrientationExtremumRec xmin, ymin, xmax, ymax; - FT_Int n; - FT_Int first, last; - FT_Vector* points = outline->points; + FT_Vector* point; - xmin.pos = ymin.pos = +32768L; - xmax.pos = ymax.pos = -32768L; + last = outline->points + *contour; - xmin.index = ymin.index = xmax.index = ymax.index = -1; + /* skip degenerate contours */ + if ( last < first + 2 ) + continue; - first = 0; - for ( n = 0; n < outline->n_contours; n++, first = last + 1 ) + for ( point = first; point <= last; point++ ) { - last = outline->contours[n]; - - /* skip single-point contours; these are degenerated cases */ - if ( last > first + 1 ) + if ( point->x < xmin ) { - FT_Int i; - - - for ( i = first; i < last; i++ ) - { - FT_Pos x = points[i].x; - FT_Pos y = points[i].y; - - - if ( x < xmin.pos ) - { - xmin.pos = x; - xmin.index = i; - xmin.first = first; - xmin.last = last; - } - if ( x > xmax.pos ) - { - xmax.pos = x; - xmax.index = i; - xmax.first = first; - xmax.last = last; - } - if ( y < ymin.pos ) - { - ymin.pos = y; - ymin.index = i; - ymin.first = first; - ymin.last = last; - } - if ( y > ymax.pos ) - { - ymax.pos = y; - ymax.index = i; - ymax.first = first; - ymax.last = last; - } - } + xmin = point->x; + xmin_point = point; + xmin_first = first; + xmin_last = last; } - - if ( xmin.index >= 0 ) - result = ft_orientation_extremum_compute( &xmin, outline ); - - else if ( xmax.index >= 0 ) - result = ft_orientation_extremum_compute( &xmax, outline ); - - else if ( ymin.index >= 0 ) - result = ft_orientation_extremum_compute( &ymin, outline ); - - else if ( ymax.index >= 0 ) - result = ft_orientation_extremum_compute( &ymax, outline ); } } - return result; + if ( !xmin_point ) + return FT_ORIENTATION_TRUETYPE; + + prev = ( xmin_point == xmin_first ) ? xmin_last : xmin_point - 1; + next = ( xmin_point == xmin_last ) ? xmin_first : xmin_point + 1; + + if ( FT_Atan2( prev->x - xmin_point->x, prev->y - xmin_point->y ) > + FT_Atan2( next->x - xmin_point->x, next->y - xmin_point->y ) ) + return FT_ORIENTATION_POSTSCRIPT; + else + return FT_ORIENTATION_TRUETYPE; } diff --git a/src/base/ftsynth.c b/src/base/ftsynth.c index cee36822f..541af4e86 100644 --- a/src/base/ftsynth.c +++ b/src/base/ftsynth.c @@ -4,7 +4,7 @@ /* */ /* FreeType synthesizing code for emboldening and slanting (body). */ /* */ -/* Copyright 2000-2001, 2002, 2003 by */ +/* Copyright 2000-2001, 2002, 2003, 2004 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -71,134 +71,6 @@ - static int - ft_test_extrema( FT_Outline* outline, - int n ) - { - FT_Vector *prev, *cur, *next; - FT_Pos product; - FT_Int c, first, last; - - - /* we need to compute the `previous' and `next' point */ - /* for these extrema. */ - cur = outline->points + n; - prev = cur - 1; - next = cur + 1; - - first = 0; - for ( c = 0; c < outline->n_contours; c++ ) - { - last = outline->contours[c]; - - if ( n == first ) - prev = outline->points + last; - - if ( n == last ) - next = outline->points + first; - - first = last + 1; - } - - product = FT_MulDiv( cur->x - prev->x, /* in.x */ - next->y - cur->y, /* out.y */ - 0x40 ) - - - FT_MulDiv( cur->y - prev->y, /* in.y */ - next->x - cur->x, /* out.x */ - 0x40 ); - - if ( product ) - product = product > 0 ? 1 : -1; - - return product; - } - - - /* Compute the orientation of path filling. It differs between TrueType */ - /* and Type1 formats. We could use the `FT_OUTLINE_REVERSE_FILL' flag, */ - /* but it is better to re-compute it directly (it seems that this flag */ - /* isn't correctly set for some weird composite glyphs currently). */ - /* */ - /* We do this by computing bounding box points, and computing their */ - /* curvature. */ - /* */ - /* The function returns either 1 or -1. */ - /* */ - static int - ft_get_orientation( FT_Outline* outline ) - { - FT_BBox box; - FT_BBox indices; - int n, last; - - - indices.xMin = -1; - indices.yMin = -1; - indices.xMax = -1; - indices.yMax = -1; - - box.xMin = box.yMin = 32767; - box.xMax = box.yMax = -32768; - - /* is it empty ? */ - if ( outline->n_contours < 1 ) - return 1; - - last = outline->contours[outline->n_contours - 1]; - - for ( n = 0; n <= last; n++ ) - { - FT_Pos x, y; - - - x = outline->points[n].x; - if ( x < box.xMin ) - { - box.xMin = x; - indices.xMin = n; - } - if ( x > box.xMax ) - { - box.xMax = x; - indices.xMax = n; - } - - y = outline->points[n].y; - if ( y < box.yMin ) - { - box.yMin = y; - indices.yMin = n; - } - if ( y > box.yMax ) - { - box.yMax = y; - indices.yMax = n; - } - } - - /* test orientation of the xmin */ - n = ft_test_extrema( outline, indices.xMin ); - if ( n ) - goto Exit; - - n = ft_test_extrema( outline, indices.yMin ); - if ( n ) - goto Exit; - - n = ft_test_extrema( outline, indices.xMax ); - if ( n ) - goto Exit; - - n = ft_test_extrema( outline, indices.yMax ); - if ( !n ) - n = 1; - - Exit: - return n; - } - - FT_EXPORT_DEF( void ) FT_GlyphSlot_Embolden( FT_GlyphSlot slot ) { @@ -208,7 +80,7 @@ FT_Outline* outline = &slot->outline; FT_Face face = FT_SLOT_FACE( slot ); FT_Angle rotate, angle_in, angle_out; - FT_Int c, n, first, orientation; + FT_Int c, n, first; /* only embolden outline glyph images */ @@ -219,8 +91,10 @@ distance = FT_MulFix( face->units_per_EM / 60, face->size->metrics.y_scale ); - orientation = ft_get_orientation( outline ); - rotate = FT_ANGLE_PI2*orientation; + if ( FT_Outline_Get_Orientation( outline ) == FT_ORIENTATION_TRUETYPE ) + rotate = -FT_ANGLE_PI2; + else + rotate = FT_ANGLE_PI2; points = outline->points; diff --git a/src/base/fttrigon.c b/src/base/fttrigon.c index 5347dd852..4212a7906 100644 --- a/src/base/fttrigon.c +++ b/src/base/fttrigon.c @@ -4,7 +4,7 @@ /* */ /* FreeType trigonometric functions (body). */ /* */ -/* Copyright 2001, 2002, 2003 by */ +/* Copyright 2001, 2002, 2003, 2004 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -485,6 +485,7 @@ { FT_Angle delta = angle2 - angle1; + delta %= FT_ANGLE_2PI; if ( delta < 0 ) delta += FT_ANGLE_2PI;