[gtk+] border-image: add support for border-image-width too
- From: Cosimo Cecchi <cosimoc src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gtk+] border-image: add support for border-image-width too
- Date: Fri, 10 Jun 2011 00:02:16 +0000 (UTC)
commit 3d1407a01a1e772f8b042801bbbde95ae1e16f9a
Author: Cosimo Cecchi <cosimoc gnome org>
Date: Thu Jun 9 19:59:14 2011 -0400
border-image: add support for border-image-width too
It's useful to set a slice size != border-width, as backgrounds are
clipped to border-width too.
As slices can be half-transparent and overlap the background,
this would not fill the border box properly if we only use a single
property for specifying the width.
Also, this brings us even closer to CSS3.
gtk/gtkborderimage.c | 40 +++++++++++++++++++++++++++++++---------
gtk/gtkborderimageprivate.h | 2 ++
gtk/gtkcssprovider.c | 10 +++++++++-
gtk/gtkstyleproperty.c | 29 ++++++++++++++++++++++++-----
4 files changed, 66 insertions(+), 15 deletions(-)
---
diff --git a/gtk/gtkborderimage.c b/gtk/gtkborderimage.c
index f259310..f5cca50 100644
--- a/gtk/gtkborderimage.c
+++ b/gtk/gtkborderimage.c
@@ -52,14 +52,16 @@ struct _GtkBorderImage {
GtkGradient *source_gradient;
GtkBorder slice;
+ GtkBorder *width;
GtkCssBorderImageRepeat repeat;
gint ref_count;
};
GtkBorderImage *
-_gtk_border_image_new (cairo_pattern_t *pattern,
- GtkBorder *slice,
+_gtk_border_image_new (cairo_pattern_t *pattern,
+ GtkBorder *slice,
+ GtkBorder *width,
GtkCssBorderImageRepeat *repeat)
{
GtkBorderImage *image;
@@ -73,6 +75,9 @@ _gtk_border_image_new (cairo_pattern_t *pattern,
if (slice != NULL)
image->slice = *slice;
+ if (width != NULL)
+ image->width = gtk_border_copy (width);
+
if (repeat != NULL)
image->repeat = *repeat;
@@ -80,8 +85,9 @@ _gtk_border_image_new (cairo_pattern_t *pattern,
}
GtkBorderImage *
-_gtk_border_image_new_for_gradient (GtkGradient *gradient,
- GtkBorder *slice,
+_gtk_border_image_new_for_gradient (GtkGradient *gradient,
+ GtkBorder *slice,
+ GtkBorder *width,
GtkCssBorderImageRepeat *repeat)
{
GtkBorderImage *image;
@@ -95,6 +101,9 @@ _gtk_border_image_new_for_gradient (GtkGradient *gradient,
if (slice != NULL)
image->slice = *slice;
+ if (width != NULL)
+ image->width = gtk_border_copy (width);
+
if (repeat != NULL)
image->repeat = *repeat;
@@ -126,6 +135,9 @@ _gtk_border_image_unref (GtkBorderImage *image)
if (image->source_gradient != NULL)
gtk_gradient_unref (image->source_gradient);
+ if (image->width != NULL)
+ gtk_border_free (image->width);
+
g_slice_free (GtkBorderImage, image);
}
}
@@ -134,7 +146,7 @@ GParameter *
_gtk_border_image_unpack (const GValue *value,
guint *n_params)
{
- GParameter *parameter = g_new0 (GParameter, 3);
+ GParameter *parameter = g_new0 (GParameter, 4);
GtkBorderImage *image = g_value_get_boxed (value);
parameter[0].name = "border-image-source";
@@ -146,14 +158,18 @@ _gtk_border_image_unpack (const GValue *value,
parameter[2].name = "border-image-repeat";
g_value_init (¶meter[2].value, GTK_TYPE_CSS_BORDER_IMAGE_REPEAT);
+ parameter[3].name = "border-image-width";
+ g_value_init (¶meter[3].value, GTK_TYPE_BORDER);
+
if (image != NULL)
{
g_value_set_boxed (¶meter[0].value, image->source);
g_value_set_boxed (¶meter[1].value, &image->slice);
g_value_set_boxed (¶meter[2].value, &image->repeat);
+ g_value_set_boxed (¶meter[3].value, image->width);
}
- *n_params = 3;
+ *n_params = 4;
return parameter;
}
@@ -164,13 +180,14 @@ _gtk_border_image_pack (GValue *value,
{
GtkBorderImage *image;
cairo_pattern_t *source;
- GtkBorder *slice;
+ GtkBorder *slice, *width;
GtkCssBorderImageRepeat *repeat;
gtk_style_properties_get (props, state,
"border-image-source", &source,
"border-image-slice", &slice,
"border-image-repeat", &repeat,
+ "border-image-width", &width,
NULL);
if (source == NULL)
@@ -179,7 +196,7 @@ _gtk_border_image_pack (GValue *value,
}
else
{
- image = _gtk_border_image_new (source, slice, repeat);
+ image = _gtk_border_image_new (source, slice, width, repeat);
g_value_take_boxed (value, image);
cairo_pattern_destroy (source);
@@ -188,6 +205,9 @@ _gtk_border_image_pack (GValue *value,
if (slice != NULL)
gtk_border_free (slice);
+ if (width != NULL)
+ gtk_border_free (width);
+
if (repeat != NULL)
g_free (repeat);
}
@@ -370,6 +390,9 @@ _gtk_border_image_render (GtkBorderImage *image,
int surface_width, surface_height;
int h, v;
+ if (image->width != NULL)
+ border_width = image->width;
+
if (cairo_pattern_get_type (image->source) != CAIRO_PATTERN_TYPE_SURFACE)
{
cairo_matrix_t matrix;
@@ -437,7 +460,6 @@ _gtk_border_image_render (GtkBorderImage *image,
horizontal_slice[h].size,
vertical_slice[v].size);
- /* xxx: we scale to border-width here, that's wrong, isn't it? */
gtk_border_image_render_slice (cr,
slice,
horizontal_slice[h].size,
diff --git a/gtk/gtkborderimageprivate.h b/gtk/gtkborderimageprivate.h
index ca2ef01..585be67 100644
--- a/gtk/gtkborderimageprivate.h
+++ b/gtk/gtkborderimageprivate.h
@@ -40,9 +40,11 @@ GType _gtk_border_image_get_type (void) G_GNUC_CONST;
GtkBorderImage * _gtk_border_image_new (cairo_pattern_t *source,
GtkBorder *slice,
+ GtkBorder *width,
GtkCssBorderImageRepeat *repeat);
GtkBorderImage * _gtk_border_image_new_for_gradient (GtkGradient *gradient,
GtkBorder *slice,
+ GtkBorder *width,
GtkCssBorderImageRepeat *repeat);
GtkBorderImage * _gtk_border_image_ref (GtkBorderImage *image);
diff --git a/gtk/gtkcssprovider.c b/gtk/gtkcssprovider.c
index 42a25a9..4258b3e 100644
--- a/gtk/gtkcssprovider.c
+++ b/gtk/gtkcssprovider.c
@@ -538,7 +538,7 @@
* <inlinegraphic fileref="slices.png" format="PNG"/>
* <para>
* The parameters of the slicing process are controlled by
- * three separate properties. Note that you can use the
+ * four separate properties. Note that you can use the
* <literallayout>border-image</literallayout> shorthand property
* to set values for the three properties at the same time.
* </para>
@@ -556,6 +556,14 @@
* of the border.
* </para>
* <para>
+ * <literallayout>border-image-width: @top @right @bottom @left</literallayout>
+ * The sizes specified by the @top, @right, @bottom and @left parameters
+ * are inward distances from the border box edge, used to specify the
+ * rendered size of each slice determined by border-image-slice.
+ * If this property is not specified, the values of border-width will
+ * be used as a fallback.
+ * </para>
+ * <para>
* <literallayout>border-image-repeat: [stretch|repeat|round|space] ?
* [stretch|repeat|round|space]</literallayout>
* Specifies how the image slices should be rendered in the area
diff --git a/gtk/gtkstyleproperty.c b/gtk/gtkstyleproperty.c
index 7a93c6a..ce2f4e1 100644
--- a/gtk/gtkstyleproperty.c
+++ b/gtk/gtkstyleproperty.c
@@ -1023,7 +1023,7 @@ border_image_value_parse (GtkCssParser *parser,
GValue temp = { 0, };
cairo_pattern_t *pattern = NULL;
GtkGradient *gradient = NULL;
- GtkBorder border, *parsed_border;
+ GtkBorder slice, *width = NULL, *parsed_slice;
GtkCssBorderImageRepeat repeat, *parsed_repeat;
gboolean retval = FALSE;
GtkBorderImage *image = NULL;
@@ -1044,8 +1044,19 @@ border_image_value_parse (GtkCssParser *parser,
if (!border_value_parse (parser, base, &temp))
goto out;
- parsed_border = g_value_get_boxed (&temp);
- border = *parsed_border;
+ parsed_slice = g_value_get_boxed (&temp);
+ slice = *parsed_slice;
+
+ if (_gtk_css_parser_try (parser, "/", TRUE))
+ {
+ g_value_unset (&temp);
+ g_value_init (&temp, GTK_TYPE_BORDER);
+
+ if (!border_value_parse (parser, base, &temp))
+ goto out;
+
+ width = g_value_dup_boxed (&temp);
+ }
g_value_unset (&temp);
g_value_init (&temp, GTK_TYPE_CSS_BORDER_IMAGE_REPEAT);
@@ -1059,9 +1070,9 @@ border_image_value_parse (GtkCssParser *parser,
g_value_unset (&temp);
if (gradient != NULL)
- image = _gtk_border_image_new_for_gradient (gradient, &border, &repeat);
+ image = _gtk_border_image_new_for_gradient (gradient, &slice, width, &repeat);
else if (pattern != NULL)
- image = _gtk_border_image_new (pattern, &border, &repeat);
+ image = _gtk_border_image_new (pattern, &slice, width, &repeat);
if (image != NULL)
{
@@ -1076,6 +1087,9 @@ border_image_value_parse (GtkCssParser *parser,
if (gradient != NULL)
gtk_gradient_unref (gradient);
+ if (width != NULL)
+ gtk_border_free (width);
+
return retval;
}
@@ -2231,6 +2245,11 @@ gtk_style_property_init (void)
"Border image slice",
"Border image slice",
GTK_TYPE_BORDER, 0));
+ gtk_style_properties_register_property (NULL,
+ g_param_spec_boxed ("border-image-width",
+ "Border image width",
+ "Border image width",
+ GTK_TYPE_BORDER, 0));
_gtk_style_property_register (g_param_spec_boxed ("border-image",
"Border Image",
"Border Image",
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]