[cairo-commit] cairo/src cairo-meta-surface-private.h, 1.1, 1.2 cairo-meta-surface.c, 1.3, 1.4 cairo-ps-surface.c, 1.41, 1.42

Kristian Hogsberg commit at pdx.freedesktop.org
Wed Jul 13 12:32:54 PDT 2005


Committed by: krh

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

Modified Files:
	cairo-meta-surface-private.h cairo-meta-surface.c 
	cairo-ps-surface.c 
Log Message:
2005-07-13  Kristian Høgsberg  <krh at redhat.com>

        * src/cairo-meta-surface.c: (_cairo_meta_surface_replay): Use
        the _cairo_surface_*() functions when replaying.

        * src/cairo-ps-surface.c: Fold the "locate fallbacks" pass into
        the postscript output pass, and add a simple, first implementation
        of image fallbacks.



Index: cairo-meta-surface-private.h
===================================================================
RCS file: /cvs/cairo/cairo/src/cairo-meta-surface-private.h,v
retrieving revision 1.1
retrieving revision 1.2
diff -u -d -r1.1 -r1.2
--- cairo-meta-surface-private.h	1 Jul 2005 19:22:23 -0000	1.1
+++ cairo-meta-surface-private.h	13 Jul 2005 19:32:51 -0000	1.2
@@ -90,6 +90,7 @@
 typedef struct _cairo_command_set_clip_region {
     cairo_command_type_t	type;
     pixman_region16_t	       *region;
+    unsigned int		serial;
 } cairo_command_set_clip_region_t;
 
 typedef struct _cairo_command_intersect_clip_path {

Index: cairo-meta-surface.c
===================================================================
RCS file: /cvs/cairo/cairo/src/cairo-meta-surface.c,v
retrieving revision 1.3
retrieving revision 1.4
diff -u -d -r1.3 -r1.4
--- cairo-meta-surface.c	8 Jul 2005 17:12:29 -0000	1.3
+++ cairo-meta-surface.c	13 Jul 2005 19:32:51 -0000	1.4
@@ -293,6 +293,8 @@
 	command->region = NULL;
     }
 
