Skip to content

Commit

Permalink
XCB: Use consistent rounding modes for a1 rasterisation.
Browse files Browse the repository at this point in the history
This ports commits 36b4b06 and 7ab9ce1 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>
  • Loading branch information
Uli Schlachter authored and Chris Wilson committed Oct 21, 2010
1 parent b80bcf6 commit fae8805
Showing 1 changed file with 50 additions and 30 deletions.
80 changes: 50 additions & 30 deletions src/cairo-xcb-surface-render.c
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -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,
Expand All @@ -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,
Expand Down Expand Up @@ -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
Expand Down Expand Up @@ -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;

Expand All @@ -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);
}
}
}
Expand Down Expand Up @@ -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);
Expand Down

0 comments on commit fae8805

Please sign in to comment.