mirror of
https://gitlab.gnome.org/GNOME/gtk.git
synced 2025-01-19 08:30:09 +00:00
Merge branch 'wip/otte/for-master' into 'master'
Wip/otte/for master See merge request GNOME/gtk!832
This commit is contained in:
commit
f8c1f7173a
@ -68,11 +68,20 @@ get_current_text (GtkTextBuffer *buffer)
|
||||
|
||||
gtk_text_buffer_get_start_iter (buffer, &start);
|
||||
gtk_text_buffer_get_end_iter (buffer, &end);
|
||||
gtk_text_buffer_remove_all_tags (buffer, &start, &end);
|
||||
|
||||
return gtk_text_buffer_get_text (buffer, &start, &end, FALSE);
|
||||
}
|
||||
|
||||
static void
|
||||
text_buffer_remove_all_tags (GtkTextBuffer *buffer)
|
||||
{
|
||||
GtkTextIter start, end;
|
||||
|
||||
gtk_text_buffer_get_start_iter (buffer, &start);
|
||||
gtk_text_buffer_get_end_iter (buffer, &end);
|
||||
gtk_text_buffer_remove_all_tags (buffer, &start, &end);
|
||||
}
|
||||
|
||||
static void
|
||||
deserialize_error_func (const GtkCssSection *section,
|
||||
const GError *error,
|
||||
@ -146,6 +155,7 @@ text_changed (GtkTextBuffer *buffer,
|
||||
|
||||
g_array_remove_range (self->errors, 0, self->errors->len);
|
||||
text = get_current_text (self->text_buffer);
|
||||
text_buffer_remove_all_tags (self->text_buffer);
|
||||
bytes = g_bytes_new_take (text, strlen (text));
|
||||
|
||||
/* If this is too slow, go fix the parser performance */
|
||||
@ -255,6 +265,7 @@ text_view_query_tooltip_cb (GtkWidget *widget,
|
||||
{
|
||||
GtkTextIter iter;
|
||||
guint i;
|
||||
GString *text;
|
||||
|
||||
if (keyboard_tip)
|
||||
{
|
||||
@ -272,6 +283,8 @@ text_view_query_tooltip_cb (GtkWidget *widget,
|
||||
gtk_text_view_get_iter_at_position (GTK_TEXT_VIEW (self->text_view), &iter, &trailing, bx, by);
|
||||
}
|
||||
|
||||
text = g_string_new ("");
|
||||
|
||||
for (i = 0; i < self->errors->len; i ++)
|
||||
{
|
||||
const TextViewError *e = &g_array_index (self->errors, TextViewError, i);
|
||||
@ -282,12 +295,23 @@ text_view_query_tooltip_cb (GtkWidget *widget,
|
||||
|
||||
if (gtk_text_iter_in_range (&iter, &start_iter, &end_iter))
|
||||
{
|
||||
gtk_tooltip_set_text (tooltip, e->message);
|
||||
return TRUE;
|
||||
if (text->len > 0)
|
||||
g_string_append (text, "\n");
|
||||
g_string_append (text, e->message);
|
||||
}
|
||||
}
|
||||
|
||||
return FALSE;
|
||||
if (text->len > 0)
|
||||
{
|
||||
gtk_tooltip_set_text (tooltip, text->str);
|
||||
g_string_free (text, TRUE);
|
||||
return TRUE;
|
||||
}
|
||||
else
|
||||
{
|
||||
g_string_free (text, TRUE);
|
||||
return FALSE;
|
||||
}
|
||||
}
|
||||
|
||||
gboolean
|
||||
|
@ -636,6 +636,7 @@ gsk_texture_node_draw (GskRenderNode *node,
|
||||
{
|
||||
GskTextureNode *self = (GskTextureNode *) node;
|
||||
cairo_surface_t *surface;
|
||||
cairo_pattern_t *pattern;
|
||||
|
||||
surface = gdk_texture_download_surface (self->texture);
|
||||
|
||||
@ -646,11 +647,14 @@ gsk_texture_node_draw (GskRenderNode *node,
|
||||
node->bounds.size.width / gdk_texture_get_width (self->texture),
|
||||
node->bounds.size.height / gdk_texture_get_height (self->texture));
|
||||
|
||||
cairo_set_source_surface (cr, surface, 0, 0);
|
||||
pattern = cairo_pattern_create_for_surface (surface);
|
||||
cairo_pattern_set_extend (pattern, CAIRO_EXTEND_PAD);
|
||||
cairo_set_source (cr, pattern);
|
||||
cairo_paint (cr);
|
||||
|
||||
cairo_restore (cr);
|
||||
|
||||
cairo_pattern_destroy (pattern);
|
||||
cairo_surface_destroy (surface);
|
||||
}
|
||||
|
||||
|
@ -1,13 +1,16 @@
|
||||
|
||||
#include "gskrendernodeparserprivate.h"
|
||||
|
||||
#include <gdk/gdkrgbaprivate.h>
|
||||
#include <gtk/css/gtkcss.h>
|
||||
#include "gtk/css/gtkcssparserprivate.h"
|
||||
#include "gskroundedrectprivate.h"
|
||||
#include "gskrendernodeprivate.h"
|
||||
#include "gsktransformprivate.h"
|
||||
|
||||
#include "gdk/gdkrgbaprivate.h"
|
||||
#include "gdk/gdktextureprivate.h"
|
||||
#include <gtk/css/gtkcss.h>
|
||||
#include "gtk/css/gtkcssparserprivate.h"
|
||||
#include "gtk/css/gtkcssdataurlprivate.h"
|
||||
|
||||
typedef struct _Declaration Declaration;
|
||||
|
||||
struct _Declaration
|
||||
@ -18,17 +21,12 @@ struct _Declaration
|
||||
};
|
||||
|
||||
static gboolean
|
||||
parse_semicolon (GtkCssParser *parser)
|
||||
check_eof (GtkCssParser *parser)
|
||||
{
|
||||
const GtkCssToken *token;
|
||||
|
||||
token = gtk_css_parser_get_token (parser);
|
||||
if (gtk_css_token_is (token, GTK_CSS_TOKEN_EOF))
|
||||
{
|
||||
gtk_css_parser_warn_syntax (parser, "No ';' at end of block");
|
||||
return TRUE;
|
||||
}
|
||||
else if (!gtk_css_token_is (token, GTK_CSS_TOKEN_SEMICOLON))
|
||||
if (!gtk_css_token_is (token, GTK_CSS_TOKEN_EOF))
|
||||
{
|
||||
gtk_css_parser_error_syntax (parser, "Expected ';' at end of statement");
|
||||
return FALSE;
|
||||
@ -62,7 +60,7 @@ parse_rect (GtkCssParser *parser,
|
||||
graphene_rect_t r;
|
||||
|
||||
if (!parse_rect_without_semicolon (parser, &r) ||
|
||||
!parse_semicolon (parser))
|
||||
!check_eof (parser))
|
||||
return FALSE;
|
||||
|
||||
graphene_rect_init_from_rect (out_rect, &r);
|
||||
@ -70,35 +68,70 @@ parse_rect (GtkCssParser *parser,
|
||||
}
|
||||
|
||||
static gboolean
|
||||
parse_data (GtkCssParser *parser,
|
||||
gpointer out_data)
|
||||
parse_texture (GtkCssParser *parser,
|
||||
gpointer out_data)
|
||||
{
|
||||
const GtkCssToken *token;
|
||||
struct {
|
||||
guchar *data;
|
||||
gsize data_len;
|
||||
} *texture_data = out_data;
|
||||
GdkTexture *texture;
|
||||
GError *error = NULL;
|
||||
GtkCssLocation start_location;
|
||||
char *url, *scheme;
|
||||
|
||||
token = gtk_css_parser_get_token (parser);
|
||||
if (!gtk_css_token_is (token, GTK_CSS_TOKEN_STRING))
|
||||
start_location = *gtk_css_parser_get_start_location (parser);
|
||||
url = gtk_css_parser_consume_url (parser);
|
||||
if (url == NULL)
|
||||
return FALSE;
|
||||
|
||||
if (!g_str_has_prefix (token->string.string, "data:;base64,"))
|
||||
scheme = g_uri_parse_scheme (url);
|
||||
if (scheme && g_ascii_strcasecmp (scheme, "data") == 0)
|
||||
{
|
||||
gtk_css_parser_error_value (parser, "Only base64 encoded data is allowed");
|
||||
GInputStream *stream;
|
||||
GdkPixbuf *pixbuf;
|
||||
GBytes *bytes;
|
||||
|
||||
texture = 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)
|
||||
{
|
||||
texture = gdk_texture_new_for_pixbuf (pixbuf);
|
||||
g_object_unref (pixbuf);
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
GFile *file;
|
||||
|
||||
file = gtk_css_parser_resolve_url (parser, url);
|
||||
texture = gdk_texture_new_from_file (file, &error);
|
||||
g_object_unref (file);
|
||||
}
|
||||
|
||||
g_free (scheme);
|
||||
g_free (url);
|
||||
|
||||
if (texture == NULL)
|
||||
{
|
||||
gtk_css_parser_emit_error (parser,
|
||||
&start_location,
|
||||
gtk_css_parser_get_end_location (parser),
|
||||
error);
|
||||
g_clear_error (&error);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
texture_data->data = g_base64_decode (token->string.string + strlen ("data:;base64,"),
|
||||
&texture_data->data_len);
|
||||
|
||||
gtk_css_parser_consume_token (parser);
|
||||
if (!parse_semicolon (parser))
|
||||
if (!check_eof (parser))
|
||||
{
|
||||
g_free (texture_data->data);
|
||||
g_object_unref (texture);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
*(GdkTexture **) out_data = texture;
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
@ -116,7 +149,7 @@ parse_rounded_rect (GtkCssParser *parser,
|
||||
|
||||
if (!gtk_css_parser_try_delim (parser, '/'))
|
||||
{
|
||||
if (!parse_semicolon (parser))
|
||||
if (!check_eof (parser))
|
||||
return FALSE;
|
||||
gsk_rounded_rect_init_from_rect (out_rect, &r, 0);
|
||||
return TRUE;
|
||||
@ -171,7 +204,7 @@ parse_rounded_rect (GtkCssParser *parser,
|
||||
corners[i].height = corners[i].width;
|
||||
}
|
||||
|
||||
if (!parse_semicolon (parser))
|
||||
if (!check_eof (parser))
|
||||
return FALSE;
|
||||
|
||||
gsk_rounded_rect_init (out_rect, &r, &corners[0], &corners[1], &corners[2], &corners[3]);
|
||||
@ -186,7 +219,7 @@ parse_color (GtkCssParser *parser,
|
||||
GdkRGBA color;
|
||||
|
||||
if (!gdk_rgba_parser_parse (parser, &color) ||
|
||||
!parse_semicolon (parser))
|
||||
!check_eof (parser))
|
||||
return FALSE;
|
||||
|
||||
*(GdkRGBA *) out_color = color;
|
||||
@ -201,7 +234,7 @@ parse_double (GtkCssParser *parser,
|
||||
double d;
|
||||
|
||||
if (!gtk_css_parser_consume_number (parser, &d) ||
|
||||
!parse_semicolon (parser))
|
||||
!check_eof (parser))
|
||||
return FALSE;
|
||||
|
||||
*(double *) out_double = d;
|
||||
@ -217,7 +250,7 @@ parse_point (GtkCssParser *parser,
|
||||
|
||||
if (!gtk_css_parser_consume_number (parser, &x) ||
|
||||
!gtk_css_parser_consume_number (parser, &y) ||
|
||||
!parse_semicolon (parser))
|
||||
!check_eof (parser))
|
||||
return FALSE;
|
||||
|
||||
graphene_point_init (out_point, x, y);
|
||||
@ -232,7 +265,7 @@ parse_transform (GtkCssParser *parser,
|
||||
GskTransform *transform;
|
||||
|
||||
if (!gsk_transform_parser_parse (parser, &transform) ||
|
||||
!parse_semicolon (parser))
|
||||
!check_eof (parser))
|
||||
{
|
||||
gsk_transform_unref (transform);
|
||||
return FALSE;
|
||||
@ -258,7 +291,7 @@ parse_string (GtkCssParser *parser,
|
||||
s = g_strdup (token->string.string);
|
||||
gtk_css_parser_consume_token (parser);
|
||||
|
||||
if (!parse_semicolon (parser))
|
||||
if (!check_eof (parser))
|
||||
{
|
||||
g_free (s);
|
||||
return FALSE;
|
||||
@ -313,7 +346,7 @@ parse_stops (GtkCssParser *parser,
|
||||
g_array_free (*(GArray **) out_stops, TRUE);
|
||||
*(GArray **) out_stops = stops;
|
||||
|
||||
return parse_semicolon (parser);
|
||||
return check_eof (parser);
|
||||
|
||||
error:
|
||||
g_array_free (stops, TRUE);
|
||||
@ -333,7 +366,7 @@ parse_colors4 (GtkCssParser *parser,
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
return parse_semicolon (parser);
|
||||
return check_eof (parser);
|
||||
}
|
||||
|
||||
static gboolean
|
||||
@ -371,7 +404,7 @@ parse_shadows (GtkCssParser *parser,
|
||||
break;
|
||||
}
|
||||
|
||||
return parse_semicolon (parser);
|
||||
return check_eof (parser);
|
||||
}
|
||||
|
||||
static const struct
|
||||
@ -407,7 +440,7 @@ parse_blend_mode (GtkCssParser *parser,
|
||||
{
|
||||
if (gtk_css_parser_try_ident (parser, blend_modes[i].name))
|
||||
{
|
||||
if (!parse_semicolon (parser))
|
||||
if (!check_eof (parser))
|
||||
return FALSE;
|
||||
*(GskBlendMode *) out_mode = blend_modes[i].mode;
|
||||
return TRUE;
|
||||
@ -444,7 +477,7 @@ parse_font (GtkCssParser *parser,
|
||||
/* Skip font name token */
|
||||
gtk_css_parser_consume_token (parser);
|
||||
|
||||
return parse_semicolon (parser);
|
||||
return check_eof (parser);
|
||||
}
|
||||
|
||||
static gboolean
|
||||
@ -497,7 +530,7 @@ parse_glyphs (GtkCssParser *parser,
|
||||
|
||||
*((PangoGlyphString **)out_glyphs) = glyph_string;
|
||||
|
||||
return parse_semicolon (parser);
|
||||
return check_eof (parser);
|
||||
}
|
||||
|
||||
static gboolean
|
||||
@ -517,15 +550,15 @@ parse_container_node (GtkCssParser *parser)
|
||||
token = gtk_css_parser_get_token (parser))
|
||||
{
|
||||
node = NULL;
|
||||
/* We don't wand a semicolon here, but the parse_node function will figure
|
||||
* that out itself and return an error if we encounter one.
|
||||
*/
|
||||
gtk_css_parser_start_semicolon_block (parser, GTK_CSS_TOKEN_OPEN_CURLY);
|
||||
|
||||
if (parse_node (parser, &node))
|
||||
{
|
||||
g_ptr_array_add (nodes, node);
|
||||
}
|
||||
else
|
||||
{
|
||||
gtk_css_parser_skip_until (parser, GTK_CSS_TOKEN_OPEN_CURLY);
|
||||
gtk_css_parser_skip (parser);
|
||||
}
|
||||
g_ptr_array_add (nodes, node);
|
||||
|
||||
gtk_css_parser_end_block (parser);
|
||||
}
|
||||
|
||||
node = gsk_container_node_new ((GskRenderNode **) nodes->pdata, nodes->len);
|
||||
@ -535,25 +568,6 @@ parse_container_node (GtkCssParser *parser)
|
||||
return node;
|
||||
}
|
||||
|
||||
static void
|
||||
parse_declarations_sync (GtkCssParser *parser)
|
||||
{
|
||||
const GtkCssToken *token;
|
||||
|
||||
for (token = gtk_css_parser_get_token (parser);
|
||||
!gtk_css_token_is (token, GTK_CSS_TOKEN_EOF);
|
||||
token = gtk_css_parser_get_token (parser))
|
||||
{
|
||||
if (gtk_css_token_is (token, GTK_CSS_TOKEN_SEMICOLON) ||
|
||||
gtk_css_token_is (token, GTK_CSS_TOKEN_OPEN_CURLY))
|
||||
{
|
||||
gtk_css_parser_skip (parser);
|
||||
break;
|
||||
}
|
||||
gtk_css_parser_skip (parser);
|
||||
}
|
||||
}
|
||||
|
||||
static guint
|
||||
parse_declarations (GtkCssParser *parser,
|
||||
const Declaration *declarations,
|
||||
@ -569,6 +583,8 @@ parse_declarations (GtkCssParser *parser,
|
||||
!gtk_css_token_is (token, GTK_CSS_TOKEN_EOF);
|
||||
token = gtk_css_parser_get_token (parser))
|
||||
{
|
||||
gtk_css_parser_start_semicolon_block (parser, GTK_CSS_TOKEN_OPEN_CURLY);
|
||||
|
||||
for (i = 0; i < n_declarations; i++)
|
||||
{
|
||||
if (gtk_css_token_is_ident (token, declarations[i].name))
|
||||
@ -578,7 +594,6 @@ parse_declarations (GtkCssParser *parser,
|
||||
if (!gtk_css_token_is (token, GTK_CSS_TOKEN_COLON))
|
||||
{
|
||||
gtk_css_parser_error_syntax (parser, "Expected ':' after variable declaration");
|
||||
parse_declarations_sync (parser);
|
||||
}
|
||||
else
|
||||
{
|
||||
@ -587,8 +602,6 @@ parse_declarations (GtkCssParser *parser,
|
||||
gtk_css_parser_warn_syntax (parser, "Variable \"%s\" defined multiple times", declarations[i].name);
|
||||
if (declarations[i].parse_func (parser, declarations[i].result))
|
||||
parsed |= (1 << i);
|
||||
else
|
||||
parse_declarations_sync (parser);
|
||||
}
|
||||
break;
|
||||
}
|
||||
@ -599,8 +612,9 @@ parse_declarations (GtkCssParser *parser,
|
||||
gtk_css_parser_error_syntax (parser, "No variable named \"%s\"", token->string.string);
|
||||
else
|
||||
gtk_css_parser_error_syntax (parser, "Expected a variable name");
|
||||
parse_declarations_sync (parser);
|
||||
}
|
||||
|
||||
gtk_css_parser_end_block (parser);
|
||||
}
|
||||
|
||||
return parsed;
|
||||
@ -691,35 +705,21 @@ static GskRenderNode *
|
||||
parse_texture_node (GtkCssParser *parser)
|
||||
{
|
||||
graphene_rect_t bounds = GRAPHENE_RECT_INIT (0, 0, 0, 0);
|
||||
struct {
|
||||
guchar *data;
|
||||
gsize data_len;
|
||||
} texture_data = { NULL, 0 };
|
||||
double width = 0.0;
|
||||
double height = 0.0;
|
||||
GdkTexture *texture = NULL;
|
||||
const Declaration declarations[] = {
|
||||
{ "bounds", parse_rect, &bounds },
|
||||
{ "width", parse_double, &width },
|
||||
{ "height", parse_double, &height },
|
||||
{ "texture", parse_data, &texture_data }
|
||||
{ "texture", parse_texture, &texture }
|
||||
};
|
||||
GdkTexture *texture;
|
||||
GdkPixbuf *pixbuf;
|
||||
GskRenderNode *node;
|
||||
|
||||
parse_declarations (parser, declarations, G_N_ELEMENTS(declarations));
|
||||
|
||||
pixbuf = gdk_pixbuf_new_from_data (texture_data.data,
|
||||
GDK_COLORSPACE_RGB,
|
||||
TRUE,
|
||||
8,
|
||||
(int)width,
|
||||
(int)height,
|
||||
4 * (int)width,
|
||||
(GdkPixbufDestroyNotify)g_free, NULL);
|
||||
if (texture == NULL)
|
||||
{
|
||||
gtk_css_parser_error_syntax (parser, "Missing \"texture\" property definition");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
texture = gdk_texture_new_for_pixbuf (pixbuf);
|
||||
g_object_unref (pixbuf);
|
||||
node = gsk_texture_node_new (texture, &bounds);
|
||||
g_object_unref (texture);
|
||||
|
||||
@ -942,7 +942,7 @@ parse_text_node (GtkCssParser *parser)
|
||||
PangoFont *font = NULL;
|
||||
double x = 0;
|
||||
double y = 0;
|
||||
GdkRGBA color = { 0, 0, 0, 0 };
|
||||
GdkRGBA color = { 0, 0, 0, 1 };
|
||||
PangoGlyphString *glyphs = NULL;
|
||||
const Declaration declarations[] = {
|
||||
{ "font", parse_font, &font },
|
||||
@ -1131,46 +1131,39 @@ parse_node (GtkCssParser *parser,
|
||||
|
||||
};
|
||||
GskRenderNode **node_p = out_node;
|
||||
const GtkCssToken *token;
|
||||
guint i;
|
||||
|
||||
token = gtk_css_parser_get_token (parser);
|
||||
if (!gtk_css_token_is (token, GTK_CSS_TOKEN_IDENT))
|
||||
{
|
||||
gtk_css_parser_error_syntax (parser, "Expected a node name");
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
for (i = 0; i < G_N_ELEMENTS (node_parsers); i++)
|
||||
{
|
||||
if (gtk_css_token_is_ident (token, node_parsers[i].name))
|
||||
if (gtk_css_parser_try_ident (parser, node_parsers[i].name))
|
||||
{
|
||||
GskRenderNode *node;
|
||||
|
||||
gtk_css_parser_consume_token (parser);
|
||||
token = gtk_css_parser_get_token (parser);
|
||||
if (!gtk_css_token_is (token, GTK_CSS_TOKEN_OPEN_CURLY))
|
||||
if (!gtk_css_parser_has_token (parser, GTK_CSS_TOKEN_EOF))
|
||||
{
|
||||
gtk_css_parser_error_syntax (parser, "Expected '{' after node name");
|
||||
return FALSE;
|
||||
}
|
||||
gtk_css_parser_start_block (parser);
|
||||
gtk_css_parser_end_block_prelude (parser);
|
||||
node = node_parsers[i].func (parser);
|
||||
if (node)
|
||||
{
|
||||
token = gtk_css_parser_get_token (parser);
|
||||
if (!gtk_css_token_is (token, GTK_CSS_TOKEN_EOF))
|
||||
if (!gtk_css_parser_has_token (parser, GTK_CSS_TOKEN_EOF))
|
||||
gtk_css_parser_error_syntax (parser, "Expected '}' at end of node definition");
|
||||
g_clear_pointer (node_p, gsk_render_node_unref);
|
||||
*node_p = node;
|
||||
}
|
||||
gtk_css_parser_end_block (parser);
|
||||
|
||||
return node != NULL;
|
||||
}
|
||||
}
|
||||
|
||||
gtk_css_parser_error_value (parser, "\"%s\" is not a valid node name", token->string.string);
|
||||
if (gtk_css_parser_has_token (parser, GTK_CSS_TOKEN_IDENT))
|
||||
gtk_css_parser_error_value (parser, "\"%s\" is not a valid node name",
|
||||
gtk_css_parser_get_token (parser)->string.string);
|
||||
else
|
||||
gtk_css_parser_error_syntax (parser, "Expected a node name");
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
@ -1497,6 +1490,16 @@ append_node_param (Printer *p,
|
||||
render_node_print (p, node);
|
||||
}
|
||||
|
||||
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
|
||||
render_node_print (Printer *p,
|
||||
GskRenderNode *node)
|
||||
@ -1737,30 +1740,25 @@ render_node_print (Printer *p,
|
||||
case GSK_TEXTURE_NODE:
|
||||
{
|
||||
GdkTexture *texture = gsk_texture_node_get_texture (node);
|
||||
int stride;
|
||||
int len;
|
||||
guchar *data;
|
||||
cairo_surface_t *surface;
|
||||
GByteArray *array;
|
||||
char *b64;
|
||||
|
||||
start_node (p, "texture");
|
||||
append_rect_param (p, "bounds", &node->bounds);
|
||||
/* TODO: width and height here are unnecessary and can later be computed from the data length? */
|
||||
append_float_param (p, "width", gdk_texture_get_width (texture));
|
||||
append_float_param (p, "height", gdk_texture_get_height (texture));
|
||||
|
||||
stride = 4 * gdk_texture_get_width (texture);
|
||||
len = sizeof (guchar) * stride * gdk_texture_get_height (texture);
|
||||
data = g_malloc (len);
|
||||
gdk_texture_download (texture, data, stride);
|
||||
|
||||
b64 = g_base64_encode (data, len);
|
||||
surface = gdk_texture_download_surface (texture);
|
||||
array = g_byte_array_new ();
|
||||
cairo_surface_write_to_png_stream (surface, surface_write, array);
|
||||
b64 = g_base64_encode (array->data, array->len);
|
||||
|
||||
_indent (p);
|
||||
g_string_append_printf (p->str, "texture: \"data:;base64,%s\";\n", b64);
|
||||
g_string_append_printf (p->str, "texture: url(\"data:image/png;base64,%s\");\n", b64);
|
||||
end_node (p);
|
||||
|
||||
g_free (b64);
|
||||
g_free (data);
|
||||
g_byte_array_free (array, TRUE);
|
||||
cairo_surface_destroy (surface);
|
||||
}
|
||||
break;
|
||||
|
||||
|
175
gtk/css/gtkcssdataurl.c
Normal file
175
gtk/css/gtkcssdataurl.c
Normal file
@ -0,0 +1,175 @@
|
||||
/* GStreamer data:// uri source element
|
||||
* Copyright (C) 2009 Igalia S.L
|
||||
* Copyright (C) 2009 Sebastian Dröge <sebastian.droege@collabora.co.uk>
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Library 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
|
||||
* Library General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Library General Public
|
||||
* License along with this library; if not, write to the
|
||||
* Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
|
||||
* Boston, MA 02110-1301, USA.
|
||||
*/
|
||||
|
||||
/*<private>
|
||||
* SECTION:data-url
|
||||
* @title: data: URLs
|
||||
*
|
||||
* These function allow encoding and decoding of data: URLs, see
|
||||
* [RFC 2397](http://tools.ietf.org/html/rfc2397) for more information.
|
||||
*/
|
||||
|
||||
#include "config.h"
|
||||
|
||||
#include "gtkcssdataurlprivate.h"
|
||||
|
||||
#include "../gtkintl.h"
|
||||
|
||||
#include <string.h>
|
||||
|
||||
/*<private>
|
||||
* gtk_css_data_url_parse:
|
||||
* @url: the URL to parse
|
||||
* @out_mimetype: (out nullable optional): Return location to set the contained
|
||||
* mime type to. If no mime type was specified, this value is set to %NULL.
|
||||
* @error: error location or %NULL for none
|
||||
*
|
||||
* Decodes a data URL according to RFC2397 and returns the decoded data.
|
||||
*
|
||||
* Returns: a new #GBytes with the decoded data or %NULL on error
|
||||
**/
|
||||
GBytes *
|
||||
gtk_css_data_url_parse (const char *url,
|
||||
char **out_mimetype,
|
||||
GError **error)
|
||||
{
|
||||
char *mimetype = NULL;
|
||||
const char *parameters_start;
|
||||
const char *data_start;
|
||||
GBytes *bytes;
|
||||
gboolean base64 = FALSE;
|
||||
char *charset = NULL;
|
||||
gpointer bdata;
|
||||
gsize bsize;
|
||||
|
||||
/* url must be an URI as defined in RFC 2397
|
||||
* data:[<mediatype>][;base64],<data>
|
||||
*/
|
||||
if (g_ascii_strncasecmp ("data:", url, 5) != 0)
|
||||
{
|
||||
g_set_error (error,
|
||||
G_IO_ERROR,
|
||||
G_IO_ERROR_INVALID_FILENAME,
|
||||
_("Not a data: URL"));
|
||||
return NULL;
|
||||
}
|
||||
|
||||
url += 5;
|
||||
|
||||
parameters_start = strchr (url, ';');
|
||||
data_start = strchr (url, ',');
|
||||
if (data_start == NULL)
|
||||
{
|
||||
g_set_error (error,
|
||||
G_IO_ERROR,
|
||||
G_IO_ERROR_INVALID_FILENAME,
|
||||
_("Malformed data: URL"));
|
||||
return NULL;
|
||||
}
|
||||
if (parameters_start > data_start)
|
||||
parameters_start = NULL;
|
||||
|
||||
if (data_start != url && parameters_start != url)
|
||||
{
|
||||
mimetype = g_strndup (url,
|
||||
(parameters_start ? parameters_start
|
||||
: data_start) - url);
|
||||
}
|
||||
else
|
||||
{
|
||||
mimetype = NULL;
|
||||
}
|
||||
|
||||
if (parameters_start != NULL)
|
||||
{
|
||||
char *parameters_str;
|
||||
char **parameters;
|
||||
guint i;
|
||||
|
||||
parameters_str = g_strndup (parameters_start + 1, data_start - parameters_start - 1);
|
||||
parameters = g_strsplit (parameters_str, ";", -1);
|
||||
|
||||
for (i = 0; parameters[i] != NULL; i++)
|
||||
{
|
||||
if (g_ascii_strcasecmp ("base64", parameters[i]) == 0)
|
||||
{
|
||||
base64 = TRUE;
|
||||
}
|
||||
else if (g_ascii_strncasecmp ("charset=", parameters[i], 8) == 0)
|
||||
{
|
||||
g_free (charset);
|
||||
charset = g_strdup (parameters[i] + 8);
|
||||
}
|
||||
}
|
||||
g_free (parameters_str);
|
||||
g_strfreev (parameters);
|
||||
}
|
||||
|
||||
/* Skip comma */
|
||||
data_start += 1;
|
||||
if (base64)
|
||||
{
|
||||
bdata = g_base64_decode (data_start, &bsize);
|
||||
}
|
||||
else
|
||||
{
|
||||
/* URI encoded, i.e. "percent" encoding */
|
||||
/* XXX: This doesn't allow nul bytes */
|
||||
bdata = g_uri_unescape_string (data_start, NULL);
|
||||
if (bdata == NULL)
|
||||
{
|
||||
g_set_error (error,
|
||||
G_IO_ERROR,
|
||||
G_IO_ERROR_INVALID_FILENAME,
|
||||
_("Could not unescape string"));
|
||||
g_free (mimetype);
|
||||
return NULL;
|
||||
}
|
||||
bsize = strlen (bdata);
|
||||
}
|
||||
|
||||
/* Convert to UTF8 */
|
||||
if ((mimetype == NULL || g_ascii_strcasecmp ("text/plain", mimetype) == 0) &&
|
||||
charset && g_ascii_strcasecmp ("US-ASCII", charset) != 0
|
||||
&& g_ascii_strcasecmp ("UTF-8", charset) != 0)
|
||||
{
|
||||
gsize read;
|
||||
gsize written;
|
||||
gpointer data;
|
||||
|
||||
data = g_convert_with_fallback (bdata, bsize,
|
||||
"UTF-8", charset,
|
||||
(char *) "*",
|
||||
&read, &written, NULL);
|
||||
g_free (bdata);
|
||||
|
||||
bdata = data;
|
||||
bsize = written;
|
||||
}
|
||||
bytes = g_bytes_new_take (bdata, bsize);
|
||||
|
||||
g_free (charset);
|
||||
if (out_mimetype)
|
||||
*out_mimetype = mimetype;
|
||||
else
|
||||
g_free (mimetype);
|
||||
|
||||
return bytes;
|
||||
}
|
35
gtk/css/gtkcssdataurlprivate.h
Normal file
35
gtk/css/gtkcssdataurlprivate.h
Normal file
@ -0,0 +1,35 @@
|
||||
/*
|
||||
* Copyright © 2019 Benjamin Otte
|
||||
*
|
||||
* 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 <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
* Authors: Benjamin Otte <otte@gnome.org>
|
||||
*/
|
||||
|
||||
|
||||
#ifndef __GTK_CSS_DATA_URL_PRIVATE_H__
|
||||
#define __GTK_CSS_DATA_URL_PRIVATE_H__
|
||||
|
||||
#include <gio/gio.h>
|
||||
|
||||
G_BEGIN_DECLS
|
||||
|
||||
GBytes * gtk_css_data_url_parse (const char *url,
|
||||
char **out_mimetype,
|
||||
GError **error);
|
||||
|
||||
G_END_DECLS
|
||||
|
||||
#endif /* __GTK_CSS_DATA_URL_PRIVATE_H__ */
|
||||
|
@ -335,7 +335,9 @@ gtk_css_parser_consume_token (GtkCssParser *self)
|
||||
/* unpreserved tokens MUST be consumed via start_block() */
|
||||
g_assert (gtk_css_token_is_preserved (&self->token, NULL));
|
||||
|
||||
gtk_css_token_clear (&self->token);
|
||||
/* Don't consume any tokens at the end of a block */
|
||||
if (!gtk_css_token_is (gtk_css_parser_peek_token (self), GTK_CSS_TOKEN_EOF))
|
||||
gtk_css_token_clear (&self->token);
|
||||
}
|
||||
|
||||
void
|
||||
@ -435,7 +437,15 @@ gtk_css_parser_end_block (GtkCssParser *self)
|
||||
else
|
||||
{
|
||||
g_array_set_size (self->blocks, self->blocks->len - 1);
|
||||
gtk_css_parser_skip (self);
|
||||
if (gtk_css_token_is_preserved (&self->token, NULL))
|
||||
{
|
||||
gtk_css_token_clear (&self->token);
|
||||
}
|
||||
else
|
||||
{
|
||||
gtk_css_parser_start_block (self);
|
||||
gtk_css_parser_end_block (self);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -963,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);
|
||||
@ -988,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
|
||||
|
@ -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,
|
||||
|
@ -5,6 +5,7 @@ gtk_css_public_sources = files([
|
||||
])
|
||||
|
||||
gtk_css_private_sources = files([
|
||||
'gtkcssdataurl.c',
|
||||
'gtkcssparser.c',
|
||||
'gtkcsstokenizer.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);
|
||||
|
@ -27,6 +27,8 @@
|
||||
#include "gtkcssimagepaintableprivate.h"
|
||||
#include "gtkstyleproviderprivate.h"
|
||||
|
||||
#include "gtk/css/gtkcssdataurlprivate.h"
|
||||
|
||||
G_DEFINE_TYPE (GtkCssImageUrl, _gtk_css_image_url, GTK_TYPE_CSS_IMAGE)
|
||||
|
||||
static GtkCssImage *
|
||||
@ -163,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;
|
||||
}
|
||||
|
||||
|
@ -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)
|
||||
|
@ -78,7 +78,6 @@ gtk_test_init (int *argcp,
|
||||
g_test_init (argcp, argvp, NULL);
|
||||
gtk_disable_setlocale();
|
||||
setlocale (LC_ALL, "en_US.UTF-8");
|
||||
g_test_bug_base ("http://bugzilla.gnome.org/show_bug.cgi?id=%s");
|
||||
|
||||
/* XSendEvent() doesn't work yet on XI2 events.
|
||||
* So at the moment gdk_test_simulate_* can only
|
||||
|
@ -27,7 +27,7 @@ test_popover_parent (void)
|
||||
GtkWidget *p;
|
||||
AtkObject *a;
|
||||
|
||||
g_test_bug ("733923");
|
||||
/*http://bugzilla.gnome.org/show_bug.cgi?id=733923 */
|
||||
|
||||
w = gtk_entry_new ();
|
||||
|
||||
@ -50,8 +50,6 @@ main (int argc, char *argv[])
|
||||
{
|
||||
gtk_test_init (&argc, &argv, NULL);
|
||||
|
||||
g_test_bug_base ("http://bugzilla.gnome.org/");
|
||||
|
||||
g_test_add_func ("/popover/accessible-parent", test_popover_parent);
|
||||
|
||||
return g_test_run ();
|
||||
|
@ -1064,7 +1064,7 @@ test_bold_label (void)
|
||||
AtkObject *atk_obj;
|
||||
gchar *text;
|
||||
|
||||
g_test_bug ("126797");
|
||||
/*http://bugzilla.gnome.org/show_bug.cgi?id=126797 */
|
||||
|
||||
label = gtk_label_new ("<b>Bold?</b>");
|
||||
g_object_ref_sink (label);
|
||||
@ -1089,8 +1089,6 @@ main (int argc, char *argv[])
|
||||
{
|
||||
gtk_test_init (&argc, &argv, NULL);
|
||||
|
||||
g_test_bug_base ("http://bugzilla.gnome.org/");
|
||||
|
||||
g_test_add_func ("/text/bold/GtkLabel", test_bold_label);
|
||||
|
||||
add_text_tests (gtk_label_new (""));
|
||||
|
@ -119,8 +119,6 @@ main (int argc, char *argv[])
|
||||
{
|
||||
gtk_test_init (&argc, &argv, NULL);
|
||||
|
||||
g_test_bug_base ("http://bugzilla.gnome.org/");
|
||||
|
||||
add_value_tests (gtk_spin_button_new_with_range (0, 100, 1));
|
||||
add_value_tests (gtk_level_bar_new_for_interval (0, 100));
|
||||
|
||||
|
100
testsuite/css/data.c
Normal file
100
testsuite/css/data.c
Normal file
@ -0,0 +1,100 @@
|
||||
/*
|
||||
* Copyright © 2019 Benjamin Otte
|
||||
*
|
||||
* 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 <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
* Authors: Benjamin Otte <otte@gnome.org>
|
||||
*/
|
||||
|
||||
#include "../../gtk/css/gtkcssdataurlprivate.h"
|
||||
|
||||
#include <locale.h>
|
||||
|
||||
typedef struct _Test Test;
|
||||
|
||||
struct _Test
|
||||
{
|
||||
const char *name;
|
||||
const char *url;
|
||||
const char *mimetype;
|
||||
const char *contents;
|
||||
gsize contents_len;
|
||||
};
|
||||
|
||||
#define CONTENTS(data) (data), sizeof(data) - 1
|
||||
Test tests[] = {
|
||||
{ "simple",
|
||||
"data:,HelloWorld",
|
||||
NULL, CONTENTS("HelloWorld") },
|
||||
{ "nodata",
|
||||
"data:,",
|
||||
NULL, CONTENTS("") },
|
||||
{ "case_sensitive",
|
||||
"dATa:,HelloWorld",
|
||||
NULL, CONTENTS("HelloWorld") },
|
||||
{ "semicolon_after_comma",
|
||||
"data:,;base64",
|
||||
NULL, CONTENTS(";base64") },
|
||||
{ "mimetype",
|
||||
"data:image/png,nopng",
|
||||
"image/png", CONTENTS("nopng") },
|
||||
{ "charset",
|
||||
"data:text/plain;charset=ISO-8859-1,Timm B\344der",
|
||||
"text/plain", CONTENTS("Timm Bäder") },
|
||||
{ "charset_base64",
|
||||
"data:text/plain;charset=ISO-8859-5;base64,wOPh29DdILjW0ePb0OLe0g==",
|
||||
"text/plain", CONTENTS("Руслан Ижбулатов") },
|
||||
};
|
||||
|
||||
static void
|
||||
test_parse (gconstpointer data)
|
||||
{
|
||||
const Test *test = data;
|
||||
GError *error = NULL;
|
||||
char *mimetype = NULL;
|
||||
GBytes *bytes;
|
||||
|
||||
bytes = gtk_css_data_url_parse (test->url, &mimetype, &error);
|
||||
|
||||
g_assert (bytes != NULL);
|
||||
g_assert_no_error (error);
|
||||
if (test->mimetype == NULL)
|
||||
g_assert (mimetype == NULL);
|
||||
else
|
||||
g_assert_cmpstr (mimetype, ==, test->mimetype);
|
||||
|
||||
g_assert_cmpmem (g_bytes_get_data (bytes, NULL), g_bytes_get_size (bytes),
|
||||
test->contents, test->contents_len);
|
||||
|
||||
g_bytes_unref (bytes);
|
||||
}
|
||||
|
||||
int
|
||||
main (int argc, char *argv[])
|
||||
{
|
||||
guint i;
|
||||
|
||||
g_test_init (&argc, &argv, NULL);
|
||||
setlocale (LC_ALL, "C");
|
||||
|
||||
for (i = 0; i < G_N_ELEMENTS (tests); i++)
|
||||
{
|
||||
char *name = g_strdup_printf ("/css/data/load/%s", tests[i].name);
|
||||
g_test_add_data_func (name, &tests[i], test_parse);
|
||||
g_free (name);
|
||||
}
|
||||
|
||||
return g_test_run ();
|
||||
}
|
||||
|
@ -20,6 +20,22 @@ test('api', test_api,
|
||||
],
|
||||
suite: 'css')
|
||||
|
||||
test_data = executable('data', ['data.c', '../../gtk/css/gtkcssdataurl.c'],
|
||||
include_directories: [confinc, ],
|
||||
dependencies: gtk_deps,
|
||||
install: get_option('install-tests'),
|
||||
install_dir: testexecdir)
|
||||
test('data', test_data,
|
||||
args: ['--tap', '-k' ],
|
||||
env: [ 'GIO_USE_VOLUME_MONITOR=unix',
|
||||
'GSETTINGS_BACKEND=memory',
|
||||
'GTK_CSD=1',
|
||||
'G_ENABLE_DIAGNOSTIC=0',
|
||||
'G_TEST_SRCDIR=@0@'.format(meson.current_source_dir()),
|
||||
'G_TEST_BUILDDIR=@0@'.format(meson.current_build_dir())
|
||||
],
|
||||
suite: 'css')
|
||||
|
||||
if get_option('install-tests')
|
||||
conf = configuration_data()
|
||||
conf.set('libexecdir', gtk_libexecdir)
|
||||
|
@ -181,8 +181,6 @@ main (int argc, char *argv[])
|
||||
|
||||
g_test_init (&argc, &argv, NULL);
|
||||
|
||||
g_test_bug_base ("http://bugzilla.gnome.org");
|
||||
|
||||
enum_class = g_type_class_ref (GDK_TYPE_MEMORY_FORMAT);
|
||||
|
||||
for (format = 0; format < GDK_MEMORY_N_FORMATS; format++)
|
||||
|
@ -72,8 +72,6 @@ main (int argc, char *argv[])
|
||||
|
||||
gtk_init ();
|
||||
|
||||
g_test_bug_base ("http://bugzilla.gnome.org/");
|
||||
|
||||
g_test_add_func ("/rectangle/equal", test_rectangle_equal);
|
||||
g_test_add_func ("/rectangle/intersect", test_rectangle_intersect);
|
||||
g_test_add_func ("/rectangle/union", test_rectangle_union);
|
||||
|
@ -121,7 +121,7 @@ test_color_parse_nonsense (void)
|
||||
GdkRGBA color;
|
||||
gboolean res;
|
||||
|
||||
g_test_bug ("667485");
|
||||
/*http://bugzilla.gnome.org/show_bug.cgi?id=667485 */
|
||||
|
||||
res = gdk_rgba_parse (&color, "rgb(,,)");
|
||||
g_assert (!res);
|
||||
@ -151,14 +151,12 @@ test_color_parse_nonsense (void)
|
||||
int
|
||||
main (int argc, char *argv[])
|
||||
{
|
||||
g_test_init (&argc, &argv, NULL);
|
||||
g_test_init (&argc, &argv, NULL);
|
||||
|
||||
g_test_bug_base ("http://bugzilla.gnome.org");
|
||||
g_test_add_func ("/rgba/parse", test_color_parse);
|
||||
g_test_add_func ("/rgba/parse/nonsense", test_color_parse_nonsense);
|
||||
g_test_add_func ("/rgba/to-string", test_color_to_string);
|
||||
g_test_add_func ("/rgba/copy", test_color_copy);
|
||||
|
||||
g_test_add_func ("/rgba/parse", test_color_parse);
|
||||
g_test_add_func ("/rgba/parse/nonsense", test_color_parse_nonsense);
|
||||
g_test_add_func ("/rgba/to-string", test_color_to_string);
|
||||
g_test_add_func ("/rgba/copy", test_color_copy);
|
||||
|
||||
return g_test_run ();
|
||||
return g_test_run ();
|
||||
}
|
||||
|
@ -111,8 +111,6 @@ main (int argc, char *argv[])
|
||||
|
||||
gtk_init ();
|
||||
|
||||
g_test_bug_base ("http://bugzilla.gnome.org/");
|
||||
|
||||
g_test_add_func ("/seat/list", test_list_seats);
|
||||
g_test_add_func ("/seat/default", test_default_seat);
|
||||
|
||||
|
@ -61,7 +61,8 @@ deserialize_error_func (const GtkCssSection *section,
|
||||
{
|
||||
char *section_str = gtk_css_section_to_string (section);
|
||||
|
||||
g_error ("Error at %s: %s", section_str, error->message);
|
||||
g_test_message ("Error at %s: %s", section_str, error->message);
|
||||
g_test_fail ();
|
||||
|
||||
free (section_str);
|
||||
}
|
||||
|
11
testsuite/gsk/compare/texture-url.node
Normal file
11
testsuite/gsk/compare/texture-url.node
Normal file
@ -0,0 +1,11 @@
|
||||
/* Add a color node to blow up the bounds so that
|
||||
we can test the texture bounds work. */
|
||||
color {
|
||||
bounds: 0 0 50 50;
|
||||
color: white;
|
||||
}
|
||||
|
||||
texture {
|
||||
bounds: 10 10 30 30;
|
||||
texture: url('data:,<svg><rect width="10" height="10" style="fill:red"/></svg>');
|
||||
}
|
BIN
testsuite/gsk/compare/texture-url.png
Normal file
BIN
testsuite/gsk/compare/texture-url.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 179 B |
@ -26,8 +26,11 @@ serialize_deserialize = executable(
|
||||
)
|
||||
|
||||
compare_render_tests = [
|
||||
'blend-normal',
|
||||
'blend-difference',
|
||||
'clip-coordinates-3d',
|
||||
'clipped_rounded_clip',
|
||||
'color-blur0',
|
||||
'cross-fade-in-opacity',
|
||||
'opacity_clip',
|
||||
'outset_shadow_offset_both',
|
||||
@ -36,9 +39,7 @@ compare_render_tests = [
|
||||
'outset_shadow_rounded_top',
|
||||
'outset_shadow_simple',
|
||||
'shadow-in-opacity',
|
||||
'blend-normal',
|
||||
'blend-difference',
|
||||
'color-blur0',
|
||||
'texture-url',
|
||||
]
|
||||
|
||||
renderers = [
|
||||
|
File diff suppressed because one or more lines are too long
@ -454,7 +454,6 @@ main (int argc, char *argv[])
|
||||
|
||||
g_test_init (&argc, &argv, NULL);
|
||||
setlocale (LC_ALL, "C");
|
||||
g_test_bug_base ("http://bugzilla.gnome.org/show_bug.cgi?id=%s");
|
||||
|
||||
create_masks ();
|
||||
|
||||
|
@ -745,7 +745,6 @@ int
|
||||
main (int argc, char *argv[])
|
||||
{
|
||||
gtk_test_init (&argc, &argv);
|
||||
g_test_bug_base ("http://bugzilla.gnome.org/");
|
||||
gtk_test_register_all_types();
|
||||
|
||||
g_test_add_func ("/tests/iconview-new", test_iconview_new);
|
||||
|
@ -311,7 +311,6 @@ main (int argc, char *argv[])
|
||||
{
|
||||
g_test_init (&argc, &argv, NULL);
|
||||
setlocale (LC_ALL, "C");
|
||||
g_test_bug_base ("http://bugzilla.gnome.org/show_bug.cgi?id=%s");
|
||||
|
||||
number_quark = g_quark_from_static_string ("Hell and fire was spawned to be released.");
|
||||
changes_quark = g_quark_from_static_string ("What did I see? Can I believe what I saw?");
|
||||
|
@ -5727,7 +5727,7 @@ specific_bug_301558 (void)
|
||||
int i;
|
||||
gboolean add;
|
||||
|
||||
g_test_bug ("301558");
|
||||
/*http://bugzilla.gnome.org/show_bug.cgi?id=301558 */
|
||||
|
||||
tree = gtk_tree_store_new (2, G_TYPE_INT, G_TYPE_BOOLEAN);
|
||||
gtk_tree_store_append (tree, &iter, NULL);
|
||||
@ -5803,7 +5803,7 @@ specific_bug_311955 (void)
|
||||
int n;
|
||||
GtkTreePath *path;
|
||||
|
||||
g_test_bug ("311955");
|
||||
/*http://bugzilla.gnome.org/show_bug.cgi?id=311955 */
|
||||
|
||||
store = gtk_tree_store_new (1, G_TYPE_INT);
|
||||
|
||||
@ -5972,7 +5972,7 @@ specific_bug_346800 (void)
|
||||
store = gtk_tree_store_newv (2, columns);
|
||||
model = GTK_TREE_MODEL (store);
|
||||
|
||||
g_test_bug ("346800");
|
||||
/*http://bugzilla.gnome.org/show_bug.cgi?id=346800 */
|
||||
|
||||
filter = GTK_TREE_MODEL_FILTER (gtk_tree_model_filter_new (model, NULL));
|
||||
gtk_tree_model_filter_set_visible_column (filter, 1);
|
||||
@ -6031,7 +6031,7 @@ specific_bug_464173 (void)
|
||||
GtkWidget *view G_GNUC_UNUSED;
|
||||
gboolean visible = TRUE;
|
||||
|
||||
g_test_bug ("464173");
|
||||
/*http://bugzilla.gnome.org/show_bug.cgi?id=464173 */
|
||||
|
||||
model = gtk_tree_store_new (1, G_TYPE_STRING);
|
||||
gtk_tree_store_append (model, &iter1, NULL);
|
||||
@ -6075,7 +6075,7 @@ specific_bug_540201 (void)
|
||||
|
||||
GtkWidget *tree_view G_GNUC_UNUSED;
|
||||
|
||||
g_test_bug ("540201");
|
||||
/*http://bugzilla.gnome.org/show_bug.cgi?id=540201 */
|
||||
|
||||
store = gtk_tree_store_new (1, G_TYPE_INT);
|
||||
|
||||
@ -6128,7 +6128,7 @@ specific_bug_549287 (void)
|
||||
GtkTreeIter iter;
|
||||
GtkTreeIter *swap, *parent, *child;
|
||||
|
||||
g_test_bug ("529287");
|
||||
/*http://bugzilla.gnome.org/show_bug.cgi?id=529287 */
|
||||
|
||||
store = gtk_tree_store_new (1, G_TYPE_STRING);
|
||||
filtered = gtk_tree_model_filter_new (GTK_TREE_MODEL (store), NULL);
|
||||
@ -6227,7 +6227,7 @@ specific_bug_621076 (void)
|
||||
GtkTreeIter item_iter;
|
||||
SignalMonitor *monitor;
|
||||
|
||||
g_test_bug ("621076");
|
||||
/*http://bugzilla.gnome.org/show_bug.cgi?id=621076 */
|
||||
|
||||
store = gtk_tree_store_new (1, G_TYPE_STRING);
|
||||
filter = gtk_tree_model_filter_new (GTK_TREE_MODEL (store), NULL);
|
||||
|
@ -356,7 +356,6 @@ main (int argc, char *argv[])
|
||||
{
|
||||
g_test_init (&argc, &argv, NULL);
|
||||
setlocale (LC_ALL, "C");
|
||||
g_test_bug_base ("http://bugzilla.gnome.org/show_bug.cgi?id=%s");
|
||||
|
||||
number_quark = g_quark_from_static_string ("Hell and fire was spawned to be released.");
|
||||
changes_quark = g_quark_from_static_string ("What did I see? Can I believe what I saw?");
|
||||
|
@ -22,7 +22,6 @@ main (int argc, char *argv[])
|
||||
g_test_init (&argc, &argv, NULL);
|
||||
gtk_disable_setlocale();
|
||||
setlocale (LC_ALL, "C");
|
||||
g_test_bug_base ("http://bugzilla.gnome.org/show_bug.cgi?id=%s");
|
||||
|
||||
g_test_add_func ("/main/init", test_init);
|
||||
|
||||
|
@ -286,7 +286,6 @@ main (int argc, char *argv[])
|
||||
{
|
||||
g_test_init (&argc, &argv, NULL);
|
||||
setlocale (LC_ALL, "C");
|
||||
g_test_bug_base ("http://bugzilla.gnome.org/show_bug.cgi?id=%s");
|
||||
|
||||
number_quark = g_quark_from_static_string ("Hell and fire was spawned to be released.");
|
||||
changes_quark = g_quark_from_static_string ("What did I see? Can I believe what I saw?");
|
||||
|
@ -49,7 +49,6 @@ main (int argc,
|
||||
g_test_init (&argc, &argv, NULL);
|
||||
g_setenv ("GTK_MODULES", "", TRUE);
|
||||
setlocale (LC_ALL, "C");
|
||||
g_test_bug_base ("http://bugzilla.gnome.org/show_bug.cgi?id=%s");
|
||||
|
||||
|
||||
g_test_add_func ("/no_gtk_init/gdk_cairo_set_source_pixbuf", test_gdk_cairo_set_source_pixbuf);
|
||||
|
@ -292,7 +292,6 @@ main (int argc, char *argv[])
|
||||
{
|
||||
g_test_init (&argc, &argv, NULL);
|
||||
setlocale (LC_ALL, "C");
|
||||
g_test_bug_base ("http://bugzilla.gnome.org/show_bug.cgi?id=%s");
|
||||
|
||||
g_test_add_func ("/rbtree/crash", test_crash);
|
||||
g_test_add_func ("/rbtree/crash2", test_crash2);
|
||||
|
@ -514,7 +514,6 @@ main (int argc,
|
||||
{
|
||||
g_test_init (&argc, &argv, NULL);
|
||||
setlocale (LC_ALL, "C");
|
||||
g_test_bug_base ("http://bugzilla.gnome.org/show_bug.cgi?id=%s");
|
||||
|
||||
g_test_add_func ("/rbtree/create", test_create);
|
||||
g_test_add_func ("/rbtree/insert_after", test_insert_after);
|
||||
|
@ -647,7 +647,6 @@ main (int argc, char *argv[])
|
||||
{
|
||||
g_test_init (&argc, &argv, NULL);
|
||||
setlocale (LC_ALL, "C");
|
||||
g_test_bug_base ("http://bugzilla.gnome.org/show_bug.cgi?id=%s");
|
||||
|
||||
number_quark = g_quark_from_static_string ("Hell and fire was spawned to be released.");
|
||||
changes_quark = g_quark_from_static_string ("What did I see? Can I believe what I saw?");
|
||||
|
@ -324,7 +324,6 @@ main (int argc, char *argv[])
|
||||
{
|
||||
g_test_init (&argc, &argv, NULL);
|
||||
setlocale (LC_ALL, "C");
|
||||
g_test_bug_base ("http://bugzilla.gnome.org/show_bug.cgi?id=%s");
|
||||
|
||||
number_quark = g_quark_from_static_string ("Hell and fire was spawned to be released.");
|
||||
changes_quark = g_quark_from_static_string ("What did I see? Can I believe what I saw?");
|
||||
|
@ -385,7 +385,6 @@ main (int argc, char *argv[])
|
||||
{
|
||||
g_test_init (&argc, &argv, NULL);
|
||||
setlocale (LC_ALL, "C");
|
||||
g_test_bug_base ("http://bugzilla.gnome.org/show_bug.cgi?id=%s");
|
||||
|
||||
number_quark = g_quark_from_static_string ("Hell and fire was spawned to be released.");
|
||||
changes_quark = g_quark_from_static_string ("What did I see? Can I believe what I saw?");
|
||||
|
@ -1040,7 +1040,7 @@ specific_bug_300089 (void)
|
||||
GtkTreePath *path;
|
||||
GtkTreeIter iter, iter2, sort_iter;
|
||||
|
||||
g_test_bug ("300089");
|
||||
/*http://bugzilla.gnome.org/show_bug.cgi?id=300089 */
|
||||
|
||||
child_model = GTK_TREE_MODEL (gtk_tree_store_new (1, G_TYPE_STRING));
|
||||
|
||||
@ -1084,7 +1084,7 @@ specific_bug_364946 (void)
|
||||
GtkTreeIter a, aa, aaa, aab, iter;
|
||||
GtkTreeModel *s_model;
|
||||
|
||||
g_test_bug ("364946");
|
||||
/*http://bugzilla.gnome.org/show_bug.cgi?id=364946 */
|
||||
|
||||
store = gtk_tree_store_new (1, G_TYPE_STRING);
|
||||
|
||||
@ -1187,7 +1187,7 @@ specific_bug_698846 (void)
|
||||
GtkTreeIter iter;
|
||||
guint count = 0;
|
||||
|
||||
g_test_bug ("698846");
|
||||
/*http://bugzilla.gnome.org/show_bug.cgi?id=698846 */
|
||||
|
||||
store = gtk_list_store_new (1, G_TYPE_STRING);
|
||||
sorted = gtk_tree_model_sort_new_with_model (GTK_TREE_MODEL (store));
|
||||
@ -1228,7 +1228,7 @@ sort_column_change (void)
|
||||
GtkSortType order;
|
||||
gboolean ret;
|
||||
|
||||
g_test_bug ("792459");
|
||||
/*http://bugzilla.gnome.org/show_bug.cgi?id=792459 */
|
||||
|
||||
store = gtk_list_store_new (1, G_TYPE_STRING);
|
||||
sorted = gtk_tree_model_sort_new_with_model (GTK_TREE_MODEL (store));
|
||||
|
@ -254,7 +254,6 @@ main (int argc, char *argv[])
|
||||
{
|
||||
g_test_init (&argc, &argv, NULL);
|
||||
setlocale (LC_ALL, "C");
|
||||
g_test_bug_base ("http://bugzilla.gnome.org/show_bug.cgi?id=%s");
|
||||
|
||||
number_quark = g_quark_from_static_string ("Hell and fire was spawned to be released.");
|
||||
changes_quark = g_quark_from_static_string ("What did I see? Can I believe what I saw?");
|
||||
|
@ -25,8 +25,6 @@ main (int argc,
|
||||
{
|
||||
gtk_test_init (&argc, &argv, NULL);
|
||||
|
||||
g_test_bug_base ("http://bugzilla.gnome.org/");
|
||||
|
||||
register_list_store_tests ();
|
||||
register_tree_store_tests ();
|
||||
register_model_ref_count_tests ();
|
||||
|
@ -1026,7 +1026,7 @@ specific_bug_77977 (void)
|
||||
|
||||
/* Stripped down version of test case for bug 77977 by Damon Chaplin */
|
||||
|
||||
g_test_bug ("77977");
|
||||
/*http://bugzilla.gnome.org/show_bug.cgi?id=77977 */
|
||||
|
||||
tree_store = gtk_tree_store_new (1, G_TYPE_STRING);
|
||||
|
||||
@ -1064,7 +1064,7 @@ specific_bug_698396 (void)
|
||||
GtkTreeStore *tree_store;
|
||||
gint new_order[1] = { 0 };
|
||||
|
||||
g_test_bug ("698396");
|
||||
/*http://bugzilla.gnome.org/show_bug.cgi?id=698396 */
|
||||
|
||||
tree_store = gtk_tree_store_new (1, G_TYPE_STRING);
|
||||
|
||||
|
@ -26,7 +26,7 @@ test_bug_546005 (void)
|
||||
GtkListStore *list_store;
|
||||
GtkWidget *view;
|
||||
|
||||
g_test_bug ("546005");
|
||||
/*http://bugzilla.gnome.org/show_bug.cgi?id=546005 */
|
||||
|
||||
/* Tests provided by Bjorn Lindqvist, Paul Pogonyshev */
|
||||
view = gtk_tree_view_new ();
|
||||
@ -78,7 +78,7 @@ test_bug_539377 (void)
|
||||
GtkTreePath *path;
|
||||
GtkListStore *list_store;
|
||||
|
||||
g_test_bug ("539377");
|
||||
/*http://bugzilla.gnome.org/show_bug.cgi?id=539377 */
|
||||
|
||||
/* Test provided by Bjorn Lindqvist */
|
||||
|
||||
@ -236,7 +236,7 @@ test_selection_count (void)
|
||||
GtkTreeSelection *selection;
|
||||
GtkWidget *view;
|
||||
|
||||
g_test_bug ("702957");
|
||||
/*http://bugzilla.gnome.org/show_bug.cgi?id=702957 */
|
||||
|
||||
list_store = gtk_list_store_new (1, G_TYPE_STRING);
|
||||
view = gtk_tree_view_new_with_model (GTK_TREE_MODEL (list_store));
|
||||
@ -299,7 +299,7 @@ test_selection_empty (void)
|
||||
GtkWidget *view;
|
||||
GtkTreeIter iter;
|
||||
|
||||
g_test_bug ("712760");
|
||||
/*http://bugzilla.gnome.org/show_bug.cgi?id=712760 */
|
||||
|
||||
list_store = gtk_list_store_new (1, G_TYPE_STRING);
|
||||
view = gtk_tree_view_new_with_model (GTK_TREE_MODEL (list_store));
|
||||
@ -340,7 +340,6 @@ main (int argc,
|
||||
char **argv)
|
||||
{
|
||||
gtk_test_init (&argc, &argv, NULL);
|
||||
g_test_bug_base ("http://bugzilla.gnome.org/");
|
||||
|
||||
g_test_add_func ("/TreeView/cursor/bug-546005", test_bug_546005);
|
||||
g_test_add_func ("/TreeView/cursor/bug-539377", test_bug_539377);
|
||||
|
@ -218,7 +218,7 @@ test_show_hide (void)
|
||||
GtkWidget *window;
|
||||
gint w, h, w1, h1;
|
||||
|
||||
g_test_bug ("696882");
|
||||
/*http://bugzilla.gnome.org/show_bug.cgi?id=696882 */
|
||||
|
||||
/* test that hide/show does not affect the size */
|
||||
|
||||
@ -258,7 +258,6 @@ main (int argc, char *argv[])
|
||||
gint i;
|
||||
|
||||
gtk_test_init (&argc, &argv);
|
||||
g_test_bug_base ("http://bugzilla.gnome.org/");
|
||||
|
||||
for (i = 0; i < argc; i++)
|
||||
{
|
||||
|
3
testsuite/reftests/data-url.css
Normal file
3
testsuite/reftests/data-url.css
Normal file
@ -0,0 +1,3 @@
|
||||
.background {
|
||||
background: red url('data:,<svg><rect width="20" height="20" style="fill:lime"/></svg>');
|
||||
}
|
12
testsuite/reftests/data-url.ref.ui
Normal file
12
testsuite/reftests/data-url.ref.ui
Normal file
@ -0,0 +1,12 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<interface>
|
||||
<object class="GtkWindow">
|
||||
<property name="type">popup</property>
|
||||
<child>
|
||||
<object class="GtkPicture">
|
||||
<property name="can-shrink">0</property>
|
||||
<property name="paintable">green-20x20.png</property>
|
||||
</object>
|
||||
</child>
|
||||
</object>
|
||||
</interface>
|
8
testsuite/reftests/data-url.ui
Normal file
8
testsuite/reftests/data-url.ui
Normal file
@ -0,0 +1,8 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<interface>
|
||||
<object class="GtkWindow" id="window1">
|
||||
<property name="width_request">20</property>
|
||||
<property name="height_request">20</property>
|
||||
<property name="type">popup</property>
|
||||
</object>
|
||||
</interface>
|
@ -194,6 +194,9 @@ testdata = [
|
||||
'css-multi-state.css',
|
||||
'css-multi-state.ref.ui',
|
||||
'css-multi-state.ui',
|
||||
'data-url.css',
|
||||
'data-url.ref.ui',
|
||||
'data-url.ui',
|
||||
'fixed-widget-stacking.ref.ui',
|
||||
'fixed-widget-stacking.ui',
|
||||
'flipping-icons.ref.ui',
|
||||
|
Loading…
Reference in New Issue
Block a user