* src/pshinter/pshalgo3.c, src/autohint/ahangles.c,

src/autohint/ahangles.h, src/autohint/ahglyph.c, src/autohint/ahhint.c,
        src/autohint/ahtypes.h: the automatic and Postscript hinter now
        automatically detect inflection points in glyph outlines and treats
        them specially. This is very useful to prevent nasty effect like the
        disappearing diagonals of "S" and "s" in many, many fonts..
BRANCH-2-1-5
David Turner 23 years ago
parent 8cb11c96f0
commit 7afd3d6b6f
  1. 16
      src/autohint/ahangles.c
  2. 5
      src/autohint/ahangles.h
  3. 115
      src/autohint/ahglyph.c
  4. 3
      src/autohint/ahhint.c
  5. 1
      src/autohint/ahtypes.h
  6. 3
      src/pshinter/pshalgo3.c

@ -127,4 +127,20 @@
}
FT_LOCAL_DEF( AH_Angle )
ah_angle_diff( AH_Angle angle1,
AH_Angle angle2 )
{
AH_Angle delta;
delta = ( angle2 - angle1 );
if ( delta < 0 )
delta += AH_2PI;
if ( delta > AH_PI )
delta -= AH_2PI;
return delta;
}
/* END */

@ -51,6 +51,11 @@ FT_BEGIN_HEADER
ah_angle( FT_Vector* v );
FT_LOCAL( AH_Angle )
ah_angle_diff( AH_Angle angle1,
AH_Angle angle2 );
FT_END_HEADER
#endif /* __AHANGLES_H__ */

@ -674,6 +674,120 @@
}
}
/* compute all inflex points in a given glyph */
static void
ah_outline_compute_inflections( AH_Outline* outline )
{
AH_Point** contour = outline->contours;
AH_Point** contour_limit = contour + outline->num_contours;
/* load original coordinates in (u,v) */
ah_setup_uv( outline, ah_uv_fxy );
/* do each contour separately */
for ( ; contour < contour_limit; contour++ )
{
FT_Vector vec;
AH_Point* point = contour[0];
AH_Point* first = point;
AH_Point* start = point;
AH_Point* end = point;
AH_Point* before;
AH_Point* after;
AH_Angle angle_in, angle_seg, angle_out;
AH_Angle diff_in, diff_out;
FT_Int finished = 0;
/* compute first segment in contour */
first = point;
start = end = first;
do
{
end = end->next;
if ( end == first )
goto Skip;
}
while ( end->u == first->u && end->v == first->v );
vec.x = end->u - start->u;
vec.y = end->v - start->v;
angle_seg = ah_angle( &vec );
/* extend the segment start whenever possible */
before = start;
do
{
do
{
start = before;
before = before->prev;
if ( before == first )
goto Skip;
}
while ( before->u == start->u && before->v == start->v );
vec.x = start->u - before->u;
vec.y = start->v - before->v;
angle_in = ah_angle( &vec );
}
while ( angle_in == angle_seg );
first = start;
diff_in = ah_angle_diff( angle_in, angle_seg );
/* now, process all segments in the contour */
do
{
/* first, extend current segment's end whenever possible */
after = end;
do
{
do
{
end = after;
after = after->next;
if ( after == first )
finished = 1;
}
while ( end->u == after->u && end->v == after->v );
vec.x = after->u - end->u;
vec.y = after->v - end->v;
angle_out = ah_angle( &vec );
}
while ( angle_out == angle_seg );
diff_out = ah_angle_diff( angle_seg, angle_out );
if ( diff_in ^ diff_out < 0 )
{
/* diff_in and diff_out have different signs, we have */
/* inflection points here... */
do
{
start->flags |= ah_flag_inflection;
start = start->next;
}
while ( start != end );
start->flags |= ah_flag_inflection;
}
start = end;
end = after;
angle_seg = angle_out;
diff_in = diff_out;
}
while ( !finished );
Skip:
;
}
}
FT_LOCAL_DEF( void )
ah_outline_compute_segments( AH_Outline* outline )
@ -1290,6 +1404,7 @@
ah_outline_compute_segments( outline );
ah_outline_link_segments ( outline );
ah_outline_compute_edges ( outline );
ah_outline_compute_inflections( outline );
}

@ -612,7 +612,8 @@
#ifndef AH_OPTION_NO_WEAK_INTERPOLATION
/* if this point is candidate to weak interpolation, we will */
/* interpolate it after all strong points have been processed */
if ( point->flags & ah_flag_weak_interpolation )
if ( (point->flags & ah_flag_weak_interpolation) &&
!(point->flags & ah_flag_inflection) )
continue;
#endif

@ -147,6 +147,7 @@ FT_BEGIN_HEADER
/* weak interpolation */
#define ah_flag_weak_interpolation 256
#define ah_flag_inflection 512
typedef FT_Int AH_Flags;

@ -1422,7 +1422,8 @@
point->dir_in != point->dir_out )
continue;
if ( !psh3_point_is_extremum( point ) )
if ( !psh3_point_is_extremum( point ) &&
!psh3_point_is_inflection( point ) )
continue;
point->flags &= ~PSH3_POINT_SMOOTH;

Loading…
Cancel
Save