[ot-glyph] move glyph decompose logic of glyf to itself

One less vector allocation yet isn't zero alloc yet
which needs more work.
pull/2016/head
Ebrahim Byagowi 5 years ago
parent 017f606c83
commit 6118523502
  1. 29
      src/hb-ot-glyf-table.hh
  2. 16
      src/hb-ot-glyph.cc
  3. 7
      src/test-ot-glyph.cc

@ -1043,10 +1043,10 @@ struct glyf
} }
bool bool
get_path (hb_font_t *font, hb_codepoint_t gid, hb_vector_t<hb_position_t> *coords, hb_vector_t<uint8_t> *commands) const get_path (hb_font_t *font, hb_codepoint_t gid,
hb_ot_glyph_decompose_funcs_t *funcs, void *user_data) const
{ {
#define PUSH_POINT(x, y) HB_STMT_START { coords->push (font->em_scalef_x (x)); coords->push (font->em_scalef_y (y)); } HB_STMT_END /* TODO: Make it work alloc free and without all_points vector */
#define PUSH_POINT_CMD(c, x, y) HB_STMT_START { commands->push (c); PUSH_POINT(x, y); } HB_STMT_END
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;
hb_array_t<contour_point_t> points = all_points.sub_array (0, all_points.length - 4); hb_array_t<contour_point_t> points = all_points.sub_array (0, all_points.length - 4);
@ -1065,14 +1065,15 @@ 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)
PUSH_POINT_CMD ('M', curr->x, curr->y); funcs->move_to (font->em_scalef_x (curr->x), font->em_scalef_y (curr->y), user_data);
else else
{ {
if (next->flag & Glyph::FLAG_ON_CURVE) if (next->flag & Glyph::FLAG_ON_CURVE)
PUSH_POINT_CMD ('M', next->x, next->y); funcs->move_to (font->em_scalef_x (next->x), font->em_scalef_y (next->y), user_data);
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. */
PUSH_POINT_CMD ('M', (curr->x + next->x) / 2.f, (curr->y + next->y) / 2.f); funcs->move_to (font->em_scalef_x ((curr->x + next->x) / 2.f),
font->em_scalef_y ((curr->y + next->y) / 2.f), user_data);
} }
for (unsigned i = 0; i < contour_length; ++i) for (unsigned i = 0; i < contour_length; ++i)
@ -1081,21 +1082,19 @@ 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)
PUSH_POINT_CMD ('L', curr->x, curr->y); /* straight line */ funcs->line_to (font->em_scalef_x (curr->x), font->em_scalef_y (curr->y), user_data);
else else
{ {
PUSH_POINT_CMD ('Q', curr->x, curr->y); float to_x, to_y;
if (next->flag & Glyph::FLAG_ON_CURVE) if (next->flag & Glyph::FLAG_ON_CURVE) { to_x = next->x; to_y = next->y; }
PUSH_POINT (next->x, next->y); else { to_x = (curr->x + next->x) / 2.f; to_y = (curr->y + next->y) / 2.f; }
else funcs->conic_to (font->em_scalef_x (curr->x), font->em_scalef_y (curr->y),
PUSH_POINT ((curr->x + next->x) / 2.f, (curr->y + next->y) / 2.f); font->em_scalef_x (to_x), font->em_scalef_y (to_y), user_data);
} }
} }
commands->push ('Z'); /* funcs->end_path (); */
contour_start += contour_length; contour_start += contour_length;
} }
#undef PUSH_POINT_CMD
#undef PUSH_POINT
return true; return true;
} }

@ -38,16 +38,15 @@ hb_ot_glyph_decompose (hb_font_t *font, hb_codepoint_t glyph,
{ {
if (unlikely (!funcs || glyph >= font->face->get_num_glyphs ())) return false; if (unlikely (!funcs || glyph >= font->face->get_num_glyphs ())) return false;
if (font->face->table.glyf->get_path (font, glyph, funcs, user_data)) return true;
#ifndef HB_NO_OT_FONT_CFF
hb_vector_t<hb_position_t> coords; hb_vector_t<hb_position_t> coords;
hb_vector_t<uint8_t> commands; hb_vector_t<uint8_t> commands;
bool ret = false; bool ret = false;
if (!ret) ret = font->face->table.glyf->get_path (font, glyph, &coords, &commands);
#ifndef HB_NO_OT_FONT_CFF
if (!ret) ret = font->face->table.cff1->get_path (font, glyph, &coords, &commands); if (!ret) ret = font->face->table.cff1->get_path (font, glyph, &coords, &commands);
if (!ret) ret = font->face->table.cff2->get_path (font, glyph, &coords, &commands); if (!ret) ret = font->face->table.cff2->get_path (font, glyph, &coords, &commands);
#endif
if (unlikely (!ret || coords.length % 2 != 0)) return false; if (unlikely (!ret || coords.length % 2 != 0)) return false;
@ -68,12 +67,6 @@ hb_ot_glyph_decompose (hb_font_t *font, hb_codepoint_t glyph,
funcs->line_to (coords[coords_idx + 0], coords[coords_idx + 1], user_data); funcs->line_to (coords[coords_idx + 0], coords[coords_idx + 1], user_data);
coords_idx += 2; coords_idx += 2;
break; break;
case 'Q':
if (unlikely (coords.length < coords_idx + 4)) return false;
funcs->conic_to (coords[coords_idx + 0], coords[coords_idx + 1],
coords[coords_idx + 2], coords[coords_idx + 3], user_data);
coords_idx += 4;
break;
case 'C': case 'C':
if (unlikely (coords.length >= coords_idx + 6)) return false; if (unlikely (coords.length >= coords_idx + 6)) return false;
funcs->cubic_to (coords[coords_idx + 0], coords[coords_idx + 1], funcs->cubic_to (coords[coords_idx + 0], coords[coords_idx + 1],
@ -84,6 +77,9 @@ hb_ot_glyph_decompose (hb_font_t *font, hb_codepoint_t glyph,
} }
return true; return true;
#endif
return false;
} }
#endif #endif

@ -107,7 +107,12 @@ main (int argc, char **argv)
hb_font_extents_t font_extents; hb_font_extents_t font_extents;
hb_font_get_extents_for_direction (font, HB_DIRECTION_LTR, &font_extents); hb_font_get_extents_for_direction (font, HB_DIRECTION_LTR, &font_extents);
hb_glyph_extents_t extents = {0}; hb_glyph_extents_t extents = {0};
hb_font_get_glyph_extents (font, gid, &extents); if (!hb_font_get_glyph_extents (font, gid, &extents))
{
printf ("Skip gid: %d\n", gid);
continue;
}
char name[100]; char name[100];
sprintf (name, "%d.svg", gid); sprintf (name, "%d.svg", gid);
FILE *f = fopen (name, "wb"); FILE *f = fopen (name, "wb");

Loading…
Cancel
Save