[glyph] Don't copy, write directly into result
This commit is contained in:
parent
f883c31cce
commit
b8b3ff1a02
|
@ -1042,8 +1042,9 @@ struct glyf
|
||||||
add_gid_and_children (item.glyphIndex, gids_to_retain, depth);
|
add_gid_and_children (item.glyphIndex, gids_to_retain, depth);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
template<typename F>
|
||||||
bool
|
bool
|
||||||
get_path (hb_font_t *font, hb_codepoint_t gid, hb_vector_t<hb_ot_glyph_path_point_t> &path) const
|
get_path (hb_font_t *font, hb_codepoint_t gid, F f) const
|
||||||
{
|
{
|
||||||
contour_point_vector_t all_points;
|
contour_point_vector_t all_points;
|
||||||
if (unlikely (!get_points (font, gid, all_points))) return false;
|
if (unlikely (!get_points (font, gid, all_points))) return false;
|
||||||
|
@ -1063,17 +1064,14 @@ struct glyf
|
||||||
contour_point_t *next = &points[contour_start];
|
contour_point_t *next = &points[contour_start];
|
||||||
|
|
||||||
if (curr->flag & Glyph::FLAG_ON_CURVE)
|
if (curr->flag & Glyph::FLAG_ON_CURVE)
|
||||||
path.push ((hb_ot_glyph_path_point_t)
|
f ('M', curr->x, curr->y);
|
||||||
{'M', font->em_scalef_x (curr->x), font->em_scalef_y (curr->y)});
|
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
if (next->flag & Glyph::FLAG_ON_CURVE)
|
if (next->flag & Glyph::FLAG_ON_CURVE)
|
||||||
path.push ((hb_ot_glyph_path_point_t)
|
f ('M', next->x, next->y);
|
||||||
{'M', font->em_scalef_x (next->x), font->em_scalef_y (next->y)});
|
|
||||||
else
|
else
|
||||||
/* If both first and last points are off-curve, start at their middle. */
|
/* If both first and last points are off-curve, start at their middle. */
|
||||||
path.push ((hb_ot_glyph_path_point_t)
|
f ('M', (curr->x + next->x) / 2.f, (curr->y + next->y) / 2.f);
|
||||||
{'M', font->em_scalef_x ((curr->x + next->x) / 2), font->em_scalef_y ((curr->y + next->y) / 2)});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
for (unsigned i = 0; i < contour_length; ++i)
|
for (unsigned i = 0; i < contour_length; ++i)
|
||||||
|
@ -1082,21 +1080,17 @@ struct glyf
|
||||||
next = &points[contour_start + ((i + 1) % contour_length)];
|
next = &points[contour_start + ((i + 1) % contour_length)];
|
||||||
|
|
||||||
if (curr->flag & Glyph::FLAG_ON_CURVE)
|
if (curr->flag & Glyph::FLAG_ON_CURVE)
|
||||||
path.push ((hb_ot_glyph_path_point_t)
|
f ('L', curr->x, curr->y); /* straight line */
|
||||||
{'L', font->em_scalef_x (curr->x), font->em_scalef_y (curr->y)}); /* straight line */
|
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
path.push ((hb_ot_glyph_path_point_t)
|
f ('Q', curr->x, curr->y);
|
||||||
{'Q', font->em_scalef_x (curr->x), font->em_scalef_y (curr->y)});
|
|
||||||
if (next->flag & Glyph::FLAG_ON_CURVE)
|
if (next->flag & Glyph::FLAG_ON_CURVE)
|
||||||
path.push ((hb_ot_glyph_path_point_t)
|
f (' ', next->x, next->y);
|
||||||
{' ', font->em_scalef_x (next->x), font->em_scalef_y (next->y)});
|
|
||||||
else
|
else
|
||||||
path.push ((hb_ot_glyph_path_point_t)
|
f (' ', (curr->x + next->x) / 2.f, (curr->y + next->y) / 2.f);
|
||||||
{' ', font->em_scalef_x ((curr->x + next->x) / 2), font->em_scalef_y ((curr->y + next->y) / 2)});
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
path.push ((hb_ot_glyph_path_point_t) {'Z', 0, 0});
|
f ('Z', 0, 0);
|
||||||
contour_start += contour_length;
|
contour_start += contour_length;
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
|
|
|
@ -36,15 +36,22 @@ hb_ot_glyph_get_outline_path (hb_font_t *font,
|
||||||
unsigned int *points_count /* IN/OUT. May be NULL. */,
|
unsigned int *points_count /* IN/OUT. May be NULL. */,
|
||||||
hb_ot_glyph_path_point_t *points /* OUT. May be NULL. */)
|
hb_ot_glyph_path_point_t *points /* OUT. May be NULL. */)
|
||||||
{
|
{
|
||||||
hb_vector_t<hb_ot_glyph_path_point_t> path;
|
unsigned int points_to_write = likely (points && points_count) ? *points_count : 0;
|
||||||
font->face->table.glyf->get_path (font, glyph, path);
|
if (likely (points_count)) *points_count = 0;
|
||||||
if (likely (points_count && points))
|
unsigned int all_points_count = 0;
|
||||||
|
font->face->table.glyf->get_path (font, glyph,
|
||||||
|
[&] (char cmd, float x, float y)
|
||||||
{
|
{
|
||||||
+ path.sub_array (start_offset, points_count)
|
all_points_count++;
|
||||||
| hb_sink (hb_array (points, *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 path.length;
|
});
|
||||||
|
return all_points_count;
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -57,7 +57,8 @@ main (int argc, char **argv)
|
||||||
{
|
{
|
||||||
hb_ot_glyph_path_point_t points[200];
|
hb_ot_glyph_path_point_t points[200];
|
||||||
unsigned int points_len = 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_glyph_extents_t extents = {0};
|
||||||
hb_font_get_glyph_extents (font, gid, &extents);
|
hb_font_get_glyph_extents (font, gid, &extents);
|
||||||
char name[100];
|
char name[100];
|
||||||
|
@ -68,10 +69,11 @@ main (int argc, char **argv)
|
||||||
fprintf (f, "<svg xmlns=\"http://www.w3.org/2000/svg\""
|
fprintf (f, "<svg xmlns=\"http://www.w3.org/2000/svg\""
|
||||||
" viewBox=\"0 0 %d %d\"><path d=\"", extents.width, extents.height * factor);
|
" viewBox=\"0 0 %d %d\"><path d=\"", extents.width, extents.height * factor);
|
||||||
for (unsigned i = 0; i < points_len; ++i)
|
for (unsigned i = 0; i < points_len; ++i)
|
||||||
|
{
|
||||||
if (points[i].cmd == 'Z') fprintf (f, "Z");
|
if (points[i].cmd == 'Z') fprintf (f, "Z");
|
||||||
else fprintf (f, "%c%d,%d", points[i].cmd, points[i].x, (points[i].y + extents.height) * factor);
|
else fprintf (f, "%c%d,%d", points[i].cmd, points[i].x, (points[i].y + extents.height) * factor);
|
||||||
|
}
|
||||||
fprintf (f, "\"/></svg>");
|
fprintf (f, "\"/></svg>");
|
||||||
|
|
||||||
fclose (f);
|
fclose (f);
|
||||||
}
|
}
|
||||||
hb_font_destroy (font);
|
hb_font_destroy (font);
|
||||||
|
|
Loading…
Reference in New Issue