summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAndrea Canciani <ranma42@gmail.com>2010-11-23 19:31:40 +0100
committerAndrea Canciani <ranma42@gmail.com>2010-12-13 09:46:09 +0100
commit08cb6db5206203fda919e3d258ce7fdbb3e3c9d8 (patch)
treed6af948f3d2a1a3360bc7783bac19962288acee3
parent790837ac68e51bdd55f13b70d54ba32917cebb45 (diff)
pattern: Use pattern parameter range when analysing all gradients.
This patch adds support for analysing the transparency of a radial gradient within some area of interest. Before the code would ignore the extents for radial gradients. Linear gradients now use _cairo_linear_pattern_box_to_parameter() allowing us to remove the superfluous _extents_to_linear_parameter(). Reviewed-by: M Joonas Pihlaja <jpihlaja@cc.helsinki.fi>
-rw-r--r--src/cairo-pattern.c95
1 files changed, 44 insertions, 51 deletions
diff --git a/src/cairo-pattern.c b/src/cairo-pattern.c
index 1ac50b6cb..e783207e5 100644
--- a/src/cairo-pattern.c
+++ b/src/cairo-pattern.c
@@ -1728,38 +1728,6 @@ _cairo_pattern_reset_solid_surface_cache (void)
CAIRO_MUTEX_UNLOCK (_cairo_pattern_solid_surface_cache_lock);
}
-static void
-_extents_to_linear_parameter (const cairo_linear_pattern_t *linear,
- const cairo_rectangle_int_t *extents,
- double t[2])
-{
- double t0, tdx, tdy;
- double p1x, p1y, pdx, pdy, invsqnorm;
-
- p1x = _cairo_fixed_to_double (linear->p1.x);
- p1y = _cairo_fixed_to_double (linear->p1.y);
- pdx = _cairo_fixed_to_double (linear->p2.x) - p1x;
- pdy = _cairo_fixed_to_double (linear->p2.y) - p1y;
- invsqnorm = 1.0 / (pdx * pdx + pdy * pdy);
- pdx *= invsqnorm;
- pdy *= invsqnorm;
-
- t0 = (extents->x - p1x) * pdx + (extents->y - p1y) * pdy;
- tdx = extents->width * pdx;
- tdy = extents->height * pdy;
-
- t[0] = t[1] = t0;
- if (tdx < 0)
- t[0] += tdx;
- else
- t[1] += tdx;
-
- if (tdy < 0)
- t[0] += tdy;
- else
- t[1] += tdy;
-}
-
static cairo_bool_t
_linear_pattern_is_degenerate (const cairo_linear_pattern_t *linear)
{
@@ -2249,27 +2217,40 @@ _gradient_is_clear (const cairo_gradient_pattern_t *gradient,
gradient->stops[0].offset == gradient->stops[gradient->n_stops - 1].offset))
return TRUE;
+ if (gradient->base.type == CAIRO_PATTERN_TYPE_RADIAL) {
+ /* degenerate radial gradients are clear */
+ if (_radial_pattern_is_degenerate ((cairo_radial_pattern_t *) gradient))
+ return TRUE;
+ } else if (gradient->base.extend == CAIRO_EXTEND_NONE) {
+ /* EXTEND_NONE degenerate linear gradients are clear */
+ if (_linear_pattern_is_degenerate ((cairo_linear_pattern_t *) gradient))
+ return TRUE;
+ }
+
/* Check if the extents intersect the drawn part of the pattern. */
- if (gradient->base.type == CAIRO_PATTERN_TYPE_LINEAR) {
- if (gradient->base.extend == CAIRO_EXTEND_NONE) {
- cairo_linear_pattern_t *linear = (cairo_linear_pattern_t *) gradient;
- /* EXTEND_NONE degenerate linear gradients are clear */
- if (_linear_pattern_is_degenerate (linear))
+ if (extents != NULL &&
+ (gradient->base.extend == CAIRO_EXTEND_NONE ||
+ gradient->base.type == CAIRO_PATTERN_TYPE_RADIAL))
+ {
+ double t[2];
+
+ _cairo_gradient_pattern_box_to_parameter (gradient,
+ extents->x,
+ extents->y,
+ extents->x + extents->width,
+ extents->y + extents->height,
+ DBL_EPSILON,
+ t);
+
+ if (gradient->base.extend == CAIRO_EXTEND_NONE &&
+ (t[0] >= gradient->stops[gradient->n_stops - 1].offset ||
+ t[1] <= gradient->stops[0].offset))
+ {
return TRUE;
-
- if (extents != NULL) {
- double t[2];
- _extents_to_linear_parameter (linear, extents, t);
- if ((t[0] <= 0.0 && t[1] <= 0.0) || (t[0] >= 1.0 && t[1] >= 1.0))
- return TRUE;
- }
}
- } else {
- cairo_radial_pattern_t *radial = (cairo_radial_pattern_t *) gradient;
- /* degenerate radial gradients are clear */
- if (_radial_pattern_is_degenerate (radial))
+
+ if (t[0] == t[1])
return TRUE;
- /* TODO: check actual intersection */
}
for (i = 0; i < gradient->n_stops; i++)
@@ -2487,7 +2468,13 @@ _cairo_gradient_pattern_is_solid (const cairo_gradient_pattern_t *gradient,
if (extents == NULL)
return FALSE;
- _extents_to_linear_parameter (linear, extents, t);
+ _cairo_linear_pattern_box_to_parameter (linear,
+ extents->x,
+ extents->y,
+ extents->x + extents->width,
+ extents->y + extents->height,
+ t);
+
if (t[0] < 0.0 || t[1] > 1.0)
return FALSE;
}
@@ -2599,7 +2586,13 @@ _gradient_is_opaque (const cairo_gradient_pattern_t *gradient,
if (extents == NULL)
return FALSE;
- _extents_to_linear_parameter (linear, extents, t);
+ _cairo_linear_pattern_box_to_parameter (linear,
+ extents->x,
+ extents->y,
+ extents->x + extents->width,
+ extents->y + extents->height,
+ t);
+
if (t[0] < 0.0 || t[1] > 1.0)
return FALSE;
}