[gtk/matthiasc/css-values: 4/4] wip: static values



commit d5ca163e2efe0a60fe79287010a195cfc2f7fc19
Author: Matthias Clasen <mclasen redhat com>
Date:   Fri Jan 10 10:04:22 2020 -0500

    wip: static values
    
    Determine whether a css value is 'static' at creation
    time. Static values don't need to have compute() called,
    since their value is always the same, so we can just
    ref them.

 gtk/gtkcssarrayvalue.c         |  15 +++-
 gtk/gtkcssbgsizevalue.c        |   6 +-
 gtk/gtkcsscolorvalue.c         |   7 +-
 gtk/gtkcssdimensionvalue.c     |  72 ++++++++++-------
 gtk/gtkcsseasevalue.c          |   2 +
 gtk/gtkcssenumvalue.c          | 172 ++++++++++++++++++++---------------------
 gtk/gtkcssfiltervalue.c        |  15 +++-
 gtk/gtkcssiconthemevalue.c     |   2 +-
 gtk/gtkcssimagevalue.c         |   4 +-
 gtk/gtkcssnumbervalueprivate.h |   3 +-
 gtk/gtkcsspositionvalue.c      |   1 +
 gtk/gtkcssrgbavalue.c          |   8 +-
 gtk/gtkcssshadowsvalue.c       |  15 +++-
 gtk/gtkcssshadowvalue.c        |   6 ++
 gtk/gtkcssstringvalue.c        |   2 +
 gtk/gtkcssstylepropertyimpl.c  |   3 +-
 gtk/gtkcsstransformvalue.c     |  33 +++++++-
 gtk/gtkcssvalue.c              |   6 +-
 gtk/gtkcssvalueprivate.h       |   3 +-
 19 files changed, 238 insertions(+), 137 deletions(-)
