[cairo] more pattern rewrite stuff...

Kristian Høgsberg krh at bitplanet.net
Mon Jan 31 12:14:12 PST 2005


David Reveman wrote:
> ok, I couldn't stop myself from trying to get this right. This patch
> includes new changes to the pattern system, this time I'm pretty happy
> with how it turned out. 
> 
> It removes backend functions set_filter, set_repeat and set_matrix.
> Makes the "pattern <-> gstate" and "pattern <-> backend" connections
> more appropriate and cleans up a lot of stuff. Looking at the diff is
> probably not good enough.

We discussed this in IRC a couple of days ago, and general consensus was 
that filter, repeat and transform should be moved out of the surface and 
into the pattern.  Owen summarized it here:

   https://bugs.freedesktop.org/show_bug.cgi?id=2397

> Futher on, we should make the mask surface passed to surface_composite a
> pattern as well, 

I think we should get this done sooner rather than later.  I can take a 
look at that once you get your patch landed.

>  static cairo_int_status_t
> +_cairo_image_surface_change_attributes (cairo_image_surface_t	   *surface,
> +					cairo_surface_attributes_t *attributes)

So, instead of this, we would set the pixman surface attributes from the 
pattern.

> @@ -380,33 +387,60 @@
>  				unsigned int		width,
>  				unsigned int		height)
>  {
> -    cairo_image_surface_t *dst = abstract_dst;
> -    cairo_image_surface_t *src;
> -    cairo_image_surface_t *mask = (cairo_image_surface_t *) generic_mask;
> -    int x_offset, y_offset;
> -
> +    cairo_surface_attributes_t	attributes;
> +    cairo_image_surface_t	*dst = abstract_dst;
> +    cairo_image_surface_t	*src;
> +    cairo_image_surface_t	*mask = (cairo_image_surface_t *) generic_mask;
> +    cairo_image_surface_t	*mask_alpha = NULL;
> +    cairo_int_status_t		status;
> +    double			alpha = pattern->color.alpha;
> +
> +    if (generic_mask)
> +    {
> +	if (generic_mask->backend != dst->base.backend)
> +	    return CAIRO_INT_STATUS_UNSUPPORTED;
> +    }
> +    else if (pattern->type == CAIRO_PATTERN_SURFACE && alpha != 1.0)
> +    {
> +	mask = mask_alpha = (cairo_image_surface_t *)
> +	    _cairo_surface_create_similar_solid (&dst->base, CAIRO_FORMAT_A8,
> +						 1, 1, &pattern->color);
> +	if (!mask)
> +	    return CAIRO_STATUS_NO_MEMORY;
> +	
> +	cairo_surface_set_repeat (&mask->base, 1);
> +	alpha = 1.0;
> +    }
> +    
>      src = (cairo_image_surface_t *)
> -	_cairo_pattern_get_surface (pattern, &dst->base,
> +	_cairo_pattern_get_surface (pattern, alpha, &dst->base,
>  				    src_x, src_y, width, height,
> -				    &x_offset, &y_offset);

Why are you reading out the alpha value from the pattern color only to 
pass it back to _cairo_pattern_get_surface, which use it as it used to 
use pattern->color.alpha?  I'll agree that using the solid color alpha 
for surface patterns is not quite right, but if we're changing it, I 
think we should rewrite it to something like:

	struct _cairo_pattern {
		unsigned int ref_count;

		cairo_extend_t extend;
		cairo_filter_t filter;
		cairo_matrix_t matrix;

		cairo_pattern_type_t type;
		union {
			cairo_color_t color;
			struct {
				cairo_surface_t *source;
				double alpha;
			} surface;
			struct {
				cairo_point_double_t point0;
				cairo_point_double_t point0;
				cairo_color_stop_t *stops;
				int num_stops;
			} gradient;
		} u;
	};

Note, we don't need the save_* fields, since a surface doesn't have 
these attributes with the changes suggested above.

cheers,
Kristian



More information about the cairo mailing list