* 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:
parent
85cc0a322e
commit
1ec3963dc8
13
ChangeLog
13
ChangeLog
|
@ -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.
|
||||
|
|
|
@ -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
|
||||
|
||||
|
||||
/*************************************************************************/
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -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;
|
||||
|
||||
|
|
|
@ -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;
|
||||
|
|
Loading…
Reference in New Issue