Example #1
0
static void
_cairo_boxes_add_internal (cairo_boxes_t *boxes,
			   const cairo_box_t *box)
{
    struct _cairo_boxes_chunk *chunk;

    if (unlikely (boxes->status))
	return;

    chunk = boxes->tail;
    if (unlikely (chunk->count == chunk->size)) {
	int size;

	size = chunk->size * 2;
	chunk->next = _cairo_malloc_ab_plus_c (size,
					       sizeof (cairo_box_t),
					       sizeof (struct _cairo_boxes_chunk));

	if (unlikely (chunk->next == NULL)) {
	    boxes->status = _cairo_error (CAIRO_STATUS_NO_MEMORY);
	    return;
	}

	chunk = chunk->next;
	boxes->tail = chunk;

	chunk->next = NULL;
	chunk->count = 0;
	chunk->size = size;
	chunk->base = (cairo_box_t *) (chunk + 1);
    }

    chunk->base[chunk->count++] = *box;
    boxes->num_boxes++;

    if (boxes->is_pixel_aligned)
	boxes->is_pixel_aligned = _cairo_box_is_pixel_aligned (box);
}
static cairo_clip_t *
_cairo_clip_intersect_rectangle_box (cairo_clip_t *clip,
				     const cairo_rectangle_int_t *r,
				     const cairo_box_t *box)
{
    cairo_box_t extents_box;
    cairo_bool_t changed = FALSE;
    int i, j;

    if (clip == NULL) {
	clip = _cairo_clip_create ();
	if (clip == NULL)
	    return _cairo_clip_set_all_clipped (clip);
    }

    if (clip->num_boxes == 0) {
	clip->boxes = &clip->embedded_box;
	clip->boxes[0] = *box;
	clip->num_boxes = 1;
	if (clip->path == NULL) {
	    clip->extents = *r;
	} else {
	    if (! _cairo_rectangle_intersect (&clip->extents, r))
		clip = _cairo_clip_set_all_clipped (clip);
	}
	if (clip->path == NULL)
	    clip->is_region = _cairo_box_is_pixel_aligned (box);
	return clip;
    }

    /* Does the new box wholly subsume the clip? Perform a cheap check
     * for the common condition of a single clip rectangle.
     */
    if (clip->num_boxes == 1 &&
	clip->boxes[0].p1.x >= box->p1.x &&
	clip->boxes[0].p1.y >= box->p1.y &&
	clip->boxes[0].p2.x <= box->p2.x &&
	clip->boxes[0].p2.y <= box->p2.y)
    {
	return clip;
    }

    for (i = j = 0; i < clip->num_boxes; i++) {
	cairo_box_t *b = &clip->boxes[j];

	if (j != i)
	    *b = clip->boxes[i];

	if (box->p1.x > b->p1.x)
	    b->p1.x = box->p1.x, changed = TRUE;
	if (box->p2.x < b->p2.x)
	    b->p2.x = box->p2.x, changed = TRUE;

	if (box->p1.y > b->p1.y)
	    b->p1.y = box->p1.y, changed = TRUE;
	if (box->p2.y < b->p2.y)
	    b->p2.y = box->p2.y, changed = TRUE;

	j += b->p2.x > b->p1.x && b->p2.y > b->p1.y;
    }
    clip->num_boxes = j;

    if (clip->num_boxes == 0)
	return _cairo_clip_set_all_clipped (clip);

    if (! changed)
	return clip;

    extents_box = clip->boxes[0];
    for (i = 1; i < clip->num_boxes; i++) {
	    if (clip->boxes[i].p1.x < extents_box.p1.x)
		extents_box.p1.x = clip->boxes[i].p1.x;

	    if (clip->boxes[i].p1.y < extents_box.p1.y)
		extents_box.p1.y = clip->boxes[i].p1.y;

	    if (clip->boxes[i].p2.x > extents_box.p2.x)
		extents_box.p2.x = clip->boxes[i].p2.x;

	    if (clip->boxes[i].p2.y > extents_box.p2.y)
		extents_box.p2.y = clip->boxes[i].p2.y;
    }

    if (clip->path == NULL) {
	_cairo_box_round_to_rectangle (&extents_box, &clip->extents);
    } else {
	cairo_rectangle_int_t extents_rect;

	_cairo_box_round_to_rectangle (&extents_box, &extents_rect);
	if (! _cairo_rectangle_intersect (&clip->extents, &extents_rect))
	    return _cairo_clip_set_all_clipped (clip);
    }

    if (clip->region) {
	cairo_region_destroy (clip->region);
	clip->region = NULL;
    }

    clip->is_region = FALSE;
    return clip;
}