[gtk+/wip/cssvalue: 116/142] cssvalue: Add a custom value for repeats



commit 1cfc8dd6a25666feb75059da3c5bbbe24ccfbafa
Author: Benjamin Otte <otte redhat com>
Date:   Wed Apr 4 11:44:57 2012 +0200

    cssvalue: Add a custom value for repeats
    
    In particular, that's background-repeat and border-image-repeat.
    
    Also, fix up the border-image shorthand to allow any order.

 gtk/Makefile.am                   |    2 +
 gtk/gtkborderimage.c              |   11 +-
 gtk/gtkborderimageprivate.h       |    4 +-
 gtk/gtkcsspositionvalue.c         |    6 -
 gtk/gtkcssrepeatvalue.c           |  299 +++++++++++++++++++++++++++++++++++++
 gtk/gtkcssrepeatvalueprivate.h    |   50 ++++++
 gtk/gtkcssshorthandpropertyimpl.c |  113 ++++++--------
 gtk/gtkcssstylefuncs.c            |   50 ------
 gtk/gtkcssstylepropertyimpl.c     |   93 +++---------
 gtk/gtkcsstypes.c                 |    1 -
 gtk/gtkcsstypesprivate.h          |   35 -----
 gtk/gtkcssvalue.c                 |   18 ---
 gtk/gtkcssvalueprivate.h          |    2 -
 gtk/gtkstylecontext.c             |   10 +-
 gtk/gtkthemingbackground.c        |   35 ++---
 15 files changed, 450 insertions(+), 279 deletions(-)
---
diff --git a/gtk/Makefile.am b/gtk/Makefile.am
index 8c98e61..a1c1147 100644
--- a/gtk/Makefile.am
+++ b/gtk/Makefile.am
@@ -445,6 +445,7 @@ gtk_private_h_sources =		\
 	gtkcssparserprivate.h	\
 	gtkcsspositionvalueprivate.h	\
 	gtkcssproviderprivate.h	\
+	gtkcssrepeatvalueprivate.h	\
 	gtkcssrgbavalueprivate.h	\
 	gtkcsssectionprivate.h 	\
 	gtkcssselectorprivate.h	\
@@ -656,6 +657,7 @@ gtk_base_c_sources = 		\
 	gtkcssparser.c		\
 	gtkcsspositionvalue.c	\
 	gtkcssprovider.c	\
+	gtkcssrepeatvalue.c	\
 	gtkcssrgbavalue.c	\
 	gtkcsssection.c 	\
 	gtkcssselector.c	\
diff --git a/gtk/gtkborderimage.c b/gtk/gtkborderimage.c
index f13cc86..9347860 100644
--- a/gtk/gtkborderimage.c
+++ b/gtk/gtkborderimage.c
@@ -26,6 +26,7 @@
 
 #include "gtkborderimageprivate.h"
 #include "gtkcssimagevalueprivate.h"
+#include "gtkcssrepeatvalueprivate.h"
 #include "gtkstylepropertiesprivate.h"
 #include "gtkthemingengineprivate.h"
 
@@ -54,7 +55,7 @@ _gtk_border_image_init (GtkBorderImage   *image,
   else
     image->has_width = FALSE;
 
-  image->repeat = *_gtk_css_value_get_border_image_repeat (_gtk_theming_engine_peek_property (engine, GTK_CSS_PROPERTY_BORDER_IMAGE_REPEAT));
+  image->repeat = _gtk_theming_engine_peek_property (engine, GTK_CSS_PROPERTY_BORDER_IMAGE_REPEAT);
 
   return TRUE;
 }
@@ -91,8 +92,8 @@ gtk_border_image_render_slice (cairo_t           *cr,
                                double             y,
                                double             width,
                                double             height,
-                               GtkCssBorderRepeatStyle  hrepeat,
-                               GtkCssBorderRepeatStyle  vrepeat)
+                               GtkCssRepeatStyle  hrepeat,
+                               GtkCssRepeatStyle  vrepeat)
 {
   double hscale, vscale;
   double xstep, ystep;
@@ -299,8 +300,8 @@ _gtk_border_image_render (GtkBorderImage   *image,
                                          vertical_border[v].offset,
                                          horizontal_border[h].size,
                                          vertical_border[v].size,
-                                         h == 1 ? image->repeat.hrepeat : GTK_CSS_REPEAT_STYLE_STRETCH,
-                                         v == 1 ? image->repeat.vrepeat : GTK_CSS_REPEAT_STYLE_STRETCH);
+                                         h == 1 ? _gtk_css_border_repeat_value_get_x (image->repeat) : GTK_CSS_REPEAT_STYLE_STRETCH,
+                                         v == 1 ? _gtk_css_border_repeat_value_get_y (image->repeat) : GTK_CSS_REPEAT_STYLE_STRETCH);
 
           cairo_surface_destroy (slice);
         }
diff --git a/gtk/gtkborderimageprivate.h b/gtk/gtkborderimageprivate.h
index 9d73fa7..c77de04 100644
--- a/gtk/gtkborderimageprivate.h
+++ b/gtk/gtkborderimageprivate.h
@@ -24,8 +24,8 @@
 
 #include "gtkborder.h"
 #include "gtkcssimageprivate.h"
+#include "gtkcssvalueprivate.h"
 #include "gtkthemingengine.h"
-#include "gtkcsstypesprivate.h"
 
 G_BEGIN_DECLS
 
