snapshot: linear-gradients cannot be affine-transformed

When different scale factors are used to transform a diagonal
linear gradient, the angle between the gradient line and its
perpendicular is no longer a right angle, which makes the
gradient come out different.

So it is necessary to use transform nodes in that case so that the
correct gradient gets rendered.

Technically, the code could check if the scales are equal or the
gradient line is horizontal/vertical, but I don't think that's worth it.
This commit is contained in:
Benjamin Otte 2023-12-25 17:17:26 +01:00
parent 57a4500bae
commit 7ed6c39862

View File

@ -2388,7 +2388,7 @@ gtk_snapshot_append_linear_gradient (GtkSnapshot *snapshot,
{
GskRenderNode *node;
graphene_rect_t real_bounds;
float scale_x, scale_y, dx, dy;
float dx, dy;
const GdkRGBA *first_color;
gboolean need_gradient = FALSE;
@ -2398,8 +2398,8 @@ gtk_snapshot_append_linear_gradient (GtkSnapshot *snapshot,
g_return_if_fail (stops != NULL);
g_return_if_fail (n_stops > 1);
gtk_snapshot_ensure_affine (snapshot, &scale_x, &scale_y, &dx, &dy);
gtk_graphene_rect_scale_affine (bounds, scale_x, scale_y, dx, dy, &real_bounds);
gtk_snapshot_ensure_translate (snapshot, &dx, &dy);
graphene_rect_offset_r (bounds, dx, dy, &real_bounds);
first_color = &stops[0].color;
for (gsize i = 0; i < n_stops; i ++)
@ -2415,10 +2415,10 @@ gtk_snapshot_append_linear_gradient (GtkSnapshot *snapshot,
{
graphene_point_t real_start_point, real_end_point;
real_start_point.x = scale_x * start_point->x + dx;
real_start_point.y = scale_y * start_point->y + dy;
real_end_point.x = scale_x * end_point->x + dx;
real_end_point.y = scale_y * end_point->y + dy;
real_start_point.x = start_point->x + dx;
real_start_point.y = start_point->y + dy;
real_end_point.x = end_point->x + dx;
real_end_point.y = end_point->y + dy;
node = gsk_linear_gradient_node_new (&real_bounds,
&real_start_point,
@ -2455,7 +2455,7 @@ gtk_snapshot_append_repeating_linear_gradient (GtkSnapshot *snapshot,
{
GskRenderNode *node;
graphene_rect_t real_bounds;
float scale_x, scale_y, dx, dy;
float dx, dy;
gboolean need_gradient = FALSE;
const GdkRGBA *first_color;
@ -2465,8 +2465,8 @@ gtk_snapshot_append_repeating_linear_gradient (GtkSnapshot *snapshot,
g_return_if_fail (stops != NULL);
g_return_if_fail (n_stops > 1);
gtk_snapshot_ensure_affine (snapshot, &scale_x, &scale_y, &dx, &dy);
gtk_graphene_rect_scale_affine (bounds, scale_x, scale_y, dx, dy, &real_bounds);
gtk_snapshot_ensure_translate (snapshot, &dx, &dy);
graphene_rect_offset_r (bounds, dx, dy, &real_bounds);
first_color = &stops[0].color;
for (gsize i = 0; i < n_stops; i ++)
@ -2482,10 +2482,10 @@ gtk_snapshot_append_repeating_linear_gradient (GtkSnapshot *snapshot,
{
graphene_point_t real_start_point, real_end_point;
real_start_point.x = scale_x * start_point->x + dx;
real_start_point.y = scale_y * start_point->y + dy;
real_end_point.x = scale_x * end_point->x + dx;
real_end_point.y = scale_y * end_point->y + dy;
real_start_point.x = start_point->x + dx;
real_start_point.y = start_point->y + dy;
real_end_point.x = end_point->x + dx;
real_end_point.y = end_point->y + dy;
node = gsk_repeating_linear_gradient_node_new (&real_bounds,
&real_start_point,