From 073d4954e01c45e8dd1cf63a53ad35563f46ef17 Mon Sep 17 00:00:00 2001 From: Ebrahim Byagowi Date: Wed, 26 Feb 2020 15:40:40 +0330 Subject: [PATCH] [draw] Port glyf path extract to draw_helper_t --- src/hb-draw.hh | 44 +++++++++++------ src/hb-ot-glyf-table.hh | 104 +++++++++------------------------------- 2 files changed, 52 insertions(+), 96 deletions(-) diff --git a/src/hb-draw.hh b/src/hb-draw.hh index 96c88675b..03b518ed6 100644 --- a/src/hb-draw.hh +++ b/src/hb-draw.hh @@ -43,30 +43,43 @@ struct draw_helper_t { void init (const hb_draw_funcs_t *funcs_, void *user_data_) { - path_open = false; funcs = funcs_; user_data = user_data_; - path_start_x = 0; - path_start_y = 0; - path_last_x = 0; - path_last_y = 0; - + path_open = false; + path_start_x = current_x = path_start_y = current_y = 0; } void fini () { end_path (); } void move_to (hb_position_t x, hb_position_t y) { if (path_open) end_path (); - path_last_x = path_start_x = x; - path_last_y = path_start_y = y; + current_x = path_start_x = x; + current_y = path_start_y = y; } void line_to (hb_position_t x, hb_position_t y) { if (!path_open) start_path (); funcs->line_to (x, y, user_data); - path_last_x = x; - path_last_y = y; + current_x = x; + current_y = y; + } + + void + quadratic_to (hb_position_t control_x, hb_position_t control_y, + hb_position_t to_x, hb_position_t to_y) + { + if (!path_open) start_path (); + if (funcs->is_quadratic_to_set) + funcs->quadratic_to (control_x, control_y, to_x, to_y, user_data); + else + funcs->cubic_to (roundf ((current_x + 2.f * control_x) / 3.f), + roundf ((current_y + 2.f * control_y) / 3.f), + roundf ((to_x + 2.f * control_x) / 3.f), + roundf ((to_y + 2.f * control_y) / 3.f), + to_x, to_y, user_data); + current_x = to_x; + current_y = to_y; } void @@ -76,19 +89,20 @@ struct draw_helper_t { if (!path_open) start_path (); funcs->cubic_to (x1, y1, x2, y2, x3, y3, user_data); - path_last_x = x3; - path_last_y = y3; + current_x = x3; + current_y = y3; } void end_path () { if (path_open) { - if ((path_start_x != path_last_x) || (path_start_y != path_last_y)) + if ((path_start_x != current_x) || (path_start_y != current_y)) funcs->line_to (path_start_x, path_start_y, user_data); funcs->close_path (user_data); } path_open = false; + path_start_x = current_x = path_start_y = current_y = 0; } protected: @@ -102,8 +116,8 @@ struct draw_helper_t hb_position_t path_start_x; hb_position_t path_start_y; - hb_position_t path_last_x; - hb_position_t path_last_y; + hb_position_t current_x; + hb_position_t current_y; bool path_open; const hb_draw_funcs_t *funcs; diff --git a/src/hb-ot-glyf-table.hh b/src/hb-ot-glyf-table.hh index efda05054..8d782ae14 100644 --- a/src/hb-ot-glyf-table.hh +++ b/src/hb-ot-glyf-table.hh @@ -1032,11 +1032,7 @@ struct glyf struct path_builder_t { hb_font_t *font; - const hb_draw_funcs_t *funcs; - void *user_data; - void (*quad_to) (hb_font_t *, const hb_draw_funcs_t *, - float, float, float, float, float, float, - void *); + draw_helper_t draw_helper; struct optional_point_t { @@ -1049,55 +1045,23 @@ struct glyf optional_point_t lerp (optional_point_t p, float t) { return optional_point_t (x + t * (p.x - x), y + t * (p.y - y)); } - } first_oncurve, first_offcurve, last_offcurve, current; + } first_oncurve, first_offcurve, last_offcurve; - path_builder_t (hb_font_t *font_, const hb_draw_funcs_t *funcs_, void *user_data_) + path_builder_t (hb_font_t *font_, const hb_draw_funcs_t *funcs, void *user_data) { font = font_; - funcs = funcs_; - user_data = user_data_; - quad_to = funcs->is_quadratic_to_set - ? _normal_quadratic_to_call - : _translate_quadratic_to_cubic; - end_of_contour (); + draw_helper = draw_helper_t (); + draw_helper.init (funcs, user_data); + first_oncurve = first_offcurve = last_offcurve = optional_point_t (); } - void end_of_contour () - { first_oncurve = first_offcurve = last_offcurve = current = optional_point_t (); } - - static void - _normal_quadratic_to_call (hb_font_t *font, const hb_draw_funcs_t *funcs, - float from_x HB_UNUSED, float from_y HB_UNUSED, - float control_x, float control_y, - float to_x, float to_y, - void *user_data) - { - funcs->quadratic_to (font->em_scalef_x (control_x), font->em_scalef_y (control_y), - font->em_scalef_x (to_x), font->em_scalef_y (to_y), - user_data); - } - - static void - _translate_quadratic_to_cubic (hb_font_t *font, const hb_draw_funcs_t *funcs, - float from_x, float from_y, - float control_x, float control_y, - float to_x, float to_y, - void *user_data) - { - funcs->cubic_to (font->em_scalef_x ((from_x + 2.f * control_x) / 3.f), - font->em_scalef_y ((from_y + 2.f * control_y) / 3.f), - font->em_scalef_x ((to_x + 2.f * control_x) / 3.f), - font->em_scalef_y ((to_y + 2.f * control_y) / 3.f), - font->em_scalef_x (to_x), - font->em_scalef_y (to_y), - user_data); - } + { first_oncurve = first_offcurve = last_offcurve = optional_point_t (); } /* based on https://github.com/RazrFalcon/ttf-parser/blob/master/src/glyf.rs#L292 */ void consume_point (const contour_point_t &point) { /* Skip empty contours */ - if (unlikely (point.is_end_point && current.is_null && first_offcurve.is_null)) + if (unlikely (point.is_end_point && first_oncurve.is_null && first_offcurve.is_null)) return; bool is_on_curve = point.flag & Glyph::FLAG_ON_CURVE; @@ -1107,10 +1071,7 @@ struct glyf if (is_on_curve) { first_oncurve = p; - funcs->move_to (font->em_scalef_x (p.x), - font->em_scalef_y (p.y), - user_data); - current = p; + draw_helper.move_to (font->em_scalef_x (p.x), font->em_scalef_y (p.y)); } else { @@ -1119,10 +1080,7 @@ struct glyf optional_point_t mid = first_offcurve.lerp (p, .5f); first_oncurve = mid; last_offcurve = p; - funcs->move_to (font->em_scalef_x (mid.x), - font->em_scalef_y (mid.y), - user_data); - current = mid; + draw_helper.move_to (font->em_scalef_x (mid.x), font->em_scalef_y (mid.y)); } else first_offcurve = p; @@ -1134,30 +1092,22 @@ struct glyf { if (is_on_curve) { - quad_to (font, funcs, current.x, current.y, - last_offcurve.x, last_offcurve.y, - p.x, p.y, user_data); - current = p; + draw_helper.quadratic_to (font->em_scalef_x (last_offcurve.x), font->em_scalef_y (last_offcurve.y), + font->em_scalef_x (p.x), font->em_scalef_y (p.y)); last_offcurve = optional_point_t (); } else { optional_point_t mid = last_offcurve.lerp (p, .5f); - quad_to (font, funcs, current.x, current.y, - last_offcurve.x, last_offcurve.y, - mid.x, mid.y, user_data); + draw_helper.quadratic_to (font->em_scalef_x (last_offcurve.x), font->em_scalef_y (last_offcurve.y), + font->em_scalef_x (mid.x), font->em_scalef_y (mid.y)); last_offcurve = p; - current = mid; } } else { if (is_on_curve) - { - funcs->line_to (font->em_scalef_x (p.x), - font->em_scalef_y (p.y), user_data); - current = p; - } + draw_helper.line_to (font->em_scalef_x (p.x), font->em_scalef_y (p.y)); else last_offcurve = p; } @@ -1170,41 +1120,33 @@ struct glyf if (!first_offcurve.is_null && !last_offcurve.is_null) { optional_point_t mid = last_offcurve.lerp (first_offcurve, .5f); - quad_to (font, funcs, current.x, current.y, - last_offcurve.x, last_offcurve.y, mid.x, mid.y, - user_data); - current = mid; + draw_helper.quadratic_to (font->em_scalef_x (last_offcurve.x), font->em_scalef_y (last_offcurve.y), + font->em_scalef_x (mid.x), font->em_scalef_y (mid.y)); last_offcurve = optional_point_t (); } else if (!first_offcurve.is_null && last_offcurve.is_null) { if (!first_oncurve.is_null) - quad_to (font, funcs, current.x, current.y, - first_offcurve.x, first_offcurve.y, - first_oncurve.x, first_oncurve.y, - user_data); + draw_helper.quadratic_to (font->em_scalef_x (first_offcurve.x), font->em_scalef_y (first_offcurve.y), + font->em_scalef_x (first_oncurve.x), font->em_scalef_y (first_oncurve.y)); break; } else if (first_offcurve.is_null && !last_offcurve.is_null) { if (!first_oncurve.is_null) - quad_to (font, funcs, current.x, current.y, - last_offcurve.x, last_offcurve.y, - first_oncurve.x, first_oncurve.y, - user_data); + draw_helper.quadratic_to (font->em_scalef_x (last_offcurve.x), font->em_scalef_y (last_offcurve.y), + font->em_scalef_x (first_oncurve.x), font->em_scalef_y (first_oncurve.y)); break; } else /* first_offcurve.is_null && last_offcurve.is_null */ { if (!first_oncurve.is_null) - funcs->line_to (font->em_scalef_x (first_oncurve.x), - font->em_scalef_y (first_oncurve.y), - user_data); + draw_helper.line_to (font->em_scalef_x (first_oncurve.x), font->em_scalef_y (first_oncurve.y)); break; } } end_of_contour (); - funcs->close_path (user_data); + draw_helper.end_path (); } } void points_end () {}