[gtk/wip/css-value-unboxing] wip: Unbox css values



commit 688c1314d49125c08f5335361908729836de0ac8
Author: Matthias Clasen <mclasen redhat com>
Date:   Sat Feb 8 18:18:24 2020 -0500

    wip: Unbox css values
    
    Keep css values unboxed in the values structs, for faster access
    to these values. So far, this is only done partially, and all the
    css values are kept.

 gtk/gtkboxlayout.c           |   9 +--
 gtk/gtkcssanimatedstyle.c    |  63 +++++++++++++++
 gtk/gtkcssboxesimplprivate.h | 178 ++++++++++++++++++++-----------------------
 gtk/gtkcssdimensionvalue.c   |  20 ++---
 gtk/gtkcssenumvalue.c        |  12 +--
 gtk/gtkcssstaticstyle.c      | 169 ++++++++++++++++++++++++++++++++++++++++
 gtk/gtkcssstyle.c            |  11 ++-
 gtk/gtkcssstyleprivate.h     |  55 ++++++++++++-
 gtk/gtkgridlayout.c          |   7 +-
 gtk/gtkwidget.c              |   2 +-
 10 files changed, 389 insertions(+), 137 deletions(-)
---
diff --git a/gtk/gtkboxlayout.c b/gtk/gtkboxlayout.c
index 098375973b..b3bd0bffe1 100644
--- a/gtk/gtkboxlayout.c
+++ b/gtk/gtkboxlayout.c
@@ -189,16 +189,11 @@ get_spacing (GtkBoxLayout *self,
              GtkCssNode   *node)
 {
   GtkCssStyle *style = gtk_css_node_get_style (node);
-  GtkCssValue *border_spacing;
-  gint css_spacing;
 
-  border_spacing = style->size->border_spacing;
   if (self->orientation == GTK_ORIENTATION_HORIZONTAL)
-    css_spacing = _gtk_css_position_value_get_x (border_spacing, 100);
+    return style->size->_border_spacing_x + self->spacing;
   else
-    css_spacing = _gtk_css_position_value_get_y (border_spacing, 100);
-
-  return css_spacing + self->spacing;
+    return style->size->_border_spacing_y + self->spacing;
 }
 
 static void
diff --git a/gtk/gtkcssanimatedstyle.c b/gtk/gtkcssanimatedstyle.c
index 2070e7f7a6..ab808aad38 100644
--- a/gtk/gtkcssanimatedstyle.c
+++ b/gtk/gtkcssanimatedstyle.c
@@ -37,6 +37,12 @@
 #include "gtkstyleanimationprivate.h"
 #include "gtkstylepropertyprivate.h"
 #include "gtkstyleproviderprivate.h"
+#include "gtkcssiconthemevalueprivate.h"
+#include "gtkcsscolorvalueprivate.h"
+#include "gtkcssdimensionvalueprivate.h"
+#include "gtkcsscornervalueprivate.h"
+#include "gtkcsspositionvalueprivate.h"
+
 
 G_DEFINE_TYPE (GtkCssAnimatedStyle, gtk_css_animated_style, GTK_TYPE_CSS_STYLE)
 
@@ -120,6 +126,9 @@ gtk_css_animated_style_init (GtkCssAnimatedStyle *style)
 }
 
 #define DEFINE_UNSHARE(TYPE, NAME) \
+\
+extern void gtk_css_ ## NAME ## _values_unbox (TYPE *values); \
+\
 static inline void \
 unshare_ ## NAME (GtkCssAnimatedStyle *animated) \
 { \
@@ -128,6 +137,7 @@ unshare_ ## NAME (GtkCssAnimatedStyle *animated) \
     { \
       gtk_css_values_unref ((GtkCssValues *)style->NAME); \
       style->NAME = (TYPE *)gtk_css_values_copy ((GtkCssValues *)animated->style->NAME); \
+      gtk_css_ ## NAME ## _values_unbox (style->NAME); \
     } \
 }
 
