[gtk+/wip/css-background-position: 3/4] css: Support background-position property



commit 6a814f70c311a6f9ba240d81a0a4a1b3ba610986
Author: Alexander Larsson <alexl redhat com>
Date:   Fri Mar 16 22:13:39 2012 +0100

    css: Support background-position property

 gtk/gtkcssstylepropertyimpl.c |  112 +++++++++++++++++++++++++++++++++++++++++
 gtk/gtkthemingbackground.c    |    9 +++-
 2 files changed, 119 insertions(+), 2 deletions(-)
---
diff --git a/gtk/gtkcssstylepropertyimpl.c b/gtk/gtkcssstylepropertyimpl.c
index f6d4b49..5e9a391 100644
--- a/gtk/gtkcssstylepropertyimpl.c
+++ b/gtk/gtkcssstylepropertyimpl.c
@@ -682,6 +682,108 @@ background_size_compute (GtkCssStyleProperty    *property,
   return _gtk_css_value_ref (specified);
 }
 
+static gboolean
+try_parse_lrbtc (GtkCssParser        *parser,
+		 GtkCssBackgroundPosition *pos)
+{
+  if (_gtk_css_parser_try (parser, "left", TRUE))
+    {
+      pos->x.value = 0;
+      pos->x.unit = GTK_CSS_PERCENT;
+      return TRUE;
+    }
+  else if (_gtk_css_parser_try (parser, "right", TRUE))
+    {
+      pos->x.value = 100;
+      pos->x.unit = GTK_CSS_PERCENT;
+      return TRUE;
+    }
+  else if (_gtk_css_parser_try (parser, "top", TRUE))
+    {
+      pos->y.value = 0;
+      pos->y.unit = GTK_CSS_PERCENT;
+      return TRUE;
+    }
+  else if (_gtk_css_parser_try (parser, "bottom", TRUE))
+    {
+      pos->y.value = 100;
+      pos->y.unit = GTK_CSS_PERCENT;
+      return TRUE;
+    }
+  else if (_gtk_css_parser_try (parser, "center", TRUE))
+    {
+      return TRUE;
+    }
+
+  return FALSE;
+}
+
+static gboolean
+background_position_parse (GtkCssStyleProperty *property,
+			   GValue              *value,
+			   GtkCssParser        *parser,
+			   GFile               *base)
+{
+  GtkCssBackgroundPosition pos = { GTK_CSS_NUMBER_INIT (50, GTK_CSS_PERCENT), GTK_CSS_NUMBER_INIT (50, GTK_CSS_PERCENT)};
+
+  if (try_parse_lrbtc (parser, &pos))
+    {
+      try_parse_lrbtc (parser, &pos);
+      g_value_set_boxed (value, &pos);
+      return TRUE;
+    }
+
+  if (!_gtk_css_parser_read_number (parser,
+				    &pos.x,
+				    GTK_CSS_PARSE_PERCENT
+				    | GTK_CSS_PARSE_LENGTH))
+    return FALSE;
+
+  if (_gtk_css_parser_has_number (parser))
+    {
+      if (!_gtk_css_parser_read_number (parser,
+					&pos.y,
+					GTK_CSS_PARSE_PERCENT
+					| GTK_CSS_PARSE_LENGTH))
+	return FALSE;
+    }
+
+  g_value_set_boxed (value, &pos);
+  return TRUE;
+}
+
+static void
+background_position_print (GtkCssStyleProperty *property,
+			   const GValue        *value,
+			   GString             *string)
+{
+  GtkCssBackgroundPosition *pos = g_value_get_boxed (value);
+
+  _gtk_css_number_print (&pos->x, string);
+  g_string_append (string, " ");
+  _gtk_css_number_print (&pos->y, string);
+}
+
+static GtkCssValue *
+background_position_compute (GtkCssStyleProperty    *property,
+			     GtkStyleContext        *context,
+			     GtkCssValue            *specified)
+{
+  GtkCssBackgroundPosition *spos = _gtk_css_value_get_background_position (specified);
+  GtkCssBackgroundPosition cpos;
+  gboolean changed;
+
+  changed = _gtk_css_number_compute (&cpos.x,
+				     &spos->x,
+				     context);
+  changed |= _gtk_css_number_compute (&cpos.y,
+				      &spos->y,
+				      context);
+  if (changed)
+    return _gtk_css_value_new_from_background_position (&cpos);
+  return _gtk_css_value_ref (specified);
+}
+
 /*** REGISTRATION ***/
 
 static GtkSymbolicColor *
