StThemeNodeDrawing: clear out node interior before filling pattern
If we aren't going to fill the content area of the node with a solid background color, then we need to clear it of any artifacts left over from drawing the border. https://bugzilla.gnome.org/show_bug.cgi?id=640465
This commit is contained in:
parent
740a946e72
commit
8c80a58fa4
@ -725,6 +725,8 @@ st_theme_node_render_background_with_border (StThemeNode *node)
|
|||||||
cairo_pattern_t *pattern = NULL;
|
cairo_pattern_t *pattern = NULL;
|
||||||
cairo_path_t *outline_path = NULL;
|
cairo_path_t *outline_path = NULL;
|
||||||
gboolean draw_solid_background = TRUE;
|
gboolean draw_solid_background = TRUE;
|
||||||
|
gboolean background_is_translucent;
|
||||||
|
gboolean interior_dirty;
|
||||||
gboolean draw_background_image_shadow = FALSE;
|
gboolean draw_background_image_shadow = FALSE;
|
||||||
gboolean has_visible_outline;
|
gboolean has_visible_outline;
|
||||||
ClutterColor border_color;
|
ClutterColor border_color;
|
||||||
@ -765,6 +767,12 @@ st_theme_node_render_background_with_border (StThemeNode *node)
|
|||||||
rowstride = cairo_format_stride_for_width (CAIRO_FORMAT_ARGB32,
|
rowstride = cairo_format_stride_for_width (CAIRO_FORMAT_ARGB32,
|
||||||
paint_box.x2 - paint_box.x1);
|
paint_box.x2 - paint_box.x1);
|
||||||
data = g_new0 (guchar, (paint_box.y2 - paint_box.y1) * rowstride);
|
data = g_new0 (guchar, (paint_box.y2 - paint_box.y1) * rowstride);
|
||||||
|
|
||||||
|
/* We zero initialize the destination memory, so it's fully transparent
|
||||||
|
* by default.
|
||||||
|
*/
|
||||||
|
interior_dirty = FALSE;
|
||||||
|
|
||||||
surface = cairo_image_surface_create_for_data (data,
|
surface = cairo_image_surface_create_for_data (data,
|
||||||
CAIRO_FORMAT_ARGB32,
|
CAIRO_FORMAT_ARGB32,
|
||||||
paint_box.x2 - paint_box.x1,
|
paint_box.x2 - paint_box.x1,
|
||||||
@ -789,6 +797,17 @@ st_theme_node_render_background_with_border (StThemeNode *node)
|
|||||||
{
|
{
|
||||||
pattern = create_cairo_pattern_of_background_gradient (node);
|
pattern = create_cairo_pattern_of_background_gradient (node);
|
||||||
draw_solid_background = FALSE;
|
draw_solid_background = FALSE;
|
||||||
|
|
||||||
|
/* If the gradient has any translucent areas, we need to
|
||||||
|
* erase the interior region before drawing, so that we show
|
||||||
|
* what's actually under the gradient and not whatever is
|
||||||
|
* left over from filling the border, etc.
|
||||||
|
*/
|
||||||
|
if (node->background_color.alpha < 255 ||
|
||||||
|
node->background_gradient_end.alpha < 255)
|
||||||
|
background_is_translucent = TRUE;
|
||||||
|
else
|
||||||
|
background_is_translucent = FALSE;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@ -803,11 +822,25 @@ st_theme_node_render_background_with_border (StThemeNode *node)
|
|||||||
if (shadow_spec && pattern != NULL)
|
if (shadow_spec && pattern != NULL)
|
||||||
draw_background_image_shadow = TRUE;
|
draw_background_image_shadow = TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* We never need to clear the interior region before drawing the
|
||||||
|
* background image, because it either always fills the entire area
|
||||||
|
* opaquely, or we draw the solid background behind it.
|
||||||
|
*/
|
||||||
|
background_is_translucent = FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (pattern == NULL)
|
if (pattern == NULL)
|
||||||
draw_solid_background = TRUE;
|
draw_solid_background = TRUE;
|
||||||
|
|
||||||
|
/* drawing the solid background implicitly clears the interior
|
||||||
|
* region, so if we're going to draw a solid background before drawing
|
||||||
|
* the background pattern, then we don't need to bother also clearing the
|
||||||
|
* background region.
|
||||||
|
*/
|
||||||
|
if (draw_solid_background)
|
||||||
|
background_is_translucent = FALSE;
|
||||||
|
|
||||||
has_visible_outline = st_theme_node_has_visible_outline (node);
|
has_visible_outline = st_theme_node_has_visible_outline (node);
|
||||||
|
|
||||||
/* Create a path for the background's outline first */
|
/* Create a path for the background's outline first */
|
||||||
@ -858,6 +891,11 @@ st_theme_node_render_background_with_border (StThemeNode *node)
|
|||||||
border_color.alpha / 255.);
|
border_color.alpha / 255.);
|
||||||
cairo_fill (cr);
|
cairo_fill (cr);
|
||||||
|
|
||||||
|
/* We were sloppy when filling in the border, and now the interior
|
||||||
|
* is filled with the border color, too.
|
||||||
|
*/
|
||||||
|
interior_dirty = TRUE;
|
||||||
|
|
||||||
if (radius[ST_CORNER_TOPLEFT] > MAX(border_width[ST_SIDE_TOP],
|
if (radius[ST_CORNER_TOPLEFT] > MAX(border_width[ST_SIDE_TOP],
|
||||||
border_width[ST_SIDE_LEFT]))
|
border_width[ST_SIDE_LEFT]))
|
||||||
elliptical_arc (cr,
|
elliptical_arc (cr,
|
||||||
@ -937,6 +975,13 @@ st_theme_node_render_background_with_border (StThemeNode *node)
|
|||||||
cairo_append_path (cr, outline_path);
|
cairo_append_path (cr, outline_path);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (interior_dirty && background_is_translucent)
|
||||||
|
{
|
||||||
|
cairo_set_operator (cr, CAIRO_OPERATOR_CLEAR);
|
||||||
|
cairo_fill_preserve (cr);
|
||||||
|
cairo_set_operator (cr, CAIRO_OPERATOR_OVER);
|
||||||
|
}
|
||||||
|
|
||||||
if (draw_solid_background)
|
if (draw_solid_background)
|
||||||
{
|
{
|
||||||
cairo_set_operator (cr, CAIRO_OPERATOR_SOURCE);
|
cairo_set_operator (cr, CAIRO_OPERATOR_SOURCE);
|
||||||
|
Loading…
Reference in New Issue
Block a user