---
diff --git a/gtk/gtkcssarrayvalue.c b/gtk/gtkcssarrayvalue.c
index 02ece79fbd..889c4da01b 100644
--- a/gtk/gtkcssarrayvalue.c
+++ b/gtk/gtkcssarrayvalue.c
@@ -392,14 +392,27 @@ _gtk_css_array_value_new_from_array (GtkCssValue **values,
                                      guint         n_values)
 {
   GtkCssValue *result;
+  gboolean is_static;
+  int i;
            
   g_return_val_if_fail (values != NULL, NULL);
   g_return_val_if_fail (n_values > 0, NULL);
 
   if (n_values == 1)
     return values[0];
-         
+
+  is_static = TRUE;
+  for (i = 0; i < n_values; i++)
+    {
+      if (!values[i]->is_static)
+        {
+          is_static = FALSE;
+          break;
+        }
+   }
+
   result = _gtk_css_value_alloc (&GTK_CSS_VALUE_ARRAY, sizeof (GtkCssValue) + sizeof (GtkCssValue *) * 
(n_values - 1));
+  result->is_static = is_static;
   result->n_values = n_values;
   memcpy (&result->values[0], values, sizeof (GtkCssValue *) * n_values);
             
diff --git a/gtk/gtkcssbgsizevalue.c b/gtk/gtkcssbgsizevalue.c
index 7b9c0d1c10..c64234b705 100644
--- a/gtk/gtkcssbgsizevalue.c
+++ b/gtk/gtkcssbgsizevalue.c
@@ -163,9 +163,9 @@ static const GtkCssValueClass GTK_CSS_VALUE_BG_SIZE = {
   gtk_css_value_bg_size_print
 };
 
-static GtkCssValue auto_singleton = { &GTK_CSS_VALUE_BG_SIZE, 1, FALSE, FALSE, NULL, NULL };
-static GtkCssValue cover_singleton = { &GTK_CSS_VALUE_BG_SIZE, 1, TRUE, FALSE, NULL, NULL };
-static GtkCssValue contain_singleton = { &GTK_CSS_VALUE_BG_SIZE, 1, FALSE, TRUE, NULL, NULL };
+static GtkCssValue auto_singleton = { &GTK_CSS_VALUE_BG_SIZE, 1, 0, FALSE, FALSE, NULL, NULL };
+static GtkCssValue cover_singleton = { &GTK_CSS_VALUE_BG_SIZE, 1, 0, TRUE, FALSE, NULL, NULL };
+static GtkCssValue contain_singleton = { &GTK_CSS_VALUE_BG_SIZE, 1, 0, FALSE, TRUE, NULL, NULL };
 
 GtkCssValue *
 _gtk_css_bg_size_value_new (GtkCssValue *x,
diff --git a/gtk/gtkcsscolorvalue.c b/gtk/gtkcsscolorvalue.c
index 450bf9f0ca..410beded8b 100644
--- a/gtk/gtkcsscolorvalue.c
+++ b/gtk/gtkcsscolorvalue.c
@@ -465,9 +465,9 @@ _gtk_css_color_value_resolve (GtkCssValue      *color,
   return value;
 }
 
-static GtkCssValue transparent_black_singleton = { &GTK_CSS_VALUE_COLOR, 1, COLOR_TYPE_LITERAL, NULL,
+static GtkCssValue transparent_black_singleton = { &GTK_CSS_VALUE_COLOR, 1, 1, COLOR_TYPE_LITERAL, NULL,
                                                    .sym_col.rgba = {0, 0, 0, 0} };
-static GtkCssValue white_singleton             = { &GTK_CSS_VALUE_COLOR, 1, COLOR_TYPE_LITERAL, NULL,
+static GtkCssValue white_singleton             = { &GTK_CSS_VALUE_COLOR, 1, 1, COLOR_TYPE_LITERAL, NULL,
                                                    .sym_col.rgba = {1, 1, 1, 1} };
 
 
@@ -491,6 +491,7 @@ _gtk_css_color_value_new_literal (const GdkRGBA *color)
   g_return_val_if_fail (color != NULL, NULL);
 
   value = _gtk_css_value_new (GtkCssValue, &GTK_CSS_VALUE_COLOR);
+  value->is_static = TRUE;
   value->type = COLOR_TYPE_LITERAL;
   value->sym_col.rgba = *color;
 
@@ -594,7 +595,7 @@ _gtk_css_color_value_new_mix (GtkCssValue *color1,
 GtkCssValue *
 _gtk_css_color_value_new_current_color (void)
 {
-  static GtkCssValue current_color = { &GTK_CSS_VALUE_COLOR, 1, COLOR_TYPE_CURRENT_COLOR, NULL, };
+  static GtkCssValue current_color = { &GTK_CSS_VALUE_COLOR, 1, 0, COLOR_TYPE_CURRENT_COLOR, NULL, };
 
   return _gtk_css_value_ref (&current_color);
 }
diff --git a/gtk/gtkcssdimensionvalue.c b/gtk/gtkcssdimensionvalue.c
index e4463bec8d..8611226045 100644
--- a/gtk/gtkcssdimensionvalue.c
+++ b/gtk/gtkcssdimensionvalue.c
@@ -301,44 +301,45 @@ gtk_css_dimension_value_new (double     value,
                              GtkCssUnit unit)
 {
   static GtkCssValue number_singletons[] = {
-    { &GTK_CSS_VALUE_DIMENSION.value_class, 1, GTK_CSS_NUMBER, 0 },
-    { &GTK_CSS_VALUE_DIMENSION.value_class, 1, GTK_CSS_NUMBER, 1 },
-    { &GTK_CSS_VALUE_DIMENSION.value_class, 1, GTK_CSS_NUMBER, 96 }, /* DPI default */
+    { &GTK_CSS_VALUE_DIMENSION.value_class, 1, 1, GTK_CSS_NUMBER, 0 },
+    { &GTK_CSS_VALUE_DIMENSION.value_class, 1, 1, GTK_CSS_NUMBER, 1 },
+    { &GTK_CSS_VALUE_DIMENSION.value_class, 1, 1, GTK_CSS_NUMBER, 96 }, /* DPI default */
   };
   static GtkCssValue px_singletons[] = {
-    { &GTK_CSS_VALUE_DIMENSION.value_class, 1, GTK_CSS_PX, 0 },
-    { &GTK_CSS_VALUE_DIMENSION.value_class, 1, GTK_CSS_PX, 1 },
-    { &GTK_CSS_VALUE_DIMENSION.value_class, 1, GTK_CSS_PX, 2 },
-    { &GTK_CSS_VALUE_DIMENSION.value_class, 1, GTK_CSS_PX, 3 },
-    { &GTK_CSS_VALUE_DIMENSION.value_class, 1, GTK_CSS_PX, 4 },
-    { &GTK_CSS_VALUE_DIMENSION.value_class, 1, GTK_CSS_PX, 5 },
-    { &GTK_CSS_VALUE_DIMENSION.value_class, 1, GTK_CSS_PX, 6 },
-    { &GTK_CSS_VALUE_DIMENSION.value_class, 1, GTK_CSS_PX, 7 },
-    { &GTK_CSS_VALUE_DIMENSION.value_class, 1, GTK_CSS_PX, 8 },
-    { &GTK_CSS_VALUE_DIMENSION.value_class, 1, GTK_CSS_PX, 16 }, /* Icon size default */
-    { &GTK_CSS_VALUE_DIMENSION.value_class, 1, GTK_CSS_PX, 32 },
-    { &GTK_CSS_VALUE_DIMENSION.value_class, 1, GTK_CSS_PX, 10 * 96.0 / 72.0 }, /* font size 10 */
-    { &GTK_CSS_VALUE_DIMENSION.value_class, 1, GTK_CSS_PX, 11 * 96.0 / 72.0 }, /* font size 11 */
+    { &GTK_CSS_VALUE_DIMENSION.value_class, 1, 1, GTK_CSS_PX, 0 },
+    { &GTK_CSS_VALUE_DIMENSION.value_class, 1, 1, GTK_CSS_PX, 1 },
+    { &GTK_CSS_VALUE_DIMENSION.value_class, 1, 1, GTK_CSS_PX, 2 },
+    { &GTK_CSS_VALUE_DIMENSION.value_class, 1, 1, GTK_CSS_PX, 3 },
+    { &GTK_CSS_VALUE_DIMENSION.value_class, 1, 1, GTK_CSS_PX, 4 },
+    { &GTK_CSS_VALUE_DIMENSION.value_class, 1, 1, GTK_CSS_PX, 5 },
+    { &GTK_CSS_VALUE_DIMENSION.value_class, 1, 1, GTK_CSS_PX, 6 },
+    { &GTK_CSS_VALUE_DIMENSION.value_class, 1, 1, GTK_CSS_PX, 7 },
+    { &GTK_CSS_VALUE_DIMENSION.value_class, 1, 1, GTK_CSS_PX, 8 },
+    { &GTK_CSS_VALUE_DIMENSION.value_class, 1, 1, GTK_CSS_PX, 16 }, /* Icon size default */
+    { &GTK_CSS_VALUE_DIMENSION.value_class, 1, 1, GTK_CSS_PX, 32 },
+    { &GTK_CSS_VALUE_DIMENSION.value_class, 1, 1, GTK_CSS_PX, 10 * 96.0 / 72.0 }, /* font size 10 */
+    { &GTK_CSS_VALUE_DIMENSION.value_class, 1, 1, GTK_CSS_PX, 11 * 96.0 / 72.0 }, /* font size 11 */
   };
   static GtkCssValue percent_singletons[] = {
-    { &GTK_CSS_VALUE_DIMENSION.value_class, 1, GTK_CSS_PERCENT, 0 },
-    { &GTK_CSS_VALUE_DIMENSION.value_class, 1, GTK_CSS_PERCENT, 50 },
-    { &GTK_CSS_VALUE_DIMENSION.value_class, 1, GTK_CSS_PERCENT, 100 },
+    { &GTK_CSS_VALUE_DIMENSION.value_class, 1, 0, GTK_CSS_PERCENT, 0 },
+    { &GTK_CSS_VALUE_DIMENSION.value_class, 1, 0, GTK_CSS_PERCENT, 50 },
+    { &GTK_CSS_VALUE_DIMENSION.value_class, 1, 0, GTK_CSS_PERCENT, 100 },
   };
   static GtkCssValue second_singletons[] = {
-    { &GTK_CSS_VALUE_DIMENSION.value_class, 1, GTK_CSS_S, 0 },
-    { &GTK_CSS_VALUE_DIMENSION.value_class, 1, GTK_CSS_S, 0.15 },
-    { &GTK_CSS_VALUE_DIMENSION.value_class, 1, GTK_CSS_S, 0.2 },
-    { &GTK_CSS_VALUE_DIMENSION.value_class, 1, GTK_CSS_S, 0.3 },
-    { &GTK_CSS_VALUE_DIMENSION.value_class, 1, GTK_CSS_S, 1 },
+    { &GTK_CSS_VALUE_DIMENSION.value_class, 1, 1, GTK_CSS_S, 0 },
+    { &GTK_CSS_VALUE_DIMENSION.value_class, 1, 1, GTK_CSS_S, 0.15 },
+    { &GTK_CSS_VALUE_DIMENSION.value_class, 1, 1, GTK_CSS_S, 0.2 },
+    { &GTK_CSS_VALUE_DIMENSION.value_class, 1, 1, GTK_CSS_S, 0.3 },
+    { &GTK_CSS_VALUE_DIMENSION.value_class, 1, 1, GTK_CSS_S, 1 },
   };
   static GtkCssValue deg_singletons[] = {
-    { &GTK_CSS_VALUE_DIMENSION.value_class, 1, GTK_CSS_DEG, 0   },
-    { &GTK_CSS_VALUE_DIMENSION.value_class, 1, GTK_CSS_DEG, 90  },
-    { &GTK_CSS_VALUE_DIMENSION.value_class, 1, GTK_CSS_DEG, 180 },
-    { &GTK_CSS_VALUE_DIMENSION.value_class, 1, GTK_CSS_DEG, 270 },
+    { &GTK_CSS_VALUE_DIMENSION.value_class, 1, 1, GTK_CSS_DEG, 0   },
+    { &GTK_CSS_VALUE_DIMENSION.value_class, 1, 1, GTK_CSS_DEG, 90  },
+    { &GTK_CSS_VALUE_DIMENSION.value_class, 1, 1, GTK_CSS_DEG, 180 },
+    { &GTK_CSS_VALUE_DIMENSION.value_class, 1, 1, GTK_CSS_DEG, 270 },
   };
   GtkCssValue *result;
+  gboolean is_static = FALSE;
 
   switch ((guint)unit)
     {
@@ -349,6 +350,7 @@ gtk_css_dimension_value_new (double     value,
       if (value == 96)
         return _gtk_css_value_ref (&number_singletons[2]);
 
+      is_static = TRUE;
       break;
 
     case GTK_CSS_PX:
@@ -371,6 +373,7 @@ gtk_css_dimension_value_new (double     value,
       if (value == 11 * 96.0 / 72.0)
         return _gtk_css_value_ref (&px_singletons[12]);
 
+      is_static = TRUE;
       break;
 
     case GTK_CSS_PERCENT:
@@ -394,6 +397,8 @@ gtk_css_dimension_value_new (double     value,
         return _gtk_css_value_ref (&second_singletons[3]);
       if (value == 1)
         return _gtk_css_value_ref (&second_singletons[4]);
+
+      is_static = TRUE;
       break;
 
     case GTK_CSS_DEG:
@@ -405,27 +410,32 @@ gtk_css_dimension_value_new (double     value,
         return _gtk_css_value_ref (&deg_singletons[2]);
       if (value == 270)
         return _gtk_css_value_ref (&deg_singletons[3]);
-
+   
+      is_static = TRUE;
       break;
 
     case GTK_CSS_RAD:
       value = value * 360.0 / (2 * G_PI);
       unit = GTK_CSS_DEG;
+      is_static = TRUE;
       break;
 
     case GTK_CSS_GRAD:
       value = value * 360.0 / 400.0;
       unit = GTK_CSS_DEG;
+      is_static = TRUE;
       break;
 
     case GTK_CSS_TURN:
       value = value * 360.0;
       unit = GTK_CSS_DEG;
+      is_static = TRUE;
       break;
 
     case GTK_CSS_MS:
       value = value / 1000.0;
       unit = GTK_CSS_S;
+      is_static = TRUE;
       break;
 
     default:
@@ -433,6 +443,7 @@ gtk_css_dimension_value_new (double     value,
     }
 
   result = _gtk_css_value_new (GtkCssValue, &GTK_CSS_VALUE_DIMENSION.value_class);
+  result->is_static = is_static;
   result->unit = unit;
   result->value = value;
 
@@ -547,6 +558,9 @@ gtk_css_dimension_value_parse (GtkCssParser           *parser,
     }
 
   result = gtk_css_dimension_value_new (number, unit);
+  if (flags & GTK_CSS_PARSE_NON_STATIC)
+    result->is_static = FALSE;
+
   gtk_css_parser_consume_token (parser);
 
   return result;
diff --git a/gtk/gtkcsseasevalue.c b/gtk/gtkcsseasevalue.c
index 7e7c6be7bd..2927ecfb4f 100644
--- a/gtk/gtkcsseasevalue.c
+++ b/gtk/gtkcsseasevalue.c
@@ -159,6 +159,7 @@ _gtk_css_ease_value_new_cubic_bezier (double x1,
   g_return_val_if_fail (x2 <= 1.0, NULL);
 
   value = _gtk_css_value_new (GtkCssValue, &GTK_CSS_VALUE_EASE);
+  value->is_static = TRUE;
   
   value->type = GTK_CSS_EASE_CUBIC_BEZIER;
   value->u.cubic.x1 = x1;
@@ -178,6 +179,7 @@ _gtk_css_ease_value_new_steps (guint n_steps,
   g_return_val_if_fail (n_steps > 0, NULL);
 
   value = _gtk_css_value_new (GtkCssValue, &GTK_CSS_VALUE_EASE);
+  value->is_static = TRUE;
   
   value->type = GTK_CSS_EASE_STEPS;
   value->u.steps.steps = n_steps;
diff --git a/gtk/gtkcssenumvalue.c b/gtk/gtkcssenumvalue.c
index 1d40344866..6aa75df6e8 100644
--- a/gtk/gtkcssenumvalue.c
+++ b/gtk/gtkcssenumvalue.c
@@ -89,16 +89,16 @@ static const GtkCssValueClass GTK_CSS_VALUE_BORDER_STYLE = {
 };
 
 static GtkCssValue border_style_values[] = {
-  { &GTK_CSS_VALUE_BORDER_STYLE, 1, GTK_BORDER_STYLE_NONE, "none" },
-  { &GTK_CSS_VALUE_BORDER_STYLE, 1, GTK_BORDER_STYLE_SOLID, "solid" },
-  { &GTK_CSS_VALUE_BORDER_STYLE, 1, GTK_BORDER_STYLE_INSET, "inset" },
-  { &GTK_CSS_VALUE_BORDER_STYLE, 1, GTK_BORDER_STYLE_OUTSET, "outset" },
-  { &GTK_CSS_VALUE_BORDER_STYLE, 1, GTK_BORDER_STYLE_HIDDEN, "hidden" },
-  { &GTK_CSS_VALUE_BORDER_STYLE, 1, GTK_BORDER_STYLE_DOTTED, "dotted" },
-  { &GTK_CSS_VALUE_BORDER_STYLE, 1, GTK_BORDER_STYLE_DASHED, "dashed" },
-  { &GTK_CSS_VALUE_BORDER_STYLE, 1, GTK_BORDER_STYLE_DOUBLE, "double" },
-  { &GTK_CSS_VALUE_BORDER_STYLE, 1, GTK_BORDER_STYLE_GROOVE, "groove" },
-  { &GTK_CSS_VALUE_BORDER_STYLE, 1, GTK_BORDER_STYLE_RIDGE, "ridge" }
+  { &GTK_CSS_VALUE_BORDER_STYLE, 1, 1, GTK_BORDER_STYLE_NONE, "none" },
+  { &GTK_CSS_VALUE_BORDER_STYLE, 1, 1, GTK_BORDER_STYLE_SOLID, "solid" },
+  { &GTK_CSS_VALUE_BORDER_STYLE, 1, 1, GTK_BORDER_STYLE_INSET, "inset" },
+  { &GTK_CSS_VALUE_BORDER_STYLE, 1, 1, GTK_BORDER_STYLE_OUTSET, "outset" },
+  { &GTK_CSS_VALUE_BORDER_STYLE, 1, 1, GTK_BORDER_STYLE_HIDDEN, "hidden" },
+  { &GTK_CSS_VALUE_BORDER_STYLE, 1, 1, GTK_BORDER_STYLE_DOTTED, "dotted" },
+  { &GTK_CSS_VALUE_BORDER_STYLE, 1, 1, GTK_BORDER_STYLE_DASHED, "dashed" },
+  { &GTK_CSS_VALUE_BORDER_STYLE, 1, 1, GTK_BORDER_STYLE_DOUBLE, "double" },
+  { &GTK_CSS_VALUE_BORDER_STYLE, 1, 1, GTK_BORDER_STYLE_GROOVE, "groove" },
+  { &GTK_CSS_VALUE_BORDER_STYLE, 1, 1, GTK_BORDER_STYLE_RIDGE, "ridge" }
 };
 
 GtkCssValue *
@@ -147,22 +147,22 @@ static const GtkCssValueClass GTK_CSS_VALUE_BLEND_MODE = {
 };
 
 static GtkCssValue blend_mode_values[] = {
-  { &GTK_CSS_VALUE_BLEND_MODE, 1, GSK_BLEND_MODE_DEFAULT, "normal" },
-  { &GTK_CSS_VALUE_BLEND_MODE, 1, GSK_BLEND_MODE_MULTIPLY, "multiply" },
-  { &GTK_CSS_VALUE_BLEND_MODE, 1, GSK_BLEND_MODE_SCREEN, "screen" },
-  { &GTK_CSS_VALUE_BLEND_MODE, 1, GSK_BLEND_MODE_OVERLAY, "overlay" },
-  { &GTK_CSS_VALUE_BLEND_MODE, 1, GSK_BLEND_MODE_DARKEN, "darken" },
-  { &GTK_CSS_VALUE_BLEND_MODE, 1, GSK_BLEND_MODE_LIGHTEN, "lighten" },
-  { &GTK_CSS_VALUE_BLEND_MODE, 1, GSK_BLEND_MODE_COLOR_DODGE, "color-dodge" },
-  { &GTK_CSS_VALUE_BLEND_MODE, 1, GSK_BLEND_MODE_COLOR_BURN, "color-burn" },
-  { &GTK_CSS_VALUE_BLEND_MODE, 1, GSK_BLEND_MODE_HARD_LIGHT, "hard-light" },
-  { &GTK_CSS_VALUE_BLEND_MODE, 1, GSK_BLEND_MODE_SOFT_LIGHT, "soft-light" },
-  { &GTK_CSS_VALUE_BLEND_MODE, 1, GSK_BLEND_MODE_DIFFERENCE, "difference" },
-  { &GTK_CSS_VALUE_BLEND_MODE, 1, GSK_BLEND_MODE_EXCLUSION, "exclusion" },
-  { &GTK_CSS_VALUE_BLEND_MODE, 1, GSK_BLEND_MODE_COLOR, "color" },
-  { &GTK_CSS_VALUE_BLEND_MODE, 1, GSK_BLEND_MODE_HUE, "hue" },
-  { &GTK_CSS_VALUE_BLEND_MODE, 1, GSK_BLEND_MODE_SATURATION, "saturation" },
-  { &GTK_CSS_VALUE_BLEND_MODE, 1, GSK_BLEND_MODE_LUMINOSITY, "luminosity" }
+  { &GTK_CSS_VALUE_BLEND_MODE, 1, 1, GSK_BLEND_MODE_DEFAULT, "normal" },
+  { &GTK_CSS_VALUE_BLEND_MODE, 1, 1, GSK_BLEND_MODE_MULTIPLY, "multiply" },
+  { &GTK_CSS_VALUE_BLEND_MODE, 1, 1, GSK_BLEND_MODE_SCREEN, "screen" },
+  { &GTK_CSS_VALUE_BLEND_MODE, 1, 1, GSK_BLEND_MODE_OVERLAY, "overlay" },
+  { &GTK_CSS_VALUE_BLEND_MODE, 1, 1, GSK_BLEND_MODE_DARKEN, "darken" },
+  { &GTK_CSS_VALUE_BLEND_MODE, 1, 1, GSK_BLEND_MODE_LIGHTEN, "lighten" },
+  { &GTK_CSS_VALUE_BLEND_MODE, 1, 1, GSK_BLEND_MODE_COLOR_DODGE, "color-dodge" },
+  { &GTK_CSS_VALUE_BLEND_MODE, 1, 1, GSK_BLEND_MODE_COLOR_BURN, "color-burn" },
+  { &GTK_CSS_VALUE_BLEND_MODE, 1, 1, GSK_BLEND_MODE_HARD_LIGHT, "hard-light" },
+  { &GTK_CSS_VALUE_BLEND_MODE, 1, 1, GSK_BLEND_MODE_SOFT_LIGHT, "soft-light" },
+  { &GTK_CSS_VALUE_BLEND_MODE, 1, 1, GSK_BLEND_MODE_DIFFERENCE, "difference" },
+  { &GTK_CSS_VALUE_BLEND_MODE, 1, 1, GSK_BLEND_MODE_EXCLUSION, "exclusion" },
+  { &GTK_CSS_VALUE_BLEND_MODE, 1, 1, GSK_BLEND_MODE_COLOR, "color" },
+  { &GTK_CSS_VALUE_BLEND_MODE, 1, 1, GSK_BLEND_MODE_HUE, "hue" },
+  { &GTK_CSS_VALUE_BLEND_MODE, 1, 1, GSK_BLEND_MODE_SATURATION, "saturation" },
+  { &GTK_CSS_VALUE_BLEND_MODE, 1, 1, GSK_BLEND_MODE_LUMINOSITY, "luminosity" }
 };
 
 GtkCssValue *
@@ -298,15 +298,15 @@ static const GtkCssValueClass GTK_CSS_VALUE_FONT_SIZE = {
 };
 
 static GtkCssValue font_size_values[] = {
-  { &GTK_CSS_VALUE_FONT_SIZE, 1, GTK_CSS_FONT_SIZE_SMALLER, "smaller" },
-  { &GTK_CSS_VALUE_FONT_SIZE, 1, GTK_CSS_FONT_SIZE_LARGER, "larger" },
-  { &GTK_CSS_VALUE_FONT_SIZE, 1, GTK_CSS_FONT_SIZE_XX_SMALL, "xx-small" },
-  { &GTK_CSS_VALUE_FONT_SIZE, 1, GTK_CSS_FONT_SIZE_X_SMALL, "x-small" },
-  { &GTK_CSS_VALUE_FONT_SIZE, 1, GTK_CSS_FONT_SIZE_SMALL, "small" },
-  { &GTK_CSS_VALUE_FONT_SIZE, 1, GTK_CSS_FONT_SIZE_MEDIUM, "medium" },
-  { &GTK_CSS_VALUE_FONT_SIZE, 1, GTK_CSS_FONT_SIZE_LARGE, "large" },
-  { &GTK_CSS_VALUE_FONT_SIZE, 1, GTK_CSS_FONT_SIZE_X_LARGE, "x-large" },
-  { &GTK_CSS_VALUE_FONT_SIZE, 1, GTK_CSS_FONT_SIZE_XX_LARGE, "xx-large" }
+  { &GTK_CSS_VALUE_FONT_SIZE, 1, 0, GTK_CSS_FONT_SIZE_SMALLER, "smaller" },
+  { &GTK_CSS_VALUE_FONT_SIZE, 1, 0, GTK_CSS_FONT_SIZE_LARGER, "larger" },
+  { &GTK_CSS_VALUE_FONT_SIZE, 1, 0, GTK_CSS_FONT_SIZE_XX_SMALL, "xx-small" },
+  { &GTK_CSS_VALUE_FONT_SIZE, 1, 0, GTK_CSS_FONT_SIZE_X_SMALL, "x-small" },
+  { &GTK_CSS_VALUE_FONT_SIZE, 1, 0, GTK_CSS_FONT_SIZE_SMALL, "small" },
+  { &GTK_CSS_VALUE_FONT_SIZE, 1, 0, GTK_CSS_FONT_SIZE_MEDIUM, "medium" },
+  { &GTK_CSS_VALUE_FONT_SIZE, 1, 0, GTK_CSS_FONT_SIZE_LARGE, "large" },
+  { &GTK_CSS_VALUE_FONT_SIZE, 1, 0, GTK_CSS_FONT_SIZE_X_LARGE, "x-large" },
+  { &GTK_CSS_VALUE_FONT_SIZE, 1, 0, GTK_CSS_FONT_SIZE_XX_LARGE, "xx-large" }
 };
 
 GtkCssValue *
@@ -355,9 +355,9 @@ static const GtkCssValueClass GTK_CSS_VALUE_FONT_STYLE = {
 };
 
 static GtkCssValue font_style_values[] = {
-  { &GTK_CSS_VALUE_FONT_STYLE, 1, PANGO_STYLE_NORMAL, "normal" },
-  { &GTK_CSS_VALUE_FONT_STYLE, 1, PANGO_STYLE_OBLIQUE, "oblique" },
-  { &GTK_CSS_VALUE_FONT_STYLE, 1, PANGO_STYLE_ITALIC, "italic" }
+  { &GTK_CSS_VALUE_FONT_STYLE, 1, 1, PANGO_STYLE_NORMAL, "normal" },
+  { &GTK_CSS_VALUE_FONT_STYLE, 1, 1, PANGO_STYLE_OBLIQUE, "oblique" },
+  { &GTK_CSS_VALUE_FONT_STYLE, 1, 1, PANGO_STYLE_ITALIC, "italic" }
 };
 
 GtkCssValue *
@@ -454,8 +454,8 @@ static const GtkCssValueClass GTK_CSS_VALUE_FONT_WEIGHT = {
 };
 
 static GtkCssValue font_weight_values[] = {
-  { &GTK_CSS_VALUE_FONT_WEIGHT, 1, BOLDER, "bolder" },
-  { &GTK_CSS_VALUE_FONT_WEIGHT, 1, LIGHTER, "lighter" },
+  { &GTK_CSS_VALUE_FONT_WEIGHT, 1, 0, BOLDER, "bolder" },
+  { &GTK_CSS_VALUE_FONT_WEIGHT, 1, 0, LIGHTER, "lighter" },
 };
 
 GtkCssValue *
@@ -504,15 +504,15 @@ static const GtkCssValueClass GTK_CSS_VALUE_FONT_STRETCH = {
 };
 
 static GtkCssValue font_stretch_values[] = {
-  { &GTK_CSS_VALUE_FONT_STRETCH, 1, PANGO_STRETCH_ULTRA_CONDENSED, "ultra-condensed" },
-  { &GTK_CSS_VALUE_FONT_STRETCH, 1, PANGO_STRETCH_EXTRA_CONDENSED, "extra-condensed" },
-  { &GTK_CSS_VALUE_FONT_STRETCH, 1, PANGO_STRETCH_CONDENSED, "condensed" },
-  { &GTK_CSS_VALUE_FONT_STRETCH, 1, PANGO_STRETCH_SEMI_CONDENSED, "semi-condensed" },
-  { &GTK_CSS_VALUE_FONT_STRETCH, 1, PANGO_STRETCH_NORMAL, "normal" },
-  { &GTK_CSS_VALUE_FONT_STRETCH, 1, PANGO_STRETCH_SEMI_EXPANDED, "semi-expanded" },
-  { &GTK_CSS_VALUE_FONT_STRETCH, 1, PANGO_STRETCH_EXPANDED, "expanded" },
-  { &GTK_CSS_VALUE_FONT_STRETCH, 1, PANGO_STRETCH_EXTRA_EXPANDED, "extra-expanded" },
-  { &GTK_CSS_VALUE_FONT_STRETCH, 1, PANGO_STRETCH_ULTRA_EXPANDED, "ultra-expanded" },
+  { &GTK_CSS_VALUE_FONT_STRETCH, 1, 1, PANGO_STRETCH_ULTRA_CONDENSED, "ultra-condensed" },
+  { &GTK_CSS_VALUE_FONT_STRETCH, 1, 1, PANGO_STRETCH_EXTRA_CONDENSED, "extra-condensed" },
+  { &GTK_CSS_VALUE_FONT_STRETCH, 1, 1, PANGO_STRETCH_CONDENSED, "condensed" },
+  { &GTK_CSS_VALUE_FONT_STRETCH, 1, 1, PANGO_STRETCH_SEMI_CONDENSED, "semi-condensed" },
+  { &GTK_CSS_VALUE_FONT_STRETCH, 1, 1, PANGO_STRETCH_NORMAL, "normal" },
+  { &GTK_CSS_VALUE_FONT_STRETCH, 1, 1, PANGO_STRETCH_SEMI_EXPANDED, "semi-expanded" },
+  { &GTK_CSS_VALUE_FONT_STRETCH, 1, 1, PANGO_STRETCH_EXPANDED, "expanded" },
+  { &GTK_CSS_VALUE_FONT_STRETCH, 1, 1, PANGO_STRETCH_EXTRA_EXPANDED, "extra-expanded" },
+  { &GTK_CSS_VALUE_FONT_STRETCH, 1, 1, PANGO_STRETCH_ULTRA_EXPANDED, "ultra-expanded" },
 };
 
 GtkCssValue *
@@ -561,9 +561,9 @@ static const GtkCssValueClass GTK_CSS_VALUE_TEXT_DECORATION_LINE = {
 };
 
 static GtkCssValue text_decoration_line_values[] = {
-  { &GTK_CSS_VALUE_TEXT_DECORATION_LINE, 1, GTK_CSS_TEXT_DECORATION_LINE_NONE, "none" },
-  { &GTK_CSS_VALUE_TEXT_DECORATION_LINE, 1, GTK_CSS_TEXT_DECORATION_LINE_UNDERLINE, "underline" },
-  { &GTK_CSS_VALUE_TEXT_DECORATION_LINE, 1, GTK_CSS_TEXT_DECORATION_LINE_LINE_THROUGH, "line-through" },
+  { &GTK_CSS_VALUE_TEXT_DECORATION_LINE, 1, 1, GTK_CSS_TEXT_DECORATION_LINE_NONE, "none" },
+  { &GTK_CSS_VALUE_TEXT_DECORATION_LINE, 1, 1, GTK_CSS_TEXT_DECORATION_LINE_UNDERLINE, "underline" },
+  { &GTK_CSS_VALUE_TEXT_DECORATION_LINE, 1, 1, GTK_CSS_TEXT_DECORATION_LINE_LINE_THROUGH, "line-through" },
 };
 
 GtkCssValue *
@@ -612,9 +612,9 @@ static const GtkCssValueClass GTK_CSS_VALUE_TEXT_DECORATION_STYLE = {
 };
 
 static GtkCssValue text_decoration_style_values[] = {
-  { &GTK_CSS_VALUE_TEXT_DECORATION_STYLE, 1, GTK_CSS_TEXT_DECORATION_STYLE_SOLID, "solid" },
-  { &GTK_CSS_VALUE_TEXT_DECORATION_STYLE, 1, GTK_CSS_TEXT_DECORATION_STYLE_DOUBLE, "double" },
-  { &GTK_CSS_VALUE_TEXT_DECORATION_STYLE, 1, GTK_CSS_TEXT_DECORATION_STYLE_WAVY, "wavy" },
+  { &GTK_CSS_VALUE_TEXT_DECORATION_STYLE, 1, 1, GTK_CSS_TEXT_DECORATION_STYLE_SOLID, "solid" },
+  { &GTK_CSS_VALUE_TEXT_DECORATION_STYLE, 1, 1, GTK_CSS_TEXT_DECORATION_STYLE_DOUBLE, "double" },
+  { &GTK_CSS_VALUE_TEXT_DECORATION_STYLE, 1, 1, GTK_CSS_TEXT_DECORATION_STYLE_WAVY, "wavy" },
 };
 
 GtkCssValue *
@@ -663,9 +663,9 @@ static const GtkCssValueClass GTK_CSS_VALUE_AREA = {
 };
 
 static GtkCssValue area_values[] = {
-  { &GTK_CSS_VALUE_AREA, 1, GTK_CSS_AREA_BORDER_BOX, "border-box" },
-  { &GTK_CSS_VALUE_AREA, 1, GTK_CSS_AREA_PADDING_BOX, "padding-box" },
-  { &GTK_CSS_VALUE_AREA, 1, GTK_CSS_AREA_CONTENT_BOX, "content-box" }
+  { &GTK_CSS_VALUE_AREA, 1, 1, GTK_CSS_AREA_BORDER_BOX, "border-box" },
+  { &GTK_CSS_VALUE_AREA, 1, 1, GTK_CSS_AREA_PADDING_BOX, "padding-box" },
+  { &GTK_CSS_VALUE_AREA, 1, 1, GTK_CSS_AREA_CONTENT_BOX, "content-box" }
 };
 
 GtkCssValue *
@@ -720,10 +720,10 @@ static const GtkCssValueClass GTK_CSS_VALUE_DIRECTION = {
 };
 
 static GtkCssValue direction_values[] = {
-  { &GTK_CSS_VALUE_DIRECTION, 1, GTK_CSS_DIRECTION_NORMAL, "normal" },
-  { &GTK_CSS_VALUE_DIRECTION, 1, GTK_CSS_DIRECTION_REVERSE, "reverse" },
-  { &GTK_CSS_VALUE_DIRECTION, 1, GTK_CSS_DIRECTION_ALTERNATE, "alternate" },
-  { &GTK_CSS_VALUE_DIRECTION, 1, GTK_CSS_DIRECTION_ALTERNATE_REVERSE, "alternate-reverse" }
+  { &GTK_CSS_VALUE_DIRECTION, 1, 1, GTK_CSS_DIRECTION_NORMAL, "normal" },
+  { &GTK_CSS_VALUE_DIRECTION, 1, 1, GTK_CSS_DIRECTION_REVERSE, "reverse" },
+  { &GTK_CSS_VALUE_DIRECTION, 1, 1, GTK_CSS_DIRECTION_ALTERNATE, "alternate" },
+  { &GTK_CSS_VALUE_DIRECTION, 1, 1, GTK_CSS_DIRECTION_ALTERNATE_REVERSE, "alternate-reverse" }
 };
 
 GtkCssValue *
@@ -781,8 +781,8 @@ static const GtkCssValueClass GTK_CSS_VALUE_PLAY_STATE = {
 };
 
 static GtkCssValue play_state_values[] = {
-  { &GTK_CSS_VALUE_PLAY_STATE, 1, GTK_CSS_PLAY_STATE_RUNNING, "running" },
-  { &GTK_CSS_VALUE_PLAY_STATE, 1, GTK_CSS_PLAY_STATE_PAUSED, "paused" }
+  { &GTK_CSS_VALUE_PLAY_STATE, 1, 1, GTK_CSS_PLAY_STATE_RUNNING, "running" },
+  { &GTK_CSS_VALUE_PLAY_STATE, 1, 1, GTK_CSS_PLAY_STATE_PAUSED, "paused" }
 };
 
 GtkCssValue *
@@ -837,10 +837,10 @@ static const GtkCssValueClass GTK_CSS_VALUE_FILL_MODE = {
 };
 
 static GtkCssValue fill_mode_values[] = {
-  { &GTK_CSS_VALUE_FILL_MODE, 1, GTK_CSS_FILL_NONE, "none" },
-  { &GTK_CSS_VALUE_FILL_MODE, 1, GTK_CSS_FILL_FORWARDS, "forwards" },
-  { &GTK_CSS_VALUE_FILL_MODE, 1, GTK_CSS_FILL_BACKWARDS, "backwards" },
-  { &GTK_CSS_VALUE_FILL_MODE, 1, GTK_CSS_FILL_BOTH, "both" }
+  { &GTK_CSS_VALUE_FILL_MODE, 1, 1, GTK_CSS_FILL_NONE, "none" },
+  { &GTK_CSS_VALUE_FILL_MODE, 1, 1, GTK_CSS_FILL_FORWARDS, "forwards" },
+  { &GTK_CSS_VALUE_FILL_MODE, 1, 1, GTK_CSS_FILL_BACKWARDS, "backwards" },
+  { &GTK_CSS_VALUE_FILL_MODE, 1, 1, GTK_CSS_FILL_BOTH, "both" }
 };
 
 GtkCssValue *
@@ -895,9 +895,9 @@ static const GtkCssValueClass GTK_CSS_VALUE_ICON_STYLE = {
 };
 
 static GtkCssValue icon_style_values[] = {
-  { &GTK_CSS_VALUE_ICON_STYLE, 1, GTK_CSS_ICON_STYLE_REQUESTED, "requested" },
-  { &GTK_CSS_VALUE_ICON_STYLE, 1, GTK_CSS_ICON_STYLE_REGULAR, "regular" },
-  { &GTK_CSS_VALUE_ICON_STYLE, 1, GTK_CSS_ICON_STYLE_SYMBOLIC, "symbolic" }
+  { &GTK_CSS_VALUE_ICON_STYLE, 1, 1, GTK_CSS_ICON_STYLE_REQUESTED, "requested" },
+  { &GTK_CSS_VALUE_ICON_STYLE, 1, 1, GTK_CSS_ICON_STYLE_REGULAR, "regular" },
+  { &GTK_CSS_VALUE_ICON_STYLE, 1, 1, GTK_CSS_ICON_STYLE_SYMBOLIC, "symbolic" }
 };
 
 GtkCssValue *
@@ -952,9 +952,9 @@ static const GtkCssValueClass GTK_CSS_VALUE_FONT_KERNING = {
 };
 
 static GtkCssValue font_kerning_values[] = {
-  { &GTK_CSS_VALUE_FONT_KERNING, 1, GTK_CSS_FONT_KERNING_AUTO, "auto" },
-  { &GTK_CSS_VALUE_FONT_KERNING, 1, GTK_CSS_FONT_KERNING_NORMAL, "normal" },
-  { &GTK_CSS_VALUE_FONT_KERNING, 1, GTK_CSS_FONT_KERNING_NONE, "none" }
+  { &GTK_CSS_VALUE_FONT_KERNING, 1, 1, GTK_CSS_FONT_KERNING_AUTO, "auto" },
+  { &GTK_CSS_VALUE_FONT_KERNING, 1, 1, GTK_CSS_FONT_KERNING_NORMAL, "normal" },
+  { &GTK_CSS_VALUE_FONT_KERNING, 1, 1, GTK_CSS_FONT_KERNING_NONE, "none" }
 };
 
 GtkCssValue *
@@ -1009,9 +1009,9 @@ static const GtkCssValueClass GTK_CSS_VALUE_FONT_VARIANT_POSITION = {
 };
 
 static GtkCssValue font_variant_position_values[] = {
-  { &GTK_CSS_VALUE_FONT_VARIANT_POSITION, 1, GTK_CSS_FONT_VARIANT_POSITION_NORMAL, "normal" },
-  { &GTK_CSS_VALUE_FONT_VARIANT_POSITION, 1, GTK_CSS_FONT_VARIANT_POSITION_SUB, "sub" },
-  { &GTK_CSS_VALUE_FONT_VARIANT_POSITION, 1, GTK_CSS_FONT_VARIANT_POSITION_SUPER, "super" }
+  { &GTK_CSS_VALUE_FONT_VARIANT_POSITION, 1, 1, GTK_CSS_FONT_VARIANT_POSITION_NORMAL, "normal" },
+  { &GTK_CSS_VALUE_FONT_VARIANT_POSITION, 1, 1, GTK_CSS_FONT_VARIANT_POSITION_SUB, "sub" },
+  { &GTK_CSS_VALUE_FONT_VARIANT_POSITION, 1, 1, GTK_CSS_FONT_VARIANT_POSITION_SUPER, "super" }
 };
 
 GtkCssValue *
@@ -1066,13 +1066,13 @@ static const GtkCssValueClass GTK_CSS_VALUE_FONT_VARIANT_CAPS = {
 };
 
 static GtkCssValue font_variant_caps_values[] = {
-  { &GTK_CSS_VALUE_FONT_VARIANT_CAPS, 1, GTK_CSS_FONT_VARIANT_CAPS_NORMAL, "normal" },
-  { &GTK_CSS_VALUE_FONT_VARIANT_CAPS, 1, GTK_CSS_FONT_VARIANT_CAPS_SMALL_CAPS, "small-caps" },
-  { &GTK_CSS_VALUE_FONT_VARIANT_CAPS, 1, GTK_CSS_FONT_VARIANT_CAPS_ALL_SMALL_CAPS, "all-small-caps" },
-  { &GTK_CSS_VALUE_FONT_VARIANT_CAPS, 1, GTK_CSS_FONT_VARIANT_CAPS_PETITE_CAPS, "petite-caps" },
-  { &GTK_CSS_VALUE_FONT_VARIANT_CAPS, 1, GTK_CSS_FONT_VARIANT_CAPS_ALL_PETITE_CAPS, "all-petite-caps" },
-  { &GTK_CSS_VALUE_FONT_VARIANT_CAPS, 1, GTK_CSS_FONT_VARIANT_CAPS_UNICASE, "unicase" },
-  { &GTK_CSS_VALUE_FONT_VARIANT_CAPS, 1, GTK_CSS_FONT_VARIANT_CAPS_TITLING_CAPS, "titling-caps" }
+  { &GTK_CSS_VALUE_FONT_VARIANT_CAPS, 1, 1, GTK_CSS_FONT_VARIANT_CAPS_NORMAL, "normal" },
+  { &GTK_CSS_VALUE_FONT_VARIANT_CAPS, 1, 1, GTK_CSS_FONT_VARIANT_CAPS_SMALL_CAPS, "small-caps" },
+  { &GTK_CSS_VALUE_FONT_VARIANT_CAPS, 1, 1, GTK_CSS_FONT_VARIANT_CAPS_ALL_SMALL_CAPS, "all-small-caps" },
+  { &GTK_CSS_VALUE_FONT_VARIANT_CAPS, 1, 1, GTK_CSS_FONT_VARIANT_CAPS_PETITE_CAPS, "petite-caps" },
+  { &GTK_CSS_VALUE_FONT_VARIANT_CAPS, 1, 1, GTK_CSS_FONT_VARIANT_CAPS_ALL_PETITE_CAPS, "all-petite-caps" },
+  { &GTK_CSS_VALUE_FONT_VARIANT_CAPS, 1, 1, GTK_CSS_FONT_VARIANT_CAPS_UNICASE, "unicase" },
+  { &GTK_CSS_VALUE_FONT_VARIANT_CAPS, 1, 1, GTK_CSS_FONT_VARIANT_CAPS_TITLING_CAPS, "titling-caps" }
 };
 
 GtkCssValue *
@@ -1127,8 +1127,8 @@ static const GtkCssValueClass GTK_CSS_VALUE_FONT_VARIANT_ALTERNATE = {
 };
 
 static GtkCssValue font_variant_alternate_values[] = {
-  { &GTK_CSS_VALUE_FONT_VARIANT_ALTERNATE, 1, GTK_CSS_FONT_VARIANT_ALTERNATE_NORMAL, "normal" },
-  { &GTK_CSS_VALUE_FONT_VARIANT_ALTERNATE, 1, GTK_CSS_FONT_VARIANT_ALTERNATE_HISTORICAL_FORMS, 
"historical-forms" }
+  { &GTK_CSS_VALUE_FONT_VARIANT_ALTERNATE, 1, 1, GTK_CSS_FONT_VARIANT_ALTERNATE_NORMAL, "normal" },
+  { &GTK_CSS_VALUE_FONT_VARIANT_ALTERNATE, 1, 1, GTK_CSS_FONT_VARIANT_ALTERNATE_HISTORICAL_FORMS, 
"historical-forms" }
 };
 
 GtkCssValue *
diff --git a/gtk/gtkcssfiltervalue.c b/gtk/gtkcssfiltervalue.c
index b22d0e272c..95eb855cc4 100644
--- a/gtk/gtkcssfiltervalue.c
+++ b/gtk/gtkcssfiltervalue.c
@@ -703,7 +703,7 @@ static const GtkCssValueClass GTK_CSS_VALUE_FILTER = {
   gtk_css_value_filter_print
 };
 
-static GtkCssValue none_singleton = { &GTK_CSS_VALUE_FILTER, 1, 0, {  { GTK_CSS_FILTER_NONE } } };
+static GtkCssValue none_singleton = { &GTK_CSS_VALUE_FILTER, 1, 1, 0, {  { GTK_CSS_FILTER_NONE } } };
 
 static GtkCssValue *
 gtk_css_filter_value_alloc (guint n_filters)
@@ -778,6 +778,7 @@ gtk_css_filter_value_parse (GtkCssParser *parser)
   GtkCssValue *value;
   GArray *array;
   guint i;
+  gboolean is_static = TRUE;
 
   if (gtk_css_parser_try_ident (parser, "none"))
     return gtk_css_filter_value_new_none ();
@@ -794,6 +795,7 @@ gtk_css_filter_value_parse (GtkCssParser *parser)
             goto fail;
 
           filter.type = GTK_CSS_FILTER_BLUR;
+          is_static = is_static && filter.blur.value->is_static;
         }
       else if (gtk_css_parser_has_function (parser, "brightness"))
         {
@@ -801,6 +803,7 @@ gtk_css_filter_value_parse (GtkCssParser *parser)
             goto fail;
 
           filter.type = GTK_CSS_FILTER_BRIGHTNESS;
+          is_static = is_static && filter.brightness.value->is_static;
         }
       else if (gtk_css_parser_has_function (parser, "contrast"))
         {
@@ -808,6 +811,7 @@ gtk_css_filter_value_parse (GtkCssParser *parser)
             goto fail;
 
           filter.type = GTK_CSS_FILTER_CONTRAST;
+          is_static = is_static && filter.contrast.value->is_static;
         }
       else if (gtk_css_parser_has_function (parser, "grayscale"))
         {
@@ -815,13 +819,15 @@ gtk_css_filter_value_parse (GtkCssParser *parser)
             goto fail;
 
           filter.type = GTK_CSS_FILTER_GRAYSCALE;
+          is_static = is_static && filter.grayscale.value->is_static;
         }
       else if (gtk_css_parser_has_function (parser, "hue-rotate"))
         {
-          if (!gtk_css_parser_consume_function (parser, 1, 1, gtk_css_filter_parse_angle, 
&filter.blur.value))
+          if (!gtk_css_parser_consume_function (parser, 1, 1, gtk_css_filter_parse_angle, 
&filter.hue_rotate.value))
             goto fail;
 
           filter.type = GTK_CSS_FILTER_HUE_ROTATE;
+          is_static = is_static && filter.hue_rotate.value->is_static;
         }
       else if (gtk_css_parser_has_function (parser, "invert"))
         {
@@ -829,6 +835,7 @@ gtk_css_filter_value_parse (GtkCssParser *parser)
             goto fail;
 
           filter.type = GTK_CSS_FILTER_INVERT;
+          is_static = is_static && filter.invert.value->is_static;
         }
       else if (gtk_css_parser_has_function (parser, "opacity"))
         {
@@ -836,6 +843,7 @@ gtk_css_filter_value_parse (GtkCssParser *parser)
             goto fail;
 
           filter.type = GTK_CSS_FILTER_OPACITY;
+          is_static = is_static && filter.opacity.value->is_static;
         }
       else if (gtk_css_parser_has_function (parser, "saturate"))
         {
@@ -843,6 +851,7 @@ gtk_css_filter_value_parse (GtkCssParser *parser)
             goto fail;
 
           filter.type = GTK_CSS_FILTER_SATURATE;
+          is_static = is_static && filter.saturate.value->is_static;
         }
       else if (gtk_css_parser_has_function (parser, "sepia"))
         {
@@ -850,6 +859,7 @@ gtk_css_filter_value_parse (GtkCssParser *parser)
             goto fail;
 
           filter.type = GTK_CSS_FILTER_SEPIA;
+          is_static = is_static && filter.sepia.value->is_static;
         }
       else
         {
@@ -866,6 +876,7 @@ gtk_css_filter_value_parse (GtkCssParser *parser)
     }
 
   value = gtk_css_filter_value_alloc (array->len);
+  value->is_static = is_static;
   memcpy (value->filters, array->data, sizeof (GtkCssFilter) * array->len);
 
   g_array_free (array, TRUE);
diff --git a/gtk/gtkcssiconthemevalue.c b/gtk/gtkcssiconthemevalue.c
index e3838f5201..c5015b7c0d 100644
--- a/gtk/gtkcssiconthemevalue.c
+++ b/gtk/gtkcssiconthemevalue.c
@@ -121,7 +121,7 @@ static const GtkCssValueClass GTK_CSS_VALUE_ICON_THEME = {
   gtk_css_value_icon_theme_print
 };
 
-static GtkCssValue default_icon_theme_value = { &GTK_CSS_VALUE_ICON_THEME, 1, NULL, 0 };
+static GtkCssValue default_icon_theme_value = { &GTK_CSS_VALUE_ICON_THEME, 1, 0, NULL, 0 };
 
 GtkCssValue *
 gtk_css_icon_theme_value_new (GtkIconTheme *icontheme)
diff --git a/gtk/gtkcssimagevalue.c b/gtk/gtkcssimagevalue.c
index 8ddc88b7a0..f3acc9bfc4 100644
--- a/gtk/gtkcssimagevalue.c
+++ b/gtk/gtkcssimagevalue.c
@@ -137,8 +137,8 @@ static const GtkCssValueClass GTK_CSS_VALUE_IMAGE = {
 GtkCssValue *
 _gtk_css_image_value_new (GtkCssImage *image)
 {
-  static GtkCssValue none_singleton = { &GTK_CSS_VALUE_IMAGE, 1, NULL };
-  static GtkCssValue builtin_singleton = { &GTK_CSS_VALUE_IMAGE, 1, NULL };
+  static GtkCssValue none_singleton = { &GTK_CSS_VALUE_IMAGE, 1, 1, NULL };
+  static GtkCssValue builtin_singleton = { &GTK_CSS_VALUE_IMAGE, 1, 0, NULL };
   GtkCssValue *value;
 
   if (image == NULL)
diff --git a/gtk/gtkcssnumbervalueprivate.h b/gtk/gtkcssnumbervalueprivate.h
index e18b69afcb..0257fd6db0 100644
--- a/gtk/gtkcssnumbervalueprivate.h
+++ b/gtk/gtkcssnumbervalueprivate.h
@@ -32,7 +32,8 @@ typedef enum /*< skip >*/ {
   GTK_CSS_PARSE_NUMBER = (1 << 2),
   GTK_CSS_PARSE_LENGTH = (1 << 3),
   GTK_CSS_PARSE_ANGLE = (1 << 4),
-  GTK_CSS_PARSE_TIME = (1 << 5)
+  GTK_CSS_PARSE_TIME = (1 << 5),
+  GTK_CSS_PARSE_NON_STATIC = (1 << 6)
 } GtkCssNumberParseFlags;
 
 typedef struct _GtkCssNumberValueClass GtkCssNumberValueClass;
diff --git a/gtk/gtkcsspositionvalue.c b/gtk/gtkcsspositionvalue.c
index 853158a056..001f7e3526 100644
--- a/gtk/gtkcsspositionvalue.c
+++ b/gtk/gtkcsspositionvalue.c
@@ -167,6 +167,7 @@ _gtk_css_position_value_new (GtkCssValue *x,
   GtkCssValue *result;
 
   result = _gtk_css_value_new (GtkCssValue, &GTK_CSS_VALUE_POSITION);
+  result->is_static = x->is_static && y->is_static;
   result->x = x;
   result->y = y;
 
diff --git a/gtk/gtkcssrgbavalue.c b/gtk/gtkcssrgbavalue.c
index a45709ad8f..f562e5f484 100644
--- a/gtk/gtkcssrgbavalue.c
+++ b/gtk/gtkcssrgbavalue.c
@@ -108,10 +108,10 @@ static const GtkCssValueClass GTK_CSS_VALUE_RGBA = {
   gtk_css_value_rgba_print
 };
 
-static GtkCssValue transparent_black_singleton = { &GTK_CSS_VALUE_RGBA, 1, { 0, 0, 0, 0 }};
-static GtkCssValue transparent_white_singleton = { &GTK_CSS_VALUE_RGBA, 1, { 1, 1, 1, 0 }};
-static GtkCssValue opaque_black_singleton      = { &GTK_CSS_VALUE_RGBA, 1, { 0, 0, 0, 1 }};
-static GtkCssValue opaque_white_singleton      = { &GTK_CSS_VALUE_RGBA, 1, { 1, 1, 1, 1 }};
+static GtkCssValue transparent_black_singleton = { &GTK_CSS_VALUE_RGBA, 1, 1, { 0, 0, 0, 0 }};
+static GtkCssValue transparent_white_singleton = { &GTK_CSS_VALUE_RGBA, 1, 1, { 1, 1, 1, 0 }};
+static GtkCssValue opaque_black_singleton      = { &GTK_CSS_VALUE_RGBA, 1, 1, { 0, 0, 0, 1 }};
+static GtkCssValue opaque_white_singleton      = { &GTK_CSS_VALUE_RGBA, 1, 1, { 1, 1, 1, 1 }};
 
 GtkCssValue *
 _gtk_css_rgba_value_new_from_rgba (const GdkRGBA *rgba)
diff --git a/gtk/gtkcssshadowsvalue.c b/gtk/gtkcssshadowsvalue.c
index 2e09dae683..97fdf1cf95 100644
--- a/gtk/gtkcssshadowsvalue.c
+++ b/gtk/gtkcssshadowsvalue.c
@@ -210,7 +210,7 @@ static const GtkCssValueClass GTK_CSS_VALUE_SHADOWS = {
   gtk_css_value_shadows_print
 };
 
-static GtkCssValue none_singleton = { &GTK_CSS_VALUE_SHADOWS, 1, 0, { NULL } };
+static GtkCssValue none_singleton = { &GTK_CSS_VALUE_SHADOWS, 1, 1, 0, { NULL } };
 
 GtkCssValue *
 _gtk_css_shadows_value_new_none (void)
@@ -223,6 +223,8 @@ gtk_css_shadows_value_new (GtkCssValue **values,
                            guint         len)
 {
   GtkCssValue *result;
+  gboolean is_static;
+  int i;
 
   g_return_val_if_fail (values != NULL, NULL);
   g_return_val_if_fail (len > 0, NULL);
@@ -230,7 +232,18 @@ gtk_css_shadows_value_new (GtkCssValue **values,
   if (len == 1)
     return values[0];
 
+  is_static = TRUE;
+  for (i = 0; i < len; i++)
+    {
+      if (!values[i]->is_static)
+        {
+          is_static = FALSE;
+          break;
+        }
+    }
+
   result = _gtk_css_value_alloc (&GTK_CSS_VALUE_SHADOWS, sizeof (GtkCssValue) + sizeof (GtkCssValue *) * 
(len - 1));
+  result->is_static = is_static;
   result->len = len;
   memcpy (&result->values[0], values, sizeof (GtkCssValue *) * len);
 
diff --git a/gtk/gtkcssshadowvalue.c b/gtk/gtkcssshadowvalue.c
index 5f939ef99b..1bc478efea 100644
--- a/gtk/gtkcssshadowvalue.c
+++ b/gtk/gtkcssshadowvalue.c
@@ -177,6 +177,12 @@ gtk_css_shadow_value_new (GtkCssValue *hoffset,
 
   retval = _gtk_css_value_new (GtkCssValue, &GTK_CSS_VALUE_SHADOW);
 
+  retval->is_static = 
+     hoffset->is_static &&
+     voffset->is_static &&
+     radius->is_static &&
+     color->is_static;
+
   retval->hoffset = hoffset;
   retval->voffset = voffset;
   retval->radius = radius;
diff --git a/gtk/gtkcssstringvalue.c b/gtk/gtkcssstringvalue.c
index 286b86e0d9..e5c74136b7 100644
--- a/gtk/gtkcssstringvalue.c
+++ b/gtk/gtkcssstringvalue.c
@@ -150,6 +150,7 @@ _gtk_css_string_value_new_take (char *string)
   GtkCssValue *result;
 
   result = _gtk_css_value_new (GtkCssValue, &GTK_CSS_VALUE_STRING);
+  result->is_static = TRUE;
   result->string = string;
 
   return result;
@@ -190,6 +191,7 @@ _gtk_css_ident_value_new_take (char *ident)
   GtkCssValue *result;
 
   result = _gtk_css_value_new (GtkCssValue, &GTK_CSS_VALUE_IDENT);
+  result->is_static = TRUE;
   result->string = ident;
 
   return result;
diff --git a/gtk/gtkcssstylepropertyimpl.c b/gtk/gtkcssstylepropertyimpl.c
index 84c6d7c75c..3ecac362d8 100644
--- a/gtk/gtkcssstylepropertyimpl.c
+++ b/gtk/gtkcssstylepropertyimpl.c
@@ -868,7 +868,8 @@ parse_border_width (GtkCssStyleProperty *property,
 {
   return _gtk_css_number_value_parse (parser,
                                       GTK_CSS_POSITIVE_ONLY
-                                      | GTK_CSS_PARSE_LENGTH);
+                                      | GTK_CSS_PARSE_LENGTH
+                                      | GTK_CSS_PARSE_NON_STATIC);
 }
 
 static GtkCssValue *
diff --git a/gtk/gtkcsstransformvalue.c b/gtk/gtkcsstransformvalue.c
index 5285d7104b..99030aff74 100644
--- a/gtk/gtkcsstransformvalue.c
+++ b/gtk/gtkcsstransformvalue.c
@@ -590,6 +590,7 @@ gtk_css_value_transform_transition (GtkCssValue *start,
     }
 
   result = gtk_css_transform_value_alloc (MAX (start->n_transforms, end->n_transforms));
+  result->is_static = start->is_static && end->is_static;
 
   for (i = 0; i < n; i++)
     {
@@ -800,7 +801,7 @@ static const GtkCssValueClass GTK_CSS_VALUE_TRANSFORM = {
   gtk_css_value_transform_print
 };
 
-static GtkCssValue none_singleton = { &GTK_CSS_VALUE_TRANSFORM, 1, 0, {  { GTK_CSS_TRANSFORM_NONE } } };
+static GtkCssValue none_singleton = { &GTK_CSS_VALUE_TRANSFORM, 1, 1, 0, {  { GTK_CSS_TRANSFORM_NONE } } };
 
 static GtkCssValue *
 gtk_css_transform_value_alloc (guint n_transforms)
@@ -931,6 +932,7 @@ _gtk_css_transform_value_parse (GtkCssParser *parser)
   GtkCssValue *value;
   GArray *array;
   guint i;
+  gboolean is_static = TRUE;
 
   if (gtk_css_parser_try_ident (parser, "none"))
     return _gtk_css_transform_value_new_none ();
@@ -967,6 +969,7 @@ _gtk_css_transform_value_parse (GtkCssParser *parser)
             goto fail;
 
           transform.type = GTK_CSS_TRANSFORM_PERSPECTIVE;
+          is_static = is_static && transform.perspective.depth->is_static;
         }
       else if (gtk_css_parser_has_function (parser, "rotate") ||
                gtk_css_parser_has_function (parser, "rotateZ"))
@@ -978,6 +981,7 @@ _gtk_css_transform_value_parse (GtkCssParser *parser)
           transform.rotate.x = _gtk_css_number_value_new (0, GTK_CSS_NUMBER);
           transform.rotate.y = _gtk_css_number_value_new (0, GTK_CSS_NUMBER);
           transform.rotate.z = _gtk_css_number_value_new (1, GTK_CSS_NUMBER);
+          is_static = is_static && transform.rotate.angle->is_static;
         }
       else if (gtk_css_parser_has_function (parser, "rotate3d"))
         {
@@ -991,6 +995,10 @@ _gtk_css_transform_value_parse (GtkCssParser *parser)
             }
 
           transform.type = GTK_CSS_TRANSFORM_ROTATE;
+          is_static = is_static && transform.rotate.angle->is_static &&
+                                   transform.rotate.x->is_static &&
+                                   transform.rotate.y->is_static &&
+                                   transform.rotate.z->is_static;
         }
       else if (gtk_css_parser_has_function (parser, "rotateX"))
         {
@@ -1001,6 +1009,7 @@ _gtk_css_transform_value_parse (GtkCssParser *parser)
           transform.rotate.x = _gtk_css_number_value_new (1, GTK_CSS_NUMBER);
           transform.rotate.y = _gtk_css_number_value_new (0, GTK_CSS_NUMBER);
           transform.rotate.z = _gtk_css_number_value_new (0, GTK_CSS_NUMBER);
+          is_static = is_static && transform.rotate.angle->is_static;
         }
       else if (gtk_css_parser_has_function (parser, "rotateY"))
         {
@@ -1011,6 +1020,7 @@ _gtk_css_transform_value_parse (GtkCssParser *parser)
           transform.rotate.x = _gtk_css_number_value_new (0, GTK_CSS_NUMBER);
           transform.rotate.y = _gtk_css_number_value_new (1, GTK_CSS_NUMBER);
           transform.rotate.z = _gtk_css_number_value_new (0, GTK_CSS_NUMBER);
+          is_static = is_static && transform.rotate.angle->is_static;
         }
       else if (gtk_css_parser_has_function (parser, "scale"))
         {
@@ -1030,6 +1040,8 @@ _gtk_css_transform_value_parse (GtkCssParser *parser)
           else
             transform.scale.y = gtk_css_value_ref (values[0]);
           transform.scale.z = _gtk_css_number_value_new (1, GTK_CSS_NUMBER);
+          is_static = is_static && transform.scale.x->is_static &&
+                                   transform.scale.y->is_static;
         }
       else if (gtk_css_parser_has_function (parser, "scale3d"))
         {
@@ -1047,6 +1059,9 @@ _gtk_css_transform_value_parse (GtkCssParser *parser)
           transform.scale.x = values[0];
           transform.scale.y = values[1];
           transform.scale.z = values[2];
+          is_static = is_static && transform.scale.x->is_static &&
+                                   transform.scale.y->is_static &&
+                                   transform.scale.z->is_static;
         }
       else if (gtk_css_parser_has_function (parser, "scaleX"))
         {
@@ -1056,6 +1071,7 @@ _gtk_css_transform_value_parse (GtkCssParser *parser)
           transform.type = GTK_CSS_TRANSFORM_SCALE;
           transform.scale.y = _gtk_css_number_value_new (1, GTK_CSS_NUMBER);
           transform.scale.z = _gtk_css_number_value_new (1, GTK_CSS_NUMBER);
+          is_static = is_static && transform.scale.x->is_static;
         }
       else if (gtk_css_parser_has_function (parser, "scaleY"))
         {
@@ -1065,6 +1081,7 @@ _gtk_css_transform_value_parse (GtkCssParser *parser)
           transform.type = GTK_CSS_TRANSFORM_SCALE;
           transform.scale.x = _gtk_css_number_value_new (1, GTK_CSS_NUMBER);
           transform.scale.z = _gtk_css_number_value_new (1, GTK_CSS_NUMBER);
+          is_static = is_static && transform.scale.y->is_static;
         }
       else if (gtk_css_parser_has_function (parser, "scaleZ"))
         {
@@ -1074,6 +1091,7 @@ _gtk_css_transform_value_parse (GtkCssParser *parser)
           transform.type = GTK_CSS_TRANSFORM_SCALE;
           transform.scale.x = _gtk_css_number_value_new (1, GTK_CSS_NUMBER);
           transform.scale.y = _gtk_css_number_value_new (1, GTK_CSS_NUMBER);
+          is_static = is_static && transform.scale.z->is_static;
         }
       else if (gtk_css_parser_has_function (parser, "skew"))
         {
@@ -1089,6 +1107,8 @@ _gtk_css_transform_value_parse (GtkCssParser *parser)
           transform.type = GTK_CSS_TRANSFORM_SKEW;
           transform.skew.x = values[0];
           transform.skew.y = values[1];
+          is_static = is_static && transform.skew.x->is_static &&
+                                   transform.skew.y->is_static;
         }
       else if (gtk_css_parser_has_function (parser, "skewX"))
         {
@@ -1096,6 +1116,7 @@ _gtk_css_transform_value_parse (GtkCssParser *parser)
             goto fail;
 
           transform.type = GTK_CSS_TRANSFORM_SKEW_X;
+          is_static = is_static && transform.skew_x.skew->is_static;
         }
       else if (gtk_css_parser_has_function (parser, "skewY"))
         {
@@ -1103,6 +1124,7 @@ _gtk_css_transform_value_parse (GtkCssParser *parser)
             goto fail;
 
           transform.type = GTK_CSS_TRANSFORM_SKEW_Y;
+          is_static = is_static && transform.skew_y.skew->is_static;
         }
       else if (gtk_css_parser_has_function (parser, "translate"))
         {
@@ -1122,6 +1144,8 @@ _gtk_css_transform_value_parse (GtkCssParser *parser)
           else
             transform.translate.y = _gtk_css_number_value_new (0, GTK_CSS_PX);
           transform.translate.z = _gtk_css_number_value_new (0, GTK_CSS_PX);
+          is_static = is_static && transform.translate.x->is_static &&
+                                   transform.translate.y->is_static;
         }
       else if (gtk_css_parser_has_function (parser, "translate3d"))
         {
@@ -1139,6 +1163,9 @@ _gtk_css_transform_value_parse (GtkCssParser *parser)
           transform.translate.x = values[0];
           transform.translate.y = values[1];
           transform.translate.z = values[2];
+          is_static = is_static && transform.translate.x->is_static &&
+                                   transform.translate.y->is_static &&
+                                   transform.translate.z->is_static;
         }
       else if (gtk_css_parser_has_function (parser, "translateX"))
         {
@@ -1148,6 +1175,7 @@ _gtk_css_transform_value_parse (GtkCssParser *parser)
           transform.type = GTK_CSS_TRANSFORM_TRANSLATE;
           transform.translate.y = _gtk_css_number_value_new (0, GTK_CSS_PX);
           transform.translate.z = _gtk_css_number_value_new (0, GTK_CSS_PX);
+          is_static = is_static && transform.translate.x->is_static;
         }
       else if (gtk_css_parser_has_function (parser, "translateY"))
         {
@@ -1157,6 +1185,7 @@ _gtk_css_transform_value_parse (GtkCssParser *parser)
           transform.type = GTK_CSS_TRANSFORM_TRANSLATE;
           transform.translate.x = _gtk_css_number_value_new (0, GTK_CSS_PX);
           transform.translate.z = _gtk_css_number_value_new (0, GTK_CSS_PX);
+          is_static = is_static && transform.translate.y->is_static;
         }
       else if (gtk_css_parser_has_function (parser, "translateZ"))
         {
@@ -1166,6 +1195,7 @@ _gtk_css_transform_value_parse (GtkCssParser *parser)
           transform.type = GTK_CSS_TRANSFORM_TRANSLATE;
           transform.translate.x = _gtk_css_number_value_new (0, GTK_CSS_PX);
           transform.translate.y = _gtk_css_number_value_new (0, GTK_CSS_PX);
+          is_static = is_static && transform.translate.z->is_static;
         }
       else
         {
@@ -1182,6 +1212,7 @@ _gtk_css_transform_value_parse (GtkCssParser *parser)
     }
 
   value = gtk_css_transform_value_alloc (array->len);
+  value->is_static = is_static;
   memcpy (value->transforms, array->data, sizeof (GtkCssTransform) * array->len);
 
   g_array_free (array, TRUE);
diff --git a/gtk/gtkcssvalue.c b/gtk/gtkcssvalue.c
index 63a23b0f6c..c925668657 100644
--- a/gtk/gtkcssvalue.c
+++ b/gtk/gtkcssvalue.c
@@ -80,6 +80,7 @@ _gtk_css_value_alloc (const GtkCssValueClass *klass,
 
   value->class = klass;
   value->ref_count = 1;
+  value->is_static = FALSE;
 
   count_value (klass->type_name, 1);
 
@@ -133,7 +134,10 @@ _gtk_css_value_compute (GtkCssValue      *value,
                         GtkCssStyle      *style,
                         GtkCssStyle      *parent_style)
 {
-  return value->class->compute (value, property_id, provider, style, parent_style);
+  if (value->is_static)
+    return _gtk_css_value_ref (value);
+  else
+    return value->class->compute (value, property_id, provider, style, parent_style);
 }
 
 gboolean
diff --git a/gtk/gtkcssvalueprivate.h b/gtk/gtkcssvalueprivate.h
index 3071d2bd17..060a03a4e5 100644
--- a/gtk/gtkcssvalueprivate.h
+++ b/gtk/gtkcssvalueprivate.h
@@ -37,7 +37,8 @@ typedef struct _GtkCssValueClass      GtkCssValueClass;
 /* using define instead of struct here so compilers get the packing right */
 #define GTK_CSS_VALUE_BASE \
   const GtkCssValueClass *class; \
-  gint ref_count;
+  gint ref_count; \
+  gboolean is_static;
 
 struct _GtkCssValueClass {
   const char *type_name;


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