Esempio n. 1
0
cairo_rectangle_list_t *
_cairo_clip_copy_rectangle_list (cairo_clip_t *clip, cairo_gstate_t *gstate)
{
    cairo_rectangle_list_t *list;
    cairo_rectangle_t *rectangles = NULL;
    int n_boxes = 0;

    if (clip->all_clipped)
	goto DONE;

    if (clip->path || clip->surface) {
	_cairo_error_throw (CAIRO_STATUS_CLIP_NOT_REPRESENTABLE);
	return (cairo_rectangle_list_t*) &_cairo_rectangles_not_representable;
    }

    if (clip->has_region) {
	cairo_box_int_t *boxes;
        int i;

	if (_cairo_region_get_boxes (&clip->region, &n_boxes, &boxes))
	    return (cairo_rectangle_list_t*) &_cairo_rectangles_nil;

	if (n_boxes) {
	    rectangles = _cairo_malloc_ab (n_boxes, sizeof (cairo_rectangle_t));
	    if (rectangles == NULL) {
		_cairo_region_boxes_fini (&clip->region, boxes);
		_cairo_error_throw (CAIRO_STATUS_NO_MEMORY);
		return (cairo_rectangle_list_t*) &_cairo_rectangles_nil;
	    }

	    for (i = 0; i < n_boxes; ++i) {
		cairo_rectangle_int_t clip_rect = { boxes[i].p1.x, boxes[i].p1.y,
						    boxes[i].p2.x - boxes[i].p1.x,
						    boxes[i].p2.y - boxes[i].p1.y };

		if (!_cairo_clip_int_rect_to_user(gstate, &clip_rect, &rectangles[i])) {
		    _cairo_error_throw (CAIRO_STATUS_CLIP_NOT_REPRESENTABLE);
		    _cairo_region_boxes_fini (&clip->region, boxes);
		    free (rectangles);
		    return (cairo_rectangle_list_t*) &_cairo_rectangles_not_representable;
		}
	    }
	}

	_cairo_region_boxes_fini (&clip->region, boxes);
    } else {
        cairo_rectangle_int_t extents;

	n_boxes = 1;

	rectangles = malloc(sizeof (cairo_rectangle_t));
	if (rectangles == NULL) {
	    _cairo_error_throw (CAIRO_STATUS_NO_MEMORY);
	    return (cairo_rectangle_list_t*) &_cairo_rectangles_nil;
	}

	if (_cairo_surface_get_extents (_cairo_gstate_get_target (gstate), &extents) ||
	    !_cairo_clip_int_rect_to_user(gstate, &extents, rectangles))
	{
	    _cairo_error_throw (CAIRO_STATUS_CLIP_NOT_REPRESENTABLE);
	    free (rectangles);
	    return (cairo_rectangle_list_t*) &_cairo_rectangles_not_representable;
	}
    }

 DONE:
    list = malloc (sizeof (cairo_rectangle_list_t));
    if (list == NULL) {
	_cairo_error_throw (CAIRO_STATUS_NO_MEMORY);
        free (rectangles);
        return (cairo_rectangle_list_t*) &_cairo_rectangles_nil;
    }

    list->status = CAIRO_STATUS_SUCCESS;
    list->rectangles = rectangles;
    list->num_rectangles = n_boxes;
    return list;
}
Esempio n. 2
0
cairo_rectangle_list_t *
_cairo_clip_copy_rectangle_list (cairo_clip_t *clip, cairo_gstate_t *gstate)
{
#define ERROR_LIST(S) _cairo_rectangle_list_create_in_error (_cairo_error (S))

    cairo_rectangle_list_t *list;
    cairo_rectangle_t *rectangles = NULL;
    cairo_region_t *region = NULL;
    cairo_int_status_t status;
    int n_rects = 0;
    int i;

    if (clip->all_clipped)
	goto DONE;

    if (!clip->path)
	return ERROR_LIST (CAIRO_STATUS_CLIP_NOT_REPRESENTABLE);

    status = _cairo_clip_get_region (clip, &region);
    if (status == CAIRO_INT_STATUS_NOTHING_TO_DO) {
	goto DONE;
    } else if (status == CAIRO_INT_STATUS_UNSUPPORTED) {
	return ERROR_LIST (CAIRO_STATUS_CLIP_NOT_REPRESENTABLE);
    } else if (unlikely (status)) {
	return ERROR_LIST (status);
    }

    n_rects = cairo_region_num_rectangles (region);
    if (n_rects) {
	rectangles = _cairo_malloc_ab (n_rects, sizeof (cairo_rectangle_t));
	if (unlikely (rectangles == NULL)) {
	    return ERROR_LIST (CAIRO_STATUS_NO_MEMORY);
	}

	for (i = 0; i < n_rects; ++i) {
	    cairo_rectangle_int_t clip_rect;

	    cairo_region_get_rectangle (region, i, &clip_rect);

	    if (! _cairo_clip_int_rect_to_user (gstate,
						&clip_rect,
						&rectangles[i]))
	    {
		free (rectangles);
		return ERROR_LIST (CAIRO_STATUS_CLIP_NOT_REPRESENTABLE);
	    }
	}
    }

 DONE:
    list = malloc (sizeof (cairo_rectangle_list_t));
    if (unlikely (list == NULL)) {
        free (rectangles);
	return ERROR_LIST (CAIRO_STATUS_NO_MEMORY);
    }

    list->status = CAIRO_STATUS_SUCCESS;
    list->rectangles = rectangles;
    list->num_rectangles = n_rects;
    return list;

#undef ERROR_LIST
}