rendernode: Scale repeat offscreens properly
authorBenjamin Otte <otte@redhat.com>
Mon, 5 Jun 2023 03:29:41 +0000 (05:29 +0200)
committerBenjamin Otte <otte@redhat.com>
Mon, 5 Jun 2023 03:33:07 +0000 (05:33 +0200)
Respect the matrix in use at time of encountering a repeat node so that
the offscreen uses roughly the same device pixel density as the target.

Fixes the handling of the clipped-repeat test.

gsk/gskrendernodeimpl.c

index 9a17de149adabaae77fc69b0d426a3df7effd2bb..33a317b735abb9479b17259c02699b05fa9087ef 100644 (file)
@@ -3956,13 +3956,19 @@ gsk_repeat_node_draw (GskRenderNode *node,
   cairo_pattern_t *pattern;
   cairo_surface_t *surface;
   cairo_t *surface_cr;
-  double scale_x, scale_y;
+  double scale_x, scale_y, width, height;
+  cairo_matrix_t matrix;
 
+  cairo_get_matrix (cr, &matrix);
+  width = ceil (self->child_bounds.size.width * (ABS (matrix.xx) + ABS (matrix.yx)));
+  height = ceil (self->child_bounds.size.height * (ABS (matrix.xy) + ABS (matrix.yy)));
   surface = cairo_surface_create_similar (cairo_get_target (cr),
                                           CAIRO_CONTENT_COLOR_ALPHA,
-                                          ceilf (self->child_bounds.size.width),
-                                          ceilf (self->child_bounds.size.height));
+                                          width, height);
   cairo_surface_get_device_scale (surface, &scale_x, &scale_y);
+  scale_x *= width / self->child_bounds.size.width;
+  scale_y *= height / self->child_bounds.size.height;
+  cairo_surface_set_device_scale (surface, scale_x, scale_y);
   cairo_surface_set_device_offset (surface, 
                                    - self->child_bounds.origin.x * scale_x,
                                    - self->child_bounds.origin.y * scale_y);