Merge branch 'normalize-node-bounds' into 'main'

Add gsk_rect_normalize

Closes #6435

See merge request GNOME/gtk!6901
This commit is contained in:
Matthias Clasen 2024-02-14 02:08:11 +00:00
commit 69500f356e
4 changed files with 126 additions and 3 deletions

View File

@ -159,3 +159,23 @@ gsk_rect_scale (const graphene_rect_t *r,
res->size.width = r->size.width * sx;
res->size.height = r->size.height * sy;
}
static inline void
gsk_rect_normalize (graphene_rect_t *r)
{
if (r->size.width < 0.f)
{
float size = fabsf (r->size.width);
r->origin.x -= size;
r->size.width = size;
}
if (r->size.height < 0.f)
{
float size = fabsf (r->size.height);
r->origin.y -= size;
r->size.height = size;
}
}

View File

@ -234,6 +234,7 @@ gsk_color_node_new (const GdkRGBA *rgba,
self->color = *rgba;
gsk_rect_init_from_rect (&node->bounds, bounds);
gsk_rect_normalize (&node->bounds);
return node;
}
@ -420,6 +421,7 @@ gsk_linear_gradient_node_new (const graphene_rect_t *bounds,
node->offscreen_for_opacity = FALSE;
gsk_rect_init_from_rect (&node->bounds, bounds);
gsk_rect_normalize (&node->bounds);
graphene_point_init_from_point (&self->start, start);
graphene_point_init_from_point (&self->end, end);
@ -473,6 +475,7 @@ gsk_repeating_linear_gradient_node_new (const graphene_rect_t *bounds,
node->offscreen_for_opacity = FALSE;
gsk_rect_init_from_rect (&node->bounds, bounds);
gsk_rect_normalize (&node->bounds);
graphene_point_init_from_point (&self->start, start);
graphene_point_init_from_point (&self->end, end);
@ -765,6 +768,7 @@ gsk_radial_gradient_node_new (const graphene_rect_t *bounds,
node->offscreen_for_opacity = FALSE;
gsk_rect_init_from_rect (&node->bounds, bounds);
gsk_rect_normalize (&node->bounds);
graphene_point_init_from_point (&self->center, center);
self->hradius = hradius;
@ -834,6 +838,7 @@ gsk_repeating_radial_gradient_node_new (const graphene_rect_t *bounds,
node->offscreen_for_opacity = FALSE;
gsk_rect_init_from_rect (&node->bounds, bounds);
gsk_rect_normalize (&node->bounds);
graphene_point_init_from_point (&self->center, center);
self->hradius = hradius;
@ -1227,6 +1232,7 @@ gsk_conic_gradient_node_new (const graphene_rect_t *bounds,
node->offscreen_for_opacity = FALSE;
gsk_rect_init_from_rect (&node->bounds, bounds);
gsk_rect_normalize (&node->bounds);
graphene_point_init_from_point (&self->center, center);
self->rotation = rotation;
@ -1872,6 +1878,7 @@ gsk_texture_node_new (GdkTexture *texture,
self->texture = g_object_ref (texture);
gsk_rect_init_from_rect (&node->bounds, bounds);
gsk_rect_normalize (&node->bounds);
node->preferred_depth = gdk_memory_format_get_depth (gdk_texture_get_format (texture));
@ -2089,6 +2096,7 @@ gsk_texture_scale_node_new (GdkTexture *texture,
self->texture = g_object_ref (texture);
gsk_rect_init_from_rect (&node->bounds, bounds);
gsk_rect_normalize (&node->bounds);
self->filter = filter;
node->preferred_depth = gdk_memory_format_get_depth (gdk_texture_get_format (texture));
@ -3077,6 +3085,7 @@ gsk_cairo_node_new (const graphene_rect_t *bounds)
node->offscreen_for_opacity = FALSE;
gsk_rect_init_from_rect (&node->bounds, bounds);
gsk_rect_normalize (&node->bounds);
return node;
}
@ -4279,13 +4288,19 @@ gsk_repeat_node_new (const graphene_rect_t *bounds,
node->offscreen_for_opacity = TRUE;
gsk_rect_init_from_rect (&node->bounds, bounds);
gsk_rect_normalize (&node->bounds);
self->child = gsk_render_node_ref (child);
if (child_bounds)
gsk_rect_init_from_rect (&self->child_bounds, child_bounds);
{
gsk_rect_init_from_rect (&self->child_bounds, child_bounds);
gsk_rect_normalize (&self->child_bounds);
}
else
gsk_rect_init_from_rect (&self->child_bounds, &child->bounds);
{
gsk_rect_init_from_rect (&self->child_bounds, &child->bounds);
}
node->preferred_depth = gsk_render_node_get_preferred_depth (child);
@ -4431,7 +4446,8 @@ gsk_clip_node_new (GskRenderNode *child,
node->offscreen_for_opacity = child->offscreen_for_opacity;
self->child = gsk_render_node_ref (child);
graphene_rect_normalize_r (clip, &self->clip);
gsk_rect_init_from_rect (&self->clip, clip);
gsk_rect_normalize (&self->clip);
gsk_rect_intersection (&self->clip, &child->bounds, &node->bounds);
@ -6820,6 +6836,8 @@ gsk_gl_shader_node_new (GskGLShader *shader,
node->offscreen_for_opacity = TRUE;
gsk_rect_init_from_rect (&node->bounds, bounds);
gsk_rect_normalize (&node->bounds);
self->shader = g_object_ref (shader);
self->args = g_bytes_ref (args);

View File

@ -453,6 +453,7 @@ if os_linux
endif
tests = [
[ 'normalize', [ 'normalize.c', '../reftests/reftest-compare.c' ] ],
[ 'transform' ],
[ 'shader' ],
[ 'path', [ 'path-utils.c' ] ],

84
testsuite/gsk/normalize.c Normal file
View File

@ -0,0 +1,84 @@
#include <gtk/gtk.h>
#include "gsk/gskrectprivate.h"
#include "../reftests/reftest-compare.h"
static void
test_normalize (GskRenderNode *node1,
GskRenderNode *node2)
{
GskRenderer *renderer = gsk_ngl_renderer_new ();
graphene_rect_t bounds1, bounds2;
GdkTexture *texture1, *texture2, *diff;
GError *error = NULL;
gsk_renderer_realize_for_display (renderer, gdk_display_get_default (), &error);
g_assert_no_error (error);
gsk_render_node_get_bounds (node1, &bounds1);
gsk_render_node_get_bounds (node2, &bounds2);
texture1 = gsk_renderer_render_texture (renderer, node1, &bounds1);
texture2 = gsk_renderer_render_texture (renderer, node2, &bounds2);
diff = reftest_compare_textures (texture1, texture2);
g_assert_null (diff);
g_object_unref (texture1);
g_object_unref (texture2);
gsk_renderer_unrealize (renderer);
g_object_unref (renderer);
}
static void
test_normalize_color (void)
{
GskRenderNode *node1, *node2;
GdkRGBA red = { 1, 0, 0, 1 };
node1 = gsk_color_node_new (&red, &GRAPHENE_RECT_INIT (0, 0, 100, 100));
node2 = gsk_color_node_new (&red, &GRAPHENE_RECT_INIT (0, 100, 100, -100));
test_normalize (node1, node2);
gsk_render_node_unref (node1);
gsk_render_node_unref (node2);
}
static void
test_normalize_linear_gradient (void)
{
GskRenderNode *node1, *node2;
GskColorStop stops[] = {
{ 0, { 1, 0, 0, 1 } },
{ 1, { 0, 0, 1, 1 } },
};
node1 = gsk_linear_gradient_node_new (&GRAPHENE_RECT_INIT (0, 0, 100, 100),
&GRAPHENE_POINT_INIT (0, 0),
&GRAPHENE_POINT_INIT (100, 100),
stops,
G_N_ELEMENTS (stops));
node2 = gsk_linear_gradient_node_new (&GRAPHENE_RECT_INIT (0, 100, 100, -100),
&GRAPHENE_POINT_INIT (0, 0),
&GRAPHENE_POINT_INIT (100, 100),
stops,
G_N_ELEMENTS (stops));
test_normalize (node1, node2);
gsk_render_node_unref (node1);
gsk_render_node_unref (node2);
}
int
main (int argc, char *argv[])
{
g_test_init (&argc, &argv, NULL);
gtk_init ();
g_test_add_func ("/node/normalize/color", test_normalize_color);
g_test_add_func ("/node/normalize/linear-gradient", test_normalize_linear_gradient);
return g_test_run ();
}