[gnome-shell/gnome-40] st/theme-node-drawing: Render box-shadow independently of background-color



commit c7880d06ab7936307869b9e24a4a25b3673e9a64
Author: Daniel van Vugt <daniel van vugt canonical com>
Date:   Thu May 27 17:12:15 2021 +0800

    st/theme-node-drawing: Render box-shadow independently of background-color
    
    Until now, the absence of a `background-color` would cause `box-shadow`s
    to be invisible. That was a bug because `box-shadow` is meant to be either
    the color specified in `box-shadow`, or if none was specified then the
    foreground `color`.
    
    There is nothing in the spec that says the `box-shadow` rendering should
    depend on `background-color`, so separate them. This ensures `box-shadow`
    is rendered even when `background-color` is absent or transparent.
    
    https://www.w3.org/TR/css-backgrounds-3/#box-shadow
    
    Part-of: <https://gitlab.gnome.org/GNOME/gnome-shell/-/merge_requests/1904>
    (cherry picked from commit 67217109328baea326d107cb6e73aeacffdbbcaf)

 src/st/st-theme-node-drawing.c | 31 +++++++++++++++++++++++++------
 1 file changed, 25 insertions(+), 6 deletions(-)
---
diff --git a/src/st/st-theme-node-drawing.c b/src/st/st-theme-node-drawing.c
index f839d990ed..b32c76be2f 100644
--- a/src/st/st-theme-node-drawing.c
+++ b/src/st/st-theme-node-drawing.c
@@ -51,6 +51,11 @@ typedef struct {
   float          resource_scale;
 } StCornerSpec;
 
+typedef enum {
+  ST_PAINT_BORDERS_MODE_COLOR,
+  ST_PAINT_BORDERS_MODE_SILHOUETTE
+} StPaintBordersMode;
+
 static void
 elliptical_arc (cairo_t *cr,
                 double   x_center,
@@ -409,7 +414,12 @@ st_theme_node_lookup_corner (StThemeNode    *node,
   if (corner.color.alpha == 0 &&
       corner.border_color_1.alpha == 0 &&
       corner.border_color_2.alpha == 0)
-    return NULL;
+    {
+      if (node->box_shadow == NULL)
+        return NULL;
+      else  /* We still need a corner texture to render the box-shadow */
+        corner.color = (ClutterColor) {0, 0, 0, 255};
+    }
 
   key = corner_to_string (&corner);
   texture = st_texture_cache_load (cache, key, ST_TEXTURE_CACHE_POLICY_FOREVER, load_corner, &corner, NULL);
@@ -1355,6 +1365,7 @@ st_theme_node_prerender_background (StThemeNode *node,
 static void st_theme_node_paint_borders (StThemeNodePaintState *state,
                                          CoglFramebuffer       *framebuffer,
                                          const ClutterActorBox *box,
+                                         StPaintBordersMode     mode,
                                          guint8                 paint_opacity);
 
 void
@@ -1580,7 +1591,7 @@ st_theme_node_render_resources (StThemeNodePaintState *state,
         state->box_shadow_pipeline = _st_create_shadow_pipeline (box_shadow_spec,
                                                                  state->prerendered_texture,
                                                                  state->resource_scale);
-      else if (node->background_color.alpha > 0 || has_border)
+      else
         st_theme_node_prerender_shadow (state);
     }
 
@@ -1697,6 +1708,7 @@ static void
 st_theme_node_paint_borders (StThemeNodePaintState *state,
                              CoglFramebuffer       *framebuffer,
                              const ClutterActorBox *box,
+                             StPaintBordersMode     mode,
                              guint8                 paint_opacity)
 {
   StThemeNode *node = state->node;
@@ -1708,6 +1720,7 @@ st_theme_node_paint_borders (StThemeNodePaintState *state,
   int corner_id, side_id;
   ClutterColor border_color;
   guint8 alpha;
+  gboolean corners_are_transparent;
 
   width = box->x2 - box->x1;
   height = box->y2 - box->y1;
@@ -1802,8 +1815,12 @@ st_theme_node_paint_borders (StThemeNodePaintState *state,
         }
     }
 
+  corners_are_transparent = mode == ST_PAINT_BORDERS_MODE_COLOR &&
+                            node->background_color.alpha == 0 &&
+                            node->border_color[0].alpha == 0;
+
   /* corners */
-  if (max_border_radius > 0 && paint_opacity > 0)
+  if (max_border_radius > 0 && paint_opacity > 0 && !corners_are_transparent)
     {
       for (corner_id = 0; corner_id < 4; corner_id++)
         {
@@ -1852,7 +1869,9 @@ st_theme_node_paint_borders (StThemeNodePaintState *state,
     }
 
   /* background color */
-  alpha = paint_opacity * node->background_color.alpha / 255;
+  alpha = mode == ST_PAINT_BORDERS_MODE_SILHOUETTE ?
+          255 :
+          paint_opacity * node->background_color.alpha / 255;
   if (alpha > 0)
     {
       st_theme_node_ensure_color_pipeline (node);
@@ -2307,7 +2326,7 @@ st_theme_node_prerender_shadow (StThemeNodePaintState *state)
                               state->resource_scale, 1);
       cogl_framebuffer_clear4f (framebuffer, COGL_BUFFER_BIT_COLOR, 0, 0, 0, 0);
 
-      st_theme_node_paint_borders (state, framebuffer, &box, 0xFF);
+      st_theme_node_paint_borders (state, framebuffer, &box, ST_PAINT_BORDERS_MODE_SILHOUETTE, 0xFF);
 
       state->box_shadow_pipeline = _st_create_shadow_pipeline (st_theme_node_get_box_shadow (node),
                                                                buffer, state->resource_scale);
@@ -2663,7 +2682,7 @@ st_theme_node_paint (StThemeNode           *node,
     }
   else
     {
-      st_theme_node_paint_borders (state, framebuffer, box, paint_opacity);
+      st_theme_node_paint_borders (state, framebuffer, box, ST_PAINT_BORDERS_MODE_COLOR, paint_opacity);
     }
 
   st_theme_node_paint_outline (node, framebuffer, box, paint_opacity);


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]