[draw] Fix invalid rendering of some glyph on Estedad-VF
Basically reverts 11f3fca
so I can do the same tested and better later
Fixes #2215
This commit is contained in:
parent
86c40b3a1d
commit
44169f3396
|
@ -573,7 +573,9 @@ struct glyf
|
|||
return true;
|
||||
}
|
||||
|
||||
bool get_contour_points (contour_point_vector_t &points_ /* OUT */, bool phantom_only = false) const
|
||||
bool get_contour_points (contour_point_vector_t &points_ /* OUT */,
|
||||
hb_vector_t<unsigned int> &end_points_ /* OUT */,
|
||||
bool phantom_only = false) const
|
||||
{
|
||||
const HBUINT16 *endPtsOfContours = &StructAfter<HBUINT16> (header);
|
||||
int num_contours = header.numberOfContours;
|
||||
|
@ -584,8 +586,13 @@ struct glyf
|
|||
for (unsigned int i = 0; i < points_.length; i++) points_[i].init ();
|
||||
if (phantom_only) return true;
|
||||
|
||||
end_points_.resize (num_contours);
|
||||
|
||||
for (int i = 0; i < num_contours; i++)
|
||||
{
|
||||
end_points_[i] = endPtsOfContours[i];
|
||||
points_[endPtsOfContours[i]].is_end_point = true;
|
||||
}
|
||||
|
||||
/* Skip instructions */
|
||||
const HBUINT8 *p = &StructAtOffset<HBUINT8> (&endPtsOfContours[num_contours + 1],
|
||||
|
@ -702,6 +709,7 @@ struct glyf
|
|||
{
|
||||
if (unlikely (depth > HB_MAX_NESTING_LEVEL)) return false;
|
||||
contour_point_vector_t points;
|
||||
hb_vector_t<unsigned> end_points;
|
||||
|
||||
switch (type) {
|
||||
case COMPOSITE:
|
||||
|
@ -714,7 +722,7 @@ struct glyf
|
|||
break;
|
||||
}
|
||||
case SIMPLE:
|
||||
if (unlikely (!SimpleGlyph (*header, bytes).get_contour_points (points, phantom_only)))
|
||||
if (unlikely (!SimpleGlyph (*header, bytes).get_contour_points (points, end_points, phantom_only)))
|
||||
return false;
|
||||
break;
|
||||
default: return false; /* empty glyph */
|
||||
|
@ -738,7 +746,8 @@ struct glyf
|
|||
}
|
||||
|
||||
#ifndef HB_NO_VAR
|
||||
if (unlikely (!face->table.gvar->apply_deltas_to_points (gid, font->coords, font->num_coords, points.as_array ()))) return false;
|
||||
if (unlikely (!face->table.gvar->apply_deltas_to_points (gid, font->coords, font->num_coords,
|
||||
points.as_array (), end_points.as_array ()))) return false;
|
||||
#endif
|
||||
|
||||
switch (type) {
|
||||
|
|
|
@ -546,7 +546,8 @@ struct gvar
|
|||
public:
|
||||
bool apply_deltas_to_points (hb_codepoint_t glyph,
|
||||
const int *coords, unsigned int coord_count,
|
||||
const hb_array_t<contour_point_t> points) const
|
||||
const hb_array_t<contour_point_t> points,
|
||||
const hb_array_t<unsigned int> end_points) const
|
||||
{
|
||||
coord_count = hb_min (coord_count, gvar_table->axisCount);
|
||||
if (!coord_count || coord_count != gvar_table->axisCount) return true;
|
||||
|
@ -605,27 +606,16 @@ struct gvar
|
|||
deltas[pt_index].y += y_deltas[i] * scalar;
|
||||
}
|
||||
|
||||
/* find point before phantoms start which is an end point */
|
||||
unsigned all_contours_end = points.length ? points.length - 1 : 0;
|
||||
while (all_contours_end > 0)
|
||||
{
|
||||
if (points[all_contours_end].is_end_point) break;
|
||||
--all_contours_end;
|
||||
}
|
||||
|
||||
/* infer deltas for unreferenced points */
|
||||
for (unsigned start_point = 0; start_point < all_contours_end; ++start_point)
|
||||
unsigned start_point = 0;
|
||||
for (unsigned c = 0; c < end_points.length; c++)
|
||||
{
|
||||
unsigned end_point = end_points[c];
|
||||
|
||||
/* Check the number of unreferenced points in a contour. If no unref points or no ref points, nothing to do. */
|
||||
unsigned end_point = start_point;
|
||||
unsigned unref_count = 0;
|
||||
for (; end_point <= all_contours_end; ++end_point)
|
||||
{
|
||||
if (!deltas[end_point].flag)
|
||||
unref_count++;
|
||||
if (points[end_point].is_end_point)
|
||||
break;
|
||||
}
|
||||
for (unsigned i = start_point; i <= end_point; i++)
|
||||
if (!deltas[i].flag) unref_count++;
|
||||
|
||||
unsigned j = start_point;
|
||||
if (unref_count == 0 || unref_count > end_point - start_point)
|
||||
|
|
Binary file not shown.
|
@ -7,3 +7,5 @@ chromacheck-* fonts are from https://github.com/RoelN/ChromaCheck/tree/master/fo
|
|||
RanaKufi-Regular.subset.otf is from https://github.com/alif-type/rana-kufi/ but the subset is licensed for us in MIT for the project use.
|
||||
|
||||
glyphs.ttf is from https://github.com/RazrFalcon/ttf-parser/blob/337e7d1/tests/fonts/glyphs.ttf
|
||||
|
||||
Estedad-VF.ttf, licensed under OFL 1.1, is from https://github.com/aminabedi68/Estedad
|
||||
|
|
|
@ -751,6 +751,66 @@ test_hb_draw_font_kit_variations_tests (void)
|
|||
}
|
||||
}
|
||||
|
||||
static void
|
||||
test_hb_draw_estedad_vf (void)
|
||||
{
|
||||
/* https://github.com/harfbuzz/harfbuzz/issues/2215 */
|
||||
char str[2048];
|
||||
user_data_t user_data = {
|
||||
.str = str,
|
||||
.size = sizeof (str)
|
||||
};
|
||||
{
|
||||
/* See https://github.com/google/skia/blob/d38f00a1/gm/stroketext.cpp#L115-L124 */
|
||||
hb_face_t *face = hb_test_open_font_file ("fonts/Estedad-VF.ttf");
|
||||
hb_font_t *font = hb_font_create (face);
|
||||
hb_face_destroy (face);
|
||||
|
||||
hb_variation_t var;
|
||||
hb_variation_from_string ("wght=100", -1, &var);
|
||||
hb_font_set_variations (font, &var, 1);
|
||||
|
||||
user_data.consumed = 0;
|
||||
g_assert (hb_font_draw_glyph (font, 156, funcs, &user_data));
|
||||
/* Skip empty path where all the points of a path are equal */
|
||||
char expected[] = "M150,1158L182,1158Q256,1158 317,1170Q377,1182 421,1213L421,430L521,430"
|
||||
"L521,1490L421,1490L421,1320Q393,1279 344,1262Q294,1244 182,1244L150,1244"
|
||||
"L150,1158ZM1815,-122L1669,-122L1669,642L1552,642L1055,-117L1055,-206"
|
||||
"L1569,-206L1569,-458L1669,-458L1669,-206L1815,-206L1815,-122ZM1569,-122"
|
||||
"L1166,-122L1569,494L1569,-122ZM609,-79L1639,1288L1555,1334L525,-33L609,-79Z";
|
||||
g_assert_cmpmem (str, user_data.consumed, expected, sizeof (expected) - 1);
|
||||
|
||||
user_data.consumed = 0;
|
||||
g_assert (hb_font_draw_glyph (font, 180, funcs, &user_data));
|
||||
/* Skip empty path where all the points of a path are equal */
|
||||
char expected2[] = "M120,693Q120,545 177,414Q233,282 333,182Q433,81 567,24Q701,-33 855,-33"
|
||||
"Q1010,-33 1144,24Q1277,81 1377,182Q1477,282 1534,414Q1590,545 1590,693"
|
||||
"Q1590,842 1534,973Q1477,1104 1377,1205Q1277,1305 1144,1362Q1010,1419 855,1419"
|
||||
"Q701,1419 567,1362Q433,1305 333,1205Q233,1104 177,973Q120,842 120,693ZM220,693"
|
||||
"Q220,828 270,945Q320,1061 409,1148Q497,1235 612,1284Q726,1333 855,1333"
|
||||
"Q984,1333 1099,1284Q1213,1235 1302,1148Q1390,1061 1440,945Q1490,828 1490,693"
|
||||
"Q1490,558 1440,442Q1390,325 1302,237Q1213,149 1099,100Q984,51 855,51"
|
||||
"Q726,51 612,100Q497,149 409,237Q320,325 270,442Q220,558 220,693ZM690,643"
|
||||
"L690,997L886,997Q970,997 1029,949Q1087,901 1087,819Q1087,737 1028,690"
|
||||
"Q969,643 886,643L690,643ZM1165,334L973,568Q1065,591 1126,658Q1187,725 1187,819"
|
||||
"Q1187,896 1147,956Q1106,1015 1038,1049Q969,1083 886,1083L590,1083L590,310"
|
||||
"L690,310L690,557L860,557L1083,286L1165,334Z";
|
||||
g_assert_cmpmem (str, user_data.consumed, expected2, sizeof (expected2) - 1);
|
||||
|
||||
user_data.consumed = 0;
|
||||
g_assert (hb_font_draw_glyph (font, 262, funcs, &user_data));
|
||||
/* Skip empty path where all the points of a path are equal */
|
||||
char expected3[] = "M422,598Q495,598 545,548Q595,498 595,426Q595,353 545,303Q494,252 422,252"
|
||||
"Q350,252 300,303Q250,353 250,426Q250,499 300,549Q349,598 422,598ZM422,698"
|
||||
"Q347,698 285,662Q223,625 187,564Q150,502 150,426Q150,351 187,289"
|
||||
"Q223,226 285,189Q346,152 422,152Q498,152 560,189Q622,226 659,289"
|
||||
"Q695,351 695,426Q695,502 658,564Q621,625 560,662Q498,698 422,698Z";
|
||||
g_assert_cmpmem (str, user_data.consumed, expected3, sizeof (expected3) - 1);
|
||||
|
||||
hb_font_destroy (font);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
test_hb_draw_stroking (void)
|
||||
{
|
||||
|
@ -866,6 +926,7 @@ main (int argc, char **argv)
|
|||
hb_test_add (test_hb_draw_ttf_parser_tests);
|
||||
hb_test_add (test_hb_draw_font_kit_glyphs_tests);
|
||||
hb_test_add (test_hb_draw_font_kit_variations_tests);
|
||||
hb_test_add (test_hb_draw_estedad_vf);
|
||||
hb_test_add (test_hb_draw_stroking);
|
||||
hb_test_add (test_hb_draw_immutable);
|
||||
unsigned result = hb_test_run ();
|
||||
|
|
Loading…
Reference in New Issue