@@ -167,18 +177,22 @@ gtk_css_animated_style_set_animated_value (GtkCssAnimatedStyle *animated,
     case GTK_CSS_PROPERTY_COLOR:
       unshare_core (animated);
       gtk_css_take_value (&style->core->color, value);
+      style->core->_color = gtk_css_color_value_get_rgba (style->core->color);
       break;
     case GTK_CSS_PROPERTY_DPI:
       unshare_core (animated);
       gtk_css_take_value (&style->core->dpi, value);
+      style->core->_dpi = _gtk_css_number_value_get (style->core->dpi, 96);
       break;
     case GTK_CSS_PROPERTY_FONT_SIZE:
       unshare_core (animated);
       gtk_css_take_value (&style->core->font_size, value);
+      style->core->_font_size = _gtk_css_number_value_get (style->core->font_size, 100);
       break;
     case GTK_CSS_PROPERTY_ICON_THEME:
       unshare_core (animated);
       gtk_css_take_value (&style->core->icon_theme, value);
+      style->core->_icon_theme = gtk_css_icon_theme_value_get_icon_theme (style->core->icon_theme);
       break;
     case GTK_CSS_PROPERTY_ICON_PALETTE:
       unshare_core (animated);
@@ -259,110 +273,145 @@ gtk_css_animated_style_set_animated_value (GtkCssAnimatedStyle *animated,
     case GTK_CSS_PROPERTY_MARGIN_TOP:
       unshare_size (animated);
       gtk_css_take_value (&style->size->margin_top, value);
+      style->size->_margin_top = _gtk_css_number_value_get (style->size->margin_top, 100);
       break;
     case GTK_CSS_PROPERTY_MARGIN_LEFT:
       unshare_size (animated);
       gtk_css_take_value (&style->size->margin_left, value);
+      style->size->_margin_left = _gtk_css_number_value_get (style->size->margin_left, 100);
       break;
     case GTK_CSS_PROPERTY_MARGIN_BOTTOM:
       unshare_size (animated);
       gtk_css_take_value (&style->size->margin_bottom, value);
+      style->size->_margin_bottom = _gtk_css_number_value_get (style->size->margin_bottom, 100);
       break;
     case GTK_CSS_PROPERTY_MARGIN_RIGHT:
       unshare_size (animated);
       gtk_css_take_value (&style->size->margin_right, value);
+      style->size->_margin_right = _gtk_css_number_value_get (style->size->margin_right, 100);
       break;
     case GTK_CSS_PROPERTY_PADDING_TOP:
       unshare_size (animated);
       gtk_css_take_value (&style->size->padding_top, value);
+      style->size->_padding_top = _gtk_css_number_value_get (style->size->padding_top, 100);
       break;
     case GTK_CSS_PROPERTY_PADDING_LEFT:
       unshare_size (animated);
       gtk_css_take_value (&style->size->padding_left, value);
+      style->size->_padding_left = _gtk_css_number_value_get (style->size->padding_left, 100);
       break;
     case GTK_CSS_PROPERTY_PADDING_BOTTOM:
       unshare_size (animated);
       gtk_css_take_value (&style->size->padding_bottom, value);
+      style->size->_padding_bottom = _gtk_css_number_value_get (style->size->padding_bottom, 100);
       break;
     case GTK_CSS_PROPERTY_PADDING_RIGHT:
       unshare_size (animated);
       gtk_css_take_value (&style->size->padding_right, value);
+      style->size->_padding_right = _gtk_css_number_value_get (style->size->padding_right, 100);
       break;
     case GTK_CSS_PROPERTY_BORDER_TOP_STYLE:
       unshare_border (animated);
       gtk_css_take_value (&style->border->border_top_style, value);
+      style->border->_border_top_style = _gtk_css_border_style_value_get (style->border->border_top_style);
       break;
     case GTK_CSS_PROPERTY_BORDER_TOP_WIDTH:
       unshare_border (animated);
       gtk_css_take_value (&style->border->border_top_width, value);
+      style->border->_border_top_width = _gtk_css_number_value_get (style->border->border_top_width, 100);
       break;
     case GTK_CSS_PROPERTY_BORDER_LEFT_STYLE:
       unshare_border (animated);
       gtk_css_take_value (&style->border->border_left_style, value);
+      style->border->_border_left_style = _gtk_css_border_style_value_get (style->border->border_left_style);
       break;
     case GTK_CSS_PROPERTY_BORDER_LEFT_WIDTH:
       unshare_border (animated);
       gtk_css_take_value (&style->border->border_left_width, value);
+      style->border->_border_left_width = _gtk_css_number_value_get (style->border->border_left_width, 100);
       break;
     case GTK_CSS_PROPERTY_BORDER_BOTTOM_STYLE:
       unshare_border (animated);
       gtk_css_take_value (&style->border->border_bottom_style, value);
+      style->border->_border_bottom_style = _gtk_css_border_style_value_get 
(style->border->border_bottom_style);
       break;
     case GTK_CSS_PROPERTY_BORDER_BOTTOM_WIDTH:
       unshare_border (animated);
       gtk_css_take_value (&style->border->border_bottom_width, value);
+      style->border->_border_bottom_width = _gtk_css_number_value_get (style->border->border_bottom_width, 
100);
       break;
     case GTK_CSS_PROPERTY_BORDER_RIGHT_STYLE:
       unshare_border (animated);
       gtk_css_take_value (&style->border->border_right_style, value);
+      style->border->_border_right_style = _gtk_css_border_style_value_get 
(style->border->border_right_style);
       break;
     case GTK_CSS_PROPERTY_BORDER_RIGHT_WIDTH:
       unshare_border (animated);
       gtk_css_take_value (&style->border->border_right_width, value);
+      style->border->_border_right_width = _gtk_css_number_value_get (style->border->border_right_width, 
100);
       break;
     case GTK_CSS_PROPERTY_BORDER_TOP_LEFT_RADIUS:
       unshare_border (animated);
       gtk_css_take_value (&style->border->border_top_left_radius, value);
+      style->border->_border_top_left_radius_x = _gtk_css_corner_value_get_x 
(style->border->border_top_left_radius, 100);
+      style->border->_border_top_left_radius_y = _gtk_css_corner_value_get_y 
(style->border->border_top_left_radius, 100);
       break;
     case GTK_CSS_PROPERTY_BORDER_TOP_RIGHT_RADIUS:
       unshare_border (animated);
       gtk_css_take_value (&style->border->border_top_right_radius, value);
+     style->border->_border_top_right_radius_x = _gtk_css_corner_value_get_x 
(style->border->border_top_right_radius, 100);
+      style->border->_border_top_right_radius_y = _gtk_css_corner_value_get_y 
(style->border->border_top_right_radius, 100);
       break;
     case GTK_CSS_PROPERTY_BORDER_BOTTOM_RIGHT_RADIUS:
       unshare_border (animated);
       gtk_css_take_value (&style->border->border_bottom_right_radius, value);
+     style->border->_border_bottom_right_radius_x = _gtk_css_corner_value_get_x 
(style->border->border_bottom_right_radius, 100);
+      style->border->_border_bottom_right_radius_y = _gtk_css_corner_value_get_y 
(style->border->border_bottom_right_radius, 100);
       break;
     case GTK_CSS_PROPERTY_BORDER_BOTTOM_LEFT_RADIUS:
       unshare_border (animated);
       gtk_css_take_value (&style->border->border_bottom_left_radius, value);
+      style->border->_border_bottom_left_radius_x = _gtk_css_corner_value_get_x 
(style->border->border_bottom_left_radius, 100);
+      style->border->_border_bottom_left_radius_y = _gtk_css_corner_value_get_y 
(style->border->border_bottom_left_radius, 100);
       break;
     case GTK_CSS_PROPERTY_OUTLINE_STYLE:
       unshare_outline (animated);
       gtk_css_take_value (&style->outline->outline_style, value);
+      style->outline->_outline_style = _gtk_css_border_style_value_get (style->outline->outline_style);
       break;
     case GTK_CSS_PROPERTY_OUTLINE_WIDTH:
       unshare_outline (animated);
       gtk_css_take_value (&style->outline->outline_width, value);
+      style->outline->_outline_width = _gtk_css_number_value_get (style->outline->outline_width, 100);
       break;
     case GTK_CSS_PROPERTY_OUTLINE_OFFSET:
       unshare_outline (animated);
       gtk_css_take_value (&style->outline->outline_offset, value);
+      style->outline->_outline_offset = _gtk_css_number_value_get (style->outline->outline_offset, 100);
       break;
     case GTK_CSS_PROPERTY_OUTLINE_TOP_LEFT_RADIUS:
       unshare_outline (animated);
       gtk_css_take_value (&style->outline->outline_top_left_radius, value);
+      style->outline->_outline_top_left_radius_x = _gtk_css_corner_value_get_x 
(style->outline->outline_top_left_radius, 100);
+      style->outline->_outline_top_left_radius_y = _gtk_css_corner_value_get_y 
(style->outline->outline_top_left_radius, 100);
       break;
     case GTK_CSS_PROPERTY_OUTLINE_TOP_RIGHT_RADIUS:
       unshare_outline (animated);
       gtk_css_take_value (&style->outline->outline_top_right_radius, value);
+      style->outline->_outline_top_right_radius_x = _gtk_css_corner_value_get_x 
(style->outline->outline_top_right_radius, 100);
+      style->outline->_outline_top_right_radius_y = _gtk_css_corner_value_get_y 
(style->outline->outline_top_right_radius, 100);
       break;
     case GTK_CSS_PROPERTY_OUTLINE_BOTTOM_RIGHT_RADIUS:
       unshare_outline (animated);
       gtk_css_take_value (&style->outline->outline_bottom_right_radius, value);
+      style->outline->_outline_bottom_right_radius_x = _gtk_css_corner_value_get_x 
(style->outline->outline_bottom_right_radius, 100);
+      style->outline->_outline_bottom_right_radius_y = _gtk_css_corner_value_get_y 
(style->outline->outline_bottom_right_radius, 100);
       break;
     case GTK_CSS_PROPERTY_OUTLINE_BOTTOM_LEFT_RADIUS:
       unshare_outline (animated);
       gtk_css_take_value (&style->outline->outline_bottom_left_radius, value);
+      style->outline->_outline_bottom_left_radius_x = _gtk_css_corner_value_get_x 
(style->outline->outline_bottom_left_radius, 100);
+      style->outline->_outline_bottom_left_radius_y = _gtk_css_corner_value_get_y 
(style->outline->outline_bottom_left_radius, 100);
       break;
     case GTK_CSS_PROPERTY_BACKGROUND_CLIP:
       unshare_background (animated);
@@ -383,22 +432,32 @@ gtk_css_animated_style_set_animated_value (GtkCssAnimatedStyle *animated,
     case GTK_CSS_PROPERTY_BORDER_TOP_COLOR:
       unshare_border (animated);
       gtk_css_take_value (&style->border->border_top_color, value);
+      if (style->border->border_top_color)
+        style->border->_border_top_color = gtk_css_color_value_get_rgba (style->border->border_top_color);
       break;
     case GTK_CSS_PROPERTY_BORDER_RIGHT_COLOR:
       unshare_border (animated);
       gtk_css_take_value (&style->border->border_right_color, value);
+      if (style->border->border_right_color)
+        style->border->_border_right_color = gtk_css_color_value_get_rgba 
(style->border->border_right_color);
       break;
     case GTK_CSS_PROPERTY_BORDER_BOTTOM_COLOR:
       unshare_border (animated);
       gtk_css_take_value (&style->border->border_bottom_color, value);
+      if (style->border->border_bottom_color)
+        style->border->_border_bottom_color = gtk_css_color_value_get_rgba 
(style->border->border_bottom_color);
       break;
     case GTK_CSS_PROPERTY_BORDER_LEFT_COLOR:
       unshare_border (animated);
       gtk_css_take_value (&style->border->border_left_color, value);
+      if (style->border->border_left_color)
+        style->border->_border_left_color = gtk_css_color_value_get_rgba (style->border->border_left_color);
       break;
     case GTK_CSS_PROPERTY_OUTLINE_COLOR:
       unshare_outline (animated);
       gtk_css_take_value (&style->outline->outline_color, value);
+      if (style->outline->outline_color)
+        style->outline->_outline_color = gtk_css_color_value_get_rgba (style->outline->outline_color);
       break;
     case GTK_CSS_PROPERTY_BACKGROUND_REPEAT:
       unshare_background (animated);
@@ -455,6 +514,8 @@ gtk_css_animated_style_set_animated_value (GtkCssAnimatedStyle *animated,
     case GTK_CSS_PROPERTY_BORDER_SPACING:
       unshare_size (animated);
       gtk_css_take_value (&style->size->border_spacing, value);
+      style->size->_border_spacing_x = _gtk_css_position_value_get_x (style->size->border_spacing, 100);
+      style->size->_border_spacing_y = _gtk_css_position_value_get_y (style->size->border_spacing, 100);
       break;
     case GTK_CSS_PROPERTY_TRANSFORM:
       unshare_other (animated);
@@ -463,10 +524,12 @@ gtk_css_animated_style_set_animated_value (GtkCssAnimatedStyle *animated,
     case GTK_CSS_PROPERTY_MIN_WIDTH:
       unshare_size (animated);
       gtk_css_take_value (&style->size->min_width, value);
+      style->size->_min_width = _gtk_css_number_value_get (style->size->min_width, 100);
       break;
     case GTK_CSS_PROPERTY_MIN_HEIGHT:
       unshare_size (animated);
       gtk_css_take_value (&style->size->min_height, value);
+      style->size->_min_height = _gtk_css_number_value_get (style->size->min_height, 100);
       break;
     case GTK_CSS_PROPERTY_TRANSITION_PROPERTY:
       unshare_transition (animated);
diff --git a/gtk/gtkcssboxesimplprivate.h b/gtk/gtkcssboxesimplprivate.h
index 65737e81f8..50650fc7f2 100644
--- a/gtk/gtkcssboxesimplprivate.h
+++ b/gtk/gtkcssboxesimplprivate.h
@@ -74,65 +74,55 @@ gtk_css_boxes_init_border_box (GtkCssBoxes *boxes,
 static inline void
 gtk_css_boxes_rect_grow (GskRoundedRect *dest,
                          GskRoundedRect *src,
-                         GtkCssValue    *top,
-                         GtkCssValue    *right,
-                         GtkCssValue    *bottom,
-                         GtkCssValue    *left)
+                         double          top,
+                         double          right,
+                         double          bottom,
+                         double          left)
 {
-  if (gtk_css_dimension_value_is_zero (left))
+  if (left == 0)
     {
       dest->bounds.origin.x = src->bounds.origin.x;
-      if (gtk_css_dimension_value_is_zero (right))
+      if (right == 0)
         dest->bounds.size.width = src->bounds.size.width;
       else
-        dest->bounds.size.width = src->bounds.size.width + _gtk_css_number_value_get (right, 100);
+        dest->bounds.size.width = src->bounds.size.width + right;
     }
   else
     {
-      const double left_value = _gtk_css_number_value_get (left, 100);
-
-      dest->bounds.origin.x = src->bounds.origin.x - left_value;
-      if (gtk_css_dimension_value_is_zero (right))
-        dest->bounds.size.width = src->bounds.size.width + left_value;
+      dest->bounds.origin.x = src->bounds.origin.x - left;
+      if (right == 0)
+        dest->bounds.size.width = src->bounds.size.width + left;
       else
-        dest->bounds.size.width = src->bounds.size.width + left_value + _gtk_css_number_value_get (right, 
100);
-
+        dest->bounds.size.width = src->bounds.size.width + left + right;
     }
 
 
-  if (gtk_css_dimension_value_is_zero (top))
+  if (top == 0)
     {
       dest->bounds.origin.y = src->bounds.origin.y;
-      if (gtk_css_dimension_value_is_zero (bottom))
+      if (bottom == 0)
         dest->bounds.size.height = src->bounds.size.height;
       else
-        dest->bounds.size.height = src->bounds.size.height + _gtk_css_number_value_get (bottom, 100);
+        dest->bounds.size.height = src->bounds.size.height + bottom;
     }
   else
     {
-      const double top_value = _gtk_css_number_value_get (top, 100);
-
-      dest->bounds.origin.y = src->bounds.origin.y - top_value;
-      if (gtk_css_dimension_value_is_zero (bottom))
-        dest->bounds.size.height = src->bounds.size.height + top_value;
+      dest->bounds.origin.y = src->bounds.origin.y - top;
+      if (bottom == 0)
+        dest->bounds.size.height = src->bounds.size.height + top;
       else
-        dest->bounds.size.height = src->bounds.size.height + top_value + _gtk_css_number_value_get (bottom, 
100);
+        dest->bounds.size.height = src->bounds.size.height + top + bottom;
     }
 }
 
 static inline void
 gtk_css_boxes_rect_shrink (GskRoundedRect *dest,
                            GskRoundedRect *src,
-                           GtkCssValue    *top_value,
-                           GtkCssValue    *right_value,
-                           GtkCssValue    *bottom_value,
-                           GtkCssValue    *left_value)
+                           double          top,
+                           double          right,
+                           double          bottom,
+                           double          left)
 {
-  double top = _gtk_css_number_value_get (top_value, 100);
-  double right = _gtk_css_number_value_get (right_value, 100);
-  double bottom = _gtk_css_number_value_get (bottom_value, 100);
-  double left = _gtk_css_number_value_get (left_value, 100);
-
   /* FIXME: Do we need underflow checks here? */
   dest->bounds.origin.x = src->bounds.origin.x + left;
   dest->bounds.origin.y = src->bounds.origin.y + top;
@@ -170,10 +160,10 @@ gtk_css_boxes_compute_border_rect (GtkCssBoxes *boxes)
 
   gtk_css_boxes_rect_grow (&boxes->box[GTK_CSS_AREA_BORDER_BOX],
                            &boxes->box[GTK_CSS_AREA_PADDING_BOX],
-                           boxes->style->border->border_top_width,
-                           boxes->style->border->border_right_width,
-                           boxes->style->border->border_bottom_width,
-                           boxes->style->border->border_left_width);
+                           boxes->style->border->_border_top_width,
+                           boxes->style->border->_border_right_width,
+                           boxes->style->border->_border_bottom_width,
+                           boxes->style->border->_border_left_width);
 
   boxes->has_rect[GTK_CSS_AREA_BORDER_BOX] = TRUE;
 }
@@ -188,19 +178,19 @@ gtk_css_boxes_compute_padding_rect (GtkCssBoxes *boxes)
     {
       gtk_css_boxes_rect_shrink (&boxes->box[GTK_CSS_AREA_PADDING_BOX],
                                  &boxes->box[GTK_CSS_AREA_BORDER_BOX],
-                                 boxes->style->border->border_top_width,
-                                 boxes->style->border->border_right_width,
-                                 boxes->style->border->border_bottom_width,
-                                 boxes->style->border->border_left_width);
+                                 boxes->style->border->_border_top_width,
+                                 boxes->style->border->_border_right_width,
+                                 boxes->style->border->_border_bottom_width,
+                                 boxes->style->border->_border_left_width);
     }
   else
     {
       gtk_css_boxes_rect_grow (&boxes->box[GTK_CSS_AREA_PADDING_BOX],
                                &boxes->box[GTK_CSS_AREA_CONTENT_BOX],
-                               boxes->style->size->padding_top,
-                               boxes->style->size->padding_right,
-                               boxes->style->size->padding_bottom,
-                               boxes->style->size->padding_left);
+                               boxes->style->size->_padding_top,
+                               boxes->style->size->_padding_right,
+                               boxes->style->size->_padding_bottom,
+                               boxes->style->size->_padding_left);
     }
 
   boxes->has_rect[GTK_CSS_AREA_PADDING_BOX] = TRUE;
@@ -216,10 +206,10 @@ gtk_css_boxes_compute_content_rect (GtkCssBoxes *boxes)
 
   gtk_css_boxes_rect_shrink (&boxes->box[GTK_CSS_AREA_CONTENT_BOX],
                              &boxes->box[GTK_CSS_AREA_PADDING_BOX],
-                             boxes->style->size->padding_top,
-                             boxes->style->size->padding_right,
-                             boxes->style->size->padding_bottom,
-                             boxes->style->size->padding_left);
+                             boxes->style->size->_padding_top,
+                             boxes->style->size->_padding_right,
+                             boxes->style->size->_padding_bottom,
+                             boxes->style->size->_padding_left);
 
   boxes->has_rect[GTK_CSS_AREA_CONTENT_BOX] = TRUE;
 }
