[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.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183
diff --git a/ChangeLog b/ChangeLog
index 89d03ef..7b51780 100644
--- a/ChangeLog
+++ b/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>
[autofit] Add hinting direction to `AF_ScriptClassRec'.
diff --git a/src/autofit/afcjk.c b/src/autofit/afcjk.c
index 73d75ae..247d447 100644
--- a/src/autofit/afcjk.c
+++ b/src/autofit/afcjk.c
@@ -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;
diff --git a/src/autofit/afhints.c b/src/autofit/afhints.c
index 56c8220..b85f4b3 100644
--- a/src/autofit/afhints.c
+++ b/src/autofit/afhints.c
@@ -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 */
diff --git a/src/autofit/afhints.h b/src/autofit/afhints.h
index a64c7a4..eb59332 100644
--- a/src/autofit/afhints.h
+++ b/src/autofit/afhints.h
@@ -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 );
diff --git a/src/autofit/aflatin.c b/src/autofit/aflatin.c
index 9c9f370..f75bf00 100644
--- a/src/autofit/aflatin.c
+++ b/src/autofit/aflatin.c
@@ -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",
diff --git a/src/autofit/aflatin2.c b/src/autofit/aflatin2.c
index 2fb7d1d..216848a 100644
--- a/src/autofit/aflatin2.c
+++ b/src/autofit/aflatin2.c
@@ -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;