From d4344164acf993cfa2deb65e8df124ee8ebd2ad6 Mon Sep 17 00:00:00 2001 From: Benjamin Otte Date: Sat, 31 Dec 2011 15:05:09 +0100 Subject: [PATCH] styleproperty: Move shorthand declarations to new file --- gtk/Makefile.am | 1 + gtk/gtkcssshorthandpropertyimpl.c | 855 +++++++++++++++++++++++++++ gtk/gtkcssshorthandpropertyprivate.h | 2 + gtk/gtkstyleproperty.c | 806 +------------------------ 4 files changed, 861 insertions(+), 803 deletions(-) create mode 100644 gtk/gtkcssshorthandpropertyimpl.c diff --git a/gtk/Makefile.am b/gtk/Makefile.am index 5407674b76..13252b6636 100644 --- a/gtk/Makefile.am +++ b/gtk/Makefile.am @@ -592,6 +592,7 @@ gtk_base_c_sources = \ gtkcsssection.c \ gtkcssselector.c \ gtkcssshorthandproperty.c \ + gtkcssshorthandpropertyimpl.c \ gtkcssstyleproperty.c \ gtkcsstypes.c \ gtkdialog.c \ diff --git a/gtk/gtkcssshorthandpropertyimpl.c b/gtk/gtkcssshorthandpropertyimpl.c new file mode 100644 index 0000000000..493377adb3 --- /dev/null +++ b/gtk/gtkcssshorthandpropertyimpl.c @@ -0,0 +1,855 @@ +/* + * Copyright © 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.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, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + * + * Authors: Benjamin Otte + */ + +#include "config.h" + +#include "gtkcssshorthandpropertyprivate.h" + +#include +#include + +#include "gtkborderimageprivate.h" +#include "gtkcsstypesprivate.h" + +/* this is in case round() is not provided by the compiler, + * such as in the case of C89 compilers, like MSVC + */ +#include "fallback-c89.c" + +/*** PARSING ***/ + +static gboolean +border_image_value_parse (GtkCssParser *parser, + GFile *base, + GValue *value) +{ + GValue temp = G_VALUE_INIT; + cairo_pattern_t *pattern = NULL; + gconstpointer *boxed = NULL; + GType boxed_type; + GtkBorder slice, *width = NULL, *parsed_slice; + GtkCssBorderImageRepeat repeat, *parsed_repeat; + gboolean retval = FALSE; + GtkBorderImage *image = NULL; + + if (_gtk_css_parser_try (parser, "none", TRUE)) + return TRUE; + + g_value_init (&temp, CAIRO_GOBJECT_TYPE_PATTERN); + + if (!_gtk_style_property_parse_value (NULL, &temp, parser, base)) + return FALSE; + + boxed_type = G_VALUE_TYPE (&temp); + if (boxed_type != CAIRO_GOBJECT_TYPE_PATTERN) + boxed = g_value_dup_boxed (&temp); + else + pattern = g_value_dup_boxed (&temp); + + g_value_unset (&temp); + g_value_init (&temp, GTK_TYPE_BORDER); + + if (!_gtk_style_property_parse_value (NULL, &temp, parser, base)) + goto out; + + 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 (!_gtk_style_property_parse_value (NULL, &temp, parser, base)) + goto out; + + width = g_value_dup_boxed (&temp); + } + + g_value_unset (&temp); + g_value_init (&temp, GTK_TYPE_CSS_BORDER_IMAGE_REPEAT); + + if (!_gtk_style_property_parse_value (NULL, &temp, parser, base)) + goto out; + + parsed_repeat = g_value_get_boxed (&temp); + repeat = *parsed_repeat; + + g_value_unset (&temp); + + if (boxed != NULL) + image = _gtk_border_image_new_for_boxed (boxed_type, boxed, &slice, width, &repeat); + else if (pattern != NULL) + image = _gtk_border_image_new (pattern, &slice, width, &repeat); + + if (image != NULL) + { + retval = TRUE; + g_value_take_boxed (value, image); + } + + out: + if (pattern != NULL) + cairo_pattern_destroy (pattern); + + if (boxed != NULL) + g_boxed_free (boxed_type, boxed); + + if (width != NULL) + gtk_border_free (width); + + return retval; +} + +static gboolean +border_radius_value_parse (GtkCssParser *parser, + GFile *base, + GValue *value) +{ + GtkCssBorderRadius border; + + if (!_gtk_css_parser_try_double (parser, &border.top_left.horizontal)) + { + _gtk_css_parser_error (parser, "Expected a number"); + return FALSE; + } + else if (border.top_left.horizontal < 0) + goto negative; + + if (_gtk_css_parser_try_double (parser, &border.top_right.horizontal)) + { + if (border.top_right.horizontal < 0) + goto negative; + if (_gtk_css_parser_try_double (parser, &border.bottom_right.horizontal)) + { + if (border.bottom_right.horizontal < 0) + goto negative; + if (!_gtk_css_parser_try_double (parser, &border.bottom_left.horizontal)) + border.bottom_left.horizontal = border.top_right.horizontal; + else if (border.bottom_left.horizontal < 0) + goto negative; + } + else + { + border.bottom_right.horizontal = border.top_left.horizontal; + border.bottom_left.horizontal = border.top_right.horizontal; + } + } + else + { + border.top_right.horizontal = border.top_left.horizontal; + border.bottom_right.horizontal = border.top_left.horizontal; + border.bottom_left.horizontal = border.top_left.horizontal; + } + + if (_gtk_css_parser_try (parser, "/", TRUE)) + { + if (!_gtk_css_parser_try_double (parser, &border.top_left.vertical)) + { + _gtk_css_parser_error (parser, "Expected a number"); + return FALSE; + } + else if (border.top_left.vertical < 0) + goto negative; + + if (_gtk_css_parser_try_double (parser, &border.top_right.vertical)) + { + if (border.top_right.vertical < 0) + goto negative; + if (_gtk_css_parser_try_double (parser, &border.bottom_right.vertical)) + { + if (border.bottom_right.vertical < 0) + goto negative; + if (!_gtk_css_parser_try_double (parser, &border.bottom_left.vertical)) + border.bottom_left.vertical = border.top_right.vertical; + else if (border.bottom_left.vertical < 0) + goto negative; + } + else + { + border.bottom_right.vertical = border.top_left.vertical; + border.bottom_left.vertical = border.top_right.vertical; + } + } + else + { + border.top_right.vertical = border.top_left.vertical; + border.bottom_right.vertical = border.top_left.vertical; + border.bottom_left.vertical = border.top_left.vertical; + } + } + else + { + border.top_left.vertical = border.top_left.horizontal; + border.top_right.vertical = border.top_right.horizontal; + border.bottom_right.vertical = border.bottom_right.horizontal; + border.bottom_left.vertical = border.bottom_left.horizontal; + } + + /* border-radius is an int property for backwards-compat reasons */ + g_value_unset (value); + g_value_init (value, GTK_TYPE_CSS_BORDER_RADIUS); + g_value_set_boxed (value, &border); + + return TRUE; + +negative: + _gtk_css_parser_error (parser, "Border radius values cannot be negative"); + return FALSE; +} + +static gboolean +border_color_shorthand_value_parse (GtkCssParser *parser, + GFile *base, + GValue *value) +{ + GtkSymbolicColor *symbolic; + GPtrArray *array; + + array = g_ptr_array_new_with_free_func ((GDestroyNotify) gtk_symbolic_color_unref); + + do + { + if (_gtk_css_parser_try (parser, "transparent", TRUE)) + { + GdkRGBA transparent = { 0, 0, 0, 0 }; + + symbolic = gtk_symbolic_color_new_literal (&transparent); + } + else + { + symbolic = _gtk_css_parser_read_symbolic_color (parser); + + if (symbolic == NULL) + return FALSE; + } + + g_ptr_array_add (array, symbolic); + } + while (array->len < 4 && + !_gtk_css_parser_is_eof (parser) && + !_gtk_css_parser_begins_with (parser, ';') && + !_gtk_css_parser_begins_with (parser, '}')); + + switch (array->len) + { + default: + g_assert_not_reached (); + break; + case 1: + g_ptr_array_add (array, gtk_symbolic_color_ref (g_ptr_array_index (array, 0))); + /* fall through */ + case 2: + g_ptr_array_add (array, gtk_symbolic_color_ref (g_ptr_array_index (array, 0))); + /* fall through */ + case 3: + g_ptr_array_add (array, gtk_symbolic_color_ref (g_ptr_array_index (array, 1))); + /* fall through */ + case 4: + break; + } + + g_value_unset (value); + g_value_init (value, G_TYPE_PTR_ARRAY); + g_value_take_boxed (value, array); + + return TRUE; +} + +/*** PRINTING ***/ + +static void +string_append_double (GString *string, + double d) +{ + char buf[G_ASCII_DTOSTR_BUF_SIZE]; + + g_ascii_dtostr (buf, sizeof (buf), d); + g_string_append (string, buf); +} + +static void +border_radius_value_print (const GValue *value, + GString *string) +{ + GtkCssBorderRadius *border; + + border = g_value_get_boxed (value); + + if (border == NULL) + { + g_string_append (string, "none"); + return; + } + + string_append_double (string, border->top_left.horizontal); + if (border->top_left.horizontal != border->top_right.horizontal || + border->top_left.horizontal != border->bottom_right.horizontal || + border->top_left.horizontal != border->bottom_left.horizontal) + { + g_string_append_c (string, ' '); + string_append_double (string, border->top_right.horizontal); + if (border->top_left.horizontal != border->bottom_right.horizontal || + border->top_right.horizontal != border->bottom_left.horizontal) + { + g_string_append_c (string, ' '); + string_append_double (string, border->bottom_right.horizontal); + if (border->top_right.horizontal != border->bottom_left.horizontal) + { + g_string_append_c (string, ' '); + string_append_double (string, border->bottom_left.horizontal); + } + } + } + + if (border->top_left.horizontal != border->top_left.vertical || + border->top_right.horizontal != border->top_right.vertical || + border->bottom_right.horizontal != border->bottom_right.vertical || + border->bottom_left.horizontal != border->bottom_left.vertical) + { + g_string_append (string, " / "); + string_append_double (string, border->top_left.vertical); + if (border->top_left.vertical != border->top_right.vertical || + border->top_left.vertical != border->bottom_right.vertical || + border->top_left.vertical != border->bottom_left.vertical) + { + g_string_append_c (string, ' '); + string_append_double (string, border->top_right.vertical); + if (border->top_left.vertical != border->bottom_right.vertical || + border->top_right.vertical != border->bottom_left.vertical) + { + g_string_append_c (string, ' '); + string_append_double (string, border->bottom_right.vertical); + if (border->top_right.vertical != border->bottom_left.vertical) + { + g_string_append_c (string, ' '); + string_append_double (string, border->bottom_left.vertical); + } + } + } + + } +} + +/*** PACKING ***/ + +static GParameter * +unpack_border (const GValue *value, + guint *n_params, + const char *top, + const char *left, + const char *bottom, + const char *right) +{ + GParameter *parameter = g_new0 (GParameter, 4); + GtkBorder *border = g_value_get_boxed (value); + + parameter[0].name = top; + g_value_init (¶meter[0].value, G_TYPE_INT); + g_value_set_int (¶meter[0].value, border->top); + parameter[1].name = left; + g_value_init (¶meter[1].value, G_TYPE_INT); + g_value_set_int (¶meter[1].value, border->left); + parameter[2].name = bottom; + g_value_init (¶meter[2].value, G_TYPE_INT); + g_value_set_int (¶meter[2].value, border->bottom); + parameter[3].name = right; + g_value_init (¶meter[3].value, G_TYPE_INT); + g_value_set_int (¶meter[3].value, border->right); + + *n_params = 4; + return parameter; +} + +static void +pack_border (GValue *value, + GtkStyleProperties *props, + GtkStateFlags state, + const char *top, + const char *left, + const char *bottom, + const char *right) +{ + GtkBorder border; + int t, l, b, r; + + gtk_style_properties_get (props, + state, + top, &t, + left, &l, + bottom, &b, + right, &r, + NULL); + + border.top = t; + border.left = l; + border.bottom = b; + border.right = r; + + g_value_set_boxed (value, &border); +} + +static GParameter * +unpack_border_width (const GValue *value, + guint *n_params) +{ + return unpack_border (value, n_params, + "border-top-width", "border-left-width", + "border-bottom-width", "border-right-width"); +} + +static void +pack_border_width (GValue *value, + GtkStyleProperties *props, + GtkStateFlags state, + GtkStylePropertyContext *context) +{ + pack_border (value, props, state, + "border-top-width", "border-left-width", + "border-bottom-width", "border-right-width"); +} + +static GParameter * +unpack_padding (const GValue *value, + guint *n_params) +{ + return unpack_border (value, n_params, + "padding-top", "padding-left", + "padding-bottom", "padding-right"); +} + +static void +pack_padding (GValue *value, + GtkStyleProperties *props, + GtkStateFlags state, + GtkStylePropertyContext *context) +{ + pack_border (value, props, state, + "padding-top", "padding-left", + "padding-bottom", "padding-right"); +} + +static GParameter * +unpack_margin (const GValue *value, + guint *n_params) +{ + return unpack_border (value, n_params, + "margin-top", "margin-left", + "margin-bottom", "margin-right"); +} + +static void +pack_margin (GValue *value, + GtkStyleProperties *props, + GtkStateFlags state, + GtkStylePropertyContext *context) +{ + pack_border (value, props, state, + "margin-top", "margin-left", + "margin-bottom", "margin-right"); +} + +static GParameter * +unpack_border_radius (const GValue *value, + guint *n_params) +{ + GParameter *parameter = g_new0 (GParameter, 4); + GtkCssBorderRadius *border; + + if (G_VALUE_HOLDS_BOXED (value)) + border = g_value_get_boxed (value); + else + border = NULL; + + parameter[0].name = "border-top-left-radius"; + g_value_init (¶meter[0].value, GTK_TYPE_CSS_BORDER_CORNER_RADIUS); + parameter[1].name = "border-top-right-radius"; + g_value_init (¶meter[1].value, GTK_TYPE_CSS_BORDER_CORNER_RADIUS); + parameter[2].name = "border-bottom-right-radius"; + g_value_init (¶meter[2].value, GTK_TYPE_CSS_BORDER_CORNER_RADIUS); + parameter[3].name = "border-bottom-left-radius"; + g_value_init (¶meter[3].value, GTK_TYPE_CSS_BORDER_CORNER_RADIUS); + if (border) + { + g_value_set_boxed (¶meter[0].value, &border->top_left); + g_value_set_boxed (¶meter[1].value, &border->top_right); + g_value_set_boxed (¶meter[2].value, &border->bottom_right); + g_value_set_boxed (¶meter[3].value, &border->bottom_left); + } + + *n_params = 4; + return parameter; +} + +static void +pack_border_radius (GValue *value, + GtkStyleProperties *props, + GtkStateFlags state, + GtkStylePropertyContext *context) +{ + GtkCssBorderCornerRadius *top_left; + + /* NB: We are an int property, so we have to resolve to an int here. + * So we just resolve to an int. We pick one and stick to it. + * Lesson learned: Don't query border-radius shorthand, query the + * real properties instead. */ + gtk_style_properties_get (props, + state, + "border-top-left-radius", &top_left, + NULL); + + if (top_left) + g_value_set_int (value, top_left->horizontal); + + g_free (top_left); +} + +static GParameter * +unpack_font_description (const GValue *value, + guint *n_params) +{ + GParameter *parameter = g_new0 (GParameter, 5); + PangoFontDescription *description; + PangoFontMask mask; + guint n; + + /* For backwards compat, we only unpack values that are indeed set. + * For strict CSS conformance we need to unpack all of them. + * Note that we do set all of them in the parse function, so it + * will not have effects when parsing CSS files. It will though + * for custom style providers. + */ + + description = g_value_get_boxed (value); + n = 0; + + if (description) + mask = pango_font_description_get_set_fields (description); + else + mask = 0; + + if (mask & PANGO_FONT_MASK_FAMILY) + { + GPtrArray *strv = g_ptr_array_new (); + + g_ptr_array_add (strv, g_strdup (pango_font_description_get_family (description))); + g_ptr_array_add (strv, NULL); + parameter[n].name = "font-family"; + g_value_init (¶meter[n].value, G_TYPE_STRV); + g_value_take_boxed (¶meter[n].value, + g_ptr_array_free (strv, FALSE)); + n++; + } + + if (mask & PANGO_FONT_MASK_STYLE) + { + parameter[n].name = "font-style"; + g_value_init (¶meter[n].value, PANGO_TYPE_STYLE); + g_value_set_enum (¶meter[n].value, + pango_font_description_get_style (description)); + n++; + } + + if (mask & PANGO_FONT_MASK_VARIANT) + { + parameter[n].name = "font-variant"; + g_value_init (¶meter[n].value, PANGO_TYPE_VARIANT); + g_value_set_enum (¶meter[n].value, + pango_font_description_get_variant (description)); + n++; + } + + if (mask & PANGO_FONT_MASK_WEIGHT) + { + parameter[n].name = "font-weight"; + g_value_init (¶meter[n].value, PANGO_TYPE_WEIGHT); + g_value_set_enum (¶meter[n].value, + pango_font_description_get_weight (description)); + n++; + } + + if (mask & PANGO_FONT_MASK_SIZE) + { + parameter[n].name = "font-size"; + g_value_init (¶meter[n].value, G_TYPE_DOUBLE); + g_value_set_double (¶meter[n].value, + (double) pango_font_description_get_size (description) / PANGO_SCALE); + n++; + } + + *n_params = n; + + return parameter; +} + +static void +pack_font_description (GValue *value, + GtkStyleProperties *props, + GtkStateFlags state, + GtkStylePropertyContext *context) +{ + PangoFontDescription *description; + char **families; + PangoStyle style; + PangoVariant variant; + PangoWeight weight; + double size; + + gtk_style_properties_get (props, + state, + "font-family", &families, + "font-style", &style, + "font-variant", &variant, + "font-weight", &weight, + "font-size", &size, + NULL); + + description = pango_font_description_new (); + /* xxx: Can we set all the families here somehow? */ + if (families) + pango_font_description_set_family (description, families[0]); + pango_font_description_set_size (description, round (size * PANGO_SCALE)); + pango_font_description_set_style (description, style); + pango_font_description_set_variant (description, variant); + pango_font_description_set_weight (description, weight); + + g_strfreev (families); + + g_value_take_boxed (value, description); +} + +static GParameter * +unpack_border_color (const GValue *value, + guint *n_params) +{ + GParameter *parameter = g_new0 (GParameter, 4); + GType type; + + type = G_VALUE_TYPE (value); + if (type == G_TYPE_PTR_ARRAY) + type = GTK_TYPE_SYMBOLIC_COLOR; + + parameter[0].name = "border-top-color"; + g_value_init (¶meter[0].value, type); + parameter[1].name = "border-right-color"; + g_value_init (¶meter[1].value, type); + parameter[2].name = "border-bottom-color"; + g_value_init (¶meter[2].value, type); + parameter[3].name = "border-left-color"; + g_value_init (¶meter[3].value, type); + + if (G_VALUE_TYPE (value) == G_TYPE_PTR_ARRAY) + { + GPtrArray *array = g_value_get_boxed (value); + guint i; + + for (i = 0; i < 4; i++) + g_value_set_boxed (¶meter[i].value, g_ptr_array_index (array, i)); + } + else + { + /* can be RGBA or symbolic color */ + gpointer p = g_value_get_boxed (value); + + g_value_set_boxed (¶meter[0].value, p); + g_value_set_boxed (¶meter[1].value, p); + g_value_set_boxed (¶meter[2].value, p); + g_value_set_boxed (¶meter[3].value, p); + } + + *n_params = 4; + return parameter; +} + +static void +pack_border_color (GValue *value, + GtkStyleProperties *props, + GtkStateFlags state, + GtkStylePropertyContext *context) +{ + /* NB: We are a color property, so we have to resolve to a color here. + * So we just resolve to a color. We pick one and stick to it. + * Lesson learned: Don't query border-color shorthand, query the + * real properties instead. */ + g_value_unset (value); + gtk_style_properties_get_property (props, "border-top-color", state, value); +} + +/*** UNSET FUNCS ***/ + +static void +unset_font_description (GtkStyleProperties *props, + GtkStateFlags state) +{ + gtk_style_properties_unset_property (props, "font-family", state); + gtk_style_properties_unset_property (props, "font-style", state); + gtk_style_properties_unset_property (props, "font-variant", state); + gtk_style_properties_unset_property (props, "font-weight", state); + gtk_style_properties_unset_property (props, "font-size", state); +} + +static void +unset_margin (GtkStyleProperties *props, + GtkStateFlags state) +{ + gtk_style_properties_unset_property (props, "margin-top", state); + gtk_style_properties_unset_property (props, "margin-right", state); + gtk_style_properties_unset_property (props, "margin-bottom", state); + gtk_style_properties_unset_property (props, "margin-left", state); +} + +static void +unset_padding (GtkStyleProperties *props, + GtkStateFlags state) +{ + gtk_style_properties_unset_property (props, "padding-top", state); + gtk_style_properties_unset_property (props, "padding-right", state); + gtk_style_properties_unset_property (props, "padding-bottom", state); + gtk_style_properties_unset_property (props, "padding-left", state); +} + +static void +unset_border_width (GtkStyleProperties *props, + GtkStateFlags state) +{ + gtk_style_properties_unset_property (props, "border-top-width", state); + gtk_style_properties_unset_property (props, "border-right-width", state); + gtk_style_properties_unset_property (props, "border-bottom-width", state); + gtk_style_properties_unset_property (props, "border-left-width", state); +} + +static void +unset_border_radius (GtkStyleProperties *props, + GtkStateFlags state) +{ + gtk_style_properties_unset_property (props, "border-top-right-radius", state); + gtk_style_properties_unset_property (props, "border-bottom-right-radius", state); + gtk_style_properties_unset_property (props, "border-bottom-left-radius", state); + gtk_style_properties_unset_property (props, "border-top-left-radius", state); +} + +static void +unset_border_color (GtkStyleProperties *props, + GtkStateFlags state) +{ + gtk_style_properties_unset_property (props, "border-top-color", state); + gtk_style_properties_unset_property (props, "border-right-color", state); + gtk_style_properties_unset_property (props, "border-bottom-color", state); + gtk_style_properties_unset_property (props, "border-left-color", state); +} + +static void +unset_border_image (GtkStyleProperties *props, + GtkStateFlags state) +{ + gtk_style_properties_unset_property (props, "border-image-source", state); + gtk_style_properties_unset_property (props, "border-image-slice", state); + gtk_style_properties_unset_property (props, "border-image-repeat", state); + gtk_style_properties_unset_property (props, "border-image-width", state); +} + +void +_gtk_css_shorthand_property_init_properties (void) +{ + _gtk_style_property_register (g_param_spec_boxed ("font", + "Font Description", + "Font Description", + PANGO_TYPE_FONT_DESCRIPTION, 0), + GTK_STYLE_PROPERTY_INHERIT, + NULL, + unpack_font_description, + pack_font_description, + NULL, + NULL, + NULL, + unset_font_description); + _gtk_style_property_register (g_param_spec_boxed ("margin", + "Margin", + "Margin", + GTK_TYPE_BORDER, 0), + 0, + NULL, + unpack_margin, + pack_margin, + NULL, + NULL, + NULL, + unset_margin); + _gtk_style_property_register (g_param_spec_boxed ("padding", + "Padding", + "Padding", + GTK_TYPE_BORDER, 0), + 0, + NULL, + unpack_padding, + pack_padding, + NULL, + NULL, + NULL, + unset_padding); + _gtk_style_property_register (g_param_spec_boxed ("border-width", + "Border width", + "Border width, in pixels", + GTK_TYPE_BORDER, 0), + 0, + NULL, + unpack_border_width, + pack_border_width, + NULL, + NULL, + NULL, + unset_border_width); + _gtk_style_property_register (g_param_spec_int ("border-radius", + "Border radius", + "Border radius, in pixels", + 0, G_MAXINT, 0, 0), + 0, + NULL, + unpack_border_radius, + pack_border_radius, + border_radius_value_parse, + border_radius_value_print, + NULL, + unset_border_radius); + _gtk_style_property_register (g_param_spec_boxed ("border-color", + "Border color", + "Border color", + GDK_TYPE_RGBA, 0), + 0, + NULL, + unpack_border_color, + pack_border_color, + border_color_shorthand_value_parse, + NULL, + NULL, + unset_border_color); + _gtk_style_property_register (g_param_spec_boxed ("border-image", + "Border Image", + "Border Image", + GTK_TYPE_BORDER_IMAGE, 0), + 0, + NULL, + _gtk_border_image_unpack, + _gtk_border_image_pack, + border_image_value_parse, + NULL, + NULL, + unset_border_image); +} diff --git a/gtk/gtkcssshorthandpropertyprivate.h b/gtk/gtkcssshorthandpropertyprivate.h index d93a8f3837..50eaa2ba57 100644 --- a/gtk/gtkcssshorthandpropertyprivate.h +++ b/gtk/gtkcssshorthandpropertyprivate.h @@ -47,6 +47,8 @@ struct _GtkCssShorthandPropertyClass GtkStylePropertyClass parent_class; }; +void _gtk_css_shorthand_property_init_properties (void); + GType _gtk_css_shorthand_property_get_type (void) G_GNUC_CONST; diff --git a/gtk/gtkstyleproperty.c b/gtk/gtkstyleproperty.c index 171b29b1e9..d61fcec448 100644 --- a/gtk/gtkstyleproperty.c +++ b/gtk/gtkstyleproperty.c @@ -41,7 +41,6 @@ /* the actual parsers we have */ #include "gtkanimationdescription.h" #include "gtkbindings.h" -#include "gtkborderimageprivate.h" #include "gtkgradient.h" #include "gtkshadowprivate.h" #include "gtkthemingengine.h" @@ -1377,89 +1376,6 @@ border_image_repeat_value_print (const GValue *value, } } -static gboolean -border_image_value_parse (GtkCssParser *parser, - GFile *base, - GValue *value) -{ - GValue temp = G_VALUE_INIT; - cairo_pattern_t *pattern = NULL; - gconstpointer *boxed = NULL; - GType boxed_type; - GtkBorder slice, *width = NULL, *parsed_slice; - GtkCssBorderImageRepeat repeat, *parsed_repeat; - gboolean retval = FALSE; - GtkBorderImage *image = NULL; - - if (_gtk_css_parser_try (parser, "none", TRUE)) - return TRUE; - - g_value_init (&temp, CAIRO_GOBJECT_TYPE_PATTERN); - - if (!pattern_value_parse (parser, base, &temp)) - return FALSE; - - boxed_type = G_VALUE_TYPE (&temp); - if (boxed_type != CAIRO_GOBJECT_TYPE_PATTERN) - boxed = g_value_dup_boxed (&temp); - else - pattern = g_value_dup_boxed (&temp); - - g_value_unset (&temp); - g_value_init (&temp, GTK_TYPE_BORDER); - - if (!border_value_parse (parser, base, &temp)) - goto out; - - 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); - - if (!border_image_repeat_value_parse (parser, base, &temp)) - goto out; - - parsed_repeat = g_value_get_boxed (&temp); - repeat = *parsed_repeat; - - g_value_unset (&temp); - - if (boxed != NULL) - image = _gtk_border_image_new_for_boxed (boxed_type, boxed, &slice, width, &repeat); - else if (pattern != NULL) - image = _gtk_border_image_new (pattern, &slice, width, &repeat); - - if (image != NULL) - { - retval = TRUE; - g_value_take_boxed (value, image); - } - - out: - if (pattern != NULL) - cairo_pattern_destroy (pattern); - - if (boxed != NULL) - g_boxed_free (boxed_type, boxed); - - if (width != NULL) - gtk_border_free (width); - - return retval; -} - static gboolean enum_value_parse (GtkCssParser *parser, GFile *base, @@ -1663,166 +1579,6 @@ border_corner_radius_value_print (const GValue *value, } } -static gboolean -border_radius_value_parse (GtkCssParser *parser, - GFile *base, - GValue *value) -{ - GtkCssBorderRadius border; - - if (!_gtk_css_parser_try_double (parser, &border.top_left.horizontal)) - { - _gtk_css_parser_error (parser, "Expected a number"); - return FALSE; - } - else if (border.top_left.horizontal < 0) - goto negative; - - if (_gtk_css_parser_try_double (parser, &border.top_right.horizontal)) - { - if (border.top_right.horizontal < 0) - goto negative; - if (_gtk_css_parser_try_double (parser, &border.bottom_right.horizontal)) - { - if (border.bottom_right.horizontal < 0) - goto negative; - if (!_gtk_css_parser_try_double (parser, &border.bottom_left.horizontal)) - border.bottom_left.horizontal = border.top_right.horizontal; - else if (border.bottom_left.horizontal < 0) - goto negative; - } - else - { - border.bottom_right.horizontal = border.top_left.horizontal; - border.bottom_left.horizontal = border.top_right.horizontal; - } - } - else - { - border.top_right.horizontal = border.top_left.horizontal; - border.bottom_right.horizontal = border.top_left.horizontal; - border.bottom_left.horizontal = border.top_left.horizontal; - } - - if (_gtk_css_parser_try (parser, "/", TRUE)) - { - if (!_gtk_css_parser_try_double (parser, &border.top_left.vertical)) - { - _gtk_css_parser_error (parser, "Expected a number"); - return FALSE; - } - else if (border.top_left.vertical < 0) - goto negative; - - if (_gtk_css_parser_try_double (parser, &border.top_right.vertical)) - { - if (border.top_right.vertical < 0) - goto negative; - if (_gtk_css_parser_try_double (parser, &border.bottom_right.vertical)) - { - if (border.bottom_right.vertical < 0) - goto negative; - if (!_gtk_css_parser_try_double (parser, &border.bottom_left.vertical)) - border.bottom_left.vertical = border.top_right.vertical; - else if (border.bottom_left.vertical < 0) - goto negative; - } - else - { - border.bottom_right.vertical = border.top_left.vertical; - border.bottom_left.vertical = border.top_right.vertical; - } - } - else - { - border.top_right.vertical = border.top_left.vertical; - border.bottom_right.vertical = border.top_left.vertical; - border.bottom_left.vertical = border.top_left.vertical; - } - } - else - { - border.top_left.vertical = border.top_left.horizontal; - border.top_right.vertical = border.top_right.horizontal; - border.bottom_right.vertical = border.bottom_right.horizontal; - border.bottom_left.vertical = border.bottom_left.horizontal; - } - - /* border-radius is an int property for backwards-compat reasons */ - g_value_unset (value); - g_value_init (value, GTK_TYPE_CSS_BORDER_RADIUS); - g_value_set_boxed (value, &border); - - return TRUE; - -negative: - _gtk_css_parser_error (parser, "Border radius values cannot be negative"); - return FALSE; -} - -static void -border_radius_value_print (const GValue *value, - GString *string) -{ - GtkCssBorderRadius *border; - - border = g_value_get_boxed (value); - - if (border == NULL) - { - g_string_append (string, "none"); - return; - } - - string_append_double (string, border->top_left.horizontal); - if (border->top_left.horizontal != border->top_right.horizontal || - border->top_left.horizontal != border->bottom_right.horizontal || - border->top_left.horizontal != border->bottom_left.horizontal) - { - g_string_append_c (string, ' '); - string_append_double (string, border->top_right.horizontal); - if (border->top_left.horizontal != border->bottom_right.horizontal || - border->top_right.horizontal != border->bottom_left.horizontal) - { - g_string_append_c (string, ' '); - string_append_double (string, border->bottom_right.horizontal); - if (border->top_right.horizontal != border->bottom_left.horizontal) - { - g_string_append_c (string, ' '); - string_append_double (string, border->bottom_left.horizontal); - } - } - } - - if (border->top_left.horizontal != border->top_left.vertical || - border->top_right.horizontal != border->top_right.vertical || - border->bottom_right.horizontal != border->bottom_right.vertical || - border->bottom_left.horizontal != border->bottom_left.vertical) - { - g_string_append (string, " / "); - string_append_double (string, border->top_left.vertical); - if (border->top_left.vertical != border->top_right.vertical || - border->top_left.vertical != border->bottom_right.vertical || - border->top_left.vertical != border->bottom_left.vertical) - { - g_string_append_c (string, ' '); - string_append_double (string, border->top_right.vertical); - if (border->top_left.vertical != border->bottom_right.vertical || - border->top_right.vertical != border->bottom_left.vertical) - { - g_string_append_c (string, ' '); - string_append_double (string, border->bottom_right.vertical); - if (border->top_right.vertical != border->bottom_left.vertical) - { - g_string_append_c (string, ' '); - string_append_double (string, border->bottom_left.vertical); - } - } - } - - } -} - static gboolean transparent_color_value_parse (GtkCssParser *parser, GFile *base, @@ -1840,481 +1596,6 @@ transparent_color_value_parse (GtkCssParser *parser, return rgba_value_parse (parser, base, value); } -static gboolean -border_color_shorthand_value_parse (GtkCssParser *parser, - GFile *base, - GValue *value) -{ - GtkSymbolicColor *symbolic; - GPtrArray *array; - - array = g_ptr_array_new_with_free_func ((GDestroyNotify) gtk_symbolic_color_unref); - - do - { - if (_gtk_css_parser_try (parser, "transparent", TRUE)) - { - GdkRGBA transparent = { 0, 0, 0, 0 }; - - symbolic = gtk_symbolic_color_new_literal (&transparent); - } - else - { - symbolic = _gtk_css_parser_read_symbolic_color (parser); - - if (symbolic == NULL) - return FALSE; - } - - g_ptr_array_add (array, symbolic); - } - while (array->len < 4 && - !_gtk_css_parser_is_eof (parser) && - !_gtk_css_parser_begins_with (parser, ';') && - !_gtk_css_parser_begins_with (parser, '}')); - - switch (array->len) - { - default: - g_assert_not_reached (); - break; - case 1: - g_ptr_array_add (array, gtk_symbolic_color_ref (g_ptr_array_index (array, 0))); - /* fall through */ - case 2: - g_ptr_array_add (array, gtk_symbolic_color_ref (g_ptr_array_index (array, 0))); - /* fall through */ - case 3: - g_ptr_array_add (array, gtk_symbolic_color_ref (g_ptr_array_index (array, 1))); - /* fall through */ - case 4: - break; - } - - g_value_unset (value); - g_value_init (value, G_TYPE_PTR_ARRAY); - g_value_take_boxed (value, array); - - return TRUE; -} - -/*** PACKING ***/ - -static GParameter * -unpack_border (const GValue *value, - guint *n_params, - const char *top, - const char *left, - const char *bottom, - const char *right) -{ - GParameter *parameter = g_new0 (GParameter, 4); - GtkBorder *border = g_value_get_boxed (value); - - parameter[0].name = top; - g_value_init (¶meter[0].value, G_TYPE_INT); - g_value_set_int (¶meter[0].value, border->top); - parameter[1].name = left; - g_value_init (¶meter[1].value, G_TYPE_INT); - g_value_set_int (¶meter[1].value, border->left); - parameter[2].name = bottom; - g_value_init (¶meter[2].value, G_TYPE_INT); - g_value_set_int (¶meter[2].value, border->bottom); - parameter[3].name = right; - g_value_init (¶meter[3].value, G_TYPE_INT); - g_value_set_int (¶meter[3].value, border->right); - - *n_params = 4; - return parameter; -} - -static void -pack_border (GValue *value, - GtkStyleProperties *props, - GtkStateFlags state, - const char *top, - const char *left, - const char *bottom, - const char *right) -{ - GtkBorder border; - int t, l, b, r; - - gtk_style_properties_get (props, - state, - top, &t, - left, &l, - bottom, &b, - right, &r, - NULL); - - border.top = t; - border.left = l; - border.bottom = b; - border.right = r; - - g_value_set_boxed (value, &border); -} - -static GParameter * -unpack_border_width (const GValue *value, - guint *n_params) -{ - return unpack_border (value, n_params, - "border-top-width", "border-left-width", - "border-bottom-width", "border-right-width"); -} - -static void -pack_border_width (GValue *value, - GtkStyleProperties *props, - GtkStateFlags state, - GtkStylePropertyContext *context) -{ - pack_border (value, props, state, - "border-top-width", "border-left-width", - "border-bottom-width", "border-right-width"); -} - -static GParameter * -unpack_padding (const GValue *value, - guint *n_params) -{ - return unpack_border (value, n_params, - "padding-top", "padding-left", - "padding-bottom", "padding-right"); -} - -static void -pack_padding (GValue *value, - GtkStyleProperties *props, - GtkStateFlags state, - GtkStylePropertyContext *context) -{ - pack_border (value, props, state, - "padding-top", "padding-left", - "padding-bottom", "padding-right"); -} - -static GParameter * -unpack_margin (const GValue *value, - guint *n_params) -{ - return unpack_border (value, n_params, - "margin-top", "margin-left", - "margin-bottom", "margin-right"); -} - -static void -pack_margin (GValue *value, - GtkStyleProperties *props, - GtkStateFlags state, - GtkStylePropertyContext *context) -{ - pack_border (value, props, state, - "margin-top", "margin-left", - "margin-bottom", "margin-right"); -} - -static GParameter * -unpack_border_radius (const GValue *value, - guint *n_params) -{ - GParameter *parameter = g_new0 (GParameter, 4); - GtkCssBorderRadius *border; - - if (G_VALUE_HOLDS_BOXED (value)) - border = g_value_get_boxed (value); - else - border = NULL; - - parameter[0].name = "border-top-left-radius"; - g_value_init (¶meter[0].value, GTK_TYPE_CSS_BORDER_CORNER_RADIUS); - parameter[1].name = "border-top-right-radius"; - g_value_init (¶meter[1].value, GTK_TYPE_CSS_BORDER_CORNER_RADIUS); - parameter[2].name = "border-bottom-right-radius"; - g_value_init (¶meter[2].value, GTK_TYPE_CSS_BORDER_CORNER_RADIUS); - parameter[3].name = "border-bottom-left-radius"; - g_value_init (¶meter[3].value, GTK_TYPE_CSS_BORDER_CORNER_RADIUS); - if (border) - { - g_value_set_boxed (¶meter[0].value, &border->top_left); - g_value_set_boxed (¶meter[1].value, &border->top_right); - g_value_set_boxed (¶meter[2].value, &border->bottom_right); - g_value_set_boxed (¶meter[3].value, &border->bottom_left); - } - - *n_params = 4; - return parameter; -} - -static void -pack_border_radius (GValue *value, - GtkStyleProperties *props, - GtkStateFlags state, - GtkStylePropertyContext *context) -{ - GtkCssBorderCornerRadius *top_left; - - /* NB: We are an int property, so we have to resolve to an int here. - * So we just resolve to an int. We pick one and stick to it. - * Lesson learned: Don't query border-radius shorthand, query the - * real properties instead. */ - gtk_style_properties_get (props, - state, - "border-top-left-radius", &top_left, - NULL); - - if (top_left) - g_value_set_int (value, top_left->horizontal); - - g_free (top_left); -} - -static GParameter * -unpack_font_description (const GValue *value, - guint *n_params) -{ - GParameter *parameter = g_new0 (GParameter, 5); - PangoFontDescription *description; - PangoFontMask mask; - guint n; - - /* For backwards compat, we only unpack values that are indeed set. - * For strict CSS conformance we need to unpack all of them. - * Note that we do set all of them in the parse function, so it - * will not have effects when parsing CSS files. It will though - * for custom style providers. - */ - - description = g_value_get_boxed (value); - n = 0; - - if (description) - mask = pango_font_description_get_set_fields (description); - else - mask = 0; - - if (mask & PANGO_FONT_MASK_FAMILY) - { - GPtrArray *strv = g_ptr_array_new (); - - g_ptr_array_add (strv, g_strdup (pango_font_description_get_family (description))); - g_ptr_array_add (strv, NULL); - parameter[n].name = "font-family"; - g_value_init (¶meter[n].value, G_TYPE_STRV); - g_value_take_boxed (¶meter[n].value, - g_ptr_array_free (strv, FALSE)); - n++; - } - - if (mask & PANGO_FONT_MASK_STYLE) - { - parameter[n].name = "font-style"; - g_value_init (¶meter[n].value, PANGO_TYPE_STYLE); - g_value_set_enum (¶meter[n].value, - pango_font_description_get_style (description)); - n++; - } - - if (mask & PANGO_FONT_MASK_VARIANT) - { - parameter[n].name = "font-variant"; - g_value_init (¶meter[n].value, PANGO_TYPE_VARIANT); - g_value_set_enum (¶meter[n].value, - pango_font_description_get_variant (description)); - n++; - } - - if (mask & PANGO_FONT_MASK_WEIGHT) - { - parameter[n].name = "font-weight"; - g_value_init (¶meter[n].value, PANGO_TYPE_WEIGHT); - g_value_set_enum (¶meter[n].value, - pango_font_description_get_weight (description)); - n++; - } - - if (mask & PANGO_FONT_MASK_SIZE) - { - parameter[n].name = "font-size"; - g_value_init (¶meter[n].value, G_TYPE_DOUBLE); - g_value_set_double (¶meter[n].value, - (double) pango_font_description_get_size (description) / PANGO_SCALE); - n++; - } - - *n_params = n; - - return parameter; -} - -static void -pack_font_description (GValue *value, - GtkStyleProperties *props, - GtkStateFlags state, - GtkStylePropertyContext *context) -{ - PangoFontDescription *description; - char **families; - PangoStyle style; - PangoVariant variant; - PangoWeight weight; - double size; - - gtk_style_properties_get (props, - state, - "font-family", &families, - "font-style", &style, - "font-variant", &variant, - "font-weight", &weight, - "font-size", &size, - NULL); - - description = pango_font_description_new (); - /* xxx: Can we set all the families here somehow? */ - if (families) - pango_font_description_set_family (description, families[0]); - pango_font_description_set_size (description, round (size * PANGO_SCALE)); - pango_font_description_set_style (description, style); - pango_font_description_set_variant (description, variant); - pango_font_description_set_weight (description, weight); - - g_strfreev (families); - - g_value_take_boxed (value, description); -} - -static GParameter * -unpack_border_color (const GValue *value, - guint *n_params) -{ - GParameter *parameter = g_new0 (GParameter, 4); - GType type; - - type = G_VALUE_TYPE (value); - if (type == G_TYPE_PTR_ARRAY) - type = GTK_TYPE_SYMBOLIC_COLOR; - - parameter[0].name = "border-top-color"; - g_value_init (¶meter[0].value, type); - parameter[1].name = "border-right-color"; - g_value_init (¶meter[1].value, type); - parameter[2].name = "border-bottom-color"; - g_value_init (¶meter[2].value, type); - parameter[3].name = "border-left-color"; - g_value_init (¶meter[3].value, type); - - if (G_VALUE_TYPE (value) == G_TYPE_PTR_ARRAY) - { - GPtrArray *array = g_value_get_boxed (value); - guint i; - - for (i = 0; i < 4; i++) - g_value_set_boxed (¶meter[i].value, g_ptr_array_index (array, i)); - } - else - { - /* can be RGBA or symbolic color */ - gpointer p = g_value_get_boxed (value); - - g_value_set_boxed (¶meter[0].value, p); - g_value_set_boxed (¶meter[1].value, p); - g_value_set_boxed (¶meter[2].value, p); - g_value_set_boxed (¶meter[3].value, p); - } - - *n_params = 4; - return parameter; -} - -static void -pack_border_color (GValue *value, - GtkStyleProperties *props, - GtkStateFlags state, - GtkStylePropertyContext *context) -{ - /* NB: We are a color property, so we have to resolve to a color here. - * So we just resolve to a color. We pick one and stick to it. - * Lesson learned: Don't query border-color shorthand, query the - * real properties instead. */ - g_value_unset (value); - gtk_style_properties_get_property (props, "border-top-color", state, value); -} - -/*** UNSET FUNCS ***/ - -static void -unset_font_description (GtkStyleProperties *props, - GtkStateFlags state) -{ - gtk_style_properties_unset_property (props, "font-family", state); - gtk_style_properties_unset_property (props, "font-style", state); - gtk_style_properties_unset_property (props, "font-variant", state); - gtk_style_properties_unset_property (props, "font-weight", state); - gtk_style_properties_unset_property (props, "font-size", state); -} - -static void -unset_margin (GtkStyleProperties *props, - GtkStateFlags state) -{ - gtk_style_properties_unset_property (props, "margin-top", state); - gtk_style_properties_unset_property (props, "margin-right", state); - gtk_style_properties_unset_property (props, "margin-bottom", state); - gtk_style_properties_unset_property (props, "margin-left", state); -} - -static void -unset_padding (GtkStyleProperties *props, - GtkStateFlags state) -{ - gtk_style_properties_unset_property (props, "padding-top", state); - gtk_style_properties_unset_property (props, "padding-right", state); - gtk_style_properties_unset_property (props, "padding-bottom", state); - gtk_style_properties_unset_property (props, "padding-left", state); -} - -static void -unset_border_width (GtkStyleProperties *props, - GtkStateFlags state) -{ - gtk_style_properties_unset_property (props, "border-top-width", state); - gtk_style_properties_unset_property (props, "border-right-width", state); - gtk_style_properties_unset_property (props, "border-bottom-width", state); - gtk_style_properties_unset_property (props, "border-left-width", state); -} - -static void -unset_border_radius (GtkStyleProperties *props, - GtkStateFlags state) -{ - gtk_style_properties_unset_property (props, "border-top-right-radius", state); - gtk_style_properties_unset_property (props, "border-bottom-right-radius", state); - gtk_style_properties_unset_property (props, "border-bottom-left-radius", state); - gtk_style_properties_unset_property (props, "border-top-left-radius", state); -} - -static void -unset_border_color (GtkStyleProperties *props, - GtkStateFlags state) -{ - gtk_style_properties_unset_property (props, "border-top-color", state); - gtk_style_properties_unset_property (props, "border-right-color", state); - gtk_style_properties_unset_property (props, "border-bottom-color", state); - gtk_style_properties_unset_property (props, "border-left-color", state); -} - -static void -unset_border_image (GtkStyleProperties *props, - GtkStateFlags state) -{ - gtk_style_properties_unset_property (props, "border-image-source", state); - gtk_style_properties_unset_property (props, "border-image-slice", state); - gtk_style_properties_unset_property (props, "border-image-repeat", state); - gtk_style_properties_unset_property (props, "border-image-width", state); -} - /*** API ***/ guint @@ -2904,18 +2185,6 @@ gtk_style_property_init_properties (void) &value, NULL); g_value_unset (&value); - _gtk_style_property_register (g_param_spec_boxed ("font", - "Font Description", - "Font Description", - PANGO_TYPE_FONT_DESCRIPTION, 0), - GTK_STYLE_PROPERTY_INHERIT, - NULL, - unpack_font_description, - pack_font_description, - font_description_value_parse, - font_description_value_print, - NULL, - unset_font_description); _gtk_style_property_register (g_param_spec_boxed ("text-shadow", "Text shadow", @@ -2968,18 +2237,6 @@ gtk_style_property_init_properties (void) "margin right", "Margin at right", 0, G_MAXINT, 0, 0)); - _gtk_style_property_register (g_param_spec_boxed ("margin", - "Margin", - "Margin", - GTK_TYPE_BORDER, 0), - 0, - NULL, - unpack_margin, - pack_margin, - NULL, - NULL, - NULL, - unset_margin); gtk_style_properties_register_property (NULL, g_param_spec_int ("padding-top", "padding top", @@ -3000,18 +2257,6 @@ gtk_style_property_init_properties (void) "padding right", "Padding at right", 0, G_MAXINT, 0, 0)); - _gtk_style_property_register (g_param_spec_boxed ("padding", - "Padding", - "Padding", - GTK_TYPE_BORDER, 0), - 0, - NULL, - unpack_padding, - pack_padding, - NULL, - NULL, - NULL, - unset_padding); gtk_style_properties_register_property (NULL, g_param_spec_int ("border-top-width", "border top width", @@ -3032,18 +2277,6 @@ gtk_style_property_init_properties (void) "border right width", "Border width at right", 0, G_MAXINT, 0, 0)); - _gtk_style_property_register (g_param_spec_boxed ("border-width", - "Border width", - "Border width, in pixels", - GTK_TYPE_BORDER, 0), - 0, - NULL, - unpack_border_width, - pack_border_width, - NULL, - NULL, - NULL, - unset_border_width); _gtk_style_property_register (g_param_spec_boxed ("border-top-left-radius", "Border top left radius", @@ -3093,18 +2326,6 @@ gtk_style_property_init_properties (void) border_corner_radius_value_print, NULL, NULL); - _gtk_style_property_register (g_param_spec_int ("border-radius", - "Border radius", - "Border radius, in pixels", - 0, G_MAXINT, 0, 0), - 0, - NULL, - unpack_border_radius, - pack_border_radius, - border_radius_value_parse, - border_radius_value_print, - NULL, - unset_border_radius); gtk_style_properties_register_property (NULL, g_param_spec_enum ("border-style", @@ -3175,18 +2396,6 @@ gtk_style_property_init_properties (void) &value, NULL); g_value_unset (&value); - _gtk_style_property_register (g_param_spec_boxed ("border-color", - "Border color", - "Border color", - GDK_TYPE_RGBA, 0), - 0, - NULL, - unpack_border_color, - pack_border_color, - border_color_shorthand_value_parse, - NULL, - NULL, - unset_border_color); gtk_style_properties_register_property (NULL, g_param_spec_boxed ("background-image", @@ -3228,18 +2437,6 @@ gtk_style_property_init_properties (void) &value, NULL); g_value_unset (&value); - _gtk_style_property_register (g_param_spec_boxed ("border-image", - "Border Image", - "Border Image", - GTK_TYPE_BORDER_IMAGE, 0), - 0, - NULL, - _gtk_border_image_unpack, - _gtk_border_image_pack, - NULL, - NULL, - NULL, - unset_border_image); gtk_style_properties_register_property (NULL, g_param_spec_object ("engine", "Theming Engine", @@ -3264,6 +2461,9 @@ gtk_style_property_init_properties (void) bindings_value_print, NULL, NULL); + + /* initialize shorthands last, they depend on the real properties existing */ + _gtk_css_shorthand_property_init_properties (); } /**