@@ -234,10 +224,10 @@ gtk_css_boxes_compute_margin_rect (GtkCssBoxes *boxes)
 
   gtk_css_boxes_rect_grow (&boxes->box[GTK_CSS_AREA_MARGIN_BOX],
                            &boxes->box[GTK_CSS_AREA_BORDER_BOX],
-                           boxes->style->size->margin_top,
-                           boxes->style->size->margin_right,
-                           boxes->style->size->margin_bottom,
-                           boxes->style->size->margin_left);
+                           boxes->style->size->_margin_top,
+                           boxes->style->size->_margin_right,
+                           boxes->style->size->_margin_bottom,
+                           boxes->style->size->_margin_left);
 
   boxes->has_rect[GTK_CSS_AREA_MARGIN_BOX] = TRUE;
 }
@@ -256,8 +246,8 @@ gtk_css_boxes_compute_outline_rect (GtkCssBoxes *boxes)
   dest = &boxes->box[GTK_CSS_AREA_OUTLINE_BOX].bounds;
   src = &boxes->box[GTK_CSS_AREA_BORDER_BOX].bounds;
 
-  d = _gtk_css_number_value_get (boxes->style->outline->outline_offset, 100) +
-      _gtk_css_number_value_get (boxes->style->outline->outline_width, 100);
+  d = boxes->style->outline->_outline_offset +
+      boxes->style->outline->_outline_width;
 
   dest->origin.x = src->origin.x - d;
   dest->origin.y = src->origin.y - d;
