Bug 825987 - Backed out changesets 1b9a99a17afb and 74493ca34d5e (bug 691061) due to regression with saving PDFs. a=akeybl
authorAnthony Jones <ajones@mozilla.com>
Wed, 30 Jan 2013 08:39:37 -0500
changeset 127403 611fbc250e5b161879de49b2d45ba1aa12bee9dd
parent 127402 c0eea5c5526a55222f8a9041ea391675e49beae7
child 127404 58bbcf8b460a78621a621945ed07574a0f07ebdf
push id2151
push userlsblakk@mozilla.com
push dateTue, 19 Feb 2013 18:06:57 +0000
treeherdermozilla-beta@4952e88741ec [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersakeybl
bugs825987, 691061
milestone20.0a2
Bug 825987 - Backed out changesets 1b9a99a17afb and 74493ca34d5e (bug 691061) due to regression with saving PDFs. a=akeybl
gfx/cairo/cairo/src/cairo-pdf-surface.c
--- a/gfx/cairo/cairo/src/cairo-pdf-surface.c
+++ b/gfx/cairo/cairo/src/cairo-pdf-surface.c
@@ -1759,101 +1759,16 @@ static cairo_int_status_t
 }
 
 static cairo_bool_t
 _cairo_pdf_surface_supports_fine_grained_fallbacks (void *abstract_surface)
 {
     return TRUE;
 }
 
-static cairo_status_t
-_cairo_pdf_surface_add_padded_image_surface (cairo_pdf_surface_t          *surface,
-					     cairo_surface_pattern_t      *source,
-					     const cairo_rectangle_int_t  *extents,
-					     cairo_pdf_resource_t         *surface_res,
-					     int                          *width,
-					     int                          *height,
-					     int                          *origin_x,
-					     int                          *origin_y)
-{
-    cairo_image_surface_t *image;
-    cairo_surface_t *pad_image;
-    void *image_extra;
-    cairo_int_status_t status;
-    int x = 0;
-    int y = 0;
-    int w, h;
-    cairo_rectangle_int_t extents2;
-    cairo_box_t box;
-    cairo_rectangle_int_t rect;
-    cairo_surface_pattern_t pad_pattern;
-
-    status = _cairo_surface_acquire_source_image (source->surface, &image, &image_extra);
-    if (unlikely (status))
-        return status;
-
-    pad_image = &image->base;
-
-    /* get the operation extents in pattern space */
-    _cairo_box_from_rectangle (&box, extents);
-    _cairo_matrix_transform_bounding_box_fixed (&source->base.matrix, &box, NULL);
-    _cairo_box_round_to_rectangle (&box, &rect);
-
-    /* Check if image needs padding to fill extents */
-    w = image->width;
-    h = image->height;
-    if (_cairo_fixed_integer_ceil(box.p1.x) < 0 ||
-	_cairo_fixed_integer_ceil(box.p1.y) < 0 ||
-	_cairo_fixed_integer_floor(box.p2.y) > w ||
-	_cairo_fixed_integer_floor(box.p2.y) > h)
-    {
-	x = -rect.x;
-	y = -rect.y;
-	pad_image = _cairo_image_surface_create_with_content (source->surface->content,
-							      rect.width,
-							      rect.height);
-	if (pad_image->status) {
-	    status = pad_image->status;
-	    goto BAIL;
-	}
-
-	_cairo_pattern_init_for_surface (&pad_pattern, &image->base);
-	cairo_matrix_init_translate (&pad_pattern.base.matrix, -x, -y);
-	pad_pattern.base.extend = CAIRO_EXTEND_PAD;
-	status = _cairo_surface_paint (pad_image,
-				       CAIRO_OPERATOR_SOURCE, &pad_pattern.base,
-				       NULL);
-        _cairo_pattern_fini (&pad_pattern.base);
-        if (unlikely (status))
-            goto BAIL;
-    }
-
-    status = _cairo_pdf_surface_add_source_surface (surface,
-						    pad_image,
-						    source->base.filter,
-						    surface_res,
-						    &w,
-						    &h);
-    if (unlikely (status))
-        goto BAIL;
-
-    *width = ((cairo_image_surface_t *)pad_image)->width;
-    *height = ((cairo_image_surface_t *)pad_image)->height;
-    *origin_x = x;
-    *origin_y = y;
-
-BAIL:
-    if (pad_image != &image->base)
-        cairo_surface_destroy (pad_image);
-
-    _cairo_surface_release_source_image (source->surface, image, image_extra);
-
-    return status;
-}
-
 /* Emit alpha channel from the image into the given data, providing
  * an id that can be used to reference the resulting SMask object.
  *
  * In the case that the alpha channel happens to be all opaque, then
  * no SMask object will be emitted and *id_ret will be set to 0.
  */
 static cairo_status_t
 _cairo_pdf_surface_emit_smask (cairo_pdf_surface_t	*surface,
@@ -2199,16 +2114,116 @@ static cairo_status_t
 
 BAIL:
     _cairo_surface_release_source_image (source, image, image_extra);
 
     return status;
 }
 
 static cairo_status_t
+_cairo_pdf_surface_emit_padded_image_surface (cairo_pdf_surface_t     *surface,
+					      cairo_pdf_pattern_t     *pdf_pattern,
+					      cairo_pdf_resource_t    *resource,
+					      int                     *width,
+					      int                     *height,
+					      int                     *origin_x,
+					      int                     *origin_y)
+{
+    cairo_image_surface_t *image;
+    cairo_surface_t *pad_image;
+    void *image_extra;
+    cairo_status_t status;
+    cairo_surface_pattern_t *pattern = (cairo_surface_pattern_t *) pdf_pattern->pattern;
+    int x = 0;
+    int y = 0;
+    cairo_bool_t interpolate;
+
+    status = _cairo_surface_acquire_source_image (pattern->surface, &image, &image_extra);
+    if (unlikely (status))
+        return status;
+
+    pad_image = &image->base;
+    if (pattern->base.extend == CAIRO_EXTEND_PAD) {
+        cairo_box_t box;
+        cairo_rectangle_int_t rect;
+        cairo_surface_pattern_t pad_pattern;
+
+        /* get the operation extents in pattern space */
+        _cairo_box_from_rectangle (&box, &pdf_pattern->extents);
+        _cairo_matrix_transform_bounding_box_fixed (&pattern->base.matrix, &box, NULL);
+        _cairo_box_round_to_rectangle (&box, &rect);
+        x = -rect.x;
+        y = -rect.y;
+
+        pad_image = _cairo_image_surface_create_with_content (pattern->surface->content,
+                                                              rect.width,
+                                                              rect.height);
+        if (pad_image->status) {
+            status = pad_image->status;
+            goto BAIL;
+        }
+
+        _cairo_pattern_init_for_surface (&pad_pattern, &image->base);
+        cairo_matrix_init_translate (&pad_pattern.base.matrix, -x, -y);
+        pad_pattern.base.extend = CAIRO_EXTEND_PAD;
+        status = _cairo_surface_composite (CAIRO_OPERATOR_SOURCE,
+                                           &pad_pattern.base,
+                                           NULL,
+                                           pad_image,
+                                           0, 0,
+                                           0, 0,
+                                           0, 0,
+                                           rect.width,
+                                           rect.height,
+					   NULL);
+        _cairo_pattern_fini (&pad_pattern.base);
+        if (unlikely (status))
+            goto BAIL;
+    }
+
+    switch (pdf_pattern->pattern->filter) {
+    case CAIRO_FILTER_GOOD:
+    case CAIRO_FILTER_BEST:
+    case CAIRO_FILTER_BILINEAR:
+	interpolate = TRUE;
+	break;
+    case CAIRO_FILTER_FAST:
+    case CAIRO_FILTER_NEAREST:
+    case CAIRO_FILTER_GAUSSIAN:
+	interpolate = FALSE;
+	break;
+    }
+
+    *resource = _cairo_pdf_surface_new_object (surface);
+    if (resource->id == 0) {
+	status = _cairo_error (CAIRO_STATUS_NO_MEMORY);
+	goto BAIL;
+    }
+
+    status = _cairo_pdf_surface_emit_image (surface, (cairo_image_surface_t *)pad_image,
+                                            resource, interpolate);
+    if (unlikely (status))
+        goto BAIL;
+
+    *width = ((cairo_image_surface_t *)pad_image)->width;
+    *height = ((cairo_image_surface_t *)pad_image)->height;
+    *origin_x = x;
+    *origin_y = y;
+
+BAIL:
+    if (pad_image != &image->base)
+        cairo_surface_destroy (pad_image);
+
+    _cairo_surface_release_source_image (pattern->surface, image, image_extra);
+
+    return status;
+}
+
+
+static cairo_status_t
 _cairo_pdf_surface_emit_recording_surface (cairo_pdf_surface_t  *surface,
 					   cairo_surface_t      *recording_surface,
 					   cairo_pdf_resource_t  resource)
 {
     double old_width, old_height;
     cairo_paginated_mode_t old_paginated_mode;
     cairo_rectangle_int_t recording_extents;
     cairo_bool_t is_bounded;
@@ -2362,24 +2377,23 @@ static cairo_status_t
     int origin_x = 0; /* squelch bogus compiler warning */
     int origin_y = 0; /* squelch bogus compiler warning */
     int bbox_x, bbox_y;
     char draw_surface[200];
 
     if (pattern->base.extend == CAIRO_EXTEND_PAD &&
 	pattern->surface->type != CAIRO_SURFACE_TYPE_RECORDING)
     {
-	status = _cairo_pdf_surface_add_padded_image_surface (surface,
-							      pattern,
-							      &pdf_pattern->extents,
-							      &pattern_resource,
-							      &pattern_width,
-							      &pattern_height,
-							      &origin_x,
-							      &origin_y);
+	status = _cairo_pdf_surface_emit_padded_image_surface (surface,
+							       pdf_pattern,
+							       &pattern_resource,
+							       &pattern_width,
+							       &pattern_height,
+							       &origin_x,
+							       &origin_y);
     }
     else
     {
 	status = _cairo_pdf_surface_add_source_surface (surface,
 							pattern->surface,
 							pdf_pattern->pattern->filter,
 							&pattern_resource,
 							&pattern_width,
@@ -3337,57 +3351,40 @@ static cairo_status_t
 					  old_width,
 					  old_height);
 
     return status;
 }
 
 static cairo_status_t
 _cairo_pdf_surface_paint_surface_pattern (cairo_pdf_surface_t     *surface,
-					  cairo_surface_pattern_t *source,
-					  const cairo_rectangle_int_t  *extents)
+					  cairo_surface_pattern_t *source)
 {
     cairo_pdf_resource_t surface_res;
     int width, height;
     cairo_matrix_t cairo_p2d, pdf_p2d;
     cairo_status_t status;
     int alpha;
-    int origin_x = 0;
-    int origin_y = 0;
-
-    if (source->base.extend == CAIRO_EXTEND_PAD &&
-	source->surface->type != CAIRO_SURFACE_TYPE_RECORDING)
-    {
-	status = _cairo_pdf_surface_add_padded_image_surface (surface,
-							      source,
-							      extents,
-							      &surface_res,
-							      &width,
-							      &height,
-							      &origin_x,
-							      &origin_y);
-    } else {
-	status = _cairo_pdf_surface_add_source_surface (surface,
-							source->surface,
-							source->base.filter,
-							&surface_res,
-							&width,
-						 	&height);
-    }
+
+    status = _cairo_pdf_surface_add_source_surface (surface,
+						    source->surface,
+						    source->base.filter,
+						    &surface_res,
+						    &width,
+						    &height);
     if (unlikely (status))
 	return status;
 
     cairo_p2d = source->base.matrix;
     status = cairo_matrix_invert (&cairo_p2d);
     /* cairo_pattern_set_matrix ensures the matrix is invertible */
     assert (status == CAIRO_STATUS_SUCCESS);
 
     pdf_p2d = surface->cairo_to_pdf;
     cairo_matrix_multiply (&pdf_p2d, &cairo_p2d, &pdf_p2d);
-    cairo_matrix_translate (&pdf_p2d, -origin_x, -origin_y);
     cairo_matrix_translate (&pdf_p2d, 0.0, height);
     cairo_matrix_scale (&pdf_p2d, 1.0, -1.0);
     if (source->surface->type != CAIRO_SURFACE_TYPE_RECORDING)
 	cairo_matrix_scale (&pdf_p2d, width, height);
 
     status = _cairo_pdf_operators_flush (&surface->pdf_operators);
     if (unlikely (status))
 	return status;
@@ -5312,38 +5309,20 @@ static cairo_int_status_t
     if (! _pattern_supported (pattern))
 	return CAIRO_INT_STATUS_UNSUPPORTED;
 
     if (_pdf_operator_supported (op)) {
 	if (pattern->type == CAIRO_PATTERN_TYPE_SURFACE) {
 	    cairo_surface_pattern_t *surface_pattern = (cairo_surface_pattern_t *) pattern;
 
 	    if (surface_pattern->surface->type == CAIRO_SURFACE_TYPE_RECORDING) {
-		if (pattern->extend == CAIRO_EXTEND_PAD) {
-		    cairo_box_t box;
-		    cairo_rectangle_int_t rect;
-		    cairo_rectangle_int_t rec_extents;
-
-		    /* get the operation extents in pattern space */
-		    _cairo_box_from_rectangle (&box, extents);
-		    _cairo_matrix_transform_bounding_box_fixed (&pattern->matrix, &box, NULL);
-		    _cairo_box_round_to_rectangle (&box, &rect);
-
-		    /* Check if surface needs padding to fill extents */
-		    if (_cairo_surface_get_extents (surface_pattern->surface, &rec_extents)) {
-			if (_cairo_fixed_integer_ceil(box.p1.x) < rec_extents.x ||
-			    _cairo_fixed_integer_ceil(box.p1.y) < rec_extents.y ||
-			    _cairo_fixed_integer_floor(box.p2.y) > rec_extents.x + rec_extents.width ||
-			    _cairo_fixed_integer_floor(box.p2.y) > rec_extents.y + rec_extents.height)
-			{
-			    return CAIRO_INT_STATUS_UNSUPPORTED;
-			}
-		    }
-		}
-		return CAIRO_INT_STATUS_ANALYZE_RECORDING_SURFACE_PATTERN;
+		if (pattern->extend == CAIRO_EXTEND_PAD)
+		    return CAIRO_INT_STATUS_UNSUPPORTED;
+		else
+		    return CAIRO_INT_STATUS_ANALYZE_RECORDING_SURFACE_PATTERN;
 	    }
 	}
 
 	return CAIRO_STATUS_SUCCESS;
     }
 
 
     /* The SOURCE operator is supported if the pattern is opaque or if
@@ -5456,18 +5435,17 @@ static cairo_int_status_t
     if (unlikely (status))
 	return status;
 
     if (source->type == CAIRO_PATTERN_TYPE_SURFACE &&
 	source->extend == CAIRO_EXTEND_NONE)
     {
 	_cairo_output_stream_printf (surface->output, "q\n");
 	status = _cairo_pdf_surface_paint_surface_pattern (surface,
-							   (cairo_surface_pattern_t *) source,
-							   &extents.bounded);
+							   (cairo_surface_pattern_t *) source);
 	if (unlikely (status))
 	    return status;
 
 	_cairo_output_stream_printf (surface->output, "Q\n");
 	return _cairo_output_stream_get_status (surface->output);
     }
 
     pattern_res.id = 0;
@@ -5828,33 +5806,31 @@ static cairo_int_status_t
     if (unlikely (status))
 	return status;
 
     status = _cairo_pdf_surface_select_operator (surface, op);
     if (unlikely (status))
 	return status;
 
     if (source->type == CAIRO_PATTERN_TYPE_SURFACE &&
-	(source->extend == CAIRO_EXTEND_NONE ||
-	 source->extend == CAIRO_EXTEND_PAD))
+	source->extend == CAIRO_EXTEND_NONE)
     {
 	status = _cairo_pdf_operators_flush (&surface->pdf_operators);
 	if (unlikely (status))
 	    return status;
 
 	_cairo_output_stream_printf (surface->output, "q\n");
 	status =  _cairo_pdf_operators_clip (&surface->pdf_operators,
 					     path,
 					     fill_rule);
 	if (unlikely (status))
 	    return status;
 
 	status = _cairo_pdf_surface_paint_surface_pattern (surface,
-							   (cairo_surface_pattern_t *) source,
-							   &extents.bounded);
+							   (cairo_surface_pattern_t *) source);
 	if (unlikely (status))
 	    return status;
 
 	_cairo_output_stream_printf (surface->output, "Q\n");
 	return _cairo_output_stream_get_status (surface->output);
     }
 
     pattern_res.id = 0;