diff options
author | Benjamin Otte <otte@redhat.com> | 2012-01-01 18:14:51 +0100 |
---|---|---|
committer | Benjamin Otte <otte@redhat.com> | 2012-01-09 18:37:53 +0100 |
commit | 078fc725e0a83250ea7e1bf37dfc4f5f95b990c8 (patch) | |
tree | 76e9a84676859a8adc9040a25c91e886577599a6 /gtk/gtkstyleproperty.c | |
parent | f5fafb18c994106362b33ac990dde9030a67cd26 (diff) | |
download | gtk+-078fc725e0a83250ea7e1bf37dfc4f5f95b990c8.tar.gz |
css: Split generic parse/print functions out
It seems to be some sort of sport for me to split them out and merge
them back in...
Diffstat (limited to 'gtk/gtkstyleproperty.c')
-rw-r--r-- | gtk/gtkstyleproperty.c | 1328 |
1 files changed, 8 insertions, 1320 deletions
diff --git a/gtk/gtkstyleproperty.c b/gtk/gtkstyleproperty.c index acc8f91601..204e1e8d0d 100644 --- a/gtk/gtkstyleproperty.c +++ b/gtk/gtkstyleproperty.c @@ -32,6 +32,7 @@ #include "gtkcssprovider.h" #include "gtkcssparserprivate.h" #include "gtkcssshorthandpropertyprivate.h" +#include "gtkcssstylefuncsprivate.h" #include "gtkcssstylepropertyprivate.h" #include "gtkcsstypesprivate.h" #include "gtkintl.h" @@ -58,9 +59,6 @@ enum { PROP_VALUE_TYPE }; -static GHashTable *parse_funcs = NULL; -static GHashTable *print_funcs = NULL; - G_DEFINE_ABSTRACT_TYPE (GtkStyleProperty, _gtk_style_property, G_TYPE_OBJECT) static void @@ -155,17 +153,6 @@ _gtk_style_property_init (GtkStyleProperty *property) } static void -register_conversion_function (GType type, - GtkStyleParseFunc parse, - GtkStylePrintFunc print) -{ - if (parse) - g_hash_table_insert (parse_funcs, GSIZE_TO_POINTER (type), parse); - if (print) - g_hash_table_insert (print_funcs, GSIZE_TO_POINTER (type), print); -} - -static void string_append_double (GString *string, double d) { @@ -214,31 +201,6 @@ string_append_string (GString *str, /*** IMPLEMENTATIONS ***/ -static gboolean -enum_parse (GtkCssParser *parser, - GType type, - int *res) -{ - char *str; - - if (_gtk_css_parser_try_enum (parser, type, res)) - return TRUE; - - str = _gtk_css_parser_try_ident (parser, TRUE); - if (str == NULL) - { - _gtk_css_parser_error (parser, "Expected an identifier"); - return FALSE; - } - - _gtk_css_parser_error (parser, - "Unknown value '%s' for enum type '%s'", - str, g_type_name (type)); - g_free (str); - - return FALSE; -} - static void enum_print (int value, GType type, @@ -256,128 +218,6 @@ enum_print (int value, } static gboolean -rgba_value_parse (GtkCssParser *parser, - GFile *base, - GValue *value) -{ - GtkSymbolicColor *symbolic; - GdkRGBA rgba; - - symbolic = _gtk_css_parser_read_symbolic_color (parser); - if (symbolic == NULL) - return FALSE; - - if (gtk_symbolic_color_resolve (symbolic, NULL, &rgba)) - { - g_value_set_boxed (value, &rgba); - gtk_symbolic_color_unref (symbolic); - } - else - { - g_value_unset (value); - g_value_init (value, GTK_TYPE_SYMBOLIC_COLOR); - g_value_take_boxed (value, symbolic); - } - - return TRUE; -} - -static void -rgba_value_print (const GValue *value, - GString *string) -{ - const GdkRGBA *rgba = g_value_get_boxed (value); - - if (rgba == NULL) - g_string_append (string, "none"); - else - { - char *s = gdk_rgba_to_string (rgba); - g_string_append (string, s); - g_free (s); - } -} - -static gboolean -color_value_parse (GtkCssParser *parser, - GFile *base, - GValue *value) -{ - GtkSymbolicColor *symbolic; - GdkRGBA rgba; - - symbolic = _gtk_css_parser_read_symbolic_color (parser); - if (symbolic == NULL) - return FALSE; - - if (gtk_symbolic_color_resolve (symbolic, NULL, &rgba)) - { - GdkColor color; - - color.red = rgba.red * 65535. + 0.5; - color.green = rgba.green * 65535. + 0.5; - color.blue = rgba.blue * 65535. + 0.5; - - g_value_set_boxed (value, &color); - } - else - { - g_value_unset (value); - g_value_init (value, GTK_TYPE_SYMBOLIC_COLOR); - g_value_take_boxed (value, symbolic); - } - - return TRUE; -} - -static void -color_value_print (const GValue *value, - GString *string) -{ - const GdkColor *color = g_value_get_boxed (value); - - if (color == NULL) - g_string_append (string, "none"); - else - { - char *s = gdk_color_to_string (color); - g_string_append (string, s); - g_free (s); - } -} - -static gboolean -symbolic_color_value_parse (GtkCssParser *parser, - GFile *base, - GValue *value) -{ - GtkSymbolicColor *symbolic; - - symbolic = _gtk_css_parser_read_symbolic_color (parser); - if (symbolic == NULL) - return FALSE; - - g_value_take_boxed (value, symbolic); - return TRUE; -} - -static void -symbolic_color_value_print (const GValue *value, - GString *string) -{ - GtkSymbolicColor *symbolic = g_value_get_boxed (value); - - if (symbolic == NULL) - g_string_append (string, "none"); - else - { - char *s = gtk_symbolic_color_to_string (symbolic); - g_string_append (string, s); - g_free (s); - } -} - -static gboolean font_family_parse (GtkCssParser *parser, GFile *base, GValue *value) @@ -446,1046 +286,6 @@ font_family_value_print (const GValue *value, } static gboolean -font_description_value_parse (GtkCssParser *parser, - GFile *base, - GValue *value) -{ - PangoFontDescription *font_desc; - guint mask; - char *str; - - str = _gtk_css_parser_read_value (parser); - if (str == NULL) - return FALSE; - - font_desc = pango_font_description_from_string (str); - mask = pango_font_description_get_set_fields (font_desc); - /* These values are not really correct, - * but the fields must be set, so we set them to something */ - if ((mask & PANGO_FONT_MASK_FAMILY) == 0) - pango_font_description_set_family_static (font_desc, "Sans"); - if ((mask & PANGO_FONT_MASK_SIZE) == 0) - pango_font_description_set_size (font_desc, 10 * PANGO_SCALE); - g_free (str); - g_value_take_boxed (value, font_desc); - return TRUE; -} - -static void -font_description_value_print (const GValue *value, - GString *string) -{ - const PangoFontDescription *desc = g_value_get_boxed (value); - - if (desc == NULL) - g_string_append (string, "none"); - else - { - char *s = pango_font_description_to_string (desc); - g_string_append (string, s); - g_free (s); - } -} - -static gboolean -boolean_value_parse (GtkCssParser *parser, - GFile *base, - GValue *value) -{ - if (_gtk_css_parser_try (parser, "true", TRUE) || - _gtk_css_parser_try (parser, "1", TRUE)) - { - g_value_set_boolean (value, TRUE); - return TRUE; - } - else if (_gtk_css_parser_try (parser, "false", TRUE) || - _gtk_css_parser_try (parser, "0", TRUE)) - { - g_value_set_boolean (value, FALSE); - return TRUE; - } - else - { - _gtk_css_parser_error (parser, "Expected a boolean value"); - return FALSE; - } -} - -static void -boolean_value_print (const GValue *value, - GString *string) -{ - if (g_value_get_boolean (value)) - g_string_append (string, "true"); - else - g_string_append (string, "false"); -} - -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); - if (res >= 0) - { - g_value_set_int (value, i); - return res > 0; - } - /* < 0 => continue */ - } - - if (!_gtk_css_parser_try_int (parser, &i)) - { - _gtk_css_parser_error (parser, "Expected a valid integer value"); - return FALSE; - } - - g_value_set_int (value, i); - return TRUE; -} - -static void -int_value_print (const GValue *value, - GString *string) -{ - g_string_append_printf (string, "%d", g_value_get_int (value)); -} - -static gboolean -uint_value_parse (GtkCssParser *parser, - GFile *base, - GValue *value) -{ - guint u; - - if (!_gtk_css_parser_try_uint (parser, &u)) - { - _gtk_css_parser_error (parser, "Expected a valid unsigned value"); - return FALSE; - } - - g_value_set_uint (value, u); - return TRUE; -} - -static void -uint_value_print (const GValue *value, - GString *string) -{ - g_string_append_printf (string, "%u", g_value_get_uint (value)); -} - -static gboolean -double_value_parse (GtkCssParser *parser, - GFile *base, - GValue *value) -{ - gdouble d; - - if (!_gtk_css_parser_try_double (parser, &d)) - { - _gtk_css_parser_error (parser, "Expected a number"); - return FALSE; - } - - g_value_set_double (value, d); - return TRUE; -} - -static void -double_value_print (const GValue *value, - GString *string) -{ - string_append_double (string, g_value_get_double (value)); -} - -static gboolean -float_value_parse (GtkCssParser *parser, - GFile *base, - GValue *value) -{ - gdouble d; - - if (!_gtk_css_parser_try_double (parser, &d)) - { - _gtk_css_parser_error (parser, "Expected a number"); - return FALSE; - } - - g_value_set_float (value, d); - return TRUE; -} - -static void -float_value_print (const GValue *value, - GString *string) -{ - string_append_double (string, g_value_get_float (value)); -} - -static gboolean -string_value_parse (GtkCssParser *parser, - GFile *base, - GValue *value) -{ - char *str = _gtk_css_parser_read_string (parser); - - if (str == NULL) - return FALSE; - - g_value_take_string (value, str); - return TRUE; -} - -static void -string_value_print (const GValue *value, - GString *str) -{ - string_append_string (str, g_value_get_string (value)); -} - -static gboolean -theming_engine_value_parse (GtkCssParser *parser, - GFile *base, - GValue *value) -{ - GtkThemingEngine *engine; - char *str; - - if (_gtk_css_parser_try (parser, "none", TRUE)) - { - g_value_set_object (value, gtk_theming_engine_load (NULL)); - return TRUE; - } - - str = _gtk_css_parser_try_ident (parser, TRUE); - if (str == NULL) - { - _gtk_css_parser_error (parser, "Expected a valid theme name"); - return FALSE; - } - - engine = gtk_theming_engine_load (str); - - if (engine == NULL) - { - _gtk_css_parser_error (parser, "Themeing engine '%s' not found", str); - g_free (str); - return FALSE; - } - - g_value_set_object (value, engine); - g_free (str); - return TRUE; -} - -static void -theming_engine_value_print (const GValue *value, - GString *string) -{ - GtkThemingEngine *engine; - char *name; - - engine = g_value_get_object (value); - if (engine == NULL) - g_string_append (string, "none"); - else - { - /* XXX: gtk_theming_engine_get_name()? */ - g_object_get (engine, "name", &name, NULL); - g_string_append (string, name ? name : "none"); - g_free (name); - } -} - -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, }; - guint i, numbers[4]; - - for (i = 0; i < G_N_ELEMENTS (numbers); i++) - { - if (_gtk_css_parser_begins_with (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, (int *)&numbers[i]); - - if (res == 0) /* Parse error, report */ - return FALSE; - - if (res < 0) /* Nothing known to expand */ - break; - } - else - { - if (!_gtk_css_parser_try_uint (parser, &numbers[i])) - break; - - /* XXX: shouldn't allow spaces here? */ - _gtk_css_parser_try (parser, "px", TRUE); - } - } - - if (i == 0) - { - _gtk_css_parser_error (parser, "Expected valid border"); - return FALSE; - } - - border.top = numbers[0]; - if (i > 1) - border.right = numbers[1]; - else - border.right = border.top; - if (i > 2) - border.bottom = numbers[2]; - else - border.bottom = border.top; - if (i > 3) - border.left = numbers[3]; - else - border.left = border.right; - - g_value_set_boxed (value, &border); - return TRUE; -} - -static void -border_value_print (const GValue *value, GString *string) -{ - const GtkBorder *border = g_value_get_boxed (value); - - if (border == NULL) - g_string_append (string, "none"); - else if (border->left != border->right) - g_string_append_printf (string, "%d %d %d %d", border->top, border->right, border->bottom, border->left); - else if (border->top != border->bottom) - g_string_append_printf (string, "%d %d %d", border->top, border->right, border->bottom); - else if (border->top != border->left) - g_string_append_printf (string, "%d %d", border->top, border->right); - else - g_string_append_printf (string, "%d", border->top); -} - -static gboolean -gradient_value_parse (GtkCssParser *parser, - GFile *base, - GValue *value) -{ - GtkGradient *gradient; - cairo_pattern_type_t type; - gdouble coords[6]; - guint i; - - if (!_gtk_css_parser_try (parser, "-gtk-gradient", TRUE)) - { - _gtk_css_parser_error (parser, - "Expected '-gtk-gradient'"); - return FALSE; - } - - if (!_gtk_css_parser_try (parser, "(", TRUE)) - { - _gtk_css_parser_error (parser, - "Expected '(' after '-gtk-gradient'"); - return FALSE; - } - - /* Parse gradient type */ - if (_gtk_css_parser_try (parser, "linear", TRUE)) - type = CAIRO_PATTERN_TYPE_LINEAR; - else if (_gtk_css_parser_try (parser, "radial", TRUE)) - type = CAIRO_PATTERN_TYPE_RADIAL; - else - { - _gtk_css_parser_error (parser, - "Gradient type must be 'radial' or 'linear'"); - return FALSE; - } - - /* Parse start/stop position parameters */ - for (i = 0; i < 2; i++) - { - if (! _gtk_css_parser_try (parser, ",", TRUE)) - { - _gtk_css_parser_error (parser, - "Expected ','"); - return FALSE; - } - - if (_gtk_css_parser_try (parser, "left", TRUE)) - coords[i * 3] = 0; - else if (_gtk_css_parser_try (parser, "right", TRUE)) - coords[i * 3] = 1; - else if (_gtk_css_parser_try (parser, "center", TRUE)) - coords[i * 3] = 0.5; - else if (!_gtk_css_parser_try_double (parser, &coords[i * 3])) - { - _gtk_css_parser_error (parser, - "Expected a valid X coordinate"); - return FALSE; - } - - if (_gtk_css_parser_try (parser, "top", TRUE)) - coords[i * 3 + 1] = 0; - else if (_gtk_css_parser_try (parser, "bottom", TRUE)) - coords[i * 3 + 1] = 1; - else if (_gtk_css_parser_try (parser, "center", TRUE)) - coords[i * 3 + 1] = 0.5; - else if (!_gtk_css_parser_try_double (parser, &coords[i * 3 + 1])) - { - _gtk_css_parser_error (parser, - "Expected a valid Y coordinate"); - return FALSE; - } - - if (type == CAIRO_PATTERN_TYPE_RADIAL) - { - /* Parse radius */ - if (! _gtk_css_parser_try (parser, ",", TRUE)) - { - _gtk_css_parser_error (parser, - "Expected ','"); - return FALSE; - } - - if (! _gtk_css_parser_try_double (parser, &coords[(i * 3) + 2])) - { - _gtk_css_parser_error (parser, - "Expected a numer for the radius"); - return FALSE; - } - } - } - - if (type == CAIRO_PATTERN_TYPE_LINEAR) - gradient = gtk_gradient_new_linear (coords[0], coords[1], coords[3], coords[4]); - else - gradient = gtk_gradient_new_radial (coords[0], coords[1], coords[2], - coords[3], coords[4], coords[5]); - - while (_gtk_css_parser_try (parser, ",", TRUE)) - { - GtkSymbolicColor *color; - gdouble position; - - if (_gtk_css_parser_try (parser, "from", TRUE)) - { - position = 0; - - if (!_gtk_css_parser_try (parser, "(", TRUE)) - { - gtk_gradient_unref (gradient); - _gtk_css_parser_error (parser, - "Expected '('"); - return FALSE; - } - - } - else if (_gtk_css_parser_try (parser, "to", TRUE)) - { - position = 1; - - if (!_gtk_css_parser_try (parser, "(", TRUE)) - { - gtk_gradient_unref (gradient); - _gtk_css_parser_error (parser, - "Expected '('"); - return FALSE; - } - - } - else if (_gtk_css_parser_try (parser, "color-stop", TRUE)) - { - if (!_gtk_css_parser_try (parser, "(", TRUE)) - { - gtk_gradient_unref (gradient); - _gtk_css_parser_error (parser, - "Expected '('"); - return FALSE; - } - - if (!_gtk_css_parser_try_double (parser, &position)) - { - gtk_gradient_unref (gradient); - _gtk_css_parser_error (parser, - "Expected a valid number"); - return FALSE; - } - - if (!_gtk_css_parser_try (parser, ",", TRUE)) - { - gtk_gradient_unref (gradient); - _gtk_css_parser_error (parser, - "Expected a comma"); - return FALSE; - } - } - else - { - gtk_gradient_unref (gradient); - _gtk_css_parser_error (parser, - "Not a valid color-stop definition"); - return FALSE; - } - - color = _gtk_css_parser_read_symbolic_color (parser); - if (color == NULL) - { - gtk_gradient_unref (gradient); - return FALSE; - } - - gtk_gradient_add_color_stop (gradient, position, color); - gtk_symbolic_color_unref (color); - - if (!_gtk_css_parser_try (parser, ")", TRUE)) - { - gtk_gradient_unref (gradient); - _gtk_css_parser_error (parser, - "Expected ')'"); - return FALSE; - } - } - - if (!_gtk_css_parser_try (parser, ")", TRUE)) - { - gtk_gradient_unref (gradient); - _gtk_css_parser_error (parser, - "Expected ')'"); - return FALSE; - } - - g_value_take_boxed (value, gradient); - return TRUE; -} - -static void -gradient_value_print (const GValue *value, - GString *string) -{ - GtkGradient *gradient = g_value_get_boxed (value); - - if (gradient == NULL) - g_string_append (string, "none"); - else - { - char *s = gtk_gradient_to_string (gradient); - g_string_append (string, s); - g_free (s); - } -} - -static GFile * -gtk_css_parse_url (GtkCssParser *parser, - GFile *base) -{ - gchar *path; - GFile *file; - - if (_gtk_css_parser_try (parser, "url", FALSE)) - { - if (!_gtk_css_parser_try (parser, "(", TRUE)) - { - _gtk_css_parser_skip_whitespace (parser); - if (_gtk_css_parser_try (parser, "(", TRUE)) - { - GError *error; - - error = g_error_new_literal (GTK_CSS_PROVIDER_ERROR, - GTK_CSS_PROVIDER_ERROR_DEPRECATED, - "Whitespace between 'url' and '(' is deprecated"); - - _gtk_css_parser_take_error (parser, error); - } - else - { - _gtk_css_parser_error (parser, "Expected '(' after 'url'"); - return NULL; - } - } - - path = _gtk_css_parser_read_string (parser); - if (path == NULL) - return NULL; - - if (!_gtk_css_parser_try (parser, ")", TRUE)) - { - _gtk_css_parser_error (parser, "No closing ')' found for 'url'"); - g_free (path); - return NULL; - } - } - else - { - path = _gtk_css_parser_try_name (parser, TRUE); - if (path == NULL) - { - _gtk_css_parser_error (parser, "Not a valid url"); - return NULL; - } - } - - file = g_file_resolve_relative_path (base, path); - g_free (path); - - return file; -} - -static gboolean -pattern_value_parse (GtkCssParser *parser, - GFile *base, - GValue *value) -{ - if (_gtk_css_parser_try (parser, "none", TRUE)) - { - /* nothing to do here */ - } - else if (_gtk_css_parser_begins_with (parser, '-')) - { - int res; - res = _gtk_win32_theme_part_parse (parser, base, value); - if (res >= 0) - return res > 0; - /* < 0 => continue */ - g_value_unset (value); - g_value_init (value, GTK_TYPE_GRADIENT); - return gradient_value_parse (parser, base, value); - } - else - { - GError *error = NULL; - gchar *path; - GdkPixbuf *pixbuf; - GFile *file; - cairo_surface_t *surface; - cairo_pattern_t *pattern; - cairo_t *cr; - cairo_matrix_t matrix; - - file = gtk_css_parse_url (parser, base); - if (file == NULL) - return FALSE; - - path = g_file_get_path (file); - g_object_unref (file); - - pixbuf = gdk_pixbuf_new_from_file (path, &error); - g_free (path); - if (pixbuf == NULL) - { - _gtk_css_parser_take_error (parser, error); - return FALSE; - } - - surface = cairo_image_surface_create (CAIRO_FORMAT_ARGB32, - gdk_pixbuf_get_width (pixbuf), - gdk_pixbuf_get_height (pixbuf)); - cr = cairo_create (surface); - gdk_cairo_set_source_pixbuf (cr, pixbuf, 0, 0); - cairo_paint (cr); - pattern = cairo_pattern_create_for_surface (surface); - - cairo_matrix_init_scale (&matrix, - gdk_pixbuf_get_width (pixbuf), - gdk_pixbuf_get_height (pixbuf)); - cairo_pattern_set_matrix (pattern, &matrix); - - cairo_surface_destroy (surface); - cairo_destroy (cr); - g_object_unref (pixbuf); - - g_value_take_boxed (value, pattern); - } - - return TRUE; -} - -static cairo_status_t -surface_write (void *closure, - const unsigned char *data, - unsigned int length) -{ - g_byte_array_append (closure, data, length); - - return CAIRO_STATUS_SUCCESS; -} - -static void -surface_print (cairo_surface_t *surface, - GString * string) -{ -#if CAIRO_HAS_PNG_FUNCTIONS - GByteArray *array; - char *base64; - - array = g_byte_array_new (); - cairo_surface_write_to_png_stream (surface, surface_write, array); - base64 = g_base64_encode (array->data, array->len); - g_byte_array_free (array, TRUE); - - g_string_append (string, "url(\"data:image/png;base64,"); - g_string_append (string, base64); - g_string_append (string, "\")"); - - g_free (base64); -#else - g_string_append (string, "none /* you need cairo png functions enabled to make this work */"); -#endif -} - -static void -pattern_value_print (const GValue *value, - GString *string) -{ - cairo_pattern_t *pattern; - cairo_surface_t *surface; - - pattern = g_value_get_boxed (value); - - if (pattern == NULL) - { - g_string_append (string, "none"); - return; - } - - switch (cairo_pattern_get_type (pattern)) - { - case CAIRO_PATTERN_TYPE_SURFACE: - if (cairo_pattern_get_surface (pattern, &surface) != CAIRO_STATUS_SUCCESS) - { - g_assert_not_reached (); - } - surface_print (surface, string); - break; - case CAIRO_PATTERN_TYPE_SOLID: - case CAIRO_PATTERN_TYPE_LINEAR: - case CAIRO_PATTERN_TYPE_RADIAL: - default: - g_assert_not_reached (); - break; - } -} - -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; - - shadow = _gtk_shadow_new (); - - if (_gtk_css_parser_try (parser, "none", TRUE)) - return TRUE; - - 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); - - } - 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 gboolean -background_repeat_value_parse (GtkCssParser *parser, - GFile *file, - GValue *value) -{ - GtkCssBackgroundRepeat repeat; - int style; - - if (!enum_parse (parser, GTK_TYPE_CSS_BACKGROUND_REPEAT_STYLE, &style)) - return FALSE; - - repeat.repeat = style; - - g_value_set_boxed (value, &repeat); - - return TRUE; -} - -static void -background_repeat_value_print (const GValue *value, - GString *string) -{ - GtkCssBackgroundRepeat *repeat; - - repeat = g_value_get_boxed (value); - - enum_print (repeat->repeat, GTK_TYPE_CSS_BACKGROUND_REPEAT_STYLE, string); -} - -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); - } -} - -static gboolean -enum_value_parse (GtkCssParser *parser, - GFile *base, - GValue *value) -{ - int v; - - if (enum_parse (parser, G_VALUE_TYPE (value), &v)) - { - g_value_set_enum (value, v); - return TRUE; - } - - return FALSE; -} - -static void -enum_value_print (const GValue *value, - GString *string) -{ - enum_print (g_value_get_enum (value), G_VALUE_TYPE (value), string); -} - -static gboolean -flags_value_parse (GtkCssParser *parser, - GFile *base, - GValue *value) -{ - GFlagsClass *flags_class; - GFlagsValue *flag_value; - guint flags = 0; - char *str; - - flags_class = g_type_class_ref (G_VALUE_TYPE (value)); - - do { - str = _gtk_css_parser_try_ident (parser, TRUE); - if (str == NULL) - { - _gtk_css_parser_error (parser, "Expected an identifier"); - g_type_class_unref (flags_class); - return FALSE; - } - - flag_value = g_flags_get_value_by_nick (flags_class, str); - if (!flag_value) - { - _gtk_css_parser_error (parser, - "Unknown flag value '%s' for type '%s'", - str, g_type_name (G_VALUE_TYPE (value))); - /* XXX Do we want to return FALSE here? We can get - * forward-compatibility for new values this way - */ - g_free (str); - g_type_class_unref (flags_class); - return FALSE; - } - - g_free (str); - } - while (_gtk_css_parser_try (parser, ",", FALSE)); - - g_type_class_unref (flags_class); - - g_value_set_enum (value, flags); - - return TRUE; -} - -static void -flags_value_print (const GValue *value, - GString *string) -{ - GFlagsClass *flags_class; - guint i, flags; - - flags_class = g_type_class_ref (G_VALUE_TYPE (value)); - flags = g_value_get_flags (value); - - for (i = 0; i < flags_class->n_values; i++) - { - GFlagsValue *flags_value = &flags_class->values[i]; - - if (flags & flags_value->value) - { - if (string->len != 0) - g_string_append (string, ", "); - - g_string_append (string, flags_value->value_nick); - } - } - - g_type_class_unref (flags_class); -} - -static gboolean bindings_value_parse (GtkCssParser *parser, GFile *base, GValue *value) @@ -1595,90 +395,15 @@ border_corner_radius_value_print (const GValue *value, /*** API ***/ -static void -css_string_funcs_init (void) -{ - if (G_LIKELY (parse_funcs != NULL)) - return; - - parse_funcs = g_hash_table_new (NULL, NULL); - print_funcs = g_hash_table_new (NULL, NULL); - - register_conversion_function (GDK_TYPE_RGBA, - rgba_value_parse, - rgba_value_print); - register_conversion_function (GDK_TYPE_COLOR, - color_value_parse, - color_value_print); - register_conversion_function (GTK_TYPE_SYMBOLIC_COLOR, - symbolic_color_value_parse, - symbolic_color_value_print); - register_conversion_function (PANGO_TYPE_FONT_DESCRIPTION, - font_description_value_parse, - font_description_value_print); - register_conversion_function (G_TYPE_BOOLEAN, - boolean_value_parse, - boolean_value_print); - register_conversion_function (G_TYPE_INT, - int_value_parse, - int_value_print); - register_conversion_function (G_TYPE_UINT, - uint_value_parse, - uint_value_print); - register_conversion_function (G_TYPE_DOUBLE, - double_value_parse, - double_value_print); - register_conversion_function (G_TYPE_FLOAT, - float_value_parse, - float_value_print); - register_conversion_function (G_TYPE_STRING, - string_value_parse, - string_value_print); - register_conversion_function (GTK_TYPE_THEMING_ENGINE, - theming_engine_value_parse, - theming_engine_value_print); - register_conversion_function (GTK_TYPE_ANIMATION_DESCRIPTION, - animation_description_value_parse, - animation_description_value_print); - register_conversion_function (GTK_TYPE_BORDER, - border_value_parse, - border_value_print); - register_conversion_function (GTK_TYPE_GRADIENT, - gradient_value_parse, - gradient_value_print); - register_conversion_function (CAIRO_GOBJECT_TYPE_PATTERN, - pattern_value_parse, - pattern_value_print); - register_conversion_function (GTK_TYPE_CSS_BORDER_IMAGE_REPEAT, - border_image_repeat_value_parse, - border_image_repeat_value_print); - register_conversion_function (GTK_TYPE_SHADOW, - shadow_value_parse, - shadow_value_print); - register_conversion_function (G_TYPE_ENUM, - enum_value_parse, - enum_value_print); - register_conversion_function (G_TYPE_FLAGS, - flags_value_parse, - flags_value_print); - register_conversion_function (GTK_TYPE_CSS_BACKGROUND_REPEAT, - background_repeat_value_parse, - background_repeat_value_print); -} - gboolean _gtk_style_property_parse_value (GtkStyleProperty *property, GValue *value, GtkCssParser *parser, GFile *base) { - GtkStyleParseFunc func; - g_return_val_if_fail (value != NULL, FALSE); g_return_val_if_fail (parser != NULL, FALSE); - css_string_funcs_init (); - if (property) { if (_gtk_css_parser_try (parser, "initial", TRUE)) @@ -1721,27 +446,11 @@ _gtk_style_property_parse_value (GtkStyleProperty *property, return success; } - func = property->parse_func; - } - else - func = NULL; - - if (func == NULL) - func = g_hash_table_lookup (parse_funcs, - GSIZE_TO_POINTER (G_VALUE_TYPE (value))); - if (func == NULL) - func = g_hash_table_lookup (parse_funcs, - GSIZE_TO_POINTER (g_type_fundamental (G_VALUE_TYPE (value)))); - - if (func == NULL) - { - _gtk_css_parser_error (parser, - "Cannot convert to type '%s'", - g_type_name (G_VALUE_TYPE (value))); - return FALSE; + if (property->parse_func) + return (* property->parse_func) (parser, base, value); } - return (*func) (parser, base, value); + return _gtk_css_style_parse_value (value, parser, base); } void @@ -1749,33 +458,12 @@ _gtk_style_property_print_value (GtkStyleProperty *property, const GValue *value, GString *string) { - GtkStylePrintFunc func; - - css_string_funcs_init (); - if (G_VALUE_HOLDS (value, GTK_TYPE_CSS_SPECIAL_VALUE)) - func = enum_value_print; - else if (property) - func = property->print_func; + enum_print (g_value_get_enum (value), GTK_TYPE_CSS_SPECIAL_VALUE, string); + else if (property && property->print_func) + (* property->print_func) (value, string); else - func = NULL; - - if (func == NULL) - func = g_hash_table_lookup (print_funcs, - GSIZE_TO_POINTER (G_VALUE_TYPE (value))); - if (func == NULL) - func = g_hash_table_lookup (print_funcs, - GSIZE_TO_POINTER (g_type_fundamental (G_VALUE_TYPE (value)))); - - if (func == NULL) - { - char *s = g_strdup_value_contents (value); - g_string_append (string, s); - g_free (s); - return; - } - - func (value, string); + _gtk_css_style_print_value (value, string); } static void |