[cairo-commit] cairo/src cairo_font.c, 1.31, 1.32 cairo_ft_font.c, 1.37, 1.38 cairo_glitz_surface.c, 1.16, 1.17 cairo_gstate.c, 1.75, 1.76 cairo_image_surface.c, 1.20, 1.21 cairo_pattern.c, 1.12, 1.13 cairo_pdf_surface.c, 1.9, 1.10 cairo_png_surface.c, 1.11, 1.12 cairo_ps_surface.c, 1.17, 1.18 cairo_surface.c, 1.37, 1.38 cairo_xlib_surface.c, 1.39, 1.40 cairoint.h, 1.87, 1.88

Kristian Hogsberg commit at pdx.freedesktop.org
Thu Jan 27 10:46:22 PST 2005


Committed by: krh

Update of /cvs/cairo/cairo/src
In directory gabe:/tmp/cvs-serv26089/src

Modified Files:
	cairo_font.c cairo_ft_font.c cairo_glitz_surface.c 
	cairo_gstate.c cairo_image_surface.c cairo_pattern.c 
	cairo_pdf_surface.c cairo_png_surface.c cairo_ps_surface.c 
	cairo_surface.c cairo_xlib_surface.c cairoint.h 
Log Message:
2005-01-27  Kristian Høgsberg  <krh at redhat.com>

	The overall idea of this rewrite is that we want to pass the
	source pattern all the way down into the backends.  The motivation
	for this is that not all backends want a surface for the source
	operand, and by passing the pattern down, backends can choose to
	convert it to a surface if they need that.

	The patch removes the create_surface function pointer from the
	surface vtable and moves much of that code into a couple of helper
	functions.  The composite, compsite_trapezoids, and show_glyphs
	backend functions are updated to take a cairo_pattern_t instead of
	a surface as the source.
	
	* src/cairo_font.c: (_cairo_font_show_glyphs):
	* src/cairo_gstate.c: (_cairo_gstate_create_pattern),
	(_cairo_gstate_clip_and_composite_trapezoids),
	(_cairo_gstate_clip), (_cairo_gstate_show_surface),
	(_cairo_gstate_show_glyphs):
	Change these functions to not create a surface for the pattern and
	just pass the pattern down to the backend functions.
	
	* src/cairo_gstate.c: (translate_traps):
	New function to translate a set of trapezoids.
	
	* src/cairo_pattern.c:
	(_cairo_pattern_init),
	(_cairo_pattern_init_copy),
	(_cairo_pattern_prepare_surface),
	(_cairo_pattern_restore_surface):
	Break out the code to adjust and restore surface transformation
	and repeat settings into _cairo_pattern_prepare_surface and
	_cairo_pattern_restore_surface.
	
	* src/cairo_pattern.c: (_cairo_pattern_fini),
	(_cairo_pattern_init_for_surface),
	(cairo_pattern_create_for_surface):
	Split cairo_pattern_create_for_surface into an init function and a
	create function.
	
	* src/cairo_pattern.c: (_cairo_pattern_get_image),
	(_cairo_pattern_get_surface):
	Utility functions to create a surface from a pattern.

	* src/cairo_ft_font.c:
	* src/cairo_image_surface.c: 
	* src/cairo_pdf_surface.c:
	* src/cairo_png_surface.c:
	* src/cairo_ps_surface.c: 
	* src/cairo_xlib_surface.c:
	* src/cairo_glitz_surface.c:
	Update these backends to work with the new pattern API.  Glitz
	work by David Reveman.
	
	* src/cairo_surface.c: (_cairo_surface_composite),
	(_cairo_surface_composite_trapezoids),
	(_cairo_surface_set_clip_region):
	Update these to pass through the new set of args.
	
	* test/coverage-ref.png:
	Update this reference image as we now render it correctly.


