StThemeNodeDrawing: generalize render_gradient to render_background_with_border
A lot of the border drawing logic in st_theme_node_render_gradient is applicable to other non-solid background types than gradients. This commit refactors that code so that support for other non-solid background types can be more easily integrated later. https://bugzilla.gnome.org/show_bug.cgi?id=636976
This commit is contained in:
parent
2b6d4ff279
commit
a7fa7d748d
@ -451,15 +451,54 @@ st_theme_node_has_visible_outline (StThemeNode *node)
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
static cairo_pattern_t *
|
||||
create_cairo_pattern_of_background_gradient (StThemeNode *node)
|
||||
{
|
||||
cairo_pattern_t *pattern;
|
||||
|
||||
g_return_val_if_fail (node->background_gradient_type != ST_GRADIENT_NONE,
|
||||
NULL);
|
||||
|
||||
if (node->background_gradient_type == ST_GRADIENT_VERTICAL)
|
||||
pattern = cairo_pattern_create_linear (0, 0, 0, node->alloc_height);
|
||||
else if (node->background_gradient_type == ST_GRADIENT_HORIZONTAL)
|
||||
pattern = cairo_pattern_create_linear (0, 0, node->alloc_width, 0);
|
||||
else
|
||||
{
|
||||
gdouble cx, cy;
|
||||
|
||||
cx = node->alloc_width / 2.;
|
||||
cy = node->alloc_height / 2.;
|
||||
pattern = cairo_pattern_create_radial (cx, cy, 0, cx, cy, MIN (cx, cy));
|
||||
}
|
||||
|
||||
cairo_pattern_add_color_stop_rgba (pattern, 0,
|
||||
node->background_color.red / 255.,
|
||||
node->background_color.green / 255.,
|
||||
node->background_color.blue / 255.,
|
||||
node->background_color.alpha / 255.);
|
||||
cairo_pattern_add_color_stop_rgba (pattern, 1,
|
||||
node->background_gradient_end.red / 255.,
|
||||
node->background_gradient_end.green / 255.,
|
||||
node->background_gradient_end.blue / 255.,
|
||||
node->background_gradient_end.alpha / 255.);
|
||||
return pattern;
|
||||
}
|
||||
|
||||
/* In order for borders to be smoothly blended with non-solid backgrounds,
|
||||
* we need to use cairo. This function is a slow fallback path for those
|
||||
* cases. It currently only supports gradients, however.
|
||||
*/
|
||||
static CoglHandle
|
||||
st_theme_node_render_gradient (StThemeNode *node)
|
||||
st_theme_node_render_background_with_border (StThemeNode *node)
|
||||
{
|
||||
StBorderImage *border_image;
|
||||
CoglHandle texture;
|
||||
int radius[4], i;
|
||||
cairo_t *cr;
|
||||
cairo_surface_t *surface;
|
||||
cairo_pattern_t *pattern;
|
||||
cairo_pattern_t *pattern = NULL;
|
||||
gboolean draw_solid_background;
|
||||
ClutterColor border_color;
|
||||
int border_width[4];
|
||||
guint rowstride;
|
||||
@ -486,30 +525,17 @@ st_theme_node_render_gradient (StThemeNode *node)
|
||||
radius[i] = st_theme_node_get_border_radius (node, i);
|
||||
}
|
||||
|
||||
if (node->background_gradient_type == ST_GRADIENT_VERTICAL)
|
||||
pattern = cairo_pattern_create_linear (0, 0, 0, node->alloc_height);
|
||||
else if (node->background_gradient_type == ST_GRADIENT_HORIZONTAL)
|
||||
pattern = cairo_pattern_create_linear (0, 0, node->alloc_width, 0);
|
||||
if (node->background_gradient_type != ST_GRADIENT_NONE)
|
||||
{
|
||||
pattern = create_cairo_pattern_of_background_gradient (node);
|
||||
draw_solid_background = FALSE;
|
||||
}
|
||||
else
|
||||
{
|
||||
gdouble cx, cy;
|
||||
|
||||
cx = node->alloc_width / 2.;
|
||||
cy = node->alloc_height / 2.;
|
||||
pattern = cairo_pattern_create_radial (cx, cy, 0, cx, cy, MIN (cx, cy));
|
||||
g_warning ("st_theme_node_render_background_with_border called with non-gradient background (which isn't yet supported). Falling back to solid background color.");
|
||||
draw_solid_background = TRUE;
|
||||
}
|
||||
|
||||
cairo_pattern_add_color_stop_rgba (pattern, 0,
|
||||
node->background_color.red / 255.,
|
||||
node->background_color.green / 255.,
|
||||
node->background_color.blue / 255.,
|
||||
node->background_color.alpha / 255.);
|
||||
cairo_pattern_add_color_stop_rgba (pattern, 1,
|
||||
node->background_gradient_end.red / 255.,
|
||||
node->background_gradient_end.green / 255.,
|
||||
node->background_gradient_end.blue / 255.,
|
||||
node->background_gradient_end.alpha / 255.);
|
||||
|
||||
/* Create a path for the background's outline first */
|
||||
if (radius[ST_CORNER_TOPLEFT] > 0)
|
||||
cairo_arc (cr,
|
||||
@ -538,11 +564,10 @@ st_theme_node_render_gradient (StThemeNode *node)
|
||||
radius[ST_CORNER_BOTTOMLEFT], M_PI / 2, M_PI);
|
||||
cairo_close_path (cr);
|
||||
|
||||
|
||||
/* If we have a solid border, we fill the outline with the border
|
||||
* color and create the inline shape for the background gradient;
|
||||
/* If we have a solid border, we fill the outline shape with the border
|
||||
* color and create the inline shape for the background;
|
||||
* otherwise the outline shape is filled with the background
|
||||
* gradient directly
|
||||
* directly
|
||||
*/
|
||||
if (border_image == NULL &&
|
||||
(border_width[ST_SIDE_TOP] > 0 ||
|
||||
@ -624,10 +649,22 @@ st_theme_node_render_gradient (StThemeNode *node)
|
||||
cairo_close_path (cr);
|
||||
}
|
||||
|
||||
cairo_set_source (cr, pattern);
|
||||
cairo_fill (cr);
|
||||
if (draw_solid_background)
|
||||
{
|
||||
cairo_set_source_rgba (cr,
|
||||
node->background_color.red / 255.,
|
||||
node->background_color.green / 255.,
|
||||
node->background_color.blue / 255.,
|
||||
node->background_color.alpha / 255.);
|
||||
cairo_fill_preserve (cr);
|
||||
}
|
||||
|
||||
cairo_pattern_destroy (pattern);
|
||||
if (pattern != NULL)
|
||||
{
|
||||
cairo_set_source (cr, pattern);
|
||||
cairo_fill (cr);
|
||||
cairo_pattern_destroy (pattern);
|
||||
}
|
||||
|
||||
texture = cogl_texture_new_from_data (node->alloc_width, node->alloc_height,
|
||||
COGL_TEXTURE_NONE,
|
||||
@ -741,7 +778,7 @@ st_theme_node_render_resources (StThemeNode *node,
|
||||
}
|
||||
|
||||
if (node->background_gradient_type != ST_GRADIENT_NONE)
|
||||
node->prerendered_texture = st_theme_node_render_gradient (node);
|
||||
node->prerendered_texture = st_theme_node_render_background_with_border (node);
|
||||
|
||||
if (node->border_slices_texture)
|
||||
node->border_slices_material = _st_create_texture_material (node->border_slices_texture);
|
||||
|
Loading…
Reference in New Issue
Block a user