Beispiel #1
0
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;
}
Beispiel #4
0
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;
}