cairo_bool_t _cairo_traps_to_boxes (cairo_traps_t *traps, cairo_antialias_t antialias, cairo_boxes_t *boxes) { int i; for (i = 0; i < traps->num_traps; i++) { if (traps->traps[i].left.p1.x != traps->traps[i].left.p2.x || traps->traps[i].right.p1.x != traps->traps[i].right.p2.x) return FALSE; } _cairo_boxes_init (boxes); boxes->num_boxes = traps->num_traps; boxes->chunks.base = (cairo_box_t *) traps->traps; boxes->chunks.count = traps->num_traps; boxes->chunks.size = traps->num_traps; 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); } } return TRUE; }
static cairo_status_t _cairo_filler_ra_line_to (void *closure, const cairo_point_t *point) { cairo_filler_ra_t *filler = closure; cairo_status_t status; cairo_point_t p; p.x = _cairo_fixed_round_down (point->x); p.y = _cairo_fixed_round_down (point->y); status = _cairo_polygon_add_external_edge (filler->polygon, &filler->current_point, &p); filler->current_point = p; return status; }
static cairo_status_t _cairo_filler_ra_move_to (void *closure, const cairo_point_t *point) { cairo_filler_ra_t *filler = closure; cairo_status_t status; cairo_point_t p; /* close current subpath */ status = _cairo_filler_ra_close (closure); if (unlikely (status)) return status; p.x = _cairo_fixed_round_down (point->x); p.y = _cairo_fixed_round_down (point->y); /* make sure that the closure represents a degenerate path */ filler->current_point = p; filler->last_move_to = p; return CAIRO_STATUS_SUCCESS; }
cairo_status_t _cairo_boxes_add (cairo_boxes_t *boxes, cairo_antialias_t antialias, const cairo_box_t *box) { cairo_box_t b; if (antialias == CAIRO_ANTIALIAS_NONE) { b.p1.x = _cairo_fixed_round_down (box->p1.x); b.p1.y = _cairo_fixed_round_down (box->p1.y); b.p2.x = _cairo_fixed_round_down (box->p2.x); b.p2.y = _cairo_fixed_round_down (box->p2.y); box = &b; } if (box->p1.y == box->p2.y) return CAIRO_STATUS_SUCCESS; if (box->p1.x == box->p2.x) return CAIRO_STATUS_SUCCESS; if (boxes->num_limits) { cairo_point_t p1, p2; cairo_bool_t reversed = FALSE; int n; /* support counter-clockwise winding for rectangular tessellation */ if (box->p1.x < box->p2.x) { p1.x = box->p1.x; p2.x = box->p2.x; } else { p2.x = box->p1.x; p1.x = box->p2.x; reversed = ! reversed; } if (p1.x >= boxes->limit.p2.x || p2.x <= boxes->limit.p1.x) return CAIRO_STATUS_SUCCESS; if (box->p1.y < box->p2.y) { p1.y = box->p1.y; p2.y = box->p2.y; } else { p2.y = box->p1.y; p1.y = box->p2.y; reversed = ! reversed; } if (p1.y >= boxes->limit.p2.y || p2.y <= boxes->limit.p1.y) return CAIRO_STATUS_SUCCESS; for (n = 0; n < boxes->num_limits; n++) { const cairo_box_t *limits = &boxes->limits[n]; cairo_box_t _box; cairo_point_t _p1, _p2; if (p1.x >= limits->p2.x || p2.x <= limits->p1.x) continue; if (p1.y >= limits->p2.y || p2.y <= limits->p1.y) continue; /* Otherwise, clip the box to the limits. */ _p1 = p1; if (_p1.x < limits->p1.x) _p1.x = limits->p1.x; if (_p1.y < limits->p1.y) _p1.y = limits->p1.y; _p2 = p2; if (_p2.x > limits->p2.x) _p2.x = limits->p2.x; if (_p2.y > limits->p2.y) _p2.y = limits->p2.y; if (_p2.y <= _p1.y || _p2.x <= _p1.x) continue; _box.p1.y = _p1.y; _box.p2.y = _p2.y; if (reversed) { _box.p1.x = _p2.x; _box.p2.x = _p1.x; } else { _box.p1.x = _p1.x; _box.p2.x = _p2.x; } _cairo_boxes_add_internal (boxes, &_box); } } else { _cairo_boxes_add_internal (boxes, box); } return boxes->status; }