[draw] Skip commands and paths not contributing anything

They aren't contributing to rendering and making issue for stroking, let's skip them
ourselves as Skia does also https://skia-review.googlesource.com/c/skia/+/268166

They are useful for extracting extents and so which that functionality won't be effected by this change.
This commit is contained in:
Ebrahim Byagowi 2020-02-26 15:58:11 +03:30
parent 073d4954e0
commit 84163c83d3
3 changed files with 27 additions and 11 deletions

View File

@ -59,6 +59,7 @@ struct draw_helper_t
void line_to (hb_position_t x, hb_position_t y) void line_to (hb_position_t x, hb_position_t y)
{ {
if (equal_to_current (x, y)) return;
if (!path_open) start_path (); if (!path_open) start_path ();
funcs->line_to (x, y, user_data); funcs->line_to (x, y, user_data);
current_x = x; current_x = x;
@ -69,6 +70,8 @@ struct draw_helper_t
quadratic_to (hb_position_t control_x, hb_position_t control_y, quadratic_to (hb_position_t control_x, hb_position_t control_y,
hb_position_t to_x, hb_position_t to_y) hb_position_t to_x, hb_position_t to_y)
{ {
if (equal_to_current (control_x, control_y) && equal_to_current (to_x, to_y))
return;
if (!path_open) start_path (); if (!path_open) start_path ();
if (funcs->is_quadratic_to_set) if (funcs->is_quadratic_to_set)
funcs->quadratic_to (control_x, control_y, to_x, to_y, user_data); funcs->quadratic_to (control_x, control_y, to_x, to_y, user_data);
@ -83,14 +86,18 @@ struct draw_helper_t
} }
void void
cubic_to (hb_position_t x1, hb_position_t y1, cubic_to (hb_position_t control1_x, hb_position_t control1_y,
hb_position_t x2, hb_position_t y2, hb_position_t control2_x, hb_position_t control2_y,
hb_position_t x3, hb_position_t y3) hb_position_t to_x, hb_position_t to_y)
{ {
if (equal_to_current (control1_x, control1_y) &&
equal_to_current (control2_x, control2_y) &&
equal_to_current (to_x, to_y))
return;
if (!path_open) start_path (); if (!path_open) start_path ();
funcs->cubic_to (x1, y1, x2, y2, x3, y3, user_data); funcs->cubic_to (control1_x, control1_y, control2_x, control2_y, to_x, to_y, user_data);
current_x = x3; current_x = to_x;
current_y = y3; current_y = to_y;
} }
void end_path () void end_path ()
@ -106,6 +113,9 @@ struct draw_helper_t
} }
protected: protected:
bool equal_to_current (hb_position_t x, hb_position_t y)
{ return current_x == x && current_y == y; }
void start_path () void start_path ()
{ {
if (path_open) end_path (); if (path_open) end_path ();

View File

@ -769,8 +769,8 @@ test_hb_draw_stroking (void)
user_data.consumed = 0; user_data.consumed = 0;
g_assert (hb_font_draw_glyph (font, 6, funcs, &user_data)); g_assert (hb_font_draw_glyph (font, 6, funcs, &user_data));
char expected[] = "M1626,1522Q1626,1522 1626,1522Q1626,1522 1626,1522ZM436,1522" /* Skip empty path where all the points of a path are equal */
"Q436,1280 531,1060Q625,839 784,680Q943,521 1164,427Q1384,332 1626,332" char expected[] = "M436,1522Q436,1280 531,1060Q625,839 784,680Q943,521 1164,427Q1384,332 1626,332"
"Q1868,332 2089,427Q2309,521 2468,680Q2627,839 2722,1060Q2816,1280 2816,1522" "Q1868,332 2089,427Q2309,521 2468,680Q2627,839 2722,1060Q2816,1280 2816,1522"
"Q2816,1764 2722,1985Q2627,2205 2468,2364Q2309,2523 2089,2618Q1868,2712 1626,2712" "Q2816,1764 2722,1985Q2627,2205 2468,2364Q2309,2523 2089,2618Q1868,2712 1626,2712"
"Q1384,2712 1164,2618Q943,2523 784,2364Q625,2205 531,1985Q436,1764 436,1522ZM256,1528" "Q1384,2712 1164,2618Q943,2523 784,2364Q625,2205 531,1985Q436,1764 436,1522ZM256,1528"
@ -810,8 +810,8 @@ test_hb_draw_stroking (void)
user_data.consumed = 0; user_data.consumed = 0;
g_assert (hb_font_draw_glyph (font, 4, funcs, &user_data)); g_assert (hb_font_draw_glyph (font, 4, funcs, &user_data));
char expected[] = "M397,372L397,372Z" /* TODO: Do we like to fold this path? */ /* Skip empty path in CFF */
"M106,372C106,532 237,662 397,662C557,662 688,532 688,372C688,212 557,81 397,81C237,81 106,212 106,372Z" char expected[] = "M106,372C106,532 237,662 397,662C557,662 688,532 688,372C688,212 557,81 397,81C237,81 106,212 106,372Z"
"M62,373C62,188 212,39 397,39C582,39 731,188 731,373C731,558 582,708 397,708C212,708 62,558 62,373Z"; "M62,373C62,188 212,39 397,39C582,39 731,188 731,373C731,558 582,708 397,708C212,708 62,558 62,373Z";
g_assert_cmpmem (str, user_data.consumed, expected, sizeof (expected) - 1); g_assert_cmpmem (str, user_data.consumed, expected, sizeof (expected) - 1);

View File

@ -36,17 +36,20 @@ _line_to (hb_position_t to_x, hb_position_t to_y, void *user_data_)
{ {
_user_data_t *user_data = (_user_data_t *) user_data_; _user_data_t *user_data = (_user_data_t *) user_data_;
assert (user_data->is_open); assert (user_data->is_open);
assert (user_data->path_last_x != to_x || user_data->path_last_y != to_y);
++user_data->path_len; ++user_data->path_len;
user_data->path_last_x = to_x; user_data->path_last_x = to_x;
user_data->path_last_y = to_y; user_data->path_last_y = to_y;
} }
static void static void
_quadratic_to (hb_position_t control_x HB_UNUSED, hb_position_t control_y HB_UNUSED, _quadratic_to (hb_position_t control_x, hb_position_t control_y,
hb_position_t to_x, hb_position_t to_y, void *user_data_) hb_position_t to_x, hb_position_t to_y, void *user_data_)
{ {
_user_data_t *user_data = (_user_data_t *) user_data_; _user_data_t *user_data = (_user_data_t *) user_data_;
assert (user_data->is_open); assert (user_data->is_open);
assert (user_data->path_last_x != control_x || user_data->path_last_y != control_y ||
user_data->path_last_x != to_x || user_data->path_last_y != to_y);
++user_data->path_len; ++user_data->path_len;
user_data->path_last_x = to_x; user_data->path_last_x = to_x;
user_data->path_last_y = to_y; user_data->path_last_y = to_y;
@ -59,6 +62,9 @@ _cubic_to (hb_position_t control1_x HB_UNUSED, hb_position_t control1_y HB_UNUSE
{ {
_user_data_t *user_data = (_user_data_t *) user_data_; _user_data_t *user_data = (_user_data_t *) user_data_;
assert (user_data->is_open); assert (user_data->is_open);
assert (user_data->path_last_x != control1_x || user_data->path_last_y != control1_y ||
user_data->path_last_x != control2_x || user_data->path_last_y != control2_y ||
user_data->path_last_x != to_x || user_data->path_last_y != to_y);
++user_data->path_len; ++user_data->path_len;
user_data->path_last_x = to_x; user_data->path_last_x = to_x;
user_data->path_last_y = to_y; user_data->path_last_y = to_y;