mirror of
https://gitlab.freedesktop.org/cairo/cairo.git
synced 2026-03-12 22:50:36 +01: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 = {
|
||||
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
|
||||
CreateGradientFunction (const cairo_gradient_pattern_t *gpat)
|
||||
{
|
||||
cairo_pattern_t *pat;
|
||||
cairo_quartz_float_t input_value_range[2] = { 0.f, 1.f };
|
||||
|
||||
if (_cairo_pattern_create_copy (&pat, &gpat->base))
|
||||
/* 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,
|
||||
1,
|
||||
input_value_range,
|
||||
nonrepeating_gradient_input_value_range,
|
||||
4,
|
||||
gradient_output_value_ranges,
|
||||
&gradient_callbacks);
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue