mirror of
https://gitlab.gnome.org/GNOME/gtk.git
synced 2025-01-12 13:30:19 +00:00
rendernode: Fix Cairo rendering of repeating gradients
Cairo and the GL renderer have a different idea of how to handle transitioning of colors outside the defined range. Consider these stops: black 50%, white 50% What color is at 0%? Cairo would transition between the last and first stop, ie it'd do a white-to-black transition and end up at rgb(0.5,0.5,0.5) at 0%. GL would behave as it would for non-repeating gradients and use black for the range [0%..50%] and white for [50%..100%]. The web would rescale the range so the first stop would be at 0% and the last stop would be at 100%, so this gradient would be illegal. Considering that it's possible for code to transition between the different behaviors by adding explicit stops at 0%/100%, I could choose any method. So I chose the simplest one, which is what the GL renderer does and which treats repeating and non-repeating gradients the same. Tests attached.
This commit is contained in:
parent
9ffd7840ba
commit
a05a021fd1
@ -248,6 +248,13 @@ gsk_linear_gradient_node_draw (GskRenderNode *node,
|
||||
if (gsk_render_node_get_node_type (node) == GSK_REPEATING_LINEAR_GRADIENT_NODE)
|
||||
cairo_pattern_set_extend (pattern, CAIRO_EXTEND_REPEAT);
|
||||
|
||||
if (self->stops[0].offset > 0.0)
|
||||
cairo_pattern_add_color_stop_rgba (pattern,
|
||||
0.0,
|
||||
self->stops[0].color.red,
|
||||
self->stops[0].color.green,
|
||||
self->stops[0].color.blue,
|
||||
self->stops[0].color.alpha);
|
||||
for (i = 0; i < self->n_stops; i++)
|
||||
{
|
||||
cairo_pattern_add_color_stop_rgba (pattern,
|
||||
@ -257,6 +264,13 @@ gsk_linear_gradient_node_draw (GskRenderNode *node,
|
||||
self->stops[i].color.blue,
|
||||
self->stops[i].color.alpha);
|
||||
}
|
||||
if (self->stops[self->n_stops-1].offset < 1.0)
|
||||
cairo_pattern_add_color_stop_rgba (pattern,
|
||||
1.0,
|
||||
self->stops[self->n_stops-1].color.red,
|
||||
self->stops[self->n_stops-1].color.green,
|
||||
self->stops[self->n_stops-1].color.blue,
|
||||
self->stops[self->n_stops-1].color.alpha);
|
||||
|
||||
cairo_set_source (cr, pattern);
|
||||
cairo_pattern_destroy (pattern);
|
||||
@ -562,13 +576,29 @@ gsk_radial_gradient_node_draw (GskRenderNode *node,
|
||||
else
|
||||
cairo_pattern_set_extend (pattern, CAIRO_EXTEND_PAD);
|
||||
|
||||
for (i = 0; i < self->n_stops; i++)
|
||||
if (self->stops[0].offset > 0.0)
|
||||
cairo_pattern_add_color_stop_rgba (pattern,
|
||||
self->stops[i].offset,
|
||||
self->stops[i].color.red,
|
||||
self->stops[i].color.green,
|
||||
self->stops[i].color.blue,
|
||||
self->stops[i].color.alpha);
|
||||
0.0,
|
||||
self->stops[0].color.red,
|
||||
self->stops[0].color.green,
|
||||
self->stops[0].color.blue,
|
||||
self->stops[0].color.alpha);
|
||||
for (i = 0; i < self->n_stops; i++)
|
||||
{
|
||||
cairo_pattern_add_color_stop_rgba (pattern,
|
||||
self->stops[i].offset,
|
||||
self->stops[i].color.red,
|
||||
self->stops[i].color.green,
|
||||
self->stops[i].color.blue,
|
||||
self->stops[i].color.alpha);
|
||||
}
|
||||
if (self->stops[self->n_stops-1].offset < 1.0)
|
||||
cairo_pattern_add_color_stop_rgba (pattern,
|
||||
1.0,
|
||||
self->stops[self->n_stops-1].color.red,
|
||||
self->stops[self->n_stops-1].color.green,
|
||||
self->stops[self->n_stops-1].color.blue,
|
||||
self->stops[self->n_stops-1].color.alpha);
|
||||
|
||||
gsk_cairo_rectangle (cr, &node->bounds);
|
||||
cairo_translate (cr, self->center.x, self->center.y);
|
||||
|
@ -0,0 +1,6 @@
|
||||
repeating-linear-gradient {
|
||||
bounds: 0 0 50 50;
|
||||
start: 0 0;
|
||||
end: 0 50;
|
||||
stops: 0.5 rgb(255,0,0), 0.5 rgb(0,255,0);
|
||||
}
|
BIN
testsuite/gsk/compare/repeating-linear-gradient-edge-colors.png
Normal file
BIN
testsuite/gsk/compare/repeating-linear-gradient-edge-colors.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 151 B |
@ -0,0 +1,10 @@
|
||||
clip {
|
||||
clip: -25 -25 50 50;
|
||||
child: repeating-radial-gradient {
|
||||
bounds: -100 -100 200 200;
|
||||
center: 0 0;
|
||||
hradius: 100;
|
||||
vradius: 100;
|
||||
stops: 0.5 rgb(255,0,0), 0.5 rgb(0,255,0);
|
||||
}
|
||||
}
|
BIN
testsuite/gsk/compare/repeating-radial-gradient-edge-colors.png
Normal file
BIN
testsuite/gsk/compare/repeating-radial-gradient-edge-colors.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 144 B |
@ -80,6 +80,8 @@ compare_render_tests = [
|
||||
'outset_shadow_rounded_top',
|
||||
'outset_shadow_simple',
|
||||
'repeat',
|
||||
'repeating-linear-gradient-edge-colors',
|
||||
'repeating-radial-gradient-edge-colors',
|
||||
'repeat-no-repeat',
|
||||
'repeat-empty-child-bounds',
|
||||
'repeat-negative-coords',
|
||||
|
Loading…
Reference in New Issue
Block a user