@@ -37,7 +37,7 @@ struct _GtkBorderImage {
   GtkBorder slice;
   gboolean has_width;
   GtkBorder width;
-  GtkCssBorderImageRepeat repeat;
+  GtkCssValue *repeat;
 };
 
 gboolean          _gtk_border_image_init             (GtkBorderImage       *image,
diff --git a/gtk/gtkcsspositionvalue.c b/gtk/gtkcsspositionvalue.c
index d37d94c..61c34f3 100644
--- a/gtk/gtkcsspositionvalue.c
+++ b/gtk/gtkcsspositionvalue.c
@@ -120,12 +120,6 @@ gtk_css_value_position_print (const GtkCssValue *position,
         g_string_append (string, "center ");
       _gtk_css_value_print (position->y, string);
     }
-  _gtk_css_value_print (position->x, string);
-  if (!_gtk_css_value_equal (position->x, position->y))
-    {
-      g_string_append_c (string, ' ');
-      _gtk_css_value_print (position->y, string);
-    }
 
 done:
   for (i = 0; i < G_N_ELEMENTS (values); i++)
diff --git a/gtk/gtkcssrepeatvalue.c b/gtk/gtkcssrepeatvalue.c
new file mode 100644
index 0000000..0ec1ef7
--- /dev/null
+++ b/gtk/gtkcssrepeatvalue.c
@@ -0,0 +1,299 @@
+/* GTK - The GIMP Toolkit
+ * Copyright (C) 2011 Red Hat, Inc.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include "config.h"
+
+#include "gtkcssrepeatvalueprivate.h"
+
+#include "gtkcssnumbervalueprivate.h"
+
+struct _GtkCssValue {
+  GTK_CSS_VALUE_BASE
+  GtkCssRepeatStyle x;
+  GtkCssRepeatStyle y;
+};
+
+static void
+gtk_css_value_repeat_free (GtkCssValue *value)
+{
+  g_slice_free (GtkCssValue, value);
+}
+
+static gboolean
+gtk_css_value_repeat_equal (const GtkCssValue *repeat1,
+                            const GtkCssValue *repeat2)
+{
+  return repeat1->x == repeat2->x
+      && repeat1->y == repeat2->y;
+}
+
+static GtkCssValue *
+gtk_css_value_repeat_transition (GtkCssValue *start,
+                                 GtkCssValue *end,
+                                 double       progress)
+{
+  return NULL;
+}
+
+static void
+gtk_css_value_background_repeat_print (const GtkCssValue *repeat,
+                                       GString           *string)
+{
+  static const char *names[] = {
+    "no-repeat",
+    "repeat",
+    "round",
+    "space"
+  };
+
+  if (repeat->x == repeat->y)
+    {
+      g_string_append (string, names[repeat->x]);
+    }
+  else if (repeat->x == GTK_CSS_REPEAT_STYLE_REPEAT &&
+           repeat->y == GTK_CSS_REPEAT_STYLE_NO_REPEAT)
+    {
+      g_string_append (string, "repeat-x");
+    }
+  else if (repeat->x == GTK_CSS_REPEAT_STYLE_NO_REPEAT &&
+           repeat->y == GTK_CSS_REPEAT_STYLE_REPEAT)
+    {
+      g_string_append (string, "repeat-y");
+    }
+  else
+    {
+      g_string_append (string, names[repeat->x]);
+      g_string_append_c (string, ' ');
+      g_string_append (string, names[repeat->y]);
+    }
+}
+
+static void
+gtk_css_value_border_repeat_print (const GtkCssValue *repeat,
+                                   GString           *string)
+{
+  static const char *names[] = {
+    "stretch",
+    "repeat",
+    "round",
+    "space"
+  };
+
+  g_string_append (string, names[repeat->x]);
+  if (repeat->x != repeat->y)
+    {
+      g_string_append_c (string, ' ');
+      g_string_append (string, names[repeat->y]);
+    }
+}
+
+static const GtkCssValueClass GTK_CSS_VALUE_BACKGROUND_REPEAT = {
+  gtk_css_value_repeat_free,
+  gtk_css_value_repeat_equal,
+  gtk_css_value_repeat_transition,
+  gtk_css_value_background_repeat_print
+};
+
+static const GtkCssValueClass GTK_CSS_VALUE_BORDER_REPEAT = {
+  gtk_css_value_repeat_free,
+  gtk_css_value_repeat_equal,
+  gtk_css_value_repeat_transition,
+  gtk_css_value_border_repeat_print
+};
+/* BACKGROUND REPEAT */
+
+static struct {
+  const char *name;
+  GtkCssValue values[4];
+} background_repeat_values[4] = {
+  { "no-repeat",
+  { { &GTK_CSS_VALUE_BACKGROUND_REPEAT, 1, GTK_CSS_REPEAT_STYLE_NO_REPEAT, GTK_CSS_REPEAT_STYLE_NO_REPEAT },
+    { &GTK_CSS_VALUE_BACKGROUND_REPEAT, 1, GTK_CSS_REPEAT_STYLE_NO_REPEAT, GTK_CSS_REPEAT_STYLE_REPEAT    },
+    { &GTK_CSS_VALUE_BACKGROUND_REPEAT, 1, GTK_CSS_REPEAT_STYLE_NO_REPEAT, GTK_CSS_REPEAT_STYLE_ROUND     },
+    { &GTK_CSS_VALUE_BACKGROUND_REPEAT, 1, GTK_CSS_REPEAT_STYLE_NO_REPEAT, GTK_CSS_REPEAT_STYLE_SPACE     }
+  } },
+  { "repeat",
+  { { &GTK_CSS_VALUE_BACKGROUND_REPEAT, 1, GTK_CSS_REPEAT_STYLE_REPEAT,    GTK_CSS_REPEAT_STYLE_NO_REPEAT },
+    { &GTK_CSS_VALUE_BACKGROUND_REPEAT, 1, GTK_CSS_REPEAT_STYLE_REPEAT,    GTK_CSS_REPEAT_STYLE_REPEAT    },
+    { &GTK_CSS_VALUE_BACKGROUND_REPEAT, 1, GTK_CSS_REPEAT_STYLE_REPEAT,    GTK_CSS_REPEAT_STYLE_ROUND     },
+    { &GTK_CSS_VALUE_BACKGROUND_REPEAT, 1, GTK_CSS_REPEAT_STYLE_REPEAT,    GTK_CSS_REPEAT_STYLE_SPACE     }
+  } }, 
+  { "round",
+  { { &GTK_CSS_VALUE_BACKGROUND_REPEAT, 1, GTK_CSS_REPEAT_STYLE_ROUND,     GTK_CSS_REPEAT_STYLE_NO_REPEAT },
+    { &GTK_CSS_VALUE_BACKGROUND_REPEAT, 1, GTK_CSS_REPEAT_STYLE_ROUND,     GTK_CSS_REPEAT_STYLE_REPEAT    },
+    { &GTK_CSS_VALUE_BACKGROUND_REPEAT, 1, GTK_CSS_REPEAT_STYLE_ROUND,     GTK_CSS_REPEAT_STYLE_ROUND     },
+    { &GTK_CSS_VALUE_BACKGROUND_REPEAT, 1, GTK_CSS_REPEAT_STYLE_ROUND,     GTK_CSS_REPEAT_STYLE_SPACE     }
+  } }, 
+  { "space",
+  { { &GTK_CSS_VALUE_BACKGROUND_REPEAT, 1, GTK_CSS_REPEAT_STYLE_SPACE,     GTK_CSS_REPEAT_STYLE_NO_REPEAT },
+    { &GTK_CSS_VALUE_BACKGROUND_REPEAT, 1, GTK_CSS_REPEAT_STYLE_SPACE,     GTK_CSS_REPEAT_STYLE_REPEAT    },
+    { &GTK_CSS_VALUE_BACKGROUND_REPEAT, 1, GTK_CSS_REPEAT_STYLE_SPACE,     GTK_CSS_REPEAT_STYLE_ROUND     },
+    { &GTK_CSS_VALUE_BACKGROUND_REPEAT, 1, GTK_CSS_REPEAT_STYLE_SPACE,     GTK_CSS_REPEAT_STYLE_SPACE     }
+  } }
+};
+
+GtkCssValue *
+_gtk_css_background_repeat_value_new (GtkCssRepeatStyle x,
+                                      GtkCssRepeatStyle y)
+{
+  return _gtk_css_value_ref (&background_repeat_values[x].values[y]);
+}
+
+static gboolean
+_gtk_css_background_repeat_style_try (GtkCssParser      *parser,
+                                      GtkCssRepeatStyle *result)
+{
+  guint i;
+
+  for (i = 0; i < G_N_ELEMENTS (background_repeat_values); i++)
+    {
+      if (_gtk_css_parser_try (parser, background_repeat_values[i].name, TRUE))
+        {
+          *result = i;
+          return TRUE;
+        }
+    }
+
+  return FALSE;
+}
+
+GtkCssValue *
+_gtk_css_background_repeat_value_try_parse (GtkCssParser *parser)
+{
+  GtkCssRepeatStyle x, y;
+
+  g_return_val_if_fail (parser != NULL, NULL);
+
+  if (_gtk_css_parser_try (parser, "repeat-x", TRUE))
+    return _gtk_css_background_repeat_value_new (GTK_CSS_REPEAT_STYLE_REPEAT, GTK_CSS_REPEAT_STYLE_NO_REPEAT);
+  if (_gtk_css_parser_try (parser, "repeat-y", TRUE))
+    return _gtk_css_background_repeat_value_new (GTK_CSS_REPEAT_STYLE_NO_REPEAT, GTK_CSS_REPEAT_STYLE_REPEAT);
+
+  if (!_gtk_css_background_repeat_style_try (parser, &x))
+    return NULL;
+
+  if (!_gtk_css_background_repeat_style_try (parser, &y))
+    y = x;
+
+  return _gtk_css_background_repeat_value_new (x, y);
+}
+
+GtkCssRepeatStyle
+_gtk_css_background_repeat_value_get_x (const GtkCssValue *repeat)
+{
+  g_return_val_if_fail (repeat->class == &GTK_CSS_VALUE_BACKGROUND_REPEAT, GTK_CSS_REPEAT_STYLE_NO_REPEAT);
+
+  return repeat->x;
+}
+
+GtkCssRepeatStyle
+_gtk_css_background_repeat_value_get_y (const GtkCssValue *repeat)
+{
+  g_return_val_if_fail (repeat->class == &GTK_CSS_VALUE_BACKGROUND_REPEAT, GTK_CSS_REPEAT_STYLE_NO_REPEAT);
+
+  return repeat->y;
+}
+
+/* BORDER IMAGE REPEAT */
+
+static struct {
+  const char *name;
+  GtkCssValue values[4];
+} border_repeat_values[4] = {
+  { "stretch",
+  { { &GTK_CSS_VALUE_BORDER_REPEAT, 1, GTK_CSS_REPEAT_STYLE_STRETCH, GTK_CSS_REPEAT_STYLE_STRETCH },
+    { &GTK_CSS_VALUE_BORDER_REPEAT, 1, GTK_CSS_REPEAT_STYLE_STRETCH, GTK_CSS_REPEAT_STYLE_REPEAT  },
+    { &GTK_CSS_VALUE_BORDER_REPEAT, 1, GTK_CSS_REPEAT_STYLE_STRETCH, GTK_CSS_REPEAT_STYLE_ROUND   },
+    { &GTK_CSS_VALUE_BORDER_REPEAT, 1, GTK_CSS_REPEAT_STYLE_STRETCH, GTK_CSS_REPEAT_STYLE_SPACE   }
+  } },
+  { "repeat",
+  { { &GTK_CSS_VALUE_BORDER_REPEAT, 1, GTK_CSS_REPEAT_STYLE_REPEAT,  GTK_CSS_REPEAT_STYLE_STRETCH },
+    { &GTK_CSS_VALUE_BORDER_REPEAT, 1, GTK_CSS_REPEAT_STYLE_REPEAT,  GTK_CSS_REPEAT_STYLE_REPEAT  },
+    { &GTK_CSS_VALUE_BORDER_REPEAT, 1, GTK_CSS_REPEAT_STYLE_REPEAT,  GTK_CSS_REPEAT_STYLE_ROUND   },
+    { &GTK_CSS_VALUE_BORDER_REPEAT, 1, GTK_CSS_REPEAT_STYLE_REPEAT,  GTK_CSS_REPEAT_STYLE_SPACE   }
+  } }, 
+  { "round",
+  { { &GTK_CSS_VALUE_BORDER_REPEAT, 1, GTK_CSS_REPEAT_STYLE_ROUND,   GTK_CSS_REPEAT_STYLE_STRETCH },
+    { &GTK_CSS_VALUE_BORDER_REPEAT, 1, GTK_CSS_REPEAT_STYLE_ROUND,   GTK_CSS_REPEAT_STYLE_REPEAT  },
+    { &GTK_CSS_VALUE_BORDER_REPEAT, 1, GTK_CSS_REPEAT_STYLE_ROUND,   GTK_CSS_REPEAT_STYLE_ROUND   },
+    { &GTK_CSS_VALUE_BORDER_REPEAT, 1, GTK_CSS_REPEAT_STYLE_ROUND,   GTK_CSS_REPEAT_STYLE_SPACE   }
+  } }, 
+  { "space",
+  { { &GTK_CSS_VALUE_BORDER_REPEAT, 1, GTK_CSS_REPEAT_STYLE_SPACE,   GTK_CSS_REPEAT_STYLE_STRETCH },
+    { &GTK_CSS_VALUE_BORDER_REPEAT, 1, GTK_CSS_REPEAT_STYLE_SPACE,   GTK_CSS_REPEAT_STYLE_REPEAT  },
+    { &GTK_CSS_VALUE_BORDER_REPEAT, 1, GTK_CSS_REPEAT_STYLE_SPACE,   GTK_CSS_REPEAT_STYLE_ROUND   },
+    { &GTK_CSS_VALUE_BORDER_REPEAT, 1, GTK_CSS_REPEAT_STYLE_SPACE,   GTK_CSS_REPEAT_STYLE_SPACE   }
+  } }
+};
+
+GtkCssValue *
+_gtk_css_border_repeat_value_new (GtkCssRepeatStyle x,
+                                  GtkCssRepeatStyle y)
+{
+  return _gtk_css_value_ref (&border_repeat_values[x].values[y]);
+}
+
+static gboolean
+_gtk_css_border_repeat_style_try (GtkCssParser      *parser,
+                                  GtkCssRepeatStyle *result)
+{
+  guint i;
+
+  for (i = 0; i < G_N_ELEMENTS (border_repeat_values); i++)
+    {
+      if (_gtk_css_parser_try (parser, border_repeat_values[i].name, TRUE))
+        {
+          *result = i;
+          return TRUE;
+        }
+    }
+
+  return FALSE;
+}
+
+GtkCssValue *
+_gtk_css_border_repeat_value_try_parse (GtkCssParser *parser)
+{
+  GtkCssRepeatStyle x, y;
+
+  g_return_val_if_fail (parser != NULL, NULL);
+
+  if (!_gtk_css_border_repeat_style_try (parser, &x))
+    return NULL;
+
+  if (!_gtk_css_border_repeat_style_try (parser, &y))
+    y = x;
+
+  return _gtk_css_border_repeat_value_new (x, y);
+}
+
+GtkCssRepeatStyle
+_gtk_css_border_repeat_value_get_x (const GtkCssValue *repeat)
+{
+  g_return_val_if_fail (repeat->class == &GTK_CSS_VALUE_BORDER_REPEAT, GTK_CSS_REPEAT_STYLE_STRETCH);
+
+  return repeat->x;
+}
+
+GtkCssRepeatStyle
+_gtk_css_border_repeat_value_get_y (const GtkCssValue *repeat)
+{
+  g_return_val_if_fail (repeat->class == &GTK_CSS_VALUE_BORDER_REPEAT, GTK_CSS_REPEAT_STYLE_STRETCH);
+
+  return repeat->y;
+}
+
diff --git a/gtk/gtkcssrepeatvalueprivate.h b/gtk/gtkcssrepeatvalueprivate.h
new file mode 100644
index 0000000..7e8baa3
--- /dev/null
+++ b/gtk/gtkcssrepeatvalueprivate.h
@@ -0,0 +1,50 @@
+/*
+ * Copyright  2012 Red Hat Inc.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library. If not, see <http://www.gnu.org/licenses/>.
+ *
+ * Authors: Alexander Larsson <alexl gnome org>
+ */
+
+#ifndef __GTK_CSS_REPEAT_VALUE_PRIVATE_H__
+#define __GTK_CSS_REPEAT_VALUE_PRIVATE_H__
+
+#include "gtkcssparserprivate.h"
+#include "gtkcssvalueprivate.h"
+
+G_BEGIN_DECLS
+
+typedef enum {
+  GTK_CSS_REPEAT_STYLE_NO_REPEAT,
+  GTK_CSS_REPEAT_STYLE_STRETCH = GTK_CSS_REPEAT_STYLE_NO_REPEAT,
+  GTK_CSS_REPEAT_STYLE_REPEAT,
+  GTK_CSS_REPEAT_STYLE_ROUND,
+  GTK_CSS_REPEAT_STYLE_SPACE
+} GtkCssRepeatStyle;
+
+GtkCssValue *       _gtk_css_background_repeat_value_new        (GtkCssRepeatStyle       x,
+                                                                 GtkCssRepeatStyle       y);
+GtkCssValue *       _gtk_css_background_repeat_value_try_parse  (GtkCssParser           *parser);
+GtkCssRepeatStyle   _gtk_css_background_repeat_value_get_x      (const GtkCssValue      *repeat);
+GtkCssRepeatStyle   _gtk_css_background_repeat_value_get_y      (const GtkCssValue      *repeat);
+
+GtkCssValue *       _gtk_css_border_repeat_value_new            (GtkCssRepeatStyle       x,
+                                                                 GtkCssRepeatStyle       y);
+GtkCssValue *       _gtk_css_border_repeat_value_try_parse      (GtkCssParser           *parser);
+GtkCssRepeatStyle   _gtk_css_border_repeat_value_get_x          (const GtkCssValue      *repeat);
+GtkCssRepeatStyle   _gtk_css_border_repeat_value_get_y          (const GtkCssValue      *repeat);
+
+G_END_DECLS
+
+#endif /* __GTK_CSS_REPEAT_VALUE_PRIVATE_H__ */
diff --git a/gtk/gtkcssshorthandpropertyimpl.c b/gtk/gtkcssshorthandpropertyimpl.c
index 1e940a3..f93859c 100644
--- a/gtk/gtkcssshorthandpropertyimpl.c
+++ b/gtk/gtkcssshorthandpropertyimpl.c
@@ -30,6 +30,7 @@
 #include "gtkcssimageprivate.h"
 #include "gtkcssimagevalueprivate.h"
 #include "gtkcssnumbervalueprivate.h"
+#include "gtkcssrepeatvalueprivate.h"
 #include "gtkcssstringvalueprivate.h"
 #include "gtkcssstylefuncsprivate.h"
 #include "gtkcsstypesprivate.h"
@@ -277,45 +278,58 @@ parse_border_image (GtkCssShorthandProperty  *shorthand,
                     GtkCssParser             *parser,
                     GFile                    *base)
 {
-  GValue value = G_VALUE_INIT;
-  GtkCssImage *image;
-  
-  if (_gtk_css_parser_try (parser, "none", TRUE))
-    image = NULL;
-  else
+  do
     {
-      image = _gtk_css_image_new_parse (parser, base);
-      if (!image)
-        return FALSE;
-    }
-  values[0] = _gtk_css_image_value_new (image);
-
-  if (value_is_done_parsing (parser))
-    return TRUE;
+      if (values[0] == NULL &&
+          (_gtk_css_parser_has_prefix (parser, "none") ||
+           _gtk_css_image_can_parse (parser)))
+        {
+          GtkCssImage *image;
 
-  g_value_init (&value, GTK_TYPE_BORDER);
-  if (!_gtk_css_style_parse_value (&value, parser, base))
-    return FALSE;
-  values[1] = _gtk_css_value_new_from_gvalue (&value);
-  g_value_unset (&value);
+          if (_gtk_css_parser_try (parser, "none", TRUE))
+            image = NULL;
+          else
+            {
+              image = _gtk_css_image_new_parse (parser, base);
+              if (image == NULL)
+                return FALSE;
+            }
 
-  if (_gtk_css_parser_try (parser, "/", TRUE))
-    {
-      g_value_init (&value, GTK_TYPE_BORDER);
-      if (!_gtk_css_style_parse_value (&value, parser, base))
-        return FALSE;
-      values[2] = _gtk_css_value_new_from_gvalue (&value);
-      g_value_unset (&value);
-    }
+          values[0] = _gtk_css_image_value_new (image);
+        }
+      else if (values[3] == NULL &&
+               (values[3] = _gtk_css_border_repeat_value_try_parse (parser)))
+        {
+          /* please move along */
+        }
+      else if (values[1] == NULL)
+        {
+          GValue value = G_VALUE_INIT;
 
-  if (value_is_done_parsing (parser))
-    return TRUE;
+          g_value_init (&value, GTK_TYPE_BORDER);
+          if (!_gtk_css_style_parse_value (&value, parser, base))
+            return FALSE;
+          values[1] = _gtk_css_value_new_from_gvalue (&value);
+          g_value_unset (&value);
 
-  g_value_init (&value, GTK_TYPE_CSS_BORDER_IMAGE_REPEAT);
-  if (!_gtk_css_style_parse_value (&value, parser, base))
-    return FALSE;
-  values[3] = _gtk_css_value_new_from_gvalue (&value);
-  g_value_unset (&value);
+          if (_gtk_css_parser_try (parser, "/", TRUE))
+            {
+              g_value_init (&value, GTK_TYPE_BORDER);
+              if (!_gtk_css_style_parse_value (&value, parser, base))
+                return FALSE;
+              values[2] = _gtk_css_value_new_from_gvalue (&value);
+              g_value_unset (&value);
+            }
+        }
+      else
+        {
+          /* We parsed everything and there's still stuff left?
+           * Pretend we didn't notice and let the normal code produce
+           * a 'junk at end of value' error */
+          break;
+        }
+    }
+  while (!value_is_done_parsing (parser));
 
   return TRUE;
 }
