diff options
author | Uli Schlachter <psychon@znc.in> | 2010-10-17 17:47:22 +0200 |
---|---|---|
committer | Chris Wilson <chris@chris-wilson.co.uk> | 2010-10-21 12:18:27 +0100 |
commit | fae88051c18722566d15b96a1b23bfde1844c3ee (patch) | |
tree | 62f53626f78b05d3299a91f82c04b972289fd8a9 /src | |
parent | b80bcf66b284deeb4d44d68a860a1e7857136982 (diff) |
XCB: Use consistent rounding modes for a1 rasterisation.
This ports commits 36b4b0631 and 7ab9ce1b9 from the image backend to xcb. Look
there for an explanation of why this is correct, I only copied this over and the
test suite said it was good. :-)
This fixes unantialiased-shapes, a1-rasterisation-rectangles and
a1-rasterisation-triangles.
Signed-off-by: Uli Schlachter <psychon@znc.in>
Diffstat (limited to 'src')
-rw-r--r-- | src/cairo-xcb-surface-render.c | 80 |
1 files changed, 50 insertions, 30 deletions
diff --git a/src/cairo-xcb-surface-render.c b/src/cairo-xcb-surface-render.c index e98148a6..f7db4910 100644 --- a/src/cairo-xcb-surface-render.c +++ b/src/cairo-xcb-surface-render.c @@ -1489,10 +1489,10 @@ _render_fill_boxes (void *abstract_dst, int i, j; for (i = j = 0; i < chunk->count; i++) { - int x1 = _cairo_fixed_integer_round (chunk->base[i].p1.x); - int y1 = _cairo_fixed_integer_round (chunk->base[i].p1.y); - int x2 = _cairo_fixed_integer_round (chunk->base[i].p2.x); - int y2 = _cairo_fixed_integer_round (chunk->base[i].p2.y); + int x1 = _cairo_fixed_integer_round_down (chunk->base[i].p1.x); + int y1 = _cairo_fixed_integer_round_down (chunk->base[i].p1.y); + int x2 = _cairo_fixed_integer_round_down (chunk->base[i].p2.x); + int y2 = _cairo_fixed_integer_round_down (chunk->base[i].p2.y); if (x2 > x1 && y2 > y1) { xrects[j].x = x1; @@ -1552,10 +1552,10 @@ _render_composite_boxes (cairo_xcb_surface_t *dst, int i; for (i = 0; i < chunk->count; i++) { - int x = _cairo_fixed_integer_round (box[i].p1.x); - int y = _cairo_fixed_integer_round (box[i].p1.y); - int width = _cairo_fixed_integer_round (box[i].p2.x) - x; - int height = _cairo_fixed_integer_round (box[i].p2.y) - y; + int x = _cairo_fixed_integer_round_down (box[i].p1.x); + int y = _cairo_fixed_integer_round_down (box[i].p1.y); + int width = _cairo_fixed_integer_round_down (box[i].p2.x) - x; + int height = _cairo_fixed_integer_round_down (box[i].p2.y) - y; if (width && height) { _cairo_xcb_connection_render_composite (dst->connection, @@ -1580,10 +1580,10 @@ _render_composite_boxes (cairo_xcb_surface_t *dst, int i; for (i = 0; i < chunk->count; i++) { - int x = _cairo_fixed_integer_round (box[i].p1.x); - int y = _cairo_fixed_integer_round (box[i].p1.y); - int width = _cairo_fixed_integer_round (box[i].p2.x) - x; - int height = _cairo_fixed_integer_round (box[i].p2.y) - y; + int x = _cairo_fixed_integer_round_down (box[i].p1.x); + int y = _cairo_fixed_integer_round_down (box[i].p1.y); + int width = _cairo_fixed_integer_round_down (box[i].p2.x) - x; + int height = _cairo_fixed_integer_round_down (box[i].p2.y) - y; if (width && height) { _cairo_xcb_connection_render_composite (dst->connection, @@ -2817,7 +2817,7 @@ _clip_and_composite_boxes (cairo_xcb_surface_t *dst, static cairo_bool_t _mono_edge_is_vertical (const cairo_line_t *line) { - return _cairo_fixed_integer_round (line->p1.x) == _cairo_fixed_integer_round (line->p2.x); + return _cairo_fixed_integer_round_down (line->p1.x) == _cairo_fixed_integer_round_down (line->p2.x); } static cairo_bool_t @@ -2855,7 +2855,8 @@ _traps_are_pixel_aligned (cairo_traps_t *traps, static void _boxes_for_traps (cairo_boxes_t *boxes, - cairo_traps_t *traps) + cairo_traps_t *traps, + cairo_antialias_t antialias) { int i; @@ -2866,21 +2867,40 @@ _boxes_for_traps (cairo_boxes_t *boxes, boxes->chunks.count = traps->num_traps; boxes->chunks.size = traps->num_traps; - for (i = 0; i < traps->num_traps; i++) { - cairo_fixed_t x1 = traps->traps[i].left.p1.x; - cairo_fixed_t x2 = traps->traps[i].right.p1.x; - cairo_fixed_t y1 = traps->traps[i].top; - cairo_fixed_t y2 = traps->traps[i].bottom; - - boxes->chunks.base[i].p1.x = x1; - boxes->chunks.base[i].p1.y = y1; - boxes->chunks.base[i].p2.x = x2; - boxes->chunks.base[i].p2.y = y2; - - if (boxes->is_pixel_aligned) { - boxes->is_pixel_aligned = - _cairo_fixed_is_integer (x1) && _cairo_fixed_is_integer (y1) && - _cairo_fixed_is_integer (x2) && _cairo_fixed_is_integer (y2); + if (antialias != CAIRO_ANTIALIAS_NONE) { + for (i = 0; i < traps->num_traps; i++) { + /* Note the traps and boxes alias so we need to take the local copies first. */ + cairo_fixed_t x1 = traps->traps[i].left.p1.x; + cairo_fixed_t x2 = traps->traps[i].right.p1.x; + cairo_fixed_t y1 = traps->traps[i].top; + cairo_fixed_t y2 = traps->traps[i].bottom; + + boxes->chunks.base[i].p1.x = x1; + boxes->chunks.base[i].p1.y = y1; + boxes->chunks.base[i].p2.x = x2; + boxes->chunks.base[i].p2.y = y2; + + if (boxes->is_pixel_aligned) { + boxes->is_pixel_aligned = + _cairo_fixed_is_integer (x1) && _cairo_fixed_is_integer (y1) && + _cairo_fixed_is_integer (x2) && _cairo_fixed_is_integer (y2); + } + } + } else { + boxes->is_pixel_aligned = TRUE; + + for (i = 0; i < traps->num_traps; i++) { + /* Note the traps and boxes alias so we need to take the local copies first. */ + cairo_fixed_t x1 = traps->traps[i].left.p1.x; + cairo_fixed_t x2 = traps->traps[i].right.p1.x; + cairo_fixed_t y1 = traps->traps[i].top; + cairo_fixed_t y2 = traps->traps[i].bottom; + + /* round down here to match Pixman's behavior when using traps. */ + boxes->chunks.base[i].p1.x = _cairo_fixed_round_down (x1); + boxes->chunks.base[i].p1.y = _cairo_fixed_round_down (y1); + boxes->chunks.base[i].p2.x = _cairo_fixed_round_down (x2); + boxes->chunks.base[i].p2.y = _cairo_fixed_round_down (y2); } } } @@ -3316,7 +3336,7 @@ _cairo_xcb_surface_render_composite_polygon (cairo_xcb_surface_t *dst, { cairo_boxes_t boxes; - _boxes_for_traps (&boxes, &traps.traps); + _boxes_for_traps (&boxes, &traps.traps, antialias); status = _clip_and_composite_boxes (dst, op, source, &boxes, antialias, extents, clip); |