Index: cairo_font.c
===================================================================
RCS file: /cvs/cairo/cairo/src/cairo_font.c,v
retrieving revision 1.31
retrieving revision 1.32
diff -u -d -r1.31 -r1.32
--- cairo_font.c	21 Jan 2005 22:33:48 -0000	1.31
+++ cairo_font.c	27 Jan 2005 18:46:20 -0000	1.32
@@ -102,25 +102,35 @@
 cairo_status_t
 _cairo_font_show_glyphs (cairo_font_t	        *font,
 			 cairo_operator_t       operator,
-			 cairo_surface_t        *source,
+			 cairo_pattern_t        *pattern,
 			 cairo_surface_t        *surface,
 			 int                    source_x,
 			 int                    source_y,
+			 int			dest_x,
+			 int			dest_y,
+			 unsigned int		width,
+			 unsigned int		height,
 			 cairo_glyph_t          *glyphs,
 			 int                    num_glyphs)
 {
     cairo_status_t status;
     if (surface->backend->show_glyphs != NULL) {
-	status = surface->backend->show_glyphs (font, operator, source, 
-						surface, source_x, source_y,
+	status = surface->backend->show_glyphs (font, operator, pattern, 
+						surface,
+						source_x, source_y,
+						dest_x, dest_y,
+						width, height,
 						glyphs, num_glyphs);
 	if (status == CAIRO_STATUS_SUCCESS)
 	    return status;
     }
 
     /* Surface display routine either does not exist or failed. */
-    return font->backend->show_glyphs (font, operator, source, 
-				       surface, source_x, source_y,
+    return font->backend->show_glyphs (font, operator, pattern, 
+				       surface,
+				       source_x, source_y,
+				       dest_x, dest_y,
+				       width, height,
 				       glyphs, num_glyphs);
 }
 

Index: cairo_ft_font.c
===================================================================
RCS file: /cvs/cairo/cairo/src/cairo_ft_font.c,v
retrieving revision 1.37
retrieving revision 1.38
diff -u -d -r1.37 -r1.38
--- cairo_ft_font.c	26 Jan 2005 14:49:16 -0000	1.37
+++ cairo_ft_font.c	27 Jan 2005 18:46:20 -0000	1.38
@@ -1001,10 +1001,14 @@
 static cairo_status_t 
 _cairo_ft_font_show_glyphs (void			*abstract_font,
                             cairo_operator_t    	operator,
-                            cairo_surface_t     	*source,
+                            cairo_pattern_t     	*pattern,
 			    cairo_surface_t     	*surface,
 			    int                 	source_x,
 			    int                 	source_y,
+			    int				dest_x,
+			    int				dest_y,
+			    unsigned int		width,
+			    unsigned int		height,
                             const cairo_glyph_t 	*glyphs,
                             int                 	num_glyphs)
 {
@@ -1013,7 +1017,6 @@
     cairo_glyph_cache_key_t key;
     cairo_ft_font_t *font = abstract_font;
     cairo_status_t status;
-
     int x, y;
     int i;
 
@@ -1022,7 +1025,7 @@
 
     if (cache == NULL
 	|| font == NULL 
-        || source == NULL 
+        || pattern == NULL 
         || surface == NULL 
         || glyphs == NULL) {
 	_cairo_unlock_global_image_glyph_cache ();
@@ -1047,11 +1050,11 @@
 	x = (int) floor (glyphs[i].x + 0.5);
 	y = (int) floor (glyphs[i].y + 0.5);
 
-	status = _cairo_surface_composite (operator, source, 
+	status = _cairo_surface_composite (operator, pattern, 
 					   &(img->image->base), 
 					   surface,
-					   source_x + x + img->size.x,
-					   source_y + y + img->size.y,
+					   x + img->size.x,
+					   y + img->size.y,
 					   0, 0, 
 					   x + img->size.x, 
 					   y + img->size.y, 
@@ -1059,11 +1062,13 @@
 					   (double) img->size.height);
 
 	if (status) {
-	    _cairo_unlock_global_image_glyph_cache ();	    
+	    _cairo_unlock_global_image_glyph_cache ();
 	    return status;
 	}
     }  
+
     _cairo_unlock_global_image_glyph_cache ();
+
     return CAIRO_STATUS_SUCCESS;
 }
 

Index: cairo_glitz_surface.c
===================================================================
RCS file: /cvs/cairo/cairo/src/cairo_glitz_surface.c,v
retrieving revision 1.16
retrieving revision 1.17
diff -u -d -r1.16 -r1.17
--- cairo_glitz_surface.c	25 Jan 2005 20:25:29 -0000	1.16
+++ cairo_glitz_surface.c	27 Jan 2005 18:46:20 -0000	1.17
@@ -68,21 +68,15 @@
     cairo_surface_t base;
 
     glitz_surface_t *surface;
-    glitz_format_t *format;
-
-    cairo_pattern_t pattern;
-    cairo_box_t pattern_box;
+    glitz_format_t  *format;
 } cairo_glitz_surface_t;
 
 static void
[...978 lines suppressed...]
 {
     return CAIRO_INT_STATUS_UNSUPPORTED;
@@ -978,7 +962,6 @@
     _cairo_glitz_surface_copy_page,
     _cairo_glitz_surface_show_page,
     _cairo_glitz_surface_set_clip_region,
-    _cairo_glitz_surface_create_pattern,
     NULL /* show_glyphs */
 };
 
@@ -1000,9 +983,5 @@
     crsurface->surface = surface;
     crsurface->format = glitz_surface_get_format (surface);
     
-    _cairo_pattern_init (&crsurface->pattern);
-    crsurface->pattern.type = CAIRO_PATTERN_SURFACE;
-    crsurface->pattern.u.surface.surface = NULL;
-    
     return (cairo_surface_t *) crsurface;
 }

Index: cairo_gstate.c
===================================================================
RCS file: /cvs/cairo/cairo/src/cairo_gstate.c,v
retrieving revision 1.75
retrieving revision 1.76
diff -u -d -r1.75 -r1.76
--- cairo_gstate.c	23 Jan 2005 20:49:56 -0000	1.75
+++ cairo_gstate.c	27 Jan 2005 18:46:20 -0000	1.76
@@ -1302,18 +1302,10 @@
    when the pattern is destroyed. The appropriate way is to pass a copy of
    the original pattern to this function just before the pattern should be
    used and destroy the copy when done. */
-static cairo_status_t
+static void
 _cairo_gstate_create_pattern (cairo_gstate_t *gstate,
-			      cairo_pattern_t *pattern,
-			      cairo_box_t *extents)
+			      cairo_pattern_t *pattern)
 {
-    cairo_int_status_t status;
-  
-    if (gstate->surface == NULL) {
-	_cairo_pattern_fini (pattern);
-	return CAIRO_STATUS_NO_TARGET_SURFACE;
-    }
-
     if (pattern->type == CAIRO_PATTERN_LINEAR ||
 	pattern->type == CAIRO_PATTERN_RADIAL) {
 	if (pattern->n_stops < 2) {
@@ -1334,17 +1326,6 @@
   
     _cairo_pattern_set_alpha (pattern, gstate->alpha);
     _cairo_pattern_transform (pattern, &gstate->ctm_inverse);
-
-    status = _cairo_surface_create_pattern (gstate->surface, pattern, extents);
-    if (status) {
-	_cairo_pattern_fini (pattern);
-	return status;
-    }
-
-    if (pattern->type == CAIRO_PATTERN_SURFACE)
-	_cairo_pattern_prepare_surface (pattern);
-    
-    return CAIRO_STATUS_SUCCESS;
 }
 
 cairo_status_t
@@ -1453,6 +1434,35 @@
 	return status;
 }
 
+static void
+translate_traps (cairo_traps_t *traps, int x, int y)
+{
+    cairo_fixed_t xoff, yoff;
+    cairo_trapezoid_t *t;
+    int i;
+
+    /* Ugh. The cairo_composite/(Render) interface doesn't allow
+       an offset for the trapezoids. Need to manually shift all
+       the coordinates to align with the offset origin of the
+       intermediate surface. */
+
+    xoff = _cairo_fixed_from_int (x);
+    yoff = _cairo_fixed_from_int (y);
+
+    for (i = 0, t = traps->traps; i < traps->num_traps; i++, t++) {
+	t->top += yoff;
+	t->bottom += yoff;
+	t->left.p1.x += xoff;
+	t->left.p1.y += yoff;
+	t->left.p2.x += xoff;
+	t->left.p2.y += yoff;
+	t->right.p1.x += xoff;
+	t->right.p1.y += yoff;
+	t->right.p2.x += xoff;
+	t->right.p2.y += yoff;
+    }
+}
+
 
 /* Warning: This call modifies the coordinates of traps */
 static cairo_status_t
@@ -1465,23 +1475,23 @@
     cairo_status_t status;
     cairo_pattern_t pattern;
     cairo_box_t extents;
-    int x_src, y_src;
+    int x, y;
+    unsigned int width, height;
 
     if (traps->num_traps == 0)
 	return CAIRO_STATUS_SUCCESS;
 
+    if (gstate->surface == NULL)
+	return CAIRO_STATUS_NO_TARGET_SURFACE;
+
     if (gstate->clip.surface) {
-	cairo_fixed_t xoff, yoff;
-	cairo_trapezoid_t *t;
-	int i;
 	cairo_surface_t *intermediate;
 	cairo_color_t empty_color;
 	pixman_box16_t *draw_extents;
 	pixman_region16_t *draw_region;
 
 	draw_region = pixman_region_create ();
-	if (draw_region == NULL)
-	{
+	if (draw_region == NULL) {
 	    status = CAIRO_STATUS_NO_MEMORY;
 	    goto BAIL0;
 	}
@@ -1501,104 +1511,74 @@
 	}
 	
 	draw_extents = pixman_region_extents (draw_region);
+	x = draw_extents->x1;
+	y = draw_extents->y1;
+	width = draw_extents->x2 - x;
+	height = draw_extents->y2 - y;
 
-	/* Ugh. The cairo_composite/(Render) interface doesn't allow
-           an offset for the trapezoids. Need to manually shift all
-           the coordinates to align with the offset origin of the
-	   intermediate surface. */
-	xoff = _cairo_fixed_from_int (draw_extents->x1);
-	yoff = _cairo_fixed_from_int (draw_extents->y1);
-	for (i=0, t=traps->traps; i < traps->num_traps; i++, t++) {
-	    t->top -= yoff;
-	    t->bottom -= yoff;
-	    t->left.p1.x -= xoff;
-	    t->left.p1.y -= yoff;
-	    t->left.p2.x -= xoff;
-	    t->left.p2.y -= yoff;
-	    t->right.p1.x -= xoff;
-	    t->right.p1.y -= yoff;
-	    t->right.p2.x -= xoff;
-	    t->right.p2.y -= yoff;
-	}
-
-	if (traps->traps[0].left.p1.y < traps->traps[0].left.p2.y) {
-	    x_src = _cairo_fixed_to_double (traps->traps[0].left.p1.x);
-	    y_src = _cairo_fixed_to_double (traps->traps[0].left.p1.y);
-	} else {
-	    x_src = _cairo_fixed_to_double (traps->traps[0].left.p2.x);
-	    y_src = _cairo_fixed_to_double (traps->traps[0].left.p2.y);
-	}
-
-	_cairo_pattern_init_solid (&pattern, 1.0, 1.0, 1.0);
-	_cairo_pattern_set_alpha (&pattern, 1.0);
-
-	status = _cairo_gstate_create_pattern (gstate, &pattern, &extents);
-	if (status)
-	    goto BAIL1;
+	translate_traps (traps, -x, -y);
 
 	_cairo_color_init (&empty_color);
 	_cairo_color_set_alpha (&empty_color, 0.);
 	intermediate = _cairo_surface_create_similar_solid (gstate->clip.surface,
 							    CAIRO_FORMAT_A8,
-							    draw_extents->x2 - draw_extents->x1,
-							    draw_extents->y2 - draw_extents->y1,
+							    width, height,
 							    &empty_color);    
 	if (intermediate == NULL) {
 	    status = CAIRO_STATUS_NO_MEMORY;
-	    goto BAIL2;
+	    goto BAIL1;
 	}
 	
+	_cairo_pattern_init_solid (&pattern, 1.0, 1.0, 1.0);
+	_cairo_gstate_create_pattern (gstate, &pattern);
+	/* Override the alpha set from gstate. */
+	_cairo_pattern_set_alpha (&pattern, 1.0);
+
 	status = _cairo_surface_composite_trapezoids (CAIRO_OPERATOR_ADD,
-						      pattern.source, intermediate,
-						      x_src,
-						      y_src,
+						      &pattern, intermediate,
+						      x, y,
+						      0, 0,
+						      width, height,
 						      traps->traps,
 						      traps->num_traps);
+	_cairo_pattern_fini (&pattern);
+
 	if (status)
-	    goto BAIL3;
+	    goto BAIL2;
+
+
+	_cairo_pattern_init_for_surface (&pattern, gstate->clip.surface);
+	_cairo_gstate_create_pattern (gstate, &pattern);
+	_cairo_pattern_set_alpha (&pattern, 1.0);
 
 	status = _cairo_surface_composite (CAIRO_OPERATOR_IN,
-					   gstate->clip.surface,
+					   &pattern,
 					   NULL,
 					   intermediate,
-					   draw_extents->x1 - gstate->clip.x,
-					   draw_extents->y1 - gstate->clip.y, 
+					   x - gstate->clip.x,
+					   y - gstate->clip.y, 
 					   0, 0,
 					   0, 0,
-					   draw_extents->x2 - draw_extents->x1,
-					   draw_extents->y2 - draw_extents->y1);
-	if (status)
-	    goto BAIL3;
-    
+					   width, height);
 	_cairo_pattern_fini (&pattern);
     
-	_cairo_pattern_init_copy (&pattern, src);
-    
-	extents.p1.x = _cairo_fixed_from_int (draw_extents->x1);
-	extents.p1.y = _cairo_fixed_from_int (draw_extents->y1);
-	extents.p2.x = _cairo_fixed_from_int (draw_extents->x2);
-	extents.p2.y = _cairo_fixed_from_int (draw_extents->y2);
-	status = _cairo_gstate_create_pattern (gstate, &pattern, &extents);
 	if (status)
-	    goto BAIL3;
+	    goto BAIL2;
+    
+	_cairo_pattern_init_copy (&pattern, src);
+	_cairo_gstate_create_pattern (gstate, &pattern);
 
-	if (dst == gstate->clip.surface)
-	    xoff = yoff = 0;
-	
 	status = _cairo_surface_composite (operator,
-					   pattern.source, intermediate, dst,
-					   0, 0,
+					   &pattern, intermediate, dst,
+					   x, y,
 					   0, 0,
-					   xoff >> 16,
-					   yoff >> 16,
-					   draw_extents->x2 - draw_extents->x1,
-					   draw_extents->y2 - draw_extents->y1);
+					   x, y,
+					   width, height);
 
+	_cairo_pattern_fini (&pattern);
 	
-    BAIL3:
-	cairo_surface_destroy (intermediate);
     BAIL2:
-	_cairo_pattern_fini (&pattern);
+	cairo_surface_destroy (intermediate);
     BAIL1:
 	pixman_region_destroy (draw_region);
     BAIL0:
