diff --git a/src/hb-ot-glyf-table.hh b/src/hb-ot-glyf-table.hh index 32028bc9c..094b6255c 100644 --- a/src/hb-ot-glyf-table.hh +++ b/src/hb-ot-glyf-table.hh @@ -1042,8 +1042,9 @@ struct glyf add_gid_and_children (item.glyphIndex, gids_to_retain, depth); } + template bool - get_path (hb_font_t *font, hb_codepoint_t gid, hb_vector_t &path) const + get_path (hb_font_t *font, hb_codepoint_t gid, F f) const { contour_point_vector_t all_points; if (unlikely (!get_points (font, gid, all_points))) return false; @@ -1063,17 +1064,14 @@ struct glyf contour_point_t *next = &points[contour_start]; if (curr->flag & Glyph::FLAG_ON_CURVE) - path.push ((hb_ot_glyph_path_point_t) - {'M', font->em_scalef_x (curr->x), font->em_scalef_y (curr->y)}); + f ('M', curr->x, curr->y); else { if (next->flag & Glyph::FLAG_ON_CURVE) - path.push ((hb_ot_glyph_path_point_t) - {'M', font->em_scalef_x (next->x), font->em_scalef_y (next->y)}); + f ('M', next->x, next->y); else /* If both first and last points are off-curve, start at their middle. */ - path.push ((hb_ot_glyph_path_point_t) - {'M', font->em_scalef_x ((curr->x + next->x) / 2), font->em_scalef_y ((curr->y + next->y) / 2)}); + f ('M', (curr->x + next->x) / 2.f, (curr->y + next->y) / 2.f); } for (unsigned i = 0; i < contour_length; ++i) @@ -1082,21 +1080,17 @@ struct glyf next = &points[contour_start + ((i + 1) % contour_length)]; if (curr->flag & Glyph::FLAG_ON_CURVE) - path.push ((hb_ot_glyph_path_point_t) - {'L', font->em_scalef_x (curr->x), font->em_scalef_y (curr->y)}); /* straight line */ + f ('L', curr->x, curr->y); /* straight line */ else { - path.push ((hb_ot_glyph_path_point_t) - {'Q', font->em_scalef_x (curr->x), font->em_scalef_y (curr->y)}); + f ('Q', curr->x, curr->y); if (next->flag & Glyph::FLAG_ON_CURVE) - path.push ((hb_ot_glyph_path_point_t) - {' ', font->em_scalef_x (next->x), font->em_scalef_y (next->y)}); + f (' ', next->x, next->y); else - path.push ((hb_ot_glyph_path_point_t) - {' ', font->em_scalef_x ((curr->x + next->x) / 2), font->em_scalef_y ((curr->y + next->y) / 2)}); + f (' ', (curr->x + next->x) / 2.f, (curr->y + next->y) / 2.f); } } - path.push ((hb_ot_glyph_path_point_t) {'Z', 0, 0}); + f ('Z', 0, 0); contour_start += contour_length; } return true; diff --git a/src/hb-ot-glyph.cc b/src/hb-ot-glyph.cc index aefea8cd5..2b5beaadd 100644 --- a/src/hb-ot-glyph.cc +++ b/src/hb-ot-glyph.cc @@ -36,15 +36,22 @@ hb_ot_glyph_get_outline_path (hb_font_t *font, unsigned int *points_count /* IN/OUT. May be NULL. */, hb_ot_glyph_path_point_t *points /* OUT. May be NULL. */) { - hb_vector_t path; - font->face->table.glyf->get_path (font, glyph, path); - if (likely (points_count && points)) - { - + path.sub_array (start_offset, points_count) - | hb_sink (hb_array (points, *points_count)) - ; - } - return path.length; + unsigned int points_to_write = likely (points && points_count) ? *points_count : 0; + if (likely (points_count)) *points_count = 0; + unsigned int all_points_count = 0; + font->face->table.glyf->get_path (font, glyph, + [&] (char cmd, float x, float y) + { + all_points_count++; + if (start_offset) { start_offset--; return; } + if (points_to_write) + { + points[*points_count] = {cmd, font->em_scalef_x (x), font->em_scalef_y (y)}; + *points_count += 1; + points_to_write--; + } + }); + return all_points_count; } #endif diff --git a/src/test-ot-glyph.cc b/src/test-ot-glyph.cc index 085fc54c9..a9b752c36 100644 --- a/src/test-ot-glyph.cc +++ b/src/test-ot-glyph.cc @@ -57,7 +57,8 @@ main (int argc, char **argv) { hb_ot_glyph_path_point_t points[200]; unsigned int points_len = 200; - printf ("\ngid %d, points count: %d\n", gid, hb_ot_glyph_get_outline_path (font, gid, 0, &points_len, points)); + hb_ot_glyph_get_outline_path (font, gid, 0, nullptr, nullptr); /* just to test it */ + printf ("gid %d, points count: %d\n", gid, hb_ot_glyph_get_outline_path (font, gid, 0, &points_len, points)); hb_glyph_extents_t extents = {0}; hb_font_get_glyph_extents (font, gid, &extents); char name[100]; @@ -68,10 +69,11 @@ main (int argc, char **argv) fprintf (f, ""); - fclose (f); } hb_font_destroy (font);