[cairo-commit] src/cairo-pattern.c src/cairo-pdf-surface.c src/cairo-ps-surface.c src/cairo-quartz-surface.c

Andrea Canciani ranma42 at kemper.freedesktop.org
Tue Jan 18 06:21:39 PST 2011


 src/cairo-pattern.c        |    3 ++-
 src/cairo-pdf-surface.c    |   10 +++++++---
 src/cairo-ps-surface.c     |   10 +++++++---
 src/cairo-quartz-surface.c |   12 +++++++++---
 4 files changed, 25 insertions(+), 10 deletions(-)

New commits:
commit 8c031c029d45d65dac22be9a809cc43f4449d41e
Author: Andrea Canciani <ranma42 at gmail.com>
Date:   Mon Jan 3 16:41:34 2011 +0100

    pdf,ps,quartz: Use correct tolerance for gradient domain computation
    
    The tolerance argument of _cairo_gradient_pattern_box_to_parameter ()
    is in pattern space, so to have it constant in device space, it should
    depend on the pattern matrix.
    
    In ps and pdf the fallback resolution alone is not meaningful. The
    resolution/fallback_resolution ratio should be used instead.

diff --git a/src/cairo-pattern.c b/src/cairo-pattern.c
index 270ba1a..82c2279 100644
--- a/src/cairo-pattern.c
+++ b/src/cairo-pattern.c
@@ -2644,10 +2644,11 @@ _cairo_radial_pattern_box_to_parameter (const cairo_radial_pattern_t *radial,
     cairo_bool_t valid;
 
     assert (! _radial_pattern_is_degenerate (radial));
-    assert (tolerance > 0);
     assert (x0 < x1);
     assert (y0 < y1);
 
+    tolerance = MAX (tolerance, DBL_EPSILON);
+
     range[0] = range[1] = 0;
     valid = FALSE;
 
diff --git a/src/cairo-pdf-surface.c b/src/cairo-pdf-surface.c
index 21dbf57..c915b3f 100644
--- a/src/cairo-pdf-surface.c
+++ b/src/cairo-pdf-surface.c
@@ -3226,7 +3226,7 @@ _cairo_pdf_surface_emit_gradient (cairo_pdf_surface_t    *surface,
 	pattern->base.extend == CAIRO_EXTEND_REFLECT)
     {
 	double bounds_x1, bounds_x2, bounds_y1, bounds_y2;
-	double tolerance;
+	double x_scale, y_scale, tolerance;
 
 	/* TODO: use tighter extents */
 	bounds_x1 = 0;
@@ -3238,8 +3238,12 @@ _cairo_pdf_surface_emit_gradient (cairo_pdf_surface_t    *surface,
 					      &bounds_x2, &bounds_y2,
 					      NULL);
 
-	tolerance = 1. / MAX (surface->base.x_fallback_resolution,
-			      surface->base.y_fallback_resolution);
+	x_scale = surface->base.x_resolution / surface->base.x_fallback_resolution;
+	y_scale = surface->base.y_resolution / surface->base.y_fallback_resolution;
+
+	tolerance = fabs (_cairo_matrix_compute_determinant (&pattern->base.matrix));
+	tolerance /= _cairo_matrix_transformed_circle_major_axis (&pattern->base.matrix, 1);
+	tolerance *= MIN (x_scale, y_scale);
 
 	_cairo_gradient_pattern_box_to_parameter (pattern,
 						  bounds_x1, bounds_y1,
diff --git a/src/cairo-ps-surface.c b/src/cairo-ps-surface.c
index 12a9dcd..ef53dd1 100644
--- a/src/cairo-ps-surface.c
+++ b/src/cairo-ps-surface.c
@@ -3259,7 +3259,7 @@ _cairo_ps_surface_emit_gradient (cairo_ps_surface_t       *surface,
 	pattern->base.extend == CAIRO_EXTEND_REFLECT)
     {
 	double bounds_x1, bounds_x2, bounds_y1, bounds_y2;
-	double tolerance;
+	double x_scale, y_scale, tolerance;
 
 	/* TODO: use tighter extents */
 	bounds_x1 = 0;
@@ -3271,8 +3271,12 @@ _cairo_ps_surface_emit_gradient (cairo_ps_surface_t       *surface,
 					      &bounds_x2, &bounds_y2,
 					      NULL);
 
-	tolerance = 1. / MAX (surface->base.x_fallback_resolution,
-			      surface->base.y_fallback_resolution);
+	x_scale = surface->base.x_resolution / surface->base.x_fallback_resolution;
+	y_scale = surface->base.y_resolution / surface->base.y_fallback_resolution;
+
+	tolerance = fabs (_cairo_matrix_compute_determinant (&pattern->base.matrix));
+	tolerance /= _cairo_matrix_transformed_circle_major_axis (&pattern->base.matrix, 1);
+	tolerance *= MIN (x_scale, y_scale);
 
 	_cairo_gradient_pattern_box_to_parameter (pattern,
 						  bounds_x1, bounds_y1,
diff --git a/src/cairo-quartz-surface.c b/src/cairo-quartz-surface.c
index 06dd128..d29eef0 100644
--- a/src/cairo-quartz-surface.c
+++ b/src/cairo-quartz-surface.c
@@ -842,7 +842,10 @@ _cairo_quartz_create_gradient_function (const cairo_gradient_pattern_t *gradient
 
     if (gradient->base.extend != CAIRO_EXTEND_NONE) {
 	double bounds_x1, bounds_x2, bounds_y1, bounds_y2;
-	double t[2];
+	double t[2], tolerance;
+
+	tolerance = fabs (_cairo_matrix_compute_determinant (&gradient->base.matrix));
+	tolerance /= _cairo_matrix_transformed_circle_major_axis (&gradient->base.matrix, 1);
 
 	bounds_x1 = extents->x;
 	bounds_y1 = extents->y;
@@ -853,8 +856,11 @@ _cairo_quartz_create_gradient_function (const cairo_gradient_pattern_t *gradient
 					      &bounds_x2, &bounds_y2,
 					      NULL);
 
-	_cairo_gradient_pattern_box_to_parameter (gradient, bounds_x1, bounds_y1,
-						  bounds_x2, bounds_y2, 1, t);
+	_cairo_gradient_pattern_box_to_parameter (gradient,
+						  bounds_x1, bounds_y1,
+						  bounds_x2, bounds_y2,
+						  tolerance,
+						  t);
 
 	/* set the input range for the function -- the function knows how
 	   to map values outside of 0.0 .. 1.0 to the correct color */


More information about the cairo-commit mailing list