@@ -1607,25 +1587,21 @@
 	    return status;
 	
     } else {
-	if (traps->traps[0].left.p1.y < traps->traps[0].left.p2.y) {
-	    x_src = _cairo_fixed_to_double (traps->traps[0].left.p1.x);
-	    y_src = _cairo_fixed_to_double (traps->traps[0].left.p1.y);
-	} else {
-	    x_src = _cairo_fixed_to_double (traps->traps[0].left.p2.x);
-	    y_src = _cairo_fixed_to_double (traps->traps[0].left.p2.y);
-	}
+	_cairo_traps_extents (traps, &extents);
+
+	x = _cairo_fixed_integer_floor (extents.p1.x);
+	y = _cairo_fixed_integer_floor (extents.p1.y);
+	width = _cairo_fixed_integer_ceil (extents.p2.x) - x;
+	height = _cairo_fixed_integer_ceil (extents.p2.y) - y;
 
 	_cairo_pattern_init_copy (&pattern, src);
-	
-	_cairo_traps_extents (traps, &extents);
-	status = _cairo_gstate_create_pattern (gstate, &pattern, &extents);
-	if (status)
-	    return status;
+	_cairo_gstate_create_pattern (gstate, &pattern);
 
 	status = _cairo_surface_composite_trapezoids (gstate->operator,
-						      pattern.source, dst,
-						      x_src - pattern.source_offset.x,
-						      y_src - pattern.source_offset.y,
+						      &pattern, dst,
+						      x, y,
+						      x, y,
+						      width, height,
 						      traps->traps,
 						      traps->num_traps);
 
@@ -1851,7 +1827,10 @@
     cairo_pattern_t pattern;
     cairo_traps_t traps;
     cairo_color_t white_color;
+    cairo_box_t extents;
     pixman_box16_t box;
+    int x, y;
+    unsigned int width, height;
 
     /* Fill the clip region as traps. */
 
@@ -1911,14 +1890,18 @@
 
     _cairo_color_init (&white_color);
 
-    if (gstate->clip.surface == NULL) {
-	cairo_box_t extents;
+    _cairo_traps_extents (&traps, &extents);
+    x = _cairo_fixed_integer_floor (extents.p1.x);
+    y = _cairo_fixed_integer_floor (extents.p1.y);
+    width = _cairo_fixed_integer_ceil (extents.p2.x) - x;
+    height = _cairo_fixed_integer_ceil (extents.p2.y) - y;
 
-	_cairo_traps_extents (&traps, &extents);
-	gstate->clip.x = extents.p1.x >> 16;
-	gstate->clip.y = extents.p1.y >> 16;
-	gstate->clip.width = ((extents.p2.x + 65535) >> 16) - gstate->clip.x;
-	gstate->clip.height = ((extents.p2.y + 65535) >> 16) - gstate->clip.y;
+
+    if (gstate->clip.surface == NULL) {
+	gstate->clip.x = x;
+	gstate->clip.y = y;
+	gstate->clip.width = width;
+	gstate->clip.height = height;
 	gstate->clip.surface =
 	    _cairo_surface_create_similar_solid (gstate->surface,
 						 CAIRO_FORMAT_A8,
@@ -1929,15 +1912,21 @@
 	    return CAIRO_STATUS_NO_MEMORY;
     }
 
+    translate_traps (&traps, -gstate->clip.x, -gstate->clip.y);
     _cairo_pattern_init_solid (&pattern, 1.0, 1.0, 1.0);
+    _cairo_gstate_create_pattern (gstate, &pattern);
     _cairo_pattern_set_alpha (&pattern, 1.0);
     
-    _cairo_gstate_clip_and_composite_trapezoids (gstate,
-						 &pattern,
-						 CAIRO_OPERATOR_IN,
-						 gstate->clip.surface,
-						 &traps);
-    
+    status = _cairo_surface_composite_trapezoids (CAIRO_OPERATOR_IN,
+						  &pattern,
+						  gstate->clip.surface,
+						  0, 0,
+						  0, 0,
+						  gstate->clip.width,
+						  gstate->clip.height,
+						  traps.traps,
+						  traps.num_traps);
+
     _cairo_pattern_fini (&pattern);
     
     _cairo_traps_fini (&traps);
@@ -2042,27 +2031,16 @@
 					  &device_x, &device_y,
 					  &device_width, &device_height);
 
-    _cairo_pattern_init (&pattern);
+    _cairo_pattern_init_for_surface (&pattern, surface);
+    _cairo_gstate_create_pattern (gstate, &pattern);
 
     pattern_extents.p1.x = _cairo_fixed_from_double (device_x);
     pattern_extents.p1.y = _cairo_fixed_from_double (device_y);
     pattern_extents.p2.x = _cairo_fixed_from_double (device_x + device_width);
     pattern_extents.p2.y = _cairo_fixed_from_double (device_y + device_height);
     
-    if ((gstate->pattern->type != CAIRO_PATTERN_SOLID) ||
-	(gstate->alpha != 1.0)) {
-	/* I'm allowing any type of pattern for the mask right now.
-	   Maybe this is bad. Will allow for some cool effects though. */
-	_cairo_pattern_init_copy (&pattern, gstate->pattern);
-	status = _cairo_gstate_create_pattern (gstate, &pattern, &pattern_extents);
-	if (status)
-	    return status;
-    }
-    
     if (gstate->clip.surface)
     {
-	cairo_surface_t *intermediate;
-	cairo_color_t empty_color;
 	pixman_box16_t *draw_extents;
 	pixman_region16_t *draw_region;
 
@@ -2087,39 +2065,9 @@
 	
 	draw_extents = pixman_region_extents (draw_region);
 	
-	_cairo_color_init (&empty_color);
-	_cairo_color_set_alpha (&empty_color, .0);
-	intermediate = _cairo_surface_create_similar_solid (gstate->clip.surface,
-							    CAIRO_FORMAT_A8,
-							    draw_extents->x2 - draw_extents->x1,
-							    draw_extents->y2 - draw_extents->y1,
-							    &empty_color);
-
-	/* it is not completely clear what the "right" way to combine the
-	 pattern and mask surface is. I will use the the clip as a source
-	 and the pattern as a mask in building up my temporary, because
-	 this is not *totally* bogus and accomodates the case where
-	 pattern's source image is NULL reasonably well. feel free to
-	 correct this if you see a reason. */
-
-	status = _cairo_surface_composite (CAIRO_OPERATOR_SRC,
-					   gstate->clip.surface,
-					   pattern.source,
-					   intermediate,
-					   draw_extents->x1 - gstate->clip.x,
-					   draw_extents->y1 - gstate->clip.y, 
-					   0, 0,
-					   0, 0,
-					   draw_extents->x2 - draw_extents->x1,
-					   draw_extents->y2 - draw_extents->y1);
-
-
-	if (status)
-	    goto BAIL2;
-
 	status = _cairo_surface_composite (gstate->operator,
-					   surface, 
-					   intermediate,
+					   &pattern, 
+					   gstate->clip.surface,
 					   gstate->surface,
 					   draw_extents->x1, draw_extents->y1,
 					   0, 0,
@@ -2127,8 +2075,6 @@
 					   draw_extents->x2 - draw_extents->x1,
 					   draw_extents->y2 - draw_extents->y1);
 	
-    BAIL2:
-	cairo_surface_destroy (intermediate);
     BAIL1:
 	pixman_region_destroy (draw_region);
     BAIL0:
@@ -2140,8 +2086,8 @@
 	/* XXX: The rendered size is sometimes 1 or 2 pixels short from
 	   what I expect. Need to fix this. */
 	status = _cairo_surface_composite (gstate->operator,
-					   surface, 
-					   pattern.source, 
+					   &pattern, 
+					   NULL,
 					   gstate->surface,
 					   device_x, device_y,
 					   0, 0,
@@ -2491,6 +2437,8 @@
     cairo_glyph_t *transformed_glyphs = NULL;
     cairo_pattern_t pattern;
     cairo_box_t bbox;
+    int x, y;
+    unsigned int width, height;
 
     status = _cairo_gstate_ensure_font (gstate);
     if (status)
@@ -2508,17 +2456,12 @@
 				      &transformed_glyphs[i].y);
     }
     
-    _cairo_pattern_init_copy (&pattern, gstate->pattern);
     status = _cairo_font_glyph_bbox (gstate->font,
 				     transformed_glyphs, num_glyphs, 
 				     &bbox);
     if (status)
 	goto CLEANUP_GLYPHS;
 
-    status = _cairo_gstate_create_pattern (gstate, &pattern, &bbox);
-    if (status)
-	goto CLEANUP_GLYPHS;
-    
     if (gstate->clip.surface)
     {
 	cairo_surface_t *intermediate;
@@ -2548,12 +2491,16 @@
 	
 	draw_extents = pixman_region_extents (draw_region);
 	
+	x = draw_extents->x1;
+	y = draw_extents->y1;
+	width = draw_extents->x2 - x;
+	height = draw_extents->y2 - y;
+
 	_cairo_color_init (&empty_color);
 	_cairo_color_set_alpha (&empty_color, .0);
 	intermediate = _cairo_surface_create_similar_solid (gstate->clip.surface,
 							    CAIRO_FORMAT_A8,
-							    draw_extents->x2 - draw_extents->x1,
-							    draw_extents->y2 - draw_extents->y1,
+							    width, height,
 							    &empty_color);
 	if (intermediate == NULL) {
 	    status = CAIRO_STATUS_NO_MEMORY;
@@ -2563,22 +2510,33 @@
 	/* move the glyphs again, from dev space to intermediate space */
 	for (i = 0; i < num_glyphs; ++i)
 	{
-	    transformed_glyphs[i].x -= draw_extents->x1;
-	    transformed_glyphs[i].y -= draw_extents->y1;
+	    transformed_glyphs[i].x -= x;
+	    transformed_glyphs[i].y -= y;
 	}
 
+	_cairo_pattern_init_solid (&pattern, 1.0, 1.0, 1.0);
+	_cairo_gstate_create_pattern (gstate, &pattern);
+	_cairo_pattern_set_alpha (&pattern, 1.0);
+    
 	status = _cairo_font_show_glyphs (gstate->font, 
 					  CAIRO_OPERATOR_ADD, 
-					  pattern.source, intermediate,
-					  draw_extents->x1 - pattern.source_offset.x,
-					  draw_extents->y1 - pattern.source_offset.y,
+					  &pattern, intermediate,
+					  x, y,
+					  0, 0,
+					  width, height,
 					  transformed_glyphs, num_glyphs);
 	
+	_cairo_pattern_fini (&pattern);
+
 	if (status)
 	    goto BAIL2;
 
+	_cairo_pattern_init_for_surface (&pattern, gstate->clip.surface);
+	_cairo_gstate_create_pattern (gstate, &pattern);
+	_cairo_pattern_set_alpha (&pattern, 1.0);
+    
 	status = _cairo_surface_composite (CAIRO_OPERATOR_IN,
-					   gstate->clip.surface,
+					   &pattern,
 					   NULL,
 					   intermediate,
 					   draw_extents->x1 - gstate->clip.x,
@@ -2588,19 +2546,23 @@
 					   draw_extents->x2 - draw_extents->x1,
 					   draw_extents->y2 - draw_extents->y1);
 
+	_cairo_pattern_fini (&pattern);
+
 	if (status)
 	    goto BAIL2;
 
+	_cairo_pattern_init_copy (&pattern, gstate->pattern);
+	_cairo_gstate_create_pattern (gstate, &pattern);
+    
 	status = _cairo_surface_composite (gstate->operator,
-					   pattern.source,
+					   &pattern,
 					   intermediate,
 					   gstate->surface,
-					   0, 0, 
+					   x, y, 
 					   0, 0,
-					   draw_extents->x1,
-					   draw_extents->y1, 
-					   draw_extents->x2 - draw_extents->x1,
-					   draw_extents->y2 - draw_extents->y1);
+					   x, y,
+					   width, height);
+	_cairo_pattern_fini (&pattern);
 
     BAIL2:
 	cairo_surface_destroy (intermediate);
@@ -2611,16 +2573,25 @@
     }
     else
     {
+	x = _cairo_fixed_integer_floor (bbox.p1.x);
+	y = _cairo_fixed_integer_floor (bbox.p1.y);
+	width = _cairo_fixed_integer_ceil (bbox.p2.x) - x;
+	height = _cairo_fixed_integer_ceil (bbox.p2.y) - y;
+
+	_cairo_pattern_init_copy (&pattern, gstate->pattern);
+	_cairo_gstate_create_pattern (gstate, &pattern);
+
 	status = _cairo_font_show_glyphs (gstate->font, 
-					  gstate->operator, pattern.source,
+					  gstate->operator, &pattern,
 					  gstate->surface,
-					  -pattern.source_offset.x,
-					  -pattern.source_offset.y,
+					  x, y,
+					  x, y,
+					  width, height,
 					  transformed_glyphs, num_glyphs);
+
+	_cairo_pattern_fini (&pattern);
     }
     
-    _cairo_pattern_fini (&pattern);
-
  CLEANUP_GLYPHS:
     free (transformed_glyphs);
     

Index: cairo_image_surface.c
===================================================================
RCS file: /cvs/cairo/cairo/src/cairo_image_surface.c,v
retrieving revision 1.20
retrieving revision 1.21
diff -u -d -r1.20 -r1.21
--- cairo_image_surface.c	20 Dec 2004 15:38:38 -0000	1.20
+++ cairo_image_surface.c	27 Jan 2005 18:46:20 -0000	1.21
@@ -368,7 +368,7 @@
 
 static cairo_int_status_t
 _cairo_image_surface_composite (cairo_operator_t	operator,
-				cairo_surface_t		*generic_src,
+				cairo_pattern_t		*pattern,
 				cairo_surface_t		*generic_mask,
 				void			*abstract_dst,
 				int			src_x,
@@ -381,20 +381,25 @@
 				unsigned int		height)
 {
     cairo_image_surface_t *dst = abstract_dst;
-    cairo_image_surface_t *src = (cairo_image_surface_t *) generic_src;
+    cairo_image_surface_t *src;
     cairo_image_surface_t *mask = (cairo_image_surface_t *) generic_mask;
+    int x_offset, y_offset;
 
-    if (generic_src->backend != dst->base.backend ||
-	(generic_mask && (generic_mask->backend != dst->base.backend)))
-    {
+    src = (cairo_image_surface_t *)
+	_cairo_pattern_get_surface (pattern, &dst->base,
+				    src_x, src_y, width, height,
+				    &x_offset, &y_offset);
+    if (src == NULL)
+	return CAIRO_STATUS_NO_MEMORY; /* Or not supported? */
+
+    if (generic_mask && (generic_mask->backend != dst->base.backend))
 	return CAIRO_INT_STATUS_UNSUPPORTED;
-    }
 
     pixman_composite (_pixman_operator (operator),
 		      src->pixman_image,
 		      mask ? mask->pixman_image : NULL,
 		      dst->pixman_image,
-		      src_x, src_y,
+		      src_x - x_offset, src_y - y_offset,
 		      mask_x, mask_y,
 		      dst_x, dst_y,
 		      width, height);
@@ -427,23 +432,50 @@
 
 static cairo_int_status_t
 _cairo_image_surface_composite_trapezoids (cairo_operator_t	operator,
-					   cairo_surface_t	*generic_src,
+					   cairo_pattern_t	*pattern,
 					   void			*abstract_dst,
-					   int			x_src,
-					   int			y_src,
+					   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_image_surface_t *dst = abstract_dst;
-    cairo_image_surface_t *src = (cairo_image_surface_t *) generic_src;
+    cairo_image_surface_t *src;
+    int x_offset, y_offset, x_src, y_src;
 
-    if (generic_src->backend != dst->base.backend)
+    src = (cairo_image_surface_t *)
+	_cairo_pattern_get_surface (pattern, &dst->base,
+				    src_x, src_y,
+				    width, height,
+				    &x_offset, &y_offset);
+    if (src == NULL)
 	return CAIRO_INT_STATUS_UNSUPPORTED;
 
+    _cairo_pattern_prepare_surface (pattern, &src->base);
+
+    if (traps[0].left.p1.y < traps[0].left.p2.y) {
+	x_src = _cairo_fixed_to_double (traps[0].left.p1.x);
+	y_src = _cairo_fixed_to_double (traps[0].left.p1.y);
+    } else {
+	x_src = _cairo_fixed_to_double (traps[0].left.p2.x);
+	y_src = _cairo_fixed_to_double (traps[0].left.p2.y);
+    }
+
+    x_src = x_src - x_offset + src_x - dst_x;
+    y_src = y_src - y_offset + src_y - dst_y;
+
     /* XXX: The pixman_trapezoid_t cast is evil and needs to go away somehow. */
     pixman_composite_trapezoids (operator, src->pixman_image, dst->pixman_image,
 				 x_src, y_src, (pixman_trapezoid_t *) traps, num_traps);
 
+    _cairo_pattern_restore_surface (pattern, &src->base);
+
+    cairo_surface_destroy (&src->base);
+
     return CAIRO_STATUS_SUCCESS;
 }
 
@@ -489,26 +521,6 @@
 
     return CAIRO_STATUS_SUCCESS;
 }
-
-static cairo_int_status_t
-_cairo_image_abstract_surface_create_pattern (void *abstract_surface,
-					      cairo_pattern_t *pattern,
-					      cairo_box_t *box)
-{
-    cairo_image_surface_t *image;
-
-    /* Fall back to general pattern creation for surface patterns. */
-    if (pattern->type == CAIRO_PATTERN_SURFACE)
-	return CAIRO_INT_STATUS_UNSUPPORTED;
-    
-    image = _cairo_pattern_get_image (pattern, box);
-    if (image) {
-	pattern->source = &image->base;
-	
-	return CAIRO_STATUS_SUCCESS;
-    } else
-	return CAIRO_STATUS_NO_MEMORY;
-}
   
 static const cairo_surface_backend_t cairo_image_surface_backend = {
     _cairo_image_surface_create_similar,
@@ -525,6 +537,5 @@
     _cairo_image_surface_copy_page,
     _cairo_image_surface_show_page,
     _cairo_image_abstract_surface_set_clip_region,
-    _cairo_image_abstract_surface_create_pattern,
     NULL /* show_glyphs */
 };

Index: cairo_pattern.c
===================================================================
RCS file: /cvs/cairo/cairo/src/cairo_pattern.c,v
retrieving revision 1.12
retrieving revision 1.13
diff -u -d -r1.12 -r1.13
--- cairo_pattern.c	22 Oct 2004 01:40:50 -0000	1.12
+++ cairo_pattern.c	27 Jan 2005 18:46:20 -0000	1.13
@@ -46,10 +46,6 @@
     pattern->n_stops = 0;
 
     pattern->type = CAIRO_PATTERN_SOLID;
-
-    pattern->source = NULL;
-    pattern->source_offset.x = 0.0;
-    pattern->source_offset.y = 0.0;
 }
 
 cairo_status_t
@@ -68,12 +64,6 @@
 		sizeof (cairo_color_stop_t) * other->n_stops);
     }
 
-    if (pattern->source)
-	cairo_surface_reference (other->source);
-
-    if (pattern->type == CAIRO_PATTERN_SURFACE)
-	cairo_surface_reference (other->u.surface.surface);
-    
     return CAIRO_STATUS_SUCCESS;
 }
 
@@ -83,22 +73,8 @@
     if (pattern->n_stops)
 	free (pattern->stops);
     
-    if (pattern->type == CAIRO_PATTERN_SURFACE) {
-	/* show_surface require us to restore surface matrix, repeat
-	   attribute, filter type */
-	if (pattern->source) {
-	    cairo_surface_set_matrix (pattern->source,
-				      &pattern->u.surface.save_matrix);
-	    cairo_surface_set_repeat (pattern->source,
-				      pattern->u.surface.save_repeat);
-	    cairo_surface_set_filter (pattern->source,
-				      pattern->u.surface.save_filter);
-	}
+    if (pattern->type == CAIRO_PATTERN_SURFACE)
 	cairo_surface_destroy (pattern->u.surface.surface);
-    }
-    
-    if (pattern->source)
-	cairo_surface_destroy (pattern->source);
 }
 
 void
@@ -125,6 +101,17 @@
     return pattern;
 }
 
+void 
+_cairo_pattern_init_for_surface (cairo_pattern_t *pattern,
+				 cairo_surface_t *surface)
+{
+    _cairo_pattern_init (pattern);
+    
+    pattern->type = CAIRO_PATTERN_SURFACE;
+    pattern->u.surface.surface = surface;
+    cairo_surface_reference (surface);
+}
+
 cairo_pattern_t *
 cairo_pattern_create_for_surface (cairo_surface_t *surface)
 {
@@ -134,11 +121,7 @@
     if (pattern == NULL)
 	return NULL;
 
-    _cairo_pattern_init (pattern);
-    
-    pattern->type = CAIRO_PATTERN_SURFACE;
-    pattern->u.surface.surface = surface;
-    cairo_surface_reference (surface);
+    _cairo_pattern_init_for_surface (pattern, surface);
 
     return pattern;
 }
@@ -336,14 +319,6 @@
 }
 
 void
-_cairo_pattern_set_source_offset (cairo_pattern_t *pattern,
-				  double x, double y)
-{
-    pattern->source_offset.x = x;
-    pattern->source_offset.y = y;
-}
-
-void
 _cairo_pattern_transform (cairo_pattern_t *pattern,
 			  cairo_matrix_t *ctm_inverse)
 {
@@ -351,36 +326,47 @@
 }
 
 void
-_cairo_pattern_prepare_surface (cairo_pattern_t *pattern)
+_cairo_pattern_prepare_surface (cairo_pattern_t *pattern,
+				cairo_surface_t *surface)
 {
     cairo_matrix_t device_to_source;
     cairo_matrix_t user_to_source;
     
     /* should the surface matrix interface be remove from the API?
        for now we multiple the surface matrix with the pattern matrix */
-    cairo_surface_get_matrix (pattern->u.surface.surface, &user_to_source);
-    cairo_matrix_multiply (&device_to_source, &pattern->matrix,
-			   &user_to_source);
-    cairo_surface_set_matrix (pattern->source, &device_to_source);
+    if (pattern->type == CAIRO_PATTERN_SURFACE) {
+	cairo_surface_get_matrix (pattern->u.surface.surface, &user_to_source);
+	cairo_matrix_multiply (&device_to_source, &pattern->matrix,
+			       &user_to_source);
+	cairo_surface_set_matrix (surface, &device_to_source);
+    }
 
     /* storing original surface matrix in pattern */
     pattern->u.surface.save_matrix = user_to_source;
 
     /* storing original surface repeat mode in pattern */
-    pattern->u.surface.save_repeat = pattern->source->repeat;
+    pattern->u.surface.save_repeat = surface->repeat;
 
     /* what do we do with extend types pad and reflect? */
-    if (pattern->extend == CAIRO_EXTEND_REPEAT
-	|| pattern->source->repeat == 1)
-	cairo_surface_set_repeat (pattern->source, 1);
+    if (pattern->extend == CAIRO_EXTEND_REPEAT || surface->repeat == 1)
+	cairo_surface_set_repeat (surface, 1);
     else
-	cairo_surface_set_repeat (pattern->source, 0);
+	cairo_surface_set_repeat (surface, 0);
     
     /* storing original surface filter in pattern */
-    pattern->u.surface.save_filter =
-        cairo_surface_get_filter (pattern->source);
+    pattern->u.surface.save_filter = cairo_surface_get_filter (surface);
     
-    cairo_surface_set_filter (pattern->source, pattern->filter);
+    cairo_surface_set_filter (surface, pattern->filter);
+}
+
+
+void
+_cairo_pattern_restore_surface (cairo_pattern_t *pattern,
+				cairo_surface_t *surface)
+{
+    cairo_surface_set_matrix (surface, &pattern->u.surface.save_matrix);
+    cairo_surface_set_repeat (surface, pattern->u.surface.save_repeat);
+    cairo_surface_set_filter (surface, pattern->u.surface.save_filter);
 }
 
 #define INTERPOLATE_COLOR_NEAREST(c1, c2, factor) \
@@ -685,18 +671,19 @@
 }
 
 cairo_image_surface_t *
