X-Git-Url: http://pileus.org/git/?a=blobdiff_plain;f=gtk%2Fgtkcssparser.c;h=ab38fc9d93560a279dc025aeb925ff48b7c3c3f0;hb=0ba92bc26d1b716f2f9c0543593f13cd5a92c521;hp=96c367e8fd24a552b5e712457e4159b63f04f08d;hpb=dcd54e20d14be57a9d080e87a47bbef8d2271c05;p=~andy%2Fgtk diff --git a/gtk/gtkcssparser.c b/gtk/gtkcssparser.c index 96c367e8f..ab38fc9d9 100644 --- a/gtk/gtkcssparser.c +++ b/gtk/gtkcssparser.c @@ -38,26 +38,31 @@ struct _GtkCssParser { - const char *data; - GtkCssParserErrorFunc error_func; - gpointer user_data; + const char *data; + GFile *file; + GtkCssParserErrorFunc error_func; + gpointer user_data; - const char *line_start; - guint line; + const char *line_start; + guint line; }; GtkCssParser * _gtk_css_parser_new (const char *data, + GFile *file, GtkCssParserErrorFunc error_func, gpointer user_data) { GtkCssParser *parser; g_return_val_if_fail (data != NULL, NULL); + g_return_val_if_fail (file == NULL || G_IS_FILE (file), NULL); parser = g_slice_new0 (GtkCssParser); parser->data = data; + if (file) + parser->file = g_object_ref (file); parser->error_func = error_func; parser->user_data = user_data; @@ -72,6 +77,9 @@ _gtk_css_parser_free (GtkCssParser *parser) { g_return_if_fail (GTK_IS_CSS_PARSER (parser)); + if (parser->file) + g_object_unref (parser->file); + g_slice_free (GtkCssParser, parser); } @@ -117,6 +125,49 @@ _gtk_css_parser_get_position (GtkCssParser *parser) return parser->data - parser->line_start; } +static GFile * +gtk_css_parser_get_base_file (GtkCssParser *parser) +{ + GFile *base; + + if (parser->file) + { + base = g_file_get_parent (parser->file); + } + else + { + char *dir = g_get_current_dir (); + base = g_file_new_for_path (dir); + g_free (dir); + } + + return base; +} + +GFile * +_gtk_css_parser_get_file_for_path (GtkCssParser *parser, + const char *path) +{ + GFile *base, *file; + + g_return_val_if_fail (parser != NULL, NULL); + g_return_val_if_fail (path != NULL, NULL); + + base = gtk_css_parser_get_base_file (parser); + file = g_file_resolve_relative_path (base, path); + g_object_unref (base); + + return file; +} + +GFile * +_gtk_css_parser_get_file (GtkCssParser *parser) +{ + g_return_val_if_fail (parser != NULL, NULL); + + return parser->file; +} + void _gtk_css_parser_take_error (GtkCssParser *parser, GError *error) @@ -206,7 +257,7 @@ gtk_css_parser_skip_comment (GtkCssParser *parser) parser->data++; - if (parser->data[-2] == '*') + if (len > 0 && parser->data[-2] == '*') return TRUE; if (parser->data[0] == '*') _gtk_css_parser_error (parser, "'/*' in comment block"); @@ -618,15 +669,16 @@ _gtk_css_number_value_parse (GtkCssParser *parser, break; } - g_free (unit_name); - if (i >= G_N_ELEMENTS (units)) { _gtk_css_parser_error (parser, "`%s' is not a valid unit.", unit_name); + g_free (unit_name); return NULL; } unit = units[i].unit; + + g_free (unit_name); } else { @@ -736,283 +788,44 @@ _gtk_css_parser_try_enum (GtkCssParser *parser, return result; } -typedef enum { - COLOR_RGBA, - COLOR_RGB, - COLOR_LIGHTER, - COLOR_DARKER, - COLOR_SHADE, - COLOR_ALPHA, - COLOR_MIX, - COLOR_WIN32 -} ColorType; - -static GtkSymbolicColor * -gtk_css_parser_read_symbolic_color_function (GtkCssParser *parser, - ColorType color) -{ - GtkSymbolicColor *symbolic; - GtkSymbolicColor *child1, *child2; - double value; - - if (!_gtk_css_parser_try (parser, "(", TRUE)) - { - _gtk_css_parser_error (parser, "Missing opening bracket in color definition"); - return NULL; - } - - if (color == COLOR_RGB || color == COLOR_RGBA) - { - GdkRGBA rgba; - double tmp; - guint i; - - for (i = 0; i < 3; i++) - { - if (i > 0 && !_gtk_css_parser_try (parser, ",", TRUE)) - { - _gtk_css_parser_error (parser, "Expected ',' in color definition"); - return NULL; - } - - if (!_gtk_css_parser_try_double (parser, &tmp)) - { - _gtk_css_parser_error (parser, "Invalid number for color value"); - return NULL; - } - if (_gtk_css_parser_try (parser, "%", TRUE)) - tmp /= 100.0; - else - tmp /= 255.0; - if (i == 0) - rgba.red = tmp; - else if (i == 1) - rgba.green = tmp; - else if (i == 2) - rgba.blue = tmp; - else - g_assert_not_reached (); - } - - if (color == COLOR_RGBA) - { - if (i > 0 && !_gtk_css_parser_try (parser, ",", TRUE)) - { - _gtk_css_parser_error (parser, "Expected ',' in color definition"); - return NULL; - } - - if (!_gtk_css_parser_try_double (parser, &rgba.alpha)) - { - _gtk_css_parser_error (parser, "Invalid number for alpha value"); - return NULL; - } - } - else - rgba.alpha = 1.0; - - symbolic = gtk_symbolic_color_new_literal (&rgba); - } - else if (color == COLOR_WIN32) - { - symbolic = _gtk_win32_theme_color_parse (parser); - if (symbolic == NULL) - return NULL; - } - else - { - child1 = _gtk_css_parser_read_symbolic_color (parser); - if (child1 == NULL) - return NULL; - - if (color == COLOR_MIX) - { - if (!_gtk_css_parser_try (parser, ",", TRUE)) - { - _gtk_css_parser_error (parser, "Expected ',' in color definition"); - gtk_symbolic_color_unref (child1); - return NULL; - } - - child2 = _gtk_css_parser_read_symbolic_color (parser); - if (child2 == NULL) - { - gtk_symbolic_color_unref (child1); - return NULL; - } - } - else - child2 = NULL; - - if (color == COLOR_LIGHTER) - value = 1.3; - else if (color == COLOR_DARKER) - value = 0.7; - else - { - if (!_gtk_css_parser_try (parser, ",", TRUE)) - { - _gtk_css_parser_error (parser, "Expected ',' in color definition"); - gtk_symbolic_color_unref (child1); - if (child2) - gtk_symbolic_color_unref (child2); - return NULL; - } - - if (!_gtk_css_parser_try_double (parser, &value)) - { - _gtk_css_parser_error (parser, "Expected number in color definition"); - gtk_symbolic_color_unref (child1); - if (child2) - gtk_symbolic_color_unref (child2); - return NULL; - } - } - - switch (color) - { - case COLOR_LIGHTER: - case COLOR_DARKER: - case COLOR_SHADE: - symbolic = gtk_symbolic_color_new_shade (child1, value); - break; - case COLOR_ALPHA: - symbolic = gtk_symbolic_color_new_alpha (child1, value); - break; - case COLOR_MIX: - symbolic = gtk_symbolic_color_new_mix (child1, child2, value); - break; - default: - g_assert_not_reached (); - symbolic = NULL; - } - - gtk_symbolic_color_unref (child1); - if (child2) - gtk_symbolic_color_unref (child2); - } - - if (!_gtk_css_parser_try (parser, ")", TRUE)) - { - _gtk_css_parser_error (parser, "Expected ')' in color definition"); - gtk_symbolic_color_unref (symbolic); - return NULL; - } - - return symbolic; -} - -static GtkSymbolicColor * -gtk_css_parser_try_hash_color (GtkCssParser *parser) +gboolean +_gtk_css_parser_try_hash_color (GtkCssParser *parser, + GdkRGBA *rgba) { if (parser->data[0] == '#' && g_ascii_isxdigit (parser->data[1]) && g_ascii_isxdigit (parser->data[2]) && g_ascii_isxdigit (parser->data[3])) { - GdkRGBA rgba; - if (g_ascii_isxdigit (parser->data[4]) && g_ascii_isxdigit (parser->data[5]) && g_ascii_isxdigit (parser->data[6])) { - rgba.red = ((get_xdigit (parser->data[1]) << 4) + get_xdigit (parser->data[2])) / 255.0; - rgba.green = ((get_xdigit (parser->data[3]) << 4) + get_xdigit (parser->data[4])) / 255.0; - rgba.blue = ((get_xdigit (parser->data[5]) << 4) + get_xdigit (parser->data[6])) / 255.0; - rgba.alpha = 1.0; + rgba->red = ((get_xdigit (parser->data[1]) << 4) + get_xdigit (parser->data[2])) / 255.0; + rgba->green = ((get_xdigit (parser->data[3]) << 4) + get_xdigit (parser->data[4])) / 255.0; + rgba->blue = ((get_xdigit (parser->data[5]) << 4) + get_xdigit (parser->data[6])) / 255.0; + rgba->alpha = 1.0; parser->data += 7; } else { - rgba.red = get_xdigit (parser->data[1]) / 15.0; - rgba.green = get_xdigit (parser->data[2]) / 15.0; - rgba.blue = get_xdigit (parser->data[3]) / 15.0; - rgba.alpha = 1.0; + rgba->red = get_xdigit (parser->data[1]) / 15.0; + rgba->green = get_xdigit (parser->data[2]) / 15.0; + rgba->blue = get_xdigit (parser->data[3]) / 15.0; + rgba->alpha = 1.0; parser->data += 4; } _gtk_css_parser_skip_whitespace (parser); - return gtk_symbolic_color_new_literal (&rgba); - } - - return NULL; -} - -GtkSymbolicColor * -_gtk_css_parser_read_symbolic_color (GtkCssParser *parser) -{ - GtkSymbolicColor *symbolic; - guint color; - const char *names[] = {"rgba", "rgb", "lighter", "darker", "shade", "alpha", "mix", - GTK_WIN32_THEME_SYMBOLIC_COLOR_NAME}; - char *name; - - g_return_val_if_fail (GTK_IS_CSS_PARSER (parser), NULL); - - if (_gtk_css_parser_try (parser, "transparent", TRUE)) - { - GdkRGBA transparent = { 0, 0, 0, 0 }; - - return gtk_symbolic_color_new_literal (&transparent); - } - - if (_gtk_css_parser_try (parser, "@", FALSE)) - { - name = _gtk_css_parser_try_name (parser, TRUE); - - if (name) - { - symbolic = gtk_symbolic_color_new_name (name); - } - else - { - _gtk_css_parser_error (parser, "'%s' is not a valid symbolic color name", name); - symbolic = NULL; - } - - g_free (name); - return symbolic; - } - - for (color = 0; color < G_N_ELEMENTS (names); color++) - { - if (_gtk_css_parser_try (parser, names[color], TRUE)) - break; - } - - if (color < G_N_ELEMENTS (names)) - return gtk_css_parser_read_symbolic_color_function (parser, color); - - symbolic = gtk_css_parser_try_hash_color (parser); - if (symbolic) - return symbolic; - - name = _gtk_css_parser_try_name (parser, TRUE); - if (name) - { - GdkRGBA rgba; - - if (gdk_rgba_parse (&rgba, name)) - { - symbolic = gtk_symbolic_color_new_literal (&rgba); - } - else - { - _gtk_css_parser_error (parser, "'%s' is not a valid color name", name); - symbolic = NULL; - } - g_free (name); - return symbolic; + return TRUE; } - _gtk_css_parser_error (parser, "Not a color definition"); - return NULL; + return FALSE; } GFile * -_gtk_css_parser_read_url (GtkCssParser *parser, - GFile *base) +_gtk_css_parser_read_url (GtkCssParser *parser) { gchar *path; char *scheme; @@ -1066,17 +879,17 @@ _gtk_css_parser_read_url (GtkCssParser *parser, } } - file = g_file_resolve_relative_path (base, path); + file = _gtk_css_parser_get_file_for_path (parser, path); g_free (path); return file; } -void -_gtk_css_parser_resync_internal (GtkCssParser *parser, - gboolean sync_at_semicolon, - gboolean read_sync_token, - char terminator) +static void +gtk_css_parser_resync_internal (GtkCssParser *parser, + gboolean sync_at_semicolon, + gboolean read_sync_token, + char terminator) { gsize len; @@ -1171,7 +984,7 @@ _gtk_css_parser_read_value (GtkCssParser *parser) start = parser->data; /* This needs to be done better */ - _gtk_css_parser_resync_internal (parser, TRUE, FALSE, '}'); + gtk_css_parser_resync_internal (parser, TRUE, FALSE, '}'); result = g_strndup (start, parser->data - start); if (result) @@ -1197,5 +1010,5 @@ _gtk_css_parser_resync (GtkCssParser *parser, { g_return_if_fail (GTK_IS_CSS_PARSER (parser)); - _gtk_css_parser_resync_internal (parser, sync_at_semicolon, TRUE, terminator); + gtk_css_parser_resync_internal (parser, sync_at_semicolon, TRUE, terminator); }