@@ -702,6 +804,7 @@ _gtk_css_style_property_init_properties (void)
   GtkCssNumber number;
   GtkSymbolicColor *symbolic;
   GtkCssBackgroundSize default_background_size = { GTK_CSS_NUMBER_INIT (0, GTK_CSS_PX), GTK_CSS_NUMBER_INIT (0, GTK_CSS_PX), FALSE, FALSE };
+  GtkCssBackgroundPosition default_background_position = { GTK_CSS_NUMBER_INIT (0, GTK_CSS_PERCENT), GTK_CSS_NUMBER_INIT (0, GTK_CSS_PERCENT)};
   GtkCssBorderCornerRadius no_corner_radius = { GTK_CSS_NUMBER_INIT (0, GTK_CSS_PX), GTK_CSS_NUMBER_INIT (0, GTK_CSS_PX) };
   GtkBorder border_of_ones = { 1, 1, 1, 1 };
   GtkCssBorderImageRepeat border_image_repeat = { GTK_CSS_REPEAT_STYLE_STRETCH, GTK_CSS_REPEAT_STYLE_STRETCH };
@@ -1054,6 +1157,15 @@ _gtk_css_style_property_init_properties (void)
                                           background_size_print,
                                           background_size_compute,
                                           &default_background_size);
+  gtk_css_style_property_register        ("background-position",
+                                          GTK_TYPE_CSS_BACKGROUND_POSITION,
+                                          GTK_TYPE_CSS_BACKGROUND_POSITION,
+                                          G_TYPE_NONE,
+                                          0,
+                                          background_position_parse,
+                                          background_position_print,
+                                          background_position_compute,
+                                          &default_background_position);
 
   gtk_css_style_property_register        ("border-top-color",
                                           GTK_TYPE_SYMBOLIC_COLOR,
diff --git a/gtk/gtkthemingbackground.c b/gtk/gtkthemingbackground.c
index 161cc5a..89d0acc 100644
--- a/gtk/gtkthemingbackground.c
+++ b/gtk/gtkthemingbackground.c
@@ -162,10 +162,12 @@ _gtk_theming_background_paint (GtkThemingBackground *bg,
     {
       GtkCssBackgroundRepeat hrepeat, vrepeat;
       GtkCssBackgroundSize *size;
+      GtkCssBackgroundPosition *pos;
       double image_width, image_height;
       double width, height;
 
       size = _gtk_css_value_get_background_size (_gtk_style_context_peek_property (bg->context, "background-size"));
+      pos = _gtk_css_value_get_background_position (_gtk_style_context_peek_property (bg->context, "background-position"));
       gtk_style_context_get (bg->context, bg->flags,
                              "background-repeat", &hrepeat,
                              NULL);
@@ -199,6 +201,9 @@ _gtk_theming_background_paint (GtkThemingBackground *bg,
 
       if (hrepeat == GTK_CSS_BACKGROUND_NO_REPEAT && vrepeat == GTK_CSS_BACKGROUND_NO_REPEAT)
         {
+	  cairo_translate (cr,
+			   _gtk_css_number_get (&pos->x, bg->image_rect.width - image_width),
+			   _gtk_css_number_get (&pos->y, bg->image_rect.height - image_height));
           /* shortcut for normal case */
           _gtk_css_image_draw (bg->image, cr, image_width, image_height);
         }
@@ -276,8 +281,8 @@ _gtk_theming_background_paint (GtkThemingBackground *bg,
           cairo_destroy (cr2);
 
           cairo_set_source_surface (cr, surface,
-                                    /* background-position goes here */
-                                    0, 0);
+				    _gtk_css_number_get (&pos->x, bg->image_rect.width - image_width),
+				    _gtk_css_number_get (&pos->y, bg->image_rect.height - image_height));
           cairo_pattern_set_extend (cairo_get_source (cr), CAIRO_EXTEND_REPEAT);
           cairo_surface_destroy (surface);
 



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