[autofit] Handle single-point contours as segments.
Doing so allows us to link them to edges – some fonts like `NotoSansGurmukhi-Regular' have such isolated points sitting exactly on other outlines. * src/autofit/aflatin.c (af_latin_hints_compute_segments): Don't ignore one-point contours but handle them specially as one-point segments. (af_latin_hints_compute_edges): Append one-point segments to edges if possible.
This commit is contained in:
parent
8b8c4408dd
commit
5e353f0786
14
ChangeLog
14
ChangeLog
|
@ -1,3 +1,17 @@
|
||||||
|
2016-07-04 Werner Lemberg <wl@gnu.org>
|
||||||
|
|
||||||
|
[autofit] Handle single-point contours as segments.
|
||||||
|
|
||||||
|
Doing so allows us to link them to edges – some fonts like
|
||||||
|
`NotoSansGurmukhi-Regular' have such isolated points sitting exactly
|
||||||
|
on other outlines.
|
||||||
|
|
||||||
|
* src/autofit/aflatin.c (af_latin_hints_compute_segments): Don't
|
||||||
|
ignore one-point contours but handle them specially as one-point
|
||||||
|
segments.
|
||||||
|
(af_latin_hints_compute_edges): Append one-point segments to edges
|
||||||
|
if possible.
|
||||||
|
|
||||||
2016-07-02 Werner Lemberg <wl@gnu.org>
|
2016-07-02 Werner Lemberg <wl@gnu.org>
|
||||||
|
|
||||||
[autofit] Remove unused structure members.
|
[autofit] Remove unused structure members.
|
||||||
|
|
|
@ -1466,9 +1466,6 @@
|
||||||
FT_Pos prev_max_on_coord = max_on_coord;
|
FT_Pos prev_max_on_coord = max_on_coord;
|
||||||
|
|
||||||
|
|
||||||
if ( point == last ) /* skip singletons -- just in case */
|
|
||||||
continue;
|
|
||||||
|
|
||||||
if ( FT_ABS( last->out_dir ) == major_dir &&
|
if ( FT_ABS( last->out_dir ) == major_dir &&
|
||||||
FT_ABS( point->out_dir ) == major_dir )
|
FT_ABS( point->out_dir ) == major_dir )
|
||||||
{
|
{
|
||||||
|
@ -1685,7 +1682,12 @@
|
||||||
passed = 1;
|
passed = 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ( !on_edge && FT_ABS( point->out_dir ) == major_dir )
|
/* if we are not on an edge, check whether the major direction */
|
||||||
|
/* coincides with the current point's `out' direction, or */
|
||||||
|
/* whether we have a single-point contour */
|
||||||
|
if ( !on_edge &&
|
||||||
|
( FT_ABS( point->out_dir ) == major_dir ||
|
||||||
|
point == point->prev ) )
|
||||||
{
|
{
|
||||||
/* this is the start of a new segment! */
|
/* this is the start of a new segment! */
|
||||||
segment_dir = (AF_Direction)point->out_dir;
|
segment_dir = (AF_Direction)point->out_dir;
|
||||||
|
@ -1719,6 +1721,24 @@
|
||||||
min_on_coord = max_on_coord = point->v;
|
min_on_coord = max_on_coord = point->v;
|
||||||
|
|
||||||
on_edge = 1;
|
on_edge = 1;
|
||||||
|
|
||||||
|
if ( point == point->prev )
|
||||||
|
{
|
||||||
|
/* we have a one-point segment: this is a one-point */
|
||||||
|
/* contour with `in' and `out' direction set to */
|
||||||
|
/* AF_DIR_NONE */
|
||||||
|
segment->pos = (FT_Short)min_pos;
|
||||||
|
|
||||||
|
if (point->flags & AF_FLAG_CONTROL)
|
||||||
|
segment->flags |= AF_EDGE_ROUND;
|
||||||
|
|
||||||
|
segment->min_coord = (FT_Short)point->v;
|
||||||
|
segment->max_coord = (FT_Short)point->v;
|
||||||
|
segment->height = 0;
|
||||||
|
|
||||||
|
on_edge = 0;
|
||||||
|
segment = NULL;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
point = point->next;
|
point = point->next;
|
||||||
|
@ -2002,7 +2022,10 @@
|
||||||
FT_Int ee;
|
FT_Int ee;
|
||||||
|
|
||||||
|
|
||||||
if ( seg->height < segment_length_threshold )
|
/* ignore too short segments and, in this loop, */
|
||||||
|
/* one-point segments without a direction */
|
||||||
|
if ( seg->height < segment_length_threshold ||
|
||||||
|
seg->dir == AF_DIR_NONE )
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
/* A special case for serif edges: If they are smaller than */
|
/* A special case for serif edges: If they are smaller than */
|
||||||
|
@ -2064,6 +2087,44 @@
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* we loop again over all segments to catch one-point segments */
|
||||||
|
/* without a direction: if possible, link them to existing edges */
|
||||||
|
for ( seg = segments; seg < segment_limit; seg++ )
|
||||||
|
{
|
||||||
|
AF_Edge found = NULL;
|
||||||
|
FT_Int ee;
|
||||||
|
|
||||||
|
|
||||||
|
if ( seg->dir != AF_DIR_NONE )
|
||||||
|
continue;
|
||||||
|
|
||||||
|
/* look for an edge corresponding to the segment */
|
||||||
|
for ( ee = 0; ee < axis->num_edges; ee++ )
|
||||||
|
{
|
||||||
|
AF_Edge edge = axis->edges + ee;
|
||||||
|
FT_Pos dist;
|
||||||
|
|
||||||
|
|
||||||
|
dist = seg->pos - edge->fpos;
|
||||||
|
if ( dist < 0 )
|
||||||
|
dist = -dist;
|
||||||
|
|
||||||
|
if ( dist < edge_distance_threshold )
|
||||||
|
{
|
||||||
|
found = edge;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* one-point segments without a match are ignored */
|
||||||
|
if ( found )
|
||||||
|
{
|
||||||
|
seg->edge_next = found->first;
|
||||||
|
found->last->edge_next = seg;
|
||||||
|
found->last = seg;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/******************************************************************/
|
/******************************************************************/
|
||||||
/* */
|
/* */
|
||||||
|
|
Loading…
Reference in New Issue