mirror of
https://gitlab.gnome.org/GNOME/gtk.git
synced 2024-12-27 06:00:22 +00:00
Merge branch 'cairo-borders-fixage' into 'master'
Cairo borders fixage See merge request GNOME/gtk!765
This commit is contained in:
commit
08c84bc830
@ -514,6 +514,30 @@ gsk_border_node_finalize (GskRenderNode *node)
|
||||
{
|
||||
}
|
||||
|
||||
static void
|
||||
gsk_border_node_mesh_add_patch (cairo_pattern_t *pattern,
|
||||
const GdkRGBA *color,
|
||||
double x0,
|
||||
double y0,
|
||||
double x1,
|
||||
double y1,
|
||||
double x2,
|
||||
double y2,
|
||||
double x3,
|
||||
double y3)
|
||||
{
|
||||
cairo_mesh_pattern_begin_patch (pattern);
|
||||
cairo_mesh_pattern_move_to (pattern, x0, y0);
|
||||
cairo_mesh_pattern_line_to (pattern, x1, y1);
|
||||
cairo_mesh_pattern_line_to (pattern, x2, y2);
|
||||
cairo_mesh_pattern_line_to (pattern, x3, y3);
|
||||
cairo_mesh_pattern_set_corner_color_rgba (pattern, 0, color->red, color->green, color->blue, color->alpha);
|
||||
cairo_mesh_pattern_set_corner_color_rgba (pattern, 1, color->red, color->green, color->blue, color->alpha);
|
||||
cairo_mesh_pattern_set_corner_color_rgba (pattern, 2, color->red, color->green, color->blue, color->alpha);
|
||||
cairo_mesh_pattern_set_corner_color_rgba (pattern, 3, color->red, color->green, color->blue, color->alpha);
|
||||
cairo_mesh_pattern_end_patch (pattern);
|
||||
}
|
||||
|
||||
static void
|
||||
gsk_border_node_draw (GskRenderNode *node,
|
||||
cairo_t *cr)
|
||||
@ -537,59 +561,82 @@ gsk_border_node_draw (GskRenderNode *node,
|
||||
gdk_rgba_equal (&self->border_color[0], &self->border_color[3]))
|
||||
{
|
||||
gdk_cairo_set_source_rgba (cr, &self->border_color[0]);
|
||||
cairo_fill (cr);
|
||||
}
|
||||
else
|
||||
{
|
||||
const graphene_rect_t *bounds = &self->outline.bounds;
|
||||
/* distance to center "line":
|
||||
* +-------------------------+
|
||||
* | |
|
||||
* | |
|
||||
* | ---this-line--- |
|
||||
* | |
|
||||
* | |
|
||||
* +-------------------------+
|
||||
* That line is equidistant from all sides. It's either horiontal
|
||||
* or vertical, depending on if the rect is wider or taller.
|
||||
* We use the 4 sides spanned up by connecting the line to the corner
|
||||
* points to color the regions of the rectangle differently.
|
||||
* Note that the call to cairo_fill() will add the potential final
|
||||
* segment by closing the path, so we don't have to care.
|
||||
*/
|
||||
float dst = MIN (bounds->size.width, bounds->size.height) / 2.0;
|
||||
cairo_pattern_t *mesh;
|
||||
cairo_matrix_t mat;
|
||||
|
||||
cairo_clip (cr);
|
||||
mesh = cairo_pattern_create_mesh ();
|
||||
cairo_matrix_init_translate (&mat, -bounds->origin.x, -bounds->origin.y);
|
||||
cairo_pattern_set_matrix (mesh, &mat);
|
||||
|
||||
/* Top */
|
||||
if (self->border_width[0] > 0)
|
||||
{
|
||||
cairo_move_to (cr, bounds->origin.x, bounds->origin.y);
|
||||
cairo_rel_line_to (cr, self->border_width[3], self->border_width[0]);
|
||||
cairo_rel_line_to (cr, bounds->size.width - self->border_width[3] - self->border_width[1], 0);
|
||||
cairo_rel_line_to (cr, self->border_width[1], - self->border_width[0]);
|
||||
gdk_cairo_set_source_rgba (cr, &self->border_color[0]);
|
||||
cairo_fill (cr);
|
||||
gsk_border_node_mesh_add_patch (mesh,
|
||||
&self->border_color[0],
|
||||
0, 0,
|
||||
dst * self->border_width[3] / self->border_width[0], dst,
|
||||
bounds->size.width - dst * self->border_width[1] / self->border_width[0], dst,
|
||||
bounds->size.width, 0);
|
||||
}
|
||||
|
||||
/* Right */
|
||||
if (self->border_width[1] > 0)
|
||||
{
|
||||
cairo_move_to (cr, bounds->origin.x + bounds->size.width, bounds->origin.y);
|
||||
cairo_rel_line_to (cr, - self->border_width[1], self->border_width[0]);
|
||||
cairo_rel_line_to (cr, 0, bounds->size.height - self->border_width[0] - self->border_width[2]);
|
||||
cairo_rel_line_to (cr, self->border_width[1], self->border_width[2]);
|
||||
gdk_cairo_set_source_rgba (cr, &self->border_color[1]);
|
||||
cairo_fill (cr);
|
||||
gsk_border_node_mesh_add_patch (mesh,
|
||||
&self->border_color[1],
|
||||
bounds->size.width, 0,
|
||||
bounds->size.width - dst, dst * self->border_width[0] / self->border_width[1],
|
||||
bounds->size.width - dst, bounds->size.height - dst * self->border_width[2] / self->border_width[1],
|
||||
bounds->size.width, bounds->size.height);
|
||||
}
|
||||
|
||||
/* Bottom */
|
||||
if (self->border_width[2] > 0)
|
||||
{
|
||||
cairo_move_to (cr, bounds->origin.x, bounds->origin.y + bounds->size.height);
|
||||
cairo_rel_line_to (cr, self->border_width[3], - self->border_width[2]);
|
||||
cairo_rel_line_to (cr, bounds->size.width - self->border_width[3] - self->border_width[1], 0);
|
||||
cairo_rel_line_to (cr, self->border_width[1], self->border_width[2]);
|
||||
gdk_cairo_set_source_rgba (cr, &self->border_color[2]);
|
||||
cairo_fill (cr);
|
||||
gsk_border_node_mesh_add_patch (mesh,
|
||||
&self->border_color[2],
|
||||
0, bounds->size.height,
|
||||
dst * self->border_width[3] / self->border_width[2], bounds->size.height - dst,
|
||||
bounds->size.width - dst * self->border_width[1] / self->border_width[2], bounds->size.height - dst,
|
||||
bounds->size.width, bounds->size.height);
|
||||
}
|
||||
|
||||
/* Left */
|
||||
if (self->border_width[3] > 0)
|
||||
{
|
||||
cairo_move_to (cr, bounds->origin.x, bounds->origin.y);
|
||||
cairo_rel_line_to (cr, self->border_width[3], self->border_width[0]);
|
||||
cairo_rel_line_to (cr, 0, bounds->size.height - self->border_width[0] - self->border_width[2]);
|
||||
cairo_rel_line_to (cr, - self->border_width[3], self->border_width[2]);
|
||||
gdk_cairo_set_source_rgba (cr, &self->border_color[3]);
|
||||
cairo_fill (cr);
|
||||
gsk_border_node_mesh_add_patch (mesh,
|
||||
&self->border_color[3],
|
||||
0, 0,
|
||||
dst, dst * self->border_width[0] / self->border_width[3],
|
||||
dst, bounds->size.height - dst * self->border_width[2] / self->border_width[3],
|
||||
0, bounds->size.height);
|
||||
}
|
||||
|
||||
cairo_set_source (cr, mesh);
|
||||
cairo_pattern_destroy (mesh);
|
||||
}
|
||||
|
||||
cairo_fill (cr);
|
||||
cairo_restore (cr);
|
||||
}
|
||||
|
||||
|
@ -325,6 +325,9 @@ testdata = [
|
||||
'paned-undersized.css',
|
||||
'paned-undersized.ref.ui',
|
||||
'paned-undersized.ui',
|
||||
'partial-rounded-border.css',
|
||||
'partial-rounded-border.ref.ui',
|
||||
'partial-rounded-border.ui',
|
||||
'picture-load-invalid-file.ui',
|
||||
'picture-load-invalid-file.ref.ui',
|
||||
'pseudoclass-on-box.css',
|
||||
|
40
testsuite/reftests/partial-rounded-border.css
Normal file
40
testsuite/reftests/partial-rounded-border.css
Normal file
@ -0,0 +1,40 @@
|
||||
* {
|
||||
all: unset;
|
||||
}
|
||||
|
||||
.background {
|
||||
background-color: red;
|
||||
}
|
||||
|
||||
button {
|
||||
padding: 10px;
|
||||
}
|
||||
|
||||
#topleft {
|
||||
border-top-left-radius: 20px;
|
||||
border-left: 5px solid blue;
|
||||
border-top: 5px solid blue;
|
||||
}
|
||||
|
||||
#topright {
|
||||
border-top-right-radius: 20px;
|
||||
border-right: 5px solid blue;
|
||||
border-top: 5px solid blue;
|
||||
}
|
||||
|
||||
#bottomleft {
|
||||
border-bottom-left-radius: 20px;
|
||||
border-left: 5px solid blue;
|
||||
border-bottom: 5px solid blue;
|
||||
}
|
||||
|
||||
#bottomright {
|
||||
border-bottom-right-radius: 20px;
|
||||
border-right: 5px solid blue;
|
||||
border-bottom: 5px solid blue;
|
||||
}
|
||||
|
||||
#reference {
|
||||
border: 5px solid blue;
|
||||
border-radius: 20px;
|
||||
}
|
47
testsuite/reftests/partial-rounded-border.ref.ui
Normal file
47
testsuite/reftests/partial-rounded-border.ref.ui
Normal file
@ -0,0 +1,47 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<interface>
|
||||
<object class="GtkWindow">
|
||||
<property name="type">popup</property>
|
||||
<child>
|
||||
<object class="GtkGrid">
|
||||
<property name="name">reference</property>
|
||||
<child>
|
||||
<object class="GtkButton">
|
||||
<property name="label">topleft</property>
|
||||
<layout>
|
||||
<property name="left-attach">0</property>
|
||||
<property name="top-attach">0</property>
|
||||
</layout>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkButton">
|
||||
<property name="label">topright</property>
|
||||
<layout>
|
||||
<property name="left-attach">1</property>
|
||||
<property name="top-attach">0</property>
|
||||
</layout>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkButton">
|
||||
<property name="label">bottomleft</property>
|
||||
<layout>
|
||||
<property name="left-attach">0</property>
|
||||
<property name="top-attach">1</property>
|
||||
</layout>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkButton">
|
||||
<property name="label">bottomright</property>
|
||||
<layout>
|
||||
<property name="left-attach">1</property>
|
||||
<property name="top-attach">1</property>
|
||||
</layout>
|
||||
</object>
|
||||
</child>
|
||||
</object>
|
||||
</child>
|
||||
</object>
|
||||
</interface>
|
50
testsuite/reftests/partial-rounded-border.ui
Normal file
50
testsuite/reftests/partial-rounded-border.ui
Normal file
@ -0,0 +1,50 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<interface>
|
||||
<object class="GtkWindow">
|
||||
<property name="type">popup</property>
|
||||
<child>
|
||||
<object class="GtkGrid">
|
||||
<child>
|
||||
<object class="GtkButton">
|
||||
<property name="label">topleft</property>
|
||||
<property name="name">topleft</property>
|
||||
<layout>
|
||||
<property name="left-attach">0</property>
|
||||
<property name="top-attach">0</property>
|
||||
</layout>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkButton">
|
||||
<property name="label">topright</property>
|
||||
<property name="name">topright</property>
|
||||
<layout>
|
||||
<property name="left-attach">1</property>
|
||||
<property name="top-attach">0</property>
|
||||
</layout>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkButton">
|
||||
<property name="label">bottomleft</property>
|
||||
<property name="name">bottomleft</property>
|
||||
<layout>
|
||||
<property name="left-attach">0</property>
|
||||
<property name="top-attach">1</property>
|
||||
</layout>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkButton">
|
||||
<property name="label">bottomright</property>
|
||||
<property name="name">bottomright</property>
|
||||
<layout>
|
||||
<property name="left-attach">1</property>
|
||||
<property name="top-attach">1</property>
|
||||
</layout>
|
||||
</object>
|
||||
</child>
|
||||
</object>
|
||||
</child>
|
||||
</object>
|
||||
</interface>
|
Loading…
Reference in New Issue
Block a user