mirror of
https://gitlab.freedesktop.org/cairo/cairo.git
synced 2026-05-08 10:18:02 +02:00
[path] Extend identical lines.
If a subsequent PATH_OP is just a continuation of the previous line, i.e. it has the same gradient, then just replace the end-point of the previous line with the new point rather than adding a new operation. Surprisingly this occurs in the wild, but the main motivation is a future optimisation to reduce the number of intersections during stroke-to-path.
This commit is contained in:
parent
85b688a3f6
commit
cb30c1f367
2 changed files with 35 additions and 3 deletions
|
|
@ -445,22 +445,47 @@ _cairo_path_fixed_line_to (cairo_path_fixed_t *path,
|
|||
if (! path->has_current_point) {
|
||||
status = _cairo_path_fixed_move_to (path, point.x, point.y);
|
||||
} else {
|
||||
/* If the previous op was also a LINE_TO with the same gradient,
|
||||
* then just change its end-point rather than adding a new op.
|
||||
*/
|
||||
if (_cairo_path_last_op (path) == CAIRO_PATH_OP_LINE_TO) {
|
||||
cairo_path_buf_t *buf;
|
||||
cairo_point_t *p;
|
||||
cairo_slope_t prev, self;
|
||||
|
||||
buf = cairo_path_tail (path);
|
||||
if (likely (buf->num_points >= 2)) {
|
||||
p = &buf->points[buf->num_points-2];
|
||||
} else {
|
||||
cairo_path_buf_t *prev_buf = cairo_path_buf_prev (buf);
|
||||
p = &prev_buf->points[prev_buf->num_points - (2 - buf->num_points)];
|
||||
}
|
||||
_cairo_slope_init (&prev, p, &path->current_point);
|
||||
_cairo_slope_init (&self, &path->current_point, &point);
|
||||
if (_cairo_slope_equal (&prev, &self)) {
|
||||
buf->points[buf->num_points - 1] = point;
|
||||
status = CAIRO_STATUS_SUCCESS;
|
||||
goto DONE;
|
||||
}
|
||||
}
|
||||
|
||||
status = _cairo_path_fixed_add (path, CAIRO_PATH_OP_LINE_TO, &point, 1);
|
||||
if (path->is_rectilinear) {
|
||||
path->is_rectilinear = path->current_point.x == x ||
|
||||
path->current_point.y == y;
|
||||
path->current_point.y == y;
|
||||
path->maybe_fill_region &= path->is_rectilinear;
|
||||
}
|
||||
if (path->maybe_fill_region) {
|
||||
path->maybe_fill_region = _cairo_fixed_is_integer (x) &&
|
||||
_cairo_fixed_is_integer (y);
|
||||
_cairo_fixed_is_integer (y);
|
||||
}
|
||||
if (path->is_empty_fill) {
|
||||
path->is_empty_fill = path->current_point.x == x &&
|
||||
path->current_point.y == y;
|
||||
path->current_point.y == y;
|
||||
}
|
||||
}
|
||||
|
||||
DONE:
|
||||
path->current_point = point;
|
||||
path->has_current_point = TRUE;
|
||||
|
||||
|
|
|
|||
|
|
@ -2726,6 +2726,13 @@ CAIRO_END_DECLS
|
|||
#include "cairo-malloc-private.h"
|
||||
#include "cairo-hash-private.h"
|
||||
|
||||
static inline cairo_bool_t
|
||||
_cairo_slope_equal (const cairo_slope_t *a, const cairo_slope_t *b)
|
||||
{
|
||||
return _cairo_int64_eq (_cairo_int32x32_64_mul (a->dy, b->dx),
|
||||
_cairo_int32x32_64_mul (b->dy, a->dx));
|
||||
}
|
||||
|
||||
#if HAVE_VALGRIND
|
||||
#include <memcheck.h>
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue