[cairo-commit] 20 commits - AUTHORS src/cairo-analysis-surface.c src/cairo-analysis-surface-private.h src/cairoint.h src/cairo-paginated-surface.c src/cairo-paginated-surface-private.h src/cairo-pdf-surface.c src/cairo-ps-surface.c src/cairo-scaled-font.c src/Makefile.am src/test-paginated-surface.c test/cairo-test.c

Carl Worth cworth at kemper.freedesktop.org
Tue Apr 4 15:16:59 PDT 2006


 AUTHORS                               |    1 
 src/Makefile.am                       |    5 
 src/cairo-analysis-surface-private.h  |   55 +++
 src/cairo-analysis-surface.c          |  256 +++++++++++++++
 src/cairo-paginated-surface-private.h |   11 
 src/cairo-paginated-surface.c         |   59 ++-
 src/cairo-pdf-surface.c               |   20 +
 src/cairo-ps-surface.c                |  572 ++++++++++++++++++----------------
 src/cairo-scaled-font.c               |    2 
 src/cairoint.h                        |    3 
 src/test-paginated-surface.c          |   19 +
 test/cairo-test.c                     |    1 
 12 files changed, 716 insertions(+), 288 deletions(-)

New commits:
diff-tree 4fd30e6f402ae031c2084c20f136b84307a128cc (from parents)
Merge: a8e5a77ad496c1716acdd279d5d5bebf1bc71eee 66ed9811cc542d99cb5a6b6b792c9a9f0832fbf9
Author: Carl Worth <cworth at cworth.org>
Date:   Tue Apr 4 15:04:36 2006 -0700

    Merge branch 'analysis-surface' into cairo

diff-tree a8e5a77ad496c1716acdd279d5d5bebf1bc71eee (from 45bbdf94cbac736c9f854012581e8f914a6e27df)
Author: Carl Worth <cworth at cworth.org>
Date:   Thu Mar 23 16:02:02 2006 -0800

    Add attribution for Bdale Garbee to the AUTHORS file.

diff --git a/AUTHORS b/AUTHORS
index e6f0863..ad0b97c 100644
--- a/AUTHORS
+++ b/AUTHORS
@@ -14,6 +14,7 @@ John Ehresman <jpe at wingide.com> Build fi
 John Ellson <ellson at research.att.com> First font/glyph extents functions
 Behdad Esfahbod <behdad at behdad.org> Release script improvements, bug fixes.
 Bertram Felgenhauer <int-e at gmx.de> Fixes for subtle arithmetic errors
+Bdale Garbee <bdale at gag.com> Provided essential support for cairo achitecture sessions
 J. Ali Harlow <ali at avrc.city.ac.uk> win32 backend updates
 Richard Henderson <rth at twiddle.net> "slim" macros for better shared libraries 
 James Henstridge <james at daa.com.au> Build fixes related to freetype
diff-tree 66ed9811cc542d99cb5a6b6b792c9a9f0832fbf9 (from parents)
Merge: edb83e306bda8a78a8a72006f257922cda7adc69 45bbdf94cbac736c9f854012581e8f914a6e27df
Author: Carl Worth <cworth at cworth.org>
Date:   Tue Apr 4 14:58:52 2006 -0700

    Merge branch 'cairo-origin' into analysis-surface
    
    With the string-array-stream stuff that this merge picks up, the
    analysis-surface branch is now passing all of the test suite again.

diff --cc src/cairo-analysis-surface.c
index 2bc51d3,0000000..76b84e1
mode 100644,000000..100644
@@@ -1,255 -1,0 +1,256 @@@
 +/*
 + * Copyright © 2006 Keith Packard
 + *
 + * This library is free software; you can redistribute it and/or
 + * modify it either under the terms of the GNU Lesser General Public
 + * License version 2.1 as published by the Free Software Foundation
 + * (the "LGPL") or, at your option, under the terms of the Mozilla
 + * Public License Version 1.1 (the "MPL"). If you do not alter this
 + * notice, a recipient may use your version of this file under either
 + * the MPL or the LGPL.
 + *
 + * You should have received a copy of the LGPL along with this library
 + * in the file COPYING-LGPL-2.1; if not, write to the Free Software
 + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
 + * You should have received a copy of the MPL along with this library
 + * in the file COPYING-MPL-1.1
 + *
 + * The contents of this file are subject to the Mozilla Public License
 + * Version 1.1 (the "License"); you may not use this file except in
 + * compliance with the License. You may obtain a copy of the License at
 + * http://www.mozilla.org/MPL/
 + *
 + * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY
 + * OF ANY KIND, either express or implied. See the LGPL or the MPL for
 + * the specific language governing rights and limitations.
 + *
 + * The Original Code is the cairo graphics library.
 + *
 + * The Initial Developer of the Original Code is Keith Packard
 + *
 + * Contributor(s):
 + *      Keith Packard <keithp at keithp.com>
 + */
 +
 +#include "cairoint.h"
 +
 +#include "cairo-analysis-surface-private.h"
 +#include "cairo-paginated-surface-private.h"
 +
 +typedef struct {
 +    cairo_surface_t base;
 +    int width;
 +    int height;
 +
 +    cairo_surface_t	*target;
 +    
 +    cairo_bool_t fallback;
 +} cairo_analysis_surface_t;
 +
 +static cairo_int_status_t
 +_cairo_analysis_surface_get_extents (void	 	*abstract_surface,
 +				     cairo_rectangle_t	*rectangle)
 +{
 +    cairo_analysis_surface_t *surface = abstract_surface;
 +
 +    return _cairo_surface_get_extents (surface->target, rectangle);
 +}
 +
 +static cairo_int_status_t
 +_cairo_analysis_surface_paint (void			*abstract_surface,
 +			      cairo_operator_t		op,
 +			      cairo_pattern_t		*source)
 +{
 +    cairo_analysis_surface_t *surface = abstract_surface;
 +    cairo_status_t	     status;
 +
 +    if (!surface->target->backend->paint)
 +	status = CAIRO_INT_STATUS_UNSUPPORTED;
 +    else
 +	status = (*surface->target->backend->paint) (surface->target, op,
 +						     source);
 +    if (status == CAIRO_INT_STATUS_UNSUPPORTED) {
 +	surface->fallback = TRUE;
 +	status = CAIRO_STATUS_SUCCESS;
 +    }
 +    return status;
 +}
 +
 +static cairo_int_status_t
 +_cairo_analysis_surface_mask (void		*abstract_surface,
 +			      cairo_operator_t	 op,
 +			      cairo_pattern_t	*source,
 +			      cairo_pattern_t	*mask)
 +{
 +    cairo_analysis_surface_t *surface = abstract_surface;
 +    cairo_status_t	     status;
 +
 +    if (!surface->target->backend->mask)
 +	status = CAIRO_INT_STATUS_UNSUPPORTED;
 +    else
 +	status = (*surface->target->backend->mask) (surface->target, op,
 +						    source, mask);
 +    if (status == CAIRO_INT_STATUS_UNSUPPORTED) {
 +	surface->fallback = TRUE;
 +	status = CAIRO_STATUS_SUCCESS;
 +    }
 +    return status;
 +}
 +
 +static cairo_int_status_t
 +_cairo_analysis_surface_stroke (void			*abstract_surface,
 +				cairo_operator_t	 op,
 +				cairo_pattern_t		*source,
 +				cairo_path_fixed_t	*path,
 +				cairo_stroke_style_t	*style,
 +				cairo_matrix_t		*ctm,
 +				cairo_matrix_t		*ctm_inverse,
 +				double			 tolerance,
 +				cairo_antialias_t	 antialias)
 +{
 +    cairo_analysis_surface_t *surface = abstract_surface;
 +    cairo_status_t	     status;
 +
 +    if (!surface->target->backend->stroke)
 +	status = CAIRO_INT_STATUS_UNSUPPORTED;
 +    else
 +	status = (*surface->target->backend->stroke) (surface->target, op,
 +						      source, path, style,
 +						      ctm, ctm_inverse,
 +						      tolerance, antialias);
 +    if (status == CAIRO_INT_STATUS_UNSUPPORTED) {
 +	surface->fallback = TRUE;
 +	status = CAIRO_STATUS_SUCCESS;
 +    }
 +    return status;
 +}
 +
 +static cairo_int_status_t
 +_cairo_analysis_surface_fill (void			*abstract_surface,
 +			      cairo_operator_t		 op,
 +			      cairo_pattern_t		*source,
 +			      cairo_path_fixed_t	*path,
 +			      cairo_fill_rule_t	 	 fill_rule,
 +			      double			 tolerance,
 +			      cairo_antialias_t	 	 antialias)
 +{
 +    cairo_analysis_surface_t *surface = abstract_surface;
 +    cairo_status_t	     status;
 +
 +    if (!surface->target->backend->fill)
 +	status = CAIRO_INT_STATUS_UNSUPPORTED;
 +    else
 +	status = (*surface->target->backend->fill) (surface->target, op,
 +						    source, path, fill_rule,
 +						    tolerance, antialias);
 +    if (status == CAIRO_INT_STATUS_UNSUPPORTED) {
 +	surface->fallback = TRUE;
 +	status = CAIRO_STATUS_SUCCESS;
 +    }
 +    return status;
 +}
 +
 +static cairo_int_status_t
 +_cairo_analysis_surface_show_glyphs (void		  *abstract_surface,
 +				     cairo_operator_t	   op,
 +				     cairo_pattern_t	  *source,
 +				     const cairo_glyph_t  *glyphs,
 +				     int		   num_glyphs,
 +				     cairo_scaled_font_t  *scaled_font)
 +{
 +    cairo_analysis_surface_t *surface = abstract_surface;
 +    cairo_status_t	     status;
 +
 +    if (!surface->target->backend->show_glyphs)
 +	status = CAIRO_INT_STATUS_UNSUPPORTED;
 +    else
 +	status = (*surface->target->backend->show_glyphs) (surface->target, op,
 +							   source,
 +							   glyphs, num_glyphs,
 +							   scaled_font);
 +    if (status == CAIRO_INT_STATUS_UNSUPPORTED) {
 +	surface->fallback = TRUE;
 +	status = CAIRO_STATUS_SUCCESS;
 +    }
 +    return status;
 +}
 +
 +static const cairo_surface_backend_t cairo_analysis_surface_backend = {
++    CAIRO_INTERNAL_SURFACE_TYPE_ANALYSIS,
 +    NULL, /* create_similar */
 +    NULL, /* finish_surface */
 +    NULL, /* acquire_source_image */
 +    NULL, /* release_source_image */
 +    NULL, /* acquire_dest_image */
 +    NULL, /* release_dest_image */
 +    NULL, /* clone_similar */
 +    NULL, /* composite */
 +    NULL, /* fill_rectangles */
 +    NULL, /* composite_trapezoids */
 +    NULL, /* copy_page */
 +    NULL, /* show_page */
 +    NULL, /* set_clip_region */
 +    NULL, /* clip_path */
 +    _cairo_analysis_surface_get_extents,
 +    NULL, /* old_show_glyphs */
 +    NULL, /* get_font_options */
 +    NULL, /* flush */
 +    NULL, /* mark_dirty_rectangle */
 +    NULL, /* scaled_font_fini */
 +    NULL, /* scaled_glyph_fini */
 +    _cairo_analysis_surface_paint,
 +    _cairo_analysis_surface_mask,
 +    _cairo_analysis_surface_stroke,
 +    _cairo_analysis_surface_fill,
 +    _cairo_analysis_surface_show_glyphs,
 +    NULL, /* snapshot */
 +};
 +
 +cairo_private cairo_surface_t *
 +_cairo_analysis_surface_create (cairo_surface_t		*target,
 +				int			 width,
 +				int			 height)
 +{
 +    cairo_analysis_surface_t *surface;
 +
 +    surface = malloc (sizeof (cairo_analysis_surface_t));
 +    if (surface == NULL)
 +	goto FAIL;
 +
 +    _cairo_surface_init (&surface->base, &cairo_analysis_surface_backend);
 +
 +    surface->width = width;
 +    surface->height = height;
 +
 +    surface->target = target;
 +    surface->fallback = FALSE;
 +
 +    return &surface->base;
 +FAIL:
 +    _cairo_error (CAIRO_STATUS_NO_MEMORY);
 +    return NULL;
 +}
 +
 +cairo_private pixman_region16_t *
 +_cairo_analysis_surface_get_supported (cairo_surface_t *abstract_surface)
 +{
 +    /* XXX */
 +    return NULL;
 +}
 +
 +cairo_private pixman_region16_t *
 +_cairo_analysis_surface_get_unsupported (cairo_surface_t *abstract_surface)
 +{
 +    /* XXX */
 +    return NULL;
 +}
 +
 +cairo_private cairo_bool_t
 +_cairo_analysis_surface_has_unsupported (cairo_surface_t *abstract_surface)
 +{
 +    cairo_analysis_surface_t	*surface = (cairo_analysis_surface_t *) abstract_surface;
 +
 +    return surface->fallback;
 +}
 +
 +
diff --cc src/cairo-ps-surface.c
index 305240a,99a1021..c8f5925
@@@ -643,48 -643,119 +643,129 @@@
  }
  
  static cairo_bool_t
 -pattern_operation_needs_fallback (cairo_operator_t op,
 -				  const cairo_pattern_t *pattern)
 +pattern_operation_supported (cairo_operator_t op,
 +			     const cairo_pattern_t *pattern)
  {
 -    if (! pattern_type_supported (pattern))
 -	return TRUE;
 -    if (operator_always_opaque (op))
 +    if (! pattern_supported (pattern))
  	return FALSE;
 -    if (operator_always_translucent (op))
 +    if (operator_always_opaque (op))
  	return TRUE;
 -    return pattern_is_translucent (pattern);
 +    if (operator_always_translucent (op))
 +	return FALSE;
 +    return pattern_is_opaque (pattern);
 +}
 +
 +static cairo_int_status_t
 +pattern_operation_analyze (cairo_operator_t op,
 +			   const cairo_pattern_t *pattern)
 +{
 +    if (pattern_operation_supported (op, pattern))
 +	return CAIRO_STATUS_SUCCESS;
 +    else
 +	return CAIRO_INT_STATUS_UNSUPPORTED;
  }
  
- /* PS Output - this section handles output of the parts of the meta
-  * surface we can render natively in PS. */
+ /* The "standard" implementation limit for PostScript string sizes is
+  * 65535 characters (see PostScript Language Reference, Appendix
+  * B). We go one short of that because we sometimes need two
+  * characters in a string to represent a single ASCII85 byte, (for the
+  * escape sequences "\\", "\(", and "\)") and we must not split these
+  * across two strings. So we'd be in trouble if we went right to the
+  * limit and one of these escape sequences just happened to land at
+  * the end.
+  */
+ #define STRING_ARRAY_MAX_STRING_SIZE (65535-1)
+ #define STRING_ARRAY_MAX_COLUMN	     72
  
- static void *
- compress_dup (const void *data, unsigned long data_size,
- 	      unsigned long *compressed_size)
- {
-     void *compressed;
- 
-     /* Bound calculation taken from zlib. */
-     *compressed_size = data_size + (data_size >> 12) + (data_size >> 14) + 11;
-     compressed = malloc (*compressed_size);
-     if (compressed == NULL)
- 	return NULL;
+ typedef struct _string_array_stream {
+     cairo_output_stream_t *output;
+     int column;
+     int string_size;
+ } string_array_stream_t;
+ 
+ static cairo_status_t
+ _string_array_stream_write (void		*closure,
+ 			    const unsigned char	*data,
+ 			    unsigned int	 length)
+ {
+     string_array_stream_t *stream = closure;
+     unsigned char c;
+     const unsigned char backslash = '\\';
+ 
+     if (length == 0)
+ 	return CAIRO_STATUS_SUCCESS;
+ 
+     while (length--) {
+ 	if (stream->string_size == 0) {
+ 	    _cairo_output_stream_printf (stream->output, "(");
+ 	    stream->column++;
+ 	}
+ 
+ 	c = *data++;
+ 	switch (c) {
+ 	case '\\':
+ 	case '(':
+ 	case ')':
+ 	    _cairo_output_stream_write (stream->output, &backslash, 1);
+ 	    stream->column++;
+ 	    stream->string_size++;
+ 	    break;
+ 	}
+ 	_cairo_output_stream_write (stream->output, &c, 1);
+ 	stream->column++;
+ 	stream->string_size++;
+ 
+ 	if (stream->string_size >= STRING_ARRAY_MAX_STRING_SIZE) {
+ 	    _cairo_output_stream_printf (stream->output, ")\n");
+ 	    stream->string_size = 0;
+ 	    stream->column = 0;
+ 	}
+ 	if (stream->column >= STRING_ARRAY_MAX_COLUMN) {
+ 	    _cairo_output_stream_printf (stream->output, "\n ");
+ 	    stream->string_size += 2;
+ 	    stream->column = 1;
+ 	}
+     }
+ 
+     return _cairo_output_stream_get_status (stream->output);
+ }
+ 
+ static cairo_status_t
+ _string_array_stream_close (void *closure)
+ {
+     cairo_status_t status;
+     string_array_stream_t *stream = closure;
+ 
+     _cairo_output_stream_printf (stream->output, ")\n");
+ 
+     status = _cairo_output_stream_get_status (stream->output);
+ 
+     free (stream);
+ 
+     return status;
+ }
  
-     compress (compressed, compressed_size, data, data_size);
+ static cairo_output_stream_t *
+ _string_array_stream_create (cairo_output_stream_t *output)
+ {
+     string_array_stream_t *stream;
  
-     return compressed;
+     stream = malloc (sizeof (string_array_stream_t));
+     if (stream == NULL)
+ 	return (cairo_output_stream_t *) &cairo_output_stream_nil;
+ 
+     stream->output = output;
+     stream->column = 0;
+     stream->string_size = 0;
+ 
+     return _cairo_output_stream_create (_string_array_stream_write,
+ 					_string_array_stream_close,
+ 					stream);
  }
  
+ /* PS Output - this section handles output of the parts of the meta
+  * surface we can render natively in PS. */
+ 
  static cairo_status_t
  emit_image (cairo_ps_surface_t    *surface,
  	    cairo_image_surface_t *image,
@@@ -768,28 -872,10 +871,10 @@@
      cairo_matrix_init (&d2i, 1, 0, 0, 1, 0, 0);
      cairo_matrix_multiply (&d2i, &d2i, matrix);
  
- #if 1
-     /* Construct a string holding the entire image (!) */
-     _cairo_output_stream_printf (surface->stream, "/%sString %d string def\n",
- 				 name, (int) rgb_size);
      _cairo_output_stream_printf (surface->stream,
- 				 "currentfile %sString readstring\n", name);
- #else
-     /* Construct a reusable stream decoder holding the image */
-     _cairo_output_stream_printf (surface->stream, "/%sString <<\n", name);
-     /* intent = image data */
-     _cairo_output_stream_printf (surface->stream, "\t/Intent 0\n");
- #endif    
-     /* Compressed image data */
-     _cairo_output_stream_write (surface->stream, rgb, rgb_size);
- 
-     _cairo_output_stream_printf (surface->stream,
- 				 "\n");
- 
-     _cairo_output_stream_printf (surface->stream, "/%s {\n", name);
-     _cairo_output_stream_printf (surface->stream,
- 				 "/DeviceRGB setcolorspace\n"
- 				 "<<\n"
 -				 "/%sImage {\n"
++				 "/%s {\n"
+ 				 "    /DeviceRGB setcolorspace\n"
+ 				 "    <<\n"
  				 "	/ImageType 1\n"
  				 "	/Width %d\n"
  				 "	/Height %d\n"
@@@ -805,9 -897,8 +896,8 @@@
  				 d2i.xx, d2i.yx,
  				 d2i.xy, d2i.yy,
  				 d2i.x0, d2i.y0);
-     _cairo_output_stream_printf (surface->stream, "} bind def\n");
 -    _cairo_output_stream_printf (surface->stream,
 -				 "%sImage\n", name);
 +
 +    status = CAIRO_STATUS_SUCCESS;
  
      free (compressed);
   bail2:
@@@ -839,40 -930,7 +929,41 @@@
  emit_surface_pattern (cairo_ps_surface_t *surface,
  		      cairo_surface_pattern_t *pattern)
  {
 -    /* XXX: NYI */
 +    cairo_rectangle_t		extents;
 +
 +    if (_cairo_surface_is_meta (pattern->surface)) {
 +	_cairo_output_stream_printf (surface->stream, "/MyPattern {\n");
 +	_cairo_meta_surface_replay (pattern->surface, &surface->base);
 +	extents.width = surface->width;
 +	extents.height = surface->height;
 +	_cairo_output_stream_printf (surface->stream, "} bind def\n");
 +    } else {
 +	cairo_image_surface_t	*image;
 +	void			*image_extra;
 +	cairo_status_t		status;
 +
 +	status = _cairo_surface_acquire_source_image (pattern->surface,
 +						      &image,
 +						      &image_extra);
 +	_cairo_surface_get_extents (&image->base, &extents);
 +	assert (status == CAIRO_STATUS_SUCCESS);
 +	emit_image (surface, image, &pattern->base.matrix, "MyPattern");
 +	_cairo_surface_release_source_image (pattern->surface, image,
 +					     image_extra);
 +    }
 +    _cairo_output_stream_printf (surface->stream,
- 				 "<< /PatternType 1 /PaintType 1 /TilingType 1\n");
++				 "<< /PatternType 1\n"
++				 "   /PaintType 1\n"
++				 "   /TilingType 1\n");
 +    _cairo_output_stream_printf (surface->stream,
- 				 "/BBox [0 0 %d %d]\n",
++				 "   /BBox [0 0 %d %d]\n",
 +				 extents.width, extents.height);
 +    _cairo_output_stream_printf (surface->stream,
- 				 "/XStep %d /YStep %d\n",
++				 "   /XStep %d /YStep %d\n",
 +				 extents.width, extents.height);
 +    _cairo_output_stream_printf (surface->stream,
- 				 "/PaintProc { begin MyPattern\n");
-     _cairo_output_stream_printf (surface->stream,
- 				 " end } bind >> matrix makepattern setpattern\n");
++				 "   /PaintProc { MyPattern } bind\n"
++				 ">> matrix makepattern setpattern\n");
  }
  
  static void
