[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:
parent
172db3254c
commit
2e09812c51
18
ChangeLog
18
ChangeLog
|
@ -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>
|
2015-12-24 Werner Lemberg <wl@gnu.org>
|
||||||
|
|
||||||
[autofit] Add hinting direction to `AF_ScriptClassRec'.
|
[autofit] Add hinting direction to `AF_ScriptClassRec'.
|
||||||
|
|
|
@ -1091,7 +1091,7 @@
|
||||||
/* insert a new edge in the list and */
|
/* insert a new edge in the list and */
|
||||||
/* sort according to the position */
|
/* sort according to the position */
|
||||||
error = af_axis_hints_new_edge( axis, seg->pos,
|
error = af_axis_hints_new_edge( axis, seg->pos,
|
||||||
(AF_Direction)seg->dir,
|
(AF_Direction)seg->dir, 0,
|
||||||
memory, &edge );
|
memory, &edge );
|
||||||
if ( error )
|
if ( error )
|
||||||
goto Exit;
|
goto Exit;
|
||||||
|
|
|
@ -99,6 +99,7 @@
|
||||||
af_axis_hints_new_edge( AF_AxisHints axis,
|
af_axis_hints_new_edge( AF_AxisHints axis,
|
||||||
FT_Int fpos,
|
FT_Int fpos,
|
||||||
AF_Direction dir,
|
AF_Direction dir,
|
||||||
|
FT_Bool top_to_bottom_hinting,
|
||||||
FT_Memory memory,
|
FT_Memory memory,
|
||||||
AF_Edge *anedge )
|
AF_Edge *anedge )
|
||||||
{
|
{
|
||||||
|
@ -153,7 +154,8 @@
|
||||||
|
|
||||||
while ( edge > edges )
|
while ( edge > edges )
|
||||||
{
|
{
|
||||||
if ( edge[-1].fpos < fpos )
|
if ( top_to_bottom_hinting ? ( edge[-1].fpos > fpos )
|
||||||
|
: ( edge[-1].fpos < fpos ) )
|
||||||
break;
|
break;
|
||||||
|
|
||||||
/* we want the edge with same position and minor direction */
|
/* we want the edge with same position and minor direction */
|
||||||
|
|
|
@ -419,6 +419,7 @@ FT_BEGIN_HEADER
|
||||||
af_axis_hints_new_edge( AF_AxisHints axis,
|
af_axis_hints_new_edge( AF_AxisHints axis,
|
||||||
FT_Int fpos,
|
FT_Int fpos,
|
||||||
AF_Direction dir,
|
AF_Direction dir,
|
||||||
|
FT_Bool top_to_bottom_hinting,
|
||||||
FT_Memory memory,
|
FT_Memory memory,
|
||||||
AF_Edge *edge );
|
AF_Edge *edge );
|
||||||
|
|
||||||
|
|
|
@ -1773,6 +1773,12 @@
|
||||||
FT_Memory memory = hints->memory;
|
FT_Memory memory = hints->memory;
|
||||||
AF_LatinAxis laxis = &((AF_LatinMetrics)hints->metrics)->axis[dim];
|
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 segments = axis->segments;
|
||||||
AF_Segment segment_limit = segments + axis->num_segments;
|
AF_Segment segment_limit = segments + axis->num_segments;
|
||||||
AF_Segment seg;
|
AF_Segment seg;
|
||||||
|
@ -1795,6 +1801,9 @@
|
||||||
: AF_DIR_RIGHT;
|
: AF_DIR_RIGHT;
|
||||||
#endif
|
#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
|
* We ignore all segments that are less than 1 pixel in length
|
||||||
* to avoid many problems with serif fonts. We compute the
|
* to avoid many problems with serif fonts. We compute the
|
||||||
|
@ -1872,6 +1881,7 @@
|
||||||
/* sort according to the position */
|
/* sort according to the position */
|
||||||
error = af_axis_hints_new_edge( axis, seg->pos,
|
error = af_axis_hints_new_edge( axis, seg->pos,
|
||||||
(AF_Direction)seg->dir,
|
(AF_Direction)seg->dir,
|
||||||
|
top_to_bottom_hinting,
|
||||||
memory, &edge );
|
memory, &edge );
|
||||||
if ( error )
|
if ( error )
|
||||||
goto Exit;
|
goto Exit;
|
||||||
|
@ -2558,8 +2568,14 @@
|
||||||
AF_Edge anchor = NULL;
|
AF_Edge anchor = NULL;
|
||||||
FT_Int has_serifs = 0;
|
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
|
#ifdef FT_DEBUG_LEVEL_TRACE
|
||||||
FT_UInt num_actions = 0;
|
FT_UInt num_actions = 0;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
@ -2567,6 +2583,9 @@
|
||||||
dim == AF_DIMENSION_VERT ? "horizontal" : "vertical",
|
dim == AF_DIMENSION_VERT ? "horizontal" : "vertical",
|
||||||
af_style_names[hints->metrics->style_class->style] ));
|
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 */
|
/* we begin by aligning all stems relative to the blue zone */
|
||||||
/* if needed -- that's only for horizontal edges */
|
/* if needed -- that's only for horizontal edges */
|
||||||
|
|
||||||
|
@ -2862,7 +2881,9 @@
|
||||||
edge->flags |= AF_EDGE_DONE;
|
edge->flags |= AF_EDGE_DONE;
|
||||||
edge2->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
|
#ifdef FT_DEBUG_LEVEL_TRACE
|
||||||
FT_TRACE5(( " BOUND: edge %d (pos=%.2f) moved to %.2f\n",
|
FT_TRACE5(( " BOUND: edge %d (pos=%.2f) moved to %.2f\n",
|
||||||
|
@ -3023,7 +3044,9 @@
|
||||||
#endif
|
#endif
|
||||||
edge->flags |= AF_EDGE_DONE;
|
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
|
#ifdef FT_DEBUG_LEVEL_TRACE
|
||||||
FT_TRACE5(( " BOUND: edge %d (pos=%.2f) moved to %.2f\n",
|
FT_TRACE5(( " BOUND: edge %d (pos=%.2f) moved to %.2f\n",
|
||||||
|
@ -3034,9 +3057,10 @@
|
||||||
edge->pos = edge[-1].pos;
|
edge->pos = edge[-1].pos;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ( edge + 1 < edge_limit &&
|
if ( edge + 1 < edge_limit &&
|
||||||
edge[1].flags & AF_EDGE_DONE &&
|
edge[1].flags & AF_EDGE_DONE &&
|
||||||
edge->pos > edge[1].pos )
|
( top_to_bottom_hinting ? ( edge->pos < edge[1].pos )
|
||||||
|
: ( edge->pos > edge[1].pos ) ) )
|
||||||
{
|
{
|
||||||
#ifdef FT_DEBUG_LEVEL_TRACE
|
#ifdef FT_DEBUG_LEVEL_TRACE
|
||||||
FT_TRACE5(( " BOUND: edge %d (pos=%.2f) moved to %.2f\n",
|
FT_TRACE5(( " BOUND: edge %d (pos=%.2f) moved to %.2f\n",
|
||||||
|
|
|
@ -1195,7 +1195,7 @@
|
||||||
|
|
||||||
/* insert a new edge in the list and */
|
/* insert a new edge in the list and */
|
||||||
/* sort according to the position */
|
/* 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 );
|
memory, &edge );
|
||||||
if ( error )
|
if ( error )
|
||||||
goto Exit;
|
goto Exit;
|
||||||
|
|
Loading…
Reference in New Issue