[cairo] more pattern rewrite stuff...

David Reveman davidr at novell.com
Tue Feb 1 12:01:45 PST 2005


On Mon, 2005-01-31 at 23:00 -0500, Kristian Høgsberg wrote: 
> David Reveman wrote:
> > 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.
> 
> What I mean is, why not just pass a cairo_pattern_t instead of 
> cairo_surface_attributes_t, since the pattern will contain all the 
> information needed.
> 
> Another point is that these attributes aren't necessarily surface 
> attributes, that's just an artifact^Wimplementation detail of the 
> render/pixman based backends.  For the PDF backend there are no surfaces 
> involved in solid color or gradient patterns.
> 
> Anyway, I guess this will look all different when you get it merged with 
> current CVS.

yeah, I think you're getting this a bit wrong. You'll probably
understand when it gets merged with current CVS (hopefully I'll be able
to get that done sometime this week), but for what it's worth:

_cairo_pattern_get_surface should exist as a convenience function for
backends with render/pixman semantics, giving it a pattern, it returns a
surface for the pattern, right? This surface needs to be updated with
surface attributes (filter, matrix...) to work correctly and these
attributes are filled in by _cairo_pattern_get_surface. This allows
_cairo_pattern_get_surface to return attributes that doesn't match the
pattern and we need to be able to do that as the backends are not
allowed to modify the pattern. PDF-like backends should never call
_cairo_pattern_get_surface.

> 
> >>>@@ -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. 
> 
> Yeah, but why don't you just change the alpha value in the pattern 
> instead of overriding it by this new alpha argument?

Backends are not allow to modify the pattern. Think of the fall-backs
handled in cairo_surface.c. We could save pattern attributes to
temporary variables and restore them, but I like my solution better than
that.

> 
> > 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;
> > };
> 
> Yeah, that looks pretty good.
> 
> cheers,
> Kristian

-David




More information about the cairo mailing list