+    command->serial = meta->base.current_clip_serial;
+
     if (_cairo_array_append (&meta->commands, &command, 1) == NULL) {
 	if (command->region)
 	    pixman_region_destroy (command->region);
@@ -490,9 +492,7 @@
 	command = elements[i];
 	switch (command->type) {
 	case CAIRO_COMMAND_COMPOSITE:
-	    if (target->backend->composite == NULL)
-		break;
-	    status = target->backend->composite
+	    status = _cairo_surface_composite
 		(command->composite.operator,
 		 &command->composite.src_pattern.base,
 		 command->composite.mask_pattern_pointer,
@@ -508,9 +508,7 @@
 	    break;
 
 	case CAIRO_COMMAND_FILL_RECTANGLES:
-	    if (target->backend->fill_rectangles == NULL)
-		break;
-	    status = target->backend->fill_rectangles
+	    status = _cairo_surface_fill_rectangles
 		(target,
 		 command->fill_rectangles.operator,
 		 &command->fill_rectangles.color,
@@ -519,9 +517,7 @@
 	    break;
 
 	case CAIRO_COMMAND_COMPOSITE_TRAPEZOIDS:
-	    if (target->backend->composite_trapezoids == NULL)
-		break;
-	    status = target->backend->composite_trapezoids
+	    status = _cairo_surface_composite_trapezoids
 		(command->composite_trapezoids.operator,
 		 &command->composite_trapezoids.pattern.base,
 		 target,
@@ -536,17 +532,19 @@
 	    break;
 
 	case CAIRO_COMMAND_SET_CLIP_REGION:
-	    if (target->backend->set_clip_region == NULL)
-		break;
-	    status = target->backend->set_clip_region
+	    status = _cairo_surface_set_clip_region
 		(target,
-		 command->set_clip_region.region);
+		 command->set_clip_region.region,
+		 command->set_clip_region.serial);
 	    break;
 
 	case CAIRO_COMMAND_INTERSECT_CLIP_PATH:
+	    /* XXX Meta surface clipping is broken and requires some
+	     * cairo-gstate.c rewriting.  Work around it for now. */
 	    if (target->backend->intersect_clip_path == NULL)
 		break;
-	    status = target->backend->intersect_clip_path
+
+	    status = _cairo_surface_intersect_clip_path
 		(target,
 		 command->intersect_clip_path.path_pointer,
 		 command->intersect_clip_path.fill_rule,
@@ -554,9 +552,7 @@
 	    break;
 
 	case CAIRO_COMMAND_SHOW_GLYPHS:
-	    if (target->backend->show_glyphs == NULL)
-		break;
-	    status = target->backend->show_glyphs
+	    status = _cairo_surface_show_glyphs
 		(command->show_glyphs.scaled_font,
 		 command->show_glyphs.operator,
 		 &command->show_glyphs.pattern.base,
@@ -572,9 +568,12 @@
 	    break;
 
 	case CAIRO_COMMAND_FILL_PATH:
+	    /* XXX Meta surface fill_path is broken and requires some
+	     * cairo-gstate.c rewriting.  Work around it for now. */
 	    if (target->backend->fill_path == NULL)
 		break;
-	    status = target->backend->fill_path
+
+	    status = _cairo_surface_fill_path
 		(command->fill_path.operator,
 		 &command->fill_path.pattern.base,
 		 target,

Index: cairo-ps-surface.c
===================================================================
RCS file: /cvs/cairo/cairo/src/cairo-ps-surface.c,v
retrieving revision 1.41
retrieving revision 1.42
diff -u -d -r1.41 -r1.42
--- cairo-ps-surface.c	13 Jul 2005 18:01:25 -0000	1.41
+++ cairo-ps-surface.c	13 Jul 2005 19:32:51 -0000	1.42
@@ -81,11 +81,6 @@
 _cairo_ps_surface_render_page (cairo_ps_surface_t *surface,
 			       cairo_surface_t *page, int page_number);
 
-static cairo_int_status_t
-_cairo_ps_surface_render_fallbacks (cairo_ps_surface_t *surface,
-				    cairo_surface_t    *page);
-
-
 static cairo_surface_t *
 _cairo_ps_surface_create_for_stream_internal (cairo_output_stream_t *stream,
 					      double		     width,
@@ -550,11 +545,60 @@
     return CAIRO_STATUS_SUCCESS;
 }
 
+typedef struct _cairo_ps_fallback_area cairo_ps_fallback_area_t;
+struct _cairo_ps_fallback_area {
+    int x, y;
+    unsigned int width, height;
+    cairo_ps_fallback_area_t *next;
+};
+
 typedef struct _ps_output_surface {
     cairo_surface_t base;
     cairo_ps_surface_t *parent;
+    cairo_ps_fallback_area_t *fallback_areas;
 } ps_output_surface_t;
 
+static cairo_int_status_t
+_ps_output_add_fallback_area (ps_output_surface_t *surface,
+			      int x, int y,
+			      unsigned int width,
+			      unsigned int height)
+{
+    cairo_ps_fallback_area_t *area;
+    
+    /* FIXME: Do a better job here.  Ideally, we would use a 32 bit
+     * region type, but probably just computing bounding boxes would
+     * also work fine. */
+
+    area = malloc (sizeof (cairo_ps_fallback_area_t));
+    if (area == NULL)
+	return CAIRO_STATUS_NO_MEMORY;
+
+    area->x = x;
+    area->y = y;
+    area->width = width;
+    area->height = height;
+    area->next = surface->fallback_areas;
+
+    surface->fallback_areas = area;
+
+    return CAIRO_STATUS_SUCCESS;
+}
+
+static cairo_status_t
+_ps_output_finish (void *abstract_surface)
+{
+    ps_output_surface_t *surface = abstract_surface;
+    cairo_ps_fallback_area_t *area, *next;
+
+    for (area = surface->fallback_areas; area != NULL; area = next) {
+	next = area->next;
+	free (area);
+    }
+
+    return CAIRO_STATUS_SUCCESS;
+}
+
 static cairo_bool_t
 color_is_gray (cairo_color_t *color)
 {
@@ -564,6 +608,24 @@
 	    fabs (color->red - color->blue) < epsilon);
 }
 
+static cairo_bool_t
+pattern_is_translucent (cairo_pattern_t *abstract_pattern)
+{
+    cairo_pattern_union_t *pattern;
+
+    pattern = (cairo_pattern_union_t *) abstract_pattern;
+    switch (pattern->base.type) {
+    case CAIRO_PATTERN_SOLID:
+	return pattern->solid.color.alpha < 0.9;
+    case CAIRO_PATTERN_SURFACE:
+    case CAIRO_PATTERN_LINEAR:
+    case CAIRO_PATTERN_RADIAL:
+	return FALSE;
+    }	
+
+    ASSERT_NOT_REACHED;
+}
+
 /* PS Output - this section handles output of the parts of the meta
  * surface we can render natively in PS. */
 
@@ -872,6 +934,9 @@
     cairo_output_stream_t *stream = surface->parent->stream;
     int i;
 
+    if (pattern_is_translucent (pattern))
+	return _ps_output_add_fallback_area (surface, x_dst, y_dst, width, height);
+
     _cairo_output_stream_printf (stream,
 				 "%% _ps_output_composite_trapezoids\n");
 
@@ -1051,6 +1116,9 @@
     if (! _cairo_scaled_font_is_ft (scaled_font))
 	return CAIRO_INT_STATUS_UNSUPPORTED;
 
+    if (pattern_is_translucent (pattern))
+	return _ps_output_add_fallback_area (surface, dest_x, dest_y, width, height);
+
     _cairo_output_stream_printf (stream,
 				 "%% _ps_output_show_glyphs\n");
 
@@ -1137,7 +1205,7 @@
 
 static const cairo_surface_backend_t ps_output_backend = {
     NULL, /* create_similar */
-    NULL, /* finish */
+    _ps_output_finish,
     NULL, /* acquire_source_image */
     NULL, /* release_source_image */
     NULL, /* acquire_dest_image */
@@ -1156,177 +1224,95 @@
 };
 
 static cairo_int_status_t
-_cairo_ps_surface_render_page (cairo_ps_surface_t *surface,
-			       cairo_surface_t *page, int page_number)
+_ps_output_render_fallbacks (cairo_surface_t *surface,
+			     cairo_surface_t *page)
 {
     ps_output_surface_t *ps_output;
+    cairo_surface_t *image;
     cairo_int_status_t status;
+    cairo_matrix_t matrix;
+    int width, height;
 
-    _cairo_output_stream_printf (surface->stream,
-				 "%%%%Page: %d\n"
-				 "gsave\n",
-				 page_number);
+    ps_output = (ps_output_surface_t *) surface;
+    if (ps_output->fallback_areas == NULL)
+	return CAIRO_STATUS_SUCCESS;
 
-    ps_output = malloc (sizeof (ps_output_surface_t));
-    if (ps_output == NULL)
-	return CAIRO_STATUS_NO_MEMORY;
+    width = ps_output->parent->width * ps_output->parent->x_dpi / 72;
+    height = ps_output->parent->height * ps_output->parent->y_dpi / 72;
 
-    _cairo_surface_init (&ps_output->base, &ps_output_backend);
-    ps_output->parent = surface;
-    status = _cairo_meta_surface_replay (page, &ps_output->base);
-    cairo_surface_destroy (&ps_output->base);
+    image = cairo_image_surface_create (CAIRO_FORMAT_RGB24, width, height);
+    if (image == NULL)
+	return CAIRO_STATUS_NO_MEMORY;
 
-    _cairo_ps_surface_render_fallbacks (surface, page);
+    status = _cairo_surface_fill_rectangle (image,
+					    CAIRO_OPERATOR_SOURCE,
+					    CAIRO_COLOR_WHITE,
+					    0, 0, width, height);
+    if (status)
+	goto bail;
 
-    _cairo_output_stream_printf (surface->stream,
-				 "showpage\n"
-				 "grestore\n"
-				 "%%%%EndPage\n");
+    status = _cairo_meta_surface_replay (page, image);
+    if (status)
+	goto bail;
 
-    return status;
-}
+    matrix.xx = 1;
+    matrix.xy = 0;
+    matrix.yx = 0;
+    matrix.yy = 1;
+    matrix.x0 = 0;
+    matrix.y0 = 0;
 
-typedef struct _cairo_ps_fallback_area cairo_ps_fallback_area_t;
-struct _cairo_ps_fallback_area {
-    /* area */
-    cairo_ps_fallback_area_t *next;
-};
+    status = emit_image (ps_output->parent,
+			 (cairo_image_surface_t *) image, &matrix);
 
-typedef struct _cairo_ps_fallback_info cairo_ps_fallback_info_t;
-struct _cairo_ps_fallback_info {
-    cairo_ps_fallback_area_t *fallback_areas;
-};
+ bail:
+    cairo_surface_destroy (image);
 
-/* XXX: This code is not compiling correctly (missing return values),
- * but also appears to not be used currently. I'm turning it off for
- * now. */
-#if 0
-static cairo_int_status_t
-_cairo_ps_fallback_info_add_area (cairo_ps_fallback_info_t *info,
-				  int x, int y,
-				  unsigned int width,
-				  unsigned int height)
-{
-    return CAIRO_STATUS_SUCCESS;
+    return status;
 }
 
-static cairo_bool_t
-_pattern_is_translucent (cairo_pattern_t *abstract_pattern)
+static cairo_surface_t *
+_ps_output_surface_create (cairo_ps_surface_t *parent)
 {
-    cairo_pattern_union_t *pattern;
+    ps_output_surface_t *ps_output;
 
-    pattern = (cairo_pattern_union_t *) abstract_pattern;
-    switch (pattern->base.type) {
-    case CAIRO_PATTERN_SOLID:
-	return pattern->solid.color.alpha < 0.999;
-    case CAIRO_PATTERN_SURFACE:
-    case CAIRO_PATTERN_LINEAR:
-    case CAIRO_PATTERN_RADIAL:
-	return FALSE;
-    }
+    ps_output = malloc (sizeof (ps_output_surface_t));
+    if (ps_output == NULL)
+	return NULL;
 
-    ASSERT_NOT_REACHED;
-    return FALSE;
-}
+    _cairo_surface_init (&ps_output->base, &ps_output_backend);
+    ps_output->parent = parent;
+    ps_output->fallback_areas = NULL;
 
-static cairo_int_status_t
-_ps_locate_fallbacks_composite (cairo_operator_t  operator,
-				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)
-{
+    return &ps_output->base;
 }
 
 static cairo_int_status_t
-_ps_locate_fallbacks_fill_rectangles (void		  *abstract_surface,
-				      cairo_operator_t	   operator,
-				      const cairo_color_t *color,
-				      cairo_rectangle_t	  *rects,
-				      int		   num_rects)
+_cairo_ps_surface_render_page (cairo_ps_surface_t *surface,
+			       cairo_surface_t *page, int page_number)
 {
-}
+    cairo_surface_t *ps_output;
+    cairo_int_status_t status;
 
-static cairo_int_status_t
-_ps_locate_fallbacks_composite_trapezoids (cairo_operator_t   operator,
-					   cairo_pattern_t   *pattern,
-					   void		     *abstract_dst,
-					   int		      x_src,
-					   int		      y_src,
-					   int		      x_dst,
-					   int		      y_dst,
-					   unsigned int	      width,
-					   unsigned int	      height,
-					   cairo_trapezoid_t *traps,
-					   int		      num_traps)
-{
-    cairo_ps_fallback_info_t *info;
+    _cairo_output_stream_printf (surface->stream,
+				 "%%%%Page: %d\n"
+				 "gsave\n",
+				 page_number);
 
-    info = abstract_dst;
+    ps_output = _ps_output_surface_create (surface);
+    if (ps_output == NULL)
+	return CAIRO_STATUS_NO_MEMORY;
 
-    if (_pattern_is_translucent (pattern))
-	_cairo_ps_fallback_info_add_area (info, x_dst, y_dst, width, height);
-}
+    status = _cairo_meta_surface_replay (page, ps_output);
 
-static cairo_int_status_t
-_ps_locate_fallbacks_show_glyphs (cairo_scaled_font_t *scaled_font,
-				  cairo_operator_t     operator,
-				  cairo_pattern_t     *pattern,
-				  void		      *abstract_surface,
-				  int		       source_x,
-				  int		       source_y,
-				  int		       dest_x,
-				  int		       dest_y,
-				  unsigned int	       width,
-				  unsigned int	       height,
-				  const cairo_glyph_t *glyphs,
-				  int		       num_glyphs)
-{
-    return CAIRO_STATUS_SUCCESS;
-}
+    _ps_output_render_fallbacks (ps_output, page);
 
-static cairo_int_status_t
-_ps_locate_fallbacks_fill_path (cairo_operator_t    operator,
-				cairo_pattern_t	   *pattern,
-				void		   *abstract_dst,
-				cairo_path_fixed_t *path,
-				cairo_fill_rule_t   fill_rule,
-				double		    tolerance)
-{
-    return CAIRO_STATUS_SUCCESS;
-}
+    cairo_surface_destroy (ps_output);
 
-static const cairo_surface_backend_t ps_locate_fallbacks_backend = {
-    NULL, /* create_similar */
-    NULL, /* finish */
-    NULL, /* acquire_source_image */
-    NULL, /* release_source_image */
-    NULL, /* acquire_dest_image */
-    NULL, /* release_dest_image */
-    NULL, /* clone_similar */
-    _ps_locate_fallbacks_composite,
-    _ps_locate_fallbacks_fill_rectangles,
-    _ps_locate_fallbacks_composite_trapezoids,
-    NULL, /* copy_page */
-    NULL, /* show_page */
-    NULL, /* set_clip_region */
-    NULL, /* intersect_clip_path */
-    NULL, /* get_extents */
-    _ps_locate_fallbacks_show_glyphs,
-    _ps_locate_fallbacks_fill_path
-};
-#endif
+    _cairo_output_stream_printf (surface->stream,
+				 "showpage\n"
+				 "grestore\n"
+				 "%%%%EndPage\n");
 
-static cairo_int_status_t
-_cairo_ps_surface_render_fallbacks (cairo_ps_surface_t *surface,
-				    cairo_surface_t    *page)
-{
-    return CAIRO_STATUS_SUCCESS;
+    return status;
 }




More information about the cairo-commit mailing list