* 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.
This commit is contained in:
Werner Lemberg 2004-11-24 07:08:21 +00:00
parent 85cc0a322e
commit 1ec3963dc8
6 changed files with 67 additions and 393 deletions

View File

@ -1,3 +1,16 @@
2004-11-23 Anders Kaseorg <anders@kaseorg.com>
* 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 <fpapa@netgate.com.uy>
* src/truetype/ttinterp.h: Fix typo.

View File

@ -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
/*************************************************************************/

View File

@ -21,6 +21,8 @@
#include <ft2build.h>
#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;
}
/*************************************************************************/
/* */
/* <Function> */
@ -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;

View File

@ -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;
}

View File

@ -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;

View File

@ -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;