[cairo-commit] 3 commits - boilerplate/cairo-boilerplate-pdf.c src/cairo-analysis-surface.c src/cairo-pdf-surface.c

Carl Worth cworth at kemper.freedesktop.org
Wed Aug 29 15:33:18 PDT 2007


 boilerplate/cairo-boilerplate-pdf.c |    4 -
 src/cairo-analysis-surface.c        |  121 +++++++++++++++++++-----------------
 src/cairo-pdf-surface.c             |   63 ++++++++++++------
 3 files changed, 111 insertions(+), 77 deletions(-)

New commits:
diff-tree e7324454a06e1f090d4e654c9cdcb774f9fb39ab (from f72078fb7660b3c8a369e7bca19628416176a55e)
Author: Carl Worth <cworth at cworth.org>
Date:   Wed Aug 29 15:26:41 2007 -0700

    Disable radial-gradient and unbounded-operator tests for pdf
    
    These are failing due to (already reported) poppler bugs.
    
    There were also problems with the gradients in the PDF
    files previously, but these have recently been fixed.

diff --git a/boilerplate/cairo-boilerplate-pdf.c b/boilerplate/cairo-boilerplate-pdf.c
index 8cf1abf..499e1cc 100644
--- a/boilerplate/cairo-boilerplate-pdf.c
+++ b/boilerplate/cairo-boilerplate-pdf.c
@@ -74,6 +74,7 @@ static const char *pdf_ignored_tests[] =
      */
     "gradient-alpha",
     "linear-gradient",