@@@ -1340,41 -1439,8 +1431,42 @@@
      return status;
  }
  
 +static cairo_int_status_t
 +_cairo_ps_surface_show_glyphs (void		     *abstract_surface,
 +			       cairo_operator_t	      op,
 +			       cairo_pattern_t	     *source,
 +			       const cairo_glyph_t   *glyphs,
 +			       int		      num_glyphs,
 +			       cairo_scaled_font_t   *scaled_font)
 +{
 +    cairo_ps_surface_t *surface = abstract_surface;
 +    cairo_output_stream_t *stream = surface->stream;
 +    cairo_int_status_t status;
 +    cairo_path_fixed_t *path;
 +
 +    if (surface->paginated_mode == CAIRO_PAGINATED_MODE_ANALYZE)
 +	return pattern_operation_analyze (op, source);
 +
 +    assert (pattern_operation_supported (op, source));
 +
 +    if (surface->need_start_page)
 +	_cairo_ps_surface_start_page (surface);
 +
 +    _cairo_output_stream_printf (stream,
 +				 "%% _cairo_ps_surface_show_glyphs\n");
 +
 +    path = _cairo_path_fixed_create ();
 +    _cairo_scaled_font_glyph_path (scaled_font, glyphs, num_glyphs, path);
 +    status = _cairo_ps_surface_fill (abstract_surface, op, source,
 +				     path, CAIRO_FILL_RULE_WINDING,
 +				     0.1, scaled_font->options.antialias);
 +    _cairo_path_fixed_destroy (path);
 +
 +    return CAIRO_STATUS_SUCCESS;
 +}
 +
  static const cairo_surface_backend_t cairo_ps_surface_backend = {
+     CAIRO_SURFACE_TYPE_PS,
      NULL, /* create_similar */
      _cairo_ps_surface_finish,
      NULL, /* acquire_source_image */
diff --cc src/cairoint.h
index 3d01e40,37998b7..6cd8bfb
@@@ -256,6 -260,14 +260,15 @@@
      CAIRO_INT_STATUS_CACHE_EMPTY
  } cairo_int_status_t;
  
