[gtk] rendernodeparser: Parse Cairo nodes
- From: Benjamin Otte <otte src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gtk] rendernodeparser: Parse Cairo nodes
- Date: Sat, 25 May 2019 22:51:59 +0000 (UTC)
commit 928c85ccc390bcd0285609373ea7859cfe072f10
Author: Benjamin Otte <otte redhat com>
Date: Sun May 26 00:50:13 2019 +0200
rendernodeparser: Parse Cairo nodes
We also print the script, but we don't parse it yet.
gsk/gskrendernode.h | 2 +-
gsk/gskrendernodeimpl.c | 2 +-
gsk/gskrendernodeparser.c | 138 +++++++++++++++++++++-----
testsuite/gsk/compare/empty-cairo.node | 1 +
testsuite/gsk/compare/empty-cairo.png | Bin 0 -> 153 bytes
testsuite/gsk/meson.build | 3 +
testsuite/gsk/nodeparser/empty-cairo.node | 1 +
testsuite/gsk/nodeparser/empty-cairo.ref.node | 5 +
8 files changed, 126 insertions(+), 26 deletions(-)
---
diff --git a/gsk/gskrendernode.h b/gsk/gskrendernode.h
index cdb59a46f4..79f0c6a059 100644
--- a/gsk/gskrendernode.h
+++ b/gsk/gskrendernode.h
@@ -189,7 +189,7 @@ GskRenderNode * gsk_cairo_node_new (const graphene_
GDK_AVAILABLE_IN_ALL
cairo_t * gsk_cairo_node_get_draw_context (GskRenderNode *node);
GDK_AVAILABLE_IN_ALL
-const cairo_surface_t * gsk_cairo_node_peek_surface (GskRenderNode *node);
+cairo_surface_t * gsk_cairo_node_peek_surface (GskRenderNode *node);
GDK_AVAILABLE_IN_ALL
GskRenderNode * gsk_container_node_new (GskRenderNode **children,
diff --git a/gsk/gskrendernodeimpl.c b/gsk/gskrendernodeimpl.c
index ec66c7f14b..32e5d57827 100644
--- a/gsk/gskrendernodeimpl.c
+++ b/gsk/gskrendernodeimpl.c
@@ -1582,7 +1582,7 @@ static const GskRenderNodeClass GSK_CAIRO_NODE_CLASS = {
gsk_render_node_diff_impossible,
};
-const cairo_surface_t *
+cairo_surface_t *
gsk_cairo_node_peek_surface (GskRenderNode *node)
{
GskCairoNode *self = (GskCairoNode *) node;
diff --git a/gsk/gskrendernodeparser.c b/gsk/gskrendernodeparser.c
index ab7b3bd2a8..937e7d796f 100644
--- a/gsk/gskrendernodeparser.c
+++ b/gsk/gskrendernodeparser.c
@@ -33,6 +33,10 @@
#include "gtk/css/gtkcssdataurlprivate.h"
#include "gtk/css/gtkcssparserprivate.h"
+#ifdef CAIRO_HAS_SCRIPT_SURFACE
+#include <cairo-script.h>
+#endif
+
typedef struct _Declaration Declaration;
struct _Declaration
@@ -768,6 +772,30 @@ parse_declarations (GtkCssParser *parser,
return parsed;
}
+static GdkTexture *
+create_default_texture (void)
+{
+ static const guint32 pixels[100] = {
+ 0xFFFF00CC, 0xFFFF00CC, 0xFFFF00CC, 0xFFFF00CC, 0xFFFF00CC, 0, 0, 0, 0, 0,
+ 0xFFFF00CC, 0xFFFF00CC, 0xFFFF00CC, 0xFFFF00CC, 0xFFFF00CC, 0, 0, 0, 0, 0,
+ 0xFFFF00CC, 0xFFFF00CC, 0xFFFF00CC, 0xFFFF00CC, 0xFFFF00CC, 0, 0, 0, 0, 0,
+ 0xFFFF00CC, 0xFFFF00CC, 0xFFFF00CC, 0xFFFF00CC, 0xFFFF00CC, 0, 0, 0, 0, 0,
+ 0xFFFF00CC, 0xFFFF00CC, 0xFFFF00CC, 0xFFFF00CC, 0xFFFF00CC, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0xFFFF00CC, 0xFFFF00CC, 0xFFFF00CC, 0xFFFF00CC, 0xFFFF00CC,
+ 0, 0, 0, 0, 0, 0xFFFF00CC, 0xFFFF00CC, 0xFFFF00CC, 0xFFFF00CC, 0xFFFF00CC,
+ 0, 0, 0, 0, 0, 0xFFFF00CC, 0xFFFF00CC, 0xFFFF00CC, 0xFFFF00CC, 0xFFFF00CC,
+ 0, 0, 0, 0, 0, 0xFFFF00CC, 0xFFFF00CC, 0xFFFF00CC, 0xFFFF00CC, 0xFFFF00CC,
+ 0, 0, 0, 0, 0, 0xFFFF00CC, 0xFFFF00CC, 0xFFFF00CC, 0xFFFF00CC, 0xFFFF00CC };
+ GBytes *bytes;
+ GdkTexture *texture;
+
+ bytes = g_bytes_new_static ((guchar *) pixels, 400);
+ texture = gdk_memory_texture_new (10, 10, GDK_MEMORY_DEFAULT, bytes, 40);
+ g_bytes_unref (bytes);
+
+ return texture;
+}
+
static GskRenderNode *
create_default_render_node (void)
{
@@ -873,23 +901,7 @@ parse_texture_node (GtkCssParser *parser)
parse_declarations (parser, declarations, G_N_ELEMENTS(declarations));
if (texture == NULL)
- {
- static const guint32 pixels[100] = {
- 0xFFFF00CC, 0xFFFF00CC, 0xFFFF00CC, 0xFFFF00CC, 0xFFFF00CC, 0, 0, 0, 0, 0,
- 0xFFFF00CC, 0xFFFF00CC, 0xFFFF00CC, 0xFFFF00CC, 0xFFFF00CC, 0, 0, 0, 0, 0,
- 0xFFFF00CC, 0xFFFF00CC, 0xFFFF00CC, 0xFFFF00CC, 0xFFFF00CC, 0, 0, 0, 0, 0,
- 0xFFFF00CC, 0xFFFF00CC, 0xFFFF00CC, 0xFFFF00CC, 0xFFFF00CC, 0, 0, 0, 0, 0,
- 0xFFFF00CC, 0xFFFF00CC, 0xFFFF00CC, 0xFFFF00CC, 0xFFFF00CC, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0xFFFF00CC, 0xFFFF00CC, 0xFFFF00CC, 0xFFFF00CC, 0xFFFF00CC,
- 0, 0, 0, 0, 0, 0xFFFF00CC, 0xFFFF00CC, 0xFFFF00CC, 0xFFFF00CC, 0xFFFF00CC,
- 0, 0, 0, 0, 0, 0xFFFF00CC, 0xFFFF00CC, 0xFFFF00CC, 0xFFFF00CC, 0xFFFF00CC,
- 0, 0, 0, 0, 0, 0xFFFF00CC, 0xFFFF00CC, 0xFFFF00CC, 0xFFFF00CC, 0xFFFF00CC,
- 0, 0, 0, 0, 0, 0xFFFF00CC, 0xFFFF00CC, 0xFFFF00CC, 0xFFFF00CC, 0xFFFF00CC };
- GBytes *bytes = g_bytes_new_static ((guchar *) pixels, 400);
-
- texture = gdk_memory_texture_new (10, 10, GDK_MEMORY_DEFAULT, bytes, 40);
- g_bytes_unref (bytes);
- }
+ texture = create_default_texture ();
node = gsk_texture_node_new (texture, &bounds);
g_object_unref (texture);
@@ -897,6 +909,44 @@ parse_texture_node (GtkCssParser *parser)
return node;
}
+static GskRenderNode *
+parse_cairo_node (GtkCssParser *parser)
+{
+ graphene_rect_t bounds = GRAPHENE_RECT_INIT (0, 0, 50, 50);
+ GdkTexture *pixels = NULL;
+ const Declaration declarations[] = {
+ { "bounds", parse_rect, NULL, &bounds },
+ { "pixels", parse_texture, clear_texture, &pixels }
+ };
+ GskRenderNode *node;
+ cairo_t *cr;
+
+ parse_declarations (parser, declarations, G_N_ELEMENTS(declarations));
+
+ node = gsk_cairo_node_new (&bounds);
+
+ cr = gsk_cairo_node_get_draw_context (node);
+
+ if (pixels != NULL)
+ {
+ cairo_surface_t *surface;
+ surface = gdk_texture_download_surface (pixels);
+ cairo_set_source_surface (cr, surface, 0, 0);
+ cairo_paint (cr);
+ cairo_surface_destroy (surface);
+ }
+ else
+ {
+ gdk_cairo_set_source_rgba (cr, &GDK_RGBA ("FF00CC"));
+ cairo_paint (cr);
+ }
+
+ cairo_destroy (cr);
+ g_clear_object (&pixels);
+
+ return node;
+}
+
static GskRenderNode *
parse_outset_shadow_node (GtkCssParser *parser)
{
@@ -1325,10 +1375,7 @@ parse_node (GtkCssParser *parser,
{ "debug", parse_debug_node },
{ "blend", parse_blend_node },
{ "repeat", parse_repeat_node },
-#if 0
{ "cairo", parse_cairo_node },
-#endif
-
};
GskRenderNode **node_p = out_node;
guint i;
@@ -1696,9 +1743,9 @@ append_node_param (Printer *p,
}
static cairo_status_t
-surface_write (void *closure,
- const unsigned char *data,
- unsigned int length)
+cairo_write_array (void *closure,
+ const unsigned char *data,
+ unsigned int length)
{
g_byte_array_append (closure, data, length);
@@ -1988,7 +2035,7 @@ render_node_print (Printer *p,
surface = gdk_texture_download_surface (texture);
array = g_byte_array_new ();
- cairo_surface_write_to_png_stream (surface, surface_write, array);
+ cairo_surface_write_to_png_stream (surface, cairo_write_array, array);
b64 = g_base64_encode (array->data, array->len);
_indent (p);
@@ -2170,6 +2217,49 @@ render_node_print (Printer *p,
break;
case GSK_CAIRO_NODE:
+ {
+ cairo_surface_t *surface = gsk_cairo_node_peek_surface (node);
+ GByteArray *array;
+ char *b64;
+
+ start_node (p, "cairo");
+ append_rect_param (p, "bounds", &node->bounds);
+
+ array = g_byte_array_new ();
+ cairo_surface_write_to_png_stream (surface, cairo_write_array, array);
+ b64 = g_base64_encode (array->data, array->len);
+
+ _indent (p);
+ g_string_append_printf (p->str, "pixels: url(\"data:image/png;base64,%s\");\n", b64);
+
+ g_free (b64);
+ g_byte_array_free (array, TRUE);
+
+#ifdef CAIRO_HAS_SCRIPT_SURFACE
+ if (cairo_surface_get_type (surface) == CAIRO_SURFACE_TYPE_RECORDING)
+ {
+ cairo_device_t *script;
+
+ array = g_byte_array_new ();
+ script = cairo_script_create_for_stream (cairo_write_array, array);
+
+ if (cairo_script_from_recording_surface (script, surface) == CAIRO_STATUS_SUCCESS)
+ {
+ b64 = g_base64_encode (array->data, array->len);
+ _indent (p);
+ g_string_append_printf (p->str, "script: url(\"data:;base64,%s\");\n", b64);
+ g_free (b64);
+ }
+
+ cairo_device_destroy (script);
+ g_byte_array_free (array, TRUE);
+ }
+#endif
+
+ end_node (p);
+ }
+ break;
+
case GSK_REPEATING_LINEAR_GRADIENT_NODE:
default:
g_error ("Unhandled node: %s", node->node_class->type_name);
diff --git a/testsuite/gsk/compare/empty-cairo.node b/testsuite/gsk/compare/empty-cairo.node
new file mode 100644
index 0000000000..1987994306
--- /dev/null
+++ b/testsuite/gsk/compare/empty-cairo.node
@@ -0,0 +1 @@
+cairo { }
diff --git a/testsuite/gsk/compare/empty-cairo.png b/testsuite/gsk/compare/empty-cairo.png
new file mode 100644
index 0000000000..3a032a391b
Binary files /dev/null and b/testsuite/gsk/compare/empty-cairo.png differ
diff --git a/testsuite/gsk/meson.build b/testsuite/gsk/meson.build
index 4751dfd537..4f469603a9 100644
--- a/testsuite/gsk/meson.build
+++ b/testsuite/gsk/meson.build
@@ -27,6 +27,7 @@ compare_render_tests = [
'empty-blend',
'empty-blur',
'empty-border',
+ 'empty-cairo',
'empty-clip',
'empty-color',
'empty-color-matrix',
@@ -101,6 +102,8 @@ node_parser_tests = [
'empty-blur.ref.node',
'empty-border.node',
'empty-border.ref.node',
+ 'empty-cairo.node',
+ 'empty-cairo.ref.node',
'empty-clip.node',
'empty-clip.ref.node',
'empty-color.node',
diff --git a/testsuite/gsk/nodeparser/empty-cairo.node b/testsuite/gsk/nodeparser/empty-cairo.node
new file mode 100644
index 0000000000..1987994306
--- /dev/null
+++ b/testsuite/gsk/nodeparser/empty-cairo.node
@@ -0,0 +1 @@
+cairo { }
diff --git a/testsuite/gsk/nodeparser/empty-cairo.ref.node b/testsuite/gsk/nodeparser/empty-cairo.ref.node
new file mode 100644
index 0000000000..4dca846961
--- /dev/null
+++ b/testsuite/gsk/nodeparser/empty-cairo.ref.node
@@ -0,0 +1,5 @@
+cairo {
+ bounds: 0 0 50 50;
+ pixels:
url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAADIAAAAyCAIAAACRXR/mAAAABmJLR0QA/wD/AP+gvaeTAAAATklEQVRYhe3OMQHAIADAMJh/aXgCA3t6wZEoyNxjjfd8twP/tAqtQqvQKrQKrUKr0Cq0Cq1Cq9AqtAqtQqvQKrQKrUKr0Cq0Cq1Cq9AqDsEHAi9RKkB7AAAAAElFTkSuQmCC");
+ script:
url("data:;base64,JSFDYWlyb1NjcmlwdAo8PCAvY29udGVudCAvL0NPTE9SX0FMUEhBIC93aWR0aCA1MCAvaGVpZ2h0IDUwID4+IHN1cmZhY2UgY29udGV4dAoxIDAgMC44IHJnYiBzZXQtc291cmNlCnBhaW50CnBvcAo=");
+}
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]