mirror of
https://gitlab.gnome.org/GNOME/gtk.git
synced 2024-12-25 13:11:13 +00:00
gpu: Change get_opaque() implementation of containers
We want to be able to express opaque grids. This means that the app provides either a row of columns of opaque nodes or a column of rows, and then the containers will magically figure it out. The main use case for this is terminals, which are uilt using cells. And when there's a transparent background configured but the contents are opaque, it'd be nice if we could figure that out. Also remove the 80% requirement. It is rather arbitrary and while it helps for some cases, the aforementioned grid would suffer.
This commit is contained in:
parent
e02de45537
commit
329dc9e0cf
@ -85,6 +85,81 @@ gsk_rect_intersection (const graphene_rect_t *r1,
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* gsk_rect_coverage:
|
||||
* @r1: a valid rectangle
|
||||
* @r2: another valid rectangle
|
||||
* @res: The result, may be one of r1/r2
|
||||
*
|
||||
* Computes the largest rectangle that is fully covered by
|
||||
* r1 and r2.
|
||||
*
|
||||
* Note that this is different from a union, which is the smallest
|
||||
* rectangle that covers the rectangles.
|
||||
*
|
||||
* The use case for this function is joining opaque rectangles.
|
||||
**/
|
||||
static inline void
|
||||
gsk_rect_coverage (const graphene_rect_t *r1,
|
||||
const graphene_rect_t *r2,
|
||||
graphene_rect_t *res)
|
||||
{
|
||||
float x1min, y1min, x2min, y2min;
|
||||
float x1max, y1max, x2max, y2max;
|
||||
float size, size2;
|
||||
graphene_rect_t r;
|
||||
|
||||
/* Assumes both rects are already normalized, as they usually are */
|
||||
size = r1->size.width * r1->size.height;
|
||||
size2 = r2->size.width * r2->size.height;
|
||||
if (size >= size2)
|
||||
{
|
||||
r = *r1;
|
||||
}
|
||||
else
|
||||
{
|
||||
r = *r2;
|
||||
size = size2;
|
||||
}
|
||||
|
||||
x1min = MIN (r1->origin.x, r2->origin.x);
|
||||
y1min = MIN (r1->origin.y, r2->origin.y);
|
||||
x1max = MAX (r1->origin.x, r2->origin.x);
|
||||
y1max = MAX (r1->origin.y, r2->origin.y);
|
||||
x2min = MIN (r1->origin.x + r1->size.width, r2->origin.x + r2->size.width);
|
||||
y2min = MIN (r1->origin.y + r1->size.height, r2->origin.y + r2->size.height);
|
||||
x2max = MAX (r1->origin.x + r1->size.width, r2->origin.x + r2->size.width);
|
||||
y2max = MAX (r1->origin.y + r1->size.height, r2->origin.y + r2->size.height);
|
||||
|
||||
if (x2min >= x1max)
|
||||
{
|
||||
float w, h;
|
||||
w = x2min - x1max;
|
||||
h = y2max - y1min;
|
||||
size2 = w * h;
|
||||
if (size2 > size)
|
||||
{
|
||||
r = GRAPHENE_RECT_INIT (x1max, y1min, w, h);
|
||||
size = size2;
|
||||
}
|
||||
}
|
||||
|
||||
if (y2min >= y1max)
|
||||
{
|
||||
float w, h;
|
||||
w = x2max - x1min;
|
||||
h = y2min - y1max;
|
||||
size2 = w * h;
|
||||
if (size2 > size)
|
||||
{
|
||||
r = GRAPHENE_RECT_INIT (x1min, y1max, w, h);
|
||||
size = size2;
|
||||
}
|
||||
}
|
||||
|
||||
*res = r;
|
||||
}
|
||||
|
||||
static inline gboolean G_GNUC_PURE
|
||||
gsk_rect_is_empty (const graphene_rect_t *rect)
|
||||
{
|
||||
|
@ -3315,7 +3315,6 @@ gsk_container_node_get_opaque_rect (GskRenderNode *node,
|
||||
{
|
||||
GskContainerNode *self = (GskContainerNode *) node;
|
||||
graphene_rect_t child_opaque;
|
||||
double size, child_size, desired_size;
|
||||
guint i;
|
||||
|
||||
for (i = 0; i < self->n_children; i++)
|
||||
@ -3327,28 +3326,12 @@ gsk_container_node_get_opaque_rect (GskRenderNode *node,
|
||||
if (i == self->n_children)
|
||||
return FALSE;
|
||||
|
||||
size = opaque->size.width * opaque->size.height;
|
||||
/* the 80% is random. I just want it to be low enough to catch
|
||||
* rounded corners, but not so small it catches on to .view
|
||||
* backgrounds for the smaller child of a paned.
|
||||
*/
|
||||
desired_size = node->bounds.size.width * node->bounds.size.height * 0.8;
|
||||
|
||||
for (i++; i < self->n_children; i++)
|
||||
{
|
||||
if (size >= desired_size)
|
||||
break;
|
||||
|
||||
if (!gsk_render_node_get_opaque_rect (self->children[i], &child_opaque))
|
||||
continue;
|
||||
|
||||
child_size = child_opaque.size.width * child_opaque.size.height;
|
||||
/* We allow == here because we want to find the topmost opaque child */
|
||||
if (child_size < size)
|
||||
continue;
|
||||
|
||||
*opaque = child_opaque;
|
||||
size = child_size;
|
||||
gsk_rect_coverage (opaque, &child_opaque, opaque);
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
|
26
testsuite/gsk/opaque/grid-0-0-100-100.node
Normal file
26
testsuite/gsk/opaque/grid-0-0-100-100.node
Normal file
@ -0,0 +1,26 @@
|
||||
/* the covered node */
|
||||
color {
|
||||
bounds: 30 30 40 40;
|
||||
color: black;
|
||||
}
|
||||
|
||||
container {
|
||||
color {
|
||||
bounds: 0 0 50 50;
|
||||
color: lime;
|
||||
}
|
||||
color {
|
||||
bounds: 50 0 50 50;
|
||||
color: red;
|
||||
}
|
||||
}
|
||||
container {
|
||||
color {
|
||||
bounds: 0 50 50 50;
|
||||
color: blue;
|
||||
}
|
||||
color {
|
||||
bounds: 50 50 50 50;
|
||||
color: yellow;
|
||||
}
|
||||
}
|
12
testsuite/gsk/opaque/horizontal-merge-0-0-100-50.node
Normal file
12
testsuite/gsk/opaque/horizontal-merge-0-0-100-50.node
Normal file
@ -0,0 +1,12 @@
|
||||
color {
|
||||
bounds: 0 0 25 50;
|
||||
}
|
||||
color {
|
||||
bounds: 25 0 25 50;
|
||||
}
|
||||
color {
|
||||
bounds: 50 0 25 50;
|
||||
}
|
||||
color {
|
||||
bounds: 75 0 25 50;
|
||||
}
|
@ -0,0 +1,12 @@
|
||||
color {
|
||||
bounds: 75 0 25 50;
|
||||
}
|
||||
color {
|
||||
bounds: 50 0 25 50;
|
||||
}
|
||||
color {
|
||||
bounds: 25 0 25 50;
|
||||
}
|
||||
color {
|
||||
bounds: 0 0 25 50;
|
||||
}
|
@ -0,0 +1,12 @@
|
||||
color {
|
||||
bounds: 75 0 50 50;
|
||||
}
|
||||
color {
|
||||
bounds: 50 0 50 50;
|
||||
}
|
||||
color {
|
||||
bounds: 25 0 50 50;
|
||||
}
|
||||
color {
|
||||
bounds: 0 0 50 50;
|
||||
}
|
@ -0,0 +1,12 @@
|
||||
color {
|
||||
bounds: 0 0 50 50;
|
||||
}
|
||||
color {
|
||||
bounds: 25 0 50 50;
|
||||
}
|
||||
color {
|
||||
bounds: 50 0 50 50;
|
||||
}
|
||||
color {
|
||||
bounds: 75 0 50 50;
|
||||
}
|
8
testsuite/gsk/opaque/horizontal-overlap-0-10-90-40.node
Normal file
8
testsuite/gsk/opaque/horizontal-overlap-0-10-90-40.node
Normal file
@ -0,0 +1,8 @@
|
||||
color {
|
||||
bounds: 0 0 50 50;
|
||||
color: lime;
|
||||
}
|
||||
color {
|
||||
bounds: 40 10 50 50;
|
||||
color: red;
|
||||
}
|
12
testsuite/gsk/opaque/vertical-merge-0-0-50-100.node
Normal file
12
testsuite/gsk/opaque/vertical-merge-0-0-50-100.node
Normal file
@ -0,0 +1,12 @@
|
||||
color {
|
||||
bounds: 0 0 50 25;
|
||||
}
|
||||
color {
|
||||
bounds: 0 25 50 25;
|
||||
}
|
||||
color {
|
||||
bounds: 0 50 50 25;
|
||||
}
|
||||
color {
|
||||
bounds: 0 75 50 25;
|
||||
}
|
@ -0,0 +1,12 @@
|
||||
color {
|
||||
bounds: 0 75 50 25;
|
||||
}
|
||||
color {
|
||||
bounds: 0 50 50 25;
|
||||
}
|
||||
color {
|
||||
bounds: 0 25 50 25;
|
||||
}
|
||||
color {
|
||||
bounds: 0 0 50 25;
|
||||
}
|
12
testsuite/gsk/opaque/vertical-merge-overlap-0-0-50-125.node
Normal file
12
testsuite/gsk/opaque/vertical-merge-overlap-0-0-50-125.node
Normal file
@ -0,0 +1,12 @@
|
||||
color {
|
||||
bounds: 0 0 50 50;
|
||||
}
|
||||
color {
|
||||
bounds: 0 25 50 50;
|
||||
}
|
||||
color {
|
||||
bounds: 0 50 50 50;
|
||||
}
|
||||
color {
|
||||
bounds: 0 75 50 50;
|
||||
}
|
8
testsuite/gsk/opaque/vertical-overlap-10-0-40-90.node
Normal file
8
testsuite/gsk/opaque/vertical-overlap-10-0-40-90.node
Normal file
@ -0,0 +1,8 @@
|
||||
color {
|
||||
bounds: 0 0 50 50;
|
||||
color: lime;
|
||||
}
|
||||
color {
|
||||
bounds: 10 40 50 50;
|
||||
color: red;
|
||||
}
|
Loading…
Reference in New Issue
Block a user