X-Git-Url: http://pileus.org/git/?a=blobdiff_plain;f=gtk%2Fgtkcssstylefuncs.c;h=af1c1b1b6f41262fdd95bc713c15bdbcf595ebde;hb=HEAD;hp=6078d7642775fb75cd53b5bab7affeec0e973e11;hpb=5c10f8ce8c17a181aa989df9a2b325d598004d7d;p=~andy%2Fgtk diff --git a/gtk/gtkcssstylefuncs.c b/gtk/gtkcssstylefuncs.c index 6078d7642..af1c1b1b6 100644 --- a/gtk/gtkcssstylefuncs.c +++ b/gtk/gtkcssstylefuncs.c @@ -12,9 +12,7 @@ * 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., 59 Temple Place - Suite 330, - * Boston, MA 02111-1307, USA. + * License along with this library. If not, see . */ #include "config.h" @@ -29,18 +27,21 @@ #include #include -#include "gtkanimationdescription.h" +#include "gtkcsscolorvalueprivate.h" #include "gtkcssimagegradientprivate.h" #include "gtkcssprovider.h" +#include "gtkcssrgbavalueprivate.h" +#include "gtkcsstypedvalueprivate.h" #include "gtkcsstypesprivate.h" -#include "gtkgradient.h" #include "gtkprivatetypebuiltins.h" -#include "gtkshadowprivate.h" #include "gtkstylecontextprivate.h" #include "gtkthemingengine.h" #include "gtktypebuiltins.h" #include "gtkwin32themeprivate.h" +#include "deprecated/gtkgradientprivate.h" +#include "deprecated/gtksymboliccolorprivate.h" + /* this is in case round() is not provided by the compiler, * such as in the case of C89 compilers, like MSVC */ @@ -50,14 +51,15 @@ static GHashTable *parse_funcs = NULL; static GHashTable *print_funcs = NULL; static GHashTable *compute_funcs = NULL; -typedef gboolean (* GtkStyleParseFunc) (GtkCssParser *parser, - GFile *base, - GValue *value); -typedef void (* GtkStylePrintFunc) (const GValue *value, - GString *string); -typedef void (* GtkStyleComputeFunc) (GValue *computed, - GtkStyleContext *context, - const GValue *specified); +typedef gboolean (* GtkStyleParseFunc) (GtkCssParser *parser, + GValue *value); +typedef void (* GtkStylePrintFunc) (const GValue *value, + GString *string); +typedef GtkCssValue * (* GtkStyleComputeFunc) (GtkStyleProviderPrivate *provider, + GtkCssComputedValues *values, + GtkCssComputedValues *parent_values, + GtkCssValue *specified, + GtkCssDependencies *dependencies); static void register_conversion_function (GType type, @@ -165,21 +167,14 @@ enum_print (int value, static gboolean rgba_value_parse (GtkCssParser *parser, - GFile *base, GValue *value) { GtkSymbolicColor *symbolic; GdkRGBA rgba; - if (_gtk_css_parser_try (parser, "currentcolor", TRUE)) - { - g_value_unset (value); - g_value_init (value, GTK_TYPE_CSS_SPECIAL_VALUE); - g_value_set_enum (value, GTK_CSS_CURRENT_COLOR); - return TRUE; - } + G_GNUC_BEGIN_IGNORE_DEPRECATIONS; - symbolic = _gtk_css_parser_read_symbolic_color (parser); + symbolic = _gtk_css_symbolic_value_new (parser); if (symbolic == NULL) return FALSE; @@ -195,6 +190,8 @@ rgba_value_parse (GtkCssParser *parser, g_value_take_boxed (value, symbolic); } + G_GNUC_END_IGNORE_DEPRECATIONS; + return TRUE; } @@ -214,40 +211,56 @@ rgba_value_print (const GValue *value, } } -static void -rgba_value_compute (GValue *computed, - GtkStyleContext *context, - const GValue *specified) +static GtkCssValue * +rgba_value_compute (GtkStyleProviderPrivate *provider, + GtkCssComputedValues *values, + GtkCssComputedValues *parent_values, + GtkCssValue *specified, + GtkCssDependencies *dependencies) { - GdkRGBA rgba, white = { 1, 1, 1, 1 }; + GdkRGBA white = { 1, 1, 1, 1 }; + const GValue *value; - if (G_VALUE_HOLDS (specified, GTK_TYPE_CSS_SPECIAL_VALUE)) - { - g_assert (g_value_get_enum (specified) == GTK_CSS_CURRENT_COLOR); - g_value_copy (_gtk_style_context_peek_property (context, "color"), computed); - } - else if (G_VALUE_HOLDS (specified, GTK_TYPE_SYMBOLIC_COLOR)) + value = _gtk_css_typed_value_get (specified); + + if (G_VALUE_HOLDS (value, GTK_TYPE_SYMBOLIC_COLOR)) { - if (_gtk_style_context_resolve_color (context, - g_value_get_boxed (specified), - &rgba)) - g_value_set_boxed (computed, &rgba); + GtkSymbolicColor *symbolic = g_value_get_boxed (value); + GtkCssValue *val; + GValue new_value = G_VALUE_INIT; + GdkRGBA rgba; + + val = _gtk_css_color_value_resolve (_gtk_symbolic_color_get_css_value (symbolic), + provider, + _gtk_css_computed_values_get_value (values, GTK_CSS_PROPERTY_COLOR), + GTK_CSS_DEPENDS_ON_COLOR, + dependencies); + if (val != NULL) + { + rgba = *_gtk_css_rgba_value_get_rgba (val); + _gtk_css_value_unref (val); + } else - g_value_set_boxed (computed, &white); + rgba = white; + + g_value_init (&new_value, GDK_TYPE_RGBA); + g_value_set_boxed (&new_value, &rgba); + return _gtk_css_typed_value_new_take (&new_value); } else - g_value_copy (specified, computed); + return _gtk_css_value_ref (specified); } static gboolean color_value_parse (GtkCssParser *parser, - GFile *base, GValue *value) { GtkSymbolicColor *symbolic; GdkRGBA rgba; - symbolic = _gtk_css_parser_read_symbolic_color (parser); + G_GNUC_BEGIN_IGNORE_DEPRECATIONS; + + symbolic = _gtk_css_symbolic_value_new (parser); if (symbolic == NULL) return FALSE; @@ -268,6 +281,8 @@ color_value_parse (GtkCssParser *parser, g_value_take_boxed (value, symbolic); } + G_GNUC_END_IGNORE_DEPRECATIONS; + return TRUE; } @@ -287,39 +302,52 @@ color_value_print (const GValue *value, } } -static void -color_value_compute (GValue *computed, - GtkStyleContext *context, - const GValue *specified) +static GtkCssValue * +color_value_compute (GtkStyleProviderPrivate *provider, + GtkCssComputedValues *values, + GtkCssComputedValues *parent_values, + GtkCssValue *specified, + GtkCssDependencies *dependencies) { - GdkRGBA rgba; GdkColor color = { 0, 65535, 65535, 65535 }; + const GValue *value; - if (G_VALUE_HOLDS (specified, GTK_TYPE_SYMBOLIC_COLOR)) + value = _gtk_css_typed_value_get (specified); + + if (G_VALUE_HOLDS (value, GTK_TYPE_SYMBOLIC_COLOR)) { - if (_gtk_style_context_resolve_color (context, - g_value_get_boxed (specified), - &rgba)) + GValue new_value = G_VALUE_INIT; + GtkCssValue *val; + + val = _gtk_css_color_value_resolve (_gtk_symbolic_color_get_css_value (g_value_get_boxed (value)), + provider, + _gtk_css_computed_values_get_value (values, GTK_CSS_PROPERTY_COLOR), + GTK_CSS_DEPENDS_ON_COLOR, + dependencies); + if (val != NULL) { - color.red = rgba.red * 65535. + 0.5; - color.green = rgba.green * 65535. + 0.5; - color.blue = rgba.blue * 65535. + 0.5; + const GdkRGBA *rgba = _gtk_css_rgba_value_get_rgba (val); + color.red = rgba->red * 65535. + 0.5; + color.green = rgba->green * 65535. + 0.5; + color.blue = rgba->blue * 65535. + 0.5; + _gtk_css_value_unref (val); } - g_value_set_boxed (computed, &color); + g_value_init (&new_value, GDK_TYPE_COLOR); + g_value_set_boxed (&new_value, &color); + return _gtk_css_typed_value_new_take (&new_value); } else - g_value_copy (specified, computed); + return _gtk_css_value_ref (specified); } static gboolean symbolic_color_value_parse (GtkCssParser *parser, - GFile *base, GValue *value) { GtkSymbolicColor *symbolic; - symbolic = _gtk_css_parser_read_symbolic_color (parser); + symbolic = _gtk_css_symbolic_value_new (parser); if (symbolic == NULL) return FALSE; @@ -333,6 +361,8 @@ symbolic_color_value_print (const GValue *value, { GtkSymbolicColor *symbolic = g_value_get_boxed (value); + G_GNUC_BEGIN_IGNORE_DEPRECATIONS; + if (symbolic == NULL) g_string_append (string, "none"); else @@ -341,11 +371,12 @@ symbolic_color_value_print (const GValue *value, g_string_append (string, s); g_free (s); } + + G_GNUC_END_IGNORE_DEPRECATIONS; } static gboolean font_description_value_parse (GtkCssParser *parser, - GFile *base, GValue *value) { PangoFontDescription *font_desc; @@ -387,7 +418,6 @@ font_description_value_print (const GValue *value, static gboolean boolean_value_parse (GtkCssParser *parser, - GFile *base, GValue *value) { if (_gtk_css_parser_try (parser, "true", TRUE) || @@ -421,14 +451,13 @@ boolean_value_print (const GValue *value, static gboolean int_value_parse (GtkCssParser *parser, - GFile *base, GValue *value) { gint i; if (_gtk_css_parser_begins_with (parser, '-')) { - int res = _gtk_win32_theme_int_parse (parser, base, &i); + int res = _gtk_win32_theme_int_parse (parser, &i); if (res >= 0) { g_value_set_int (value, i); @@ -456,7 +485,6 @@ int_value_print (const GValue *value, static gboolean uint_value_parse (GtkCssParser *parser, - GFile *base, GValue *value) { guint u; @@ -480,7 +508,6 @@ uint_value_print (const GValue *value, static gboolean double_value_parse (GtkCssParser *parser, - GFile *base, GValue *value) { gdouble d; @@ -504,7 +531,6 @@ double_value_print (const GValue *value, static gboolean float_value_parse (GtkCssParser *parser, - GFile *base, GValue *value) { gdouble d; @@ -528,7 +554,6 @@ float_value_print (const GValue *value, static gboolean string_value_parse (GtkCssParser *parser, - GFile *base, GValue *value) { char *str = _gtk_css_parser_read_string (parser); @@ -549,7 +574,6 @@ string_value_print (const GValue *value, static gboolean theming_engine_value_parse (GtkCssParser *parser, - GFile *base, GValue *value) { GtkThemingEngine *engine; @@ -601,46 +625,8 @@ theming_engine_value_print (const GValue *value, } } -static gboolean -animation_description_value_parse (GtkCssParser *parser, - GFile *base, - GValue *value) -{ - GtkAnimationDescription *desc; - char *str; - - str = _gtk_css_parser_read_value (parser); - if (str == NULL) - return FALSE; - - desc = _gtk_animation_description_from_string (str); - g_free (str); - - if (desc == NULL) - { - _gtk_css_parser_error (parser, "Invalid animation description"); - return FALSE; - } - - g_value_take_boxed (value, desc); - return TRUE; -} - -static void -animation_description_value_print (const GValue *value, - GString *string) -{ - GtkAnimationDescription *desc = g_value_get_boxed (value); - - if (desc == NULL) - g_string_append (string, "none"); - else - _gtk_animation_description_print (desc, string); -} - static gboolean border_value_parse (GtkCssParser *parser, - GFile *base, GValue *value) { GtkBorder border = { 0, }; @@ -653,7 +639,7 @@ border_value_parse (GtkCssParser *parser, { /* These are strictly speaking signed, but we want to be able to use them for unsigned types too, as the actual ranges of values make this safe */ - int res = _gtk_win32_theme_int_parse (parser, base, &numbers[i]); + int res = _gtk_win32_theme_int_parse (parser, &numbers[i]); if (res == 0) /* Parse error, report */ return FALSE; @@ -711,7 +697,6 @@ border_value_print (const GValue *value, GString *string) static gboolean gradient_value_parse (GtkCssParser *parser, - GFile *base, GValue *value) { GtkGradient *gradient; @@ -730,6 +715,8 @@ gradient_value_print (const GValue *value, { GtkGradient *gradient = g_value_get_boxed (value); + G_GNUC_BEGIN_IGNORE_DEPRECATIONS; + if (gradient == NULL) g_string_append (string, "none"); else @@ -738,11 +725,12 @@ gradient_value_print (const GValue *value, g_string_append (string, s); g_free (s); } + + G_GNUC_END_IGNORE_DEPRECATIONS; } static gboolean pattern_value_parse (GtkCssParser *parser, - GFile *base, GValue *value) { if (_gtk_css_parser_try (parser, "none", TRUE)) @@ -753,7 +741,7 @@ pattern_value_parse (GtkCssParser *parser, { g_value_unset (value); g_value_init (value, GTK_TYPE_GRADIENT); - return gradient_value_parse (parser, base, value); + return gradient_value_parse (parser, value); } else { @@ -766,7 +754,7 @@ pattern_value_parse (GtkCssParser *parser, cairo_t *cr; cairo_matrix_t matrix; - file = _gtk_css_parser_read_url (parser, base); + file = _gtk_css_parser_read_url (parser); if (file == NULL) return FALSE; @@ -861,197 +849,43 @@ pattern_value_print (const GValue *value, } surface_print (surface, string); break; - case CAIRO_PATTERN_TYPE_SOLID: case CAIRO_PATTERN_TYPE_LINEAR: case CAIRO_PATTERN_TYPE_RADIAL: + g_string_append (string, "none /* FIXME: add support for printing gradients */"); + break; + case CAIRO_PATTERN_TYPE_SOLID: default: g_assert_not_reached (); break; } } -static void -pattern_value_compute (GValue *computed, - GtkStyleContext *context, - const GValue *specified) +static GtkCssValue * +pattern_value_compute (GtkStyleProviderPrivate *provider, + GtkCssComputedValues *values, + GtkCssComputedValues *parent_values, + GtkCssValue *specified, + GtkCssDependencies *dependencies) { - if (G_VALUE_HOLDS (specified, GTK_TYPE_GRADIENT)) + const GValue *value = _gtk_css_typed_value_get (specified); + + if (G_VALUE_HOLDS (value, GTK_TYPE_GRADIENT)) { + GValue new_value = G_VALUE_INIT; cairo_pattern_t *gradient; - gradient = gtk_gradient_resolve_for_context (g_value_get_boxed (specified), context); - - g_value_take_boxed (computed, gradient); - } - else - g_value_copy (specified, computed); -} - -static gboolean -shadow_value_parse (GtkCssParser *parser, - GFile *base, - GValue *value) -{ - gboolean have_inset, have_color, have_lengths; - gdouble hoffset, voffset, blur, spread; - GtkSymbolicColor *color; - GtkShadow *shadow; - guint i; - - if (_gtk_css_parser_try (parser, "none", TRUE)) - return TRUE; - - shadow = _gtk_shadow_new (); - - do - { - have_inset = have_lengths = have_color = FALSE; - - for (i = 0; i < 3; i++) - { - if (!have_inset && - _gtk_css_parser_try (parser, "inset", TRUE)) - { - have_inset = TRUE; - continue; - } - - if (!have_lengths && - _gtk_css_parser_try_double (parser, &hoffset)) - { - have_lengths = TRUE; - - if (!_gtk_css_parser_try_double (parser, &voffset)) - { - _gtk_css_parser_error (parser, "Horizontal and vertical offsets are required"); - _gtk_shadow_unref (shadow); - return FALSE; - } - - if (!_gtk_css_parser_try_double (parser, &blur)) - blur = 0; - - if (!_gtk_css_parser_try_double (parser, &spread)) - spread = 0; - - continue; - } - - if (!have_color) - { - have_color = TRUE; - - /* XXX: the color is optional and UA-defined if it's missing, - * but it doesn't really make sense for us... - */ - color = _gtk_css_parser_read_symbolic_color (parser); - - if (color == NULL) - { - _gtk_shadow_unref (shadow); - return FALSE; - } - } - } - - if (!have_color || !have_lengths) - { - _gtk_css_parser_error (parser, "Must specify at least color and offsets"); - _gtk_shadow_unref (shadow); - return FALSE; - } - - _gtk_shadow_append (shadow, - hoffset, voffset, - blur, spread, - have_inset, color); - - gtk_symbolic_color_unref (color); + gradient = _gtk_gradient_resolve_full (g_value_get_boxed (value), provider, values, parent_values, dependencies); + g_value_init (&new_value, CAIRO_GOBJECT_TYPE_PATTERN); + g_value_take_boxed (&new_value, gradient); + return _gtk_css_typed_value_new_take (&new_value); } - while (_gtk_css_parser_try (parser, ",", TRUE)); - - g_value_take_boxed (value, shadow); - return TRUE; -} - -static void -shadow_value_print (const GValue *value, - GString *string) -{ - GtkShadow *shadow; - - shadow = g_value_get_boxed (value); - - if (shadow == NULL) - g_string_append (string, "none"); else - _gtk_shadow_print (shadow, string); -} - -static void -shadow_value_compute (GValue *computed, - GtkStyleContext *context, - const GValue *specified) -{ - GtkShadow *shadow; - - shadow = g_value_get_boxed (specified); - if (shadow) - shadow = _gtk_shadow_resolve (shadow, context); - - g_value_take_boxed (computed, shadow); -} - -static gboolean -border_image_repeat_value_parse (GtkCssParser *parser, - GFile *file, - GValue *value) -{ - GtkCssBorderImageRepeat image_repeat; - GtkCssBorderRepeatStyle styles[2]; - gint i, v; - - for (i = 0; i < 2; i++) - { - if (_gtk_css_parser_try_enum (parser, GTK_TYPE_CSS_BORDER_REPEAT_STYLE, &v)) - styles[i] = v; - else if (i == 0) - { - styles[1] = styles[0] = GTK_CSS_REPEAT_STYLE_STRETCH; - break; - } - else - styles[i] = styles[0]; - } - - image_repeat.hrepeat = styles[0]; - image_repeat.vrepeat = styles[1]; - - g_value_set_boxed (value, &image_repeat); - - return TRUE; -} - -static void -border_image_repeat_value_print (const GValue *value, - GString *string) -{ - GtkCssBorderImageRepeat *image_repeat; - - image_repeat = g_value_get_boxed (value); - - enum_print (image_repeat->hrepeat, GTK_TYPE_CSS_BORDER_REPEAT_STYLE, string); - if (image_repeat->hrepeat != image_repeat->vrepeat) - { - g_string_append (string, " "); - enum_print (image_repeat->vrepeat, GTK_TYPE_CSS_BORDER_REPEAT_STYLE, string); - } + return _gtk_css_value_ref (specified); } static gboolean enum_value_parse (GtkCssParser *parser, - GFile *base, GValue *value) { int v; @@ -1074,7 +908,6 @@ enum_value_print (const GValue *value, static gboolean flags_value_parse (GtkCssParser *parser, - GFile *base, GValue *value) { GFlagsClass *flags_class; @@ -1200,10 +1033,6 @@ gtk_css_style_funcs_init (void) theming_engine_value_parse, theming_engine_value_print, NULL); - register_conversion_function (GTK_TYPE_ANIMATION_DESCRIPTION, - animation_description_value_parse, - animation_description_value_print, - NULL); register_conversion_function (GTK_TYPE_BORDER, border_value_parse, border_value_print, @@ -1216,14 +1045,6 @@ gtk_css_style_funcs_init (void) pattern_value_parse, pattern_value_print, pattern_value_compute); - register_conversion_function (GTK_TYPE_CSS_BORDER_IMAGE_REPEAT, - border_image_repeat_value_parse, - border_image_repeat_value_print, - NULL); - register_conversion_function (GTK_TYPE_SHADOW, - shadow_value_parse, - shadow_value_print, - shadow_value_compute); register_conversion_function (G_TYPE_ENUM, enum_value_parse, enum_value_print, @@ -1238,7 +1059,6 @@ gtk_css_style_funcs_init (void) * _gtk_css_style_parse_value: * @value: the value to parse into. Must be a valid initialized #GValue * @parser: the parser to parse from - * @base: the base URL for @parser * * This is the generic parsing function used for CSS values. If the * function fails to parse a value, it will emit an error on @parser, @@ -1248,8 +1068,7 @@ gtk_css_style_funcs_init (void) **/ gboolean _gtk_css_style_parse_value (GValue *value, - GtkCssParser *parser, - GFile *base) + GtkCssParser *parser) { GtkStyleParseFunc func; @@ -1272,7 +1091,7 @@ _gtk_css_style_parse_value (GValue *value, return FALSE; } - return (*func) (parser, base, value); + return (*func) (parser, value); } /** @@ -1310,37 +1129,47 @@ _gtk_css_style_print_value (const GValue *value, /** * _gtk_css_style_compute_value: - * @computed: (out): a value to be filled with the result - * @context: the context to use for computing the value + * @provider: Style provider to look up information from + * @values: The values to compute for + * @parent_values: Values to look up inherited values from + * @target_type: Type the resulting value should have * @specified: the value to use for the computation + * @dependencies: (out): Value initialized with 0 to take the dependencies + * of the returned value * * Converts the @specified value into the @computed value using the * information in @context. The values must have matching types, ie * @specified must be a result of a call to * _gtk_css_style_parse_value() with the same type as @computed. + * + * Returns: the resulting value **/ -void -_gtk_css_style_compute_value (GValue *computed, - GtkStyleContext *context, - const GValue *specified) +GtkCssValue * +_gtk_css_style_compute_value (GtkStyleProviderPrivate *provider, + GtkCssComputedValues *values, + GtkCssComputedValues *parent_values, + GType target_type, + GtkCssValue *specified, + GtkCssDependencies *dependencies) { 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_PROVIDER (provider), NULL); + g_return_val_if_fail (GTK_IS_CSS_COMPUTED_VALUES (values), NULL); + g_return_val_if_fail (parent_values == NULL || GTK_IS_CSS_COMPUTED_VALUES (parent_values), NULL); + g_return_val_if_fail (*dependencies == 0, 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 (provider, values, parent_values, specified, dependencies); else - g_value_copy (specified, computed); + return _gtk_css_value_ref (specified); }