diff --git a/gtk/Makefile.am b/gtk/Makefile.am index 99ac63d358..41e42d5b28 100644 --- a/gtk/Makefile.am +++ b/gtk/Makefile.am @@ -438,6 +438,7 @@ gtk_private_h_sources = \ gtkcssshorthandpropertyprivate.h \ gtkcssstylefuncsprivate.h \ gtkcssstylepropertyprivate.h \ + gtkcssvalueprivate.h \ gtkcustompaperunixdialog.h \ gtkentryprivate.h \ gtkfilechooserdefault.h \ @@ -634,6 +635,7 @@ gtk_base_c_sources = \ gtkcssstylefuncs.c \ gtkcssstyleproperty.c \ gtkcssstylepropertyimpl.c \ + gtkcssvalue.c \ gtkcsstypes.c \ gtkdialog.c \ gtkdrawingarea.c \ diff --git a/gtk/gtkborderimage.c b/gtk/gtkborderimage.c index e43abc6ce3..a05c9d5bfe 100644 --- a/gtk/gtkborderimage.c +++ b/gtk/gtkborderimage.c @@ -39,12 +39,12 @@ _gtk_border_image_init (GtkBorderImage *image, { GtkBorder *width; - image->source = g_value_get_object (_gtk_theming_engine_peek_property (engine, "border-image-source")); + image->source = _gtk_css_value_get_object (_gtk_theming_engine_peek_property (engine, "border-image-source")); if (image->source == NULL) return FALSE; - image->slice = *(GtkBorder *) g_value_get_boxed (_gtk_theming_engine_peek_property (engine, "border-image-slice")); - width = g_value_get_boxed (_gtk_theming_engine_peek_property (engine, "border-image-width")); + image->slice = *(GtkBorder *) _gtk_css_value_get_boxed (_gtk_theming_engine_peek_property (engine, "border-image-slice")); + width = _gtk_css_value_get_boxed (_gtk_theming_engine_peek_property (engine, "border-image-width")); if (width) { image->width = *width; @@ -53,8 +53,7 @@ _gtk_border_image_init (GtkBorderImage *image, else image->has_width = FALSE; - image->repeat = *(GtkCssBorderImageRepeat *) g_value_get_boxed ( - _gtk_theming_engine_peek_property (engine, "border-image-repeat")); + image->repeat = *_gtk_css_value_get_border_image_repeat (_gtk_theming_engine_peek_property (engine, "border-image-repeat")); return TRUE; } diff --git a/gtk/gtkcsscomputedvalues.c b/gtk/gtkcsscomputedvalues.c index 0eee9b68b7..305ff4fd41 100644 --- a/gtk/gtkcsscomputedvalues.c +++ b/gtk/gtkcsscomputedvalues.c @@ -34,7 +34,7 @@ gtk_css_computed_values_dispose (GObject *object) if (values->values) { - g_array_free (values->values, TRUE); + g_ptr_array_unref (values->values); values->values = NULL; } if (values->sections) @@ -77,7 +77,7 @@ void _gtk_css_computed_values_compute_value (GtkCssComputedValues *values, GtkStyleContext *context, guint id, - const GValue *specified, + GtkCssValue *specified, GtkCssSection *section) { GtkCssStyleProperty *prop; @@ -85,18 +85,14 @@ _gtk_css_computed_values_compute_value (GtkCssComputedValues *values, g_return_if_fail (GTK_IS_CSS_COMPUTED_VALUES (values)); g_return_if_fail (GTK_IS_STYLE_CONTEXT (context)); - g_return_if_fail (specified == NULL || G_IS_VALUE (specified)); prop = _gtk_css_style_property_lookup_by_id (id); parent = gtk_style_context_get_parent (context); if (values->values == NULL) - { - values->values = g_array_new (FALSE, TRUE, sizeof (GValue)); - g_array_set_clear_func (values->values, (GDestroyNotify) g_value_unset); - } + values->values = g_ptr_array_new_with_free_func ((GDestroyNotify)_gtk_css_value_unref); if (id <= values->values->len) - g_array_set_size (values->values, id + 1); + g_ptr_array_set_size (values->values, id + 1); /* http://www.w3.org/TR/css3-cascade/#cascade * Then, for every element, the value for each property can be found @@ -105,9 +101,9 @@ _gtk_css_computed_values_compute_value (GtkCssComputedValues *values, */ if (specified != NULL) { - if (G_VALUE_HOLDS (specified, GTK_TYPE_CSS_SPECIAL_VALUE)) + if (_gtk_css_value_is_special (specified)) { - switch (g_value_get_enum (specified)) + switch (_gtk_css_value_get_special_kind (specified)) { case GTK_CSS_INHERIT: /* 3) if the value of the winning declaration is ‘inherit’, @@ -159,20 +155,19 @@ _gtk_css_computed_values_compute_value (GtkCssComputedValues *values, if (specified) { - _gtk_css_style_property_compute_value (prop, - &g_array_index (values->values, GValue, id), - context, - specified); + g_ptr_array_index (values->values, id) = + _gtk_css_style_property_compute_value (prop, + context, + specified); } else { - const GValue *parent_value; - GValue *value = &g_array_index (values->values, GValue, id); + GtkCssValue *parent_value; /* Set NULL here and do the inheritance upon lookup? */ parent_value = _gtk_style_context_peek_property (parent, _gtk_style_property_get_name (GTK_STYLE_PROPERTY (prop))); - g_value_init (value, G_VALUE_TYPE (parent_value)); - g_value_copy (parent_value, value); + + g_ptr_array_index (values->values, id) = _gtk_css_value_ref (parent_value); } if (section) @@ -189,26 +184,17 @@ _gtk_css_computed_values_compute_value (GtkCssComputedValues *values, void _gtk_css_computed_values_set_value (GtkCssComputedValues *values, guint id, - const GValue *value, + GtkCssValue *value, GtkCssSection *section) { - GValue *set; - g_return_if_fail (GTK_IS_CSS_COMPUTED_VALUES (values)); - g_return_if_fail (value == NULL || G_IS_VALUE (value)); if (values->values == NULL) - { - values->values = g_array_new (FALSE, TRUE, sizeof (GValue)); - g_array_set_clear_func (values->values, (GDestroyNotify) g_value_unset); - } + values->values = g_ptr_array_new_with_free_func ((GDestroyNotify)_gtk_css_value_unref); if (id <= values->values->len) - g_array_set_size (values->values, id + 1); + g_ptr_array_set_size (values->values, id + 1); - - set = &g_array_index (values->values, GValue, id); - g_value_init (set, G_VALUE_TYPE (value)); - g_value_copy (value, set); + g_ptr_array_index (values->values, id) = _gtk_css_value_ref (value); if (section) { @@ -221,26 +207,20 @@ _gtk_css_computed_values_set_value (GtkCssComputedValues *values, } } -const GValue * +GtkCssValue * _gtk_css_computed_values_get_value (GtkCssComputedValues *values, guint id) { - const GValue *v; - g_return_val_if_fail (GTK_IS_CSS_COMPUTED_VALUES (values), NULL); if (values->values == NULL || id >= values->values->len) return NULL; - v = &g_array_index (values->values, GValue, id); - if (!G_IS_VALUE (v)) - return NULL; - - return v; + return g_ptr_array_index (values->values, id); } -const GValue * +GtkCssValue * _gtk_css_computed_values_get_value_by_name (GtkCssComputedValues *values, const char *name) { diff --git a/gtk/gtkcsscomputedvaluesprivate.h b/gtk/gtkcsscomputedvaluesprivate.h index f52064137e..1b4dc13293 100644 --- a/gtk/gtkcsscomputedvaluesprivate.h +++ b/gtk/gtkcsscomputedvaluesprivate.h @@ -24,6 +24,7 @@ #include "gtk/gtkcsssection.h" #include "gtk/gtkstylecontext.h" +#include "gtk/gtkcssvalueprivate.h" G_BEGIN_DECLS @@ -41,7 +42,7 @@ struct _GtkCssComputedValues { GObject parent; - GArray *values; + GPtrArray *values; GPtrArray *sections; }; @@ -57,16 +58,16 @@ GtkCssComputedValues * _gtk_css_computed_values_new (void); void _gtk_css_computed_values_compute_value (GtkCssComputedValues *values, GtkStyleContext *context, guint id, - const GValue *specified, + GtkCssValue *specified, GtkCssSection *section); void _gtk_css_computed_values_set_value (GtkCssComputedValues *values, guint id, - const GValue *value, + GtkCssValue *value, GtkCssSection *section); -const GValue * _gtk_css_computed_values_get_value (GtkCssComputedValues *values, +GtkCssValue * _gtk_css_computed_values_get_value (GtkCssComputedValues *values, guint id); -const GValue * _gtk_css_computed_values_get_value_by_name (GtkCssComputedValues *values, +GtkCssValue * _gtk_css_computed_values_get_value_by_name (GtkCssComputedValues *values, const char *name); GtkCssSection * _gtk_css_computed_values_get_section (GtkCssComputedValues *values, guint id); diff --git a/gtk/gtkcsscustomproperty.c b/gtk/gtkcsscustomproperty.c index a7009f8490..179705b5c1 100644 --- a/gtk/gtkcsscustomproperty.c +++ b/gtk/gtkcsscustomproperty.c @@ -91,29 +91,32 @@ gtk_css_custom_property_get_specified_type (GParamSpec *pspec) return pspec->value_type; } -static void -gtk_css_custom_property_create_initial_value (GParamSpec *pspec, - GValue *value) +static GtkCssValue * +gtk_css_custom_property_create_initial_value (GParamSpec *pspec) { - g_value_init (value, gtk_css_custom_property_get_specified_type (pspec)); + GValue value = G_VALUE_INIT; + + g_value_init (&value, gtk_css_custom_property_get_specified_type (pspec)); if (pspec->value_type == GTK_TYPE_THEMING_ENGINE) - g_value_set_object (value, gtk_theming_engine_load (NULL)); + g_value_set_object (&value, gtk_theming_engine_load (NULL)); else if (pspec->value_type == PANGO_TYPE_FONT_DESCRIPTION) - g_value_take_boxed (value, pango_font_description_from_string ("Sans 10")); + g_value_take_boxed (&value, pango_font_description_from_string ("Sans 10")); else if (pspec->value_type == GDK_TYPE_RGBA || pspec->value_type == GDK_TYPE_COLOR) { GdkRGBA color; gdk_rgba_parse (&color, "pink"); - g_value_take_boxed (value, gtk_symbolic_color_new_literal (&color)); + g_value_take_boxed (&value, gtk_symbolic_color_new_literal (&color)); } else if (pspec->value_type == GTK_TYPE_BORDER) { - g_value_take_boxed (value, gtk_border_new ()); + g_value_take_boxed (&value, gtk_border_new ()); } else - g_param_value_set_default (pspec, value); + g_param_value_set_default (pspec, &value); + + return _gtk_css_value_new_take_gvalue (&value); } /* Property registration functions */ @@ -164,7 +167,7 @@ gtk_theming_engine_register_property (const gchar *name_space, GParamSpec *pspec) { GtkCssCustomProperty *node; - GValue initial = { 0, }; + GtkCssValue *initial; gchar *name; g_return_if_fail (name_space != NULL); @@ -172,10 +175,10 @@ gtk_theming_engine_register_property (const gchar *name_space, g_return_if_fail (G_IS_PARAM_SPEC (pspec)); name = g_strdup_printf ("-%s-%s", name_space, pspec->name); - gtk_css_custom_property_create_initial_value (pspec, &initial); + initial = gtk_css_custom_property_create_initial_value (pspec); node = g_object_new (GTK_TYPE_CSS_CUSTOM_PROPERTY, - "initial-value", &initial, + "initial-value", initial, "name", name, "computed-type", pspec->value_type, "value-type", pspec->value_type, @@ -183,7 +186,7 @@ gtk_theming_engine_register_property (const gchar *name_space, node->pspec = pspec; node->property_parse_func = parse_func; - g_value_unset (&initial); + _gtk_css_value_unref (initial); g_free (name); } @@ -204,14 +207,14 @@ gtk_style_properties_register_property (GtkStylePropertyParser parse_func, GParamSpec *pspec) { GtkCssCustomProperty *node; - GValue initial = { 0, }; + GtkCssValue *initial; g_return_if_fail (G_IS_PARAM_SPEC (pspec)); - gtk_css_custom_property_create_initial_value (pspec, &initial); + initial = gtk_css_custom_property_create_initial_value (pspec); node = g_object_new (GTK_TYPE_CSS_CUSTOM_PROPERTY, - "initial-value", &initial, + "initial-value", initial, "name", pspec->name, "computed-type", pspec->value_type, "value-type", pspec->value_type, @@ -219,7 +222,7 @@ gtk_style_properties_register_property (GtkStylePropertyParser parse_func, node->pspec = pspec; node->property_parse_func = parse_func; - g_value_unset (&initial); + _gtk_css_value_unref (initial); } /** diff --git a/gtk/gtkcsslookup.c b/gtk/gtkcsslookup.c index a40e2df899..940f68cebb 100644 --- a/gtk/gtkcsslookup.c +++ b/gtk/gtkcsslookup.c @@ -26,8 +26,8 @@ typedef struct { GtkCssSection *section; - const GValue *value; - const GValue *computed; + GtkCssValue *value; + GtkCssValue *computed; } GtkCssLookupValue; struct _GtkCssLookup { @@ -91,7 +91,7 @@ void _gtk_css_lookup_set (GtkCssLookup *lookup, guint id, GtkCssSection *section, - const GValue *value) + GtkCssValue *value) { g_return_if_fail (lookup != NULL); g_return_if_fail (_gtk_bitmask_get (lookup->missing, id)); @@ -125,7 +125,7 @@ void _gtk_css_lookup_set_computed (GtkCssLookup *lookup, guint id, GtkCssSection *section, - const GValue *value) + GtkCssValue *value) { g_return_if_fail (lookup != NULL); g_return_if_fail (_gtk_bitmask_get (lookup->missing, id)); diff --git a/gtk/gtkcsslookupprivate.h b/gtk/gtkcsslookupprivate.h index 99d946788d..3e8824cdc7 100644 --- a/gtk/gtkcsslookupprivate.h +++ b/gtk/gtkcsslookupprivate.h @@ -38,11 +38,11 @@ gboolean _gtk_css_lookup_is_missing (const GtkCssLoo void _gtk_css_lookup_set (GtkCssLookup *lookup, guint id, GtkCssSection *section, - const GValue *value); + GtkCssValue *value); void _gtk_css_lookup_set_computed (GtkCssLookup *lookup, guint id, GtkCssSection *section, - const GValue *value); + GtkCssValue *value); void _gtk_css_lookup_resolve (GtkCssLookup *lookup, GtkStyleContext *context, GtkCssComputedValues *values); diff --git a/gtk/gtkcssprovider.c b/gtk/gtkcssprovider.c index 250bcb46fa..100155058b 100644 --- a/gtk/gtkcssprovider.c +++ b/gtk/gtkcssprovider.c @@ -969,14 +969,14 @@ typedef enum ParserSymbol ParserSymbol; struct _PropertyValue { GtkCssStyleProperty *property; - GValue value; + GtkCssValue *value; GtkCssSection *section; }; struct _WidgetPropertyValue { char *name; WidgetPropertyValue *next; - GValue value; + GtkCssValue *value; GtkCssSection *section; }; @@ -1156,7 +1156,8 @@ gtk_css_ruleset_clear (GtkCssRuleset *ruleset) for (i = 0; i < ruleset->n_styles; i++) { - g_value_unset (&ruleset->styles[i].value); + _gtk_css_value_unref (ruleset->styles[i].value); + ruleset->styles[i].value = NULL; gtk_css_section_unref (ruleset->styles[i].section); } g_free (ruleset->styles); @@ -1187,9 +1188,7 @@ widget_property_value_new (char *name, GtkCssSection *section) static void widget_property_value_free (WidgetPropertyValue *value) { - if (G_IS_VALUE (&value->value)) - g_value_unset (&value->value); - + _gtk_css_value_unref (value->value); g_free (value->name); gtk_css_section_unref (value->section); @@ -1263,7 +1262,8 @@ gtk_css_ruleset_add (GtkCssRuleset *ruleset, { if (ruleset->styles[i].property == property) { - g_value_unset (&ruleset->styles[i].value); + _gtk_css_value_unref (ruleset->styles[i].value); + ruleset->styles[i].value = NULL; gtk_css_section_unref (ruleset->styles[i].section); break; } @@ -1272,12 +1272,11 @@ gtk_css_ruleset_add (GtkCssRuleset *ruleset, { ruleset->n_styles++; ruleset->styles = g_realloc (ruleset->styles, ruleset->n_styles * sizeof (PropertyValue)); - memset (&ruleset->styles[i].value, 0, sizeof (GValue)); + ruleset->styles[i].value = NULL; ruleset->styles[i].property = property; } - g_value_init (&ruleset->styles[i].value, G_VALUE_TYPE (value)); - g_value_copy (value, &ruleset->styles[i].value); + ruleset->styles[i].value = _gtk_css_value_new_from_gvalue (value); ruleset->styles[i].section = gtk_css_section_ref (section); } @@ -1485,7 +1484,7 @@ gtk_css_provider_get_style (GtkStyleProvider *provider, _gtk_style_properties_set_property_by_property (props, GTK_CSS_STYLE_PROPERTY (ruleset->styles[i].property), _gtk_css_selector_get_state_flags (ruleset->selector), - &ruleset->styles[i].value); + ruleset->styles[i].value); } return props; @@ -1531,7 +1530,7 @@ gtk_css_provider_get_style_property (GtkStyleProvider *provider, NULL, val->section, gtk_css_section_get_file (val->section), - g_value_get_string (&val->value)); + _gtk_css_value_get_string (val->value)); found = _gtk_css_style_parse_value (value, scanner->parser, @@ -1609,7 +1608,7 @@ gtk_css_style_provider_lookup (GtkStyleProviderPrivate *provider, _gtk_css_lookup_set (lookup, id, ruleset->styles[j].section, - &ruleset->styles[j].value); + ruleset->styles[j].value); } } } @@ -2215,8 +2214,7 @@ parse_declaration (GtkCssScanner *scanner, WidgetPropertyValue *val; val = widget_property_value_new (name, scanner->section); - g_value_init (&val->value, G_TYPE_STRING); - g_value_take_string (&val->value, value_str); + val->value = _gtk_css_value_new_take_string (value_str); gtk_css_ruleset_add_style (ruleset, name, val); } @@ -2799,7 +2797,7 @@ gtk_css_ruleset_print (const GtkCssRuleset *ruleset, g_string_append (str, " "); g_string_append (str, _gtk_style_property_get_name (GTK_STYLE_PROPERTY (prop->property))); g_string_append (str, ": "); - _gtk_css_style_property_print_value (prop->property, &prop->value, str); + _gtk_css_style_property_print_value (prop->property, prop->value, str); g_string_append (str, ";\n"); } @@ -2822,7 +2820,7 @@ gtk_css_ruleset_print (const GtkCssRuleset *ruleset, g_string_append (str, " "); g_string_append (str, widget_value->name); g_string_append (str, ": "); - g_string_append (str, g_value_get_string (&widget_value->value)); + g_string_append (str, _gtk_css_value_get_string (widget_value->value)); g_string_append (str, ";\n"); } diff --git a/gtk/gtkcssshorthandproperty.c b/gtk/gtkcssshorthandproperty.c index 157c946ef4..f9617914ab 100644 --- a/gtk/gtkcssshorthandproperty.c +++ b/gtk/gtkcssshorthandproperty.c @@ -72,15 +72,14 @@ _gtk_css_shorthand_property_assign (GtkStyleProperty *property, shorthand->assign (shorthand, props, state, value); } -static void +static GtkCssValue * _gtk_css_shorthand_property_query (GtkStyleProperty *property, - GValue *value, GtkStyleQueryFunc query_func, gpointer query_data) { GtkCssShorthandProperty *shorthand = GTK_CSS_SHORTHAND_PROPERTY (property); - shorthand->query (shorthand, value, query_func, query_data); + return shorthand->query (shorthand, query_func, query_data); } static void diff --git a/gtk/gtkcssshorthandpropertyimpl.c b/gtk/gtkcssshorthandpropertyimpl.c index 74e75ffd2c..9684dc4e1b 100644 --- a/gtk/gtkcssshorthandpropertyimpl.c +++ b/gtk/gtkcssshorthandpropertyimpl.c @@ -31,6 +31,7 @@ #include "gtkstylepropertiesprivate.h" #include "gtksymboliccolorprivate.h" #include "gtktypebuiltins.h" +#include "gtkcssvalueprivate.h" /* this is in case round() is not provided by the compiler, * such as in the case of C89 compilers, like MSVC @@ -608,34 +609,33 @@ unpack_border (GtkCssShorthandProperty *shorthand, g_value_unset (&v); } -static void +static GtkCssValue * pack_border (GtkCssShorthandProperty *shorthand, - GValue *value, GtkStyleQueryFunc query_func, gpointer query_data) { GtkCssStyleProperty *prop; GtkBorder border; - const GValue *v; + GtkCssValue *v; prop = _gtk_css_shorthand_property_get_subproperty (shorthand, 0); v = (* query_func) (_gtk_css_style_property_get_id (prop), query_data); if (v) - border.top = g_value_get_int (v); + border.top = _gtk_css_value_get_int (v); prop = _gtk_css_shorthand_property_get_subproperty (shorthand, 1); v = (* query_func) (_gtk_css_style_property_get_id (prop), query_data); if (v) - border.right = g_value_get_int (v); + border.right = _gtk_css_value_get_int (v); prop = _gtk_css_shorthand_property_get_subproperty (shorthand, 2); v = (* query_func) (_gtk_css_style_property_get_id (prop), query_data); if (v) - border.bottom = g_value_get_int (v); + border.bottom = _gtk_css_value_get_int (v); prop = _gtk_css_shorthand_property_get_subproperty (shorthand, 3); v = (* query_func) (_gtk_css_style_property_get_id (prop), query_data); if (v) - border.left = g_value_get_int (v); + border.left = _gtk_css_value_get_int (v); - g_value_set_boxed (value, &border); + return _gtk_css_value_new_from_border (&border); } static void @@ -659,24 +659,26 @@ unpack_border_radius (GtkCssShorthandProperty *shorthand, g_value_unset (&v); } -static void +static GtkCssValue * pack_border_radius (GtkCssShorthandProperty *shorthand, - GValue *value, GtkStyleQueryFunc query_func, gpointer query_data) { GtkCssBorderCornerRadius *top_left; GtkCssStyleProperty *prop; - const GValue *v; + GtkCssValue *v; + int value = 0; prop = GTK_CSS_STYLE_PROPERTY (_gtk_style_property_lookup ("border-top-left-radius")); v = (* query_func) (_gtk_css_style_property_get_id (prop), query_data); if (v) { - top_left = g_value_get_boxed (v); + top_left = _gtk_css_value_get_border_corner_radius (v); if (top_left) - g_value_set_int (value, top_left->horizontal.value); + value = top_left->horizontal.value; } + + return _gtk_css_value_new_from_int (value); } static void @@ -759,21 +761,20 @@ unpack_font_description (GtkCssShorthandProperty *shorthand, } } -static void +static GtkCssValue * pack_font_description (GtkCssShorthandProperty *shorthand, - GValue *value, GtkStyleQueryFunc query_func, gpointer query_data) { PangoFontDescription *description; - const GValue *v; + GtkCssValue *v; description = pango_font_description_new (); v = (* query_func) (_gtk_css_style_property_get_id (GTK_CSS_STYLE_PROPERTY (_gtk_style_property_lookup ("font-family"))), query_data); if (v) { - const char **families = g_value_get_boxed (v); + const char **families = _gtk_css_value_get_strv (v); /* xxx: Can we set all the families here somehow? */ if (families) pango_font_description_set_family (description, families[0]); @@ -781,21 +782,21 @@ pack_font_description (GtkCssShorthandProperty *shorthand, v = (* query_func) (_gtk_css_style_property_get_id (GTK_CSS_STYLE_PROPERTY (_gtk_style_property_lookup ("font-size"))), query_data); if (v) - pango_font_description_set_size (description, round (g_value_get_double (v) * PANGO_SCALE)); + pango_font_description_set_size (description, round (_gtk_css_value_get_double (v) * PANGO_SCALE)); v = (* query_func) (_gtk_css_style_property_get_id (GTK_CSS_STYLE_PROPERTY (_gtk_style_property_lookup ("font-style"))), query_data); if (v) - pango_font_description_set_style (description, g_value_get_enum (v)); + pango_font_description_set_style (description, _gtk_css_value_get_pango_style (v)); v = (* query_func) (_gtk_css_style_property_get_id (GTK_CSS_STYLE_PROPERTY (_gtk_style_property_lookup ("font-variant"))), query_data); if (v) - pango_font_description_set_variant (description, g_value_get_enum (v)); + pango_font_description_set_variant (description, _gtk_css_value_get_pango_variant (v)); v = (* query_func) (_gtk_css_style_property_get_id (GTK_CSS_STYLE_PROPERTY (_gtk_style_property_lookup ("font-weight"))), query_data); if (v) - pango_font_description_set_weight (description, g_value_get_enum (v)); + pango_font_description_set_weight (description, _gtk_css_value_get_pango_weight (v)); - g_value_take_boxed (value, description); + return _gtk_css_value_new_take_font_description (description); } static void @@ -816,14 +817,13 @@ unpack_to_everything (GtkCssShorthandProperty *shorthand, } } -static void +static GtkCssValue * pack_first_element (GtkCssShorthandProperty *shorthand, - GValue *value, GtkStyleQueryFunc query_func, gpointer query_data) { GtkCssStyleProperty *prop; - const GValue *v; + GtkCssValue *v; guint i; /* NB: This is a fallback for properties that originally were @@ -837,10 +837,10 @@ pack_first_element (GtkCssShorthandProperty *shorthand, v = (* query_func) (_gtk_css_style_property_get_id (prop), query_data); if (v) { - g_value_copy (v, value); - return; + return _gtk_css_value_ref (v); } } + return NULL; } static void diff --git a/gtk/gtkcssshorthandpropertyprivate.h b/gtk/gtkcssshorthandpropertyprivate.h index 4592949a56..9a79a3d6c8 100644 --- a/gtk/gtkcssshorthandpropertyprivate.h +++ b/gtk/gtkcssshorthandpropertyprivate.h @@ -46,8 +46,7 @@ typedef void (* GtkCssShorthandPropertyAssignFunc) (GtkCssS GtkStyleProperties *props, GtkStateFlags state, const GValue *value); -typedef void (* GtkCssShorthandPropertyQueryFunc) (GtkCssShorthandProperty *shorthand, - GValue *value, +typedef GtkCssValue * (* GtkCssShorthandPropertyQueryFunc) (GtkCssShorthandProperty *shorthand, GtkStyleQueryFunc query_func, gpointer query_data); diff --git a/gtk/gtkcssstylefuncs.c b/gtk/gtkcssstylefuncs.c index e2ccd75505..0693e04487 100644 --- a/gtk/gtkcssstylefuncs.c +++ b/gtk/gtkcssstylefuncs.c @@ -54,9 +54,8 @@ typedef gboolean (* GtkStyleParseFunc) (GtkCssParser GValue *value); typedef void (* GtkStylePrintFunc) (const GValue *value, GString *string); -typedef void (* GtkStyleComputeFunc) (GValue *computed, - GtkStyleContext *context, - const GValue *specified); +typedef GtkCssValue * (* GtkStyleComputeFunc) (GtkStyleContext *context, + GtkCssValue *specified); static void register_conversion_function (GType type, @@ -212,31 +211,33 @@ rgba_value_print (const GValue *value, } } -static void -rgba_value_compute (GValue *computed, - GtkStyleContext *context, - const GValue *specified) +static GtkCssValue * +rgba_value_compute (GtkStyleContext *context, + GtkCssValue *specified) { - GdkRGBA rgba, white = { 1, 1, 1, 1 }; - - if (G_VALUE_HOLDS (specified, GTK_TYPE_CSS_SPECIAL_VALUE)) + GdkRGBA white = { 1, 1, 1, 1 }; + GtkCssValue *res; + + if (_gtk_css_value_holds (specified, GTK_TYPE_CSS_SPECIAL_VALUE)) { + return _gtk_css_value_new_from_rgba (NULL); } - else if (G_VALUE_HOLDS (specified, GTK_TYPE_SYMBOLIC_COLOR)) + else if (_gtk_css_value_holds (specified, GTK_TYPE_SYMBOLIC_COLOR)) { - GtkSymbolicColor *symbolic = g_value_get_boxed (specified); - + GtkSymbolicColor *symbolic = _gtk_css_value_get_symbolic_color (specified); + if (symbolic == _gtk_symbolic_color_get_current_color ()) - g_value_copy (_gtk_style_context_peek_property (context, "color"), computed); - else if (_gtk_style_context_resolve_color (context, - symbolic, - &rgba)) - g_value_set_boxed (computed, &rgba); - else - g_value_set_boxed (computed, &white); + return _gtk_css_value_ref (_gtk_style_context_peek_property (context, "color")); + else { + res = _gtk_style_context_resolve_color_value (context, symbolic); + if (res != NULL) + return res; + + return _gtk_css_value_new_from_rgba (&white); + } } else - g_value_copy (specified, computed); + return _gtk_css_value_ref (specified); } static gboolean @@ -287,18 +288,17 @@ color_value_print (const GValue *value, } } -static void -color_value_compute (GValue *computed, - GtkStyleContext *context, - const GValue *specified) +static GtkCssValue * +color_value_compute (GtkStyleContext *context, + GtkCssValue *specified) { GdkRGBA rgba; GdkColor color = { 0, 65535, 65535, 65535 }; - if (G_VALUE_HOLDS (specified, GTK_TYPE_SYMBOLIC_COLOR)) + if (_gtk_css_value_holds (specified, GTK_TYPE_SYMBOLIC_COLOR)) { if (_gtk_style_context_resolve_color (context, - g_value_get_boxed (specified), + _gtk_css_value_get_symbolic_color (specified), &rgba)) { color.red = rgba.red * 65535. + 0.5; @@ -306,10 +306,10 @@ color_value_compute (GValue *computed, color.blue = rgba.blue * 65535. + 0.5; } - g_value_set_boxed (computed, &color); + return _gtk_css_value_new_from_color (&color); } else - g_value_copy (specified, computed); + return _gtk_css_value_ref (specified); } static gboolean @@ -877,21 +877,20 @@ pattern_value_print (const GValue *value, } } -static void -pattern_value_compute (GValue *computed, - GtkStyleContext *context, - const GValue *specified) +static GtkCssValue * +pattern_value_compute (GtkStyleContext *context, + GtkCssValue *specified) { - if (G_VALUE_HOLDS (specified, GTK_TYPE_GRADIENT)) + if (_gtk_css_value_holds (specified, GTK_TYPE_GRADIENT)) { cairo_pattern_t *gradient; - gradient = gtk_gradient_resolve_for_context (g_value_get_boxed (specified), context); + gradient = gtk_gradient_resolve_for_context (_gtk_css_value_get_gradient (specified), context); - g_value_take_boxed (computed, gradient); + return _gtk_css_value_new_take_pattern (gradient); } else - g_value_copy (specified, computed); + return _gtk_css_value_ref (specified); } static gboolean @@ -996,18 +995,17 @@ shadow_value_print (const GValue *value, _gtk_shadow_print (shadow, string); } -static void -shadow_value_compute (GValue *computed, - GtkStyleContext *context, - const GValue *specified) +static GtkCssValue * +shadow_value_compute (GtkStyleContext *context, + GtkCssValue *specified) { GtkShadow *shadow; - - shadow = g_value_get_boxed (specified); + + shadow = _gtk_css_value_get_shadow (specified); if (shadow) shadow = _gtk_shadow_resolve (shadow, context); - g_value_take_boxed (computed, shadow); + return _gtk_css_value_new_take_shadow (shadow); } static gboolean @@ -1337,28 +1335,26 @@ _gtk_css_style_print_value (const GValue *value, * @specified must be a result of a call to * _gtk_css_style_parse_value() with the same type as @computed. **/ -void -_gtk_css_style_compute_value (GValue *computed, - GtkStyleContext *context, - const GValue *specified) +GtkCssValue * +_gtk_css_style_compute_value (GtkStyleContext *context, + GType target_type, + GtkCssValue *specified) { GtkStyleComputeFunc func; - g_return_if_fail (G_IS_VALUE (computed)); - g_return_if_fail (GTK_IS_STYLE_CONTEXT (context)); - g_return_if_fail (G_IS_VALUE (specified)); + g_return_val_if_fail (GTK_IS_STYLE_CONTEXT (context), NULL); gtk_css_style_funcs_init (); func = g_hash_table_lookup (compute_funcs, - GSIZE_TO_POINTER (G_VALUE_TYPE (computed))); + GSIZE_TO_POINTER (target_type)); if (func == NULL) func = g_hash_table_lookup (compute_funcs, - GSIZE_TO_POINTER (g_type_fundamental (G_VALUE_TYPE (computed)))); + GSIZE_TO_POINTER (g_type_fundamental (target_type))); if (func) - func (computed, context, specified); + return func (context, specified); else - g_value_copy (specified, computed); + return _gtk_css_value_ref (specified); } diff --git a/gtk/gtkcssstylefuncsprivate.h b/gtk/gtkcssstylefuncsprivate.h index 2728aa98a1..647a950456 100644 --- a/gtk/gtkcssstylefuncsprivate.h +++ b/gtk/gtkcssstylefuncsprivate.h @@ -20,6 +20,7 @@ #include "gtkcssparserprivate.h" #include "gtkstylecontext.h" +#include "gtkcssvalueprivate.h" G_BEGIN_DECLS @@ -28,9 +29,9 @@ gboolean _gtk_css_style_parse_value (GValue GFile *base); void _gtk_css_style_print_value (const GValue *value, GString *string); -void _gtk_css_style_compute_value (GValue *computed, - GtkStyleContext *context, - const GValue *specified); +GtkCssValue * _gtk_css_style_compute_value (GtkStyleContext *context, + GType target_type, + GtkCssValue *specified); G_END_DECLS diff --git a/gtk/gtkcssstyleproperty.c b/gtk/gtkcssstyleproperty.c index a0873ec243..cbbe606af9 100644 --- a/gtk/gtkcssstyleproperty.c +++ b/gtk/gtkcssstyleproperty.c @@ -67,7 +67,6 @@ gtk_css_style_property_set_property (GObject *object, GParamSpec *pspec) { GtkCssStyleProperty *property = GTK_CSS_STYLE_PROPERTY (object); - const GValue *initial; switch (prop_id) { @@ -75,10 +74,8 @@ gtk_css_style_property_set_property (GObject *object, property->inherit = g_value_get_boolean (value); break; case PROP_INITIAL: - initial = g_value_get_boxed (value); - g_assert (initial); - g_value_init (&property->initial_value, G_VALUE_TYPE (initial)); - g_value_copy (initial, &property->initial_value); + property->initial_value = g_value_dup_boxed (value); + g_assert (property->initial_value != NULL); break; case PROP_COMPUTED_TYPE: property->computed_type = g_value_get_gtype (value); @@ -113,7 +110,7 @@ gtk_css_style_property_get_property (GObject *object, g_value_set_boolean (value, property->inherit); break; case PROP_INITIAL: - g_value_set_boxed (value, &property->initial_value); + g_value_set_boxed (value, property->initial_value); break; default: G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); @@ -127,35 +124,36 @@ _gtk_css_style_property_assign (GtkStyleProperty *property, GtkStateFlags state, const GValue *value) { + GtkCssValue *css_value = _gtk_css_value_new_from_gvalue (value); _gtk_style_properties_set_property_by_property (props, GTK_CSS_STYLE_PROPERTY (property), state, - value); + css_value); + _gtk_css_value_unref (css_value); } -static void +static GtkCssValue * _gtk_css_style_property_query (GtkStyleProperty *property, - GValue *value, GtkStyleQueryFunc query_func, gpointer query_data) { - const GValue *val; + GtkCssValue *css_value; - val = (* query_func) (GTK_CSS_STYLE_PROPERTY (property)->id, query_data); - if (val) + css_value = (* query_func) (GTK_CSS_STYLE_PROPERTY (property)->id, query_data); + if (css_value) { /* Somebody make this a vfunc */ - if (G_VALUE_TYPE (val) == GTK_TYPE_CSS_IMAGE) + if (_gtk_css_value_holds (css_value, GTK_TYPE_CSS_IMAGE)) { - GtkCssImage *image = g_value_get_object (val); + GtkCssImage *image = _gtk_css_value_get_image (css_value); cairo_pattern_t *pattern; cairo_surface_t *surface; cairo_matrix_t matrix; if (image == NULL) - g_value_set_boxed (value, NULL); + return _gtk_css_value_new_from_pattern (NULL); else if (GTK_IS_CSS_IMAGE_GRADIENT (image)) - g_value_set_boxed (value, GTK_CSS_IMAGE_GRADIENT (image)->pattern); + return _gtk_css_value_new_from_pattern (GTK_CSS_IMAGE_GRADIENT (image)->pattern); else { double width, height; @@ -167,18 +165,19 @@ _gtk_css_style_property_query (GtkStyleProperty *property, cairo_matrix_init_scale (&matrix, width, height); cairo_pattern_set_matrix (pattern, &matrix); cairo_surface_destroy (surface); - g_value_take_boxed (value, pattern); + return _gtk_css_value_new_take_pattern (pattern); } } - else if (G_VALUE_TYPE (val) == GTK_TYPE_CSS_NUMBER) + else if (_gtk_css_value_holds (css_value, GTK_TYPE_CSS_NUMBER)) { - g_value_set_int (value, round (_gtk_css_number_get (g_value_get_boxed (val), 100))); + int v = round (_gtk_css_number_get (_gtk_css_value_get_number (css_value), 100)); + return _gtk_css_value_new_from_int (v); } else - g_value_copy (val, value); + return _gtk_css_value_ref (css_value); } else - g_value_copy (_gtk_css_style_property_get_initial_value (GTK_CSS_STYLE_PROPERTY (property)), value); + return _gtk_css_value_ref (_gtk_css_style_property_get_initial_value (GTK_CSS_STYLE_PROPERTY (property))); } static gboolean @@ -264,7 +263,7 @@ _gtk_css_style_property_class_init (GtkCssStylePropertyClass *klass) g_param_spec_boxed ("initial-value", P_("Initial value"), P_("The initial specified value used for this property"), - G_TYPE_VALUE, + GTK_TYPE_CSS_VALUE, G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY)); property_class->assign = _gtk_css_style_property_assign; @@ -291,13 +290,12 @@ gtk_css_style_property_real_print_value (GtkCssStyleProperty *property, _gtk_css_style_print_value (value, string); } -static void +static GtkCssValue * gtk_css_style_property_real_compute_value (GtkCssStyleProperty *property, - GValue *computed, GtkStyleContext *context, - const GValue *specified) + GtkCssValue *specified) { - _gtk_css_style_compute_value (computed, context, specified); + return _gtk_css_style_compute_value (context, _gtk_css_style_property_get_computed_type (property), specified); } static void @@ -404,12 +402,12 @@ _gtk_css_style_property_get_id (GtkCssStyleProperty *property) * * Returns: a reference to the initial value. The value will never change. **/ -const GValue * +GtkCssValue * _gtk_css_style_property_get_initial_value (GtkCssStyleProperty *property) { g_return_val_if_fail (GTK_IS_CSS_STYLE_PROPERTY (property), NULL); - return &property->initial_value; + return property->initial_value; } /** @@ -448,7 +446,7 @@ _gtk_css_style_property_get_specified_type (GtkCssStyleProperty *property) { g_return_val_if_fail (GTK_IS_CSS_STYLE_PROPERTY (property), G_TYPE_NONE); - return G_VALUE_TYPE (&property->initial_value); + return _gtk_css_value_get_content_type (property->initial_value); } gboolean @@ -458,7 +456,7 @@ _gtk_css_style_property_is_specified_type (GtkCssStyleProperty *property, g_return_val_if_fail (GTK_IS_CSS_STYLE_PROPERTY (property), FALSE); /* If it's our specified type, of course it's valid */ - if (type == G_VALUE_TYPE (&property->initial_value)) + if (type == _gtk_css_value_get_content_type (property->initial_value)) return TRUE; /* The special values 'inherit' and 'initial' are always valid */ @@ -466,7 +464,7 @@ _gtk_css_style_property_is_specified_type (GtkCssStyleProperty *property, return TRUE; /* XXX: Someone needs to fix that legacy */ - if (G_VALUE_TYPE (&property->initial_value) == CAIRO_GOBJECT_TYPE_PATTERN && + if (_gtk_css_value_holds (property->initial_value, CAIRO_GOBJECT_TYPE_PATTERN) && type == GTK_TYPE_GRADIENT) return TRUE; @@ -485,20 +483,15 @@ _gtk_css_style_property_is_specified_type (GtkCssStyleProperty *property, * compute_value = compute_value; - g_value_unset (&initial_value); + _gtk_css_value_unref (initial_value); } /*** HELPERS ***/ @@ -137,14 +140,13 @@ string_append_string (GString *str, /*** IMPLEMENTATIONS ***/ -static void +static GtkCssValue * color_compute (GtkCssStyleProperty *property, - GValue *computed, GtkStyleContext *context, - const GValue *specified) + GtkCssValue *specified) { - GtkSymbolicColor *symbolic = g_value_get_boxed (specified); - GdkRGBA rgba; + GtkSymbolicColor *symbolic = _gtk_css_value_get_symbolic_color (specified); + GtkCssValue *resolved; if (symbolic == _gtk_symbolic_color_get_current_color ()) { @@ -157,29 +159,27 @@ color_compute (GtkCssStyleProperty *property, GtkStyleContext *parent = gtk_style_context_get_parent (context); if (parent) - g_value_copy (_gtk_style_context_peek_property (parent, "color"), computed); + return _gtk_css_value_ref (_gtk_style_context_peek_property (parent, "color")); else - _gtk_css_style_compute_value (computed, - context, - _gtk_css_style_property_get_initial_value (property)); + return _gtk_css_style_compute_value (context, + GDK_TYPE_RGBA, + _gtk_css_style_property_get_initial_value (property)); } else { - g_value_copy (_gtk_style_context_peek_property (context, "color"), computed); + return _gtk_css_value_ref (_gtk_style_context_peek_property (context, "color")); } } - else if (_gtk_style_context_resolve_color (context, - symbolic, - &rgba)) + else if ((resolved = _gtk_style_context_resolve_color_value (context, + symbolic)) != NULL) { - g_value_set_boxed (computed, &rgba); + return resolved; } else { - color_compute (property, - computed, - context, - _gtk_css_style_property_get_initial_value (property)); + return color_compute (property, + context, + _gtk_css_style_property_get_initial_value (property)); } } @@ -395,18 +395,17 @@ css_image_value_print (GtkCssStyleProperty *property, g_string_append (string, "none"); } -static void +static GtkCssValue * css_image_value_compute (GtkCssStyleProperty *property, - GValue *computed, GtkStyleContext *context, - const GValue *specified) + GtkCssValue *specified) { - GtkCssImage *image = g_value_get_object (specified); + GtkCssImage *image = _gtk_css_value_get_image (specified); if (image) image = _gtk_css_image_compute (image, context); - g_value_take_object (computed, image); + return _gtk_css_value_new_take_image (image); } static gboolean @@ -427,18 +426,20 @@ parse_margin (GtkCssStyleProperty *property, return TRUE; } -static void +static GtkCssValue * compute_margin (GtkCssStyleProperty *property, - GValue *computed, GtkStyleContext *context, - const GValue *specified) + GtkCssValue *specified) { GtkCssNumber number; - _gtk_css_number_compute (&number, - g_value_get_boxed (specified), - context); - g_value_set_boxed (computed, &number); + if (_gtk_css_number_compute (&number, + _gtk_css_value_get_number (specified), + context)) + { + return _gtk_css_value_new_from_number (&number); + } + return _gtk_css_value_ref (specified); } static gboolean @@ -460,18 +461,18 @@ parse_padding (GtkCssStyleProperty *property, return TRUE; } -static void +static GtkCssValue * compute_padding (GtkCssStyleProperty *property, - GValue *computed, GtkStyleContext *context, - const GValue *specified) + GtkCssValue *specified) { GtkCssNumber number; - - _gtk_css_number_compute (&number, - g_value_get_boxed (specified), - context); - g_value_set_boxed (computed, &number); + + if (_gtk_css_number_compute (&number, + _gtk_css_value_get_number (specified), + context)) + return _gtk_css_value_new_from_number (&number); + return _gtk_css_value_ref (specified); } static gboolean @@ -493,33 +494,36 @@ parse_border_width (GtkCssStyleProperty *property, return TRUE; } -static void +static GtkCssValue * compute_border_width (GtkCssStyleProperty *property, - GValue *computed, GtkStyleContext *context, - const GValue *specified) + GtkCssValue *specified) { GtkCssStyleProperty *style; GtkBorderStyle border_style; GtkCssNumber number; + int value = 0; /* The -1 is magic that is only true because we register the style * properties directly after the width properties. */ style = _gtk_css_style_property_lookup_by_id (_gtk_css_style_property_get_id (property) - 1); - border_style = g_value_get_enum (_gtk_style_context_peek_property (context, _gtk_style_property_get_name (GTK_STYLE_PROPERTY (style)))); + + border_style = _gtk_css_value_get_border_style (_gtk_style_context_peek_property (context, _gtk_style_property_get_name (GTK_STYLE_PROPERTY (style)))); if (border_style == GTK_BORDER_STYLE_NONE || border_style == GTK_BORDER_STYLE_HIDDEN) { - g_value_set_int (computed, 0); - return; + value = 0; } - - _gtk_css_number_compute (&number, - g_value_get_boxed (specified), - context); - g_value_set_int (computed, round (number.value)); + else + { + _gtk_css_number_compute (&number, + _gtk_css_value_get_number (specified), + context); + value = round (number.value); + } + return _gtk_css_value_new_from_int (value); } static gboolean @@ -656,25 +660,26 @@ background_size_print (GtkCssStyleProperty *property, } } -static void +static GtkCssValue * background_size_compute (GtkCssStyleProperty *property, - GValue *computed, GtkStyleContext *context, - const GValue *specified) + GtkCssValue *specified) { - GtkCssBackgroundSize *ssize = g_value_get_boxed (specified); + GtkCssBackgroundSize *ssize = _gtk_css_value_get_background_size (specified); GtkCssBackgroundSize csize; + gboolean changed; csize.cover = ssize->cover; csize.contain = ssize->contain; - _gtk_css_number_compute (&csize.width, - &ssize->width, - context); - _gtk_css_number_compute (&csize.height, - &ssize->height, - context); - - g_value_set_boxed (computed, &csize); + changed = _gtk_css_number_compute (&csize.width, + &ssize->width, + context); + changed |= _gtk_css_number_compute (&csize.height, + &ssize->height, + context); + if (changed) + return _gtk_css_value_new_from_background_size (&csize); + return _gtk_css_value_ref (specified); } /*** REGISTRATION ***/ diff --git a/gtk/gtkcssstylepropertyprivate.h b/gtk/gtkcssstylepropertyprivate.h index 2d758272f9..a51d455eaa 100644 --- a/gtk/gtkcssstylepropertyprivate.h +++ b/gtk/gtkcssstylepropertyprivate.h @@ -41,16 +41,15 @@ typedef gboolean (* GtkCssStylePropertyParseFunc) (GtkCssStyleProperty typedef void (* GtkCssStylePropertyPrintFunc) (GtkCssStyleProperty *property, const GValue *value, GString *string); -typedef void (* GtkCssStylePropertyComputeFunc)(GtkCssStyleProperty *property, - GValue *computed, +typedef GtkCssValue * (* GtkCssStylePropertyComputeFunc)(GtkCssStyleProperty *property, GtkStyleContext *context, - const GValue *specified); + GtkCssValue *specified); struct _GtkCssStyleProperty { GtkStyleProperty parent; GType computed_type; - GValue initial_value; + GtkCssValue *initial_value; guint id; guint inherit :1; @@ -75,20 +74,19 @@ GtkCssStyleProperty * _gtk_css_style_property_lookup_by_id (guint gboolean _gtk_css_style_property_is_inherit (GtkCssStyleProperty *property); guint _gtk_css_style_property_get_id (GtkCssStyleProperty *property); -const GValue * _gtk_css_style_property_get_initial_value +GtkCssValue * _gtk_css_style_property_get_initial_value (GtkCssStyleProperty *property); GType _gtk_css_style_property_get_computed_type (GtkCssStyleProperty *property); GType _gtk_css_style_property_get_specified_type (GtkCssStyleProperty *property); gboolean _gtk_css_style_property_is_specified_type (GtkCssStyleProperty *property, GType type); -void _gtk_css_style_property_compute_value (GtkCssStyleProperty *property, - GValue *computed, +GtkCssValue * _gtk_css_style_property_compute_value (GtkCssStyleProperty *property, GtkStyleContext *context, - const GValue *specified); + GtkCssValue *specified); void _gtk_css_style_property_print_value (GtkCssStyleProperty *property, - const GValue *value, + GtkCssValue *value, GString *string); diff --git a/gtk/gtkcsstypes.c b/gtk/gtkcsstypes.c index ffa7a27ab5..c454fea9fe 100644 --- a/gtk/gtkcsstypes.c +++ b/gtk/gtkcsstypes.c @@ -62,7 +62,7 @@ _gtk_css_number_get (const GtkCssNumber *number, return number->value; } -void +gboolean _gtk_css_number_compute (GtkCssNumber *dest, const GtkCssNumber *src, GtkStyleContext *context) @@ -100,12 +100,12 @@ _gtk_css_number_compute (GtkCssNumber *dest, dest->unit = GTK_CSS_PX; break; case GTK_CSS_EM: - dest->value = src->value * g_value_get_double (_gtk_style_context_peek_property (context, "font-size")); + dest->value = src->value * _gtk_css_value_get_double (_gtk_style_context_peek_property (context, "font-size")); dest->unit = GTK_CSS_PX; break; case GTK_CSS_EX: /* for now we pretend ex is half of em */ - dest->value = src->value * g_value_get_double (_gtk_style_context_peek_property (context, "font-size")); + dest->value = src->value * _gtk_css_value_get_double (_gtk_style_context_peek_property (context, "font-size")); dest->unit = GTK_CSS_PX; break; case GTK_CSS_RAD: @@ -121,6 +121,8 @@ _gtk_css_number_compute (GtkCssNumber *dest, dest->unit = GTK_CSS_DEG; break; } + + return !_gtk_css_number_equal (src, dest); } void diff --git a/gtk/gtkcsstypesprivate.h b/gtk/gtkcsstypesprivate.h index 109699472c..d481427781 100644 --- a/gtk/gtkcsstypesprivate.h +++ b/gtk/gtkcsstypesprivate.h @@ -142,7 +142,7 @@ gboolean _gtk_css_number_equal (const GtkCssNum const GtkCssNumber *two); double _gtk_css_number_get (const GtkCssNumber *number, double one_hundred_percent); -void _gtk_css_number_compute (GtkCssNumber *dest, +gboolean _gtk_css_number_compute (GtkCssNumber *dest, const GtkCssNumber *src, GtkStyleContext *context); void _gtk_css_number_print (const GtkCssNumber *number, diff --git a/gtk/gtkcssvalue.c b/gtk/gtkcssvalue.c new file mode 100644 index 0000000000..56c4eac1e3 --- /dev/null +++ b/gtk/gtkcssvalue.c @@ -0,0 +1,635 @@ +/* GTK - The GIMP Toolkit + * Copyright (C) 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 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, see . + */ + +#include "config.h" + +#include "gtkcssvalueprivate.h" +#include "gtktypebuiltins.h" +#include "gtkgradient.h" +#include +#include "gtkprivatetypebuiltins.h" + +#include "fallback-c89.c" + +struct _GtkCssValue +{ + volatile gint ref_count; + GType type; + union { + gpointer ptr; + gint gint; + guint guint; + double dbl; + float flt; + } u; +}; + +G_DEFINE_BOXED_TYPE (GtkCssValue, _gtk_css_value, _gtk_css_value_ref, _gtk_css_value_unref) + +static GtkCssValue * +_gtk_css_value_new (GType type) +{ + GtkCssValue *value; + + value = g_slice_new0 (GtkCssValue); + + value->ref_count = 1; + value->type = type; + + return value; +} + +GtkCssValue * +_gtk_css_value_new_from_gvalue (const GValue *g_value) +{ + GtkCssValue *value; + GType type; + + g_return_val_if_fail (g_value != NULL, NULL); + + type = G_VALUE_TYPE (g_value); + + /* Make sure we reuse the int/number singletons */ + if (type == G_TYPE_INT) + value = _gtk_css_value_new_from_int (g_value_get_int (g_value)); + else if (type == GTK_TYPE_CSS_NUMBER) + value = _gtk_css_value_new_from_number (g_value_get_boxed (g_value)); + else + { + value = _gtk_css_value_new (type); + + if (g_type_is_a (type, G_TYPE_OBJECT)) + value->u.ptr = g_value_dup_object (g_value); + else if (g_type_is_a (type, G_TYPE_BOXED)) + value->u.ptr = g_value_dup_boxed (g_value); + else if (g_type_is_a (type, G_TYPE_INT)) + value->u.gint = g_value_get_int (g_value); + else if (g_type_is_a (type, G_TYPE_UINT)) + value->u.guint = g_value_get_uint (g_value); + else if (g_type_is_a (type, G_TYPE_BOOLEAN)) + value->u.gint = g_value_get_boolean (g_value); + else if (g_type_is_a (type, G_TYPE_ENUM)) + value->u.gint = g_value_get_enum (g_value); + else if (g_type_is_a (type, G_TYPE_FLAGS)) + value->u.guint = g_value_get_flags (g_value); + else if (g_type_is_a (type, G_TYPE_STRING)) + value->u.ptr = g_value_dup_string (g_value); + else if (g_type_is_a (type, G_TYPE_DOUBLE)) + value->u.dbl = g_value_get_double (g_value); + else if (g_type_is_a (type, G_TYPE_FLOAT)) + value->u.flt = g_value_get_float (g_value); + else + g_assert_not_reached (); + } + + return value; +} + +GtkCssValue * +_gtk_css_value_new_take_gvalue (GValue *g_value) +{ + GtkCssValue *value; + GType type; + + g_return_val_if_fail (g_value != NULL, NULL); + + type = G_VALUE_TYPE (g_value); + + /* Make sure we reuse the int/number singletons */ + if (type == G_TYPE_INT) + { + value = _gtk_css_value_new_from_int (g_value_get_int (g_value)); + g_value_unset (g_value); + } + else if (type == GTK_TYPE_CSS_NUMBER) + { + value = _gtk_css_value_new_from_number (g_value_get_boxed (g_value)); + g_value_unset (g_value); + } + else + { + value = _gtk_css_value_new (type); + + if (g_type_is_a (type, G_TYPE_OBJECT)) + value->u.ptr = g_value_get_object (g_value); + else if (g_type_is_a (type, G_TYPE_BOXED)) + value->u.ptr = g_value_get_boxed (g_value); + else if (g_type_is_a (type, G_TYPE_INT)) + value->u.gint = g_value_get_int (g_value); + else if (g_type_is_a (type, G_TYPE_UINT)) + value->u.guint = g_value_get_uint (g_value); + else if (g_type_is_a (type, G_TYPE_BOOLEAN)) + value->u.gint = g_value_get_boolean (g_value); + else if (g_type_is_a (type, G_TYPE_ENUM)) + value->u.gint = g_value_get_enum (g_value); + else if (g_type_is_a (type, G_TYPE_FLAGS)) + value->u.guint = g_value_get_flags (g_value); + else if (g_type_is_a (type, G_TYPE_STRING)) + value->u.ptr = g_value_dup_string (g_value); + else if (g_type_is_a (type, G_TYPE_DOUBLE)) + value->u.dbl = g_value_get_double (g_value); + else if (g_type_is_a (type, G_TYPE_FLOAT)) + value->u.flt = g_value_get_float (g_value); + else + g_assert_not_reached (); + } + + return value; +} + +GtkCssValue * +_gtk_css_value_new_from_int (gint val) +{ + GtkCssValue *value; + static GtkCssValue *singletons[4] = {NULL}; + + if (val >= 0 && val < G_N_ELEMENTS (singletons)) + { + if (singletons[val] == NULL) + { + value = _gtk_css_value_new (G_TYPE_INT); + value->u.gint = val; + singletons[val] = value; + } + return _gtk_css_value_ref (singletons[val]); + } + + value = _gtk_css_value_new (G_TYPE_INT); + value->u.gint = val; + + return value; +} + +GtkCssValue * +_gtk_css_value_new_take_string (char *string) +{ + GtkCssValue *value; + + value = _gtk_css_value_new (G_TYPE_STRING); + value->u.ptr = string; + + return value; +} + +GtkCssValue * +_gtk_css_value_new_from_string (const char *string) +{ + GtkCssValue *value; + + value = _gtk_css_value_new (G_TYPE_STRING); + value->u.ptr = g_strdup (string); + + return value; +} + +static gpointer +g_boxed_copy0 (GType boxed_type, + gconstpointer src_boxed) +{ + if (src_boxed == NULL) + return NULL; + return g_boxed_copy (boxed_type, src_boxed); +} + +GtkCssValue * +_gtk_css_value_new_from_border (const GtkBorder *border) +{ + GtkCssValue *value; + + value = _gtk_css_value_new (GTK_TYPE_BORDER); + value->u.ptr = g_boxed_copy0 (GTK_TYPE_BORDER, border); + + return value; +} + +GtkCssValue * +_gtk_css_value_new_take_pattern (cairo_pattern_t *v) +{ + GtkCssValue *value; + + value = _gtk_css_value_new (CAIRO_GOBJECT_TYPE_PATTERN); + value->u.ptr = v; + + return value; +} + +GtkCssValue * +_gtk_css_value_new_from_pattern (const cairo_pattern_t *v) +{ + GtkCssValue *value; + + value = _gtk_css_value_new (CAIRO_GOBJECT_TYPE_PATTERN); + value->u.ptr = g_boxed_copy0 (CAIRO_GOBJECT_TYPE_PATTERN, v); + + return value; +} + +GtkCssValue * +_gtk_css_value_new_take_shadow (GtkShadow *v) +{ + GtkCssValue *value; + + value = _gtk_css_value_new (GTK_TYPE_SHADOW); + value->u.ptr = v; + + return value; +} + +GtkCssValue * +_gtk_css_value_new_take_font_description (PangoFontDescription *v) +{ + GtkCssValue *value; + + value = _gtk_css_value_new (PANGO_TYPE_FONT_DESCRIPTION); + value->u.ptr = v; + + return value; +} + +GtkCssValue * +_gtk_css_value_new_take_image (GtkCssImage *v) +{ + GtkCssValue *value; + + value = _gtk_css_value_new (GTK_TYPE_CSS_IMAGE); + value->u.ptr = v; + + return value; +} + +GtkCssValue * +_gtk_css_value_new_from_number (const GtkCssNumber *v) +{ + GtkCssValue *value; + static GtkCssValue *zero_singleton = NULL; + static GtkCssValue *px_singletons[5] = {NULL}; + + if (v->unit == GTK_CSS_NUMBER && + v->value == 0) + { + if (zero_singleton == NULL) + { + value = _gtk_css_value_new (GTK_TYPE_CSS_NUMBER); + value->u.ptr = g_boxed_copy0 (GTK_TYPE_CSS_NUMBER, v); + zero_singleton = value; + } + return _gtk_css_value_ref (zero_singleton); + } + + if (v->unit == GTK_CSS_PX && + (v->value == 0 || + v->value == 1 || + v->value == 2 || + v->value == 3 || + v->value == 4)) + { + int i = round (v->value); + if (px_singletons[i] == NULL) + { + value = _gtk_css_value_new (GTK_TYPE_CSS_NUMBER); + value->u.ptr = g_boxed_copy0 (GTK_TYPE_CSS_NUMBER, v); + px_singletons[i] = value; + } + + return _gtk_css_value_ref (px_singletons[i]); + } + + value = _gtk_css_value_new (GTK_TYPE_CSS_NUMBER); + value->u.ptr = g_boxed_copy0 (GTK_TYPE_CSS_NUMBER, v); + + return value; +} + +GtkCssValue * +_gtk_css_value_new_from_rgba (const GdkRGBA *v) +{ + GtkCssValue *value; + + value = _gtk_css_value_new (GDK_TYPE_RGBA); + value->u.ptr = g_boxed_copy0 (GDK_TYPE_RGBA, v); + + return value; +} + +GtkCssValue * +_gtk_css_value_new_from_color (const GdkColor *v) +{ + GtkCssValue *value; + + value = _gtk_css_value_new (GDK_TYPE_COLOR); + value->u.ptr = g_boxed_copy0 (GDK_TYPE_COLOR, v); + + return value; +} + +GtkCssValue * +_gtk_css_value_new_from_background_size (const GtkCssBackgroundSize *v) +{ + GtkCssValue *value; + + value = _gtk_css_value_new (GTK_TYPE_CSS_BACKGROUND_SIZE); + value->u.ptr = g_boxed_copy0 (GTK_TYPE_CSS_BACKGROUND_SIZE, v); + + return value; +} + +GtkCssValue * +_gtk_css_value_new_take_symbolic_color (GtkSymbolicColor *v) +{ + GtkCssValue *value; + + value = _gtk_css_value_new (GTK_TYPE_SYMBOLIC_COLOR); + value->u.ptr = v; + + return value; +} + +GtkCssValue * +_gtk_css_value_ref (GtkCssValue *value) +{ + g_return_val_if_fail (value != NULL, NULL); + + g_atomic_int_add (&value->ref_count, 1); + + return value; +} + +void +_gtk_css_value_unref (GtkCssValue *value) +{ + GType type; + + if (value == NULL) + return; + + if (!g_atomic_int_dec_and_test (&value->ref_count)) + return; + + type = value->type; + + if (g_type_is_a (type, G_TYPE_OBJECT) && value->u.ptr != NULL) + g_object_unref (value->u.ptr); + else if (g_type_is_a (type, G_TYPE_BOXED) && value->u.ptr != NULL) + g_boxed_free (type, value->u.ptr); + else if (g_type_is_a (type, G_TYPE_STRING)) + g_free (value->u.ptr); + + g_slice_free (GtkCssValue, value); +} + +GType +_gtk_css_value_get_content_type (GtkCssValue *value) +{ + return value->type; +} + +gboolean +_gtk_css_value_holds (GtkCssValue *value, GType type) +{ + return g_type_is_a (value->type, type); +} + +static void +fill_gvalue (GtkCssValue *value, + GValue *g_value) +{ + GType type; + + type = value->type; + + if (g_type_is_a (type, G_TYPE_OBJECT)) + g_value_set_object (g_value, value->u.ptr); + else if (g_type_is_a (type, G_TYPE_BOXED)) + g_value_set_boxed (g_value, value->u.ptr); + else if (g_type_is_a (type, G_TYPE_INT)) + g_value_set_int (g_value, value->u.gint); + else if (g_type_is_a (type, G_TYPE_UINT)) + g_value_set_uint (g_value, value->u.guint); + else if (g_type_is_a (type, G_TYPE_BOOLEAN)) + g_value_set_boolean (g_value, value->u.gint); + else if (g_type_is_a (type, G_TYPE_ENUM)) + g_value_set_enum (g_value, value->u.gint); + else if (g_type_is_a (type, G_TYPE_FLAGS)) + g_value_set_flags (g_value, value->u.guint); + else if (g_type_is_a (type, G_TYPE_STRING)) + g_value_set_string (g_value, value->u.ptr); + else if (g_type_is_a (type, G_TYPE_DOUBLE)) + g_value_set_double (g_value, value->u.dbl); + else if (g_type_is_a (type, G_TYPE_FLOAT)) + g_value_set_float (g_value, value->u.flt); + else + g_assert_not_reached (); +} + +void +_gtk_css_value_init_gvalue (GtkCssValue *value, + GValue *g_value) +{ + if (value != NULL) + { + g_value_init (g_value, value->type); + fill_gvalue (value, g_value); + } +} + +void +_gtk_css_value_to_gvalue (GtkCssValue *value, + GValue *g_value) +{ + if (value->type == G_VALUE_TYPE (g_value)) + fill_gvalue (value, g_value); + else if (g_value_type_transformable (value->type, G_VALUE_TYPE (g_value))) + { + GValue v = G_VALUE_INIT; + _gtk_css_value_init_gvalue (value, &v); + g_value_transform (&v, g_value); + g_value_unset (&v); + } + else + g_warning ("can't convert css value of type `%s' as value of type `%s'", + g_type_name (value->type), + G_VALUE_TYPE_NAME (g_value)); +} + +gboolean +_gtk_css_value_is_special (GtkCssValue *value) +{ + return _gtk_css_value_holds (value, GTK_TYPE_CSS_SPECIAL_VALUE); +} + +GtkCssSpecialValue +_gtk_css_value_get_special_kind (GtkCssValue *value) +{ + g_return_val_if_fail (_gtk_css_value_holds (value, GTK_TYPE_CSS_SPECIAL_VALUE), 0); + return value->u.gint; +} + +GtkCssNumber * +_gtk_css_value_get_number (GtkCssValue *value) +{ + g_return_val_if_fail (_gtk_css_value_holds (value, GTK_TYPE_CSS_NUMBER), NULL); + return value->u.ptr; +} + +GtkSymbolicColor * +_gtk_css_value_get_symbolic_color (GtkCssValue *value) +{ + g_return_val_if_fail (_gtk_css_value_holds (value, GTK_TYPE_SYMBOLIC_COLOR), NULL); + return value->u.ptr; +} + +int +_gtk_css_value_get_int (GtkCssValue *value) +{ + g_return_val_if_fail (_gtk_css_value_holds (value, G_TYPE_INT), 0); + return value->u.gint; +} + +double +_gtk_css_value_get_double (GtkCssValue *value) +{ + g_return_val_if_fail (_gtk_css_value_holds (value, G_TYPE_DOUBLE), 0); + return value->u.dbl; +} + +const char * +_gtk_css_value_get_string (GtkCssValue *value) +{ + g_return_val_if_fail (_gtk_css_value_holds (value, G_TYPE_STRING), 0); + return value->u.ptr; +} + +gpointer +_gtk_css_value_dup_object (GtkCssValue *value) +{ + g_return_val_if_fail (_gtk_css_value_holds (value, G_TYPE_OBJECT), NULL); + if (value->u.ptr) + return g_object_ref (value->u.ptr); + return NULL; +} + +gpointer +_gtk_css_value_get_object (GtkCssValue *value) +{ + g_return_val_if_fail (_gtk_css_value_holds (value, G_TYPE_OBJECT), NULL); + return value->u.ptr; +} + +gpointer +_gtk_css_value_get_boxed (GtkCssValue *value) +{ + g_return_val_if_fail (_gtk_css_value_holds (value, G_TYPE_BOXED), NULL); + return value->u.ptr; +} + +const char ** +_gtk_css_value_get_strv (GtkCssValue *value) +{ + g_return_val_if_fail (_gtk_css_value_holds (value, G_TYPE_STRV), NULL); + return value->u.ptr; +} + +GtkCssImage * +_gtk_css_value_get_image (GtkCssValue *value) +{ + g_return_val_if_fail (_gtk_css_value_holds (value, GTK_TYPE_CSS_IMAGE), NULL); + return value->u.ptr; +} + +GtkBorderStyle +_gtk_css_value_get_border_style (GtkCssValue *value) +{ + g_return_val_if_fail (_gtk_css_value_holds (value, GTK_TYPE_BORDER_STYLE), 0); + return value->u.gint; +} + +GtkCssBackgroundSize * +_gtk_css_value_get_background_size (GtkCssValue *value) +{ + g_return_val_if_fail (_gtk_css_value_holds (value, GTK_TYPE_CSS_BACKGROUND_SIZE), NULL); + return value->u.ptr; +} + +GtkCssBorderImageRepeat * +_gtk_css_value_get_border_image_repeat (GtkCssValue *value) +{ + g_return_val_if_fail (_gtk_css_value_holds (value, GTK_TYPE_CSS_BORDER_IMAGE_REPEAT), NULL); + return value->u.ptr; +} + +GtkCssBorderCornerRadius * +_gtk_css_value_get_border_corner_radius (GtkCssValue *value) +{ + g_return_val_if_fail (_gtk_css_value_holds (value, GTK_TYPE_CSS_BORDER_CORNER_RADIUS), NULL); + return value->u.ptr; +} + +PangoFontDescription * +_gtk_css_value_get_font_description (GtkCssValue *value) +{ + g_return_val_if_fail (_gtk_css_value_holds (value, PANGO_TYPE_FONT_DESCRIPTION), 0); + return value->u.ptr; +} + +PangoStyle +_gtk_css_value_get_pango_style (GtkCssValue *value) +{ + g_return_val_if_fail (_gtk_css_value_holds (value, PANGO_TYPE_STYLE), 0); + return value->u.gint; +} + +PangoVariant +_gtk_css_value_get_pango_variant (GtkCssValue *value) +{ + g_return_val_if_fail (_gtk_css_value_holds (value, PANGO_TYPE_VARIANT), 0); + return value->u.gint; +} + +PangoWeight +_gtk_css_value_get_pango_weight (GtkCssValue *value) +{ + g_return_val_if_fail (_gtk_css_value_holds (value, PANGO_TYPE_WEIGHT), 0); + return value->u.gint; +} + +GdkRGBA * +_gtk_css_value_get_rgba (GtkCssValue *value) +{ + g_return_val_if_fail (_gtk_css_value_holds (value, GDK_TYPE_RGBA), NULL); + return value->u.ptr; +} + +cairo_pattern_t * +_gtk_css_value_get_pattern (GtkCssValue *value) +{ + g_return_val_if_fail (_gtk_css_value_holds (value, CAIRO_GOBJECT_TYPE_PATTERN), NULL); + return value->u.ptr; +} + +GtkGradient * +_gtk_css_value_get_gradient (GtkCssValue *value) +{ + g_return_val_if_fail (_gtk_css_value_holds (value, GTK_TYPE_GRADIENT), NULL); + return value->u.ptr; +} + +GtkShadow * +_gtk_css_value_get_shadow (GtkCssValue *value) +{ + g_return_val_if_fail (_gtk_css_value_holds (value, GTK_TYPE_SHADOW), NULL); + return value->u.ptr; +} diff --git a/gtk/gtkcssvalueprivate.h b/gtk/gtkcssvalueprivate.h new file mode 100644 index 0000000000..62f17a320f --- /dev/null +++ b/gtk/gtkcssvalueprivate.h @@ -0,0 +1,96 @@ +/* + * Copyright © 2012 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, see . + * + * Authors: Alexander Larsson + */ + +#ifndef __GTK_CSS_VALUE_PRIVATE_H__ +#define __GTK_CSS_VALUE_PRIVATE_H__ + +#include +#include "gtkcsstypesprivate.h" +#include "gtksymboliccolor.h" +#include "gtkcssimageprivate.h" +#include "gtkshadowprivate.h" + +G_BEGIN_DECLS + +#define GTK_TYPE_CSS_VALUE (_gtk_css_value_get_type ()) +#define GTK_CSS_VALUE(obj) (G_TYPE_CHECK_INSTANCE_CAST (obj, GTK_TYPE_CSS_VALUE, GtkCssValue)) +#define GTK_CSS_VALUE_CLASS(cls) (G_TYPE_CHECK_CLASS_CAST (cls, GTK_TYPE_CSS_VALUE, GtkCssValueClass)) +#define GTK_IS_CSS_VALUE(obj) (G_TYPE_CHECK_INSTANCE_TYPE (obj, GTK_TYPE_CSS_VALUE)) +#define GTK_IS_CSS_VALUE_CLASS(obj) (G_TYPE_CHECK_CLASS_TYPE (obj, GTK_TYPE_CSS_VALUE)) +#define GTK_CSS_VALUE_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), GTK_TYPE_CSS_VALUE, GtkCssValueClass)) + +typedef struct _GtkCssValue GtkCssValue; + +/* A GtkCssValue is a refcounted immutable value type */ + +GType _gtk_css_value_get_type (void) G_GNUC_CONST; +GtkCssValue *_gtk_css_value_ref (GtkCssValue *value); +void _gtk_css_value_unref (GtkCssValue *value); +GType _gtk_css_value_get_content_type (GtkCssValue *value); +gboolean _gtk_css_value_holds (GtkCssValue *value, + GType type); +GtkCssValue *_gtk_css_value_new_from_gvalue (const GValue *g_value); +GtkCssValue *_gtk_css_value_new_take_gvalue (GValue *g_value); +GtkCssValue *_gtk_css_value_new_from_int (gint val); +GtkCssValue *_gtk_css_value_new_from_string (const char *string); +GtkCssValue *_gtk_css_value_new_take_string (char *string); +GtkCssValue *_gtk_css_value_new_take_font_description (PangoFontDescription *v); +GtkCssValue *_gtk_css_value_new_from_rgba (const GdkRGBA *v); +GtkCssValue *_gtk_css_value_new_from_color (const GdkColor *v); +GtkCssValue *_gtk_css_value_new_take_symbolic_color (GtkSymbolicColor *v); +GtkCssValue *_gtk_css_value_new_from_border (const GtkBorder *border); +GtkCssValue *_gtk_css_value_new_take_pattern (cairo_pattern_t *v); +GtkCssValue *_gtk_css_value_new_from_pattern (const cairo_pattern_t *v); +GtkCssValue *_gtk_css_value_new_take_shadow (GtkShadow *v); +GtkCssValue *_gtk_css_value_new_take_image (GtkCssImage *v); +GtkCssValue *_gtk_css_value_new_from_number (const GtkCssNumber *v); +GtkCssValue *_gtk_css_value_new_from_background_size (const GtkCssBackgroundSize *v); +void _gtk_css_value_to_gvalue (GtkCssValue *value, + GValue *g_value); +void _gtk_css_value_init_gvalue (GtkCssValue *value, + GValue *g_value); + +gboolean _gtk_css_value_is_special (GtkCssValue *value); +GtkCssSpecialValue _gtk_css_value_get_special_kind (GtkCssValue *value); +int _gtk_css_value_get_int (GtkCssValue *value); +double _gtk_css_value_get_double (GtkCssValue *value); +const char * _gtk_css_value_get_string (GtkCssValue *value); +gpointer _gtk_css_value_dup_object (GtkCssValue *value); +gpointer _gtk_css_value_get_object (GtkCssValue *value); +gpointer _gtk_css_value_get_boxed (GtkCssValue *value); +const char ** _gtk_css_value_get_strv (GtkCssValue *value); +GtkCssNumber *_gtk_css_value_get_number (GtkCssValue *value); +GtkSymbolicColor *_gtk_css_value_get_symbolic_color (GtkCssValue *value); +GtkCssImage *_gtk_css_value_get_image (GtkCssValue *value); +GtkBorderStyle _gtk_css_value_get_border_style (GtkCssValue *value); +GtkCssBackgroundSize *_gtk_css_value_get_background_size (GtkCssValue *value); +GtkCssBorderCornerRadius *_gtk_css_value_get_border_corner_radius (GtkCssValue *value); +GtkCssBorderImageRepeat *_gtk_css_value_get_border_image_repeat (GtkCssValue *value); +PangoFontDescription * _gtk_css_value_get_font_description (GtkCssValue *value); +PangoStyle _gtk_css_value_get_pango_style (GtkCssValue *value); +PangoVariant _gtk_css_value_get_pango_variant (GtkCssValue *value); +PangoWeight _gtk_css_value_get_pango_weight (GtkCssValue *value); +GdkRGBA *_gtk_css_value_get_rgba (GtkCssValue *value); +cairo_pattern_t *_gtk_css_value_get_pattern (GtkCssValue *value); +GtkGradient *_gtk_css_value_get_gradient (GtkCssValue *value); +GtkShadow *_gtk_css_value_get_shadow (GtkCssValue *value); + +G_END_DECLS + +#endif /* __GTK_CSS_VALUE_PRIVATE_H__ */ diff --git a/gtk/gtkstylecontext.c b/gtk/gtkstylecontext.c index a46be6fa54..e04e03b452 100644 --- a/gtk/gtkstylecontext.c +++ b/gtk/gtkstylecontext.c @@ -1072,7 +1072,7 @@ style_data_lookup (GtkStyleContext *context, GtkStyleContextPrivate *priv; StyleData *data; gboolean state_mismatch; - const GValue *v; + GtkCssValue *v; priv = context->priv; state_mismatch = ((GtkStyleInfo *) priv->info_stack->data)->state_flags != state; @@ -1116,7 +1116,7 @@ style_data_lookup (GtkStyleContext *context, v = _gtk_css_computed_values_get_value_by_name (priv->current_data->store, "engine"); if (v) - priv->theming_engine = g_value_dup_object (v); + priv->theming_engine = _gtk_css_value_dup_object (v); else priv->theming_engine = g_object_ref (gtk_theming_engine_load (NULL)); @@ -1440,7 +1440,7 @@ gtk_style_context_get_section (GtkStyleContext *context, return _gtk_css_computed_values_get_section (data->store, _gtk_css_style_property_get_id (GTK_CSS_STYLE_PROPERTY (prop))); } -static const GValue * +static GtkCssValue * gtk_style_context_query_func (guint id, gpointer values) { @@ -1470,6 +1470,7 @@ gtk_style_context_get_property (GtkStyleContext *context, GtkStyleContextPrivate *priv; GtkStyleProperty *prop; StyleData *data; + GtkCssValue *v; g_return_if_fail (GTK_IS_STYLE_CONTEXT (context)); g_return_if_fail (property != NULL); @@ -1491,7 +1492,9 @@ gtk_style_context_get_property (GtkStyleContext *context, } data = style_data_lookup (context, state); - _gtk_style_property_query (prop, value, gtk_style_context_query_func, data->store); + v = _gtk_style_property_query (prop, gtk_style_context_query_func, data->store); + _gtk_css_value_init_gvalue (v, value); + _gtk_css_value_unref (v); } /** @@ -2362,7 +2365,7 @@ style_property_values_cmp (gconstpointer bsearch_node1, return 0; } -const GValue * +GtkCssValue * _gtk_style_context_peek_property (GtkStyleContext *context, const char *property_name) { @@ -2376,10 +2379,10 @@ _gtk_style_context_get_number (GtkStyleContext *context, const char *property_name, double one_hundred_percent) { - const GValue *value; + GtkCssValue *value; value = _gtk_style_context_peek_property (context, property_name); - return _gtk_css_number_get (g_value_get_boxed (value), one_hundred_percent); + return _gtk_css_number_get (_gtk_css_value_get_number (value), one_hundred_percent); } const GValue * @@ -2916,19 +2919,39 @@ gtk_style_context_color_lookup_func (gpointer contextp, return sym_color; } +GtkCssValue * +_gtk_style_context_resolve_color_value (GtkStyleContext *context, + GtkSymbolicColor *color) +{ + g_return_val_if_fail (GTK_IS_STYLE_CONTEXT (context), FALSE); + g_return_val_if_fail (color != NULL, FALSE); + + return _gtk_symbolic_color_resolve_full (color, + gtk_style_context_color_lookup_func, + context); +} + + gboolean _gtk_style_context_resolve_color (GtkStyleContext *context, GtkSymbolicColor *color, GdkRGBA *result) { + GtkCssValue *val; + g_return_val_if_fail (GTK_IS_STYLE_CONTEXT (context), FALSE); g_return_val_if_fail (color != NULL, FALSE); g_return_val_if_fail (result != NULL, FALSE); - return _gtk_symbolic_color_resolve_full (color, - gtk_style_context_color_lookup_func, - context, - result); + val = _gtk_symbolic_color_resolve_full (color, + gtk_style_context_color_lookup_func, + context); + if (val == NULL) + return FALSE; + + *result = *_gtk_css_value_get_rgba (val); + _gtk_css_value_unref (val); + return TRUE; } /** @@ -3023,7 +3046,7 @@ gtk_style_context_notify_state_change (GtkStyleContext *context, GtkAnimationDescription *desc; AnimationInfo *info; GtkStateFlags flags; - const GValue *v; + GtkCssValue *v; StyleData *data; g_return_if_fail (GTK_IS_STYLE_CONTEXT (context)); @@ -3068,7 +3091,7 @@ gtk_style_context_notify_state_change (GtkStyleContext *context, v = _gtk_css_computed_values_get_value_by_name (data->store, "transition"); if (!v) return; - desc = g_value_get_boxed (v); + desc = _gtk_css_value_get_boxed (v); if (!desc) return; diff --git a/gtk/gtkstylecontextprivate.h b/gtk/gtkstylecontextprivate.h index a5933c39f8..dbec998443 100644 --- a/gtk/gtkstylecontextprivate.h +++ b/gtk/gtkstylecontextprivate.h @@ -20,10 +20,11 @@ #include "gtkstylecontext.h" #include "gtksymboliccolor.h" +#include "gtkcssvalueprivate.h" G_BEGIN_DECLS -const GValue * _gtk_style_context_peek_property (GtkStyleContext *context, +GtkCssValue * _gtk_style_context_peek_property (GtkStyleContext *context, const char *property_name); double _gtk_style_context_get_number (GtkStyleContext *context, const char *property_name, @@ -40,6 +41,8 @@ gboolean _gtk_style_context_check_region_name (const gchar *s gboolean _gtk_style_context_resolve_color (GtkStyleContext *context, GtkSymbolicColor *color, GdkRGBA *result); +GtkCssValue * _gtk_style_context_resolve_color_value (GtkStyleContext *context, + GtkSymbolicColor *color); void _gtk_style_context_get_cursor_color (GtkStyleContext *context, GdkRGBA *primary_color, GdkRGBA *secondary_color); diff --git a/gtk/gtkstyleproperties.c b/gtk/gtkstyleproperties.c index 362f384fdf..e73e74b6ac 100644 --- a/gtk/gtkstyleproperties.c +++ b/gtk/gtkstyleproperties.c @@ -65,7 +65,7 @@ typedef struct ValueData ValueData; struct ValueData { GtkStateFlags state; - GValue value; + GtkCssValue *value; }; struct PropertyData @@ -122,8 +122,8 @@ property_data_remove_values (PropertyData *data) value_data = &g_array_index (data->values, ValueData, i); - if (G_IS_VALUE (&value_data->value)) - g_value_unset (&value_data->value); + _gtk_css_value_unref (value_data->value); + value_data->value = NULL; } if (data->values->len > 0) @@ -188,11 +188,10 @@ property_data_find_position (PropertyData *data, return found; } -static GValue * +static ValueData * property_data_get_value (PropertyData *data, GtkStateFlags state) { - ValueData *val_data; guint pos; if (!property_data_find_position (data, state, &pos)) @@ -203,12 +202,10 @@ property_data_get_value (PropertyData *data, g_array_insert_val (data->values, pos, new); } - val_data = &g_array_index (data->values, ValueData, pos); - - return &val_data->value; + return &g_array_index (data->values, ValueData, pos); } -static GValue * +static GtkCssValue * property_data_match_state (PropertyData *data, GtkStateFlags state) { @@ -221,7 +218,7 @@ property_data_match_state (PropertyData *data, /* Exact match */ val_data = &g_array_index (data->values, ValueData, pos); - return &val_data->value; + return val_data->value; } if (pos >= data->values->len) @@ -248,7 +245,7 @@ property_data_match_state (PropertyData *data, if (val_data->state == 0 || ((val_data->state & state) != 0 && (val_data->state & ~state) == 0)) - return &val_data->value; + return val_data->value; } return NULL; @@ -325,7 +322,7 @@ gtk_style_properties_provider_lookup (GtkStyleProviderPrivate *provider, { GtkCssStyleProperty *prop = key; PropertyData *data = value; - const GValue *value; + GtkCssValue *value; guint id; id = _gtk_css_style_property_get_id (prop); @@ -431,13 +428,13 @@ void _gtk_style_properties_set_property_by_property (GtkStyleProperties *props, GtkCssStyleProperty *style_prop, GtkStateFlags state, - const GValue *value) + GtkCssValue *value) { GtkStylePropertiesPrivate *priv; PropertyData *prop; - GValue *val; + ValueData *val; - g_return_if_fail (G_VALUE_TYPE (value) == _gtk_css_style_property_get_computed_type (style_prop)); + g_return_if_fail (_gtk_css_value_holds (value, _gtk_css_style_property_get_computed_type (style_prop))); priv = props->priv; prop = g_hash_table_lookup (priv->properties, style_prop); @@ -450,17 +447,8 @@ _gtk_style_properties_set_property_by_property (GtkStyleProperties *props, val = property_data_get_value (prop, state); - if (G_VALUE_TYPE (val) == G_VALUE_TYPE (value)) - g_value_reset (val); - else - { - if (G_IS_VALUE (val)) - g_value_unset (val); - - g_value_init (val, G_VALUE_TYPE (value)); - } - - g_value_copy (value, val); + _gtk_css_value_unref (val->value); + val->value = _gtk_css_value_ref (value); } /** @@ -586,7 +574,7 @@ gtk_style_properties_set (GtkStyleProperties *props, va_end (args); } -const GValue * +GtkCssValue * _gtk_style_properties_peek_property (GtkStyleProperties *props, GtkCssStyleProperty *property, GtkStateFlags state) @@ -610,7 +598,7 @@ typedef struct { GtkStateFlags state; } StyleQueryData; -static const GValue * +static GtkCssValue * style_query_func (guint id, gpointer data) { @@ -643,6 +631,7 @@ gtk_style_properties_get_property (GtkStyleProperties *props, { StyleQueryData query = { props, state }; GtkStyleProperty *node; + GtkCssValue *v; g_return_val_if_fail (GTK_IS_STYLE_PROPERTIES (props), FALSE); g_return_val_if_fail (property != NULL, FALSE); @@ -660,10 +649,12 @@ gtk_style_properties_get_property (GtkStyleProperties *props, return FALSE; } - _gtk_style_property_query (node, - value, - style_query_func, - &query); + v = _gtk_style_property_query (node, + style_query_func, + &query); + _gtk_css_value_init_gvalue (v, value); + _gtk_css_value_unref (v); + return TRUE; } @@ -800,8 +791,8 @@ gtk_style_properties_unset_property (GtkStyleProperties *props, data = &g_array_index (prop->values, ValueData, pos); - if (G_IS_VALUE (&data->value)) - g_value_unset (&data->value); + _gtk_css_value_unref (data->value); + data->value = NULL; g_array_remove_index (prop->values, pos); } @@ -893,12 +884,12 @@ gtk_style_properties_merge (GtkStyleProperties *props, for (i = 0; i < prop_to_merge->values->len; i++) { ValueData *data; - GValue *value; + ValueData *value; data = &g_array_index (prop_to_merge->values, ValueData, i); if (replace && data->state == GTK_STATE_FLAG_NORMAL && - G_VALUE_TYPE (&data->value) != PANGO_TYPE_FONT_DESCRIPTION) + _gtk_css_value_holds (data->value, PANGO_TYPE_FONT_DESCRIPTION)) { /* Let normal state override all states * previously set in the original set @@ -908,20 +899,20 @@ gtk_style_properties_merge (GtkStyleProperties *props, value = property_data_get_value (prop, data->state); - if (G_VALUE_TYPE (&data->value) == PANGO_TYPE_FONT_DESCRIPTION && - G_IS_VALUE (value)) + if (_gtk_css_value_holds (data->value, PANGO_TYPE_FONT_DESCRIPTION) && + value->value != NULL) { PangoFontDescription *font_desc; PangoFontDescription *font_desc_to_merge; /* Handle merging of font descriptions */ - font_desc = g_value_get_boxed (value); - font_desc_to_merge = g_value_get_boxed (&data->value); + font_desc = _gtk_css_value_get_font_description (value->value); + font_desc_to_merge = _gtk_css_value_get_font_description (data->value); pango_font_description_merge (font_desc, font_desc_to_merge, replace); } - else if (G_VALUE_TYPE (&data->value) == G_TYPE_PTR_ARRAY && - G_IS_VALUE (value)) + else if (_gtk_css_value_holds (data->value, G_TYPE_PTR_ARRAY) && + value->value != NULL) { GPtrArray *array, *array_to_merge; gint i; @@ -929,23 +920,16 @@ gtk_style_properties_merge (GtkStyleProperties *props, /* Append the array, mainly thought * for the gtk-key-bindings property */ - array = g_value_get_boxed (value); - array_to_merge = g_value_get_boxed (&data->value); + array = _gtk_css_value_get_boxed (value->value); + array_to_merge = _gtk_css_value_get_boxed (data->value); for (i = 0; i < array_to_merge->len; i++) g_ptr_array_add (array, g_ptr_array_index (array_to_merge, i)); } - else if (replace || !G_IS_VALUE (value)) + else if (replace || value->value == NULL) { - if (!G_IS_VALUE (value)) - g_value_init (value, G_VALUE_TYPE (&data->value)); - else if (G_VALUE_TYPE (value) != G_VALUE_TYPE (&data->value)) - { - g_value_unset (value); - g_value_init (value, G_VALUE_TYPE (&data->value)); - } - - g_value_copy (&data->value, value); + _gtk_css_value_unref (value->value); + value->value = _gtk_css_value_ref (data->value); } } } diff --git a/gtk/gtkstylepropertiesprivate.h b/gtk/gtkstylepropertiesprivate.h index 1b9caf4aaa..c5b742e791 100644 --- a/gtk/gtkstylepropertiesprivate.h +++ b/gtk/gtkstylepropertiesprivate.h @@ -25,13 +25,13 @@ G_BEGIN_DECLS -const GValue * _gtk_style_properties_peek_property (GtkStyleProperties *props, +GtkCssValue * _gtk_style_properties_peek_property (GtkStyleProperties *props, GtkCssStyleProperty *property, GtkStateFlags state); void _gtk_style_properties_set_property_by_property (GtkStyleProperties *props, GtkCssStyleProperty *property, GtkStateFlags state, - const GValue *value); + GtkCssValue *value); G_END_DECLS diff --git a/gtk/gtkstyleproperty.c b/gtk/gtkstyleproperty.c index 7cc6cbb724..c70c76fdd4 100644 --- a/gtk/gtkstyleproperty.c +++ b/gtk/gtkstyleproperty.c @@ -205,23 +205,19 @@ _gtk_style_property_assign (GtkStyleProperty *property, * turn gtk_style_context_get() and similar functions to get the * value to return to code using old APIs. **/ -void +GtkCssValue * _gtk_style_property_query (GtkStyleProperty *property, - GValue *value, GtkStyleQueryFunc query_func, gpointer query_data) { GtkStylePropertyClass *klass; - g_return_if_fail (GTK_IS_STYLE_PROPERTY (property)); - g_return_if_fail (value != NULL); - g_return_if_fail (query_func != NULL); + g_return_val_if_fail (GTK_IS_STYLE_PROPERTY (property), NULL); + g_return_val_if_fail (query_func != NULL, NULL); klass = GTK_STYLE_PROPERTY_GET_CLASS (property); - g_value_init (value, property->value_type); - - klass->query (property, value, query_func, query_data); + return klass->query (property, query_func, query_data); } void diff --git a/gtk/gtkstylepropertyprivate.h b/gtk/gtkstylepropertyprivate.h index 936b48a317..898b97f776 100644 --- a/gtk/gtkstylepropertyprivate.h +++ b/gtk/gtkstylepropertyprivate.h @@ -20,6 +20,7 @@ #include "gtkcssparserprivate.h" #include "gtkstylecontextprivate.h" +#include "gtkcssvalueprivate.h" G_BEGIN_DECLS @@ -37,8 +38,8 @@ typedef enum { GTK_STYLE_PROPERTY_INHERIT = (1 << 0) } GtkStylePropertyFlags; -typedef const GValue * (* GtkStyleQueryFunc) (guint id, - gpointer data); +typedef GtkCssValue * (* GtkStyleQueryFunc) (guint id, + gpointer data); struct _GtkStyleProperty { @@ -56,8 +57,7 @@ struct _GtkStylePropertyClass GtkStyleProperties *props, GtkStateFlags state, const GValue *value); - void (* query) (GtkStyleProperty *property, - GValue *value, + GtkCssValue * (* query) (GtkStyleProperty *property, GtkStyleQueryFunc query_func, gpointer query_data); gboolean (* parse_value) (GtkStyleProperty * property, @@ -82,8 +82,7 @@ gboolean _gtk_style_property_parse_value (GtkStyleProperty * GFile *base); GType _gtk_style_property_get_value_type(GtkStyleProperty * property); -void _gtk_style_property_query (GtkStyleProperty * property, - GValue *value, +GtkCssValue * _gtk_style_property_query (GtkStyleProperty * property, GtkStyleQueryFunc query_func, gpointer query_data); void _gtk_style_property_assign (GtkStyleProperty *property, diff --git a/gtk/gtksymboliccolor.c b/gtk/gtksymboliccolor.c index bb4c2b8e89..b96a2348fd 100644 --- a/gtk/gtksymboliccolor.c +++ b/gtk/gtksymboliccolor.c @@ -58,10 +58,10 @@ struct _GtkSymbolicColor { ColorType type; guint ref_count; + GtkCssValue *last_value; union { - GdkRGBA color; gchar *name; struct @@ -104,7 +104,7 @@ gtk_symbolic_color_new_literal (const GdkRGBA *color) symbolic_color = g_slice_new0 (GtkSymbolicColor); symbolic_color->type = COLOR_TYPE_LITERAL; - symbolic_color->color = *color; + symbolic_color->last_value = _gtk_css_value_new_from_rgba (color); symbolic_color->ref_count = 1; return symbolic_color; @@ -328,27 +328,28 @@ gtk_symbolic_color_unref (GtkSymbolicColor *color) if (color->ref_count == 0) { + _gtk_css_value_unref (color->last_value); switch (color->type) - { - case COLOR_TYPE_NAME: - g_free (color->name); - break; - case COLOR_TYPE_SHADE: - gtk_symbolic_color_unref (color->shade.color); - break; - case COLOR_TYPE_ALPHA: - gtk_symbolic_color_unref (color->alpha.color); - break; - case COLOR_TYPE_MIX: - gtk_symbolic_color_unref (color->mix.color1); - gtk_symbolic_color_unref (color->mix.color2); - break; - case COLOR_TYPE_WIN32: - g_free (color->win32.theme_class); - break; - default: - break; - } + { + case COLOR_TYPE_NAME: + g_free (color->name); + break; + case COLOR_TYPE_SHADE: + gtk_symbolic_color_unref (color->shade.color); + break; + case COLOR_TYPE_ALPHA: + gtk_symbolic_color_unref (color->alpha.color); + break; + case COLOR_TYPE_MIX: + gtk_symbolic_color_unref (color->mix.color1); + gtk_symbolic_color_unref (color->mix.color2); + break; + case COLOR_TYPE_WIN32: + g_free (color->win32.theme_class); + break; + default: + break; + } g_slice_free (GtkSymbolicColor, color); } @@ -560,106 +561,155 @@ resolve_lookup_color (gpointer data, const char *name) **/ gboolean gtk_symbolic_color_resolve (GtkSymbolicColor *color, - GtkStyleProperties *props, - GdkRGBA *resolved_color) + GtkStyleProperties *props, + GdkRGBA *resolved_color) { + GtkCssValue *v; + g_return_val_if_fail (color != NULL, FALSE); g_return_val_if_fail (resolved_color != NULL, FALSE); g_return_val_if_fail (props == NULL || GTK_IS_STYLE_PROPERTIES (props), FALSE); - return _gtk_symbolic_color_resolve_full (color, - resolve_lookup_color, - props, - resolved_color); + v =_gtk_symbolic_color_resolve_full (color, + resolve_lookup_color, + props); + if (v == NULL) + return FALSE; + + *resolved_color = *_gtk_css_value_get_rgba (v); + _gtk_css_value_unref (v); + return TRUE; } -gboolean +GtkCssValue * _gtk_symbolic_color_resolve_full (GtkSymbolicColor *color, - GtkSymbolicColorLookupFunc func, - gpointer data, - GdkRGBA *resolved_color) + GtkSymbolicColorLookupFunc func, + gpointer data) { + GtkCssValue *value; + g_return_val_if_fail (color != NULL, FALSE); - g_return_val_if_fail (resolved_color != NULL, FALSE); g_return_val_if_fail (func != NULL, FALSE); + value = NULL; switch (color->type) { case COLOR_TYPE_LITERAL: - *resolved_color = color->color; - return TRUE; + return _gtk_css_value_ref (color->last_value); case COLOR_TYPE_NAME: { - GtkSymbolicColor *named_color; + GtkSymbolicColor *named_color; - named_color = func (data, color->name); + named_color = func (data, color->name); - if (!named_color) - return FALSE; + if (!named_color) + return NULL; - return _gtk_symbolic_color_resolve_full (named_color, func, data, resolved_color); + return _gtk_symbolic_color_resolve_full (named_color, func, data); } break; case COLOR_TYPE_SHADE: { - GdkRGBA shade; + GtkCssValue *val; + GdkRGBA shade; - if (!_gtk_symbolic_color_resolve_full (color->shade.color, func, data, &shade)) - return FALSE; + val = _gtk_symbolic_color_resolve_full (color->shade.color, func, data); + if (val == NULL) + return NULL; - _shade_color (&shade, color->shade.factor); - *resolved_color = shade; + shade = *_gtk_css_value_get_rgba (val); + _shade_color (&shade, color->shade.factor); - return TRUE; + _gtk_css_value_unref (val); + + value = _gtk_css_value_new_from_rgba (&shade); } break; case COLOR_TYPE_ALPHA: { - GdkRGBA alpha; + GtkCssValue *val; + GdkRGBA alpha; - if (!_gtk_symbolic_color_resolve_full (color->alpha.color, func, data, &alpha)) - return FALSE; + val = _gtk_symbolic_color_resolve_full (color->alpha.color, func, data); + if (val == NULL) + return NULL; - *resolved_color = alpha; - resolved_color->alpha = CLAMP (alpha.alpha * color->alpha.factor, 0, 1); + alpha = *_gtk_css_value_get_rgba (val); + alpha.alpha = CLAMP (alpha.alpha * color->alpha.factor, 0, 1); - return TRUE; + _gtk_css_value_unref (val); + + value = _gtk_css_value_new_from_rgba (&alpha); } + break; + case COLOR_TYPE_MIX: { - GdkRGBA color1, color2; + GtkCssValue *val; + GdkRGBA color1, color2, res; - if (!_gtk_symbolic_color_resolve_full (color->mix.color1, func, data, &color1)) - return FALSE; + val = _gtk_symbolic_color_resolve_full (color->mix.color1, func, data); + if (val == NULL) + return NULL; + color1 = *_gtk_css_value_get_rgba (val); + _gtk_css_value_unref (val); - if (!_gtk_symbolic_color_resolve_full (color->mix.color2, func, data, &color2)) - return FALSE; + val = _gtk_symbolic_color_resolve_full (color->mix.color2, func, data); + if (val == NULL) + return NULL; + color2 = *_gtk_css_value_get_rgba (val); + _gtk_css_value_unref (val); - resolved_color->red = CLAMP (color1.red + ((color2.red - color1.red) * color->mix.factor), 0, 1); - resolved_color->green = CLAMP (color1.green + ((color2.green - color1.green) * color->mix.factor), 0, 1); - resolved_color->blue = CLAMP (color1.blue + ((color2.blue - color1.blue) * color->mix.factor), 0, 1); - resolved_color->alpha = CLAMP (color1.alpha + ((color2.alpha - color1.alpha) * color->mix.factor), 0, 1); - return TRUE; + res.red = CLAMP (color1.red + ((color2.red - color1.red) * color->mix.factor), 0, 1); + res.green = CLAMP (color1.green + ((color2.green - color1.green) * color->mix.factor), 0, 1); + res.blue = CLAMP (color1.blue + ((color2.blue - color1.blue) * color->mix.factor), 0, 1); + res.alpha = CLAMP (color1.alpha + ((color2.alpha - color1.alpha) * color->mix.factor), 0, 1); + + value =_gtk_css_value_new_from_rgba (&res); } break; case COLOR_TYPE_WIN32: - return _gtk_win32_theme_color_resolve (color->win32.theme_class, + { + GdkRGBA res; + + if (!_gtk_win32_theme_color_resolve (color->win32.theme_class, color->win32.id, - resolved_color); + &res)) + return NULL; + + value = _gtk_css_value_new_from_rgba (&res); + } break; case COLOR_TYPE_CURRENT_COLOR: - return FALSE; + return NULL; break; default: g_assert_not_reached (); } - return FALSE; + if (value != NULL) + { + if (color->last_value != NULL && + gdk_rgba_equal (_gtk_css_value_get_rgba (color->last_value), + _gtk_css_value_get_rgba (value))) + { + _gtk_css_value_unref (value); + value = _gtk_css_value_ref (color->last_value); + } + else + { + if (color->last_value != NULL) + _gtk_css_value_unref (color->last_value); + color->last_value = _gtk_css_value_ref (value); + } + } + + return value; } /** @@ -684,7 +734,7 @@ gtk_symbolic_color_to_string (GtkSymbolicColor *color) switch (color->type) { case COLOR_TYPE_LITERAL: - s = gdk_rgba_to_string (&color->color); + s = gdk_rgba_to_string (_gtk_css_value_get_rgba (color->last_value)); break; case COLOR_TYPE_NAME: s = g_strconcat ("@", color->name, NULL); diff --git a/gtk/gtksymboliccolorprivate.h b/gtk/gtksymboliccolorprivate.h index a469626cc9..869af698a9 100644 --- a/gtk/gtksymboliccolorprivate.h +++ b/gtk/gtksymboliccolorprivate.h @@ -19,15 +19,15 @@ #define __GTK_SYMBOLIC_COLOR_PRIVATE_H__ #include "gtk/gtksymboliccolor.h" +#include "gtk/gtkcssvalueprivate.h" G_BEGIN_DECLS typedef GtkSymbolicColor * (* GtkSymbolicColorLookupFunc) (gpointer data, const char *name); -gboolean _gtk_symbolic_color_resolve_full (GtkSymbolicColor *color, +GtkCssValue * _gtk_symbolic_color_resolve_full (GtkSymbolicColor *color, GtkSymbolicColorLookupFunc func, - gpointer data, - GdkRGBA *resolved_color); + gpointer data); GtkSymbolicColor * _gtk_symbolic_color_get_current_color (void); diff --git a/gtk/gtkthemingbackground.c b/gtk/gtkthemingbackground.c index 1e21d2dcef..161cc5a8ee 100644 --- a/gtk/gtkthemingbackground.c +++ b/gtk/gtkthemingbackground.c @@ -165,7 +165,7 @@ _gtk_theming_background_paint (GtkThemingBackground *bg, double image_width, image_height; double width, height; - size = g_value_get_boxed (_gtk_style_context_peek_property (bg->context, "background-size")); + size = _gtk_css_value_get_background_size (_gtk_style_context_peek_property (bg->context, "background-size")); gtk_style_context_get (bg->context, bg->flags, "background-repeat", &hrepeat, NULL); @@ -338,7 +338,7 @@ _gtk_theming_background_init_context (GtkThemingBackground *bg) _gtk_theming_background_apply_clip (bg); _gtk_theming_background_apply_origin (bg); - bg->image = g_value_get_object (_gtk_style_context_peek_property (bg->context, "background-image")); + bg->image = _gtk_css_value_get_image (_gtk_style_context_peek_property (bg->context, "background-image")); } void diff --git a/gtk/gtkthemingengine.c b/gtk/gtkthemingengine.c index 662f1ceab5..d5eb10be74 100644 --- a/gtk/gtkthemingengine.c +++ b/gtk/gtkthemingengine.c @@ -338,7 +338,7 @@ _gtk_theming_engine_get_context (GtkThemingEngine *engine) return engine->priv->context; } -const GValue * +GtkCssValue * _gtk_theming_engine_peek_property (GtkThemingEngine *engine, const char *property_name) { @@ -1820,17 +1820,17 @@ render_frame_internal (GtkThemingEngine *engine, render_border (cr, &border_box, &border, hidden_side, colors, border_style); } - border_style[0] = g_value_get_enum (_gtk_theming_engine_peek_property (engine, "outline-style")); + border_style[0] = _gtk_css_value_get_border_style (_gtk_theming_engine_peek_property (engine, "outline-style")); if (border_style[0] != GTK_BORDER_STYLE_NONE) { int offset; border_style[1] = border_style[2] = border_style[3] = border_style[0]; - border.top = g_value_get_int (_gtk_theming_engine_peek_property (engine, "outline-width")); + border.top = _gtk_css_value_get_int (_gtk_theming_engine_peek_property (engine, "outline-width")); border.left = border.right = border.bottom = border.top; - colors[0] = *(GdkRGBA *) g_value_get_boxed (_gtk_theming_engine_peek_property (engine, "outline-color")); + colors[0] = *_gtk_css_value_get_rgba (_gtk_theming_engine_peek_property (engine, "outline-color")); colors[3] = colors[2] = colors[1] = colors[0]; - offset = g_value_get_int (_gtk_theming_engine_peek_property (engine, "outline-offset")); + offset = _gtk_css_value_get_int (_gtk_theming_engine_peek_property (engine, "outline-offset")); /* reinit box here - outlines don't have a border radius */ _gtk_rounded_box_init_rect (&border_box, x, y, width, height); diff --git a/gtk/gtkthemingengineprivate.h b/gtk/gtkthemingengineprivate.h index 64dbfaf66f..63d0cfab00 100644 --- a/gtk/gtkthemingengineprivate.h +++ b/gtk/gtkthemingengineprivate.h @@ -20,13 +20,14 @@ #include #include "gtk/gtkthemingengine.h" +#include "gtk/gtkcssvalueprivate.h" void _gtk_theming_engine_paint_spinner (cairo_t *cr, gdouble radius, gdouble progress, GdkRGBA *color); -const GValue *_gtk_theming_engine_peek_property (GtkThemingEngine *engine, +GtkCssValue *_gtk_theming_engine_peek_property (GtkThemingEngine *engine, const char *property_name); double _gtk_theming_engine_get_number (GtkThemingEngine *engine, const char *property_name,