@@ -353,13 +367,6 @@ parse_border_side (GtkCssShorthandProperty  *shorthand,
 
         values[2] = _gtk_css_value_new_take_symbolic_color (symbolic);
       }
-    else
-      {
-        /* We parsed everything and there's still stuff left?
-         * Pretend we didn't notice and let the normal code produce
-         * a 'junk at end of value' error */
-        break;
-      }
   }
   while (!value_is_done_parsing (parser));
 
@@ -474,8 +481,6 @@ parse_background (GtkCssShorthandProperty  *shorthand,
                   GtkCssParser             *parser,
                   GFile                    *base)
 {
-  int enum_value;
-
   do
     {
       /* the image part */
@@ -497,27 +502,9 @@ parse_background (GtkCssShorthandProperty  *shorthand,
           values[0] = _gtk_css_image_value_new (image);
         }
       else if (values[1] == NULL &&
-               _gtk_css_parser_try_enum (parser, GTK_TYPE_CSS_BACKGROUND_REPEAT, &enum_value))
+               (values[1] = _gtk_css_background_repeat_value_try_parse (parser)))
         {
-          if (enum_value <= GTK_CSS_BACKGROUND_REPEAT_MASK)
-            {
-              int vertical;
-
-              if (_gtk_css_parser_try_enum (parser, GTK_TYPE_CSS_BACKGROUND_REPEAT, &vertical))
-                {
-                  if (vertical >= GTK_CSS_BACKGROUND_REPEAT_MASK)
-                    {
-                      _gtk_css_parser_error (parser, "Not a valid 2nd value for border-repeat");
-                      return FALSE;
-                    }
-                  else
-                    enum_value |= vertical << GTK_CSS_BACKGROUND_REPEAT_SHIFT;
-                }
-              else
-                enum_value |= enum_value << GTK_CSS_BACKGROUND_REPEAT_SHIFT;
-            }
-
-          values[1] = _gtk_css_value_new_from_enum (GTK_TYPE_CSS_BACKGROUND_REPEAT, enum_value);
+          /* nothing to do here */
         }
       else if ((values[2] == NULL || values[3] == NULL) &&
                (values[3] = _gtk_css_area_value_try_parse (parser)))
diff --git a/gtk/gtkcssstylefuncs.c b/gtk/gtkcssstylefuncs.c
index 518a327..2105d5a 100644
--- a/gtk/gtkcssstylefuncs.c
+++ b/gtk/gtkcssstylefuncs.c
@@ -887,52 +887,6 @@ pattern_value_compute (GtkStyleContext *context,
     return _gtk_css_value_ref (specified);
 }
 
-static gboolean
-border_image_repeat_value_parse (GtkCssParser *parser,
-                                 GFile *file,
-                                 GValue *value)
-{
-  GtkCssBorderImageRepeat image_repeat;
-  GtkCssBorderRepeatStyle styles[2];
-  gint i, v;
-
-  for (i = 0; i < 2; i++)
-    {
-      if (_gtk_css_parser_try_enum (parser, GTK_TYPE_CSS_BORDER_REPEAT_STYLE, &v))
-        styles[i] = v;
-      else if (i == 0)
-        {
-          styles[1] = styles[0] = GTK_CSS_REPEAT_STYLE_STRETCH;
-          break;
-        }
-      else
-        styles[i] = styles[0];
-    }
-
-  image_repeat.hrepeat = styles[0];
-  image_repeat.vrepeat = styles[1];
-
-  g_value_set_boxed (value, &image_repeat);
-
-  return TRUE;
-}
-
-static void
-border_image_repeat_value_print (const GValue *value,
-                                 GString      *string)
-{
-  GtkCssBorderImageRepeat *image_repeat;
-
-  image_repeat = g_value_get_boxed (value);
-
-  enum_print (image_repeat->hrepeat, GTK_TYPE_CSS_BORDER_REPEAT_STYLE, string);
-  if (image_repeat->hrepeat != image_repeat->vrepeat)
-    {
-      g_string_append (string, " ");
-      enum_print (image_repeat->vrepeat, GTK_TYPE_CSS_BORDER_REPEAT_STYLE, string);
-    }
-}
-
 static gboolean 
 enum_value_parse (GtkCssParser *parser,
                   GFile        *base,
@@ -1100,10 +1054,6 @@ gtk_css_style_funcs_init (void)
                                 pattern_value_parse,
                                 pattern_value_print,
                                 pattern_value_compute);
-  register_conversion_function (GTK_TYPE_CSS_BORDER_IMAGE_REPEAT,
-                                border_image_repeat_value_parse,
-                                border_image_repeat_value_print,
-                                NULL);
   register_conversion_function (G_TYPE_ENUM,
                                 enum_value_parse,
                                 enum_value_print,
diff --git a/gtk/gtkcssstylepropertyimpl.c b/gtk/gtkcssstylepropertyimpl.c
index 19fc6de..4100125 100644
--- a/gtk/gtkcssstylepropertyimpl.c
+++ b/gtk/gtkcssstylepropertyimpl.c
@@ -50,6 +50,7 @@
 #include "gtkcssenumvalueprivate.h"
 #include "gtkcssnumbervalueprivate.h"
 #include "gtkcsspositionvalueprivate.h"
+#include "gtkcssrepeatvalueprivate.h"
 #include "gtkcssrgbavalueprivate.h"
 #include "gtkcssshadowsvalueprivate.h"
 #include "gtkcssstringvalueprivate.h"
@@ -655,20 +656,15 @@ border_image_repeat_parse (GtkCssStyleProperty *property,
                            GtkCssParser        *parser,
                            GFile               *base)
 {
-  GValue value = G_VALUE_INIT;
-  GtkCssValue *result;
+  GtkCssValue *value = _gtk_css_border_repeat_value_try_parse (parser);
 
-  g_value_init (&value, GTK_TYPE_CSS_BORDER_IMAGE_REPEAT);
-  if (!_gtk_css_style_parse_value (&value, parser, base))
+  if (value == NULL)
     {
-      g_value_unset (&value);
+      _gtk_css_parser_error (parser, "Not a valid value");
       return NULL;
     }
 
-  result = _gtk_css_value_new_from_gvalue (&value);
-  g_value_unset (&value);
-
-  return result;
+  return value;
 }
 
 static GtkCssValue *
@@ -876,63 +872,15 @@ background_repeat_value_parse (GtkCssStyleProperty *property,
                                GtkCssParser        *parser,
                                GFile               *base)
 {
-  int repeat, vertical;
+  GtkCssValue *value = _gtk_css_background_repeat_value_try_parse (parser);
 
-  if (!_gtk_css_parser_try_enum (parser, GTK_TYPE_CSS_BACKGROUND_REPEAT, &repeat))
+  if (value == NULL)
     {
       _gtk_css_parser_error (parser, "Not a valid value");
-      return FALSE;
-    }
-
-  if (repeat <= GTK_CSS_BACKGROUND_REPEAT_MASK)
-    {
-      if (_gtk_css_parser_try_enum (parser, GTK_TYPE_CSS_BACKGROUND_REPEAT, &vertical))
-        {
-          if (vertical >= GTK_CSS_BACKGROUND_REPEAT_MASK)
-            {
-              _gtk_css_parser_error (parser, "Not a valid 2nd value");
-              return FALSE;
-            }
-          else
-            repeat |= vertical << GTK_CSS_BACKGROUND_REPEAT_SHIFT;
-        }
-      else
-        repeat |= repeat << GTK_CSS_BACKGROUND_REPEAT_SHIFT;
-    }
-
-  return _gtk_css_value_new_from_enum (GTK_TYPE_CSS_BACKGROUND_REPEAT, repeat);
-}
-
-static void
-background_repeat_value_print (GtkCssStyleProperty *property,
-                               const GtkCssValue   *value,
-                               GString             *string)
-{
-  GEnumClass *enum_class;
-  GEnumValue *enum_value;
-  GtkCssBackgroundRepeat repeat;
-
-  repeat = _gtk_css_value_get_enum (value);
-  enum_class = g_type_class_ref (GTK_TYPE_CSS_BACKGROUND_REPEAT);
-  enum_value = g_enum_get_value (enum_class, repeat);
-
-  /* only triggers for 'repeat-x' and 'repeat-y' */
-  if (enum_value)
-    g_string_append (string, enum_value->value_nick);
-  else
-    {
-      enum_value = g_enum_get_value (enum_class, GTK_CSS_BACKGROUND_HORIZONTAL (repeat));
-      g_string_append (string, enum_value->value_nick);
-
-      if (GTK_CSS_BACKGROUND_HORIZONTAL (repeat) != GTK_CSS_BACKGROUND_VERTICAL (repeat))
-        {
-          enum_value = g_enum_get_value (enum_class, GTK_CSS_BACKGROUND_VERTICAL (repeat));
-          g_string_append (string, " ");
-          g_string_append (string, enum_value->value_nick);
-        }
+      return NULL;
     }
 
-  g_type_class_unref (enum_class);
+  return value;
 }
 
 static GtkCssValue *
@@ -1057,7 +1005,6 @@ _gtk_css_style_property_init_properties (void)
 {
   GtkCssBackgroundSize default_background_size = { GTK_CSS_NUMBER_INIT (0, GTK_CSS_PX), GTK_CSS_NUMBER_INIT (0, GTK_CSS_PX), FALSE, FALSE };
   GtkBorder border_of_ones = { 1, 1, 1, 1 };
-  GtkCssBorderImageRepeat border_image_repeat = { GTK_CSS_REPEAT_STYLE_STRETCH, GTK_CSS_REPEAT_STYLE_STRETCH };
 
   /* Initialize "color" and "font-size" first,
    * so that when computing values later they are
@@ -1561,17 +1508,16 @@ _gtk_css_style_property_init_properties (void)
 
   gtk_css_style_property_register        ("background-repeat",
                                           GTK_CSS_PROPERTY_BACKGROUND_REPEAT,
-                                          GTK_TYPE_CSS_BACKGROUND_REPEAT,
+                                          G_TYPE_NONE,
                                           0,
                                           background_repeat_value_parse,
-                                          background_repeat_value_print,
                                           NULL,
-                                          query_simple,
-                                          assign_simple,
                                           NULL,
-                                          _gtk_css_value_new_from_enum (GTK_TYPE_CSS_BACKGROUND_REPEAT,
-                                                                        GTK_CSS_BACKGROUND_REPEAT | 
-                                                                        (GTK_CSS_BACKGROUND_REPEAT << GTK_CSS_BACKGROUND_REPEAT_SHIFT)));
+                                          NULL,
+                                          NULL,
+                                          NULL,
+                                          _gtk_css_background_repeat_value_new (GTK_CSS_REPEAT_STYLE_REPEAT,
+                                                                                GTK_CSS_REPEAT_STYLE_REPEAT));
   gtk_css_style_property_register        ("background-image",
                                           GTK_CSS_PROPERTY_BACKGROUND_IMAGE,
                                           CAIRO_GOBJECT_TYPE_PATTERN,
@@ -1597,15 +1543,16 @@ _gtk_css_style_property_init_properties (void)
                                           _gtk_css_image_value_new (NULL));
   gtk_css_style_property_register        ("border-image-repeat",
                                           GTK_CSS_PROPERTY_BORDER_IMAGE_REPEAT,
-                                          GTK_TYPE_CSS_BORDER_IMAGE_REPEAT,
+                                          G_TYPE_NONE,
                                           0,
                                           border_image_repeat_parse,
                                           NULL,
                                           NULL,
-                                          query_simple,
-                                          assign_simple,
                                           NULL,
-                                          _gtk_css_value_new_from_border_image_repeat (&border_image_repeat));
+                                          NULL,
+                                          NULL,
+                                          _gtk_css_border_repeat_value_new (GTK_CSS_REPEAT_STYLE_STRETCH,
+                                                                            GTK_CSS_REPEAT_STYLE_STRETCH));
 
   /* XXX: The initial value is wrong, it should be 100% */
   gtk_css_style_property_register        ("border-image-slice",
diff --git a/gtk/gtkcsstypes.c b/gtk/gtkcsstypes.c
index 4347d5a..af1a699 100644
--- a/gtk/gtkcsstypes.c
+++ b/gtk/gtkcsstypes.c
@@ -33,7 +33,6 @@ type_name ## _copy (const TypeName *foo) \
 G_DEFINE_BOXED_TYPE (TypeName, type_name, type_name ## _copy, g_free)
 
 DEFINE_BOXED_TYPE_WITH_COPY_FUNC (GtkCssBackgroundSize, _gtk_css_background_size)
-DEFINE_BOXED_TYPE_WITH_COPY_FUNC (GtkCssBorderImageRepeat, _gtk_css_border_image_repeat)
 
 typedef struct _GtkCssChangeTranslation GtkCssChangeTranslation;
 struct _GtkCssChangeTranslation {
diff --git a/gtk/gtkcsstypesprivate.h b/gtk/gtkcsstypesprivate.h
index c260d27..cc56937 100644
--- a/gtk/gtkcsstypesprivate.h
+++ b/gtk/gtkcsstypesprivate.h
@@ -112,33 +112,6 @@ enum { /*< skip >*/
   GTK_CSS_PROPERTY_GTK_KEY_BINDINGS
 };
 
-/* We encode horizontal and vertical repeat in one enum value.
- * This eases parsing and storage, but you need to be aware that
- * you have to "unpack" this value.
- */
-#define GTK_CSS_BACKGROUND_REPEAT_SHIFT (8)
-#define GTK_CSS_BACKGROUND_REPEAT_MASK ((1 << GTK_CSS_BACKGROUND_REPEAT_SHIFT) - 1)
-#define GTK_CSS_BACKGROUND_HORIZONTAL(repeat) ((repeat) & GTK_CSS_BACKGROUND_REPEAT_MASK)
-#define GTK_CSS_BACKGROUND_VERTICAL(repeat) (((repeat) >> GTK_CSS_BACKGROUND_REPEAT_SHIFT) & GTK_CSS_BACKGROUND_REPEAT_MASK)
-typedef enum /*< enum >*/
-{
-  GTK_CSS_BACKGROUND_INVALID, /*< skip >*/
-  GTK_CSS_BACKGROUND_REPEAT, /* start at one so we know if a value has been set */
-  GTK_CSS_BACKGROUND_SPACE,
-  GTK_CSS_BACKGROUND_ROUND,
-  GTK_CSS_BACKGROUND_NO_REPEAT,
-  /* need to hardcode the numer or glib-mkenums makes us into a flags type */
-  GTK_CSS_BACKGROUND_REPEAT_X = 1025,
-  GTK_CSS_BACKGROUND_REPEAT_Y = 260
-} GtkCssBackgroundRepeat;
-
-typedef enum {
-  GTK_CSS_REPEAT_STYLE_STRETCH,
-  GTK_CSS_REPEAT_STYLE_REPEAT,
-  GTK_CSS_REPEAT_STYLE_ROUND,
-  GTK_CSS_REPEAT_STYLE_SPACE
-} GtkCssBorderRepeatStyle;
-
 typedef enum /*< skip >*/ {
   GTK_CSS_AREA_BORDER_BOX,
   GTK_CSS_AREA_PADDING_BOX,
@@ -186,7 +159,6 @@ typedef enum /*< skip >*/ {
 
 typedef struct _GtkCssNumber GtkCssNumber;
 typedef struct _GtkCssBackgroundSize GtkCssBackgroundSize;
-typedef struct _GtkCssBorderImageRepeat GtkCssBorderImageRepeat;
 
 struct _GtkCssNumber {
   gdouble        value;
@@ -200,16 +172,9 @@ struct _GtkCssBackgroundSize {
   guint contain :1;
 };
 
-struct _GtkCssBorderImageRepeat {
-  GtkCssBorderRepeatStyle vrepeat;
-  GtkCssBorderRepeatStyle hrepeat;
-};
-
 #define GTK_TYPE_CSS_BACKGROUND_SIZE _gtk_css_background_size_get_type ()
-#define GTK_TYPE_CSS_BORDER_IMAGE_REPEAT _gtk_css_border_image_repeat_get_type ()
 
 GType           _gtk_css_background_size_get_type               (void);
-GType           _gtk_css_border_image_repeat_get_type           (void);
 
 GtkCssChange    _gtk_css_change_for_sibling                      (GtkCssChange       match);
 GtkCssChange    _gtk_css_change_for_child                        (GtkCssChange       match);
diff --git a/gtk/gtkcssvalue.c b/gtk/gtkcssvalue.c
index a67da3b..25a0a1d 100644
--- a/gtk/gtkcssvalue.c
+++ b/gtk/gtkcssvalue.c
@@ -261,17 +261,6 @@ _gtk_css_value_new_from_background_size (const GtkCssBackgroundSize *v)
 }
 
 GtkCssValue *
-_gtk_css_value_new_from_border_image_repeat (const GtkCssBorderImageRepeat *v)
-{
-  GtkCssValue *value;
-
-  value = gtk_css_value_new (GTK_TYPE_CSS_BORDER_IMAGE_REPEAT);
-  value->u.ptr = g_boxed_copy0 (GTK_TYPE_CSS_BORDER_IMAGE_REPEAT, v);
-
-  return value;
-}
-
-GtkCssValue *
 _gtk_css_value_new_from_border_style (GtkBorderStyle style)
 {
   GtkCssValue *value;
@@ -503,13 +492,6 @@ _gtk_css_value_get_background_size (const GtkCssValue *value)
   return value->u.ptr;
 }
 
-const GtkCssBorderImageRepeat *
-_gtk_css_value_get_border_image_repeat (const GtkCssValue *value)
-{
-  g_return_val_if_fail (_gtk_css_value_holds (value, GTK_TYPE_CSS_BORDER_IMAGE_REPEAT), NULL);
-  return value->u.ptr;
-}
-
 GtkGradient *
 _gtk_css_value_get_gradient (const GtkCssValue *value)
 {
diff --git a/gtk/gtkcssvalueprivate.h b/gtk/gtkcssvalueprivate.h
index b7d0656..7cd450a 100644
--- a/gtk/gtkcssvalueprivate.h
+++ b/gtk/gtkcssvalueprivate.h
@@ -89,7 +89,6 @@ GtkCssValue *_gtk_css_value_new_take_symbolic_color   (GtkSymbolicColor
 GtkCssValue *_gtk_css_value_new_take_pattern          (cairo_pattern_t            *v);
 GtkCssValue *_gtk_css_value_new_take_binding_sets     (GPtrArray                  *array);
 GtkCssValue *_gtk_css_value_new_from_background_size  (const GtkCssBackgroundSize *v);
-GtkCssValue *_gtk_css_value_new_from_border_image_repeat (const GtkCssBorderImageRepeat *v);
 void         _gtk_css_value_init_gvalue               (const GtkCssValue          *value,
 						       GValue                     *g_value);
 
@@ -101,7 +100,6 @@ gpointer                        _gtk_css_value_get_boxed                  (const
 const char **                   _gtk_css_value_get_strv                   (const GtkCssValue *value);
 GtkSymbolicColor               *_gtk_css_value_get_symbolic_color         (const GtkCssValue *value);
 const GtkCssBackgroundSize     *_gtk_css_value_get_background_size        (const GtkCssValue *value);
-const GtkCssBorderImageRepeat  *_gtk_css_value_get_border_image_repeat    (const GtkCssValue *value);
 GtkGradient                    *_gtk_css_value_get_gradient               (const GtkCssValue *value);
 
 G_END_DECLS
diff --git a/gtk/gtkstylecontext.c b/gtk/gtkstylecontext.c
index 43f87c0..b59d217 100644
--- a/gtk/gtkstylecontext.c
+++ b/gtk/gtkstylecontext.c
@@ -23,6 +23,7 @@
 #include <gobject/gvaluecollector.h>
 
 #include "gtkstylecontextprivate.h"
+#include "gtkcssenginevalueprivate.h"
 #include "gtkcssrgbavalueprivate.h"
 #include "gtkstylepropertiesprivate.h"
 #include "gtktypebuiltins.h"
@@ -974,7 +975,6 @@ style_data_lookup (GtkStyleContext *context)
 {
   GtkStyleContextPrivate *priv;
   GtkStyleInfo *info;
-  GtkCssValue *v;
 
   priv = context->priv;
   info = priv->info_stack->data;
@@ -1006,11 +1006,9 @@ style_data_lookup (GtkStyleContext *context)
   if (priv->theming_engine)
     g_object_unref (priv->theming_engine);
 
-  v = _gtk_css_computed_values_get_value (info->data->store, GTK_CSS_PROPERTY_ENGINE);
-  if (v)
-    priv->theming_engine = _gtk_css_value_dup_object (v);
-  else
-    priv->theming_engine = g_object_ref (gtk_theming_engine_load (NULL));
+  priv->theming_engine = g_object_ref (
+                           _gtk_css_engine_value_get_engine (
+                             _gtk_css_computed_values_get_value (info->data->store, GTK_CSS_PROPERTY_ENGINE)));
 
   return info->data;
 }
diff --git a/gtk/gtkthemingbackground.c b/gtk/gtkthemingbackground.c
index e937464..4cb43aa 100644
--- a/gtk/gtkthemingbackground.c
+++ b/gtk/gtkthemingbackground.c
@@ -28,6 +28,7 @@
 #include "gtkcssimagevalueprivate.h"
 #include "gtkcssshadowsvalueprivate.h"
 #include "gtkcsspositionvalueprivate.h"
+#include "gtkcssrepeatvalueprivate.h"
 #include "gtkcsstypesprivate.h"
 #include "gtkthemingengineprivate.h"
 
@@ -160,19 +161,17 @@ _gtk_theming_background_paint (GtkThemingBackground *bg,
       && bg->image_rect.width > 0
       && bg->image_rect.height > 0)
     {
-      GtkCssBackgroundRepeat hrepeat, vrepeat;
       const GtkCssBackgroundSize *size;
-      const GtkCssValue *pos;
+      const GtkCssValue *pos, *repeat;
       double image_width, image_height;
       double width, height;
+      GtkCssRepeatStyle hrepeat, vrepeat;
 
       size = _gtk_css_value_get_background_size (_gtk_style_context_peek_property (bg->context, GTK_CSS_PROPERTY_BACKGROUND_SIZE));
       pos = _gtk_style_context_peek_property (bg->context, GTK_CSS_PROPERTY_BACKGROUND_POSITION);
-      gtk_style_context_get (bg->context, bg->flags,
-                             "background-repeat", &hrepeat,
-                             NULL);
-      vrepeat = GTK_CSS_BACKGROUND_VERTICAL (hrepeat);
-      hrepeat = GTK_CSS_BACKGROUND_HORIZONTAL (hrepeat);
+      repeat = _gtk_style_context_peek_property (bg->context, GTK_CSS_PROPERTY_BACKGROUND_REPEAT);
+      hrepeat = _gtk_css_background_repeat_value_get_x (repeat);
+      vrepeat = _gtk_css_background_repeat_value_get_y (repeat);
       width = bg->image_rect.width;
       height = bg->image_rect.height;
 
@@ -193,13 +192,13 @@ _gtk_theming_background_paint (GtkThemingBackground *bg,
 
       /* optimization */
       if (image_width == width)
-        hrepeat = GTK_CSS_BACKGROUND_NO_REPEAT;
+        hrepeat = GTK_CSS_REPEAT_STYLE_NO_REPEAT;
       if (image_height == height)
-        vrepeat = GTK_CSS_BACKGROUND_NO_REPEAT;
+        vrepeat = GTK_CSS_REPEAT_STYLE_NO_REPEAT;
 
       cairo_translate (cr, bg->image_rect.x, bg->image_rect.y);
 
-      if (hrepeat == GTK_CSS_BACKGROUND_NO_REPEAT && vrepeat == GTK_CSS_BACKGROUND_NO_REPEAT)
+      if (hrepeat == GTK_CSS_REPEAT_STYLE_NO_REPEAT && vrepeat == GTK_CSS_REPEAT_STYLE_NO_REPEAT)
         {
 	  cairo_translate (cr,
 			   _gtk_css_position_value_get_x (pos, width - image_width),
@@ -229,24 +228,24 @@ _gtk_theming_background_paint (GtkThemingBackground *bg,
            * a third step: that other dimension is scaled so that the original
            * aspect ratio is restored. 
            */
-          if (hrepeat == GTK_CSS_BACKGROUND_ROUND)
+          if (hrepeat == GTK_CSS_REPEAT_STYLE_ROUND)
             {
               double n = round (width / image_width);
 
               n = MAX (1, n);
 
-              if (vrepeat != GTK_CSS_BACKGROUND_ROUND
+              if (vrepeat != GTK_CSS_REPEAT_STYLE_ROUND
                   /* && vsize == auto (it is by default) */)
                 image_height *= width / (image_width * n);
               image_width = width / n;
             }
-          if (vrepeat == GTK_CSS_BACKGROUND_ROUND)
+          if (vrepeat == GTK_CSS_REPEAT_STYLE_ROUND)
             {
               double n = round (height / image_height);
 
               n = MAX (1, n);
 
-              if (hrepeat != GTK_CSS_BACKGROUND_ROUND
+              if (hrepeat != GTK_CSS_REPEAT_STYLE_ROUND
                   /* && hsize == auto (it is by default) */)
                 image_width *= height / (image_height * n);
               image_height = height / n;
@@ -254,7 +253,7 @@ _gtk_theming_background_paint (GtkThemingBackground *bg,
 
           /* if hrepeat or vrepeat is 'space', we create a somewhat larger surface
            * to store the extra space. */
-          if (hrepeat == GTK_CSS_BACKGROUND_SPACE)
+          if (hrepeat == GTK_CSS_REPEAT_STYLE_SPACE)
             {
               double n = floor (width / image_width);
               surface_width = n ? round (width / n) : 0;
@@ -262,7 +261,7 @@ _gtk_theming_background_paint (GtkThemingBackground *bg,
           else
             surface_width = round (image_width);
 
-          if (vrepeat == GTK_CSS_BACKGROUND_SPACE)
+          if (vrepeat == GTK_CSS_REPEAT_STYLE_SPACE)
             {
               double n = floor (height / image_height);
               surface_height = n ? round (height / n) : 0;
@@ -288,8 +287,8 @@ _gtk_theming_background_paint (GtkThemingBackground *bg,
 
           cairo_rectangle (cr,
                            0, 0,
-                           hrepeat == GTK_CSS_BACKGROUND_NO_REPEAT ? image_width : width,
-                           vrepeat == GTK_CSS_BACKGROUND_NO_REPEAT ? image_height : height);
+                           hrepeat == GTK_CSS_REPEAT_STYLE_NO_REPEAT ? image_width : width,
+                           vrepeat == GTK_CSS_REPEAT_STYLE_NO_REPEAT ? image_height : height);
           cairo_fill (cr);
         }
     }



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