@@ -342,42 +332,28 @@ gtk_css_boxes_clamp_border_radius (GskRoundedRect *box)
 
 static inline void
 gtk_css_boxes_apply_border_radius (GskRoundedRect    *box,
-                                   const GtkCssValue *top_left,
-                                   const GtkCssValue *top_right,
-                                   const GtkCssValue *bottom_right,
-                                   const GtkCssValue *bottom_left)
+                                   double             top_left_x,
+                                   double             top_left_y,
+                                   double             top_right_x,
+                                   double             top_right_y,
+                                   double             bottom_right_x,
+                                   double             bottom_right_y,
+                                   double             bottom_left_x,
+                                   double             bottom_left_y)
 {
-  gboolean has_border_radius = FALSE;
-
-  if (!gtk_css_corner_value_is_zero (top_left))
-    {
-      box->corner[GSK_CORNER_TOP_LEFT].width = _gtk_css_corner_value_get_x (top_left, 
box->bounds.size.width);
-      box->corner[GSK_CORNER_TOP_LEFT].height = _gtk_css_corner_value_get_y (top_left, 
box->bounds.size.height);
-      has_border_radius = TRUE;
-    }
-
-  if (!gtk_css_corner_value_is_zero (top_right))
-    {
-      box->corner[GSK_CORNER_TOP_RIGHT].width = _gtk_css_corner_value_get_x (top_right, 
box->bounds.size.width);
-      box->corner[GSK_CORNER_TOP_RIGHT].height = _gtk_css_corner_value_get_y (top_right, 
box->bounds.size.height);
-      has_border_radius = TRUE;
-    }
-
-  if (!gtk_css_corner_value_is_zero (bottom_right))
-    {
-      box->corner[GSK_CORNER_BOTTOM_RIGHT].width = _gtk_css_corner_value_get_x (bottom_right, 
box->bounds.size.width);
-      box->corner[GSK_CORNER_BOTTOM_RIGHT].height = _gtk_css_corner_value_get_y (bottom_right, 
box->bounds.size.height);
-      has_border_radius = TRUE;
-    }
-
-  if (!gtk_css_corner_value_is_zero (bottom_left))
-    {
-      box->corner[GSK_CORNER_BOTTOM_LEFT].width = _gtk_css_corner_value_get_x (bottom_left, 
box->bounds.size.width);
-      box->corner[GSK_CORNER_BOTTOM_LEFT].height = _gtk_css_corner_value_get_y (bottom_left, 
box->bounds.size.height);
-      has_border_radius = TRUE;
-    }
-
-  if (has_border_radius)
+  box->corner[GSK_CORNER_TOP_LEFT].width = top_left_x;
+  box->corner[GSK_CORNER_TOP_LEFT].height = top_left_y;
+  box->corner[GSK_CORNER_TOP_RIGHT].width = top_right_x;
+  box->corner[GSK_CORNER_TOP_RIGHT].height = top_right_y;
+  box->corner[GSK_CORNER_BOTTOM_RIGHT].width = bottom_right_x;
+  box->corner[GSK_CORNER_BOTTOM_RIGHT].height = bottom_right_y;
+  box->corner[GSK_CORNER_BOTTOM_LEFT].width = bottom_left_x;
+  box->corner[GSK_CORNER_BOTTOM_LEFT].height = bottom_left_y;
+
+  if (top_left_x != 0 || top_left_y != 0 ||
+      top_right_x != 0 || top_right_y != 0 ||
+      bottom_right_x != 0 || bottom_right_y != 0 ||
+      bottom_left_x != 0 || bottom_left_y != 0)
     gtk_css_boxes_clamp_border_radius (box);
 }
 
@@ -430,10 +406,14 @@ gtk_css_boxes_compute_border_box (GtkCssBoxes *boxes)
   gtk_css_boxes_compute_border_rect (boxes);
 
   gtk_css_boxes_apply_border_radius (&boxes->box[GTK_CSS_AREA_BORDER_BOX],
-                                     boxes->style->border->border_top_left_radius,
-                                     boxes->style->border->border_top_right_radius,
-                                     boxes->style->border->border_bottom_right_radius,
-                                     boxes->style->border->border_bottom_left_radius);
+                                     boxes->style->border->_border_top_left_radius_x,
+                                     boxes->style->border->_border_top_left_radius_y,
+                                     boxes->style->border->_border_top_right_radius_x,
+                                     boxes->style->border->_border_top_right_radius_y,
+                                     boxes->style->border->_border_bottom_right_radius_x,
+                                     boxes->style->border->_border_bottom_right_radius_y,
+                                     boxes->style->border->_border_bottom_left_radius_x,
+                                     boxes->style->border->_border_bottom_left_radius_y);
 
   boxes->has_box[GTK_CSS_AREA_BORDER_BOX] = TRUE;
 }
@@ -477,10 +457,14 @@ gtk_css_boxes_compute_outline_box (GtkCssBoxes *boxes)
   gtk_css_boxes_compute_outline_rect (boxes);
 
   gtk_css_boxes_apply_border_radius (&boxes->box[GTK_CSS_AREA_OUTLINE_BOX],
-                                     boxes->style->outline->outline_top_left_radius,
-                                     boxes->style->outline->outline_top_right_radius,
-                                     boxes->style->outline->outline_bottom_right_radius,
-                                     boxes->style->outline->outline_bottom_left_radius);
+                                     boxes->style->outline->_outline_top_left_radius_x,
+                                     boxes->style->outline->_outline_top_left_radius_y,
+                                     boxes->style->outline->_outline_top_right_radius_x,
+                                     boxes->style->outline->_outline_top_right_radius_y,
+                                     boxes->style->outline->_outline_bottom_right_radius_x,
+                                     boxes->style->outline->_outline_bottom_right_radius_y,
+                                     boxes->style->outline->_outline_bottom_left_radius_x,
+                                     boxes->style->outline->_outline_bottom_left_radius_y);
 
   boxes->has_box[GTK_CSS_AREA_OUTLINE_BOX] = TRUE;
 }
diff --git a/gtk/gtkcssdimensionvalue.c b/gtk/gtkcssdimensionvalue.c
index b54309d079..64a0959caa 100644
--- a/gtk/gtkcssdimensionvalue.c
+++ b/gtk/gtkcssdimensionvalue.c
@@ -45,18 +45,12 @@ get_base_font_size_px (guint             property_id,
   if (property_id == GTK_CSS_PROPERTY_FONT_SIZE)
     {
       if (parent_style)
-        return _gtk_css_number_value_get (parent_style->core->font_size, 100);
+        return parent_style->core->_font_size;
       else
         return gtk_css_font_size_get_default_px (provider, style);
     }
 
-  return _gtk_css_number_value_get (style->core->font_size, 100);
-}
-
-static double
-get_dpi (GtkCssStyle *style)
-{
-  return _gtk_css_number_value_get (style->core->dpi, 96);
+  return style->core->_font_size;
 }
 
 static GtkCssValue *
