[autofit] Fix handling of neutral blue zones in stems.
* src/autofit/afhints.h (AF_Edge_Flags): New value `AF_EDGE_NEUTRAL'. * src/autofit/aflatin.c (af_latin_hints_compute_blue_edges): Trace neutral blue zones with AF_EDGE_NEUTRAL. (af_latin_hint_edges): Skip neutral blue zones if necessary.
This commit is contained in:
parent
ccfc4b4c4e
commit
63bef9a588
11
ChangeLog
11
ChangeLog
|
@ -1,3 +1,14 @@
|
||||||
|
2014-05-01 Werner Lemberg <wl@gnu.org>
|
||||||
|
|
||||||
|
[autofit] Fix handling of neutral blue zones in stems.
|
||||||
|
|
||||||
|
* src/autofit/afhints.h (AF_Edge_Flags): New value
|
||||||
|
`AF_EDGE_NEUTRAL'.
|
||||||
|
|
||||||
|
* src/autofit/aflatin.c (af_latin_hints_compute_blue_edges): Trace
|
||||||
|
neutral blue zones with AF_EDGE_NEUTRAL.
|
||||||
|
(af_latin_hint_edges): Skip neutral blue zones if necessary.
|
||||||
|
|
||||||
2014-04-28 Werner Lemberg <wl@gnu.org>
|
2014-04-28 Werner Lemberg <wl@gnu.org>
|
||||||
|
|
||||||
[autofit] Introduce neutral blue zones to the latin module.
|
[autofit] Introduce neutral blue zones to the latin module.
|
||||||
|
|
|
@ -247,7 +247,8 @@ FT_BEGIN_HEADER
|
||||||
AF_EDGE_NORMAL = 0,
|
AF_EDGE_NORMAL = 0,
|
||||||
AF_EDGE_ROUND = 1 << 0,
|
AF_EDGE_ROUND = 1 << 0,
|
||||||
AF_EDGE_SERIF = 1 << 1,
|
AF_EDGE_SERIF = 1 << 1,
|
||||||
AF_EDGE_DONE = 1 << 2
|
AF_EDGE_DONE = 1 << 2,
|
||||||
|
AF_EDGE_NEUTRAL = 1 << 3 /* set if edge aligns to a neutral blue zone */
|
||||||
|
|
||||||
} AF_Edge_Flags;
|
} AF_Edge_Flags;
|
||||||
|
|
||||||
|
|
|
@ -1842,6 +1842,7 @@
|
||||||
{
|
{
|
||||||
FT_UInt bb;
|
FT_UInt bb;
|
||||||
AF_Width best_blue = NULL;
|
AF_Width best_blue = NULL;
|
||||||
|
FT_Bool best_blue_is_neutral = 0;
|
||||||
FT_Pos best_dist; /* initial threshold */
|
FT_Pos best_dist; /* initial threshold */
|
||||||
|
|
||||||
|
|
||||||
|
@ -1856,7 +1857,7 @@
|
||||||
for ( bb = 0; bb < latin->blue_count; bb++ )
|
for ( bb = 0; bb < latin->blue_count; bb++ )
|
||||||
{
|
{
|
||||||
AF_LatinBlue blue = latin->blues + bb;
|
AF_LatinBlue blue = latin->blues + bb;
|
||||||
FT_Bool is_top_blue, is_major_dir;
|
FT_Bool is_top_blue, is_neutral_blue, is_major_dir;
|
||||||
|
|
||||||
|
|
||||||
/* skip inactive blue zones (i.e., those that are too large) */
|
/* skip inactive blue zones (i.e., those that are too large) */
|
||||||
|
@ -1867,12 +1868,15 @@
|
||||||
/* direction); if it is a bottom zone, check for left edges (in */
|
/* direction); if it is a bottom zone, check for left edges (in */
|
||||||
/* the major direction) -- this assumes the TrueType convention */
|
/* the major direction) -- this assumes the TrueType convention */
|
||||||
/* for the orientation of contours */
|
/* for the orientation of contours */
|
||||||
is_top_blue = (FT_Byte)( ( blue->flags & AF_LATIN_BLUE_TOP ) != 0 );
|
is_top_blue =
|
||||||
is_major_dir = FT_BOOL( edge->dir == axis->major_dir );
|
(FT_Byte)( ( blue->flags & AF_LATIN_BLUE_TOP ) != 0 );
|
||||||
|
is_neutral_blue =
|
||||||
|
(FT_Byte)( ( blue->flags & AF_LATIN_BLUE_NEUTRAL ) != 0);
|
||||||
|
is_major_dir =
|
||||||
|
FT_BOOL( edge->dir == axis->major_dir );
|
||||||
|
|
||||||
/* neutral blue zones are handled for both directions */
|
/* neutral blue zones are handled for both directions */
|
||||||
if ( is_top_blue ^ is_major_dir ||
|
if ( is_top_blue ^ is_major_dir || is_neutral_blue )
|
||||||
blue->flags & AF_LATIN_BLUE_NEUTRAL )
|
|
||||||
{
|
{
|
||||||
FT_Pos dist;
|
FT_Pos dist;
|
||||||
|
|
||||||
|
@ -1887,6 +1891,7 @@
|
||||||
{
|
{
|
||||||
best_dist = dist;
|
best_dist = dist;
|
||||||
best_blue = &blue->ref;
|
best_blue = &blue->ref;
|
||||||
|
best_blue_is_neutral = is_neutral_blue;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* now compare it to the overshoot position and check whether */
|
/* now compare it to the overshoot position and check whether */
|
||||||
|
@ -1896,7 +1901,7 @@
|
||||||
/* neutral blue zone) */
|
/* neutral blue zone) */
|
||||||
if ( edge->flags & AF_EDGE_ROUND &&
|
if ( edge->flags & AF_EDGE_ROUND &&
|
||||||
dist != 0 &&
|
dist != 0 &&
|
||||||
!( blue->flags & AF_LATIN_BLUE_NEUTRAL ) )
|
!is_neutral_blue )
|
||||||
{
|
{
|
||||||
FT_Bool is_under_ref = FT_BOOL( edge->fpos < blue->ref.org );
|
FT_Bool is_under_ref = FT_BOOL( edge->fpos < blue->ref.org );
|
||||||
|
|
||||||
|
@ -1912,6 +1917,7 @@
|
||||||
{
|
{
|
||||||
best_dist = dist;
|
best_dist = dist;
|
||||||
best_blue = &blue->shoot;
|
best_blue = &blue->shoot;
|
||||||
|
best_blue_is_neutral = is_neutral_blue;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1919,7 +1925,11 @@
|
||||||
}
|
}
|
||||||
|
|
||||||
if ( best_blue )
|
if ( best_blue )
|
||||||
|
{
|
||||||
edge->blue_edge = best_blue;
|
edge->blue_edge = best_blue;
|
||||||
|
if ( best_blue_is_neutral )
|
||||||
|
edge->flags |= AF_EDGE_NEUTRAL;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2304,14 +2314,41 @@
|
||||||
if ( edge->flags & AF_EDGE_DONE )
|
if ( edge->flags & AF_EDGE_DONE )
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
blue = edge->blue_edge;
|
|
||||||
edge1 = NULL;
|
edge1 = NULL;
|
||||||
edge2 = edge->link;
|
edge2 = edge->link;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* If a stem contains both a neutral and a non-neutral blue zone,
|
||||||
|
* skip the neutral one. Otherwise, outlines with different
|
||||||
|
* directions might be incorrectly aligned at the same vertical
|
||||||
|
* position.
|
||||||
|
*
|
||||||
|
* If we have two neutral blue zones, skip one of them.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
if ( edge->blue_edge && edge2 && edge2->blue_edge )
|
||||||
|
{
|
||||||
|
FT_Byte neutral = edge->flags & AF_EDGE_NEUTRAL;
|
||||||
|
FT_Byte neutral2 = edge2->flags & AF_EDGE_NEUTRAL;
|
||||||
|
|
||||||
|
|
||||||
|
if ( ( neutral && neutral2 ) || neutral2 )
|
||||||
|
{
|
||||||
|
edge2->blue_edge = NULL;
|
||||||
|
edge2->flags &= ~AF_EDGE_NEUTRAL;
|
||||||
|
}
|
||||||
|
else if ( neutral )
|
||||||
|
{
|
||||||
|
edge->blue_edge = NULL;
|
||||||
|
edge->flags &= ~AF_EDGE_NEUTRAL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
blue = edge->blue_edge;
|
||||||
if ( blue )
|
if ( blue )
|
||||||
edge1 = edge;
|
edge1 = edge;
|
||||||
|
|
||||||
/* flip edges if the other stem is aligned to a blue zone */
|
/* flip edges if the other edge is aligned to a blue zone */
|
||||||
else if ( edge2 && edge2->blue_edge )
|
else if ( edge2 && edge2->blue_edge )
|
||||||
{
|
{
|
||||||
blue = edge2->blue_edge;
|
blue = edge2->blue_edge;
|
||||||
|
@ -2378,7 +2415,7 @@
|
||||||
/* this should not happen, but it's better to be safe */
|
/* this should not happen, but it's better to be safe */
|
||||||
if ( edge2->blue_edge )
|
if ( edge2->blue_edge )
|
||||||
{
|
{
|
||||||
FT_TRACE5(( " ASSERTION FAILED for edge %d\n", edge2-edges ));
|
FT_TRACE5(( " ASSERTION FAILED for edge %d\n", edge2 - edges ));
|
||||||
|
|
||||||
af_latin_align_linked_edge( hints, dim, edge2, edge );
|
af_latin_align_linked_edge( hints, dim, edge2, edge );
|
||||||
edge->flags |= AF_EDGE_DONE;
|
edge->flags |= AF_EDGE_DONE;
|
||||||
|
|
Loading…
Reference in New Issue