[gtk+] css: start background-repeat
- From: Cosimo Cecchi <cosimoc src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gtk+] css: start background-repeat
- Date: Tue, 8 Nov 2011 17:43:21 +0000 (UTC)
commit 3b436eec6d9b0c7aa046ff4b2b4c3a9f99b86574
Author: Marc-Andrà Lureau <marcandre lureau redhat com>
Date: Sun Nov 6 19:33:05 2011 +0100
css: start background-repeat
By default, a background image is stretched. Instead, it is worth to
have a tiled background.
This patch allows background surfaces to be repeated or not, and should
be compatible with future extensions and CSS.
https://bugzilla.gnome.org/show_bug.cgi?id=663522
gtk/gtkcssprovider.c | 10 ++++++++
gtk/gtkcsstypes.c | 2 +
gtk/gtkcsstypesprivate.h | 17 ++++++++++++++
gtk/gtkstylecontext.h | 1 -
gtk/gtkstyleproperty.c | 56 ++++++++++++++++++++++++++++++++++++++++++++++
gtk/gtkthemingengine.c | 31 +++++++++++++++++++++++-
6 files changed, 114 insertions(+), 3 deletions(-)
---
diff --git a/gtk/gtkcssprovider.c b/gtk/gtkcssprovider.c
index 1245766..555a4b5 100644
--- a/gtk/gtkcssprovider.c
+++ b/gtk/gtkcssprovider.c
@@ -840,6 +840,16 @@
* </entry>
* </row>
* <row>
+ * <entry>background-repeat</entry>
+ * <entry>[repeat|no-repeat]</entry>
+ * <entry>internal</entry>
+ * <entry><literallayout>background-repeat: no-repeat;</literallayout>
+ * If not specified, the style doesn't respect the CSS3
+ * specification, since the background will be
+ * stretched to fill the area.
+ * </entry>
+ * </row>
+ * <row>
* <entry>border-top-width</entry>
* <entry>integer</entry>
* <entry>#gint</entry>
diff --git a/gtk/gtkcsstypes.c b/gtk/gtkcsstypes.c
index e84bd2c..73f2d16 100644
--- a/gtk/gtkcsstypes.c
+++ b/gtk/gtkcsstypes.c
@@ -31,6 +31,8 @@ type_name ## _copy (const TypeName *foo) \
\
G_DEFINE_BOXED_TYPE (TypeName, type_name, type_name ## _copy, g_free)
+DEFINE_BOXED_TYPE_WITH_COPY_FUNC (GtkCssBackgroundRepeat, _gtk_css_background_repeat)
+
DEFINE_BOXED_TYPE_WITH_COPY_FUNC (GtkCssBorderCornerRadius, _gtk_css_border_corner_radius)
DEFINE_BOXED_TYPE_WITH_COPY_FUNC (GtkCssBorderRadius, _gtk_css_border_radius)
DEFINE_BOXED_TYPE_WITH_COPY_FUNC (GtkCssBorderImageRepeat, _gtk_css_border_image_repeat)
diff --git a/gtk/gtkcsstypesprivate.h b/gtk/gtkcsstypesprivate.h
index 0ee049a..4dc93fa 100644
--- a/gtk/gtkcsstypesprivate.h
+++ b/gtk/gtkcsstypesprivate.h
@@ -25,16 +25,29 @@
G_BEGIN_DECLS
typedef enum {
+ GTK_CSS_BACKGROUND_REPEAT_STYLE_NONE,
+ GTK_CSS_BACKGROUND_REPEAT_STYLE_REPEAT,
+ GTK_CSS_BACKGROUND_REPEAT_STYLE_NO_REPEAT,
+} GtkCssBackgroundRepeatStyle;
+
+typedef enum {
GTK_CSS_REPEAT_STYLE_NONE,
GTK_CSS_REPEAT_STYLE_REPEAT,
GTK_CSS_REPEAT_STYLE_ROUND,
GTK_CSS_REPEAT_STYLE_SPACE
} GtkCssBorderRepeatStyle;
+typedef struct _GtkCssBackgroundRepeat GtkCssBackgroundRepeat;
+
typedef struct _GtkCssBorderCornerRadius GtkCssBorderCornerRadius;
typedef struct _GtkCssBorderRadius GtkCssBorderRadius;
typedef struct _GtkCssBorderImageRepeat GtkCssBorderImageRepeat;
+struct _GtkCssBackgroundRepeat {
+ /* FIXME: will have vrepeat and hrepeat instead */
+ GtkCssBackgroundRepeatStyle repeat;
+};
+
struct _GtkCssBorderCornerRadius {
double horizontal;
double vertical;
@@ -52,10 +65,14 @@ struct _GtkCssBorderImageRepeat {
GtkCssBorderRepeatStyle hrepeat;
};
+#define GTK_TYPE_CSS_BACKGROUND_REPEAT _gtk_css_background_repeat_get_type ()
+
#define GTK_TYPE_CSS_BORDER_CORNER_RADIUS _gtk_css_border_corner_radius_get_type ()
#define GTK_TYPE_CSS_BORDER_RADIUS _gtk_css_border_radius_get_type ()
#define GTK_TYPE_CSS_BORDER_IMAGE_REPEAT _gtk_css_border_image_repeat_get_type ()
+GType _gtk_css_background_repeat_get_type (void);
+
GType _gtk_css_border_corner_radius_get_type (void);
GType _gtk_css_border_radius_get_type (void);
GType _gtk_css_border_image_repeat_get_type (void);
diff --git a/gtk/gtkstylecontext.h b/gtk/gtkstylecontext.h
index b5af48b..634c31a 100644
--- a/gtk/gtkstylecontext.h
+++ b/gtk/gtkstylecontext.h
@@ -148,7 +148,6 @@ struct _GtkStyleContextClass
*/
#define GTK_STYLE_PROPERTY_BACKGROUND_IMAGE "background-image"
-
/* Predefined set of CSS classes */
/**
diff --git a/gtk/gtkstyleproperty.c b/gtk/gtkstyleproperty.c
index 6997293..8913d92 100644
--- a/gtk/gtkstyleproperty.c
+++ b/gtk/gtkstyleproperty.c
@@ -1127,6 +1127,53 @@ shadow_value_print (const GValue *value,
}
static gboolean
+background_repeat_value_parse (GtkCssParser *parser,
+ GFile *file,
+ GValue *value)
+{
+ GtkCssBackgroundRepeat repeat;
+ GtkCssBackgroundRepeatStyle style;
+
+ if (_gtk_css_parser_try (parser, "repeat", TRUE))
+ style = GTK_CSS_BACKGROUND_REPEAT_STYLE_REPEAT;
+ else if (_gtk_css_parser_try (parser, "no-repeat", TRUE))
+ style = GTK_CSS_BACKGROUND_REPEAT_STYLE_NO_REPEAT;
+ else
+ style = GTK_CSS_BACKGROUND_REPEAT_STYLE_NONE;
+
+ repeat.repeat = style;
+
+ g_value_set_boxed (value, &repeat);
+
+ return TRUE;
+}
+
+static const gchar *
+background_repeat_style_to_string (GtkCssBackgroundRepeatStyle repeat)
+{
+ switch (repeat)
+ {
+ case GTK_CSS_BACKGROUND_REPEAT_STYLE_REPEAT:
+ return "repeat";
+ case GTK_CSS_BACKGROUND_REPEAT_STYLE_NO_REPEAT:
+ return "no-repeat";
+ default:
+ return NULL;
+ }
+}
+
+static void
+background_repeat_value_print (const GValue *value,
+ GString *string)
+{
+ GtkCssBackgroundRepeat *repeat;
+
+ repeat = g_value_get_boxed (value);
+
+ g_string_append (string, background_repeat_style_to_string (repeat->repeat));
+}
+
+static gboolean
border_image_repeat_value_parse (GtkCssParser *parser,
GFile *file,
GValue *value)
@@ -2246,6 +2293,9 @@ css_string_funcs_init (void)
register_conversion_function (G_TYPE_FLAGS,
flags_value_parse,
flags_value_print);
+ register_conversion_function (GTK_TYPE_CSS_BACKGROUND_REPEAT,
+ background_repeat_value_parse,
+ background_repeat_value_print);
}
gboolean
@@ -2913,6 +2963,12 @@ gtk_style_property_init (void)
"Background Image",
CAIRO_GOBJECT_TYPE_PATTERN, 0));
gtk_style_properties_register_property (NULL,
+ g_param_spec_boxed ("background-repeat",
+ "Background repeat",
+ "Background repeat",
+ GTK_TYPE_CSS_BACKGROUND_REPEAT, 0));
+
+ gtk_style_properties_register_property (NULL,
g_param_spec_boxed ("border-image-source",
"Border image source",
"Border image source",
diff --git a/gtk/gtkthemingengine.c b/gtk/gtkthemingengine.c
index d917a0c..8d6da01 100644
--- a/gtk/gtkthemingengine.c
+++ b/gtk/gtkthemingengine.c
@@ -1381,6 +1381,7 @@ render_background_internal (GtkThemingEngine *engine,
{
GdkRGBA bg_color;
cairo_pattern_t *pattern;
+ GtkCssBackgroundRepeat *repeat;
GtkStateFlags flags;
gboolean running;
gdouble progress;
@@ -1394,6 +1395,7 @@ render_background_internal (GtkThemingEngine *engine,
gtk_theming_engine_get (engine, flags,
"background-image", &pattern,
+ "background-repeat", &repeat,
"box-shadow", &box_shadow,
NULL);
@@ -1602,9 +1604,31 @@ render_background_internal (GtkThemingEngine *engine,
if (pattern)
{
- cairo_scale (cr, width, height);
+ cairo_surface_t *surface;
+ int scale_width, scale_height;
+
+ if (cairo_pattern_get_surface (pattern, &surface) != CAIRO_STATUS_SUCCESS)
+ surface = NULL;
+
+ if (surface && repeat &&
+ repeat->repeat != GTK_CSS_BACKGROUND_REPEAT_STYLE_NONE)
+ {
+ scale_width = cairo_image_surface_get_width (surface);
+ scale_height = cairo_image_surface_get_height (surface);
+ if (repeat->repeat == GTK_CSS_BACKGROUND_REPEAT_STYLE_REPEAT)
+ cairo_pattern_set_extend (pattern, CAIRO_EXTEND_REPEAT);
+ else if (repeat->repeat == GTK_CSS_BACKGROUND_REPEAT_STYLE_NO_REPEAT)
+ cairo_pattern_set_extend (pattern, CAIRO_EXTEND_NONE);
+ }
+ else
+ {
+ scale_width = width;
+ scale_height = height;
+ }
+
+ cairo_scale (cr, scale_width, scale_height);
cairo_set_source (cr, pattern);
- cairo_scale (cr, 1.0 / width, 1.0 / height);
+ cairo_scale (cr, 1.0 / scale_width, 1.0 / scale_height);
}
else
gdk_cairo_set_source_rgba (cr, &bg_color);
@@ -1614,6 +1638,9 @@ render_background_internal (GtkThemingEngine *engine,
if (pattern)
cairo_pattern_destroy (pattern);
+ if (repeat)
+ g_free (repeat);
+
if (box_shadow != NULL)
{
_gtk_box_shadow_render (box_shadow, cr, &border_box);
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]