cairo_surface_t * _cairo_analysis_surface_create (cairo_surface_t *target, int width, int height) { cairo_analysis_surface_t *surface; cairo_status_t status; status = target->status; if (unlikely (status)) return _cairo_surface_create_in_error (status); surface = malloc (sizeof (cairo_analysis_surface_t)); if (unlikely (surface == NULL)) return _cairo_surface_create_in_error (_cairo_error (CAIRO_STATUS_NO_MEMORY)); /* I believe the content type here is truly arbitrary. I'm quite * sure nothing will ever use this value. */ _cairo_surface_init (&surface->base, &cairo_analysis_surface_backend, CAIRO_CONTENT_COLOR_ALPHA); surface->width = width; surface->height = height; cairo_matrix_init_identity (&surface->ctm); surface->has_ctm = FALSE; surface->target = cairo_surface_reference (target); surface->first_op = TRUE; surface->has_supported = FALSE; surface->has_unsupported = FALSE; surface->page_bbox.p1.x = 0; surface->page_bbox.p1.y = 0; surface->page_bbox.p2.x = 0; surface->page_bbox.p2.y = 0; _cairo_region_init (&surface->supported_region); _cairo_region_init (&surface->fallback_region); if (width == -1 && height == -1) { surface->current_clip.x = CAIRO_RECT_INT_MIN; surface->current_clip.y = CAIRO_RECT_INT_MIN; surface->current_clip.width = CAIRO_RECT_INT_MAX - CAIRO_RECT_INT_MIN; surface->current_clip.height = CAIRO_RECT_INT_MAX - CAIRO_RECT_INT_MIN; } else { surface->current_clip.x = 0; surface->current_clip.y = 0; surface->current_clip.width = width; surface->current_clip.height = height; } return &surface->base; }
cairo_status_t _cairo_clip_init_copy (cairo_clip_t *clip, cairo_clip_t *other) { clip->mode = other->mode; clip->all_clipped = other->all_clipped; clip->surface = cairo_surface_reference (other->surface); clip->surface_rect = other->surface_rect; clip->serial = other->serial; _cairo_region_init (&clip->region); if (other->has_region) { cairo_status_t status; status = _cairo_region_copy (&clip->region, &other->region); if (status) { _cairo_region_fini (&clip->region); cairo_surface_destroy (clip->surface); return status; } clip->has_region = TRUE; } else { clip->has_region = FALSE; } clip->path = _cairo_clip_path_reference (other->path); return CAIRO_STATUS_SUCCESS; }
cairo_surface_t * _cairo_analysis_surface_create (cairo_surface_t *target) { cairo_analysis_surface_t *surface; cairo_status_t status; status = target->status; if (unlikely (status)) return _cairo_surface_create_in_error (status); surface = malloc (sizeof (cairo_analysis_surface_t)); if (unlikely (surface == NULL)) return _cairo_surface_create_in_error (_cairo_error (CAIRO_STATUS_NO_MEMORY)); /* I believe the content type here is truly arbitrary. I'm quite * sure nothing will ever use this value. */ _cairo_surface_init (&surface->base, &cairo_analysis_surface_backend, NULL, /* device */ CAIRO_CONTENT_COLOR_ALPHA, target->is_vector); cairo_matrix_init_identity (&surface->ctm); surface->has_ctm = FALSE; surface->target = cairo_surface_reference (target); surface->first_op = TRUE; surface->has_supported = FALSE; surface->has_unsupported = FALSE; _cairo_region_init (&surface->supported_region); _cairo_region_init (&surface->fallback_region); surface->page_bbox.p1.x = 0; surface->page_bbox.p1.y = 0; surface->page_bbox.p2.x = 0; surface->page_bbox.p2.y = 0; return &surface->base; }
static cairo_int_status_t _cairo_clip_intersect_region (cairo_clip_t *clip, cairo_traps_t *traps, cairo_surface_t *target) { cairo_region_t region; cairo_int_status_t status; if (clip->all_clipped) return CAIRO_STATUS_SUCCESS; if (clip->mode != CAIRO_CLIP_MODE_REGION) return CAIRO_INT_STATUS_UNSUPPORTED; status = _cairo_traps_extract_region (traps, ®ion); if (status) return status; status = CAIRO_STATUS_SUCCESS; if (!clip->has_region) { status = _cairo_region_copy (&clip->region, ®ion); if (status == CAIRO_STATUS_SUCCESS) clip->has_region = TRUE; } else { cairo_region_t intersection; _cairo_region_init (&intersection); status = _cairo_region_intersect (&intersection, &clip->region, ®ion); if (status == CAIRO_STATUS_SUCCESS) status = _cairo_region_copy (&clip->region, &intersection); _cairo_region_fini (&intersection); } clip->serial = _cairo_surface_allocate_clip_serial (target); _cairo_region_fini (®ion); if (! _cairo_region_not_empty (&clip->region)) _cairo_clip_set_all_clipped (clip, target); return status; }
void _cairo_clip_init (cairo_clip_t *clip, cairo_surface_t *target) { if (target) clip->mode = _cairo_surface_get_clip_mode (target); else clip->mode = CAIRO_CLIP_MODE_MASK; clip->all_clipped = FALSE; clip->surface = NULL; clip->surface_rect.x = 0; clip->surface_rect.y = 0; clip->surface_rect.width = 0; clip->surface_rect.height = 0; clip->serial = 0; _cairo_region_init (&clip->region); clip->has_region = FALSE; clip->path = NULL; }
void _cairo_clip_reset (cairo_clip_t *clip) { clip->all_clipped = FALSE; /* destroy any existing clip-region artifacts */ cairo_surface_destroy (clip->surface); clip->surface = NULL; clip->serial = 0; if (clip->has_region) { /* _cairo_region_fini just releases the resources used but * doesn't bother with leaving the region in a valid state. * So _cairo_region_init has to be called afterwards. */ _cairo_region_fini (&clip->region); _cairo_region_init (&clip->region); clip->has_region = FALSE; } _cairo_clip_path_destroy (clip->path); clip->path = NULL; }
/** * _cairo_traps_extract_region: * @traps: a #cairo_traps_t * @region: a #cairo_region_t * * Determines if a set of trapezoids are exactly representable as a * cairo region. If so, the passed-in region is initialized to * the area representing the given traps. It should be finalized * with _cairo_region_fini(). If not, %CAIRO_INT_STATUS_UNSUPPORTED * is returned. * * Return value: %CAIRO_STATUS_SUCCESS, %CAIRO_INT_STATUS_UNSUPPORTED * or %CAIRO_STATUS_NO_MEMORY **/ cairo_int_status_t _cairo_traps_extract_region (const cairo_traps_t *traps, cairo_region_t *region) { cairo_box_int_t stack_boxes[CAIRO_STACK_ARRAY_LENGTH (cairo_box_int_t)]; cairo_box_int_t *boxes = stack_boxes; int i, box_count; cairo_int_status_t status; if (traps->num_traps == 0) { _cairo_region_init (region); return CAIRO_STATUS_SUCCESS; } 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 || ! _cairo_fixed_is_integer (traps->traps[i].top) || ! _cairo_fixed_is_integer (traps->traps[i].bottom) || ! _cairo_fixed_is_integer (traps->traps[i].left.p1.x) || ! _cairo_fixed_is_integer (traps->traps[i].right.p1.x)) { return CAIRO_INT_STATUS_UNSUPPORTED; } } if (traps->num_traps > ARRAY_LENGTH (stack_boxes)) { boxes = _cairo_malloc_ab (traps->num_traps, sizeof (cairo_box_int_t)); if (unlikely (boxes == NULL)) return _cairo_error (CAIRO_STATUS_NO_MEMORY); } box_count = 0; for (i = 0; i < traps->num_traps; i++) { int x1 = _cairo_fixed_integer_part (traps->traps[i].left.p1.x); int y1 = _cairo_fixed_integer_part (traps->traps[i].top); int x2 = _cairo_fixed_integer_part (traps->traps[i].right.p1.x); int y2 = _cairo_fixed_integer_part (traps->traps[i].bottom); /* XXX: Sometimes we get degenerate trapezoids from the tesellator; * skip these. */ if (x1 == x2 || y1 == y2) continue; boxes[box_count].p1.x = x1; boxes[box_count].p1.y = y1; boxes[box_count].p2.x = x2; boxes[box_count].p2.y = y2; box_count++; } status = _cairo_region_init_boxes (region, boxes, box_count); if (boxes != stack_boxes) free (boxes); if (unlikely (status)) _cairo_region_fini (region); return status; }