@@ -84,19 +78,19 @@ gtk_css_value_dimension_compute (GtkCssValue      *number,
     case GTK_CSS_S:
       return _gtk_css_value_ref (number);
     case GTK_CSS_PT:
-      return gtk_css_dimension_value_new (number->value * get_dpi (style) / 72.0,
+      return gtk_css_dimension_value_new (number->value * style->core->_dpi / 72.0,
                                           GTK_CSS_PX);
     case GTK_CSS_PC:
-      return gtk_css_dimension_value_new (number->value * get_dpi (style) / 72.0 * 12.0,
+      return gtk_css_dimension_value_new (number->value * style->core->_dpi / 72.0 * 12.0,
                                           GTK_CSS_PX);
     case GTK_CSS_IN:
-      return gtk_css_dimension_value_new (number->value * get_dpi (style),
+      return gtk_css_dimension_value_new (number->value * style->core->_dpi,
                                           GTK_CSS_PX);
     case GTK_CSS_CM:
-      return gtk_css_dimension_value_new (number->value * get_dpi (style) * 0.39370078740157477,
+      return gtk_css_dimension_value_new (number->value * style->core->_dpi * 0.39370078740157477,
                                           GTK_CSS_PX);
     case GTK_CSS_MM:
-      return gtk_css_dimension_value_new (number->value * get_dpi (style) * 0.039370078740157477,
+      return gtk_css_dimension_value_new (number->value * style->core->_dpi * 0.039370078740157477,
                                           GTK_CSS_PX);
     case GTK_CSS_EM:
       return gtk_css_dimension_value_new (number->value *
diff --git a/gtk/gtkcssenumvalue.c b/gtk/gtkcssenumvalue.c
index 82d5580773..0f35b00dfe 100644
--- a/gtk/gtkcssenumvalue.c
+++ b/gtk/gtkcssenumvalue.c
@@ -199,12 +199,6 @@ _gtk_css_blend_mode_value_get (const GtkCssValue *value)
 
 /* GtkCssFontSize */
 
-static double
-get_dpi (GtkCssStyle *style)
-{
-  return _gtk_css_number_value_get (style->core->dpi, 96);
-}
-
 /* XXX: Kinda bad to have that machinery here, nobody expects vital font
  * size code to appear in gtkcssvalueenum.c.
  */
@@ -219,15 +213,15 @@ gtk_css_font_size_get_default_px (GtkStyleProvider *provider,
 
   settings = gtk_style_provider_get_settings (provider);
   if (settings == NULL)
-    return DEFAULT_FONT_SIZE_PT * get_dpi (style) / 72.0;
+    return DEFAULT_FONT_SIZE_PT * style->core->_dpi / 72.0;
 
   font_size = gtk_settings_get_font_size (settings);
   if (font_size == 0)
-    return DEFAULT_FONT_SIZE_PT * get_dpi (style) / 72.0;
+    return DEFAULT_FONT_SIZE_PT * style->core->_dpi / 72.0;
   else if (gtk_settings_get_font_size_is_absolute (settings))
     return (double) font_size / PANGO_SCALE;
   else
-    return ((double) font_size / PANGO_SCALE) * get_dpi (style) / 72.0;
+    return ((double) font_size / PANGO_SCALE) * style->core->_dpi / 72.0;
 }
 
 static GtkCssValue *
diff --git a/gtk/gtkcssstaticstyle.c b/gtk/gtkcssstaticstyle.c
index 5a9336ce79..e02b3c0cab 100644
--- a/gtk/gtkcssstaticstyle.c
+++ b/gtk/gtkcssstaticstyle.c
@@ -27,6 +27,8 @@
 #include "gtkcssinheritvalueprivate.h"
 #include "gtkcssinitialvalueprivate.h"
 #include "gtkcssnumbervalueprivate.h"
+#include "gtkcsscolorvalueprivate.h"
+#include "gtkcssiconthemevalueprivate.h"
 #include "gtkcssshorthandpropertyprivate.h"
 #include "gtkcssstringvalueprivate.h"
 #include "gtkcssstylepropertyprivate.h"
@@ -38,6 +40,9 @@
 #include "gtkstylepropertyprivate.h"
 #include "gtkstyleproviderprivate.h"
 #include "gtkcssdimensionvalueprivate.h"
+#include "gtkcsscornervalueprivate.h"
+#include "gtkcsspositionvalueprivate.h"
+
 
 static void gtk_css_static_style_compute_value (GtkCssStaticStyle *style,
                                                 GtkStyleProvider  *provider,
@@ -223,6 +228,7 @@ static GtkBitmask * gtk_css_ ## NAME ## _values_mask; \
 static GtkCssValues * gtk_css_ ## NAME ## _initial_values; \
 \
 static GtkCssValues * gtk_css_ ## NAME ## _create_initial_values (void); \
+void gtk_css_ ## NAME ## _values_unbox (GtkCss ## TYPE ## Values *values); \
 \
 static void \
 gtk_css_ ## NAME ## _values_init (void) \
@@ -393,15 +399,19 @@ gtk_css_static_style_set_value (GtkCssStaticStyle *sstyle,
     {
     case GTK_CSS_PROPERTY_COLOR:
       gtk_css_take_value (&style->core->color, value);
+      style->core->_color = gtk_css_color_value_get_rgba (style->core->color);
       break;
     case GTK_CSS_PROPERTY_DPI:
       gtk_css_take_value (&style->core->dpi, value);
+      style->core->_dpi = _gtk_css_number_value_get (style->core->dpi, 96);
       break;
     case GTK_CSS_PROPERTY_FONT_SIZE:
       gtk_css_take_value (&style->core->font_size, value);
+      style->core->_font_size = _gtk_css_number_value_get (style->core->font_size, 100);
       break;
     case GTK_CSS_PROPERTY_ICON_THEME:
       gtk_css_take_value (&style->core->icon_theme, value);
+      style->core->_icon_theme = gtk_css_icon_theme_value_get_icon_theme (style->core->icon_theme);
       break;
     case GTK_CSS_PROPERTY_ICON_PALETTE:
       gtk_css_take_value (&style->core->icon_palette, value);
@@ -462,84 +472,120 @@ gtk_css_static_style_set_value (GtkCssStaticStyle *sstyle,
       break;
     case GTK_CSS_PROPERTY_MARGIN_TOP:
       gtk_css_take_value (&style->size->margin_top, value);
+      style->size->_margin_top = _gtk_css_number_value_get (style->size->margin_top, 100);
       break;
     case GTK_CSS_PROPERTY_MARGIN_LEFT:
       gtk_css_take_value (&style->size->margin_left, value);
+      style->size->_margin_left = _gtk_css_number_value_get (style->size->margin_left, 100);
       break;
     case GTK_CSS_PROPERTY_MARGIN_BOTTOM:
       gtk_css_take_value (&style->size->margin_bottom, value);
+      style->size->_margin_bottom = _gtk_css_number_value_get (style->size->margin_bottom, 100);
       break;
     case GTK_CSS_PROPERTY_MARGIN_RIGHT:
       gtk_css_take_value (&style->size->margin_right, value);
+      style->size->_margin_right = _gtk_css_number_value_get (style->size->margin_right, 100);
       break;
     case GTK_CSS_PROPERTY_PADDING_TOP:
       gtk_css_take_value (&style->size->padding_top, value);
+      style->size->_padding_top = _gtk_css_number_value_get (style->size->padding_top, 100);
       break;
     case GTK_CSS_PROPERTY_PADDING_LEFT:
       gtk_css_take_value (&style->size->padding_left, value);
+      style->size->_padding_left = _gtk_css_number_value_get (style->size->padding_left, 100);
       break;
     case GTK_CSS_PROPERTY_PADDING_BOTTOM:
       gtk_css_take_value (&style->size->padding_bottom, value);
+      style->size->_padding_bottom = _gtk_css_number_value_get (style->size->padding_bottom, 100);
       break;
     case GTK_CSS_PROPERTY_PADDING_RIGHT:
       gtk_css_take_value (&style->size->padding_right, value);
+      style->size->_padding_right = _gtk_css_number_value_get (style->size->padding_right, 100);
       break;
     case GTK_CSS_PROPERTY_BORDER_TOP_STYLE:
       gtk_css_take_value (&style->border->border_top_style, value);
+      style->border->_border_top_style = _gtk_css_border_style_value_get (style->border->border_top_style);
       break;
     case GTK_CSS_PROPERTY_BORDER_TOP_WIDTH:
       gtk_css_take_value (&style->border->border_top_width, value);
+      style->border->_border_top_width = _gtk_css_number_value_get (style->border->border_top_width, 100);
       break;
     case GTK_CSS_PROPERTY_BORDER_LEFT_STYLE:
       gtk_css_take_value (&style->border->border_left_style, value);
+      style->border->_border_left_style = _gtk_css_border_style_value_get (style->border->border_left_style);
       break;
     case GTK_CSS_PROPERTY_BORDER_LEFT_WIDTH:
       gtk_css_take_value (&style->border->border_left_width, value);
+      style->border->_border_left_width = _gtk_css_number_value_get (style->border->border_left_width, 100);
       break;
     case GTK_CSS_PROPERTY_BORDER_BOTTOM_STYLE:
       gtk_css_take_value (&style->border->border_bottom_style, value);
+      style->border->_border_bottom_style = _gtk_css_border_style_value_get 
(style->border->border_bottom_style);
       break;
     case GTK_CSS_PROPERTY_BORDER_BOTTOM_WIDTH:
       gtk_css_take_value (&style->border->border_bottom_width, value);
+      style->border->_border_bottom_width = _gtk_css_number_value_get (style->border->border_bottom_width, 
100);
       break;
     case GTK_CSS_PROPERTY_BORDER_RIGHT_STYLE:
       gtk_css_take_value (&style->border->border_right_style, value);
+      style->border->_border_right_style = _gtk_css_border_style_value_get 
(style->border->border_right_style);
       break;
     case GTK_CSS_PROPERTY_BORDER_RIGHT_WIDTH:
       gtk_css_take_value (&style->border->border_right_width, value);
+      style->border->_border_right_width = _gtk_css_number_value_get (style->border->border_right_width, 
100);
       break;
     case GTK_CSS_PROPERTY_BORDER_TOP_LEFT_RADIUS:
       gtk_css_take_value (&style->border->border_top_left_radius, value);
+      style->border->_border_top_left_radius_x = _gtk_css_corner_value_get_x 
(style->border->border_top_left_radius, 100);
+      style->border->_border_top_left_radius_y = _gtk_css_corner_value_get_y 
(style->border->border_top_left_radius, 100);
       break;
     case GTK_CSS_PROPERTY_BORDER_TOP_RIGHT_RADIUS:
       gtk_css_take_value (&style->border->border_top_right_radius, value);
+      style->border->_border_top_right_radius_x = _gtk_css_corner_value_get_x 
(style->border->border_top_right_radius, 100);
+      style->border->_border_top_right_radius_y = _gtk_css_corner_value_get_y 
(style->border->border_top_right_radius, 100);
       break;
     case GTK_CSS_PROPERTY_BORDER_BOTTOM_RIGHT_RADIUS:
       gtk_css_take_value (&style->border->border_bottom_right_radius, value);
+      style->border->_border_bottom_right_radius_x = _gtk_css_corner_value_get_x 
(style->border->border_bottom_right_radius, 100);
+      style->border->_border_bottom_right_radius_y = _gtk_css_corner_value_get_y 
(style->border->border_bottom_right_radius, 100);
       break;
     case GTK_CSS_PROPERTY_BORDER_BOTTOM_LEFT_RADIUS:
       gtk_css_take_value (&style->border->border_bottom_left_radius, value);
+      style->border->_border_bottom_left_radius_x = _gtk_css_corner_value_get_x 
(style->border->border_bottom_left_radius, 100);
+      style->border->_border_bottom_left_radius_y = _gtk_css_corner_value_get_y 
(style->border->border_bottom_left_radius, 100);
       break;
     case GTK_CSS_PROPERTY_OUTLINE_STYLE:
       gtk_css_take_value (&style->outline->outline_style, value);
+      style->outline->_outline_style = _gtk_css_border_style_value_get (style->outline->outline_style);
       break;
     case GTK_CSS_PROPERTY_OUTLINE_WIDTH:
       gtk_css_take_value (&style->outline->outline_width, value);
+      style->outline->_outline_width = _gtk_css_number_value_get (style->outline->outline_width, 100);
       break;
     case GTK_CSS_PROPERTY_OUTLINE_OFFSET:
       gtk_css_take_value (&style->outline->outline_offset, value);
+      style->outline->_outline_offset = _gtk_css_number_value_get (style->outline->outline_offset, 100);
       break;
     case GTK_CSS_PROPERTY_OUTLINE_TOP_LEFT_RADIUS:
       gtk_css_take_value (&style->outline->outline_top_left_radius, value);
+      style->outline->_outline_top_left_radius_x = _gtk_css_corner_value_get_x 
(style->outline->outline_top_left_radius, 100);
+      style->outline->_outline_top_left_radius_y = _gtk_css_corner_value_get_y 
(style->outline->outline_top_left_radius, 100);
       break;
     case GTK_CSS_PROPERTY_OUTLINE_TOP_RIGHT_RADIUS:
       gtk_css_take_value (&style->outline->outline_top_right_radius, value);
+      style->outline->_outline_top_right_radius_x = _gtk_css_corner_value_get_x 
(style->outline->outline_top_right_radius, 100);
+      style->outline->_outline_top_right_radius_y = _gtk_css_corner_value_get_y 
(style->outline->outline_top_right_radius, 100);
       break;
     case GTK_CSS_PROPERTY_OUTLINE_BOTTOM_RIGHT_RADIUS:
       gtk_css_take_value (&style->outline->outline_bottom_right_radius, value);
+      style->outline->_outline_bottom_right_radius_x = _gtk_css_corner_value_get_x 
(style->outline->outline_bottom_right_radius, 100);
+      style->outline->_outline_bottom_right_radius_y = _gtk_css_corner_value_get_y 
(style->outline->outline_bottom_right_radius, 100);
       break;
     case GTK_CSS_PROPERTY_OUTLINE_BOTTOM_LEFT_RADIUS:
       gtk_css_take_value (&style->outline->outline_bottom_left_radius, value);
+      style->outline->_outline_bottom_left_radius_x = _gtk_css_corner_value_get_x 
(style->outline->outline_bottom_left_radius, 100);
+      style->outline->_outline_bottom_left_radius_y = _gtk_css_corner_value_get_y 
(style->outline->outline_bottom_left_radius, 100);
+      break;
       break;
     case GTK_CSS_PROPERTY_BACKGROUND_CLIP:
       gtk_css_take_value (&style->background->background_clip, value);
@@ -555,18 +601,28 @@ gtk_css_static_style_set_value (GtkCssStaticStyle *sstyle,
       break;
     case GTK_CSS_PROPERTY_BORDER_TOP_COLOR:
       gtk_css_take_value (&style->border->border_top_color, value);
+      if (style->border->border_top_color)
+        style->border->_border_top_color = gtk_css_color_value_get_rgba (style->border->border_top_color);
       break;
     case GTK_CSS_PROPERTY_BORDER_RIGHT_COLOR:
       gtk_css_take_value (&style->border->border_right_color, value);
+      if (style->border->border_right_color)
+        style->border->_border_right_color = gtk_css_color_value_get_rgba 
(style->border->border_right_color);
       break;
     case GTK_CSS_PROPERTY_BORDER_BOTTOM_COLOR:
       gtk_css_take_value (&style->border->border_bottom_color, value);
+      if (style->border->border_bottom_color)
+        style->border->_border_bottom_color = gtk_css_color_value_get_rgba 
(style->border->border_bottom_color);
       break;
     case GTK_CSS_PROPERTY_BORDER_LEFT_COLOR:
       gtk_css_take_value (&style->border->border_left_color, value);
+      if (style->border->border_left_color)
+        style->border->_border_left_color = gtk_css_color_value_get_rgba (style->border->border_left_color);
       break;
     case GTK_CSS_PROPERTY_OUTLINE_COLOR:
       gtk_css_take_value (&style->outline->outline_color, value);
+      if (style->outline->outline_color)
+        style->outline->_outline_color = gtk_css_color_value_get_rgba (style->outline->outline_color);
       break;
     case GTK_CSS_PROPERTY_BACKGROUND_REPEAT:
       gtk_css_take_value (&style->background->background_repeat, value);
@@ -609,15 +665,19 @@ gtk_css_static_style_set_value (GtkCssStaticStyle *sstyle,
       break;
     case GTK_CSS_PROPERTY_BORDER_SPACING:
       gtk_css_take_value (&style->size->border_spacing, value);
+      style->size->_border_spacing_x = _gtk_css_position_value_get_x (style->size->border_spacing, 100);
+      style->size->_border_spacing_y = _gtk_css_position_value_get_y (style->size->border_spacing, 100);
       break;
     case GTK_CSS_PROPERTY_TRANSFORM:
       gtk_css_take_value (&style->other->transform, value);
       break;
     case GTK_CSS_PROPERTY_MIN_WIDTH:
       gtk_css_take_value (&style->size->min_width, value);
+      style->size->_min_width = _gtk_css_number_value_get (style->size->min_width, 100);
       break;
     case GTK_CSS_PROPERTY_MIN_HEIGHT:
       gtk_css_take_value (&style->size->min_height, value);
+      style->size->_min_height = _gtk_css_number_value_get (style->size->min_height, 100);
       break;
     case GTK_CSS_PROPERTY_TRANSITION_PROPERTY:
       gtk_css_take_value (&style->transition->transition_property, value);
@@ -734,6 +794,16 @@ gtk_css_core_create_initial_values (void)
   return NULL;
 
 }
+
+void
+gtk_css_core_values_unbox (GtkCssCoreValues *values)
+{
+  values->_color = gtk_css_color_value_get_rgba (values->color);
+  values->_dpi = _gtk_css_number_value_get (values->dpi, 96);
+  values->_font_size = _gtk_css_number_value_get (values->font_size, 100);
+  values->_icon_theme = gtk_css_icon_theme_value_get_icon_theme (values->icon_theme);
+}
+
 static GtkCssValues *
 gtk_css_background_create_initial_values (void)
 {
@@ -754,6 +824,11 @@ gtk_css_background_create_initial_values (void)
   return (GtkCssValues *)values;
 }
 
+void
+gtk_css_background_values_unbox (GtkCssBackgroundValues *values)
+{
+}
+
 static GtkCssValues *
 gtk_css_border_create_initial_values (void)
 {
@@ -785,6 +860,35 @@ gtk_css_border_create_initial_values (void)
   return (GtkCssValues *)values;
 }
 
+void
+gtk_css_border_values_unbox (GtkCssBorderValues *values)
+{
+  values->_border_top_style = _gtk_css_border_style_value_get (values->border_top_style);
+  values->_border_right_style = _gtk_css_border_style_value_get (values->border_right_style);
+  values->_border_bottom_style = _gtk_css_border_style_value_get (values->border_bottom_style);
+  values->_border_left_style = _gtk_css_border_style_value_get (values->border_left_style);
+  values->_border_top_width = _gtk_css_number_value_get (values->border_top_width, 100);
+  values->_border_right_width = _gtk_css_number_value_get (values->border_right_width, 100);
+  values->_border_bottom_width = _gtk_css_number_value_get (values->border_bottom_width, 100);
+  values->_border_left_width = _gtk_css_number_value_get (values->border_left_width, 100);
+  values->_border_top_left_radius_x = _gtk_css_corner_value_get_x (values->border_top_left_radius, 100);
+  values->_border_top_left_radius_y = _gtk_css_corner_value_get_y (values->border_top_left_radius, 100);
+  values->_border_top_right_radius_x = _gtk_css_corner_value_get_x (values->border_top_right_radius, 100);
+  values->_border_top_right_radius_y = _gtk_css_corner_value_get_y (values->border_top_right_radius, 100);
+  values->_border_bottom_right_radius_x = _gtk_css_corner_value_get_x (values->border_bottom_right_radius, 
100);
+  values->_border_bottom_right_radius_y = _gtk_css_corner_value_get_y (values->border_bottom_right_radius, 
100);
+  values->_border_bottom_left_radius_x = _gtk_css_corner_value_get_x (values->border_bottom_left_radius, 
100);
+  values->_border_bottom_left_radius_y = _gtk_css_corner_value_get_y (values->border_bottom_left_radius, 
100);
+  if (values->border_top_color)
+    values->_border_top_color = gtk_css_color_value_get_rgba (values->border_top_color);
+  if (values->border_right_color)
+    values->_border_right_color = gtk_css_color_value_get_rgba (values->border_right_color);
+  if (values->border_bottom_color)
+    values->_border_bottom_color = gtk_css_color_value_get_rgba (values->border_bottom_color);
+  if (values->border_left_color)
+    values->_border_left_color = gtk_css_color_value_get_rgba (values->border_left_color);
+}
+
 static GtkCssValues *
 gtk_css_outline_create_initial_values (void)
 {
@@ -804,18 +908,46 @@ gtk_css_outline_create_initial_values (void)
   return (GtkCssValues *)values;
 }
 
+void
+gtk_css_outline_values_unbox (GtkCssOutlineValues *values)
+{
+  values->_outline_style = _gtk_css_border_style_value_get (values->outline_style);
+  values->_outline_width = _gtk_css_number_value_get (values->outline_width, 100);
+  values->_outline_offset = _gtk_css_number_value_get (values->outline_offset, 100);
+  values->_outline_top_left_radius_x = _gtk_css_corner_value_get_x (values->outline_top_left_radius, 100);
+  values->_outline_top_left_radius_y = _gtk_css_corner_value_get_y (values->outline_top_left_radius, 100);
+  values->_outline_top_right_radius_x = _gtk_css_corner_value_get_x (values->outline_top_right_radius, 100);
+  values->_outline_top_right_radius_y = _gtk_css_corner_value_get_y (values->outline_top_right_radius, 100);
+  values->_outline_bottom_right_radius_x = _gtk_css_corner_value_get_x (values->outline_bottom_right_radius, 
100);
+  values->_outline_bottom_right_radius_y = _gtk_css_corner_value_get_y (values->outline_bottom_right_radius, 
100);
+  values->_outline_bottom_left_radius_x = _gtk_css_corner_value_get_x (values->outline_bottom_left_radius, 
100);
+  values->_outline_bottom_left_radius_y = _gtk_css_corner_value_get_y (values->outline_bottom_left_radius, 
100);
+  if (values->outline_color)
+    values->_outline_color = gtk_css_color_value_get_rgba (values->outline_color);
+}
+
 static GtkCssValues *
 gtk_css_icon_create_initial_values (void)
 {
   return NULL;
 }
 
+void
+gtk_css_icon_values_unbox (GtkCssIconValues *values)
+{
+}
+
 static GtkCssValues *
 gtk_css_font_create_initial_values (void)
 {
   return NULL;
 }
 
+void
+gtk_css_font_values_unbox (GtkCssFontValues *values)
+{
+}
+
 static GtkCssValues *
 gtk_css_font_variant_create_initial_values (void)
 {
@@ -837,6 +969,11 @@ gtk_css_font_variant_create_initial_values (void)
   return (GtkCssValues *)values;
 }
 
+void
+gtk_css_font_variant_values_unbox (GtkCssFontVariantValues *values)
+{
+}
+
 static GtkCssValues *
 gtk_css_animation_create_initial_values (void)
 {
@@ -856,6 +993,11 @@ gtk_css_animation_create_initial_values (void)
   return (GtkCssValues *)values;
 }
 
+void
+gtk_css_animation_values_unbox (GtkCssAnimationValues *values)
+{
+}
+
 static GtkCssValues *
 gtk_css_transition_create_initial_values (void)
 {
@@ -871,6 +1013,11 @@ gtk_css_transition_create_initial_values (void)
   return (GtkCssValues *)values;
 }
 
+void
+gtk_css_transition_values_unbox (GtkCssTransitionValues *values)
+{
+}
+
 static GtkCssValues *
 gtk_css_size_create_initial_values (void)
 {
@@ -893,6 +1040,23 @@ gtk_css_size_create_initial_values (void)
   return (GtkCssValues *)values;
 }
 
+void
+gtk_css_size_values_unbox (GtkCssSizeValues *values)
+{
+   values->_margin_top = _gtk_css_number_value_get (values->margin_top, 100);
+   values->_margin_left = _gtk_css_number_value_get (values->margin_left, 100);
+   values->_margin_bottom = _gtk_css_number_value_get (values->margin_bottom, 100);
+   values->_margin_right = _gtk_css_number_value_get (values->margin_right, 100);
+   values->_padding_top = _gtk_css_number_value_get (values->padding_top, 100);
+   values->_padding_left = _gtk_css_number_value_get (values->padding_left, 100);
+   values->_padding_bottom = _gtk_css_number_value_get (values->padding_bottom, 100);
+   values->_padding_right = _gtk_css_number_value_get (values->padding_right, 100);
+   values->_border_spacing_x = _gtk_css_position_value_get_x (values->border_spacing, 100);
+   values->_border_spacing_y = _gtk_css_position_value_get_y (values->border_spacing, 100);
+   values->_min_width = _gtk_css_number_value_get (values->min_width, 100);
+   values->_min_height = _gtk_css_number_value_get (values->min_height, 100);
+}
+
 static GtkCssValues *
 gtk_css_other_create_initial_values (void)
 {
@@ -910,6 +1074,11 @@ gtk_css_other_create_initial_values (void)
   return (GtkCssValues *)values;
 }
 
+void
+gtk_css_other_values_unbox (GtkCssOtherValues *values)
+{
+}
+
 static void
 gtk_css_lookup_resolve (GtkCssLookup      *lookup,
                         GtkStyleProvider  *provider,
diff --git a/gtk/gtkcssstyle.c b/gtk/gtkcssstyle.c
index 24e1b5225c..2792ffbdc9 100644
--- a/gtk/gtkcssstyle.c
+++ b/gtk/gtkcssstyle.c
@@ -445,7 +445,7 @@ gtk_css_style_get_pango_attributes (GtkCssStyle *style)
   /* text-decoration */
   decoration_line = _gtk_css_text_decoration_line_value_get (style->font_variant->text_decoration_line);
   decoration_style = _gtk_css_text_decoration_style_value_get (style->font_variant->text_decoration_style);
-  color = gtk_css_color_value_get_rgba (style->core->color);
+  color = style->core->_color;
   decoration_color = gtk_css_color_value_get_rgba (style->font_variant->text_decoration_color
                                                    ? style->font_variant->text_decoration_color
                                                    : style->core->color);
@@ -666,8 +666,7 @@ gtk_css_style_get_pango_font (GtkCssStyle *style)
                                          _gtk_css_string_value_get (_gtk_css_array_value_get_nth (v, 0)));
     }
 
-  v = style->core->font_size;
-  pango_font_description_set_absolute_size (description, round (_gtk_css_number_value_get (v, 100) * 
PANGO_SCALE));
+  pango_font_description_set_absolute_size (description, round (style->core->_font_size * PANGO_SCALE));
 
   v = style->font->font_style;
   pango_font_description_set_style (description, _gtk_css_font_style_value_get (v));
@@ -702,9 +701,13 @@ static const int values_size[] = {
   sizeof (GtkCssOtherValues)
 };
 
+static int n_values[] = {
+  5, 9, 20, 3, 8, 10, 10, 8, 4, 11, 6
+};
+
 #define TYPE_INDEX(type) ((type) - ((type) % 2))
 #define VALUES_SIZE(type) (values_size[(type) / 2])
-#define N_VALUES(type) ((VALUES_SIZE(type) - sizeof (GtkCssValues)) / sizeof (GtkCssValue *))
+#define N_VALUES(type) (n_values[(type) / 2])
 
 #define GET_VALUES(v) (GtkCssValue **)((guint8 *)(v) + sizeof (GtkCssValues))
 
diff --git a/gtk/gtkcssstyleprivate.h b/gtk/gtkcssstyleprivate.h
index 8cf069c98d..7eee0812e3 100644
--- a/gtk/gtkcssstyleprivate.h
+++ b/gtk/gtkcssstyleprivate.h
@@ -25,6 +25,7 @@
 
 #include "gtk/gtkbitmaskprivate.h"
 #include "gtk/gtkcssvalueprivate.h"
+#include "gtk/gtkicontheme.h"
 
 G_BEGIN_DECLS
 
@@ -85,6 +86,11 @@ struct _GtkCssCoreValues {
   GtkCssValue *font_size;
   GtkCssValue *icon_theme;
   GtkCssValue *icon_palette;
+
+  const GdkRGBA *_color;
+  double         _dpi;
+  double         _font_size;
+  GtkIconTheme  *_icon_theme;
 };
 
 struct _GtkCssBackgroundValues {
@@ -122,6 +128,27 @@ struct _GtkCssBorderValues {
   GtkCssValue *border_image_repeat;
   GtkCssValue *border_image_slice;
   GtkCssValue *border_image_width;
+
+  GtkBorderStyle _border_top_style;
+  GtkBorderStyle _border_left_style;
+  GtkBorderStyle _border_bottom_style;
+  GtkBorderStyle _border_right_style;
+  double _border_top_width;
+  double _border_left_width;
+  double _border_bottom_width;
+  double _border_right_width;
+  double _border_top_left_radius_x;
+  double _border_top_left_radius_y;
+  double _border_top_right_radius_x;
+  double _border_top_right_radius_y;
+  double _border_bottom_right_radius_x;
+  double _border_bottom_right_radius_y;
+  double _border_bottom_left_radius_x;
+  double _border_bottom_left_radius_y;
+  const GdkRGBA *_border_top_color;
+  const GdkRGBA *_border_right_color;
+  const GdkRGBA *_border_bottom_color;
+  const GdkRGBA *_border_left_color;
 };
 
 struct _GtkCssIconValues {
@@ -141,7 +168,20 @@ struct _GtkCssOutlineValues {
   GtkCssValue *outline_top_right_radius;
   GtkCssValue *outline_bottom_right_radius;
   GtkCssValue *outline_bottom_left_radius;
-  GtkCssValue *outline_color;
+  GtkCssValue *outline_color; // NULL if currentColor
+
+  GtkBorderStyle _outline_style;
+  double         _outline_width;
+  double         _outline_offset;
+  double         _outline_top_left_radius_x;
+  double         _outline_top_left_radius_y;
+  double         _outline_top_right_radius_x;
+  double         _outline_top_right_radius_y;
+  double         _outline_bottom_right_radius_x;
+  double         _outline_bottom_right_radius_y;
+  double         _outline_bottom_left_radius_x;
+  double         _outline_bottom_left_radius_y;
+  const GdkRGBA *_outline_color;
 };
 
 struct _GtkCssFontValues {
@@ -205,6 +245,19 @@ struct _GtkCssSizeValues {
   GtkCssValue *border_spacing;
   GtkCssValue *min_width;
   GtkCssValue *min_height;
+
+  double _margin_top;
+  double _margin_left;
+  double _margin_bottom;
+  double _margin_right;
+  double _padding_top;
+  double _padding_left;
+  double _padding_bottom;
+  double _padding_right;
+  double _border_spacing_x;
+  double _border_spacing_y;
+  double _min_width;
+  double _min_height;
 };
 
 struct _GtkCssOtherValues {
diff --git a/gtk/gtkgridlayout.c b/gtk/gtkgridlayout.c
index f913490741..0f2f0f27a3 100644
--- a/gtk/gtkgridlayout.c
+++ b/gtk/gtkgridlayout.c
@@ -472,15 +472,12 @@ get_spacing (GtkGridLayout  *self,
 {
   GtkCssNode *node = gtk_widget_get_css_node (widget);
   GtkCssStyle *style = gtk_css_node_get_style (node);
-  GtkCssValue *border_spacing;
   int css_spacing;
 
-  border_spacing = style->size->border_spacing;
-
   if (orientation == GTK_ORIENTATION_HORIZONTAL)
-    css_spacing = _gtk_css_position_value_get_x (border_spacing, 100);
+    css_spacing = style->size->_border_spacing_x;
   else
-    css_spacing = _gtk_css_position_value_get_y (border_spacing, 100);
+    css_spacing = style->size->_border_spacing_y;
 
   return css_spacing + self->linedata[orientation].spacing;
 }
diff --git a/gtk/gtkwidget.c b/gtk/gtkwidget.c
index 447d39a16f..7c5c30460e 100644
--- a/gtk/gtkwidget.c
+++ b/gtk/gtkwidget.c
@@ -6545,7 +6545,7 @@ update_pango_context (GtkWidget    *widget,
                              _gtk_widget_get_direction (widget) == GTK_TEXT_DIR_LTR ?
                              PANGO_DIRECTION_LTR : PANGO_DIRECTION_RTL);
 
-  pango_cairo_context_set_resolution (context, _gtk_css_number_value_get (style->core->dpi, 100));
+  pango_cairo_context_set_resolution (context, style->core->_dpi);
 
   settings = gtk_widget_get_settings (widget);
   font_options = (cairo_font_options_t*)g_object_get_qdata (G_OBJECT (widget), quark_font_options);


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