diff options
author | Timm Bäder <mail@baedert.org> | 2020-05-22 19:37:15 +0200 |
---|---|---|
committer | Timm Bäder <mail@baedert.org> | 2020-05-22 21:29:10 +0200 |
commit | f3ca814f3daac1a20ea483787179a83a4c92ebb4 (patch) | |
tree | 6a2dedb6abe866215d9d71305ca7b263a17b6678 | |
parent | 56a6120136e790e6190e53bf82648579b3d16083 (diff) | |
download | gtk+-f3ca814f3daac1a20ea483787179a83a4c92ebb4.tar.gz |
gl renderer: Fix some off-by-one and rounding errors in the shadow code
Take 24
Fixes #2759
-rw-r--r-- | gsk/gl/glutilsprivate.h | 12 | ||||
-rw-r--r-- | gsk/gl/gskglrenderer.c | 24 |
2 files changed, 19 insertions, 17 deletions
diff --git a/gsk/gl/glutilsprivate.h b/gsk/gl/glutilsprivate.h index fb2c67d11b..c2a67796b0 100644 --- a/gsk/gl/glutilsprivate.h +++ b/gsk/gl/glutilsprivate.h @@ -55,7 +55,7 @@ nine_slice_rounded_rect (const GskRoundedRect *rect, /* Top center */ out_rects[1] = (cairo_rectangle_int_t) { - origin->x + size->width / 2.0 - 1, origin->y, + origin->x + size->width / 2.0 - 0.5, origin->y, 1, top_height, }; @@ -73,15 +73,15 @@ nine_slice_rounded_rect (const GskRoundedRect *rect, /* center */ out_rects[4] = (cairo_rectangle_int_t) { - origin->x + size->width / 2.0, - origin->y + size->height / 2.0, + origin->x + size->width / 2.0 - 0.5, + origin->y + size->height / 2.0 - 0.5, 1, 1 }; /* Right center */ out_rects[5] = (cairo_rectangle_int_t) { origin->x + size->width - right_width, - origin->y + (size->height / 2.0), + origin->y + (size->height / 2.0) - 0.5, right_width, 1, }; @@ -94,7 +94,8 @@ nine_slice_rounded_rect (const GskRoundedRect *rect, /* Bottom center */ out_rects[7] = (cairo_rectangle_int_t) { - origin->x + (size->width / 2.0), origin->y + size->height - bottom_height, + origin->x + (size->width / 2.0) - 0.5, + origin->y + size->height - bottom_height, 1, bottom_height, }; @@ -136,7 +137,6 @@ nine_slice_grow (cairo_rectangle_int_t *slices, else slices[1].height += amount; - /* top right */ slices[2].y -= amount; if (amount > slices[2].width) diff --git a/gsk/gl/gskglrenderer.c b/gsk/gl/gskglrenderer.c index 288a015524..9780c51d55 100644 --- a/gsk/gl/gskglrenderer.c +++ b/gsk/gl/gskglrenderer.c @@ -1717,6 +1717,7 @@ render_outset_shadow_node (GskGLRenderer *self, const GdkRGBA *color = gsk_outset_shadow_node_peek_color (node); const float blur_radius = gsk_outset_shadow_node_get_blur_radius (node); const float blur_extra = blur_radius * 3; /* 3 Because we use that in the shader as well */ + const int extra_blur_pixels = (int) ceilf(blur_extra / 2.0 * scale); const float spread = gsk_outset_shadow_node_get_spread (node); const float dx = gsk_outset_shadow_node_get_dx (node); const float dy = gsk_outset_shadow_node_get_dy (node); @@ -1734,7 +1735,7 @@ render_outset_shadow_node (GskGLRenderer *self, /* Increase by the spread */ gsk_rounded_rect_shrink (&scaled_outline, -spread, -spread, -spread, -spread); /* Grow bounds but don't grow corners */ - graphene_rect_inset (&scaled_outline.bounds, - blur_extra / 2.0 * scale, - blur_extra / 2.0 * scale); + graphene_rect_inset (&scaled_outline.bounds, - extra_blur_pixels, - extra_blur_pixels); /* For the center part, we add a few pixels */ scaled_outline.bounds.size.width += SHADOW_EXTRA_SIZE; scaled_outline.bounds.size.height += SHADOW_EXTRA_SIZE; @@ -1742,11 +1743,10 @@ render_outset_shadow_node (GskGLRenderer *self, texture_width = (int)ceil ((scaled_outline.bounds.size.width + blur_extra) * scale); texture_height = (int)ceil ((scaled_outline.bounds.size.height + blur_extra) * scale); - scaled_outline.bounds.origin.x = blur_extra / 2.0 * scale; - scaled_outline.bounds.origin.y = blur_extra / 2.0 * scale; - scaled_outline.bounds.size.width = texture_width - (blur_extra * scale); - scaled_outline.bounds.size.height = texture_height - (blur_extra * scale); - + scaled_outline.bounds.origin.x = extra_blur_pixels; + scaled_outline.bounds.origin.y = extra_blur_pixels; + scaled_outline.bounds.size.width = texture_width - (extra_blur_pixels * 2); + scaled_outline.bounds.size.height = texture_height - (extra_blur_pixels * 2); for (int i = 0; i < 4; i ++) { @@ -1831,17 +1831,19 @@ render_outset_shadow_node (GskGLRenderer *self, shadow->outline = transform_rect (self, builder, outline); { - const float min_x = builder->dx + outline->bounds.origin.x - spread - (blur_extra / 2.0) + dx; - const float min_y = builder->dy + outline->bounds.origin.y - spread - (blur_extra / 2.0) + dy; - const float max_x = min_x + outline->bounds.size.width + (spread + (blur_extra / 2.0)) * 2; - const float max_y = min_y + outline->bounds.size.height + (spread + (blur_extra / 2.0)) * 2; + const float min_x = floorf (builder->dx + outline->bounds.origin.x - spread - (blur_extra / 2.0) + dx); + const float min_y = floorf (builder->dy + outline->bounds.origin.y - spread - (blur_extra / 2.0) + dy); + const float max_x = ceilf (builder->dx + outline->bounds.origin.x + outline->bounds.size.width + + (blur_extra / 2.0) + dx + spread); + const float max_y = ceilf (builder->dy + outline->bounds.origin.y + outline->bounds.size.height + + (blur_extra / 2.0) + dy + spread); float x1, x2, y1, y2, tx1, tx2, ty1, ty2; cairo_rectangle_int_t slices[9]; TextureRegion tregs[9]; /* TODO: The slicing never changes and could just go into the cache */ nine_slice_rounded_rect (&scaled_outline, slices); - nine_slice_grow (slices, blur_extra / 2.0 * scale); + nine_slice_grow (slices, extra_blur_pixels); nine_slice_to_texture_coords (slices, texture_width, texture_height, tregs); /* Our texture coordinates MUST be scaled, while the actual vertex coords |