[cairo] more pattern rewrite stuff...

David Reveman davidr at novell.com
Mon Jan 31 15:51:17 PST 2005


On Mon, 2005-01-31 at 15:14 -0500, Kristian Høgsberg wrote: 
> 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

ok, I've done the first step of this then. The the repeat, filter and
matrix attributes are still left in the surface only to be picked up by
caior_show_surface. Moving filter attribute into the gstate and removing
the surface matrix should now be simple, but as it's a quite large
change to public API I think it can wait until we get my current patch
merged with Owen's fall-back bits. We could also remove the width and
height parameters from show_surface, at the same time.

> 
> > 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.

good, it shouldn't be to hard once we get the _cairo_pattern_get_surface
stuff working well.

> 
> >  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.

_cairo_image_surface_change_attributes is actually doing this.
cairo_surface_attributes_t is basically the same as cairo_pattern_info_t
in Owen's patch. Hmm, _cairo_pattern_get_surface returns a surface
representing the pattern so I think cairo_surface_attributes_t is more
appropriate.

> 
> > @@ -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?  

If no mask surface or eventually mask pattern is passed to composite, we
can use the mask to accelerate overall surface alpha. The alpha
parameter tells _cairo_pattern_get_surface what alpha to use for surface
patterns. Hence, passing alpha=1.0 and _cairo_pattern_get_surface will
not do overall alpha for us. 

> 
> 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;
> 	};

The gradient struct will need to have alpha as well. How about this?

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 {
		double	alpha;
		struct {
			double	alpha;
			double	red, green, blue;
		} color;
		struct {
			double		alpha;
			cairo_surface_t *source;
		} surface;
		struct {
			double			alpha;
			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.

correct, in my latest patch, I had those removed.

-David




More information about the cairo mailing list