-_cairo_pattern_get_image (cairo_pattern_t *pattern, cairo_box_t *box)
+_cairo_pattern_get_image (cairo_pattern_t *pattern, int x, int y,
+			  unsigned int width, unsigned int height,
+			  int *x_offset, int *y_offset)
 {
     cairo_surface_t *surface;
 
+    *x_offset = 0;
+    *y_offset = 0;
+
     switch (pattern->type) {
     case CAIRO_PATTERN_LINEAR:
     case CAIRO_PATTERN_RADIAL: {
 	char *data;
-	double x = box->p1.x >> 16;
-	double y = box->p1.y >> 16;
-	int width = ((box->p2.x + 65535) >> 16) - (box->p1.x >> 16);
-	int height = ((box->p2.y + 65535) >> 16) - (box->p1.y >> 16);
 	
 	data = malloc (width * height * 4);
 	if (!data)
@@ -709,7 +696,8 @@
 	    _cairo_image_data_set_linear (pattern, x, y, (int *) data,
 					  width, height);
 
-	_cairo_pattern_set_source_offset (pattern, x, y);
+	*x_offset = x;
+	*y_offset = y;
 
 	surface = cairo_image_surface_create_for_data (data,
 						       CAIRO_FORMAT_ARGB32,
@@ -749,3 +737,108 @@
     return (cairo_image_surface_t *) surface;
 }
  
+cairo_surface_t *
+_cairo_pattern_get_surface (cairo_pattern_t	*pattern,
+			    cairo_surface_t	*dst,			    
+			    int			x,
+			    int			y,
+			    unsigned int	width,
+			    unsigned int	height,
+			    int			*x_offset,
+			    int			*y_offset)
+{
+    cairo_surface_t *surface;
+    cairo_image_surface_t *image;
+    cairo_status_t status;
+
+    *x_offset = 0;
+    *y_offset = 0;
+
+    switch (pattern->type) {
+    case CAIRO_PATTERN_LINEAR:
+    case CAIRO_PATTERN_RADIAL:
+	image = _cairo_pattern_get_image (pattern, x, y, width, height,
+					  x_offset, y_offset);
+	if (image)
+	    return &image->base;
+	else
+	    return NULL;
+
+    case CAIRO_PATTERN_SOLID:
+	surface = _cairo_surface_create_similar_solid (dst,
+						       CAIRO_FORMAT_ARGB32,
+						       1, 1,
+						       &pattern->color);
+	if (surface == NULL)
+	    return NULL;
+
+	cairo_surface_set_repeat (surface, 1);
+	return surface;
+
+    case CAIRO_PATTERN_SURFACE:
+	/* handle pattern opacity */
+	if (pattern->color.alpha != 1.0) {
+	    cairo_surface_t *alpha_surface;
+	    double save_alpha;
+	    int save_repeat;
+
+	    surface = cairo_surface_create_similar (dst,
+						    CAIRO_FORMAT_ARGB32,
+						    width, height);
+	    if (surface == NULL)
+		return NULL;
+
+	    alpha_surface =
+		_cairo_surface_create_similar_solid (surface,
+						     CAIRO_FORMAT_A8,
+						     1, 1,
+						     &pattern->color);
+	    if (alpha_surface == NULL) {
+		cairo_surface_destroy (surface);
+		return NULL;
+	    }
+
+	    cairo_surface_set_repeat (alpha_surface, 1);
+
+	    save_repeat = pattern->u.surface.surface->repeat;
+	    if (pattern->extend == CAIRO_EXTEND_REPEAT ||
+		pattern->u.surface.surface->repeat == 1)
+		cairo_surface_set_repeat (pattern->u.surface.surface, 1);
+	    else
+		cairo_surface_set_repeat (pattern->u.surface.surface, 0);
+
+	    save_alpha = pattern->color.alpha;
+	    pattern->color.alpha = 1.0;
+
+	    status = _cairo_surface_composite (CAIRO_OPERATOR_OVER,
+					       pattern,
+					       alpha_surface,
+					       surface,
+					       x, y, 0, 0, 0, 0,
+					       width, height);
+
+	    pattern->color.alpha = save_alpha;
+
+	    cairo_surface_set_repeat (pattern->u.surface.surface,
+				      save_repeat);
+            
+	    cairo_surface_destroy (alpha_surface);
+
+	    if (status == CAIRO_STATUS_SUCCESS) {
+		*x_offset = x;
+		*y_offset = y;
+		return surface;
+	    }
+	    else {
+		cairo_surface_destroy (surface);
+		return NULL;
+	    }
+	} else {
+	    cairo_surface_reference (pattern->u.surface.surface);
+	    return pattern->u.surface.surface;
+	}
+
+    default:
+	return NULL;
+    }
+}

Index: cairo_pdf_surface.c
===================================================================
RCS file: /cvs/cairo/cairo/src/cairo_pdf_surface.c,v
retrieving revision 1.9
retrieving revision 1.10
diff -u -d -r1.9 -r1.10
--- cairo_pdf_surface.c	25 Jan 2005 18:56:50 -0000	1.9
+++ cairo_pdf_surface.c	27 Jan 2005 18:46:20 -0000	1.10
@@ -53,10 +53,6 @@
  * - Why doesn't pages inherit /alpha%d GS dictionaries from the Pages
  *   object?
  *
- * - Why isn't the pattern passed to composite traps instead of
- *   pattern->source?  If composite traps needs an image or a surface it
- *   can call create_pattern().
- *
  * - We embed an image in the stream each time it's composited.  We
  *   could add generation counters to surfaces and remember the stream
  *   ID for a particular generation for a particular surface.
@@ -182,9 +178,6 @@
     double width_inches;
     double height_inches;
 
-    /* HACK: Non-null if this surface was created for a pattern. */
-    cairo_pattern_t *pattern;
-
     cairo_pdf_document_t *document;
     cairo_pdf_stream_t *current_stream;
 
@@ -951,7 +944,6 @@
     surface->width_inches = width_inches;
     surface->height_inches = height_inches;
 
-    surface->pattern = NULL;
     _cairo_pdf_document_reference (document);
     surface->document = document;
     _cairo_array_init (&surface->streams, sizeof (cairo_pdf_stream_t *));
@@ -1266,9 +1258,6 @@
     cairo_pdf_stream_t *stream;
     int num_streams, i;
 
-    if (src->pattern != NULL)
-	return CAIRO_STATUS_SUCCESS;
-
     _cairo_pdf_surface_ensure_stream (dst);
 
     cairo_matrix_copy (&i2u, &src->base.matrix);
@@ -1301,7 +1290,7 @@
 
 static cairo_int_status_t
 _cairo_pdf_surface_composite (cairo_operator_t	operator,
-			      cairo_surface_t	*generic_src,
+			      cairo_pattern_t	*pattern,
 			      cairo_surface_t	*generic_mask,
 			      void		*abstract_dst,
 			      int		src_x,
@@ -1317,12 +1306,16 @@
     cairo_pdf_surface_t *src;
     cairo_image_surface_t *image;
 
-    if (generic_src->backend == &cairo_pdf_surface_backend) {
-	src = (cairo_pdf_surface_t *) generic_src;
+    if (pattern->type != CAIRO_PATTERN_SURFACE)
+	return CAIRO_INT_STATUS_UNSUPPORTED;
+
+    src = (cairo_pdf_surface_t *) pattern->u.surface.surface;
+
+    if (src->base.backend == &cairo_pdf_surface_backend) {
 	return _cairo_pdf_surface_composite_pdf (dst, src, width, height);
     }
     else {
-	image = _cairo_surface_get_image (generic_src);
+	image = _cairo_surface_get_image (&src->base);
 	return _cairo_pdf_surface_composite_image (dst, image);
     }
 }
@@ -1339,9 +1332,6 @@
     FILE *file = document->file;
     int i;
 
-    if (surface->pattern != NULL)
-	return CAIRO_STATUS_SUCCESS;
-
     _cairo_pdf_surface_ensure_stream (surface);
 
     fprintf (file,
@@ -1578,36 +1568,23 @@
 
 static cairo_int_status_t
 _cairo_pdf_surface_composite_trapezoids (cairo_operator_t	operator,
-					 cairo_surface_t	*generic_src,
+					 cairo_pattern_t	*pattern,
 					 void			*abstract_dst,
 					 int			x_src,
 					 int			y_src,
+					 int			x_dst,
+					 int			y_dst,
+					 unsigned int		width,
+					 unsigned int		height,
 					 cairo_trapezoid_t	*traps,
 					 int			num_traps)
 {
     cairo_pdf_surface_t *surface = abstract_dst;
-    cairo_pdf_surface_t *source = (cairo_pdf_surface_t *) generic_src;
     cairo_pdf_document_t *document = surface->document;
-    cairo_pattern_t *pattern;
     FILE *file = document->file;
     int i;
     unsigned int alpha;
 
-    /* FIXME: we really just want the original pattern here, not a
-     * source surface. */
-    pattern = source->pattern;
-
-    if (source->base.backend != &cairo_pdf_surface_backend) {
-	printf ("_cairo_pdf_surface_composite_trapezoids: not a pdf source\r");
-	return CAIRO_STATUS_SUCCESS;
-    }
-
-    if (pattern == NULL) {
-	printf ("_cairo_pdf_surface_composite_trapezoids: "
-		"non-pattern pdf source\r");
-	return CAIRO_STATUS_SUCCESS;
-    }
-
     switch (pattern->type) {
     case CAIRO_PATTERN_SOLID:	
 	alpha = _cairo_pdf_surface_add_alpha (surface, pattern->color.alpha);
@@ -1690,22 +1667,6 @@
     return CAIRO_INT_STATUS_UNSUPPORTED;
 }
 
-static cairo_int_status_t
-_cairo_pdf_surface_create_pattern (void *abstract_surface,
-				   cairo_pattern_t *pattern,
-				   cairo_box_t *extents)
-{
-    cairo_pdf_surface_t *surface = abstract_surface;
-    cairo_pdf_surface_t *source;
-
-    source = (cairo_pdf_surface_t *) 
-	_cairo_pdf_surface_create_for_document (surface->document, 0, 0);
-    source->pattern = pattern;
-    pattern->source = &source->base;
-
-    return CAIRO_STATUS_SUCCESS;
-}
-
 static cairo_pdf_font_t *
 _cairo_pdf_document_get_font (cairo_pdf_document_t	*document,
 			      cairo_font_t	        *font)
@@ -1740,10 +1701,14 @@
 static cairo_status_t
 _cairo_pdf_surface_show_glyphs (cairo_font_t	        *font,
 				cairo_operator_t	operator,
-				cairo_surface_t		*source,
+				cairo_pattern_t		*pattern,
 				void			*abstract_surface,
 				int			source_x,
 				int			source_y,
+				int			dest_x,
+				int			dest_y,
+				unsigned int		width,
+				unsigned int		height,
 				const cairo_glyph_t	*glyphs,
 				int			num_glyphs)
 {
@@ -1796,7 +1761,6 @@
     _cairo_pdf_surface_copy_page,
     _cairo_pdf_surface_show_page,
     _cairo_pdf_surface_set_clip_region,
-    _cairo_pdf_surface_create_pattern,
     _cairo_pdf_surface_show_glyphs
 };
 

Index: cairo_png_surface.c
===================================================================
RCS file: /cvs/cairo/cairo/src/cairo_png_surface.c,v
retrieving revision 1.11
retrieving revision 1.12
diff -u -d -r1.11 -r1.12
--- cairo_png_surface.c	20 Jan 2005 16:28:54 -0000	1.11
+++ cairo_png_surface.c	27 Jan 2005 18:46:20 -0000	1.12
@@ -266,10 +266,14 @@
 
 static cairo_int_status_t
 _cairo_png_surface_composite_trapezoids (cairo_operator_t	operator,
-					 cairo_surface_t		*generic_src,
+					 cairo_pattern_t	*pattern,
 					 void			*abstract_dst,
-					 int			x_src,
-					 int			y_src,
+					 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)
 {
@@ -397,14 +401,6 @@
     return _cairo_image_surface_set_clip_region (surface->image, region);
 }
 
-static cairo_int_status_t
-_cairo_png_surface_create_pattern (void *abstract_surface,
-                                   cairo_pattern_t *pattern,
-                                   cairo_box_t *extents)
-{
-    return CAIRO_INT_STATUS_UNSUPPORTED;
-}
-
 static const cairo_surface_backend_t cairo_png_surface_backend = {
     _cairo_png_surface_create_similar,
     _cairo_png_surface_destroy,
@@ -420,6 +416,5 @@
     _cairo_png_surface_copy_page,
     _cairo_png_surface_show_page,
     _cairo_png_surface_set_clip_region,
-    _cairo_png_surface_create_pattern,
     NULL /* show_glyphs */
 };

Index: cairo_ps_surface.c
===================================================================
RCS file: /cvs/cairo/cairo/src/cairo_ps_surface.c,v
retrieving revision 1.17
retrieving revision 1.18
diff -u -d -r1.17 -r1.18
--- cairo_ps_surface.c	20 Jan 2005 16:28:54 -0000	1.17
+++ cairo_ps_surface.c	27 Jan 2005 18:46:20 -0000	1.18
@@ -273,10 +273,14 @@
 
 static cairo_int_status_t
 _cairo_ps_surface_composite_trapezoids (cairo_operator_t	operator,
-					cairo_surface_t		*generic_src,
+					cairo_pattern_t		*generic_src,
 					void			*abstract_dst,
 					int			x_src,
 					int			y_src,
+					int			x_dst,
+					int			y_dst,
+					unsigned int		width,
+					unsigned int		height,
 					cairo_trapezoid_t	*traps,
 					int			num_traps)
 {
@@ -412,14 +416,6 @@
     return _cairo_image_surface_set_clip_region (surface->image, region);
 }
 
-static cairo_int_status_t
-_cairo_ps_surface_create_pattern (void *abstract_surface,
-                                  cairo_pattern_t *pattern,
-                                  cairo_box_t *extents)
-{
-    return CAIRO_INT_STATUS_UNSUPPORTED;
-}
-
 static const cairo_surface_backend_t cairo_ps_surface_backend = {
     _cairo_ps_surface_create_similar,
     _cairo_ps_surface_destroy,
@@ -435,6 +431,5 @@
     _cairo_ps_surface_copy_page,
     _cairo_ps_surface_show_page,
     _cairo_ps_surface_set_clip_region,
-    _cairo_ps_surface_create_pattern,
     NULL /* show_glyphs */
 };

Index: cairo_surface.c
===================================================================
RCS file: /cvs/cairo/cairo/src/cairo_surface.c,v
retrieving revision 1.37
retrieving revision 1.38
diff -u -d -r1.37 -r1.38
--- cairo_surface.c	22 Oct 2004 01:40:50 -0000	1.37
+++ cairo_surface.c	27 Jan 2005 18:46:20 -0000	1.38
@@ -230,7 +230,7 @@
 
 cairo_status_t
 _cairo_surface_composite (cairo_operator_t	operator,
-			  cairo_surface_t	*src,
+			  cairo_pattern_t	*pattern,
 			  cairo_surface_t	*mask,
 			  cairo_surface_t	*dst,
 			  int			src_x,
@@ -243,10 +243,10 @@
 			  unsigned int		height)
 {
     cairo_int_status_t status;
-    cairo_image_surface_t *src_image, *mask_image = 0, *dst_image;
+    cairo_image_surface_t *mask_image = 0, *dst_image;
 
     status = dst->backend->composite (operator,
-				      src, mask, dst,
+				      pattern, mask, dst,
 				      src_x, src_y,
 				      mask_x, mask_y,
 				      dst_x, dst_y,
@@ -254,13 +254,12 @@
     if (status != CAIRO_INT_STATUS_UNSUPPORTED)
 	return status;
 
-    src_image = _cairo_surface_get_image (src);
     if (mask)
 	mask_image = _cairo_surface_get_image (mask);
     dst_image = _cairo_surface_get_image (dst);
 
     dst_image->base.backend->composite (operator,
-					&src_image->base,
+					pattern,
 					mask ? &mask_image->base : NULL,
 					dst_image,
 					src_x, src_y,
@@ -270,7 +269,6 @@
 
     status = _cairo_surface_set_image (dst, dst_image);
 
-    cairo_surface_destroy (&src_image->base);
     if (mask)
 	cairo_surface_destroy (&mask_image->base);
     cairo_surface_destroy (&dst_image->base);
@@ -333,35 +331,41 @@
 
 cairo_status_t
 _cairo_surface_composite_trapezoids (cairo_operator_t		operator,
-				     cairo_surface_t		*src,
+				     cairo_pattern_t		*pattern,
 				     cairo_surface_t		*dst,
-				     int			x_src,
-				     int			y_src,
+				     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_int_status_t status;
-    cairo_image_surface_t *src_image, *dst_image;
+    cairo_image_surface_t *dst_image;
 
     status = dst->backend->composite_trapezoids (operator,
-						 src, dst,
-						 x_src, y_src,
+						 pattern, dst,
+						 src_x, src_y,
+						 dst_x, dst_y,
+						 width, height,
 						 traps, num_traps);
     if (status != CAIRO_INT_STATUS_UNSUPPORTED)
 	return status;
 
-    src_image = _cairo_surface_get_image (src);
     dst_image = _cairo_surface_get_image (dst);
 
     dst_image->base.backend->composite_trapezoids (operator,
-						   &src_image->base,
+						   pattern,
 						   dst_image,
-						   x_src, y_src,
+						   src_x, src_y,
+						   dst_x, dst_y,
+						   width, height,
 						   traps, num_traps);
 
     status = _cairo_surface_set_image (dst, dst_image);
 
-    cairo_surface_destroy (&src_image->base);
     cairo_surface_destroy (&dst_image->base);
 
     return status;
@@ -402,109 +406,3 @@
 {
     return surface->backend->set_clip_region (surface, region);
 }
-
-cairo_status_t
-_cairo_surface_create_pattern (cairo_surface_t *surface,
-			       cairo_pattern_t *pattern,
-			       cairo_box_t *box)
-{
-    cairo_int_status_t status;
-
-    status = surface->backend->create_pattern (surface, pattern, box);
-  
-    /* The backend cannot accelerate this pattern, lets create an
-       unaccelerated source instead. */
-    if (status == CAIRO_INT_STATUS_UNSUPPORTED) {
-
-	status = CAIRO_STATUS_SUCCESS;
-	switch (pattern->type) {
-	case CAIRO_PATTERN_LINEAR:
-	case CAIRO_PATTERN_RADIAL: {
-	    cairo_image_surface_t *image;
-      
-	    image = _cairo_pattern_get_image (pattern, box);
-	    if (image) {
-		pattern->source = &image->base;
-        
-		return CAIRO_STATUS_SUCCESS;
-	    } else
-		return CAIRO_STATUS_NO_MEMORY;
-      
-	} break;
-	case CAIRO_PATTERN_SOLID:
-	    pattern->source =
-		_cairo_surface_create_similar_solid (surface,
-						     CAIRO_FORMAT_ARGB32,
-						     1, 1,
-						     &pattern->color);
-	    if (pattern->source) {
-		cairo_surface_set_repeat (pattern->source, 1);
-        
-		return CAIRO_STATUS_SUCCESS;
-	    } else
-		return CAIRO_STATUS_NO_MEMORY;
-	    break;    
-	case CAIRO_PATTERN_SURFACE:
-	    status = CAIRO_INT_STATUS_UNSUPPORTED;
-
-	    /* handle pattern opacity */
-	    if (pattern->color.alpha != 1.0) {
-		double x = box->p1.x >> 16;
-		double y = box->p1.y >> 16;
-		int width = ((box->p2.x + 65535) >> 16) - (box->p1.x >> 16);
-		int height = ((box->p2.y + 65535) >> 16) - (box->p1.y >> 16);
-		cairo_pattern_t alpha;
-        
-		pattern->source =
-		    cairo_surface_create_similar (surface,
-						  CAIRO_FORMAT_ARGB32,
-						  width, height);
-		if (pattern->source) {
-		    _cairo_pattern_init_solid (&alpha, 1.0, 1.0, 1.0);
-		    _cairo_pattern_set_alpha (&alpha, pattern->color.alpha);
-          
-		    status = _cairo_surface_create_pattern (pattern->source,
-							    &alpha, box);
-          
-		    if (status == CAIRO_STATUS_SUCCESS) {
-			int save_repeat = pattern->u.surface.surface->repeat;
-
-			if (pattern->extend == CAIRO_EXTEND_REPEAT ||
-			    pattern->u.surface.surface->repeat == 1)
-			    cairo_surface_set_repeat (pattern->u.surface.surface, 1);
-			else
-			    cairo_surface_set_repeat (pattern->u.surface.surface, 0);
-			
-			status =
-			    _cairo_surface_composite (CAIRO_OPERATOR_OVER,
-						      pattern->u.surface.surface,
-						      alpha.source,
-						      pattern->source,
-						      0, 0, 0, 0, 0, 0,
-						      width, height);
-
-			cairo_surface_set_repeat (pattern->u.surface.surface,
-						  save_repeat);
-            
-			if (status == CAIRO_STATUS_SUCCESS)
-			    _cairo_pattern_set_source_offset (pattern, x, y);
-			else
-			    cairo_surface_destroy (pattern->source);
-		    }
-          
-		    _cairo_pattern_fini (&alpha);
-		}
-	    }
-
-	    if (status != CAIRO_STATUS_SUCCESS) {
-		pattern->source = pattern->u.surface.surface;
-		cairo_surface_reference (pattern->u.surface.surface);
-		
-		return CAIRO_STATUS_SUCCESS;
-	    }
-	    break;
-	}
-    }
-  
-    return status;
-}

Index: cairo_xlib_surface.c
===================================================================
RCS file: /cvs/cairo/cairo/src/cairo_xlib_surface.c,v
retrieving revision 1.39
retrieving revision 1.40
diff -u -d -r1.39 -r1.40
--- cairo_xlib_surface.c	26 Jan 2005 14:49:16 -0000	1.39
+++ cairo_xlib_surface.c	27 Jan 2005 18:46:20 -0000	1.40
@@ -462,7 +462,7 @@
 
 static cairo_int_status_t
 _cairo_xlib_surface_composite (cairo_operator_t		operator,
-			       cairo_surface_t		*generic_src,
+			       cairo_pattern_t		*pattern,
 			       cairo_surface_t		*generic_mask,
 			       void			*abstract_dst,
 			       int			src_x,
@@ -475,16 +475,28 @@
 			       unsigned int		height)
 {
     cairo_xlib_surface_t *dst = abstract_dst;
-    cairo_xlib_surface_t *src = (cairo_xlib_surface_t *) generic_src;
+    cairo_xlib_surface_t *src;
     cairo_xlib_surface_t *mask = (cairo_xlib_surface_t *) generic_mask;
     cairo_xlib_surface_t *src_clone = NULL;
     cairo_xlib_surface_t *mask_clone = NULL;
+    cairo_surface_t *generic_src;
     XGCValues gc_values;
     int src_x_off, src_y_off, dst_x_off, dst_y_off;
+    int x_offset, y_offset;
 
     if (!CAIRO_SURFACE_RENDER_HAS_COMPOSITE (dst))
 	return CAIRO_INT_STATUS_UNSUPPORTED;
 
+    /* I'm thinking that _cairo_pattern_get_surface and
+     * _cairo_xlib_surface_clone_similar can be combined into a more
+     * fine tuned _cairo_xlib_create_surface_for_pattern.*/
+
+    generic_src = _cairo_pattern_get_surface (pattern, &dst->base,
+					      src_x, src_y,
+					      width, height,
+					      &x_offset, &y_offset);
+    src = (cairo_xlib_surface_t *) generic_src;
+
     if (generic_src->backend != dst->base.backend || src->dpy != dst->dpy) {
 	src_clone = _cairo_xlib_surface_clone_similar (generic_src, dst,
 						       CAIRO_FORMAT_ARGB32, 32);
@@ -535,6 +547,7 @@
 
     /* XXX: This is messed up. If I can xlib_surface_create, then I
        should be able to xlib_surface_destroy. */
+    cairo_surface_destroy (generic_src);
     if (src_clone)
 	cairo_surface_destroy (&src_clone->base);
     if (mask_clone)
@@ -572,34 +585,61 @@
 
 static cairo_int_status_t
 _cairo_xlib_surface_composite_trapezoids (cairo_operator_t	operator,
-					  cairo_surface_t	*generic_src,
+					  cairo_pattern_t	*pattern,
 					  void			*abstract_dst,
-					  int			xSrc,
-					  int			ySrc,
+					  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_xlib_surface_t *dst = abstract_dst;
-    cairo_xlib_surface_t *src = (cairo_xlib_surface_t *) generic_src;
+    cairo_xlib_surface_t *src;
     cairo_xlib_surface_t *src_clone = NULL;
+    int x_offset, y_offset, x_src, y_src;
 
     if (!CAIRO_SURFACE_RENDER_HAS_TRAPEZOIDS (dst))
 	return CAIRO_INT_STATUS_UNSUPPORTED;
 
-    if (generic_src->backend != dst->base.backend || src->dpy != dst->dpy) {
-	src_clone = _cairo_xlib_surface_clone_similar (generic_src, dst,
+    src = (cairo_xlib_surface_t *)
+	_cairo_pattern_get_surface (pattern, &dst->base,
+				    src_x, src_y, width, height,
+				    &x_offset, &y_offset);
+    if (src == NULL)
+	return CAIRO_STATUS_NO_MEMORY;
+
+    _cairo_pattern_prepare_surface (pattern, &src->base);
+
+    if (src->base.backend != dst->base.backend || src->dpy != dst->dpy) {
+	src_clone = _cairo_xlib_surface_clone_similar (&src->base, dst,
 						       CAIRO_FORMAT_ARGB32, 32);
 	if (!src_clone)
 	    return CAIRO_INT_STATUS_UNSUPPORTED;
 	src = src_clone;
     }
 
+    if (traps[0].left.p1.y < traps[0].left.p2.y) {
+	x_src = _cairo_fixed_to_double (traps[0].left.p1.x);
+	y_src = _cairo_fixed_to_double (traps[0].left.p1.y);
+    } else {
+	x_src = _cairo_fixed_to_double (traps[0].left.p2.x);
+	y_src = _cairo_fixed_to_double (traps[0].left.p2.y);
+    }
+
+    x_src = x_src - x_offset + src_x - dst_x;
+    y_src = y_src - y_offset + src_y - dst_y;
+
     /* XXX: The XTrapezoid cast is evil and needs to go away somehow. */
     XRenderCompositeTrapezoids (dst->dpy,
 				_render_operator (operator),
 				src->picture, dst->picture,
 				XRenderFindStandardFormat (dst->dpy, PictStandardA8),
-				xSrc, ySrc, (XTrapezoid *) traps, num_traps);
+				x_src, y_src, (XTrapezoid *) traps, num_traps);
+
+    _cairo_pattern_restore_surface (pattern, &src->base);
 
     /* XXX: This is messed up. If I can xlib_surface_create, then I
        should be able to xlib_surface_destroy. */
@@ -685,21 +725,17 @@
     return CAIRO_STATUS_SUCCESS;
 }
 
-static cairo_int_status_t
-_cairo_xlib_surface_create_pattern (void *abstract_surface,
-				    cairo_pattern_t *pattern,
-				    cairo_box_t *extents)
-{
-    return CAIRO_INT_STATUS_UNSUPPORTED;
-}
-
 static cairo_status_t
 _cairo_xlib_surface_show_glyphs (cairo_font_t           *font,
 				 cairo_operator_t       operator,
-				 cairo_surface_t        *source,
+				 cairo_pattern_t	*pattern,
 				 void			*abstract_surface,
 				 int                    source_x,
 				 int                    source_y,
+				 int			dest_x,
+				 int			dest_y,
+				 unsigned int		width,
+				 unsigned int		height,
 				 const cairo_glyph_t    *glyphs,
 				 int                    num_glyphs);
 
@@ -718,7 +754,6 @@
     _cairo_xlib_surface_copy_page,
     _cairo_xlib_surface_show_page,
     _cairo_xlib_surface_set_clip_region,
-    _cairo_xlib_surface_create_pattern,
     _cairo_xlib_surface_show_glyphs
 };
 
@@ -1256,23 +1291,28 @@
 static cairo_status_t
 _cairo_xlib_surface_show_glyphs (cairo_font_t           *font,
 				 cairo_operator_t       operator,
-				 cairo_surface_t        *source,
+				 cairo_pattern_t        *pattern,
 				 void		        *abstract_surface,
 				 int                    source_x,
 				 int                    source_y,
+				 int			dest_x,
+				 int			dest_y,
+				 unsigned int		width,
+				 unsigned int		height,
 				 const cairo_glyph_t    *glyphs,
 				 int                    num_glyphs)
 {
     unsigned int elt_size;
     cairo_xlib_surface_t *self = abstract_surface;
     cairo_image_surface_t *tmp = NULL;
+    cairo_surface_t *generic_src;
     cairo_xlib_surface_t *src = NULL;
     glyphset_cache_t *g;
     cairo_status_t status;
     cairo_glyph_cache_key_t key;
     glyphset_cache_entry_t **entries;
     glyphset_cache_entry_t *stack_entries [N_STACK_BUF];
-    int i;
+    int i, x_offset, y_offset;
 
     /* Acquire an entry array of suitable size. */
     if (num_glyphs < N_STACK_BUF) {
@@ -1284,12 +1324,23 @@
 	    goto FAIL;
     }
 
+    generic_src = _cairo_pattern_get_surface (pattern, &self->base,
+					      source_x, source_y,
+					      width, height,
+					      &x_offset, &y_offset);
+    if (generic_src == NULL) {
+	status = CAIRO_STATUS_NO_MEMORY;
+	goto FREE_ENTRIES;
+    }
+
     /* prep the source surface. */
-    if (source->backend == self->base.backend) {
-	src = (cairo_xlib_surface_t *) source;
+    if (generic_src->backend == self->base.backend) {
+	src = (cairo_xlib_surface_t *) generic_src;
 
     } else {
-	tmp = _cairo_surface_get_image (source);
+	/* XXX Use _cairo_xlib_surface_clone_similar here instead of
+	 * this stuff? */
+	tmp = _cairo_surface_get_image (generic_src);
 	if (tmp == NULL)
 	    goto FREE_ENTRIES;
 
@@ -1304,6 +1355,8 @@
 	    goto FREE_SRC;	    
     }
 
+    _cairo_pattern_prepare_surface (pattern, &src->base);
+
     _lock_xlib_glyphset_caches ();
     g = _get_glyphset_cache (self->dpy);
     if (g == NULL)
@@ -1368,6 +1421,7 @@
 
  UNLOCK:
     _unlock_xlib_glyphset_caches ();
+    _cairo_pattern_restore_surface (pattern, &src->base);
 
  FREE_SRC:
     cairo_surface_destroy (&(src->base));

Index: cairoint.h
===================================================================
RCS file: /cvs/cairo/cairo/src/cairoint.h,v
retrieving revision 1.87
retrieving revision 1.88
diff -u -d -r1.87 -r1.88
--- cairoint.h	24 Jan 2005 17:01:52 -0000	1.87
+++ cairoint.h	27 Jan 2005 18:46:20 -0000	1.88
@@ -488,10 +488,14 @@
   
     cairo_status_t (*show_glyphs)    (void			*font,
 				      cairo_operator_t		operator,
-				      cairo_surface_t		*source,
+				      cairo_pattern_t		*pattern,
 				      cairo_surface_t     	*surface,
 				      int                       source_x,
 				      int                       source_y,
+				      int			dest_x,
+				      int			dest_y,
+				      unsigned int		width,
+				      unsigned int		height,
 				      const cairo_glyph_t	*glyphs,
 				      int			num_glyphs);
   
@@ -560,7 +564,7 @@
     /* XXX: dst should be the first argument for consistency */
     cairo_int_status_t
     (*composite)		(cairo_operator_t	operator,
-				 cairo_surface_t       	*src,
+				 cairo_pattern_t       	*src,
 				 cairo_surface_t	*mask,
 				 void			*dst,
 				 int			src_x,
@@ -582,10 +586,14 @@
     /* XXX: dst should be the first argument for consistency */
     cairo_int_status_t
     (*composite_trapezoids)	(cairo_operator_t	operator,
-				 cairo_surface_t	*src,
+				 cairo_pattern_t	*pattern,
 				 void			*dst,
-				 int			xSrc,
-				 int			ySrc,
+				 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);
 
@@ -598,11 +606,6 @@
     cairo_int_status_t
     (*set_clip_region)		(void			*surface,
 				 pixman_region16_t	*region);
-    cairo_int_status_t
-    (*create_pattern)		(void			*surface,
-				 cairo_pattern_t	*pattern,
-				 cairo_box_t		*extents);
-
     /* 
      * This is an optional entry to let the surface manage its own glyph
      * resources. If null, the font will be asked to render against this
@@ -611,10 +614,14 @@
     cairo_status_t 
     (*show_glyphs)		(cairo_font_t		        *font,
 				 cairo_operator_t		operator,
-				 cairo_surface_t		*source,
+				 cairo_pattern_t		*pattern,
 				 void				*surface,
 				 int				source_x,
 				 int				source_y,
+				 int				dest_x,
+				 int				dest_y,
+				 unsigned int			width,
+				 unsigned int			height,
 				 const cairo_glyph_t		*glyphs,
 				 int				num_glyphs);
 } cairo_surface_backend_t;
@@ -717,9 +724,6 @@
 
     cairo_color_t color;
   
-    cairo_surface_t *source;
-    cairo_point_double_t source_offset;
-  
     cairo_pattern_type_t type;
     union {
         struct {
@@ -1243,14 +1247,18 @@
 			cairo_box_t	      *bbox);
 
 cairo_private cairo_status_t
-_cairo_font_show_glyphs (cairo_font_t        *font,
-			 cairo_operator_t    operator,
-			 cairo_surface_t     *source,
-			 cairo_surface_t     *surface,
-			 int                 source_x,
-			 int                 source_y,
-			 cairo_glyph_t       *glyphs,
-			 int                 num_glyphs);
+_cairo_font_show_glyphs (cairo_font_t		*font,
+			 cairo_operator_t	operator,
+			 cairo_pattern_t	*source,
+			 cairo_surface_t	*surface,
+			 int			source_x,
+			 int			source_y,
+			 int			dest_x,
+			 int			dest_y,
+			 unsigned int		widht,
+			 unsigned int		height,
+			 cairo_glyph_t		*glyphs,
+			 int			num_glyphs);
 
 cairo_private cairo_status_t
 _cairo_font_glyph_path (cairo_font_t        *font,
@@ -1375,7 +1383,7 @@
 
 cairo_private cairo_status_t
 _cairo_surface_composite (cairo_operator_t	operator,
-			  cairo_surface_t	*src,
+			  cairo_pattern_t	*pattern,
 			  cairo_surface_t	*mask,
 			  cairo_surface_t	*dst,
 			  int			src_x,
@@ -1396,10 +1404,14 @@
 
 cairo_private cairo_status_t
 _cairo_surface_composite_trapezoids (cairo_operator_t	operator,
-				     cairo_surface_t	*src,
+				     cairo_pattern_t	*pattern,
 				     cairo_surface_t	*dst,
-				     int		xSrc,
-				     int		ySrc,
+				     int		src_x,
+				     int		src_y,
+				     int		dst_x,
+				     int		dst_y,
+				     unsigned int	width,
+				     unsigned int	height,
 				     cairo_trapezoid_t	*traps,
 				     int		ntraps);
 
@@ -1422,11 +1434,6 @@
 cairo_private cairo_status_t
 _cairo_surface_set_clip_region (cairo_surface_t *surface, pixman_region16_t *region);
 
-cairo_private cairo_status_t
-_cairo_surface_create_pattern (cairo_surface_t *surface,
-			       cairo_pattern_t *pattern,
-			       cairo_box_t *extents);
-
 /* cairo_image_surface.c */
 
 cairo_private cairo_image_surface_t *
@@ -1614,6 +1621,10 @@
 _cairo_pattern_init_solid (cairo_pattern_t *pattern,
 			   double red, double green, double blue);
 
+void 
+_cairo_pattern_init_for_surface (cairo_pattern_t *pattern,
+				 cairo_surface_t *surface);
+
 cairo_private cairo_pattern_t *
 _cairo_pattern_create_solid (double red, double green, double blue);
 
@@ -1625,15 +1636,16 @@
 _cairo_pattern_set_alpha (cairo_pattern_t *pattern, double alpha);
 
 cairo_private void
-_cairo_pattern_set_source_offset (cairo_pattern_t *pattern,
-				  double x, double y);
-
-cairo_private void
 _cairo_pattern_transform (cairo_pattern_t *pattern,
 			  cairo_matrix_t *ctm_inverse);
 
 cairo_private void
-_cairo_pattern_prepare_surface (cairo_pattern_t *pattern);
+_cairo_pattern_prepare_surface (cairo_pattern_t *pattern,
+				cairo_surface_t *surface);
+
+cairo_private void
+_cairo_pattern_restore_surface (cairo_pattern_t *pattern,
+				cairo_surface_t *surface);
 
 cairo_private void
 _cairo_pattern_shader_init (cairo_pattern_t *pattern,
@@ -1645,7 +1657,23 @@
 				    int *pixel);
 
 cairo_private cairo_image_surface_t *
-_cairo_pattern_get_image (cairo_pattern_t *pattern, cairo_box_t *box);
+_cairo_pattern_get_image (cairo_pattern_t	*pattern,
+			  int			x,
+			  int			y,
+			  unsigned int		width,
+			  unsigned int		height,
+			  int			*x_offset,
+			  int			*y_offset);
+
+cairo_private cairo_surface_t *
+_cairo_pattern_get_surface (cairo_pattern_t	*pattern,
+			    cairo_surface_t	*dst,
+			    int			x,
+			    int			y,
+			    unsigned int	width,
+			    unsigned int	height,
+			    int			*x_offset,
+			    int			*y_offset);
 
 /* Avoid unnecessary PLT entries.  */
 




More information about the cairo-commit mailing list