|
1 diff --git a/gfx/cairo/cairo/src/cairo-quartz-surface.c b/gfx/cairo/cairo/src/cairo-quartz-surface.c |
|
2 --- a/gfx/cairo/cairo/src/cairo-quartz-surface.c |
|
3 +++ b/gfx/cairo/cairo/src/cairo-quartz-surface.c |
|
4 @@ -690,31 +690,51 @@ ComputeGradientValue (void *info, const |
|
5 } |
|
6 |
|
7 static const float gradient_output_value_ranges[8] = { |
|
8 0.f, 1.f, 0.f, 1.f, 0.f, 1.f, 0.f, 1.f |
|
9 }; |
|
10 static const CGFunctionCallbacks gradient_callbacks = { |
|
11 0, ComputeGradientValue, (CGFunctionReleaseInfoCallback) cairo_pattern_destroy |
|
12 }; |
|
13 +/* Quartz will clamp input values to the input range. |
|
14 + |
|
15 + Our stops are all in the range 0.0 to 1.0. However, the color before the |
|
16 + beginning of the gradient line is obtained by Quartz computing a negative |
|
17 + position on the gradient line, clamping it to the input range we specified |
|
18 + for our color function, and then calling our color function (actually it |
|
19 + pre-samples the color function into an array, but that doesn't matter just |
|
20 + here). Therefore if we set the lower bound to 0.0, a negative position |
|
21 + on the gradient line will pass 0.0 to ComputeGradientValue, which will |
|
22 + select the last color stop with position 0, although it should select |
|
23 + the first color stop (this matters when there are multiple color stops with |
|
24 + position 0). |
|
25 + |
|
26 + Therefore we pass a small negative number as the lower bound of the input |
|
27 + range, so this value gets passed into ComputeGradientValue, which will |
|
28 + return the color of the first stop. The number should be small because |
|
29 + as far as I can tell, Quartz pre-samples the entire input range of the color |
|
30 + function into an array of fixed size, so if the input range is larger |
|
31 + than needed, the resolution of the gradient will be unnecessarily low. |
|
32 +*/ |
|
33 +static const float nonrepeating_gradient_input_value_range[2] = { -0.001f, 1.f }; |
|
34 |
|
35 static CGFunctionRef |
|
36 CreateGradientFunction (const cairo_gradient_pattern_t *gpat) |
|
37 { |
|
38 cairo_pattern_t *pat; |
|
39 - float input_value_range[2] = { 0.f, 1.f }; |
|
40 |
|
41 if (_cairo_pattern_create_copy (&pat, &gpat->base)) |
|
42 /* quartz doesn't deal very well with malloc failing, so there's |
|
43 * not much point in us trying either */ |
|
44 return NULL; |
|
45 |
|
46 return CGFunctionCreate (pat, |
|
47 1, |
|
48 - input_value_range, |
|
49 + nonrepeating_gradient_input_value_range, |
|
50 4, |
|
51 gradient_output_value_ranges, |
|
52 &gradient_callbacks); |
|
53 } |
|
54 |
|
55 static void |
|
56 UpdateLinearParametersToIncludePoint(double *min_t, double *max_t, CGPoint *start, |
|
57 double dx, double dy, |