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

View File

@ -769,8 +769,8 @@ test_hb_draw_stroking (void)
user_data.consumed = 0;
g_assert (hb_font_draw_glyph (font, 6, funcs, &user_data));
char expected[] = "M1626,1522Q1626,1522 1626,1522Q1626,1522 1626,1522ZM436,1522"
"Q436,1280 531,1060Q625,839 784,680Q943,521 1164,427Q1384,332 1626,332"
/* Skip empty path where all the points of a path are equal */
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"
"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"
@ -810,8 +810,8 @@ test_hb_draw_stroking (void)
user_data.consumed = 0;
g_assert (hb_font_draw_glyph (font, 4, funcs, &user_data));
char expected[] = "M397,372L397,372Z" /* TODO: Do we like to fold this path? */
"M106,372C106,532 237,662 397,662C557,662 688,532 688,372C688,212 557,81 397,81C237,81 106,212 106,372Z"
/* Skip empty path in CFF */
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";
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_;
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_last_x = to_x;
user_data->path_last_y = to_y;
}
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_)
{
_user_data_t *user_data = (_user_data_t *) user_data_;
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_last_x = to_x;
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_;
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_last_x = to_x;
user_data->path_last_y = to_y;