[autofit] Make top-to-bottom hinting work in latin auto-hinter.

This improves rendering of scripts like Bengali or Devanagari.

* src/autofit/afhints.c (af_axis_hints_new_edge): Add parameter to
pass top-to-bottom hinting flag.  This makes the function sort edges
in descending vertical position.

* src/autofit/afhints.c: Updated.

* src/autofit/aflatin.c (af_latin_hints_compute_edges,
af_latin_hint_edges): Use `top_to_bottom_hinting' flag.

* src/autofit/afcjk.c (af_cjk_hints_compute_edges),
src/autofit/aflatin2.c (af_latin2_hints_compute_edges): Updated.
This commit is contained in:
Werner Lemberg 2015-12-25 08:05:30 +01:00
parent 172db3254c
commit 2e09812c51
6 changed files with 54 additions and 9 deletions

View File

@ -1,3 +1,21 @@
2015-12-25 Werner Lemberg <wl@gnu.org>
[autofit] Make top-to-bottom hinting work in latin auto-hinter.
This improves rendering of scripts like Bengali or Devanagari.
* src/autofit/afhints.c (af_axis_hints_new_edge): Add parameter to
pass top-to-bottom hinting flag. This makes the function sort edges
in descending vertical position.
* src/autofit/afhints.c: Updated.
* src/autofit/aflatin.c (af_latin_hints_compute_edges,
af_latin_hint_edges): Use `top_to_bottom_hinting' flag.
* src/autofit/afcjk.c (af_cjk_hints_compute_edges),
src/autofit/aflatin2.c (af_latin2_hints_compute_edges): Updated.
2015-12-24 Werner Lemberg <wl@gnu.org>
[autofit] Add hinting direction to `AF_ScriptClassRec'.

View File

@ -1091,7 +1091,7 @@
/* insert a new edge in the list and */
/* sort according to the position */
error = af_axis_hints_new_edge( axis, seg->pos,
(AF_Direction)seg->dir,
(AF_Direction)seg->dir, 0,
memory, &edge );
if ( error )
goto Exit;

View File

@ -99,6 +99,7 @@
af_axis_hints_new_edge( AF_AxisHints axis,
FT_Int fpos,
AF_Direction dir,
FT_Bool top_to_bottom_hinting,
FT_Memory memory,
AF_Edge *anedge )
{
@ -153,7 +154,8 @@
while ( edge > edges )
{
if ( edge[-1].fpos < fpos )
if ( top_to_bottom_hinting ? ( edge[-1].fpos > fpos )
: ( edge[-1].fpos < fpos ) )
break;
/* we want the edge with same position and minor direction */

View File

@ -419,6 +419,7 @@ FT_BEGIN_HEADER
af_axis_hints_new_edge( AF_AxisHints axis,
FT_Int fpos,
AF_Direction dir,
FT_Bool top_to_bottom_hinting,
FT_Memory memory,
AF_Edge *edge );

View File

@ -1773,6 +1773,12 @@
FT_Memory memory = hints->memory;
AF_LatinAxis laxis = &((AF_LatinMetrics)hints->metrics)->axis[dim];
AF_StyleClass style_class = hints->metrics->style_class;
AF_ScriptClass script_class = AF_SCRIPT_CLASSES_GET
[style_class->script];
FT_Bool top_to_bottom_hinting = 0;
AF_Segment segments = axis->segments;
AF_Segment segment_limit = segments + axis->num_segments;
AF_Segment seg;
@ -1795,6 +1801,9 @@
: AF_DIR_RIGHT;
#endif
if ( dim == AF_DIMENSION_VERT )
top_to_bottom_hinting = script_class->top_to_bottom_hinting;
/*
* We ignore all segments that are less than 1 pixel in length
* to avoid many problems with serif fonts. We compute the
@ -1872,6 +1881,7 @@
/* sort according to the position */
error = af_axis_hints_new_edge( axis, seg->pos,
(AF_Direction)seg->dir,
top_to_bottom_hinting,
memory, &edge );
if ( error )
goto Exit;
@ -2558,8 +2568,14 @@
AF_Edge anchor = NULL;
FT_Int has_serifs = 0;
AF_StyleClass style_class = hints->metrics->style_class;
AF_ScriptClass script_class = AF_SCRIPT_CLASSES_GET
[style_class->script];
FT_Bool top_to_bottom_hinting = 0;
#ifdef FT_DEBUG_LEVEL_TRACE
FT_UInt num_actions = 0;
FT_UInt num_actions = 0;
#endif
@ -2567,6 +2583,9 @@
dim == AF_DIMENSION_VERT ? "horizontal" : "vertical",
af_style_names[hints->metrics->style_class->style] ));
if ( dim == AF_DIMENSION_VERT )
top_to_bottom_hinting = script_class->top_to_bottom_hinting;
/* we begin by aligning all stems relative to the blue zone */
/* if needed -- that's only for horizontal edges */
@ -2862,7 +2881,9 @@
edge->flags |= AF_EDGE_DONE;
edge2->flags |= AF_EDGE_DONE;
if ( edge > edges && edge->pos < edge[-1].pos )
if ( edge > edges &&
( top_to_bottom_hinting ? ( edge->pos > edge[-1].pos )
: ( edge->pos < edge[-1].pos ) ) )
{
#ifdef FT_DEBUG_LEVEL_TRACE
FT_TRACE5(( " BOUND: edge %d (pos=%.2f) moved to %.2f\n",
@ -3023,7 +3044,9 @@
#endif
edge->flags |= AF_EDGE_DONE;
if ( edge > edges && edge->pos < edge[-1].pos )
if ( edge > edges &&
( top_to_bottom_hinting ? ( edge->pos > edge[-1].pos )
: ( edge->pos < edge[-1].pos ) ) )
{
#ifdef FT_DEBUG_LEVEL_TRACE
FT_TRACE5(( " BOUND: edge %d (pos=%.2f) moved to %.2f\n",
@ -3034,9 +3057,10 @@
edge->pos = edge[-1].pos;
}
if ( edge + 1 < edge_limit &&
edge[1].flags & AF_EDGE_DONE &&
edge->pos > edge[1].pos )
if ( edge + 1 < edge_limit &&
edge[1].flags & AF_EDGE_DONE &&
( top_to_bottom_hinting ? ( edge->pos < edge[1].pos )
: ( edge->pos > edge[1].pos ) ) )
{
#ifdef FT_DEBUG_LEVEL_TRACE
FT_TRACE5(( " BOUND: edge %d (pos=%.2f) moved to %.2f\n",

View File

@ -1195,7 +1195,7 @@
/* insert a new edge in the list and */
/* sort according to the position */
error = af_axis_hints_new_edge( axis, seg->pos, seg->dir,
error = af_axis_hints_new_edge( axis, seg->pos, seg->dir, 0,
memory, &edge );
if ( error )
goto Exit;