mirror of
https://gitlab.freedesktop.org/cairo/cairo.git
synced 2026-05-09 03:48:03 +02:00
Ensure the quartz backend returns the first stop for negative positions on the gradient line of a nonrepeating linear gradient.
I discovered a small bug in cairo-quartz gradients. If you have multiple stops at position 0, then cairo-quartz pads with the *last* stop at position 0, instead of the first stop at position 0. This patch fixes that. From https://bugzilla.mozilla.org/show_bug.cgi?id=513395
This commit is contained in:
parent
ce27db9a55
commit
d65e8064c0
1 changed files with 22 additions and 2 deletions
|
|
@ -800,12 +800,32 @@ static const cairo_quartz_float_t gradient_output_value_ranges[8] = {
|
||||||
static const CGFunctionCallbacks gradient_callbacks = {
|
static const CGFunctionCallbacks gradient_callbacks = {
|
||||||
0, ComputeGradientValue, (CGFunctionReleaseInfoCallback) cairo_pattern_destroy
|
0, ComputeGradientValue, (CGFunctionReleaseInfoCallback) cairo_pattern_destroy
|
||||||
};
|
};
|
||||||
|
/* Quartz will clamp input values to the input range.
|
||||||
|
|
||||||
|
Our stops are all in the range 0.0 to 1.0. However, the color before the
|
||||||
|
beginning of the gradient line is obtained by Quartz computing a negative
|
||||||
|
position on the gradient line, clamping it to the input range we specified
|
||||||
|
for our color function, and then calling our color function (actually it
|
||||||
|
pre-samples the color function into an array, but that doesn't matter just
|
||||||
|
here). Therefore if we set the lower bound to 0.0, a negative position
|
||||||
|
on the gradient line will pass 0.0 to ComputeGradientValue, which will
|
||||||
|
select the last color stop with position 0, although it should select
|
||||||
|
the first color stop (this matters when there are multiple color stops with
|
||||||
|
position 0).
|
||||||
|
|
||||||
|
Therefore we pass a small negative number as the lower bound of the input
|
||||||
|
range, so this value gets passed into ComputeGradientValue, which will
|
||||||
|
return the color of the first stop. The number should be small because
|
||||||
|
as far as I can tell, Quartz pre-samples the entire input range of the color
|
||||||
|
function into an array of fixed size, so if the input range is larger
|
||||||
|
than needed, the resolution of the gradient will be unnecessarily low.
|
||||||
|
*/
|
||||||
|
static const cairo_quartz_float_t nonrepeating_gradient_input_value_range[2] = { -0.001f, 1.f };
|
||||||
|
|
||||||
static CGFunctionRef
|
static CGFunctionRef
|
||||||
CreateGradientFunction (const cairo_gradient_pattern_t *gpat)
|
CreateGradientFunction (const cairo_gradient_pattern_t *gpat)
|
||||||
{
|
{
|
||||||
cairo_pattern_t *pat;
|
cairo_pattern_t *pat;
|
||||||
cairo_quartz_float_t input_value_range[2] = { 0.f, 1.f };
|
|
||||||
|
|
||||||
if (_cairo_pattern_create_copy (&pat, &gpat->base))
|
if (_cairo_pattern_create_copy (&pat, &gpat->base))
|
||||||
/* quartz doesn't deal very well with malloc failing, so there's
|
/* quartz doesn't deal very well with malloc failing, so there's
|
||||||
|
|
@ -814,7 +834,7 @@ CreateGradientFunction (const cairo_gradient_pattern_t *gpat)
|
||||||
|
|
||||||
return CGFunctionCreate (pat,
|
return CGFunctionCreate (pat,
|
||||||
1,
|
1,
|
||||||
input_value_range,
|
nonrepeating_gradient_input_value_range,
|
||||||
4,
|
4,
|
||||||
gradient_output_value_ranges,
|
gradient_output_value_ranges,
|
||||||
&gradient_callbacks);
|
&gradient_callbacks);
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue