Bug 825987 - Backed out changesets 1b9a99a17afb and 74493ca34d5e (bug 691061) due to regression with saving PDFs.
authorAnthony Jones <ajones@mozilla.com>
Wed, 30 Jan 2013 08:39:37 -0500
changeset 120369 f6a638c16bd4a30b06cbf535b84b226a7ab47c6f
parent 120368 a1adb678b5dbfe91c10f1363d93ee2b8048d4bcb
child 120370 0bbcb088b1b8d6df646a516f3be193883b128135
push id24251
push userryanvm@gmail.com
push dateThu, 31 Jan 2013 20:56:22 +0000
treeherdermozilla-central@683b08dc1afd [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
bugs825987, 691061
milestone21.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Bug 825987 - Backed out changesets 1b9a99a17afb and 74493ca34d5e (bug 691061) due to regression with saving PDFs.
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;