From 86bd5a0ba12e389eb0742bf63eb9c88ca3fd8786 Mon Sep 17 00:00:00 2001 From: Ebrahim Byagowi Date: Sun, 23 Feb 2020 22:46:26 +0330 Subject: [PATCH] [draw] End CFF paths with a line-to Issue a line-to command when start and end point of a path isn't same, matches freetype also. --- src/hb-ot-cff1-table.cc | 35 ++++++++++++++++++++++++++++++++--- src/hb-ot-cff2-table.cc | 40 ++++++++++++++++++++++++++++++++++++---- test/api/test-draw.c | 16 +++++++++------- 3 files changed, 77 insertions(+), 14 deletions(-) diff --git a/src/hb-ot-cff1-table.cc b/src/hb-ot-cff1-table.cc index 83bf9195a..9f03aa526 100644 --- a/src/hb-ot-cff1-table.cc +++ b/src/hb-ot-cff1-table.cc @@ -355,18 +355,26 @@ struct cff1_path_param_t funcs = funcs_; user_data = user_data_; delta = delta_; + path_start_x = 0; + path_start_y = 0; + path_last_x = 0; + path_last_y = 0; } ~cff1_path_param_t () { end_path (); } - void start_path () { path_open = true; } - void end_path () { if (path_open) funcs->close_path (user_data); path_open = false; } + void start_path () + { + path_open = true; + } bool is_path_open () const { return path_open; } void move_to (const point_t &p) { point_t point = p; if (delta) point.move (*delta); - funcs->move_to (font->em_scalef_x (point.x.to_real ()), font->em_scalef_y (point.y.to_real ()), + path_last_x = path_start_x = point.x.to_real (); + path_last_y = path_start_y = point.y.to_real (); + funcs->move_to (font->em_scalef_x (path_start_x), font->em_scalef_y (path_start_y), user_data); } @@ -376,6 +384,8 @@ struct cff1_path_param_t if (delta) point.move (*delta); funcs->line_to (font->em_scalef_x (point.x.to_real ()), font->em_scalef_y (point.y.to_real ()), user_data); + path_last_x = point.x.to_real (); + path_last_y = point.y.to_real (); } void cubic_to (const point_t &p1, const point_t &p2, const point_t &p3) @@ -391,8 +401,27 @@ struct cff1_path_param_t font->em_scalef_x (point2.x.to_real ()), font->em_scalef_y (point2.y.to_real ()), font->em_scalef_x (point3.x.to_real ()), font->em_scalef_y (point3.y.to_real ()), user_data); + path_last_x = point3.x.to_real (); + path_last_y = point3.y.to_real (); } + void end_path () + { + if (path_open) + { + if ((path_start_x != path_last_x) || (path_start_y != path_last_y)) + funcs->line_to (font->em_scalef_x (path_start_x), font->em_scalef_y (path_start_y), user_data); + funcs->close_path (user_data); + } + path_open = false; + } + + double path_start_x; + double path_start_y; + + double path_last_x; + double path_last_y; + bool path_open; hb_font_t *font; const hb_draw_funcs_t *funcs; diff --git a/src/hb-ot-cff2-table.cc b/src/hb-ot-cff2-table.cc index d772f7776..3f8508332 100644 --- a/src/hb-ot-cff2-table.cc +++ b/src/hb-ot-cff2-table.cc @@ -151,16 +151,24 @@ struct cff2_path_param_t font = font_; funcs = funcs_; user_data = user_data_; + path_start_x = 0; + path_start_y = 0; + path_last_x = 0; + path_last_y = 0; } ~cff2_path_param_t () { end_path (); } - void start_path () { path_open = true; } - void end_path () { if (path_open) funcs->close_path (user_data); path_open = false; } + void start_path () + { + path_open = true; + } bool is_path_open () const { return path_open; } void move_to (const point_t &p) { - funcs->move_to (font->em_scalef_x (p.x.to_real ()), font->em_scalef_y (p.y.to_real ()), + path_last_x = path_start_x = p.x.to_real (); + path_last_y = path_start_y = p.y.to_real (); + funcs->move_to (font->em_scalef_x (path_start_x), font->em_scalef_y (path_start_y), user_data); } @@ -168,6 +176,8 @@ struct cff2_path_param_t { funcs->line_to (font->em_scalef_x (p.x.to_real ()), font->em_scalef_y (p.y.to_real ()), user_data); + path_last_x = p.x.to_real (); + path_last_y = p.y.to_real (); } void cubic_to (const point_t &p1, const point_t &p2, const point_t &p3) @@ -176,12 +186,34 @@ struct cff2_path_param_t font->em_scalef_x (p2.x.to_real ()), font->em_scalef_y (p2.y.to_real ()), font->em_scalef_x (p3.x.to_real ()), font->em_scalef_y (p3.y.to_real ()), user_data); + path_last_x = p3.x.to_real (); + path_last_y = p3.y.to_real (); } - bool path_open; + void end_path () + { + if (path_open) + { + if ((path_start_x != path_last_x) || (path_start_y != path_last_y)) + funcs->line_to (font->em_scalef_x (path_start_x), font->em_scalef_y (path_start_y), user_data); + funcs->close_path (user_data); + } + path_open = false; + } + + double path_start_x; + double path_start_y; + + double path_last_x; + double path_last_y; + + bool path_open; hb_font_t *font; const hb_draw_funcs_t *funcs; void *user_data; + point_t *delta; + + const OT::cff2::accelerator_t *cff; }; struct cff2_path_procs_path_t : path_procs_t diff --git a/test/api/test-draw.c b/test/api/test-draw.c index 4addac3ef..1df40c7d1 100644 --- a/test/api/test-draw.c +++ b/test/api/test-draw.c @@ -243,9 +243,10 @@ test_hb_draw_cff1 (void) .consumed = 0 }; g_assert (hb_font_draw_glyph (font, 3, funcs, &user_data)); - char expected[] = "M203,367C227,440 248,512 268,588L272,588C293,512 314,440 338,367L369,267L172,267Z" - "M3,0L88,0L151,200L390,200L452,0L541,0L319,656L225,656Z" - "M300,653L342,694L201,861L143,806Z"; + puts (str); + char expected[] = "M203,367C227,440 248,512 268,588L272,588C293,512 314,440 338,367L369,267L172,267L203,367Z" + "M3,0L88,0L151,200L390,200L452,0L541,0L319,656L225,656L3,0Z" + "M300,653L342,694L201,861L143,806L300,653Z"; g_assert_cmpmem (str, user_data.consumed, expected, sizeof (expected) - 1); hb_font_destroy (font); @@ -394,8 +395,9 @@ test_hb_draw_ttf_parser_tests (void) user_data.consumed = 0; g_assert (hb_font_draw_glyph (font, 1, funcs, &user_data)); - char expected[] = "M82,0L164,0L164,486L82,486ZM124,586C156,586 181,608 181,639" - "C181,671 156,692 124,692C92,692 67,671 67,639C67,608 92,586 124,586Z"; + char expected[] = "M82,0L164,0L164,486L82,486L82,0Z" + "M124,586C156,586 181,608 181,639C181,671 156,692 124,692" + "C92,692 67,671 67,639C67,608 92,586 124,586Z"; g_assert_cmpmem (str, user_data.consumed, expected, sizeof (expected) - 1); hb_font_destroy (font); @@ -492,8 +494,8 @@ test_hb_draw_font_kit_glyphs_tests (void) user_data.consumed = 0; g_assert (hb_font_draw_glyph (font, 5, funcs, &user_data)); - char expected[] = "M90,0L258,0C456,0 564,122 564,331C564,539 456,656 254,656L90,656ZM173,68" - "L173,588L248,588C401,588 478,496 478,331C478,165 401,68 248,68Z"; + char expected[] = "M90,0L258,0C456,0 564,122 564,331C564,539 456,656 254,656L90,656L90,0Z" + "M173,68L173,588L248,588C401,588 478,496 478,331C478,165 401,68 248,68L173,68Z"; g_assert_cmpmem (str, user_data.consumed, expected, sizeof (expected) - 1); hb_font_destroy (font);