[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:
Chris Wilson 2009-08-04 13:59:03 +01:00
parent 85b688a3f6
commit cb30c1f367
2 changed files with 35 additions and 3 deletions

View file

@ -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;

View file

@ -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>