From 61185235025db6b205dea65c5423905d69c457cd Mon Sep 17 00:00:00 2001 From: Ebrahim Byagowi Date: Fri, 10 Jan 2020 21:08:21 +0330 Subject: [PATCH] [ot-glyph] move glyph decompose logic of glyf to itself One less vector allocation yet isn't zero alloc yet which needs more work. --- src/hb-ot-glyf-table.hh | 31 +++++++++++++++---------------- src/hb-ot-glyph.cc | 16 ++++++---------- src/test-ot-glyph.cc | 7 ++++++- 3 files changed, 27 insertions(+), 27 deletions(-) diff --git a/src/hb-ot-glyf-table.hh b/src/hb-ot-glyf-table.hh index f48f5cd38..7f5d0e6ab 100644 --- a/src/hb-ot-glyf-table.hh +++ b/src/hb-ot-glyf-table.hh @@ -1043,10 +1043,10 @@ struct glyf } bool - get_path (hb_font_t *font, hb_codepoint_t gid, hb_vector_t *coords, hb_vector_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 -#define PUSH_POINT_CMD(c, x, y) HB_STMT_START { commands->push (c); PUSH_POINT(x, y); } HB_STMT_END + /* TODO: Make it work alloc free and without all_points vector */ contour_point_vector_t all_points; if (unlikely (!get_points (font, gid, all_points))) return false; hb_array_t points = all_points.sub_array (0, all_points.length - 4); @@ -1065,14 +1065,15 @@ struct glyf contour_point_t *next = &points[contour_start]; 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 { 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 - /* 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); + /* If both first and last points are off-curve, start at their middle. */ + 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) @@ -1081,21 +1082,19 @@ struct glyf next = &points[contour_start + ((i + 1) % contour_length)]; 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 { - PUSH_POINT_CMD ('Q', curr->x, curr->y); - if (next->flag & Glyph::FLAG_ON_CURVE) - PUSH_POINT (next->x, next->y); - else - PUSH_POINT ((curr->x + next->x) / 2.f, (curr->y + next->y) / 2.f); + float to_x, to_y; + if (next->flag & Glyph::FLAG_ON_CURVE) { to_x = next->x; to_y = next->y; } + else { to_x = (curr->x + next->x) / 2.f; to_y = (curr->y + next->y) / 2.f; } + funcs->conic_to (font->em_scalef_x (curr->x), font->em_scalef_y (curr->y), + font->em_scalef_x (to_x), font->em_scalef_y (to_y), user_data); } } - commands->push ('Z'); + /* funcs->end_path (); */ contour_start += contour_length; } -#undef PUSH_POINT_CMD -#undef PUSH_POINT return true; } diff --git a/src/hb-ot-glyph.cc b/src/hb-ot-glyph.cc index 77b3a137c..a58650b10 100644 --- a/src/hb-ot-glyph.cc +++ b/src/hb-ot-glyph.cc @@ -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 (font->face->table.glyf->get_path (font, glyph, funcs, user_data)) return true; + +#ifndef HB_NO_OT_FONT_CFF hb_vector_t coords; hb_vector_t commands; 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.cff2->get_path (font, glyph, &coords, &commands); -#endif 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); coords_idx += 2; 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': if (unlikely (coords.length >= coords_idx + 6)) return false; 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; +#endif + + return false; } #endif diff --git a/src/test-ot-glyph.cc b/src/test-ot-glyph.cc index a735e6a07..f132321af 100644 --- a/src/test-ot-glyph.cc +++ b/src/test-ot-glyph.cc @@ -107,7 +107,12 @@ main (int argc, char **argv) hb_font_extents_t font_extents; hb_font_get_extents_for_direction (font, HB_DIRECTION_LTR, &font_extents); 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]; sprintf (name, "%d.svg", gid); FILE *f = fopen (name, "wb");