+    "radial-gradient",
     "text-pattern",
     "trap-clip",
     /* These next 7 failures are due to:
@@ -87,7 +88,8 @@ static const char *pdf_ignored_tests[] =
     "over-above-source",
     "over-around-source",
     "over-below-source",
-    "over-between-source"
+    "over-between-source",
+    "unbounded-operator"
 };
 
 cairo_surface_t *
diff-tree f72078fb7660b3c8a369e7bca19628416176a55e (from 3216275fd9a9cd8d51b1c3a8671393912d50d899)
Author: Adrian Johnson <ajohnson at redneon.com>
Date:   Wed Aug 29 20:18:09 2007 +0930

    Fix unbounded operator bug in analysis surface

diff --git a/src/cairo-analysis-surface.c b/src/cairo-analysis-surface.c
index b2295ea..afbd30f 100644
--- a/src/cairo-analysis-surface.c
+++ b/src/cairo-analysis-surface.c
@@ -288,32 +288,34 @@ _cairo_analysis_surface_stroke (void			*
 
     _cairo_rectangle_intersect (&extents, &surface->current_clip);
 
-    box.p1.x = _cairo_fixed_from_int (extents.x);
-    box.p1.y = _cairo_fixed_from_int (extents.y);
-    box.p2.x = _cairo_fixed_from_int (extents.x + extents.width);
-    box.p2.y = _cairo_fixed_from_int (extents.y + extents.height);
-
-    _cairo_traps_init (&traps);
-
-    _cairo_traps_limit (&traps, &box);
-
-    status = _cairo_path_fixed_stroke_to_traps (path,
-						style,
-						ctm, ctm_inverse,
-						tolerance,
-						&traps);
-    if (status)
-	goto FINISH;
+    if (_cairo_operator_bounded_by_mask (op)) {
+	box.p1.x = _cairo_fixed_from_int (extents.x);
+	box.p1.y = _cairo_fixed_from_int (extents.y);
+	box.p2.x = _cairo_fixed_from_int (extents.x + extents.width);
+	box.p2.y = _cairo_fixed_from_int (extents.y + extents.height);
+
+	_cairo_traps_init (&traps);
+	_cairo_traps_limit (&traps, &box);
+	status = _cairo_path_fixed_stroke_to_traps (path,
+						    style,
+						    ctm, ctm_inverse,
+						    tolerance,
+						    &traps);
 
-    _cairo_traps_extents (&traps, &box);
-    extents.x = _cairo_fixed_integer_floor (box.p1.x);
-    extents.y = _cairo_fixed_integer_floor (box.p1.y);
-    extents.width = _cairo_fixed_integer_ceil (box.p2.x) - extents.x;
-    extents.height = _cairo_fixed_integer_ceil (box.p2.y) - extents.y;
-    status = _cairo_analysis_surface_add_operation (surface, &extents, backend_status);
+	if (status) {
+	    _cairo_traps_fini (&traps);
+	    return status;
+	}
 
-FINISH:
-    _cairo_traps_fini (&traps);
+	_cairo_traps_extents (&traps, &box);
+	extents.x = _cairo_fixed_integer_floor (box.p1.x);
+	extents.y = _cairo_fixed_integer_floor (box.p1.y);
+	extents.width = _cairo_fixed_integer_ceil (box.p2.x) - extents.x;
+	extents.height = _cairo_fixed_integer_ceil (box.p2.y) - extents.y;
+	_cairo_traps_fini (&traps);
+    }
+
+    status = _cairo_analysis_surface_add_operation (surface, &extents, backend_status);
 
     return status;
 }
@@ -355,31 +357,34 @@ _cairo_analysis_surface_fill (void			*ab
 
     _cairo_rectangle_intersect (&extents, &surface->current_clip);
 
-    box.p1.x = _cairo_fixed_from_int (extents.x);
-    box.p1.y = _cairo_fixed_from_int (extents.y);
-    box.p2.x = _cairo_fixed_from_int (extents.x + extents.width);
-    box.p2.y = _cairo_fixed_from_int (extents.y + extents.height);
-
-    _cairo_traps_init (&traps);
-
-    _cairo_traps_limit (&traps, &box);
-
-    status = _cairo_path_fixed_fill_to_traps (path,
-					      fill_rule,
-					      tolerance,
-					      &traps);
-    if (status)
-	goto FINISH;
+    if (_cairo_operator_bounded_by_mask (op)) {
+	box.p1.x = _cairo_fixed_from_int (extents.x);
+	box.p1.y = _cairo_fixed_from_int (extents.y);
+	box.p2.x = _cairo_fixed_from_int (extents.x + extents.width);
+	box.p2.y = _cairo_fixed_from_int (extents.y + extents.height);
+
+	_cairo_traps_init (&traps);
+	_cairo_traps_limit (&traps, &box);
+	status = _cairo_path_fixed_fill_to_traps (path,
+						  fill_rule,
+						  tolerance,
+						  &traps);
 
-    _cairo_traps_extents (&traps, &box);
-    extents.x = _cairo_fixed_integer_floor (box.p1.x);
-    extents.y = _cairo_fixed_integer_floor (box.p1.y);
-    extents.width = _cairo_fixed_integer_ceil (box.p2.x) - extents.x;
-    extents.height = _cairo_fixed_integer_ceil (box.p2.y) - extents.y;
-    status = _cairo_analysis_surface_add_operation (surface, &extents, backend_status);
+	if (status) {
+	    _cairo_traps_fini (&traps);
+	    return status;
+	}
 
-FINISH:
-    _cairo_traps_fini (&traps);
+	_cairo_traps_extents (&traps, &box);
+	extents.x = _cairo_fixed_integer_floor (box.p1.x);
+	extents.y = _cairo_fixed_integer_floor (box.p1.y);
+	extents.width = _cairo_fixed_integer_ceil (box.p2.x) - extents.x;
+	extents.height = _cairo_fixed_integer_ceil (box.p2.y) - extents.y;
+
+	_cairo_traps_fini (&traps);
+    }
+
+    status = _cairo_analysis_surface_add_operation (surface, &extents, backend_status);
 
     return status;
 }
@@ -394,7 +399,7 @@ _cairo_analysis_surface_show_glyphs (voi
 {
     cairo_analysis_surface_t *surface = abstract_surface;
     cairo_status_t	     status, backend_status;
-    cairo_rectangle_int_t  extent;
+    cairo_rectangle_int_t    extents, glyph_extents;
 
     if (!surface->target->backend->show_glyphs)
 	backend_status = CAIRO_INT_STATUS_UNSUPPORTED;
@@ -404,15 +409,23 @@ _cairo_analysis_surface_show_glyphs (voi
 							   glyphs, num_glyphs,
 							   scaled_font);
 
-    status = _cairo_scaled_font_glyph_device_extents (scaled_font,
-						      glyphs,
-						      num_glyphs,
-						      &extent);
+    status = _cairo_surface_get_extents (&surface->base, &extents);
     if (status)
 	return status;
 
-    _cairo_rectangle_intersect (&extent, &surface->current_clip);
-    status = _cairo_analysis_surface_add_operation (surface, &extent, backend_status);
+    if (_cairo_operator_bounded_by_mask (op)) {
+	status = _cairo_scaled_font_glyph_device_extents (scaled_font,
+							  glyphs,
+							  num_glyphs,
+							  &glyph_extents);
+	if (status)
+	    return status;
+
+	_cairo_rectangle_intersect (&extents, &glyph_extents);
+    }
+
+    _cairo_rectangle_intersect (&extents, &surface->current_clip);
+    status = _cairo_analysis_surface_add_operation (surface, &extents, backend_status);
 
     return status;
 }
diff-tree 3216275fd9a9cd8d51b1c3a8671393912d50d899 (from bdc70d1fc2a31aa829571244c54f98210e97a2cf)
Author: Adrian Johnson <ajohnson at redneon.com>
Date:   Tue Aug 28 23:40:18 2007 +0930

    Fix PDF gradients bug
    
    The PDF surface was adding extra stops at the 0.0 and 1.0 offset when
    there was not already stops at these offsets. This has been replaced
    with code to move the coordinates of the linear gradient line in to
    the position of the first and last offset.

diff --git a/src/cairo-pdf-surface.c b/src/cairo-pdf-surface.c
index 7d39baf..2677605 100644
--- a/src/cairo-pdf-surface.c
+++ b/src/cairo-pdf-surface.c
@@ -1612,9 +1612,9 @@ _cairo_pdf_surface_emit_stitched_colorgr
     for (i = 0; i < n_stops-1; i++) {
         if (is_alpha) {
             status = cairo_pdf_surface_emit_alpha_linear_function (surface,
-                                                             &stops[i],
-                                                             &stops[i+1],
-                                                             &stops[i].resource);
+                                                                   &stops[i],
+                                                                   &stops[i+1],
+                                                                   &stops[i].resource);
             if (status)
                 return status;
         } else {
@@ -1632,8 +1632,10 @@ _cairo_pdf_surface_emit_stitched_colorgr
     _cairo_output_stream_printf (surface->output,
 				 "%d 0 obj\r\n"
 				 "<< /FunctionType 3\r\n"
-				 "   /Domain [ 0 1 ]\r\n",
-				 res.id);
+				 "   /Domain [ %f %f ]\r\n",
+				 res.id,
+                                 stops[0].offset,
+                                 stops[n_stops - 1].offset);
 
     _cairo_output_stream_printf (surface->output,
 				 "   /Functions [ ");
@@ -1702,23 +1704,6 @@ _cairo_pdf_surface_emit_pattern_stops (c
 	stops[i].offset = _cairo_fixed_to_double (pattern->stops[i].x);
     }
 
-    /* make sure first offset is 0.0 and last offset is 1.0. (Otherwise Acrobat
-     * Reader chokes.) */
-    if (stops[0].offset > COLOR_STOP_EPSILON) {
-	    memcpy (allstops, stops, sizeof (cairo_pdf_color_stop_t));
-	    stops = allstops;
-	    n_stops++;
-    }
-    stops[0].offset = 0.0;
-
-    if (stops[n_stops-1].offset < 1.0 - COLOR_STOP_EPSILON) {
-	    memcpy (&stops[n_stops],
-		    &stops[n_stops - 1],
-		    sizeof (cairo_pdf_color_stop_t));
-	    n_stops++;
-    }
-    stops[n_stops-1].offset = 1.0;
-
     if (n_stops == 2) {
         /* no need for stitched function */
         status = cairo_pdf_surface_emit_rgb_linear_function (surface,
@@ -1844,6 +1829,8 @@ _cairo_pdf_surface_emit_linear_pattern (
     cairo_matrix_t pat_to_pdf;
     cairo_extend_t extend;
     cairo_status_t status;
+    cairo_gradient_pattern_t *gradient = &pattern->base;
+    double first_stop, last_stop;
 
     extend = cairo_pattern_get_extend (&pattern->base.base);
     _cairo_pdf_surface_pause_content_stream (surface);
@@ -1865,6 +1852,36 @@ _cairo_pdf_surface_emit_linear_pattern (
     x2 = _cairo_fixed_to_double (pattern->p2.x);
     y2 = _cairo_fixed_to_double (pattern->p2.y);
 
+    first_stop = _cairo_fixed_to_double (gradient->stops[0].x);
+    last_stop = _cairo_fixed_to_double (gradient->stops[gradient->n_stops - 1].x);
+
+    /* PDF requires the first and last stop to be the same as the line
+     * coordinates. If this is not a repeating pattern move the line
+     * coordinates to the location of first and last stop. */
+
+    if (pattern->base.base.extend == CAIRO_EXTEND_NONE ||
+	pattern->base.base.extend == CAIRO_EXTEND_PAD) {
+	double _x1, _y1, _x2, _y2;
+
+	_x1 = x1 + (x2 - x1)*first_stop;
+	_y1 = y1 + (y2 - y1)*first_stop;
+	_x2 = x1 + (x2 - x1)*last_stop;
+	_y2 = y1 + (y2 - y1)*last_stop;
+
+	x1 = _x1;
+	x2 = _x2;
+	y1 = _y1;
+	y2 = _y2;
+    }
+
+    if (gradient->n_stops == 2) {
+	/* If only two stops the Type 2 function is used by itself
+	 * without a Stitching function. Type 2 functions always have
+	 * the domain [0 1] */
+	first_stop = 0.0;
+	last_stop = 1.0;
+    }
+
     pattern_resource = _cairo_pdf_surface_new_object (surface);
     _cairo_output_stream_printf (surface->output,
                                  "%d 0 obj\r\n"
@@ -1875,12 +1892,14 @@ _cairo_pdf_surface_emit_linear_pattern (
                                  "      << /ShadingType 2\r\n"
                                  "         /ColorSpace /DeviceRGB\r\n"
                                  "         /Coords [ %f %f %f %f ]\r\n"
+                                 "         /Domain [ %f %f ]\r\n"
                                  "         /Function %d 0 R\r\n",
                                  pattern_resource.id,
                                  pat_to_pdf.xx, pat_to_pdf.yx,
                                  pat_to_pdf.xy, pat_to_pdf.yy,
                                  pat_to_pdf.x0, pat_to_pdf.y0,
                                  x1, y1, x2, y2,
+                                 first_stop, last_stop,
                                  color_function.id);
 
     if (extend == CAIRO_EXTEND_PAD) {


More information about the cairo-commit mailing list