/* Destroy this brush. */ CStatus CBrush_Destroy(CBrush **_this) { /* ensure we have a this pointer pointer */ CStatus_Require((_this != 0), CStatus_ArgumentNull); /* ensure we have a this pointer */ CStatus_Require(((*_this) != 0), CStatus_ArgumentNull); /* finalize the brush */ (*_this)->_class->Finalize(*_this); /* destroy the pattern, as needed */ if((*_this)->pattern.image != 0) { pixman_image_destroy((*_this)->pattern.image); (*_this)->pattern.image = 0; } /* dispose of the brush */ CFree(*_this); /* null the this pointer */ *_this = 0; /* return successfully */ return CStatus_OK; }
/* Handle a change signal. */ CINTERNAL void CBrush_OnChange(CBrush *_this) { /* assertions */ CASSERT((_this != 0)); /* destroy the current pattern, as needed */ if(_this->pattern.image != 0) { pixman_image_destroy(_this->pattern.image); _this->pattern.image = 0; } }
void pixman_image_destroyClip (pixman_image_t *image) { switch (image->clientClipType) { case CT_NONE: return; case CT_PIXMAP: pixman_image_destroy (image->clientClip); break; default: pixman_region_destroy (image->clientClip); break; } image->clientClip = NULL; image->clientClipType = CT_NONE; }
static cairo_status_t _cairo_image_surface_finish (void *abstract_surface) { cairo_image_surface_t *surface = abstract_surface; if (surface->pixman_image) { pixman_image_destroy (surface->pixman_image); surface->pixman_image = NULL; } if (surface->owns_data) { free (surface->data); surface->data = NULL; } return CAIRO_STATUS_SUCCESS; }
/* XXX: There are failure cases in this function. Don't we need to * propagate the errors out? */ void pixman_composite_trapezoids (pixman_operator_t op, pixman_image_t *src, pixman_image_t *dst, int xSrc, int ySrc, const pixman_trapezoid_t *traps, int ntraps) { pixman_image_t *image = NULL; pixman_box16_t traps_bounds, dst_bounds, bounds; pixman_region16_t *traps_region, *dst_region; int16_t xDst, yDst; int16_t xRel, yRel; pixman_format_t *format; if (ntraps == 0) return; /* * Check for solid alpha add */ if (op == PIXMAN_OPERATOR_ADD && miIsSolidAlpha (src)) { for (; ntraps; ntraps--, traps++) fbRasterizeTrapezoid (dst, traps, 0, 0); return; } xDst = traps[0].left.p1.x >> 16; yDst = traps[0].left.p1.y >> 16; pixman_trapezoid_bounds (ntraps, traps, &traps_bounds); traps_region = pixman_region_create_simple (&traps_bounds); /* XXX: If the image has a clip region set, we should really be * fetching it here instead, but it looks like we don't yet expose * a pixman_image_get_clip_region function. */ dst_bounds.x1 = 0; dst_bounds.y1 = 0; dst_bounds.x2 = pixman_image_get_width (dst); dst_bounds.y2 = pixman_image_get_height (dst); dst_region = pixman_region_create_simple (&dst_bounds); pixman_region_intersect (traps_region, traps_region, dst_region); bounds = *(pixman_region_extents (traps_region)); pixman_region_destroy (traps_region); pixman_region_destroy (dst_region); if (bounds.y1 >= bounds.y2 || bounds.x1 >= bounds.x2) return; format = pixman_format_create (PIXMAN_FORMAT_NAME_A8); if (!format) return; image = FbCreateAlphaPicture (dst, format, bounds.x2 - bounds.x1, bounds.y2 - bounds.y1); if (!image) { pixman_format_destroy (format); return; } for (; ntraps; ntraps--, traps++) { if (!xTrapezoidValid(traps)) continue; fbRasterizeTrapezoid (image, traps, -bounds.x1, -bounds.y1); } xRel = bounds.x1 + xSrc - xDst; yRel = bounds.y1 + ySrc - yDst; pixman_composite (op, src, image, dst, xRel, yRel, 0, 0, bounds.x1, bounds.y1, bounds.x2 - bounds.x1, bounds.y2 - bounds.y1); pixman_image_destroy (image); pixman_format_destroy (format); }
static cairo_int_status_t _cairo_image_surface_composite_trapezoids (cairo_operator_t op, cairo_pattern_t *pattern, void *abstract_dst, cairo_antialias_t antialias, int src_x, int src_y, int dst_x, int dst_y, unsigned int width, unsigned int height, cairo_trapezoid_t *traps, int num_traps) { cairo_surface_attributes_t attributes; cairo_image_surface_t *dst = abstract_dst; cairo_image_surface_t *src; cairo_int_status_t status; pixman_image_t *mask; pixman_format_t *format; pixman_bits_t *mask_data; int mask_stride; int mask_bpp; /* Special case adding trapezoids onto a mask surface; we want to avoid * creating an intermediate temporary mask unecessarily. * * We make the assumption here that the portion of the trapezoids * contained within the surface is bounded by [dst_x,dst_y,width,height]; * the Cairo core code passes bounds based on the trapezoid extents. * * Currently the check surface->has_clip is needed for correct * functioning, since pixman_add_trapezoids() doesn't obey the * surface clip, which is a libpixman bug , but there's no harm in * falling through to the general case when the surface is clipped * since libpixman would have to generate an intermediate mask anyways. */ if (op == CAIRO_OPERATOR_ADD && _cairo_pattern_is_opaque_solid (pattern) && _cairo_image_surface_is_alpha_only (dst) && !dst->has_clip && antialias != CAIRO_ANTIALIAS_NONE) { pixman_add_trapezoids (dst->pixman_image, 0, 0, (pixman_trapezoid_t *) traps, num_traps); return CAIRO_STATUS_SUCCESS; } status = _cairo_pattern_acquire_surface (pattern, &dst->base, src_x, src_y, width, height, (cairo_surface_t **) &src, &attributes); if (status) return status; status = _cairo_image_surface_set_attributes (src, &attributes); if (status) goto CLEANUP_SOURCE; switch (antialias) { case CAIRO_ANTIALIAS_NONE: format = pixman_format_create (PIXMAN_FORMAT_NAME_A1); mask_stride = (width + 31)/8; mask_bpp = 1; break; default: format = pixman_format_create (PIXMAN_FORMAT_NAME_A8); mask_stride = (width + 3) & ~3; mask_bpp = 8; break; } if (!format) { status = CAIRO_STATUS_NO_MEMORY; goto CLEANUP_SOURCE; } /* The image must be initially transparent */ mask_data = calloc (1, mask_stride * height); if (!mask_data) { status = CAIRO_STATUS_NO_MEMORY; pixman_format_destroy (format); goto CLEANUP_SOURCE; } mask = pixman_image_create_for_data (mask_data, format, width, height, mask_bpp, mask_stride); pixman_format_destroy (format); if (!mask) { status = CAIRO_STATUS_NO_MEMORY; goto CLEANUP_IMAGE_DATA; } /* XXX: The pixman_trapezoid_t cast is evil and needs to go away * somehow. */ pixman_add_trapezoids (mask, - dst_x, - dst_y, (pixman_trapezoid_t *) traps, num_traps); pixman_composite (_pixman_operator (op), src->pixman_image, mask, dst->pixman_image, src_x + attributes.x_offset, src_y + attributes.y_offset, 0, 0, dst_x, dst_y, width, height); if (!_cairo_operator_bounded_by_mask (op)) status = _cairo_surface_composite_shape_fixup_unbounded (&dst->base, &attributes, src->width, src->height, width, height, src_x, src_y, 0, 0, dst_x, dst_y, width, height); pixman_image_destroy (mask); CLEANUP_IMAGE_DATA: free (mask_data); CLEANUP_SOURCE: _cairo_pattern_release_surface (pattern, &src->base, &attributes); return status; }
void pixman_fill_rectangles (pixman_operator_t op, pixman_image_t *dst, const pixman_color_t *color, const pixman_rectangle_t *rects, int nRects) { pixman_color_t color_s = *color; if (color_s.alpha == 0xffff) { if (op == PIXMAN_OPERATOR_OVER) op = PIXMAN_OPERATOR_SRC; } if (op == PIXMAN_OPERATOR_CLEAR) color_s.red = color_s.green = color_s.blue = color_s.alpha = 0; if (op == PIXMAN_OPERATOR_SRC || op == PIXMAN_OPERATOR_CLEAR) { /* We cast away the constness of rects here, because pixman_color_rects temporarily modifies it */ pixman_color_rects (dst, dst, &color_s, nRects, (pixman_rectangle_t *)rects, 0, 0); if (dst->alphaMap) pixman_color_rects (dst->alphaMap, dst, &color_s, nRects, (pixman_rectangle_t *)rects, dst->alphaOrigin.x, dst->alphaOrigin.y); } else { pixman_format_t rgbaFormat; FbPixels *pixels; pixman_image_t *src; pixman_bits_t pixel; pixman_format_init (&rgbaFormat, PICT_a8r8g8b8); pixels = FbPixelsCreate (1, 1, rgbaFormat.depth); if (!pixels) goto bail1; pixman_color_to_pixel (&rgbaFormat, &color_s, &pixel); /* XXX: Originally, fb had the following: (*pGC->ops->PolyFillRect) (&pPixmap->drawable, pGC, 1, &one); I haven't checked to see what I might be breaking with a trivial assignment instead. */ pixels->data[0] = pixel; src = pixman_image_createForPixels (pixels, &rgbaFormat); if (!src) goto bail2; pixman_image_set_repeat (src, 1); while (nRects--) { pixman_composite (op, src, NULL, dst, 0, 0, 0, 0, rects->x, rects->y, rects->width, rects->height); rects++; } pixman_image_destroy (src); bail2: FbPixelsDestroy (pixels); bail1: ; } }