[gtk+/css-fixes: 11/15] Implement background-clip and background-origin



commit be5c5ad5279b63e8c18f0977f6a7c90f858f6b48
Author: Alexander Larsson <alexl redhat com>
Date:   Thu Nov 24 21:00:57 2011 +0100

    Implement background-clip and background-origin

 gtk/gtkstyleproperty.c |   12 ++++++
 gtk/gtkthemingengine.c |   88 +++++++++++++++++++++++++++++++++++++----------
 2 files changed, 81 insertions(+), 19 deletions(-)
---
diff --git a/gtk/gtkstyleproperty.c b/gtk/gtkstyleproperty.c
index 21b190e..d300fef 100644
--- a/gtk/gtkstyleproperty.c
+++ b/gtk/gtkstyleproperty.c
@@ -2945,6 +2945,18 @@ gtk_style_property_init (void)
                                                              "Border style",
                                                              GTK_TYPE_BORDER_STYLE,
                                                              GTK_BORDER_STYLE_NONE, 0));
+  gtk_style_properties_register_property (NULL,
+                                          g_param_spec_enum ("background-clip",
+                                                             "Background clip",
+                                                             "Background clip",
+                                                             GTK_TYPE_CSS_AREA,
+                                                             GTK_CSS_AREA_BORDER_BOX, 0));
+  gtk_style_properties_register_property (NULL,
+                                          g_param_spec_enum ("background-origin",
+                                                             "Background origin",
+                                                             "Background origin",
+                                                             GTK_TYPE_CSS_AREA,
+                                                             GTK_CSS_AREA_PADDING_BOX, 0));
   _gtk_style_property_register           (g_param_spec_boxed ("border-top-color",
                                                               "Border top color",
                                                               "Border top color",
diff --git a/gtk/gtkthemingengine.c b/gtk/gtkthemingengine.c
index fabd30b..0d30b97 100644
--- a/gtk/gtkthemingengine.c
+++ b/gtk/gtkthemingengine.c
@@ -1446,17 +1446,55 @@ render_background_internal (GtkThemingEngine *engine,
   GtkStateFlags flags;
   gboolean running;
   gdouble progress;
-  GtkRoundedBox border_box;
+  GtkRoundedBox padding_box;
+  GtkRoundedBox clip_box;
   GtkShadow *box_shadow;
-  GtkBorder border;
+  GtkBorder border, padding;
   GtkStylePropertyContext context;
+  GtkCssArea clip, origin;
+  gdouble bg_width, bg_height, bg_x, bg_y;
 
   flags = gtk_theming_engine_get_state (engine);
 
   gtk_theming_engine_get_background_color (engine, flags, &bg_color);
 
-  context.width = width;
-  context.height = height;
+  gtk_theming_engine_get (engine, flags,
+			  "background-origin", &origin,
+			  "background-clip", &clip,
+			  "background-repeat", &repeat,
+			  "box-shadow", &box_shadow,
+			  NULL);
+
+  gtk_theming_engine_get_border (engine, flags, &border);
+  gtk_theming_engine_get_padding (engine, flags, &padding);
+
+  /* The default size of the background image depends on the
+     background-origin value as this affects the top left
+     and the bottom right corners. */
+  switch (origin) {
+  case GTK_CSS_AREA_BORDER_BOX:
+    bg_x = 0;
+    bg_y = 0;
+    bg_width = width;
+    bg_height = height;
+    break;
+  case GTK_CSS_AREA_PADDING_BOX:
+  default:
+    bg_x = border.left;
+    bg_y = border.top;
+    bg_width = width - border.left - border.left;
+    bg_height = height - border.top - border.bottom;
+    break;
+  case GTK_CSS_AREA_CONTENT_BOX:
+    bg_x = border.left + padding.left;
+    bg_y = border.top + padding.top;
+    bg_width = width - border.left - border.right - padding.left - padding.right;
+    bg_height = height - border.top - border.bottom - padding.top - padding.bottom;
+    break;
+  }
+
+  context.width = bg_width;
+  context.height = bg_height;
 
   if (optional_background)
     pattern = cairo_pattern_reference (optional_background);
@@ -1465,10 +1503,6 @@ render_background_internal (GtkThemingEngine *engine,
 			     "background-image", &pattern,
 			     NULL);
 
-  _gtk_theming_engine_get (engine, flags, &context, 
-			   "background-repeat", &repeat,
-			   "box-shadow", &box_shadow,
-			   NULL);
 
   cairo_save (cr);
   cairo_translate (cr, x, y);
@@ -1656,8 +1690,6 @@ render_background_internal (GtkThemingEngine *engine,
         cairo_pattern_destroy (other_pattern);
     }
 
-  gtk_theming_engine_get_border (engine, flags, &border);
-
   /* In the CSS box model, by default the background positioning area is
    * the padding-box, i.e. all the border-box minus the borders themselves,
    * which determines also its default size, see
@@ -1666,12 +1698,28 @@ render_background_internal (GtkThemingEngine *engine,
    * In the future we might want to support different origins or clips, but
    * right now we just shrink to the default.
    */
-  _gtk_rounded_box_init_rect (&border_box, 0, 0, width, height);
-  _gtk_rounded_box_apply_border_radius (&border_box, engine, flags, junction);
-  _gtk_rounded_box_shrink (&border_box,
-                           border.top, border.right,
-                           border.bottom, border.left);
-  _gtk_rounded_box_path (&border_box, cr);
+  _gtk_rounded_box_init_rect (&padding_box, 0, 0, width, height);
+  _gtk_rounded_box_apply_border_radius (&padding_box, engine, flags, junction);
+  clip_box = padding_box;
+  _gtk_rounded_box_shrink (&padding_box,
+			   border.top, border.right,
+			   border.bottom, border.left);
+  if (clip == GTK_CSS_AREA_PADDING_BOX)
+    {
+      _gtk_rounded_box_shrink (&clip_box,
+			       border.top, border.right,
+			       border.bottom, border.left);
+    }
+  else if (clip == GTK_CSS_AREA_CONTENT_BOX)
+    {
+      _gtk_rounded_box_shrink (&clip_box,
+			       border.top + padding.top,
+			       border.right + padding.right,
+			       border.bottom + padding.bottom,
+			       border.left + padding.left);
+    }
+
+  _gtk_rounded_box_path (&clip_box, cr);
 
   if (pattern)
     {
@@ -1694,13 +1742,15 @@ render_background_internal (GtkThemingEngine *engine,
       else
         {
           cairo_pattern_set_extend (pattern, CAIRO_EXTEND_PAD);
-          scale_width = width;
-          scale_height = height;
+          scale_width = bg_width;
+          scale_height = bg_height;
         }
 
+      cairo_translate (cr, bg_x, bg_y);
       cairo_scale (cr, scale_width, scale_height);
       cairo_set_source (cr, pattern);
       cairo_scale (cr, 1.0 / scale_width, 1.0 / scale_height);
+      cairo_translate (cr, -bg_x, -bg_y);
     }
   else
     gdk_cairo_set_source_rgba (cr, &bg_color);
@@ -1715,7 +1765,7 @@ render_background_internal (GtkThemingEngine *engine,
 
   if (box_shadow != NULL)
     {
-      _gtk_box_shadow_render (box_shadow, cr, &border_box);
+      _gtk_box_shadow_render (box_shadow, cr, &padding_box);
       _gtk_shadow_unref (box_shadow);
     }
 



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