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; }
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, ®ion); 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 }