+ typedef enum cairo_internal_surface_type {
+     CAIRO_INTERNAL_SURFACE_TYPE_META = 0x1000,
+     CAIRO_INTERNAL_SURFACE_TYPE_PAGINATED,
++    CAIRO_INTERNAL_SURFACE_TYPE_ANALYSIS,
+     CAIRO_INTERNAL_SURFACE_TYPE_TEST_META,
+     CAIRO_INTERNAL_SURFACE_TYPE_TEST_FALLBACK,
+     CAIRO_INTERNAL_SURFACE_TYPE_TEST_PAGINATED
+ } cairo_internal_surface_type_t;
+ 
  typedef enum cairo_direction {
      CAIRO_DIRECTION_FORWARD,
      CAIRO_DIRECTION_REVERSE
diff --cc test/cairo-test.c
index 557ccb6,928ab63..0d8a961
@@@ -47,6 -47,20 +47,21 @@@
  #include "write-png.h"
  #include "xmalloc.h"
  
+ /* This is copied from cairoint.h. That makes it painful to keep in
+  * sync, but the slim stuff makes cairoint.h "hard" to include when
+  * not actually building the cairo library itself. Fortunately, since
+  * we're checking all these values, we do have a safeguard for keeping
+  * them in sync.
+  */
+ typedef enum cairo_internal_surface_type {
+     CAIRO_INTERNAL_SURFACE_TYPE_META = 0x1000,
+     CAIRO_INTERNAL_SURFACE_TYPE_PAGINATED,
++    CAIRO_INTERNAL_SURFACE_TYPE_ANALYSIS,
+     CAIRO_INTERNAL_SURFACE_TYPE_TEST_META,
+     CAIRO_INTERNAL_SURFACE_TYPE_TEST_FALLBACK,
+     CAIRO_INTERNAL_SURFACE_TYPE_TEST_PAGINATED
+ } cairo_internal_surface_type_t;
+ 
  #ifdef _MSC_VER
  #define vsnprintf _vsnprintf
  #define access _access
diff-tree edb83e306bda8a78a8a72006f257922cda7adc69 (from 29dad9867aa5f00f4f38da5da7df6aded794682c)
Author: Carl Worth <cworth at cworth.org>
Date:   Fri Mar 24 12:07:21 2006 -0800

    cairo-ps-surface: Simplify operation analysis.
    
    Introduce a new pattern_operation_analyze function which allows a much
    simpler idiom to be used by all of the drawing operations. This also
    provides new assertions that when we are not analyzing we are never
    called to perform an operation that we would analyze as
    unsupported.

diff --git a/src/cairo-ps-surface.c b/src/cairo-ps-surface.c
index f90a9c8..305240a 100644
--- a/src/cairo-ps-surface.c
+++ b/src/cairo-ps-surface.c
@@ -644,7 +644,7 @@ pattern_supported (const cairo_pattern_t
 
 static cairo_bool_t
 pattern_operation_supported (cairo_operator_t op,
-				  const cairo_pattern_t *pattern)
+			     const cairo_pattern_t *pattern)
 {
     if (! pattern_supported (pattern))
 	return FALSE;
@@ -655,6 +655,16 @@ pattern_operation_supported (cairo_opera
     return pattern_is_opaque (pattern);
 }
 
+static cairo_int_status_t
+pattern_operation_analyze (cairo_operator_t op,
+			   const cairo_pattern_t *pattern)
+{
+    if (pattern_operation_supported (op, pattern))
+	return CAIRO_STATUS_SUCCESS;
+    else
+	return CAIRO_INT_STATUS_UNSUPPORTED;
+}
+
 /* PS Output - this section handles output of the parts of the meta
  * surface we can render natively in PS. */
 
@@ -1132,11 +1142,18 @@ _cairo_ps_surface_paint (void			*abstrac
     cairo_output_stream_t *stream = surface->stream;
     cairo_ps_surface_path_info_t info;
 
-    if (surface->paginated_mode == CAIRO_PAGINATED_MODE_ANALYZE) {
-	if (!pattern_operation_supported (op, source))
-	    return CAIRO_INT_STATUS_UNSUPPORTED;
-	return CAIRO_STATUS_SUCCESS;
-    }
+    if (surface->paginated_mode == CAIRO_PAGINATED_MODE_ANALYZE)
+	return pattern_operation_analyze (op, source);
+
+    /* XXX: It would be nice to be able to assert this condition
+     * here. But, we actually allow one 'cheat' that is used when
+     * painting the final image-based fallbacks. The final fallbacks
+     * do have alpha which we support by blending with white. This is
+     * possible only because there is nothing between the fallback
+     * images and the paper, nor is anything painted above. */
+    /*
+    assert (pattern_operation_supported (op, source));
+    */
     
     if (surface->need_start_page)
 	_cairo_ps_surface_start_page (surface);
@@ -1206,12 +1223,10 @@ _cairo_ps_surface_stroke (void			*abstra
     cairo_int_status_t status;
     cairo_ps_surface_path_info_t info;
 
-    if (surface->paginated_mode == CAIRO_PAGINATED_MODE_ANALYZE) {
-	if (!pattern_operation_supported (op, source))
-	    return CAIRO_INT_STATUS_UNSUPPORTED;
-    
-	return CAIRO_STATUS_SUCCESS;
-    }
+    if (surface->paginated_mode == CAIRO_PAGINATED_MODE_ANALYZE)
+	return pattern_operation_analyze (op, source);
+
+    assert (pattern_operation_supported (op, source));
     
     if (surface->need_start_page)
 	_cairo_ps_surface_start_page (surface);
@@ -1284,11 +1299,10 @@ _cairo_ps_surface_fill (void		*abstract_
     cairo_ps_surface_path_info_t info;
     const char *ps_operator;
 
-    if (surface->paginated_mode == CAIRO_PAGINATED_MODE_ANALYZE) {
-	if (!pattern_operation_supported (op, source))
-	    return CAIRO_INT_STATUS_UNSUPPORTED;
-	return CAIRO_STATUS_SUCCESS;
-    }
+    if (surface->paginated_mode == CAIRO_PAGINATED_MODE_ANALYZE)
+	return pattern_operation_analyze (op, source);
+
+    assert (pattern_operation_supported (op, source));
     
     if (surface->need_start_page)
 	_cairo_ps_surface_start_page (surface);
@@ -1339,11 +1353,10 @@ _cairo_ps_surface_show_glyphs (void		   
     cairo_int_status_t status;
     cairo_path_fixed_t *path;
 
-    if (surface->paginated_mode == CAIRO_PAGINATED_MODE_ANALYZE) {
-	if (!pattern_operation_supported (op, source))
-	    return CAIRO_INT_STATUS_UNSUPPORTED;
-	return CAIRO_STATUS_SUCCESS;
-    }
+    if (surface->paginated_mode == CAIRO_PAGINATED_MODE_ANALYZE)
+	return pattern_operation_analyze (op, source);
+
+    assert (pattern_operation_supported (op, source));
 
     if (surface->need_start_page)
 	_cairo_ps_surface_start_page (surface);
diff-tree 29dad9867aa5f00f4f38da5da7df6aded794682c (from 7cee03957b805db55df6f54deef5012535dfa7f4)
Author: Carl Worth <cworth at cworth.org>
Date:   Fri Mar 24 11:58:45 2006 -0800

    cairo-ps-surface: Don't support meta-surfaces. This isn't ready yet.

diff --git a/src/cairo-ps-surface.c b/src/cairo-ps-surface.c
index 6606992..f90a9c8 100644
--- a/src/cairo-ps-surface.c
+++ b/src/cairo-ps-surface.c
@@ -626,8 +626,6 @@ operator_always_translucent (cairo_opera
 static cairo_bool_t
 pattern_surface_supported (const cairo_surface_pattern_t *pattern)
 {
-    if (_cairo_surface_is_meta (pattern->surface))
-	return TRUE;
     if (pattern->surface->backend->acquire_source_image != NULL)
 	return TRUE;
     return FALSE;
diff-tree 7cee03957b805db55df6f54deef5012535dfa7f4 (from 498094027e18fbc8f190a225a87787a5b445e547)
Author: Carl Worth <cworth at cworth.org>
Date:   Fri Mar 24 11:57:18 2006 -0800

    cairo-ps-surface: Fix characterization of CLEAR and SOURCE operators.
    
    CLEAR should always be considered a translucent operator, while SOURCE is not
    necessarily always opaque.

diff --git a/src/cairo-ps-surface.c b/src/cairo-ps-surface.c
index f35f823..6606992 100644
--- a/src/cairo-ps-surface.c
+++ b/src/cairo-ps-surface.c
@@ -562,9 +562,10 @@ operator_always_opaque (cairo_operator_t
 {
     switch (op) {
     case CAIRO_OPERATOR_CLEAR:
+	return FALSE;
 
     case CAIRO_OPERATOR_SOURCE:
-	return TRUE;
+	return FALSE;
 	
     case CAIRO_OPERATOR_OVER:
     case CAIRO_OPERATOR_IN:
@@ -594,6 +595,7 @@ operator_always_translucent (cairo_opera
 {
     switch (op) {
     case CAIRO_OPERATOR_CLEAR:
+	return TRUE;
 
     case CAIRO_OPERATOR_SOURCE:
 	return FALSE;
diff-tree 498094027e18fbc8f190a225a87787a5b445e547 (from ecb062a6792d39f7ddb670ef35ea89b868e79353)
Author: Carl Worth <cworth at cworth.org>
Date:   Fri Mar 24 11:49:48 2006 -0800

    Back out use of meta-surface for similar-paginated-surface. It's not ready yet.

diff --git a/src/cairo-paginated-surface.c b/src/cairo-paginated-surface.c
index fb56953..bb5e034 100644
--- a/src/cairo-paginated-surface.c
+++ b/src/cairo-paginated-surface.c
@@ -155,15 +155,6 @@ _cairo_paginated_surface_get_target (cai
     return paginated_surface->target;
 }
 
-static cairo_surface_t *
-_cairo_paginated_surface_create_similar (void		 *other,
-					 cairo_content_t  content,
-					 int		  width,
-					 int		  height)
-{
-    return _cairo_meta_surface_create (content, width, height);
-}
-
 static cairo_status_t
 _cairo_paginated_surface_finish (void *abstract_surface)
 {
@@ -421,7 +412,7 @@ _cairo_paginated_surface_snapshot (void 
 }
 
 const cairo_surface_backend_t cairo_paginated_surface_backend = {
-    _cairo_paginated_surface_create_similar,
+    NULL, /* create_similar */
     _cairo_paginated_surface_finish,
     _cairo_paginated_surface_acquire_source_image,
     _cairo_paginated_surface_release_source_image,
diff-tree ecb062a6792d39f7ddb670ef35ea89b868e79353 (from e2855502f2f2e701b96a2a7eee4cda8c374bcbb9)
Author: Carl Worth <cworth at cworth.org>
Date:   Fri Mar 24 11:48:35 2006 -0800

    Update PDF backend for new paginated API so it at least doesn't crash.

diff --git a/src/cairo-pdf-surface.c b/src/cairo-pdf-surface.c
index dd2fa90..1d6eeac 100644
--- a/src/cairo-pdf-surface.c
+++ b/src/cairo-pdf-surface.c
@@ -140,6 +140,8 @@ struct cairo_pdf_surface {
     cairo_array_t alphas;
     cairo_array_t fonts;
     cairo_bool_t has_clip;
+
+    cairo_paginated_mode_t paginated_mode;
 };
 
 #define DEFAULT_DPI 300
@@ -185,6 +187,10 @@ _cairo_pdf_surface_add_stream (cairo_pdf
 static void
 _cairo_pdf_surface_ensure_stream (cairo_pdf_surface_t	*surface);
 
+static void
+_cairo_pdf_set_paginated_mode (cairo_surface_t *target,
+			       cairo_paginated_mode_t mode);
+
 static const cairo_surface_backend_t cairo_pdf_surface_backend;
 
 static unsigned int
@@ -307,7 +313,7 @@ _cairo_pdf_surface_create_for_stream_int
     return _cairo_paginated_surface_create (target,
 					    CAIRO_CONTENT_COLOR_ALPHA,
 					    width, height,
-					    NULL); /* XXX */
+					    _cairo_pdf_set_paginated_mode);
 }
 
 /**
@@ -452,6 +458,8 @@ _cairo_pdf_surface_create_for_document (
     _cairo_array_init (&surface->fonts, sizeof (cairo_pdf_resource_t));
     surface->has_clip = FALSE;
 
+    surface->paginated_mode = CAIRO_PAGINATED_MODE_ANALYZE;
+
     return &surface->base;
 }
 
@@ -2111,3 +2119,12 @@ _cairo_pdf_document_add_page (cairo_pdf_
 
     return CAIRO_STATUS_SUCCESS;
 }
+
+static void
+_cairo_pdf_set_paginated_mode (cairo_surface_t *target,
+			       cairo_paginated_mode_t paginated_mode)
+{
+    cairo_pdf_surface_t *surface = (cairo_pdf_surface_t *) target;
+
+    surface->paginated_mode = paginated_mode;
+}
diff-tree e2855502f2f2e701b96a2a7eee4cda8c374bcbb9 (from e3017c3c8de2b90e1d3470866f9bd6cc2cd313fa)
Author: Carl Worth <cworth at cworth.org>
Date:   Tue Feb 28 14:10:36 2006 -0800

    Fix last piece of merge resolution missing from previous commit

diff --git a/src/cairo-ps-surface.c b/src/cairo-ps-surface.c
index 951e1d6..f35f823 100644
--- a/src/cairo-ps-surface.c
+++ b/src/cairo-ps-surface.c
@@ -1339,7 +1339,7 @@ _cairo_ps_surface_show_glyphs (void		   
     cairo_int_status_t status;
     cairo_path_fixed_t *path;
 
-    if (surface->mode == CAIRO_PAGINATED_MODE_ANALYZE) {
+    if (surface->paginated_mode == CAIRO_PAGINATED_MODE_ANALYZE) {
 	if (!pattern_operation_supported (op, source))
 	    return CAIRO_INT_STATUS_UNSUPPORTED;
 	return CAIRO_STATUS_SUCCESS;
diff-tree e3017c3c8de2b90e1d3470866f9bd6cc2cd313fa (from parents)
Merge: ce683a240236fbe8083f284195acf0f78aa05048 2984f60a3a4571a8d4179fdc64a9e67ce9854f21
Author: Carl Worth <cworth at cworth.org>
Date:   Tue Feb 28 12:07:14 2006 -0800

    Merge in upstream 'ps-surface' changes

diff --cc src/cairo-analysis-surface.c
index 20ac5ae,0000000..2bc51d3
mode 100644,000000..100644
@@@ -1,246 -1,0 +1,255 @@@
 +/*
 + * Copyright © 2006 Keith Packard
 + *
 + * This library is free software; you can redistribute it and/or
 + * modify it either under the terms of the GNU Lesser General Public
 + * License version 2.1 as published by the Free Software Foundation
 + * (the "LGPL") or, at your option, under the terms of the Mozilla
 + * Public License Version 1.1 (the "MPL"). If you do not alter this
 + * notice, a recipient may use your version of this file under either
 + * the MPL or the LGPL.
 + *
 + * You should have received a copy of the LGPL along with this library
 + * in the file COPYING-LGPL-2.1; if not, write to the Free Software
 + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
 + * You should have received a copy of the MPL along with this library
 + * in the file COPYING-MPL-1.1
 + *
 + * The contents of this file are subject to the Mozilla Public License
 + * Version 1.1 (the "License"); you may not use this file except in
 + * compliance with the License. You may obtain a copy of the License at
 + * http://www.mozilla.org/MPL/
 + *
 + * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY
 + * OF ANY KIND, either express or implied. See the LGPL or the MPL for
 + * the specific language governing rights and limitations.
 + *
 + * The Original Code is the cairo graphics library.
 + *
 + * The Initial Developer of the Original Code is Keith Packard
 + *
 + * Contributor(s):
 + *      Keith Packard <keithp at keithp.com>
 + */
 +
 +#include "cairoint.h"
 +
 +#include "cairo-analysis-surface-private.h"
 +#include "cairo-paginated-surface-private.h"
 +
 +typedef struct {
 +    cairo_surface_t base;
 +    int width;
 +    int height;
 +
 +    cairo_surface_t	*target;
 +    
 +    cairo_bool_t fallback;
 +} cairo_analysis_surface_t;
 +
 +static cairo_int_status_t
++_cairo_analysis_surface_get_extents (void	 	*abstract_surface,
++				     cairo_rectangle_t	*rectangle)
++{
++    cairo_analysis_surface_t *surface = abstract_surface;
++
++    return _cairo_surface_get_extents (surface->target, rectangle);
++}
++
++static cairo_int_status_t
 +_cairo_analysis_surface_paint (void			*abstract_surface,
- 			       cairo_operator_t		op,
- 			       cairo_pattern_t		*source)
++			      cairo_operator_t		op,
++			      cairo_pattern_t		*source)
 +{
 +    cairo_analysis_surface_t *surface = abstract_surface;
 +    cairo_status_t	     status;
 +
 +    if (!surface->target->backend->paint)
 +	status = CAIRO_INT_STATUS_UNSUPPORTED;
 +    else
 +	status = (*surface->target->backend->paint) (surface->target, op,
 +						     source);
 +    if (status == CAIRO_INT_STATUS_UNSUPPORTED) {
 +	surface->fallback = TRUE;
 +	status = CAIRO_STATUS_SUCCESS;
 +    }
 +    return status;
 +}
 +
 +static cairo_int_status_t
 +_cairo_analysis_surface_mask (void		*abstract_surface,
 +			      cairo_operator_t	 op,
 +			      cairo_pattern_t	*source,
 +			      cairo_pattern_t	*mask)
 +{
 +    cairo_analysis_surface_t *surface = abstract_surface;
 +    cairo_status_t	     status;
 +
 +    if (!surface->target->backend->mask)
 +	status = CAIRO_INT_STATUS_UNSUPPORTED;
 +    else
 +	status = (*surface->target->backend->mask) (surface->target, op,
 +						    source, mask);
 +    if (status == CAIRO_INT_STATUS_UNSUPPORTED) {
 +	surface->fallback = TRUE;
 +	status = CAIRO_STATUS_SUCCESS;
 +    }
 +    return status;
 +}
 +
 +static cairo_int_status_t
 +_cairo_analysis_surface_stroke (void			*abstract_surface,
 +				cairo_operator_t	 op,
 +				cairo_pattern_t		*source,
 +				cairo_path_fixed_t	*path,
 +				cairo_stroke_style_t	*style,
 +				cairo_matrix_t		*ctm,
 +				cairo_matrix_t		*ctm_inverse,
 +				double			 tolerance,
 +				cairo_antialias_t	 antialias)
 +{
 +    cairo_analysis_surface_t *surface = abstract_surface;
 +    cairo_status_t	     status;
 +
 +    if (!surface->target->backend->stroke)
 +	status = CAIRO_INT_STATUS_UNSUPPORTED;
 +    else
 +	status = (*surface->target->backend->stroke) (surface->target, op,
 +						      source, path, style,
 +						      ctm, ctm_inverse,
 +						      tolerance, antialias);
 +    if (status == CAIRO_INT_STATUS_UNSUPPORTED) {
 +	surface->fallback = TRUE;
 +	status = CAIRO_STATUS_SUCCESS;
 +    }
 +    return status;
 +}
 +
 +static cairo_int_status_t
 +_cairo_analysis_surface_fill (void			*abstract_surface,
 +			      cairo_operator_t		 op,
 +			      cairo_pattern_t		*source,
 +			      cairo_path_fixed_t	*path,
 +			      cairo_fill_rule_t	 	 fill_rule,
 +			      double			 tolerance,
 +			      cairo_antialias_t	 	 antialias)
 +{
 +    cairo_analysis_surface_t *surface = abstract_surface;
 +    cairo_status_t	     status;
 +
 +    if (!surface->target->backend->fill)
 +	status = CAIRO_INT_STATUS_UNSUPPORTED;
 +    else
 +	status = (*surface->target->backend->fill) (surface->target, op,
 +						    source, path, fill_rule,
 +						    tolerance, antialias);
 +    if (status == CAIRO_INT_STATUS_UNSUPPORTED) {
 +	surface->fallback = TRUE;
 +	status = CAIRO_STATUS_SUCCESS;
 +    }
 +    return status;
 +}
 +
 +static cairo_int_status_t
 +_cairo_analysis_surface_show_glyphs (void		  *abstract_surface,
 +				     cairo_operator_t	   op,
 +				     cairo_pattern_t	  *source,
 +				     const cairo_glyph_t  *glyphs,
 +				     int		   num_glyphs,
 +				     cairo_scaled_font_t  *scaled_font)
 +{
 +    cairo_analysis_surface_t *surface = abstract_surface;
 +    cairo_status_t	     status;
 +
 +    if (!surface->target->backend->show_glyphs)
 +	status = CAIRO_INT_STATUS_UNSUPPORTED;
 +    else
 +	status = (*surface->target->backend->show_glyphs) (surface->target, op,
 +							   source,
 +							   glyphs, num_glyphs,
 +							   scaled_font);
 +    if (status == CAIRO_INT_STATUS_UNSUPPORTED) {
 +	surface->fallback = TRUE;
 +	status = CAIRO_STATUS_SUCCESS;
 +    }
 +    return status;
 +}
 +
 +static const cairo_surface_backend_t cairo_analysis_surface_backend = {
 +    NULL, /* create_similar */
 +    NULL, /* finish_surface */
 +    NULL, /* acquire_source_image */
 +    NULL, /* release_source_image */
 +    NULL, /* acquire_dest_image */
 +    NULL, /* release_dest_image */
 +    NULL, /* clone_similar */
 +    NULL, /* composite */
 +    NULL, /* fill_rectangles */
 +    NULL, /* composite_trapezoids */
 +    NULL, /* copy_page */
 +    NULL, /* show_page */
 +    NULL, /* set_clip_region */
 +    NULL, /* clip_path */
-     NULL, /* get_extents */
++    _cairo_analysis_surface_get_extents,
 +    NULL, /* old_show_glyphs */
 +    NULL, /* get_font_options */
 +    NULL, /* flush */
 +    NULL, /* mark_dirty_rectangle */
 +    NULL, /* scaled_font_fini */
 +    NULL, /* scaled_glyph_fini */
 +    _cairo_analysis_surface_paint,
 +    _cairo_analysis_surface_mask,
 +    _cairo_analysis_surface_stroke,
 +    _cairo_analysis_surface_fill,
 +    _cairo_analysis_surface_show_glyphs,
 +    NULL, /* snapshot */
 +};
 +
 +cairo_private cairo_surface_t *
 +_cairo_analysis_surface_create (cairo_surface_t		*target,
 +				int			 width,
 +				int			 height)
 +{
 +    cairo_analysis_surface_t *surface;
 +
 +    surface = malloc (sizeof (cairo_analysis_surface_t));
 +    if (surface == NULL)
 +	goto FAIL;
 +
 +    _cairo_surface_init (&surface->base, &cairo_analysis_surface_backend);
 +
 +    surface->width = width;
 +    surface->height = height;
 +
 +    surface->target = target;
 +    surface->fallback = FALSE;
 +
 +    return &surface->base;
 +FAIL:
 +    _cairo_error (CAIRO_STATUS_NO_MEMORY);
 +    return NULL;
 +}
 +
 +cairo_private pixman_region16_t *
 +_cairo_analysis_surface_get_supported (cairo_surface_t *abstract_surface)
 +{
 +    /* XXX */
 +    return NULL;
 +}
 +
 +cairo_private pixman_region16_t *
 +_cairo_analysis_surface_get_unsupported (cairo_surface_t *abstract_surface)
 +{
 +    /* XXX */
 +    return NULL;
 +}
 +
 +cairo_private cairo_bool_t
 +_cairo_analysis_surface_has_unsupported (cairo_surface_t *abstract_surface)
 +{
 +    cairo_analysis_surface_t	*surface = (cairo_analysis_surface_t *) abstract_surface;
 +
 +    return surface->fallback;
 +}
 +
 +
diff --cc src/test-paginated-surface.c
index 155f277,155f277..d07ac37
@@@ -51,6 -51,6 +51,22 @@@
  
  #include "cairo-paginated-surface-private.h"
  
++static void
++_test_paginated_surface_set_paginated_mode (cairo_surface_t *target,
++					    cairo_paginated_mode_t mode)
++{
++    /* XXX: We don't do anything to save the paginated mode here. This
++     * means that all the rendering will hit the image surface
++     * twice. This will work (but less efficiently) for all tests that
++     * explicitly initialize all pixels. Tests that expect the
++     * background to initially be transparent and leave it that way in
++     * spots will likely fail.
++     *
++     * If we see this as worth fixing, it will just require shoving
++     * some set_paginated_mode support into cairo_image_surface_t.
++     */
++}
++
  cairo_surface_t *
  _test_paginated_surface_create_for_data (unsigned char		*data,
  					 cairo_content_t	 content,
@@@ -64,5 -64,5 +80,6 @@@
  								width, height,
  								stride);
  
--    return _cairo_paginated_surface_create (target, content, width, height);
++    return _cairo_paginated_surface_create (target, content, width, height,
++					    _test_paginated_surface_set_paginated_mode);
  }
diff-tree 2984f60a3a4571a8d4179fdc64a9e67ce9854f21 (from 9ca67992a5816db49e8dca866816481483896814)
Author: Keith Packard <keithp at evo.keithp.com>
Date:   Mon Feb 27 20:09:24 2006 -0800

    Need cairo_analyze_surface_get_extents

diff --git a/src/cairo-analyze-surface.c b/src/cairo-analyze-surface.c
index e2d5e84..a3ea707 100644
--- a/src/cairo-analyze-surface.c
+++ b/src/cairo-analyze-surface.c
@@ -48,6 +48,15 @@ typedef struct {
 } cairo_analyze_surface_t;
 
 static cairo_int_status_t
+_cairo_analyze_surface_get_extents (void	 	*abstract_surface,
+				    cairo_rectangle_t	*rectangle)
+{
+    cairo_analyze_surface_t *surface = abstract_surface;
+
+    return _cairo_surface_get_extents (surface->target, rectangle);
+}
+
+static cairo_int_status_t
 _cairo_analyze_surface_paint (void			*abstract_surface,
 			      cairo_operator_t		op,
 			      cairo_pattern_t		*source)
@@ -181,7 +190,7 @@ static const cairo_surface_backend_t cai
     NULL, /* show_page */
     NULL, /* set_clip_region */
     NULL, /* clip_path */
-    NULL, /* get_extents */
+    _cairo_analyze_surface_get_extents,
     NULL, /* old_show_glyphs */
     NULL, /* get_font_options */
     NULL, /* flush */
diff-tree 9ca67992a5816db49e8dca866816481483896814 (from ad247974ebcfc5ede9fd3856eeaee4860318d118)
Author: Keith Packard <keithp at evo.keithp.com>
Date:   Mon Feb 27 20:05:57 2006 -0800

    Support meta surface patterns

diff --git a/src/cairo-paginated-surface.c b/src/cairo-paginated-surface.c
index a4979c1..17036a4 100644
--- a/src/cairo-paginated-surface.c
+++ b/src/cairo-paginated-surface.c
@@ -155,6 +155,15 @@ _cairo_paginated_surface_get_target (cai
     return paginated_surface->target;
 }
 
+static cairo_surface_t *
+_cairo_paginated_surface_create_similar (void		 *other,
+					 cairo_content_t  content,
+					 int		  width,
+					 int		  height)
+{
+    return _cairo_meta_surface_create (content, width, height);
+}
+
 static cairo_status_t
 _cairo_paginated_surface_finish (void *abstract_surface)
 {
@@ -412,7 +421,7 @@ _cairo_paginated_surface_snapshot (void 
 }
 
 const cairo_surface_backend_t cairo_paginated_surface_backend = {
-    NULL, /* create_similar */
+    _cairo_paginated_surface_create_similar,
     _cairo_paginated_surface_finish,
     _cairo_paginated_surface_acquire_source_image,
     _cairo_paginated_surface_release_source_image,
diff --git a/src/cairo-ps-surface.c b/src/cairo-ps-surface.c
index aa5ac89..4245c9b 100644
--- a/src/cairo-ps-surface.c
+++ b/src/cairo-ps-surface.c
@@ -41,6 +41,7 @@
 #include "cairo-ps.h"
 #include "cairo-font-subset-private.h"
 #include "cairo-paginated-surface-private.h"
+#include "cairo-meta-surface-private.h"
 #include "cairo-ft-private.h"
 
 #include <time.h>
@@ -620,9 +621,11 @@ operator_always_translucent (cairo_opera
 static cairo_bool_t
 pattern_surface_supported (const cairo_surface_pattern_t *pattern)
 {
-    if (pattern->surface->backend->acquire_source_image == NULL)
-	return FALSE;
-    return TRUE;
+    if (_cairo_surface_is_meta (pattern->surface))
+	return TRUE;
+    if (pattern->surface->backend->acquire_source_image != NULL)
+	return TRUE;
+    return FALSE;
 }
 
 static cairo_bool_t
@@ -823,20 +826,30 @@ static void
 emit_surface_pattern (cairo_ps_surface_t *surface,
 		      cairo_surface_pattern_t *pattern)
 {
-    cairo_image_surface_t	*image;
-    cairo_status_t		status;
-    void			*image_extra;
     cairo_rectangle_t		extents;
 
-    status = _cairo_surface_acquire_source_image (pattern->surface,
-						  &image,
-						  &image_extra);
-    assert (status == CAIRO_STATUS_SUCCESS);
-    emit_image (surface, image, &pattern->base.matrix, "MyPattern");
-    _cairo_surface_release_source_image (pattern->surface, image, image_extra);
+    if (_cairo_surface_is_meta (pattern->surface)) {
+	_cairo_output_stream_printf (surface->stream, "/MyPattern {\n");
+	_cairo_meta_surface_replay (pattern->surface, &surface->base);
+	extents.width = surface->width;
+	extents.height = surface->height;
+	_cairo_output_stream_printf (surface->stream, "} bind def\n");
+    } else {
+	cairo_image_surface_t	*image;
+	void			*image_extra;
+	cairo_status_t		status;
+
+	status = _cairo_surface_acquire_source_image (pattern->surface,
+						      &image,
+						      &image_extra);
+	_cairo_surface_get_extents (&image->base, &extents);
+	assert (status == CAIRO_STATUS_SUCCESS);
+	emit_image (surface, image, &pattern->base.matrix, "MyPattern");
+	_cairo_surface_release_source_image (pattern->surface, image,
+					     image_extra);
+    }
     _cairo_output_stream_printf (surface->stream,
 				 "<< /PatternType 1 /PaintType 1 /TilingType 1\n");
-    _cairo_surface_get_extents (&image->base, &extents);
     _cairo_output_stream_printf (surface->stream,
 				 "/BBox [0 0 %d %d]\n",
 				 extents.width, extents.height);
diff-tree ad247974ebcfc5ede9fd3856eeaee4860318d118 (from 59e4a32d550d14cfaa0687e716c7df0cadf56adc)
Author: Keith Packard <keithp at evo.keithp.com>
Date:   Mon Feb 27 19:34:32 2006 -0800

    Release pattern source image when done with it

diff --git a/src/cairo-ps-surface.c b/src/cairo-ps-surface.c
index 119b99e..aa5ac89 100644
--- a/src/cairo-ps-surface.c
+++ b/src/cairo-ps-surface.c
@@ -833,6 +833,7 @@ emit_surface_pattern (cairo_ps_surface_t
 						  &image_extra);
     assert (status == CAIRO_STATUS_SUCCESS);
     emit_image (surface, image, &pattern->base.matrix, "MyPattern");
+    _cairo_surface_release_source_image (pattern->surface, image, image_extra);
     _cairo_output_stream_printf (surface->stream,
 				 "<< /PatternType 1 /PaintType 1 /TilingType 1\n");
     _cairo_surface_get_extents (&image->base, &extents);
diff-tree 59e4a32d550d14cfaa0687e716c7df0cadf56adc (from 06b83b89fc4271060c63b284d7909162b92152f1)
Author: Keith Packard <keithp at evo.keithp.com>
Date:   Mon Feb 27 19:23:47 2006 -0800

    Primitive ps glyph support. Fix ps strokes to not leave path defined

diff --git a/src/cairo-ps-surface.c b/src/cairo-ps-surface.c
index c6aeff0..119b99e 100644
--- a/src/cairo-ps-surface.c
+++ b/src/cairo-ps-surface.c
@@ -752,10 +752,18 @@ emit_image (cairo_ps_surface_t    *surfa
     cairo_matrix_init (&d2i, 1, 0, 0, 1, 0, 0);
     cairo_matrix_multiply (&d2i, &d2i, matrix);
 
+#if 1
+    /* Construct a string holding the entire image (!) */
     _cairo_output_stream_printf (surface->stream, "/%sString %d string def\n",
 				 name, (int) rgb_size);
     _cairo_output_stream_printf (surface->stream,
 				 "currentfile %sString readstring\n", name);
+#else
+    /* Construct a reusable stream decoder holding the image */
+    _cairo_output_stream_printf (surface->stream, "/%sString <<\n", name);
+    /* intent = image data */
+    _cairo_output_stream_printf (surface->stream, "\t/Intent 0\n");
+#endif    
     /* Compressed image data */
     _cairo_output_stream_write (surface->stream, rgb, rgb_size);
 
@@ -781,7 +789,7 @@ emit_image (cairo_ps_surface_t    *surfa
 				 d2i.xx, d2i.yx,
 				 d2i.xy, d2i.yy,
 				 d2i.x0, d2i.y0);
-    _cairo_output_stream_printf (surface->stream, "} def\n");
+    _cairo_output_stream_printf (surface->stream, "} bind def\n");
 
     status = CAIRO_STATUS_SUCCESS;
 
@@ -1200,6 +1208,8 @@ _cairo_ps_surface_stroke (void			*abstra
     info.output_stream = stream;
     info.has_current_point = FALSE;
 
+    _cairo_output_stream_printf (stream,
+				 "gsave\n");
     status = _cairo_path_fixed_interpret (path,
 					  CAIRO_DIRECTION_FORWARD,
 					  _cairo_ps_surface_path_move_to,
@@ -1212,8 +1222,6 @@ _cairo_ps_surface_stroke (void			*abstra
      * Switch to user space to set line parameters
      */
     _cairo_output_stream_printf (stream,
-				 "gsave\n");
-    _cairo_output_stream_printf (stream,
 				 "[%f %f %f %f 0 0] concat\n",
 				 ctm->xx, ctm->yx, ctm->xy, ctm->yy);
     /* line width */
@@ -1301,6 +1309,41 @@ _cairo_ps_surface_fill (void		*abstract_
     return status;
 }
 
+static cairo_int_status_t
+_cairo_ps_surface_show_glyphs (void		     *abstract_surface,
+			       cairo_operator_t	      op,
+			       cairo_pattern_t	     *source,
+			       const cairo_glyph_t   *glyphs,
+			       int		      num_glyphs,
+			       cairo_scaled_font_t   *scaled_font)
+{
+    cairo_ps_surface_t *surface = abstract_surface;
+    cairo_output_stream_t *stream = surface->stream;
+    cairo_int_status_t status;
+    cairo_path_fixed_t *path;
+
+    if (surface->mode == CAIRO_PAGINATED_MODE_ANALYZE) {
+	if (!pattern_operation_supported (op, source))
+	    return CAIRO_INT_STATUS_UNSUPPORTED;
+	return CAIRO_STATUS_SUCCESS;
+    }
+
+    if (surface->need_start_page)
+	_cairo_ps_surface_start_page (surface);
+
+    _cairo_output_stream_printf (stream,
+				 "%% _cairo_ps_surface_show_glyphs\n");
+
+    path = _cairo_path_fixed_create ();
+    _cairo_scaled_font_glyph_path (scaled_font, glyphs, num_glyphs, path);
+    status = _cairo_ps_surface_fill (abstract_surface, op, source,
+				     path, CAIRO_FILL_RULE_WINDING,
+				     0.1, scaled_font->options.antialias);
+    _cairo_path_fixed_destroy (path);
+
+    return CAIRO_STATUS_SUCCESS;
+}
+
 static const cairo_surface_backend_t cairo_ps_surface_backend = {
     NULL, /* create_similar */
     _cairo_ps_surface_finish,
@@ -1334,7 +1377,8 @@ static const cairo_surface_backend_t cai
     NULL, /* mask */
     _cairo_ps_surface_stroke,
     _cairo_ps_surface_fill,
-    NULL /* show_glyphs */
+    _cairo_ps_surface_show_glyphs,
+    NULL, /* snapshot */
 };
 
 static void
diff --git a/src/cairo-scaled-font.c b/src/cairo-scaled-font.c
index 8ebbf45..22d22be 100644
--- a/src/cairo-scaled-font.c
+++ b/src/cairo-scaled-font.c
@@ -1008,7 +1008,7 @@ _scaled_glyph_path_close_path (void *abs
 
 cairo_status_t
 _cairo_scaled_font_glyph_path (cairo_scaled_font_t *scaled_font,
-			       cairo_glyph_t	   *glyphs, 
+			       const cairo_glyph_t *glyphs, 
 			       int		    num_glyphs,
 			       cairo_path_fixed_t  *path)
 {
diff --git a/src/cairoint.h b/src/cairoint.h
index 401114c..3d01e40 100644
--- a/src/cairoint.h
+++ b/src/cairoint.h
@@ -1529,7 +1529,7 @@ _cairo_scaled_font_show_glyphs (cairo_sc
 
 cairo_private cairo_status_t
 _cairo_scaled_font_glyph_path (cairo_scaled_font_t *scaled_font,
-			       cairo_glyph_t       *glyphs, 
+			       const cairo_glyph_t *glyphs, 
 			       int                  num_glyphs,
 			       cairo_path_fixed_t  *path);
 
diff-tree 06b83b89fc4271060c63b284d7909162b92152f1 (from f9d4482137e7f13e634cc578c64d84ffdea16bca)
Author: Keith Packard <keithp at evo.keithp.com>
Date:   Mon Feb 27 17:49:53 2006 -0800

    Support image surface patterns

diff --git a/src/cairo-ps-surface.c b/src/cairo-ps-surface.c
index f1ae414..c6aeff0 100644
--- a/src/cairo-ps-surface.c
+++ b/src/cairo-ps-surface.c
@@ -672,7 +672,8 @@ compress_dup (const void *data, unsigned
 static cairo_status_t
 emit_image (cairo_ps_surface_t    *surface,
 	    cairo_image_surface_t *image,
-	    cairo_matrix_t	  *matrix)
+	    cairo_matrix_t	  *matrix,
+	    char		  *name)
 {
     cairo_status_t status;
     unsigned char *rgb, *compressed;
@@ -751,6 +752,17 @@ emit_image (cairo_ps_surface_t    *surfa
     cairo_matrix_init (&d2i, 1, 0, 0, 1, 0, 0);
     cairo_matrix_multiply (&d2i, &d2i, matrix);
 
+    _cairo_output_stream_printf (surface->stream, "/%sString %d string def\n",
+				 name, (int) rgb_size);
+    _cairo_output_stream_printf (surface->stream,
+				 "currentfile %sString readstring\n", name);
+    /* Compressed image data */
+    _cairo_output_stream_write (surface->stream, rgb, rgb_size);
+
+    _cairo_output_stream_printf (surface->stream,
+				 "\n");
+
+    _cairo_output_stream_printf (surface->stream, "/%s {\n", name);
     _cairo_output_stream_printf (surface->stream,
 				 "/DeviceRGB setcolorspace\n"
 				 "<<\n"
@@ -759,23 +771,20 @@ emit_image (cairo_ps_surface_t    *surfa
 				 "	/Height %d\n"
 				 "	/BitsPerComponent 8\n"
 				 "	/Decode [ 0 1 0 1 0 1 ]\n"
-				 "	/DataSource currentfile\n"
+				 "	/DataSource %sString\n"
 				 "	/ImageMatrix [ %f %f %f %f %f %f ]\n"
 				 ">>\n"
 				 "image\n",
 				 opaque_image->width,
 				 opaque_image->height,
+				 name,
 				 d2i.xx, d2i.yx,
 				 d2i.xy, d2i.yy,
 				 d2i.x0, d2i.y0);
+    _cairo_output_stream_printf (surface->stream, "} def\n");
 
-    /* Compressed image data */
-    _cairo_output_stream_write (surface->stream, rgb, rgb_size);
     status = CAIRO_STATUS_SUCCESS;
 
-    _cairo_output_stream_printf (surface->stream,
-				 "\n");
-
     free (compressed);
  bail2:
     free (rgb);
@@ -809,12 +818,26 @@ emit_surface_pattern (cairo_ps_surface_t
     cairo_image_surface_t	*image;
     cairo_status_t		status;
     void			*image_extra;
+    cairo_rectangle_t		extents;
 
     status = _cairo_surface_acquire_source_image (pattern->surface,
 						  &image,
 						  &image_extra);
     assert (status == CAIRO_STATUS_SUCCESS);
-    emit_image (surface, image, &pattern->base.matrix);
+    emit_image (surface, image, &pattern->base.matrix, "MyPattern");
+    _cairo_output_stream_printf (surface->stream,
+				 "<< /PatternType 1 /PaintType 1 /TilingType 1\n");
+    _cairo_surface_get_extents (&image->base, &extents);
+    _cairo_output_stream_printf (surface->stream,
+				 "/BBox [0 0 %d %d]\n",
+				 extents.width, extents.height);
+    _cairo_output_stream_printf (surface->stream,
+				 "/XStep %d /YStep %d\n",
+				 extents.width, extents.height);
+    _cairo_output_stream_printf (surface->stream,
+				 "/PaintProc { begin MyPattern\n");
+    _cairo_output_stream_printf (surface->stream,
+				 " end } bind >> matrix makepattern setpattern\n");
 }
 
 static void
diff-tree ce683a240236fbe8083f284195acf0f78aa05048 (from aecb07a26d1db73cf6eee183de0f77615dea6830)
Author: Carl Worth <cworth at cworth.org>
Date:   Mon Feb 27 15:12:15 2006 -0800

    Drop gratuitous structure with single function pointer. Rename
    paginated_set_mode to set_paginated_mode.

diff --git a/src/cairo-paginated-surface-private.h b/src/cairo-paginated-surface-private.h
index b81b78b..cb32596 100644
--- a/src/cairo-paginated-surface-private.h
+++ b/src/cairo-paginated-surface-private.h
@@ -43,19 +43,15 @@ typedef enum {
     CAIRO_PAGINATED_MODE_RENDER		/* render page contents */
 } cairo_paginated_mode_t;
 
-typedef void (*cairo_paginated_set_mode_t) (cairo_surface_t 	   *target,
-					    cairo_paginated_mode_t mode);
-
-typedef struct {
-    cairo_paginated_set_mode_t	set_mode;
-} cairo_paginated_funcs_t;
+typedef void (*cairo_set_paginated_mode_func_t) (cairo_surface_t	*target,
+						 cairo_paginated_mode_t	 mode);
 
 cairo_private cairo_surface_t *
 _cairo_paginated_surface_create (cairo_surface_t	*target,
 				 cairo_content_t	 content,
 				 int			 width,
 				 int			 height,
-				 const cairo_paginated_funcs_t *funcs);
+				 cairo_set_paginated_mode_func_t set_paginated_mode);
 
 cairo_private cairo_surface_t *
 _cairo_paginated_surface_get_target (cairo_surface_t *surface);
diff --git a/src/cairo-paginated-surface.c b/src/cairo-paginated-surface.c
index 80e87ab..bb5e034 100644
--- a/src/cairo-paginated-surface.c
+++ b/src/cairo-paginated-surface.c
@@ -87,8 +87,8 @@ typedef struct _cairo_paginated_surface 
     /* The target surface to hold the final result. */
     cairo_surface_t *target;
 
-    /* Paginated-surface specific functions for the target */
-    const cairo_paginated_funcs_t *funcs;
+    /* Paginated-surface specific function for the target */
+    cairo_set_paginated_mode_func_t set_paginated_mode;
 
     /* A cairo_meta_surface to record all operations. To be replayed
      * against target, and also against image surface as necessary for
@@ -107,7 +107,7 @@ _cairo_paginated_surface_create (cairo_s
 				 cairo_content_t	 content,
 				 int			 width,
 				 int			 height,
-				 const cairo_paginated_funcs_t *funcs)
+				 cairo_set_paginated_mode_func_t set_paginated_mode)
 {
     cairo_paginated_surface_t *surface;
 
@@ -122,7 +122,7 @@ _cairo_paginated_surface_create (cairo_s
     surface->height = height;
 
     surface->target = target;
-    surface->funcs = funcs;
+    surface->set_paginated_mode = set_paginated_mode;
 
     surface->meta = _cairo_meta_surface_create (content, width, height);
     if (cairo_surface_status (surface->meta))
@@ -209,9 +209,9 @@ _paint_page (cairo_paginated_surface_t *
     analysis = _cairo_analysis_surface_create (surface->target,
 					       surface->width, surface->height);
 
-    surface->funcs->set_mode (surface->target, CAIRO_PAGINATED_MODE_ANALYZE);
+    surface->set_paginated_mode (surface->target, CAIRO_PAGINATED_MODE_ANALYZE);
     _cairo_meta_surface_replay (surface->meta, analysis);
-    surface->funcs->set_mode (surface->target, CAIRO_PAGINATED_MODE_RENDER);
+    surface->set_paginated_mode (surface->target, CAIRO_PAGINATED_MODE_RENDER);
 
     if (analysis->status) {
 	status = analysis->status;
diff --git a/src/cairo-ps-surface.c b/src/cairo-ps-surface.c
index f1ae414..7f31f58 100644
--- a/src/cairo-ps-surface.c
+++ b/src/cairo-ps-surface.c
@@ -56,7 +56,10 @@
  */
 
 static const cairo_surface_backend_t cairo_ps_surface_backend;
-static const cairo_paginated_funcs_t cairo_ps_paginated_funcs;
+
+static void
+_cairo_ps_set_paginated_mode (cairo_surface_t *target,
+			      cairo_paginated_mode_t mode);
 
 typedef struct cairo_ps_surface {
     cairo_surface_t base;
@@ -72,7 +75,7 @@ typedef struct cairo_ps_surface {
     cairo_bool_t need_start_page; 
     int num_pages;
 
-    cairo_paginated_mode_t mode;
+    cairo_paginated_mode_t paginated_mode;
 
 #if DONE_ADDING_FONTS_SUPPORT_BACK_AFTER_SWITCHING_TO_PAGINATED
     cairo_array_t fonts;
@@ -144,7 +147,7 @@ _cairo_ps_surface_create_for_stream_inte
     surface->height = height;
     surface->x_dpi = PS_SURFACE_DPI_DEFAULT;
     surface->y_dpi = PS_SURFACE_DPI_DEFAULT;
-    surface->mode = CAIRO_PAGINATED_MODE_ANALYZE;
+    surface->paginated_mode = CAIRO_PAGINATED_MODE_ANALYZE;
 #if DONE_ADDING_DEVICE_SCALE_SUPPORT_AFTER_SWITCHING_TO_PAGINATED
     surface->base.device_x_scale = surface->x_dpi / 72.0;
     surface->base.device_y_scale = surface->y_dpi / 72.0;
@@ -162,7 +165,7 @@ _cairo_ps_surface_create_for_stream_inte
     return _cairo_paginated_surface_create (&surface->base,
 					    CAIRO_CONTENT_COLOR_ALPHA,
 					    width, height,
-					    &cairo_ps_paginated_funcs);
+					    _cairo_ps_set_paginated_mode);
 }
 
 /**
@@ -943,7 +946,7 @@ _cairo_ps_surface_intersect_clip_path (v
     cairo_ps_surface_path_info_t info;
     const char *ps_operator;
 
-    if (surface->mode == CAIRO_PAGINATED_MODE_ANALYZE)
+    if (surface->paginated_mode == CAIRO_PAGINATED_MODE_ANALYZE)
 	return CAIRO_STATUS_SUCCESS;
 
     _cairo_output_stream_printf (stream,
@@ -1084,7 +1087,7 @@ _cairo_ps_surface_paint (void			*abstrac
     cairo_output_stream_t *stream = surface->stream;
     cairo_ps_surface_path_info_t info;
 
-    if (surface->mode == CAIRO_PAGINATED_MODE_ANALYZE) {
+    if (surface->paginated_mode == CAIRO_PAGINATED_MODE_ANALYZE) {
 	if (!pattern_operation_supported (op, source))
 	    return CAIRO_INT_STATUS_UNSUPPORTED;
 	return CAIRO_STATUS_SUCCESS;
@@ -1158,7 +1161,7 @@ _cairo_ps_surface_stroke (void			*abstra
     cairo_int_status_t status;
     cairo_ps_surface_path_info_t info;
 
-    if (surface->mode == CAIRO_PAGINATED_MODE_ANALYZE) {
+    if (surface->paginated_mode == CAIRO_PAGINATED_MODE_ANALYZE) {
 	if (!pattern_operation_supported (op, source))
 	    return CAIRO_INT_STATUS_UNSUPPORTED;
     
@@ -1236,7 +1239,7 @@ _cairo_ps_surface_fill (void		*abstract_
     cairo_ps_surface_path_info_t info;
     const char *ps_operator;
 
-    if (surface->mode == CAIRO_PAGINATED_MODE_ANALYZE) {
+    if (surface->paginated_mode == CAIRO_PAGINATED_MODE_ANALYZE) {
 	if (!pattern_operation_supported (op, source))
 	    return CAIRO_INT_STATUS_UNSUPPORTED;
 	return CAIRO_STATUS_SUCCESS;
@@ -1315,14 +1318,10 @@ static const cairo_surface_backend_t cai
 };
 
 static void
-_cairo_ps_paginated_set_mode (cairo_surface_t *target,
-			      cairo_paginated_mode_t mode)
+_cairo_ps_set_paginated_mode (cairo_surface_t *target,
+			      cairo_paginated_mode_t paginated_mode)
 {
-    cairo_ps_surface_t	*surface = (cairo_ps_surface_t *) target;
+    cairo_ps_surface_t *surface = (cairo_ps_surface_t *) target;
 
-    surface->mode = mode;
+    surface->paginated_mode = paginated_mode;
 }
-
-static const cairo_paginated_funcs_t cairo_ps_paginated_funcs = {
-    _cairo_ps_paginated_set_mode,
-};
diff-tree aecb07a26d1db73cf6eee183de0f77615dea6830 (from 2660e79e674a55e71014f83e9247372edd9ab531)
Author: Carl Worth <cworth at cworth.org>
Date:   Mon Feb 27 14:58:51 2006 -0800

    cairo_analysis_surface: Rename region_[un]supported() to get_[un]supported().

diff --git a/src/cairo-analysis-surface-private.h b/src/cairo-analysis-surface-private.h
index 75ec9ff..62e67ae 100644
--- a/src/cairo-analysis-surface-private.h
+++ b/src/cairo-analysis-surface-private.h
@@ -44,10 +44,10 @@ _cairo_analysis_surface_create (cairo_su
 				int			 height);
 
 cairo_private pixman_region16_t *
-_cairo_analysis_surface_region_supported (cairo_surface_t *surface);
+_cairo_analysis_surface_get_supported (cairo_surface_t *surface);
 
 cairo_private pixman_region16_t *
-_cairo_analysis_surface_region_unsupported (cairo_surface_t *unsupported);
+_cairo_analysis_surface_get_unsupported (cairo_surface_t *unsupported);
 
 cairo_private cairo_bool_t
 _cairo_analysis_surface_has_unsupported (cairo_surface_t *unsupported);
diff --git a/src/cairo-analysis-surface.c b/src/cairo-analysis-surface.c
index 4349da7..20ac5ae 100644
--- a/src/cairo-analysis-surface.c
+++ b/src/cairo-analysis-surface.c
@@ -222,14 +222,14 @@ FAIL:
 }
 
 cairo_private pixman_region16_t *
-_cairo_analysis_surface_region_supported (cairo_surface_t *abstract_surface)
+_cairo_analysis_surface_get_supported (cairo_surface_t *abstract_surface)
 {
     /* XXX */
     return NULL;
 }
 
 cairo_private pixman_region16_t *
-_cairo_analysis_surface_region_unsupported (cairo_surface_t *abstract_surface)
+_cairo_analysis_surface_get_unsupported (cairo_surface_t *abstract_surface)
 {
     /* XXX */
     return NULL;
diff-tree 2660e79e674a55e71014f83e9247372edd9ab531 (from f9d4482137e7f13e634cc578c64d84ffdea16bca)
Author: Carl Worth <cworth at cworth.org>
Date:   Mon Feb 27 14:56:41 2006 -0800

    Rename cairo_analyze_surface_t to cairo_analysis_surface_t.

diff --git a/src/Makefile.am b/src/Makefile.am
index 38947d4..adc6552 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -173,8 +173,8 @@ libcairo_la_SOURCES =				\
 	cairo-meta-surface-private.h		\
 	cairo-paginated-surface.c		\
 	cairo-paginated-surface-private.h	\
-	cairo-analyze-surface.c			\
-	cairo-analyze-surface-private.h		\
+	cairo-analysis-surface.c		\
+	cairo-analysis-surface-private.h	\
 	$(libcairo_atsui_sources)		\
 	$(libcairo_ft_sources)			\
 	$(libcairo_ps_sources)			\
@@ -189,7 +189,7 @@ libcairo_la_SOURCES =				\
 	$(libcairo_glitz_sources)		\
 	$(libcairo_win32_sources)		\
 	$(libcairo_beos_sources)		\
- 	$(libcairo_directfb_sources)	\
+	$(libcairo_directfb_sources)		\
 	cairoint.h
 
 libcairo_la_LDFLAGS = -version-info @VERSION_INFO@ -no-undefined $(export_symbols)
diff --git a/src/cairo-analysis-surface-private.h b/src/cairo-analysis-surface-private.h
new file mode 100644
index 0000000..75ec9ff
--- /dev/null
+++ b/src/cairo-analysis-surface-private.h
@@ -0,0 +1,55 @@
+/* $Id: $
+ *
+ * Copyright © 2005 Keith Packard
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it either under the terms of the GNU Lesser General Public
+ * License version 2.1 as published by the Free Software Foundation
+ * (the "LGPL") or, at your option, under the terms of the Mozilla
+ * Public License Version 1.1 (the "MPL"). If you do not alter this
+ * notice, a recipient may use your version of this file under either
+ * the MPL or the LGPL.
+ *
+ * You should have received a copy of the LGPL along with this library
+ * in the file COPYING-LGPL-2.1; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ * You should have received a copy of the MPL along with this library
+ * in the file COPYING-MPL-1.1
+ *
+ * The contents of this file are subject to the Mozilla Public License
+ * Version 1.1 (the "License"); you may not use this file except in
+ * compliance with the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY
+ * OF ANY KIND, either express or implied. See the LGPL or the MPL for
+ * the specific language governing rights and limitations.
+ *
+ * The Original Code is the cairo graphics library.
+ *
+ * The Initial Developer of the Original Code is Keith Packard
+ *
+ * Contributor(s):
+ *      Keith Packard <keithp at keithp.com>
+ */
+
+#ifndef CAIRO_ANALYSIS_SURFACE_H
+#define CAIRO_ANALYSIS_SURFACE_H
+
+#include "cairoint.h"
+
+cairo_private cairo_surface_t *
+_cairo_analysis_surface_create (cairo_surface_t		*target,
+				int			 width,
+				int			 height);
+
+cairo_private pixman_region16_t *
+_cairo_analysis_surface_region_supported (cairo_surface_t *surface);
+
+cairo_private pixman_region16_t *
+_cairo_analysis_surface_region_unsupported (cairo_surface_t *unsupported);
+
+cairo_private cairo_bool_t
+_cairo_analysis_surface_has_unsupported (cairo_surface_t *unsupported);
+
+#endif /* CAIRO_ANALYSIS_SURFACE_H */
diff --git a/src/cairo-analysis-surface.c b/src/cairo-analysis-surface.c
new file mode 100644
index 0000000..4349da7
--- /dev/null
+++ b/src/cairo-analysis-surface.c
@@ -0,0 +1,246 @@
+/*
+ * Copyright © 2006 Keith Packard
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it either under the terms of the GNU Lesser General Public
+ * License version 2.1 as published by the Free Software Foundation
+ * (the "LGPL") or, at your option, under the terms of the Mozilla
+ * Public License Version 1.1 (the "MPL"). If you do not alter this
+ * notice, a recipient may use your version of this file under either
+ * the MPL or the LGPL.
+ *
+ * You should have received a copy of the LGPL along with this library
+ * in the file COPYING-LGPL-2.1; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ * You should have received a copy of the MPL along with this library
+ * in the file COPYING-MPL-1.1
+ *
+ * The contents of this file are subject to the Mozilla Public License
+ * Version 1.1 (the "License"); you may not use this file except in
+ * compliance with the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY
+ * OF ANY KIND, either express or implied. See the LGPL or the MPL for
+ * the specific language governing rights and limitations.
+ *
+ * The Original Code is the cairo graphics library.
+ *
+ * The Initial Developer of the Original Code is Keith Packard
+ *
+ * Contributor(s):
+ *      Keith Packard <keithp at keithp.com>
+ */
+
+#include "cairoint.h"
+
+#include "cairo-analysis-surface-private.h"
+#include "cairo-paginated-surface-private.h"
+
+typedef struct {
+    cairo_surface_t base;
+    int width;
+    int height;
+
+    cairo_surface_t	*target;
+    
+    cairo_bool_t fallback;
+} cairo_analysis_surface_t;
+
+static cairo_int_status_t
+_cairo_analysis_surface_paint (void			*abstract_surface,
+			       cairo_operator_t		op,
+			       cairo_pattern_t		*source)
+{
+    cairo_analysis_surface_t *surface = abstract_surface;
+    cairo_status_t	     status;
+
+    if (!surface->target->backend->paint)
+	status = CAIRO_INT_STATUS_UNSUPPORTED;
+    else
+	status = (*surface->target->backend->paint) (surface->target, op,
+						     source);
+    if (status == CAIRO_INT_STATUS_UNSUPPORTED) {
+	surface->fallback = TRUE;
+	status = CAIRO_STATUS_SUCCESS;
+    }
+    return status;
+}
+
+static cairo_int_status_t
+_cairo_analysis_surface_mask (void		*abstract_surface,
+			      cairo_operator_t	 op,
+			      cairo_pattern_t	*source,
+			      cairo_pattern_t	*mask)
+{
+    cairo_analysis_surface_t *surface = abstract_surface;
+    cairo_status_t	     status;
+
+    if (!surface->target->backend->mask)
+	status = CAIRO_INT_STATUS_UNSUPPORTED;
+    else
+	status = (*surface->target->backend->mask) (surface->target, op,
+						    source, mask);
+    if (status == CAIRO_INT_STATUS_UNSUPPORTED) {
+	surface->fallback = TRUE;
+	status = CAIRO_STATUS_SUCCESS;
+    }
+    return status;
+}
+
+static cairo_int_status_t
+_cairo_analysis_surface_stroke (void			*abstract_surface,
+				cairo_operator_t	 op,
+				cairo_pattern_t		*source,
+				cairo_path_fixed_t	*path,
+				cairo_stroke_style_t	*style,
+				cairo_matrix_t		*ctm,
+				cairo_matrix_t		*ctm_inverse,
+				double			 tolerance,
+				cairo_antialias_t	 antialias)
+{
+    cairo_analysis_surface_t *surface = abstract_surface;
+    cairo_status_t	     status;
+
+    if (!surface->target->backend->stroke)
+	status = CAIRO_INT_STATUS_UNSUPPORTED;
+    else
+	status = (*surface->target->backend->stroke) (surface->target, op,
+						      source, path, style,
+						      ctm, ctm_inverse,
+						      tolerance, antialias);
+    if (status == CAIRO_INT_STATUS_UNSUPPORTED) {
+	surface->fallback = TRUE;
+	status = CAIRO_STATUS_SUCCESS;
+    }
+    return status;
+}
+
+static cairo_int_status_t
+_cairo_analysis_surface_fill (void			*abstract_surface,
+			      cairo_operator_t		 op,
+			      cairo_pattern_t		*source,
+			      cairo_path_fixed_t	*path,
+			      cairo_fill_rule_t	 	 fill_rule,
+			      double			 tolerance,
+			      cairo_antialias_t	 	 antialias)
+{
+    cairo_analysis_surface_t *surface = abstract_surface;
+    cairo_status_t	     status;
+
+    if (!surface->target->backend->fill)
+	status = CAIRO_INT_STATUS_UNSUPPORTED;
+    else
+	status = (*surface->target->backend->fill) (surface->target, op,
+						    source, path, fill_rule,
+						    tolerance, antialias);
+    if (status == CAIRO_INT_STATUS_UNSUPPORTED) {
+	surface->fallback = TRUE;
+	status = CAIRO_STATUS_SUCCESS;
+    }
+    return status;
+}
+
+static cairo_int_status_t
+_cairo_analysis_surface_show_glyphs (void		  *abstract_surface,
+				     cairo_operator_t	   op,
+				     cairo_pattern_t	  *source,
+				     const cairo_glyph_t  *glyphs,
+				     int		   num_glyphs,
+				     cairo_scaled_font_t  *scaled_font)
+{
+    cairo_analysis_surface_t *surface = abstract_surface;
+    cairo_status_t	     status;
+
+    if (!surface->target->backend->show_glyphs)
+	status = CAIRO_INT_STATUS_UNSUPPORTED;
+    else
+	status = (*surface->target->backend->show_glyphs) (surface->target, op,
+							   source,
+							   glyphs, num_glyphs,
+							   scaled_font);
+    if (status == CAIRO_INT_STATUS_UNSUPPORTED) {
+	surface->fallback = TRUE;
+	status = CAIRO_STATUS_SUCCESS;
+    }
+    return status;
+}
+
+static const cairo_surface_backend_t cairo_analysis_surface_backend = {
+    NULL, /* create_similar */
+    NULL, /* finish_surface */
+    NULL, /* acquire_source_image */
+    NULL, /* release_source_image */
+    NULL, /* acquire_dest_image */
+    NULL, /* release_dest_image */
+    NULL, /* clone_similar */
+    NULL, /* composite */
+    NULL, /* fill_rectangles */
+    NULL, /* composite_trapezoids */
+    NULL, /* copy_page */
+    NULL, /* show_page */
+    NULL, /* set_clip_region */
+    NULL, /* clip_path */
+    NULL, /* get_extents */
+    NULL, /* old_show_glyphs */
+    NULL, /* get_font_options */
+    NULL, /* flush */
+    NULL, /* mark_dirty_rectangle */
+    NULL, /* scaled_font_fini */
+    NULL, /* scaled_glyph_fini */
+    _cairo_analysis_surface_paint,
+    _cairo_analysis_surface_mask,
+    _cairo_analysis_surface_stroke,
+    _cairo_analysis_surface_fill,
+    _cairo_analysis_surface_show_glyphs,
+    NULL, /* snapshot */
+};
+
+cairo_private cairo_surface_t *
+_cairo_analysis_surface_create (cairo_surface_t		*target,
+				int			 width,
+				int			 height)
+{
+    cairo_analysis_surface_t *surface;
+
+    surface = malloc (sizeof (cairo_analysis_surface_t));
+    if (surface == NULL)
+	goto FAIL;
+
+    _cairo_surface_init (&surface->base, &cairo_analysis_surface_backend);
+
+    surface->width = width;
+    surface->height = height;
+
+    surface->target = target;
+    surface->fallback = FALSE;
+
+    return &surface->base;
+FAIL:
+    _cairo_error (CAIRO_STATUS_NO_MEMORY);
+    return NULL;
+}
+
+cairo_private pixman_region16_t *
+_cairo_analysis_surface_region_supported (cairo_surface_t *abstract_surface)
+{
+    /* XXX */
+    return NULL;
+}
+
+cairo_private pixman_region16_t *
+_cairo_analysis_surface_region_unsupported (cairo_surface_t *abstract_surface)
+{
+    /* XXX */
+    return NULL;
+}
+
+cairo_private cairo_bool_t
+_cairo_analysis_surface_has_unsupported (cairo_surface_t *abstract_surface)
+{
+    cairo_analysis_surface_t	*surface = (cairo_analysis_surface_t *) abstract_surface;
+
+    return surface->fallback;
+}
+
+
diff --git a/src/cairo-analyze-surface-private.h b/src/cairo-analyze-surface-private.h
deleted file mode 100644
index 1c90fc9..0000000
--- a/src/cairo-analyze-surface-private.h
+++ /dev/null
@@ -1,55 +0,0 @@
-/* $Id: $
- *
- * Copyright © 2005 Keith Packard
- *
- * This library is free software; you can redistribute it and/or
- * modify it either under the terms of the GNU Lesser General Public
- * License version 2.1 as published by the Free Software Foundation
- * (the "LGPL") or, at your option, under the terms of the Mozilla
- * Public License Version 1.1 (the "MPL"). If you do not alter this
- * notice, a recipient may use your version of this file under either
- * the MPL or the LGPL.
- *
- * You should have received a copy of the LGPL along with this library
- * in the file COPYING-LGPL-2.1; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- * You should have received a copy of the MPL along with this library
- * in the file COPYING-MPL-1.1
- *
- * The contents of this file are subject to the Mozilla Public License
- * Version 1.1 (the "License"); you may not use this file except in
- * compliance with the License. You may obtain a copy of the License at
- * http://www.mozilla.org/MPL/
- *
- * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY
- * OF ANY KIND, either express or implied. See the LGPL or the MPL for
- * the specific language governing rights and limitations.
- *
- * The Original Code is the cairo graphics library.
- *
- * The Initial Developer of the Original Code is Keith Packard
- *
- * Contributor(s):
- *      Keith Packard <keithp at keithp.com>
- */
-
-#ifndef CAIRO_ANALYZE_SURFACE_H
-#define CAIRO_ANALYZE_SURFACE_H
-
-#include "cairoint.h"
-
-cairo_private cairo_surface_t *
-_cairo_analyze_surface_create (cairo_surface_t		*target,
-			       int			 width,
-			       int			 height);
-
-cairo_private pixman_region16_t *
-_cairo_analyze_surface_region_supported (cairo_surface_t *surface);
-
-cairo_private pixman_region16_t *
-_cairo_analyze_surface_region_unsupported (cairo_surface_t *unsupported);
-
-cairo_private cairo_bool_t
-_cairo_analyze_surface_has_unsupported (cairo_surface_t *unsupported);
-
-#endif /* CAIRO_ANALYZE_SURFACE_H */
diff --git a/src/cairo-analyze-surface.c b/src/cairo-analyze-surface.c
deleted file mode 100644
index e2d5e84..0000000
--- a/src/cairo-analyze-surface.c
+++ /dev/null
@@ -1,246 +0,0 @@
-/*
- * Copyright © 2006 Keith Packard
- *
- * This library is free software; you can redistribute it and/or
- * modify it either under the terms of the GNU Lesser General Public
- * License version 2.1 as published by the Free Software Foundation
- * (the "LGPL") or, at your option, under the terms of the Mozilla
- * Public License Version 1.1 (the "MPL"). If you do not alter this
- * notice, a recipient may use your version of this file under either
- * the MPL or the LGPL.
- *
- * You should have received a copy of the LGPL along with this library
- * in the file COPYING-LGPL-2.1; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- * You should have received a copy of the MPL along with this library
- * in the file COPYING-MPL-1.1
- *
- * The contents of this file are subject to the Mozilla Public License
- * Version 1.1 (the "License"); you may not use this file except in
- * compliance with the License. You may obtain a copy of the License at
- * http://www.mozilla.org/MPL/
- *
- * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY
- * OF ANY KIND, either express or implied. See the LGPL or the MPL for
- * the specific language governing rights and limitations.
- *
- * The Original Code is the cairo graphics library.
- *
- * The Initial Developer of the Original Code is Keith Packard
- *
- * Contributor(s):
- *      Keith Packard <keithp at keithp.com>
- */
-
-#include "cairoint.h"
-
-#include "cairo-analyze-surface-private.h"
-#include "cairo-paginated-surface-private.h"
-
-typedef struct {
-    cairo_surface_t base;
-    int width;
-    int height;
-
-    cairo_surface_t	*target;
-    
-    cairo_bool_t fallback;
-} cairo_analyze_surface_t;
-
-static cairo_int_status_t
-_cairo_analyze_surface_paint (void			*abstract_surface,
-			      cairo_operator_t		op,
-			      cairo_pattern_t		*source)
-{
-    cairo_analyze_surface_t *surface = abstract_surface;
-    cairo_status_t	     status;
-
-    if (!surface->target->backend->paint)
-	status = CAIRO_INT_STATUS_UNSUPPORTED;
-    else
-	status = (*surface->target->backend->paint) (surface->target, op,
-						     source);
-    if (status == CAIRO_INT_STATUS_UNSUPPORTED) {
-	surface->fallback = TRUE;
-	status = CAIRO_STATUS_SUCCESS;
-    }
-    return status;
-}
-
-static cairo_int_status_t
-_cairo_analyze_surface_mask (void		*abstract_surface,
-			     cairo_operator_t	 op,
-			     cairo_pattern_t	*source,
-			     cairo_pattern_t	*mask)
-{
-    cairo_analyze_surface_t *surface = abstract_surface;
-    cairo_status_t	     status;
-
-    if (!surface->target->backend->mask)
-	status = CAIRO_INT_STATUS_UNSUPPORTED;
-    else
-	status = (*surface->target->backend->mask) (surface->target, op,
-						    source, mask);
-    if (status == CAIRO_INT_STATUS_UNSUPPORTED) {
-	surface->fallback = TRUE;
-	status = CAIRO_STATUS_SUCCESS;
-    }
-    return status;
-}
-
-static cairo_int_status_t
-_cairo_analyze_surface_stroke (void			*abstract_surface,
-			       cairo_operator_t	 	 op,
-			       cairo_pattern_t		*source,
-			       cairo_path_fixed_t	*path,
-			       cairo_stroke_style_t	*style,
-			       cairo_matrix_t		*ctm,
-			       cairo_matrix_t		*ctm_inverse,
-			       double			 tolerance,
-			       cairo_antialias_t	 antialias)
-{
-    cairo_analyze_surface_t *surface = abstract_surface;
-    cairo_status_t	     status;
-
-    if (!surface->target->backend->stroke)
-	status = CAIRO_INT_STATUS_UNSUPPORTED;
-    else
-	status = (*surface->target->backend->stroke) (surface->target, op,
-						      source, path, style,
-						      ctm, ctm_inverse,
-						      tolerance, antialias);
-    if (status == CAIRO_INT_STATUS_UNSUPPORTED) {
-	surface->fallback = TRUE;
-	status = CAIRO_STATUS_SUCCESS;
-    }
-    return status;
-}
-
-static cairo_int_status_t
-_cairo_analyze_surface_fill (void			*abstract_surface,
-			     cairo_operator_t		 op,
-			     cairo_pattern_t		*source,
-			     cairo_path_fixed_t		*path,
-			     cairo_fill_rule_t	 	 fill_rule,
-			     double			 tolerance,
-			     cairo_antialias_t	 	 antialias)
-{
-    cairo_analyze_surface_t *surface = abstract_surface;
-    cairo_status_t	     status;
-
-    if (!surface->target->backend->fill)
-	status = CAIRO_INT_STATUS_UNSUPPORTED;
-    else
-	status = (*surface->target->backend->fill) (surface->target, op,
-						    source, path, fill_rule,
-						    tolerance, antialias);
-    if (status == CAIRO_INT_STATUS_UNSUPPORTED) {
-	surface->fallback = TRUE;
-	status = CAIRO_STATUS_SUCCESS;
-    }
-    return status;
-}
-
-static cairo_int_status_t
-_cairo_analyze_surface_show_glyphs (void		  *abstract_surface,
-				    cairo_operator_t	   op,
-				    cairo_pattern_t	  *source,
-				    const cairo_glyph_t	  *glyphs,
-				    int		   	   num_glyphs,
-				    cairo_scaled_font_t   *scaled_font)
-{
-    cairo_analyze_surface_t *surface = abstract_surface;
-    cairo_status_t	     status;
-
-    if (!surface->target->backend->show_glyphs)
-	status = CAIRO_INT_STATUS_UNSUPPORTED;
-    else
-	status = (*surface->target->backend->show_glyphs) (surface->target, op,
-							   source,
-							   glyphs, num_glyphs,
-							   scaled_font);
-    if (status == CAIRO_INT_STATUS_UNSUPPORTED) {
-	surface->fallback = TRUE;
-	status = CAIRO_STATUS_SUCCESS;
-    }
-    return status;
-}
-
-static const cairo_surface_backend_t cairo_analyze_surface_backend = {
-    NULL, /* create_similar */
-    NULL, /* finish_surface */
-    NULL, /* acquire_source_image */
-    NULL, /* release_source_image */
-    NULL, /* acquire_dest_image */
-    NULL, /* release_dest_image */
-    NULL, /* clone_similar */
-    NULL, /* composite */
-    NULL, /* fill_rectangles */
-    NULL, /* composite_trapezoids */
-    NULL, /* copy_page */
-    NULL, /* show_page */
-    NULL, /* set_clip_region */
-    NULL, /* clip_path */
-    NULL, /* get_extents */
-    NULL, /* old_show_glyphs */
-    NULL, /* get_font_options */
-    NULL, /* flush */
-    NULL, /* mark_dirty_rectangle */
-    NULL, /* scaled_font_fini */
-    NULL, /* scaled_glyph_fini */
-    _cairo_analyze_surface_paint,
-    _cairo_analyze_surface_mask,
-    _cairo_analyze_surface_stroke,
-    _cairo_analyze_surface_fill,
-    _cairo_analyze_surface_show_glyphs,
-    NULL, /* snapshot */
-};
-
-cairo_private cairo_surface_t *
-_cairo_analyze_surface_create (cairo_surface_t		*target,
-				int			 width,
-				int			 height)
-{
-    cairo_analyze_surface_t *surface;
-
-    surface = malloc (sizeof (cairo_analyze_surface_t));
-    if (surface == NULL)
-	goto FAIL;
-
-    _cairo_surface_init (&surface->base, &cairo_analyze_surface_backend);
-
-    surface->width = width;
-    surface->height = height;
-
-    surface->target = target;
-    surface->fallback = FALSE;
-
-    return &surface->base;
-FAIL:
-    _cairo_error (CAIRO_STATUS_NO_MEMORY);
-    return NULL;
-}
-
-cairo_private pixman_region16_t *
-_cairo_analyze_surface_region_supported (cairo_surface_t *abstract_surface)
-{
-    /* XXX */
-    return NULL;
-}
-
-cairo_private pixman_region16_t *
-_cairo_analyze_surface_region_unsupported (cairo_surface_t *abstract_surface)
-{
-    /* XXX */
-    return NULL;
-}
-
-cairo_private cairo_bool_t
-_cairo_analyze_surface_has_unsupported (cairo_surface_t *abstract_surface)
-{
-    cairo_analyze_surface_t	*surface = (cairo_analyze_surface_t *) abstract_surface;
-
-    return surface->fallback;
-}
-
-
diff --git a/src/cairo-paginated-surface.c b/src/cairo-paginated-surface.c
index a4979c1..80e87ab 100644
--- a/src/cairo-paginated-surface.c
+++ b/src/cairo-paginated-surface.c
@@ -69,7 +69,7 @@
 
 #include "cairo-paginated-surface-private.h"
 #include "cairo-meta-surface-private.h"
-#include "cairo-analyze-surface-private.h"
+#include "cairo-analysis-surface-private.h"
 
 typedef struct _cairo_paginated_surface {
     cairo_surface_t base;
@@ -201,25 +201,25 @@ _cairo_paginated_surface_release_source_
 static cairo_int_status_t
 _paint_page (cairo_paginated_surface_t *surface)
 {
-    cairo_surface_t *analyze;
+    cairo_surface_t *analysis;
     cairo_surface_t *image;
     cairo_pattern_t *pattern;
     cairo_status_t status;
 
-    analyze = _cairo_analyze_surface_create (surface->target,
-					     surface->width, surface->height);
+    analysis = _cairo_analysis_surface_create (surface->target,
+					       surface->width, surface->height);
 
     surface->funcs->set_mode (surface->target, CAIRO_PAGINATED_MODE_ANALYZE);
-    _cairo_meta_surface_replay (surface->meta, analyze);
+    _cairo_meta_surface_replay (surface->meta, analysis);
     surface->funcs->set_mode (surface->target, CAIRO_PAGINATED_MODE_RENDER);
 
-    if (analyze->status) {
-	status = analyze->status;
-	cairo_surface_destroy (analyze);
+    if (analysis->status) {
+	status = analysis->status;
+	cairo_surface_destroy (analysis);
 	return status;
     }
     
-    if (_cairo_analyze_surface_has_unsupported (analyze))
+    if (_cairo_analysis_surface_has_unsupported (analysis))
     {
 	image = _cairo_image_surface_create_with_content (surface->content,
 							  surface->width,
diff-tree f9d4482137e7f13e634cc578c64d84ffdea16bca (from cb3a445150e3771d23854849c2a1c991eaee712c)
Author: Keith Packard <keithp at evo.keithp.com>
Date:   Mon Feb 27 17:14:57 2006 -0500

    rename evaluate surface to analyze surface, pull to separate files

diff --git a/src/Makefile.am b/src/Makefile.am
index 908bcb2..38947d4 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -173,6 +173,8 @@ libcairo_la_SOURCES =				\
 	cairo-meta-surface-private.h		\
 	cairo-paginated-surface.c		\
 	cairo-paginated-surface-private.h	\
+	cairo-analyze-surface.c			\
+	cairo-analyze-surface-private.h		\
 	$(libcairo_atsui_sources)		\
 	$(libcairo_ft_sources)			\
 	$(libcairo_ps_sources)			\
diff --git a/src/cairo-analyze-surface-private.h b/src/cairo-analyze-surface-private.h
new file mode 100644
index 0000000..1c90fc9
--- /dev/null
+++ b/src/cairo-analyze-surface-private.h
@@ -0,0 +1,55 @@
+/* $Id: $
+ *
+ * Copyright © 2005 Keith Packard
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it either under the terms of the GNU Lesser General Public
+ * License version 2.1 as published by the Free Software Foundation
+ * (the "LGPL") or, at your option, under the terms of the Mozilla
+ * Public License Version 1.1 (the "MPL"). If you do not alter this
+ * notice, a recipient may use your version of this file under either
+ * the MPL or the LGPL.
+ *
+ * You should have received a copy of the LGPL along with this library
+ * in the file COPYING-LGPL-2.1; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ * You should have received a copy of the MPL along with this library
+ * in the file COPYING-MPL-1.1
+ *
+ * The contents of this file are subject to the Mozilla Public License
+ * Version 1.1 (the "License"); you may not use this file except in
+ * compliance with the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY
+ * OF ANY KIND, either express or implied. See the LGPL or the MPL for
+ * the specific language governing rights and limitations.
+ *
+ * The Original Code is the cairo graphics library.
+ *
+ * The Initial Developer of the Original Code is Keith Packard
+ *
+ * Contributor(s):
+ *      Keith Packard <keithp at keithp.com>
+ */
+
+#ifndef CAIRO_ANALYZE_SURFACE_H
+#define CAIRO_ANALYZE_SURFACE_H
+
+#include "cairoint.h"
+
+cairo_private cairo_surface_t *
+_cairo_analyze_surface_create (cairo_surface_t		*target,
+			       int			 width,
+			       int			 height);
+
+cairo_private pixman_region16_t *
+_cairo_analyze_surface_region_supported (cairo_surface_t *surface);
+
+cairo_private pixman_region16_t *
+_cairo_analyze_surface_region_unsupported (cairo_surface_t *unsupported);
+
+cairo_private cairo_bool_t
+_cairo_analyze_surface_has_unsupported (cairo_surface_t *unsupported);
+
+#endif /* CAIRO_ANALYZE_SURFACE_H */
diff --git a/src/cairo-analyze-surface.c b/src/cairo-analyze-surface.c
new file mode 100644
index 0000000..e2d5e84
--- /dev/null
+++ b/src/cairo-analyze-surface.c
@@ -0,0 +1,246 @@
+/*
+ * Copyright © 2006 Keith Packard
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it either under the terms of the GNU Lesser General Public
+ * License version 2.1 as published by the Free Software Foundation
+ * (the "LGPL") or, at your option, under the terms of the Mozilla
+ * Public License Version 1.1 (the "MPL"). If you do not alter this
+ * notice, a recipient may use your version of this file under either
+ * the MPL or the LGPL.
+ *
+ * You should have received a copy of the LGPL along with this library
+ * in the file COPYING-LGPL-2.1; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ * You should have received a copy of the MPL along with this library
+ * in the file COPYING-MPL-1.1
+ *
+ * The contents of this file are subject to the Mozilla Public License
+ * Version 1.1 (the "License"); you may not use this file except in
+ * compliance with the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY
+ * OF ANY KIND, either express or implied. See the LGPL or the MPL for
+ * the specific language governing rights and limitations.
+ *
+ * The Original Code is the cairo graphics library.
+ *
+ * The Initial Developer of the Original Code is Keith Packard
+ *
+ * Contributor(s):
+ *      Keith Packard <keithp at keithp.com>
+ */
+
+#include "cairoint.h"
+
+#include "cairo-analyze-surface-private.h"
+#include "cairo-paginated-surface-private.h"
+
+typedef struct {
+    cairo_surface_t base;
+    int width;
+    int height;
+
+    cairo_surface_t	*target;
+    
+    cairo_bool_t fallback;
+} cairo_analyze_surface_t;
+
+static cairo_int_status_t
+_cairo_analyze_surface_paint (void			*abstract_surface,
+			      cairo_operator_t		op,
+			      cairo_pattern_t		*source)
+{
+    cairo_analyze_surface_t *surface = abstract_surface;
+    cairo_status_t	     status;
+
+    if (!surface->target->backend->paint)
+	status = CAIRO_INT_STATUS_UNSUPPORTED;
+    else
+	status = (*surface->target->backend->paint) (surface->target, op,
+						     source);
+    if (status == CAIRO_INT_STATUS_UNSUPPORTED) {
+	surface->fallback = TRUE;
+	status = CAIRO_STATUS_SUCCESS;
+    }
+    return status;
+}
+
+static cairo_int_status_t
+_cairo_analyze_surface_mask (void		*abstract_surface,
+			     cairo_operator_t	 op,
+			     cairo_pattern_t	*source,
+			     cairo_pattern_t	*mask)
+{
+    cairo_analyze_surface_t *surface = abstract_surface;
+    cairo_status_t	     status;
+
+    if (!surface->target->backend->mask)
+	status = CAIRO_INT_STATUS_UNSUPPORTED;
+    else
+	status = (*surface->target->backend->mask) (surface->target, op,
+						    source, mask);
+    if (status == CAIRO_INT_STATUS_UNSUPPORTED) {
+	surface->fallback = TRUE;
+	status = CAIRO_STATUS_SUCCESS;
+    }
+    return status;
+}
+
+static cairo_int_status_t
+_cairo_analyze_surface_stroke (void			*abstract_surface,
+			       cairo_operator_t	 	 op,
+			       cairo_pattern_t		*source,
+			       cairo_path_fixed_t	*path,
+			       cairo_stroke_style_t	*style,
+			       cairo_matrix_t		*ctm,
+			       cairo_matrix_t		*ctm_inverse,
+			       double			 tolerance,
+			       cairo_antialias_t	 antialias)
+{
+    cairo_analyze_surface_t *surface = abstract_surface;
+    cairo_status_t	     status;
+
+    if (!surface->target->backend->stroke)
+	status = CAIRO_INT_STATUS_UNSUPPORTED;
+    else
+	status = (*surface->target->backend->stroke) (surface->target, op,
+						      source, path, style,
+						      ctm, ctm_inverse,
+						      tolerance, antialias);
+    if (status == CAIRO_INT_STATUS_UNSUPPORTED) {
+	surface->fallback = TRUE;
+	status = CAIRO_STATUS_SUCCESS;
+    }
+    return status;
+}
+
+static cairo_int_status_t
+_cairo_analyze_surface_fill (void			*abstract_surface,
+			     cairo_operator_t		 op,
+			     cairo_pattern_t		*source,
+			     cairo_path_fixed_t		*path,
+			     cairo_fill_rule_t	 	 fill_rule,
+			     double			 tolerance,
+			     cairo_antialias_t	 	 antialias)
+{
+    cairo_analyze_surface_t *surface = abstract_surface;
+    cairo_status_t	     status;
+
+    if (!surface->target->backend->fill)
+	status = CAIRO_INT_STATUS_UNSUPPORTED;
+    else
+	status = (*surface->target->backend->fill) (surface->target, op,
+						    source, path, fill_rule,
+						    tolerance, antialias);
+    if (status == CAIRO_INT_STATUS_UNSUPPORTED) {
+	surface->fallback = TRUE;
+	status = CAIRO_STATUS_SUCCESS;
+    }
+    return status;
+}
+
+static cairo_int_status_t
+_cairo_analyze_surface_show_glyphs (void		  *abstract_surface,
+				    cairo_operator_t	   op,
+				    cairo_pattern_t	  *source,
+				    const cairo_glyph_t	  *glyphs,
+				    int		   	   num_glyphs,
+				    cairo_scaled_font_t   *scaled_font)
+{
+    cairo_analyze_surface_t *surface = abstract_surface;
+    cairo_status_t	     status;
+
+    if (!surface->target->backend->show_glyphs)
+	status = CAIRO_INT_STATUS_UNSUPPORTED;
+    else
+	status = (*surface->target->backend->show_glyphs) (surface->target, op,
+							   source,
+							   glyphs, num_glyphs,
+							   scaled_font);
+    if (status == CAIRO_INT_STATUS_UNSUPPORTED) {
+	surface->fallback = TRUE;
+	status = CAIRO_STATUS_SUCCESS;
+    }
+    return status;
+}
+
+static const cairo_surface_backend_t cairo_analyze_surface_backend = {
+    NULL, /* create_similar */
+    NULL, /* finish_surface */
+    NULL, /* acquire_source_image */
+    NULL, /* release_source_image */
+    NULL, /* acquire_dest_image */
+    NULL, /* release_dest_image */
+    NULL, /* clone_similar */
+    NULL, /* composite */
+    NULL, /* fill_rectangles */
+    NULL, /* composite_trapezoids */
+    NULL, /* copy_page */
+    NULL, /* show_page */
+    NULL, /* set_clip_region */
+    NULL, /* clip_path */
+    NULL, /* get_extents */
+    NULL, /* old_show_glyphs */
+    NULL, /* get_font_options */
+    NULL, /* flush */
+    NULL, /* mark_dirty_rectangle */
+    NULL, /* scaled_font_fini */
+    NULL, /* scaled_glyph_fini */
+    _cairo_analyze_surface_paint,
+    _cairo_analyze_surface_mask,
+    _cairo_analyze_surface_stroke,
+    _cairo_analyze_surface_fill,
+    _cairo_analyze_surface_show_glyphs,
+    NULL, /* snapshot */
+};
+
+cairo_private cairo_surface_t *
+_cairo_analyze_surface_create (cairo_surface_t		*target,
+				int			 width,
+				int			 height)
+{
+    cairo_analyze_surface_t *surface;
+
+    surface = malloc (sizeof (cairo_analyze_surface_t));
+    if (surface == NULL)
+	goto FAIL;
+
+    _cairo_surface_init (&surface->base, &cairo_analyze_surface_backend);
+
+    surface->width = width;
+    surface->height = height;
+
+    surface->target = target;
+    surface->fallback = FALSE;
+
+    return &surface->base;
+FAIL:
+    _cairo_error (CAIRO_STATUS_NO_MEMORY);
+    return NULL;
+}
+
+cairo_private pixman_region16_t *
+_cairo_analyze_surface_region_supported (cairo_surface_t *abstract_surface)
+{
+    /* XXX */
+    return NULL;
+}
+
+cairo_private pixman_region16_t *
+_cairo_analyze_surface_region_unsupported (cairo_surface_t *abstract_surface)
+{
+    /* XXX */
+    return NULL;
+}
+
+cairo_private cairo_bool_t
+_cairo_analyze_surface_has_unsupported (cairo_surface_t *abstract_surface)
+{
+    cairo_analyze_surface_t	*surface = (cairo_analyze_surface_t *) abstract_surface;
+
+    return surface->fallback;
+}
+
+
diff --git a/src/cairo-paginated-surface-private.h b/src/cairo-paginated-surface-private.h
index c4c656b..b81b78b 100644
--- a/src/cairo-paginated-surface-private.h
+++ b/src/cairo-paginated-surface-private.h
@@ -39,7 +39,7 @@
 #include "cairoint.h"
 
 typedef enum {
-    CAIRO_PAGINATED_MODE_EVALUATE,	/* evaluate page regions */
+    CAIRO_PAGINATED_MODE_ANALYZE,	/* analyze page regions */
     CAIRO_PAGINATED_MODE_RENDER		/* render page contents */
 } cairo_paginated_mode_t;
 
diff --git a/src/cairo-paginated-surface.c b/src/cairo-paginated-surface.c
index 6d4c02e..a4979c1 100644
--- a/src/cairo-paginated-surface.c
+++ b/src/cairo-paginated-surface.c
@@ -69,6 +69,7 @@
 
 #include "cairo-paginated-surface-private.h"
 #include "cairo-meta-surface-private.h"
+#include "cairo-analyze-surface-private.h"
 
 typedef struct _cairo_paginated_surface {
     cairo_surface_t base;
@@ -101,21 +102,6 @@ const cairo_private cairo_surface_backen
 static cairo_int_status_t
 _cairo_paginated_surface_show_page (void *abstract_surface);
 
-typedef struct {
-    cairo_surface_t base;
-    int width;
-    int height;
-
-    cairo_surface_t	*target;
-    
-    cairo_bool_t fallback;
-} cairo_evaluate_surface_t;
-
-static cairo_evaluate_surface_t *
-_cairo_evaluate_surface_create (cairo_surface_t		*target,
-				int			 width,
-				int			 height);
-
 cairo_surface_t *
 _cairo_paginated_surface_create (cairo_surface_t	*target,
 				 cairo_content_t	 content,
@@ -215,25 +201,25 @@ _cairo_paginated_surface_release_source_
 static cairo_int_status_t
 _paint_page (cairo_paginated_surface_t *surface)
 {
-    cairo_evaluate_surface_t *evaluate;
+    cairo_surface_t *analyze;
     cairo_surface_t *image;
     cairo_pattern_t *pattern;
     cairo_status_t status;
 
-    evaluate = _cairo_evaluate_surface_create (surface->target,
-					       surface->width, surface->height);
+    analyze = _cairo_analyze_surface_create (surface->target,
+					     surface->width, surface->height);
 
-    surface->funcs->set_mode (surface->target, CAIRO_PAGINATED_MODE_EVALUATE);
-    _cairo_meta_surface_replay (surface->meta, &evaluate->base);
+    surface->funcs->set_mode (surface->target, CAIRO_PAGINATED_MODE_ANALYZE);
+    _cairo_meta_surface_replay (surface->meta, analyze);
     surface->funcs->set_mode (surface->target, CAIRO_PAGINATED_MODE_RENDER);
 
-    if (evaluate->base.status) {
-	status = evaluate->base.status;
-	cairo_surface_destroy (&evaluate->base);
+    if (analyze->status) {
+	status = analyze->status;
+	cairo_surface_destroy (analyze);
 	return status;
     }
     
-    if (evaluate->fallback)
+    if (_cairo_analyze_surface_has_unsupported (analyze))
     {
 	image = _cairo_image_surface_create_with_content (surface->content,
 							  surface->width,
@@ -454,179 +440,3 @@ const cairo_surface_backend_t cairo_pagi
     _cairo_paginated_surface_show_glyphs,
     _cairo_paginated_surface_snapshot
 };
-
-static cairo_int_status_t
-_cairo_evaluate_surface_paint (void			*abstract_surface,
-			       cairo_operator_t		op,
-			       cairo_pattern_t		*source)
-{
-    cairo_evaluate_surface_t *surface = abstract_surface;
-    cairo_status_t	     status;
-
-    if (!surface->target->backend->paint)
-	status = CAIRO_INT_STATUS_UNSUPPORTED;
-    else
-	status = (*surface->target->backend->paint) (surface->target, op,
-						     source);
-    if (status == CAIRO_INT_STATUS_UNSUPPORTED) {
-	surface->fallback = TRUE;
-	status = CAIRO_STATUS_SUCCESS;
-    }
-    return status;
-}
-
-static cairo_int_status_t
-_cairo_evaluate_surface_mask (void		*abstract_surface,
-			      cairo_operator_t	 op,
-			      cairo_pattern_t	*source,
-			      cairo_pattern_t	*mask)
-{
-    cairo_evaluate_surface_t *surface = abstract_surface;
-    cairo_status_t	     status;
-
-    if (!surface->target->backend->mask)
-	status = CAIRO_INT_STATUS_UNSUPPORTED;
-    else
-	status = (*surface->target->backend->mask) (surface->target, op,
-						    source, mask);
-    if (status == CAIRO_INT_STATUS_UNSUPPORTED) {
-	surface->fallback = TRUE;
-	status = CAIRO_STATUS_SUCCESS;
-    }
-    return status;
-}
-
-static cairo_int_status_t
-_cairo_evaluate_surface_stroke (void			*abstract_surface,
-				cairo_operator_t	 op,
-				cairo_pattern_t		*source,
-				cairo_path_fixed_t	*path,
-				cairo_stroke_style_t	*style,
-				cairo_matrix_t		*ctm,
-				cairo_matrix_t		*ctm_inverse,
-				double			 tolerance,
-				cairo_antialias_t	 antialias)
-{
-    cairo_evaluate_surface_t *surface = abstract_surface;
-    cairo_status_t	     status;
-
-    if (!surface->target->backend->stroke)
-	status = CAIRO_INT_STATUS_UNSUPPORTED;
-    else
-	status = (*surface->target->backend->stroke) (surface->target, op,
-						      source, path, style,
-						      ctm, ctm_inverse,
-						      tolerance, antialias);
-    if (status == CAIRO_INT_STATUS_UNSUPPORTED) {
-	surface->fallback = TRUE;
-	status = CAIRO_STATUS_SUCCESS;
-    }
-    return status;
-}
-
-static cairo_int_status_t
-_cairo_evaluate_surface_fill (void			*abstract_surface,
-			      cairo_operator_t		 op,
-			      cairo_pattern_t		*source,
-			      cairo_path_fixed_t	*path,
-			      cairo_fill_rule_t	 	 fill_rule,
-			      double			 tolerance,
-			      cairo_antialias_t	 	 antialias)
-{
-    cairo_evaluate_surface_t *surface = abstract_surface;
-    cairo_status_t	     status;
-
-    if (!surface->target->backend->fill)
-	status = CAIRO_INT_STATUS_UNSUPPORTED;
-    else
-	status = (*surface->target->backend->fill) (surface->target, op,
-						    source, path, fill_rule,
-						    tolerance, antialias);
-    if (status == CAIRO_INT_STATUS_UNSUPPORTED) {
-	surface->fallback = TRUE;
-	status = CAIRO_STATUS_SUCCESS;
-    }
-    return status;
-}
-
-static cairo_int_status_t
-_cairo_evaluate_surface_show_glyphs (void		  *abstract_surface,
-				     cairo_operator_t	   op,
-				     cairo_pattern_t	  *source,
-				     const cairo_glyph_t  *glyphs,
-				     int		   num_glyphs,
-				     cairo_scaled_font_t  *scaled_font)
-{
-    cairo_evaluate_surface_t *surface = abstract_surface;
-    cairo_status_t	     status;
-
-    if (!surface->target->backend->show_glyphs)
-	status = CAIRO_INT_STATUS_UNSUPPORTED;
-    else
-	status = (*surface->target->backend->show_glyphs) (surface->target, op,
-							   source,
-							   glyphs, num_glyphs,
-							   scaled_font);
-    if (status == CAIRO_INT_STATUS_UNSUPPORTED) {
-	surface->fallback = TRUE;
-	status = CAIRO_STATUS_SUCCESS;
-    }
-    return status;
-}
-
-static const cairo_surface_backend_t cairo_evaluate_surface_backend = {
-    NULL, /* create_similar */
-    NULL, /* finish_surface */
-    NULL, /* acquire_source_image */
-    NULL, /* release_source_image */
-    NULL, /* acquire_dest_image */
-    NULL, /* release_dest_image */
-    NULL, /* clone_similar */
-    NULL, /* composite */
-    NULL, /* fill_rectangles */
-    NULL, /* composite_trapezoids */
-    NULL, /* copy_page */
-    NULL, /* show_page */
-    NULL, /* set_clip_region */
-    NULL, /* clip_path */
-    NULL, /* get_extents */
-    NULL, /* old_show_glyphs */
-    NULL, /* get_font_options */
-    NULL, /* flush */
-    NULL, /* mark_dirty_rectangle */
-    NULL, /* scaled_font_fini */
-    NULL, /* scaled_glyph_fini */
-    _cairo_evaluate_surface_paint,
-    _cairo_evaluate_surface_mask,
-    _cairo_evaluate_surface_stroke,
-    _cairo_evaluate_surface_fill,
-    _cairo_evaluate_surface_show_glyphs,
-    NULL, /* snapshot */
-};
-
-static cairo_evaluate_surface_t *
-_cairo_evaluate_surface_create (cairo_surface_t		*target,
-				int			 width,
-				int			 height)
-{
-    cairo_evaluate_surface_t *surface;
-
-    surface = malloc (sizeof (cairo_evaluate_surface_t));
-    if (surface == NULL)
-	goto FAIL;
-
-    _cairo_surface_init (&surface->base, &cairo_evaluate_surface_backend);
-
-    surface->width = width;
-    surface->height = height;
-
-    surface->target = target;
-    surface->fallback = FALSE;
-
-    return surface;
-FAIL:
-    _cairo_error (CAIRO_STATUS_NO_MEMORY);
-    return NULL;
-}
-
-
diff --git a/src/cairo-ps-surface.c b/src/cairo-ps-surface.c
index 2cf8a9d..f1ae414 100644
--- a/src/cairo-ps-surface.c
+++ b/src/cairo-ps-surface.c
@@ -144,7 +144,7 @@ _cairo_ps_surface_create_for_stream_inte
     surface->height = height;
     surface->x_dpi = PS_SURFACE_DPI_DEFAULT;
     surface->y_dpi = PS_SURFACE_DPI_DEFAULT;
-    surface->mode = CAIRO_PAGINATED_MODE_EVALUATE;
+    surface->mode = CAIRO_PAGINATED_MODE_ANALYZE;
 #if DONE_ADDING_DEVICE_SCALE_SUPPORT_AFTER_SWITCHING_TO_PAGINATED
     surface->base.device_x_scale = surface->x_dpi / 72.0;
     surface->base.device_y_scale = surface->y_dpi / 72.0;
@@ -943,7 +943,7 @@ _cairo_ps_surface_intersect_clip_path (v
     cairo_ps_surface_path_info_t info;
     const char *ps_operator;
 
-    if (surface->mode == CAIRO_PAGINATED_MODE_EVALUATE)
+    if (surface->mode == CAIRO_PAGINATED_MODE_ANALYZE)
 	return CAIRO_STATUS_SUCCESS;
 
     _cairo_output_stream_printf (stream,
@@ -1084,7 +1084,7 @@ _cairo_ps_surface_paint (void			*abstrac
     cairo_output_stream_t *stream = surface->stream;
     cairo_ps_surface_path_info_t info;
 
-    if (surface->mode == CAIRO_PAGINATED_MODE_EVALUATE) {
+    if (surface->mode == CAIRO_PAGINATED_MODE_ANALYZE) {
 	if (!pattern_operation_supported (op, source))
 	    return CAIRO_INT_STATUS_UNSUPPORTED;
 	return CAIRO_STATUS_SUCCESS;
@@ -1158,7 +1158,7 @@ _cairo_ps_surface_stroke (void			*abstra
     cairo_int_status_t status;
     cairo_ps_surface_path_info_t info;
 
-    if (surface->mode == CAIRO_PAGINATED_MODE_EVALUATE) {
+    if (surface->mode == CAIRO_PAGINATED_MODE_ANALYZE) {
 	if (!pattern_operation_supported (op, source))
 	    return CAIRO_INT_STATUS_UNSUPPORTED;
     
@@ -1236,7 +1236,7 @@ _cairo_ps_surface_fill (void		*abstract_
     cairo_ps_surface_path_info_t info;
     const char *ps_operator;
 
-    if (surface->mode == CAIRO_PAGINATED_MODE_EVALUATE) {
+    if (surface->mode == CAIRO_PAGINATED_MODE_ANALYZE) {
 	if (!pattern_operation_supported (op, source))
 	    return CAIRO_INT_STATUS_UNSUPPORTED;
 	return CAIRO_STATUS_SUCCESS;
diff-tree cb3a445150e3771d23854849c2a1c991eaee712c (from 5a3c30eafe0b77f69434e139a2e247c8eb4230d7)
Author: Keith Packard <keithp at evo.keithp.com>
Date:   Mon Feb 27 19:47:14 2006 +0100

    Primitive "real" postscript output for stroke/fill/paint

diff --git a/src/cairo-paginated-surface-private.h b/src/cairo-paginated-surface-private.h
index 79438e4..c4c656b 100644
--- a/src/cairo-paginated-surface-private.h
+++ b/src/cairo-paginated-surface-private.h
@@ -38,11 +38,24 @@
 
 #include "cairoint.h"
 
+typedef enum {
+    CAIRO_PAGINATED_MODE_EVALUATE,	/* evaluate page regions */
+    CAIRO_PAGINATED_MODE_RENDER		/* render page contents */
+} cairo_paginated_mode_t;
+
+typedef void (*cairo_paginated_set_mode_t) (cairo_surface_t 	   *target,
+					    cairo_paginated_mode_t mode);
+
+typedef struct {
+    cairo_paginated_set_mode_t	set_mode;
+} cairo_paginated_funcs_t;
+
 cairo_private cairo_surface_t *
 _cairo_paginated_surface_create (cairo_surface_t	*target,
 				 cairo_content_t	 content,
 				 int			 width,
-				 int			 height);
+				 int			 height,
+				 const cairo_paginated_funcs_t *funcs);
 
 cairo_private cairo_surface_t *
 _cairo_paginated_surface_get_target (cairo_surface_t *surface);
diff --git a/src/cairo-paginated-surface.c b/src/cairo-paginated-surface.c
index 6317d70..6d4c02e 100644
--- a/src/cairo-paginated-surface.c
+++ b/src/cairo-paginated-surface.c
@@ -31,6 +31,7 @@
  *
  * Contributor(s):
  *	Carl Worth <cworth at cworth.org>
+ *	Keith Packard <keithp at keithp.com>
  */
 
 /* The paginated surface layer exists to provide as much code sharing
@@ -85,6 +86,9 @@ typedef struct _cairo_paginated_surface 
     /* The target surface to hold the final result. */
     cairo_surface_t *target;
 
+    /* Paginated-surface specific functions for the target */
+    const cairo_paginated_funcs_t *funcs;
+
     /* A cairo_meta_surface to record all operations. To be replayed
      * against target, and also against image surface as necessary for
      * fallbacks. */
@@ -97,11 +101,27 @@ const cairo_private cairo_surface_backen
 static cairo_int_status_t
 _cairo_paginated_surface_show_page (void *abstract_surface);
 
+typedef struct {
+    cairo_surface_t base;
+    int width;
+    int height;
+
+    cairo_surface_t	*target;
+    
+    cairo_bool_t fallback;
+} cairo_evaluate_surface_t;
+
+static cairo_evaluate_surface_t *
+_cairo_evaluate_surface_create (cairo_surface_t		*target,
+				int			 width,
+				int			 height);
+
 cairo_surface_t *
 _cairo_paginated_surface_create (cairo_surface_t	*target,
 				 cairo_content_t	 content,
 				 int			 width,
-				 int			 height)
+				 int			 height,
+				 const cairo_paginated_funcs_t *funcs)
 {
     cairo_paginated_surface_t *surface;
 
@@ -116,6 +136,7 @@ _cairo_paginated_surface_create (cairo_s
     surface->height = height;
 
     surface->target = target;
+    surface->funcs = funcs;
 
     surface->meta = _cairo_meta_surface_create (content, width, height);
     if (cairo_surface_status (surface->meta))
@@ -191,25 +212,49 @@ _cairo_paginated_surface_release_source_
     cairo_surface_destroy (&image->base);
 }
 
-static void
+static cairo_int_status_t
 _paint_page (cairo_paginated_surface_t *surface)
 {
+    cairo_evaluate_surface_t *evaluate;
     cairo_surface_t *image;
     cairo_pattern_t *pattern;
+    cairo_status_t status;
 
-    image = _cairo_image_surface_create_with_content (surface->content,
-						      surface->width,
-						      surface->height);
-
-    _cairo_meta_surface_replay (surface->meta, image);
-
-    pattern = cairo_pattern_create_for_surface (image);
-
-    _cairo_surface_paint (surface->target, CAIRO_OPERATOR_SOURCE, pattern);
+    evaluate = _cairo_evaluate_surface_create (surface->target,
+					       surface->width, surface->height);
 
-    cairo_pattern_destroy (pattern);
-
-    cairo_surface_destroy (image);
+    surface->funcs->set_mode (surface->target, CAIRO_PAGINATED_MODE_EVALUATE);
+    _cairo_meta_surface_replay (surface->meta, &evaluate->base);
+    surface->funcs->set_mode (surface->target, CAIRO_PAGINATED_MODE_RENDER);
+
+    if (evaluate->base.status) {
+	status = evaluate->base.status;
+	cairo_surface_destroy (&evaluate->base);
+	return status;
+    }
+    
+    if (evaluate->fallback)
+    {
+	image = _cairo_image_surface_create_with_content (surface->content,
+							  surface->width,
+							  surface->height);
+
+	_cairo_meta_surface_replay (surface->meta, image);
+
+	pattern = cairo_pattern_create_for_surface (image);
+
+	_cairo_surface_paint (surface->target, CAIRO_OPERATOR_SOURCE, pattern);
+
+	cairo_pattern_destroy (pattern);
+
+	cairo_surface_destroy (image);
+    }
+    else
+    {
+	_cairo_meta_surface_replay (surface->meta, surface->target);
+    }
+	
+    return CAIRO_STATUS_SUCCESS;
 }
 
 static cairo_int_status_t
@@ -409,3 +454,179 @@ const cairo_surface_backend_t cairo_pagi
     _cairo_paginated_surface_show_glyphs,
     _cairo_paginated_surface_snapshot
 };
+
+static cairo_int_status_t
+_cairo_evaluate_surface_paint (void			*abstract_surface,
+			       cairo_operator_t		op,
+			       cairo_pattern_t		*source)
+{
+    cairo_evaluate_surface_t *surface = abstract_surface;
+    cairo_status_t	     status;
+
+    if (!surface->target->backend->paint)
+	status = CAIRO_INT_STATUS_UNSUPPORTED;
+    else
+	status = (*surface->target->backend->paint) (surface->target, op,
+						     source);
+    if (status == CAIRO_INT_STATUS_UNSUPPORTED) {
+	surface->fallback = TRUE;
+	status = CAIRO_STATUS_SUCCESS;
+    }
+    return status;
+}
+
+static cairo_int_status_t
+_cairo_evaluate_surface_mask (void		*abstract_surface,
+			      cairo_operator_t	 op,
+			      cairo_pattern_t	*source,
+			      cairo_pattern_t	*mask)
+{
+    cairo_evaluate_surface_t *surface = abstract_surface;
+    cairo_status_t	     status;
+
+    if (!surface->target->backend->mask)
+	status = CAIRO_INT_STATUS_UNSUPPORTED;
+    else
+	status = (*surface->target->backend->mask) (surface->target, op,
+						    source, mask);
+    if (status == CAIRO_INT_STATUS_UNSUPPORTED) {
+	surface->fallback = TRUE;
+	status = CAIRO_STATUS_SUCCESS;
+    }
+    return status;
+}
+
+static cairo_int_status_t
+_cairo_evaluate_surface_stroke (void			*abstract_surface,
+				cairo_operator_t	 op,
+				cairo_pattern_t		*source,
+				cairo_path_fixed_t	*path,
+				cairo_stroke_style_t	*style,
+				cairo_matrix_t		*ctm,
+				cairo_matrix_t		*ctm_inverse,
+				double			 tolerance,
+				cairo_antialias_t	 antialias)
+{
+    cairo_evaluate_surface_t *surface = abstract_surface;
+    cairo_status_t	     status;
+
+    if (!surface->target->backend->stroke)
+	status = CAIRO_INT_STATUS_UNSUPPORTED;
+    else
+	status = (*surface->target->backend->stroke) (surface->target, op,
+						      source, path, style,
+						      ctm, ctm_inverse,
+						      tolerance, antialias);
+    if (status == CAIRO_INT_STATUS_UNSUPPORTED) {
+	surface->fallback = TRUE;
+	status = CAIRO_STATUS_SUCCESS;
+    }
+    return status;
+}
+
+static cairo_int_status_t
+_cairo_evaluate_surface_fill (void			*abstract_surface,
+			      cairo_operator_t		 op,
+			      cairo_pattern_t		*source,
+			      cairo_path_fixed_t	*path,
+			      cairo_fill_rule_t	 	 fill_rule,
+			      double			 tolerance,
+			      cairo_antialias_t	 	 antialias)
+{
+    cairo_evaluate_surface_t *surface = abstract_surface;
+    cairo_status_t	     status;
+
+    if (!surface->target->backend->fill)
+	status = CAIRO_INT_STATUS_UNSUPPORTED;
+    else
+	status = (*surface->target->backend->fill) (surface->target, op,
+						    source, path, fill_rule,
+						    tolerance, antialias);
+    if (status == CAIRO_INT_STATUS_UNSUPPORTED) {
+	surface->fallback = TRUE;
+	status = CAIRO_STATUS_SUCCESS;
+    }
+    return status;
+}
+
+static cairo_int_status_t
+_cairo_evaluate_surface_show_glyphs (void		  *abstract_surface,
+				     cairo_operator_t	   op,
+				     cairo_pattern_t	  *source,
+				     const cairo_glyph_t  *glyphs,
+				     int		   num_glyphs,
+				     cairo_scaled_font_t  *scaled_font)
+{
+    cairo_evaluate_surface_t *surface = abstract_surface;
+    cairo_status_t	     status;
+
+    if (!surface->target->backend->show_glyphs)
+	status = CAIRO_INT_STATUS_UNSUPPORTED;
+    else
+	status = (*surface->target->backend->show_glyphs) (surface->target, op,
+							   source,
+							   glyphs, num_glyphs,
+							   scaled_font);
+    if (status == CAIRO_INT_STATUS_UNSUPPORTED) {
+	surface->fallback = TRUE;
+	status = CAIRO_STATUS_SUCCESS;
+    }
+    return status;
+}
+
+static const cairo_surface_backend_t cairo_evaluate_surface_backend = {
+    NULL, /* create_similar */
+    NULL, /* finish_surface */
+    NULL, /* acquire_source_image */
+    NULL, /* release_source_image */
+    NULL, /* acquire_dest_image */
+    NULL, /* release_dest_image */
+    NULL, /* clone_similar */
+    NULL, /* composite */
+    NULL, /* fill_rectangles */
+    NULL, /* composite_trapezoids */
+    NULL, /* copy_page */
+    NULL, /* show_page */
+    NULL, /* set_clip_region */
+    NULL, /* clip_path */
+    NULL, /* get_extents */
+    NULL, /* old_show_glyphs */
+    NULL, /* get_font_options */
+    NULL, /* flush */
+    NULL, /* mark_dirty_rectangle */
+    NULL, /* scaled_font_fini */
+    NULL, /* scaled_glyph_fini */
+    _cairo_evaluate_surface_paint,
+    _cairo_evaluate_surface_mask,
+    _cairo_evaluate_surface_stroke,
+    _cairo_evaluate_surface_fill,
+    _cairo_evaluate_surface_show_glyphs,
+    NULL, /* snapshot */
+};
+
+static cairo_evaluate_surface_t *
+_cairo_evaluate_surface_create (cairo_surface_t		*target,
+				int			 width,
+				int			 height)
+{
+    cairo_evaluate_surface_t *surface;
+
+    surface = malloc (sizeof (cairo_evaluate_surface_t));
+    if (surface == NULL)
+	goto FAIL;
+
+    _cairo_surface_init (&surface->base, &cairo_evaluate_surface_backend);
+
+    surface->width = width;
+    surface->height = height;
+
+    surface->target = target;
+    surface->fallback = FALSE;
+
+    return surface;
+FAIL:
+    _cairo_error (CAIRO_STATUS_NO_MEMORY);
+    return NULL;
+}
+
+
diff --git a/src/cairo-pdf-surface.c b/src/cairo-pdf-surface.c
index 289eeb9..dd2fa90 100644
--- a/src/cairo-pdf-surface.c
+++ b/src/cairo-pdf-surface.c
@@ -306,7 +306,8 @@ _cairo_pdf_surface_create_for_stream_int
 
     return _cairo_paginated_surface_create (target,
 					    CAIRO_CONTENT_COLOR_ALPHA,
-					    width, height);
+					    width, height,
+					    NULL); /* XXX */
 }
 
 /**
diff --git a/src/cairo-ps-surface.c b/src/cairo-ps-surface.c
index 371290c..2cf8a9d 100644
--- a/src/cairo-ps-surface.c
+++ b/src/cairo-ps-surface.c
@@ -56,6 +56,7 @@
  */
 
 static const cairo_surface_backend_t cairo_ps_surface_backend;
+static const cairo_paginated_funcs_t cairo_ps_paginated_funcs;
 
 typedef struct cairo_ps_surface {
     cairo_surface_t base;
@@ -71,6 +72,8 @@ typedef struct cairo_ps_surface {
     cairo_bool_t need_start_page; 
     int num_pages;
 
+    cairo_paginated_mode_t mode;
+
 #if DONE_ADDING_FONTS_SUPPORT_BACK_AFTER_SWITCHING_TO_PAGINATED
     cairo_array_t fonts;
 #endif
@@ -141,6 +144,7 @@ _cairo_ps_surface_create_for_stream_inte
     surface->height = height;
     surface->x_dpi = PS_SURFACE_DPI_DEFAULT;
     surface->y_dpi = PS_SURFACE_DPI_DEFAULT;
+    surface->mode = CAIRO_PAGINATED_MODE_EVALUATE;
 #if DONE_ADDING_DEVICE_SCALE_SUPPORT_AFTER_SWITCHING_TO_PAGINATED
     surface->base.device_x_scale = surface->x_dpi / 72.0;
     surface->base.device_y_scale = surface->y_dpi / 72.0;
@@ -157,7 +161,8 @@ _cairo_ps_surface_create_for_stream_inte
 
     return _cairo_paginated_surface_create (&surface->base,
 					    CAIRO_CONTENT_COLOR_ALPHA,
-					    width, height);
+					    width, height,
+					    &cairo_ps_paginated_funcs);
 }
 
 /**
@@ -472,17 +477,6 @@ _cairo_ps_surface_write_font_subsets (ca
 }
 #endif
 
-/* XXX: This function wil go away in favor of the new "analysis mode"
- * of cairo_paginated_surface_t */
-static cairo_int_status_t
-_cairo_ps_surface_add_fallback_area (cairo_ps_surface_t *surface,
-				     int x, int y,
-				     unsigned int width,
-				     unsigned int height)
-{
-    return CAIRO_STATUS_SUCCESS;
-}
-
 static cairo_bool_t
 color_is_gray (cairo_color_t *color)
 {
@@ -493,66 +487,66 @@ color_is_gray (cairo_color_t *color)
 }
 
 static cairo_bool_t
-color_is_translucent (const cairo_color_t *color)
+color_is_opaque (const cairo_color_t *color)
 {
-    return color->alpha < 0.999;
+    return color->alpha >= 0.999;
 }
 
 static cairo_bool_t
-format_is_translucent (cairo_format_t format)
+format_is_opaque (cairo_format_t format)
 {
     switch (format) {
     case CAIRO_FORMAT_ARGB32:
-	return TRUE;
-    case CAIRO_FORMAT_RGB24:
 	return FALSE;
-    case CAIRO_FORMAT_A8:
+    case CAIRO_FORMAT_RGB24:
 	return TRUE;
+    case CAIRO_FORMAT_A8:
+	return FALSE;
     case CAIRO_FORMAT_A1:
 	return TRUE;
     }
-    return TRUE;
+    return FALSE;
 }
 
 static cairo_bool_t
-surface_is_translucent (const cairo_surface_t *surface)
+surface_is_opaque (const cairo_surface_t *surface)
 { 
     if (_cairo_surface_is_image (surface)) {
 	const cairo_image_surface_t	*image_surface = (cairo_image_surface_t *) surface;
 
-	return format_is_translucent (image_surface->format);
+	return format_is_opaque (image_surface->format);
     }
     return TRUE;
 }
 
 static cairo_bool_t
-gradient_is_translucent (const cairo_gradient_pattern_t *gradient)
+gradient_is_opaque (const cairo_gradient_pattern_t *gradient)
 {
-    return TRUE;    /* XXX no gradient support */
+    return FALSE;    /* XXX no gradient support */
 #if 0
     int i;
     
     for (i = 0; i < gradient->n_stops; i++)
-	if (color_is_translucent (&gradient->stops[i].color))
-	    return TRUE;
-    return FALSE;
+	if (!color_is_opaque (&gradient->stops[i].color))
+	    return FALSE;
+    return TRUE;
 #endif
 }
 
 static cairo_bool_t
-pattern_is_translucent (const cairo_pattern_t *abstract_pattern)
+pattern_is_opaque (const cairo_pattern_t *abstract_pattern)
 {
     const cairo_pattern_union_t *pattern;
 
     pattern = (cairo_pattern_union_t *) abstract_pattern;
     switch (pattern->base.type) {
     case CAIRO_PATTERN_TYPE_SOLID:
-	return color_is_translucent (&pattern->solid.color);
+	return color_is_opaque (&pattern->solid.color);
     case CAIRO_PATTERN_TYPE_SURFACE:
-	return surface_is_translucent (pattern->surface.surface);
+	return surface_is_opaque (pattern->surface.surface);
     case CAIRO_PATTERN_TYPE_LINEAR:
     case CAIRO_PATTERN_TYPE_RADIAL:
-	return gradient_is_translucent (&pattern->gradient.base);
+	return gradient_is_opaque (&pattern->gradient.base);
     }	
 
     ASSERT_NOT_REACHED;
@@ -624,35 +618,35 @@ operator_always_translucent (cairo_opera
 }
 
 static cairo_bool_t
-color_operation_needs_fallback (cairo_operator_t op,
-				const cairo_color_t *color)
+pattern_surface_supported (const cairo_surface_pattern_t *pattern)
 {
-    if (operator_always_opaque (op))
+    if (pattern->surface->backend->acquire_source_image == NULL)
 	return FALSE;
-    if (operator_always_translucent (op))
-	return TRUE;
-    return color_is_translucent (color);
+    return TRUE;
 }
 
 static cairo_bool_t
-pattern_type_supported (const cairo_pattern_t *pattern)
+pattern_supported (const cairo_pattern_t *pattern)
 {
     if (pattern->type == CAIRO_PATTERN_TYPE_SOLID)
 	return TRUE;
+    if (pattern->type == CAIRO_PATTERN_TYPE_SURFACE)
+	return pattern_surface_supported ((const cairo_surface_pattern_t *) pattern);
+	
     return FALSE;
 }
 
 static cairo_bool_t
-pattern_operation_needs_fallback (cairo_operator_t op,
+pattern_operation_supported (cairo_operator_t op,
 				  const cairo_pattern_t *pattern)
 {
-    if (! pattern_type_supported (pattern))
-	return TRUE;
-    if (operator_always_opaque (op))
+    if (! pattern_supported (pattern))
 	return FALSE;
-    if (operator_always_translucent (op))
+    if (operator_always_opaque (op))
 	return TRUE;
-    return pattern_is_translucent (pattern);
+    if (operator_always_translucent (op))
+	return FALSE;
+    return pattern_is_opaque (pattern);
 }
 
 /* PS Output - this section handles output of the parts of the meta
@@ -812,7 +806,15 @@ static void
 emit_surface_pattern (cairo_ps_surface_t *surface,
 		      cairo_surface_pattern_t *pattern)
 {
-    /* XXX: NYI */
+    cairo_image_surface_t	*image;
+    cairo_status_t		status;
+    void			*image_extra;
+
+    status = _cairo_surface_acquire_source_image (pattern->surface,
+						  &image,
+						  &image_extra);
+    assert (status == CAIRO_STATUS_SUCCESS);
+    emit_image (surface, image, &pattern->base.matrix);
 }
 
 static void
@@ -855,200 +857,6 @@ emit_pattern (cairo_ps_surface_t *surfac
     }
 }
 
-
-static cairo_int_status_t
-_cairo_ps_surface_composite (cairo_operator_t	op,
-		      cairo_pattern_t  *src_pattern,
-		      cairo_pattern_t  *mask_pattern,
-		      void	       *abstract_dst,
-		      int		src_x,
-		      int		src_y,
-		      int		mask_x,
-		      int		mask_y,
-		      int		dst_x,
-		      int		dst_y,
-		      unsigned int	width,
-		      unsigned int	height)
-{
-    cairo_ps_surface_t *surface = abstract_dst;
-    cairo_output_stream_t *stream = surface->stream;
-    cairo_surface_pattern_t *surface_pattern;
-    cairo_status_t status;
-    cairo_image_surface_t *image;
-    void *image_extra;
-
-    if (surface->need_start_page)
-	_cairo_ps_surface_start_page (surface);
-
-    if (mask_pattern) {
-	/* FIXME: Investigate how this can be done... we'll probably
-	 * need pixmap fallbacks for this, though. */
-	_cairo_output_stream_printf (stream,
-				     "%% _cairo_ps_surface_composite: with mask\n");
-	goto bail;
-    }
-
-    status = CAIRO_STATUS_SUCCESS;
-    switch (src_pattern->type) {
-    case CAIRO_PATTERN_TYPE_SOLID:
-	_cairo_output_stream_printf (stream,
-				     "%% _cairo_ps_surface_composite: solid\n");
-	goto bail;
-
-    case CAIRO_PATTERN_TYPE_SURFACE:
-	surface_pattern = (cairo_surface_pattern_t *) src_pattern;
-
-	if (src_pattern->extend != CAIRO_EXTEND_NONE) {
-	    _cairo_output_stream_printf (stream,
-					 "%% _cairo_ps_surface_composite: repeating image\n");
-	    goto bail;
-	}
-	    
-
-	status = _cairo_surface_acquire_source_image (surface_pattern->surface,
-						      &image,
-						      &image_extra);
-	if (status == CAIRO_INT_STATUS_UNSUPPORTED) {
-	    _cairo_output_stream_printf (stream,
-					 "%% _cairo_ps_surface_composite: src_pattern not available as image\n");
-	    goto bail;
-	} else if (status) {
-	    break;
-	}
-	status = emit_image (surface, image, &src_pattern->matrix);
-	_cairo_surface_release_source_image (surface_pattern->surface,
-					     image, image_extra);
-	break;
-
-    case CAIRO_PATTERN_TYPE_LINEAR:
-    case CAIRO_PATTERN_TYPE_RADIAL:
-	_cairo_output_stream_printf (stream,
-				     "%% _cairo_ps_surface_composite: gradient\n");
-	goto bail;
-    }
-
-    return status;
-bail:
-    return _cairo_ps_surface_add_fallback_area (surface, dst_x, dst_y, width, height);
-}
-
-static cairo_int_status_t
-_cairo_ps_surface_fill_rectangles (void		*abstract_surface,
-			    cairo_operator_t	 op,
-			    const cairo_color_t	*color,
-			    cairo_rectangle_t	*rects,
-			    int			 num_rects)
-{
-    cairo_ps_surface_t *surface = abstract_surface;
-    cairo_output_stream_t *stream = surface->stream;
-    cairo_solid_pattern_t solid;
-    int i;
-
-    if (!num_rects)
-	return CAIRO_STATUS_SUCCESS;
-
-    if (surface->need_start_page)
-	_cairo_ps_surface_start_page (surface);
-    
-    if (color_operation_needs_fallback (op, color)) {
-	int min_x = rects[0].x;
-	int min_y = rects[0].y;
-	int max_x = rects[0].x + rects[0].width;
-	int max_y = rects[0].y + rects[0].height;
-
-	for (i = 1; i < num_rects; i++) {
-	    if (rects[i].x < min_x) min_x = rects[i].x;
-	    if (rects[i].y < min_y) min_y = rects[i].y;
-	    if (rects[i].x + rects[i].width > max_x) max_x = rects[i].x + rects[i].width;
-	    if (rects[i].y + rects[i].height > max_y) max_y = rects[i].y + rects[i].height;
-	}
-	return _cairo_ps_surface_add_fallback_area (surface, min_x, min_y, max_x - min_x, max_y - min_y);
-    }
-	
-    _cairo_output_stream_printf (stream,
-				 "%% _cairo_ps_surface_fill_rectangles\n");
-
-    _cairo_pattern_init_solid (&solid, color);
-    emit_pattern (surface, &solid.base);
-    _cairo_pattern_fini (&solid.base);
-
-    _cairo_output_stream_printf (stream, "[");
-    for (i = 0; i < num_rects; i++) {
-      _cairo_output_stream_printf (stream,
-				   " %d %d %d %d",
-				   rects[i].x, rects[i].y,
-				   rects[i].width, rects[i].height);
-    }
-
-    _cairo_output_stream_printf (stream, " ] rectfill\n");
-
-    return CAIRO_STATUS_SUCCESS;
-}
-
-static double
-intersect (cairo_line_t *line, cairo_fixed_t y)
-{
-    return _cairo_fixed_to_double (line->p1.x) +
-	_cairo_fixed_to_double (line->p2.x - line->p1.x) *
-	_cairo_fixed_to_double (y - line->p1.y) /
-	_cairo_fixed_to_double (line->p2.y - line->p1.y);
-}
-
-static cairo_int_status_t
-_cairo_ps_surface_composite_trapezoids (cairo_operator_t	op,
-				 cairo_pattern_t	*pattern,
-				 void			*abstract_dst,
-				 cairo_antialias_t	antialias,
-				 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_ps_surface_t *surface = abstract_dst;
-    cairo_output_stream_t *stream = surface->stream;
-    int i;
-
-    if (pattern_operation_needs_fallback (op, pattern))
-	return _cairo_ps_surface_add_fallback_area (surface, x_dst, y_dst, width, height);
-
-    if (surface->need_start_page)
-	_cairo_ps_surface_start_page (surface);
-
-    _cairo_output_stream_printf (stream,
-				 "%% _cairo_ps_surface_composite_trapezoids\n");
-
-    emit_pattern (surface, pattern);
-
-    for (i = 0; i < num_traps; i++) {
-	double left_x1, left_x2, right_x1, right_x2, top, bottom;
-
-	left_x1  = intersect (&traps[i].left, traps[i].top);
-	left_x2  = intersect (&traps[i].left, traps[i].bottom);
-	right_x1 = intersect (&traps[i].right, traps[i].top);
-	right_x2 = intersect (&traps[i].right, traps[i].bottom);
-	top      = _cairo_fixed_to_double (traps[i].top);
-	bottom   = _cairo_fixed_to_double (traps[i].bottom);
-
-	_cairo_output_stream_printf
-	    (stream,
-	     "%f %f moveto %f %f lineto %f %f lineto %f %f lineto "
-	     "closepath\n",
-	     left_x1, top,
-	     left_x2, bottom,
-	     right_x2, bottom,
-	     right_x1, top);
-    }
-
-    _cairo_output_stream_printf (stream,
-				 "fill\n");
-
-    return CAIRO_STATUS_SUCCESS;
-}
-
 typedef struct
 {
     cairo_output_stream_t *output_stream;
@@ -1135,6 +943,9 @@ _cairo_ps_surface_intersect_clip_path (v
     cairo_ps_surface_path_info_t info;
     const char *ps_operator;
 
+    if (surface->mode == CAIRO_PAGINATED_MODE_EVALUATE)
+	return CAIRO_STATUS_SUCCESS;
+
     _cairo_output_stream_printf (stream,
 				 "%% _cairo_ps_surface_intersect_clip_path\n");
 
@@ -1265,7 +1076,153 @@ _cairo_ps_surface_old_show_glyphs (cairo
 #endif
 
 static cairo_int_status_t
-_cairo_ps_surface_fill (void			*abstract_surface,
+_cairo_ps_surface_paint (void			*abstract_surface,
+			 cairo_operator_t	 op,
+			 cairo_pattern_t	*source)
+{
+    cairo_ps_surface_t *surface = abstract_surface;
+    cairo_output_stream_t *stream = surface->stream;
+    cairo_ps_surface_path_info_t info;
+
+    if (surface->mode == CAIRO_PAGINATED_MODE_EVALUATE) {
+	if (!pattern_operation_supported (op, source))
+	    return CAIRO_INT_STATUS_UNSUPPORTED;
+	return CAIRO_STATUS_SUCCESS;
+    }
+    
+    if (surface->need_start_page)
+	_cairo_ps_surface_start_page (surface);
+
+    _cairo_output_stream_printf (stream,
+				 "%% _cairo_ps_surface_paint\n");
+
+    emit_pattern (surface, source);
+
+    info.output_stream = stream;
+    info.has_current_point = FALSE;
+
+    _cairo_output_stream_printf (stream, "0 0 moveto\n");
+    _cairo_output_stream_printf (stream, "%f 0 lineto\n", surface->width);
+    _cairo_output_stream_printf (stream, "%f %f lineto\n",
+				 surface->width, surface->height);
+    _cairo_output_stream_printf (stream, "0 %f lineto\n", surface->height);
+    _cairo_output_stream_printf (stream, "closepath fill\n");
+    return CAIRO_STATUS_SUCCESS;
+}
+
+static int
+_cairo_ps_line_cap (cairo_line_cap_t cap)
+{
+    switch (cap) {
+    case CAIRO_LINE_CAP_BUTT:
+	return 0;
+    case CAIRO_LINE_CAP_ROUND:
+	return 1;
+    case CAIRO_LINE_CAP_SQUARE:
+	return 2;
+    default:
+	ASSERT_NOT_REACHED;
+	return 0;
+    }
+}
+
+static int
+_cairo_ps_line_join (cairo_line_join_t join)
+{
+    switch (join) {
+    case CAIRO_LINE_JOIN_MITER:
+	return 0;
+    case CAIRO_LINE_JOIN_ROUND:
+	return 1;
+    case CAIRO_LINE_JOIN_BEVEL:
+	return 2;
+    default:
+	ASSERT_NOT_REACHED;
+	return 0;
+    }
+}
+
+static cairo_int_status_t
+_cairo_ps_surface_stroke (void			*abstract_surface,
+			  cairo_operator_t	 op,
+			  cairo_pattern_t	*source,
+			  cairo_path_fixed_t	*path,
+			  cairo_stroke_style_t	*style,
+			  cairo_matrix_t	*ctm,
+			  cairo_matrix_t	*ctm_inverse,
+			  double		 tolerance,
+			  cairo_antialias_t	 antialias)
+{
+    cairo_ps_surface_t *surface = abstract_surface;
+    cairo_output_stream_t *stream = surface->stream;
+    cairo_int_status_t status;
+    cairo_ps_surface_path_info_t info;
+
+    if (surface->mode == CAIRO_PAGINATED_MODE_EVALUATE) {
+	if (!pattern_operation_supported (op, source))
+	    return CAIRO_INT_STATUS_UNSUPPORTED;
+    
+	return CAIRO_STATUS_SUCCESS;
+    }
+    
+    if (surface->need_start_page)
+	_cairo_ps_surface_start_page (surface);
+
+    _cairo_output_stream_printf (stream,
+				 "%% _cairo_ps_surface_stroke\n");
+
+    emit_pattern (surface, source);
+
+    
+    info.output_stream = stream;
+    info.has_current_point = FALSE;
+
+    status = _cairo_path_fixed_interpret (path,
+					  CAIRO_DIRECTION_FORWARD,
+					  _cairo_ps_surface_path_move_to,
+					  _cairo_ps_surface_path_line_to,
+					  _cairo_ps_surface_path_curve_to,
+					  _cairo_ps_surface_path_close_path,
+					  &info);
+
+    /*
+     * Switch to user space to set line parameters
+     */
+    _cairo_output_stream_printf (stream,
+				 "gsave\n");
+    _cairo_output_stream_printf (stream,
+				 "[%f %f %f %f 0 0] concat\n",
+				 ctm->xx, ctm->yx, ctm->xy, ctm->yy);
+    /* line width */
+    _cairo_output_stream_printf (stream, "%f setlinewidth\n",
+				 style->line_width);
+    /* line cap */
+    _cairo_output_stream_printf (stream, "%d setlinecap\n",
+				 _cairo_ps_line_cap (style->line_cap));
+    /* line join */
+    _cairo_output_stream_printf (stream, "%d setlinejoin\n",
+				 _cairo_ps_line_join (style->line_join));
+    /* dashes */
+    if (style->num_dashes) {
+	int d;
+	_cairo_output_stream_printf (stream, "[");
+	for (d = 0; d < style->num_dashes; d++)
+	    _cairo_output_stream_printf (stream, " %f", style->dash[d]);
+	_cairo_output_stream_printf (stream, "] %f setdash\n",
+				     style->dash_offset);
+    }
+    /* miter limit */
+    _cairo_output_stream_printf (stream, "%f setmiterlimit\n",
+				 style->miter_limit);
+    _cairo_output_stream_printf (stream,
+				 "stroke\n");
+    _cairo_output_stream_printf (stream,
+				 "grestore\n");
+    return status;
+}
+
+static cairo_int_status_t
+_cairo_ps_surface_fill (void		*abstract_surface,
 		 cairo_operator_t	 op,
 		 cairo_pattern_t	*source,
 		 cairo_path_fixed_t	*path,
@@ -1279,12 +1236,12 @@ _cairo_ps_surface_fill (void			*abstract
     cairo_ps_surface_path_info_t info;
     const char *ps_operator;
 
-    if (pattern_operation_needs_fallback (op, source))
-	return _cairo_ps_surface_add_fallback_area (surface,
-					     0, 0,
-					     surface->width,
-					     surface->height);
-
+    if (surface->mode == CAIRO_PAGINATED_MODE_EVALUATE) {
+	if (!pattern_operation_supported (op, source))
+	    return CAIRO_INT_STATUS_UNSUPPORTED;
+	return CAIRO_STATUS_SUCCESS;
+    }
+    
     if (surface->need_start_page)
 	_cairo_ps_surface_start_page (surface);
 
@@ -1329,9 +1286,9 @@ static const cairo_surface_backend_t cai
     NULL, /* acquire_dest_image */
     NULL, /* release_dest_image */
     NULL, /* clone_similar */
-    _cairo_ps_surface_composite,
-    _cairo_ps_surface_fill_rectangles,
-    _cairo_ps_surface_composite_trapezoids,
+    NULL, /* composite */
+    NULL, /* fill_rectangles */
+    NULL, /* composite_trapezoids */
     _cairo_ps_surface_copy_page,
     _cairo_ps_surface_show_page,
     NULL, /* set_clip_region */
@@ -1350,9 +1307,22 @@ static const cairo_surface_backend_t cai
 
     /* Here are the drawing functions */
     
-    NULL, /* paint */
+    _cairo_ps_surface_paint, /* paint */
     NULL, /* mask */
-    NULL, /* stroke */
+    _cairo_ps_surface_stroke,
     _cairo_ps_surface_fill,
     NULL /* show_glyphs */
 };
+
+static void
+_cairo_ps_paginated_set_mode (cairo_surface_t *target,
+			      cairo_paginated_mode_t mode)
+{
+    cairo_ps_surface_t	*surface = (cairo_ps_surface_t *) target;
+
+    surface->mode = mode;
+}
+
+static const cairo_paginated_funcs_t cairo_ps_paginated_funcs = {
+    _cairo_ps_paginated_set_mode,
+};


More information about the cairo-commit mailing list