summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorUli Schlachter <psychon@znc.in>2010-10-17 17:47:22 +0200
committerChris Wilson <chris@chris-wilson.co.uk>2010-10-21 12:18:27 +0100
commitfae88051c18722566d15b96a1b23bfde1844c3ee (patch)
tree62f53626f78b05d3299a91f82c04b972289fd8a9 /src
parentb80bcf66b284deeb4d44d68a860a1e7857136982 (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.c80
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);