static __inline int FbClipImageReg (pixman_region16_t *region, pixman_region16_t *clip, int dx, int dy) { if (pixman_region_num_rects (region) == 1 && pixman_region_num_rects (clip) == 1) { pixman_box16_t *pRbox = pixman_region_rects (region); pixman_box16_t *pCbox = pixman_region_rects (clip); int v; if (pRbox->x1 < (v = pCbox->x1 + dx)) pRbox->x1 = BOUND(v); if (pRbox->x2 > (v = pCbox->x2 + dx)) pRbox->x2 = BOUND(v); if (pRbox->y1 < (v = pCbox->y1 + dy)) pRbox->y1 = BOUND(v); if (pRbox->y2 > (v = pCbox->y2 + dy)) pRbox->y2 = BOUND(v); if (pRbox->x1 >= pRbox->x2 || pRbox->y1 >= pRbox->y2) { pixman_region_empty (region); } } else { pixman_region_translate (region, dx, dy); pixman_region_intersect (region, clip, region); pixman_region_translate (region, -dx, -dy); } return 1; }
static cairo_int_status_t _cairo_beos_surface_set_clip_region (void *abstract_surface, pixman_region16_t *region) { fprintf(stderr, "Setting clip region\n"); cairo_beos_surface_t *surface = reinterpret_cast<cairo_beos_surface_t*>( abstract_surface); AutoLockView locker(surface->view); if (!locker) return CAIRO_INT_STATUS_SUCCESS; if (region == NULL) { // No clipping surface->view->ConstrainClippingRegion(NULL); return CAIRO_INT_STATUS_SUCCESS; } int count = pixman_region_num_rects(region); pixman_box16_t* rects = pixman_region_rects(region); BRegion bregion; for (int i = 0; i < count; ++i) { // Have to substract one, because for pixman, the second coordinate // lies outside the rectangle. bregion.Include(BRect(rects[i].x1, rects[i].y1, rects[i].x2 - 1, rects[i].y2 - 1)); } surface->view->ConstrainClippingRegion(&bregion); return CAIRO_INT_STATUS_SUCCESS; }
static cairo_int_status_t _cairo_xynth_surface_set_clip_region (void *abstract_surface, pixman_region16_t *region) { int i; int nboxes; pixman_box16_t *boxes; s_rect_t *render_rects; cairo_xynth_surface_t *surface; ENTER(); surface = (cairo_xynth_surface_t *) abstract_surface; nboxes = pixman_region_num_rects(region); if (nboxes > 0) { render_rects = (s_rect_t *) malloc(sizeof(s_rect_t) * nboxes); if (render_rects == NULL) { LEAVE(); return CAIRO_STATUS_NO_MEMORY; } } else { nboxes = 0; render_rects = NULL; } boxes = pixman_region_rects(region); for (i = 0; i < nboxes; i++) { render_rects[i].x = boxes[i].x1; render_rects[i].y = boxes[i].y1; render_rects[i].w = boxes[i].x2 - boxes[i].x1; render_rects[i].h = boxes[i].y2 - boxes[i].y1; } s_render_set_clip(surface->render, nboxes, render_rects); free(render_rects); LEAVE(); return CAIRO_STATUS_SUCCESS; }
static cairo_bool_t _cairo_region_to_clip_rectangles (pixman_region16_t *region, int max_rectangles, cairo_clip_rect_t *rectangles_out, int *num_rectangles_out) { int n_boxes, i; pixman_box16_t *boxes; /* no region -> we can't represent it as rectangles */ if (region == NULL) return FALSE; n_boxes = pixman_region_num_rects (region); *num_rectangles_out = n_boxes; if (n_boxes > max_rectangles) return FALSE; boxes = pixman_region_rects (region); for (i = 0; i < n_boxes; i++) { rectangles_out[i].x = boxes[i].x1; rectangles_out[i].y = boxes[i].y1; rectangles_out[i].width = boxes[i].x2 - boxes[i].x1; rectangles_out[i].height = boxes[i].y2 - boxes[i].y1; } return TRUE; }
static cairo_int_status_t _cairo_xcb_surface_set_clip_region (void *abstract_surface, pixman_region16_t *region) { cairo_xcb_surface_t *surface = abstract_surface; if (surface->clip_rects) { free (surface->clip_rects); surface->clip_rects = NULL; } surface->num_clip_rects = 0; if (region == NULL) { if (surface->gc.xid) { CARD32 mask = XCBGCClipMask; CARD32 pa[] = { XCBNone }; XCBChangeGC (surface->dpy, surface->gc, mask, pa); } if (surface->has_format && surface->picture.xid) { CARD32 mask = XCBRenderCPClipMask; CARD32 pa[] = { XCBNone }; XCBRenderChangePicture (surface->dpy, surface->picture, mask, pa); } } else { pixman_box16_t *boxes; XCBRECTANGLE *rects = NULL; int n_boxes, i; n_boxes = pixman_region_num_rects (region); if (n_boxes > 0) { rects = malloc (sizeof(XCBRECTANGLE) * n_boxes); if (rects == NULL) return CAIRO_STATUS_NO_MEMORY; } else { rects = NULL; } boxes = pixman_region_rects (region); for (i = 0; i < n_boxes; i++) { rects[i].x = boxes[i].x1; rects[i].y = boxes[i].y1; rects[i].width = boxes[i].x2 - boxes[i].x1; rects[i].height = boxes[i].y2 - boxes[i].y1; } surface->clip_rects = rects; surface->num_clip_rects = n_boxes; if (surface->gc.xid) _cairo_xcb_surface_set_gc_clip_rects (surface); if (surface->picture.xid) _cairo_xcb_surface_set_picture_clip_rects (surface); } return CAIRO_STATUS_SUCCESS; }
/* Composites a region representing a set of trapezoids. */ static cairo_status_t _composite_trap_region (cairo_clip_t *clip, cairo_pattern_t *src, cairo_operator_t op, cairo_surface_t *dst, pixman_region16_t *trap_region, cairo_rectangle_int16_t *extents) { cairo_status_t status; cairo_pattern_union_t solid_pattern; cairo_pattern_union_t mask; int num_rects = pixman_region_num_rects (trap_region); unsigned int clip_serial; cairo_surface_t *clip_surface = clip ? clip->surface : NULL; if (clip_surface && op == CAIRO_OPERATOR_CLEAR) { _cairo_pattern_init_solid (&solid_pattern.solid, CAIRO_COLOR_WHITE); src = &solid_pattern.base; op = CAIRO_OPERATOR_DEST_OUT; } if (num_rects == 0) return CAIRO_STATUS_SUCCESS; if (num_rects > 1) { if (_cairo_surface_get_clip_mode (dst) != CAIRO_CLIP_MODE_REGION) return CAIRO_INT_STATUS_UNSUPPORTED; clip_serial = _cairo_surface_allocate_clip_serial (dst); status = _cairo_surface_set_clip_region (dst, trap_region, clip_serial); if (status) return status; } if (clip_surface) _cairo_pattern_init_for_surface (&mask.surface, clip_surface); status = _cairo_surface_composite (op, src, clip_surface ? &mask.base : NULL, dst, extents->x, extents->y, extents->x - (clip_surface ? clip->surface_rect.x : 0), extents->y - (clip_surface ? clip->surface_rect.y : 0), extents->x, extents->y, extents->width, extents->height); /* Restore the original clip if we modified it temporarily. */ if (num_rects >1) _cairo_surface_set_clip (dst, clip); if (clip_surface) _cairo_pattern_fini (&mask.base); if (src == &solid_pattern.base) _cairo_pattern_fini (&solid_pattern.base); return status; }
static void pixman_color_rects (pixman_image_t *dst, pixman_image_t *clipPict, pixman_color_t *color, int nRect, pixman_rectangle_t *rects, int xoff, int yoff) { pixman_bits_t pixel; pixman_region16_t *clip; pixman_region16_t *rects_as_region; pixman_box16_t *clipped_rects; int i, n_clipped_rects; FillFunc func; pixman_color_to_pixel (&dst->image_format, color, &pixel); /* offset to the right place on the destination image */ xoff -= dst->pixels->x; yoff -= dst->pixels->y; clip = pixman_region_create(); pixman_region_union_rect (clip, clip, dst->pixels->x, dst->pixels->y, dst->pixels->width, dst->pixels->height); pixman_region_intersect (clip, clip, clipPict->pCompositeClip); if (clipPict->alphaMap) { pixman_region_translate (clip, -clipPict->alphaOrigin.x, -clipPict->alphaOrigin.y); pixman_region_intersect (clip, clip, clipPict->alphaMap->pCompositeClip); pixman_region_translate (clip, clipPict->alphaOrigin.x, clipPict->alphaOrigin.y); } if (xoff || yoff) { for (i = 0; i < nRect; i++) { rects[i].x -= xoff; rects[i].y -= yoff; } } rects_as_region = pixman_region_create (); for (i = 0; i < nRect; i++) { pixman_region_union_rect (rects_as_region, rects_as_region, rects[i].x, rects[i].y, rects[i].width, rects[i].height); } pixman_region_intersect (rects_as_region, rects_as_region, clip); pixman_region_destroy (clip); n_clipped_rects = pixman_region_num_rects (rects_as_region); clipped_rects = pixman_region_rects (rects_as_region); if (dst->pixels->bpp == 8) func = pixman_fill_rect_8bpp; else if (dst->pixels->bpp == 32) func = pixman_fill_rect_32bpp; else if (dst->pixels->bpp == 1) func = pixman_fill_rect_1bpp; else func = pixman_fill_rect_general; for (i = 0; i < n_clipped_rects; i++) { (*func) (dst, clipped_rects[i].x1, clipped_rects[i].y1, clipped_rects[i].x2 - clipped_rects[i].x1, clipped_rects[i].y2 - clipped_rects[i].y1, &pixel); } pixman_region_destroy (rects_as_region); if (xoff || yoff) { for (i = 0; i < nRect; i++) { rects[i].x += xoff; rects[i].y += yoff; } } }