path: Add stroke_is_rectilinear flag

Stroke and fill rectilinearity cannot be represented by a single flag
without missing the opportunity of considering some strokes
rectilinear.
This commit is contained in:
Andrea Canciani 2010-10-28 17:56:37 +02:00
parent 166453c1ab
commit e48cb95493
3 changed files with 33 additions and 27 deletions

View file

@ -84,7 +84,8 @@ struct _cairo_path_fixed {
unsigned int needs_move_to : 1;
unsigned int has_extents : 1;
unsigned int has_curve_to : 1;
unsigned int is_rectilinear : 1;
unsigned int stroke_is_rectilinear : 1;
unsigned int fill_is_rectilinear : 1;
unsigned int maybe_fill_region : 1;
unsigned int is_empty_fill : 1;
@ -142,8 +143,8 @@ _cairo_path_fixed_fill_is_empty (const cairo_path_fixed_t *path)
static inline cairo_bool_t
_cairo_path_fixed_fill_is_rectilinear (const cairo_path_fixed_t *path)
{
if (! path->is_rectilinear)
return 0;
if (! path->fill_is_rectilinear)
return FALSE;
if (! path->has_current_point || path->needs_move_to)
return TRUE;
@ -156,7 +157,7 @@ _cairo_path_fixed_fill_is_rectilinear (const cairo_path_fixed_t *path)
static inline cairo_bool_t
_cairo_path_fixed_stroke_is_rectilinear (const cairo_path_fixed_t *path)
{
return path->is_rectilinear;
return path->stroke_is_rectilinear;
}
static inline cairo_bool_t

View file

@ -103,7 +103,8 @@ _cairo_path_fixed_init (cairo_path_fixed_t *path)
path->needs_move_to = TRUE;
path->has_extents = FALSE;
path->has_curve_to = FALSE;
path->is_rectilinear = TRUE;
path->stroke_is_rectilinear = TRUE;
path->fill_is_rectilinear = TRUE;
path->maybe_fill_region = TRUE;
path->is_empty_fill = TRUE;
@ -134,7 +135,8 @@ _cairo_path_fixed_init_copy (cairo_path_fixed_t *path,
path->needs_move_to = other->needs_move_to;
path->has_extents = other->has_extents;
path->has_curve_to = other->has_curve_to;
path->is_rectilinear = other->is_rectilinear;
path->stroke_is_rectilinear = other->stroke_is_rectilinear;
path->fill_is_rectilinear = other->fill_is_rectilinear;
path->maybe_fill_region = other->maybe_fill_region;
path->is_empty_fill = other->is_empty_fill;
@ -466,11 +468,11 @@ _cairo_path_fixed_new_sub_path (cairo_path_fixed_t *path)
{
if (! path->needs_move_to) {
/* If the current subpath doesn't need_move_to, it contains at least one command */
if (path->is_rectilinear) {
if (path->fill_is_rectilinear) {
/* Implicitly close for fill */
path->is_rectilinear = path->current_point.x == path->last_move_point.x ||
path->current_point.y == path->last_move_point.y;
path->maybe_fill_region &= path->is_rectilinear;
path->fill_is_rectilinear = path->current_point.x == path->last_move_point.x ||
path->current_point.y == path->last_move_point.y;
path->maybe_fill_region &= path->fill_is_rectilinear;
}
path->needs_move_to = TRUE;
}
@ -554,19 +556,19 @@ _cairo_path_fixed_line_to (cairo_path_fixed_t *path,
}
}
if (path->is_rectilinear) {
path->is_rectilinear = path->current_point.x == x ||
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);
}
if (path->is_empty_fill) {
path->is_empty_fill = path->current_point.x == x &&
path->current_point.y == y;
if (path->stroke_is_rectilinear) {
path->stroke_is_rectilinear = path->current_point.x == x ||
path->current_point.y == y;
path->fill_is_rectilinear &= path->stroke_is_rectilinear;
path->maybe_fill_region &= path->fill_is_rectilinear;
if (path->maybe_fill_region) {
path->maybe_fill_region = _cairo_fixed_is_integer (x) &&
_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 = point;
@ -630,7 +632,8 @@ _cairo_path_fixed_curve_to (cairo_path_fixed_t *path,
path->current_point = point[2];
path->has_curve_to = TRUE;
path->is_rectilinear = FALSE;
path->stroke_is_rectilinear = FALSE;
path->fill_is_rectilinear = FALSE;
path->maybe_fill_region = FALSE;
path->is_empty_fill = FALSE;
@ -1204,7 +1207,7 @@ _cairo_path_fixed_is_box (const cairo_path_fixed_t *path,
{
const cairo_path_buf_t *buf = cairo_path_head (path);
if (! path->is_rectilinear)
if (! path->fill_is_rectilinear)
return FALSE;
/* Do we have the right number of ops? */

View file

@ -120,7 +120,8 @@ static const cairo_t _cairo_nil = {
TRUE, /* needs_move_to */
FALSE, /* has_extents */
FALSE, /* has_curve_to */
FALSE, /* is_box */
TRUE, /* stroke_is_rectilinear */
TRUE, /* fill_is_rectilinear */
FALSE, /* maybe_fill_region */
TRUE, /* is_empty_fill */
{ {0, 0}, {0, 0}}, /* extents */
@ -142,7 +143,8 @@ static const cairo_t _cairo_nil__null_pointer = {
TRUE, /* needs_move_to */
FALSE, /* has_extents */
FALSE, /* has_curve_to */
FALSE, /* is_box */
TRUE, /* stroke_is_rectilinear */
TRUE, /* fill_is_rectilinear */
FALSE, /* maybe_fill_region */
TRUE, /* is_empty_fill */
{ {0, 0}, {0, 0}}, /* extents */