示例#1
0
文件: CBrush.c 项目: bencz/DotGnu
/* 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;
}
示例#2
0
文件: CBrush.c 项目: bencz/DotGnu
/* 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;
}
示例#5
0
/* 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;
}
示例#7
0
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:
        ;
    }
}