mirror of
https://gitlab.freedesktop.org/cairo/cairo.git
synced 2026-05-05 08:48:00 +02:00
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>
This commit is contained in:
parent
790837ac68
commit
08cb6db520
1 changed files with 46 additions and 53 deletions
|
|
@ -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;
|
||||
|
||||
/* 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))
|
||||
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;
|
||||
if (gradient->base.type == CAIRO_PATTERN_TYPE_RADIAL) {
|
||||
/* degenerate radial gradients are clear */
|
||||
if (_radial_pattern_is_degenerate (radial))
|
||||
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 (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 (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;
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue