From: Benjamin Otte Date: Sun, 12 May 2019 13:18:46 +0000 (+0200) Subject: cssparser: Make gsk_renderer_consume_url() return a string X-Git-Tag: archive/raspbian/4.4.1+ds1-2+rpi1^2~18^2~20^2~1670^2~3 X-Git-Url: https://dgit.raspbian.org/?a=commitdiff_plain;h=0886ade182f1a958024202d5c20248d57fcdb053;p=gtk4.git cssparser: Make gsk_renderer_consume_url() return a string We don't want to return a GFile because GFile can't handle can't deal with data: urls. That makes the code a bit more complicated that doesn't deal with those URLs, but it makes the other code actually work. GtkCssImageUrl also now decodes data urls immediately instead of only at the first load. So don't use data urls if you care about performance. --- diff --git a/gsk/gskrendernodeparser.c b/gsk/gskrendernodeparser.c index 9f164a93aa..06b2b183c7 100644 --- a/gsk/gskrendernodeparser.c +++ b/gsk/gskrendernodeparser.c @@ -71,27 +71,26 @@ static gboolean parse_texture (GtkCssParser *parser, gpointer out_data) { - GFile *file; GdkTexture *texture; GError *error = NULL; GtkCssLocation start_location; + char *url, *scheme; start_location = *gtk_css_parser_get_start_location (parser); - file = gtk_css_parser_consume_url (parser); - if (file == NULL) + url = gtk_css_parser_consume_url (parser); + if (url == NULL) return FALSE; - if (g_file_has_uri_scheme (file, "data")) + scheme = g_uri_parse_scheme (url); + if (scheme && g_ascii_strcasecmp (scheme, "data") == 0) { GInputStream *stream; - char *uri; GdkPixbuf *pixbuf; GBytes *bytes; - uri = g_file_get_uri (file); texture = NULL; - bytes = gtk_css_data_url_parse (uri, NULL, &error); + bytes = gtk_css_data_url_parse (url, NULL, &error); if (bytes) { stream = g_memory_input_stream_new_from_bytes (bytes); @@ -103,14 +102,18 @@ parse_texture (GtkCssParser *parser, g_object_unref (pixbuf); } } - - g_free (uri); } else { + GFile *file; + + file = gtk_css_parser_resolve_url (parser, url); texture = gdk_texture_new_from_file (file, &error); + g_object_unref (file); } - g_object_unref (file); + + g_free (scheme); + g_free (url); if (texture == NULL) { diff --git a/gtk/css/gtkcssparser.c b/gtk/css/gtkcssparser.c index 5ba0997b4d..84bc4fc8e7 100644 --- a/gtk/css/gtkcssparser.c +++ b/gtk/css/gtkcssparser.c @@ -973,11 +973,10 @@ gtk_css_parser_parse_url_arg (GtkCssParser *parser, * * Returns: (nullable) (transfer full): the resulting URL or %NULL on error **/ -GFile * +char * gtk_css_parser_consume_url (GtkCssParser *self) { const GtkCssToken *token; - GFile *result; char *url; token = gtk_css_parser_get_token (self); @@ -998,16 +997,7 @@ gtk_css_parser_consume_url (GtkCssParser *self) return NULL; } - result = gtk_css_parser_resolve_url (self, url); - if (result == NULL) - { - gtk_css_parser_error_import (self, "Could not resolve \"%s\" to a valid URL", url); - g_free (url); - return NULL; - } - g_free (url); - - return result; + return url; } gboolean diff --git a/gtk/css/gtkcssparserprivate.h b/gtk/css/gtkcssparserprivate.h index 520d0eeaa0..349ad67999 100644 --- a/gtk/css/gtkcssparserprivate.h +++ b/gtk/css/gtkcssparserprivate.h @@ -134,7 +134,7 @@ gboolean gtk_css_parser_try_token (GtkCssParser char * gtk_css_parser_consume_ident (GtkCssParser *self) G_GNUC_WARN_UNUSED_RESULT; char * gtk_css_parser_consume_string (GtkCssParser *self) G_GNUC_WARN_UNUSED_RESULT; -GFile * gtk_css_parser_consume_url (GtkCssParser *self) G_GNUC_WARN_UNUSED_RESULT; +char * gtk_css_parser_consume_url (GtkCssParser *self) G_GNUC_WARN_UNUSED_RESULT; gboolean gtk_css_parser_consume_number (GtkCssParser *self, double *number); gboolean gtk_css_parser_consume_integer (GtkCssParser *self, diff --git a/gtk/gtkcssimagerecolor.c b/gtk/gtkcssimagerecolor.c index 7dadd660a0..98e1ff2e80 100644 --- a/gtk/gtkcssimagerecolor.c +++ b/gtk/gtkcssimagerecolor.c @@ -245,10 +245,16 @@ gtk_css_image_recolor_parse_arg (GtkCssParser *parser, switch (arg) { case 0: - self->file = gtk_css_parser_consume_url (parser); - if (self->file == NULL) - return 0; - return 1; + { + char *url = gtk_css_parser_consume_url (parser); + if (url == NULL) + return 0; + self->file = gtk_css_parser_resolve_url (parser, url); + g_free (url); + if (self->file == NULL) + return 0; + return 1; + } case 1: self->palette = gtk_css_palette_value_parse (parser); diff --git a/gtk/gtkcssimageurl.c b/gtk/gtkcssimageurl.c index 361844394d..398e9c3705 100644 --- a/gtk/gtkcssimageurl.c +++ b/gtk/gtkcssimageurl.c @@ -54,31 +54,6 @@ gtk_css_image_url_load_image (GtkCssImageUrl *url, g_free (resource_path); g_free (uri); } - else if (g_file_has_uri_scheme (url->file, "data")) - { - GInputStream *stream; - char *uri; - GdkPixbuf *pixbuf; - GBytes *bytes; - - uri = g_file_get_uri (url->file); - texture = NULL; - - bytes = gtk_css_data_url_parse (uri, NULL, &local_error); - if (bytes) - { - stream = g_memory_input_stream_new_from_bytes (bytes); - pixbuf = gdk_pixbuf_new_from_stream (stream, NULL, &local_error); - g_object_unref (stream); - if (pixbuf != NULL) - { - texture = gdk_texture_new_for_pixbuf (pixbuf); - g_object_unref (pixbuf); - } - } - - g_free (uri); - } else { texture = gdk_texture_new_from_file (url->file, &local_error); @@ -190,12 +165,52 @@ static gboolean gtk_css_image_url_parse (GtkCssImage *image, GtkCssParser *parser) { - GtkCssImageUrl *url = GTK_CSS_IMAGE_URL (image); + GtkCssImageUrl *self = GTK_CSS_IMAGE_URL (image); + char *url, *scheme; - url->file = gtk_css_parser_consume_url (parser); - if (url->file == NULL) + url = gtk_css_parser_consume_url (parser); + if (url == NULL) return FALSE; + scheme = g_uri_parse_scheme (url); + if (scheme && g_ascii_strcasecmp (scheme, "data") == 0) + { + GInputStream *stream; + GdkPixbuf *pixbuf; + GBytes *bytes; + GError *error = NULL; + + bytes = gtk_css_data_url_parse (url, NULL, &error); + if (bytes) + { + stream = g_memory_input_stream_new_from_bytes (bytes); + pixbuf = gdk_pixbuf_new_from_stream (stream, NULL, &error); + g_object_unref (stream); + if (pixbuf == NULL) + { + gtk_css_parser_emit_error (parser, + gtk_css_parser_get_start_location (parser), + gtk_css_parser_get_end_location (parser), + error); + g_clear_error (&error); + } + else + { + GdkTexture *texture = gdk_texture_new_for_pixbuf (pixbuf); + self->loaded_image = gtk_css_image_paintable_new (GDK_PAINTABLE (texture), GDK_PAINTABLE (texture)); + g_object_unref (texture); + g_object_unref (pixbuf); + } + } + } + else + { + self->file = gtk_css_parser_resolve_url (parser, url); + } + + g_free (url); + g_free (scheme); + return TRUE; } diff --git a/gtk/gtkcssprovider.c b/gtk/gtkcssprovider.c index ab4a1cb2a8..f3dfa9922b 100644 --- a/gtk/gtkcssprovider.c +++ b/gtk/gtkcssprovider.c @@ -695,7 +695,14 @@ parse_import (GtkCssScanner *scanner) } else { - file = gtk_css_parser_consume_url (scanner->parser); + char *url = gtk_css_parser_consume_url (scanner->parser); + if (url) + { + file = gtk_css_parser_resolve_url (scanner->parser, url); + g_free (url); + } + else + file = NULL; } if (file == NULL)