From b4f5baf4fa031a2ba8d7aef0bf9215c513995985 Mon Sep 17 00:00:00 2001 From: Benjamin Otte Date: Sat, 27 Apr 2019 09:03:51 +0200 Subject: [PATCH] rendernode: Parse and print blend nodes properly --- gsk/gskrendernodeparser.c | 93 ++++++++++++++++++- testsuite/gsk/meson.build | 3 +- testsuite/gsk/serializedeserialize/blend.node | 16 ++++ 3 files changed, 107 insertions(+), 5 deletions(-) create mode 100644 testsuite/gsk/serializedeserialize/blend.node diff --git a/gsk/gskrendernodeparser.c b/gsk/gskrendernodeparser.c index 9ebf4aab24..ea640c01e8 100644 --- a/gsk/gskrendernodeparser.c +++ b/gsk/gskrendernodeparser.c @@ -374,6 +374,49 @@ parse_shadows (GtkCssParser *parser, return parse_semicolon (parser); } +static const struct +{ + GskBlendMode mode; + const char *name; +} blend_modes[] = { + { GSK_BLEND_MODE_DEFAULT, "normal" }, + { GSK_BLEND_MODE_MULTIPLY, "multiply" }, + { GSK_BLEND_MODE_SCREEN, "screen" }, + { GSK_BLEND_MODE_OVERLAY, "overlay" }, + { GSK_BLEND_MODE_DARKEN, "darken" }, + { GSK_BLEND_MODE_LIGHTEN, "lighten" }, + { GSK_BLEND_MODE_COLOR_DODGE, "color-dodge" }, + { GSK_BLEND_MODE_COLOR_BURN, "color-burn" }, + { GSK_BLEND_MODE_HARD_LIGHT, "hard-light" }, + { GSK_BLEND_MODE_SOFT_LIGHT, "soft-light" }, + { GSK_BLEND_MODE_DIFFERENCE, "difference" }, + { GSK_BLEND_MODE_EXCLUSION, "exclusion" }, + { GSK_BLEND_MODE_COLOR, "color" }, + { GSK_BLEND_MODE_HUE, "hue" }, + { GSK_BLEND_MODE_SATURATION, "saturation" }, + { GSK_BLEND_MODE_LUMINOSITY, "luminosity" } +}; + +static gboolean +parse_blend_mode (GtkCssParser *parser, + gpointer out_mode) +{ + guint i; + + for (i = 0; i < G_N_ELEMENTS (blend_modes); i++) + { + if (gtk_css_parser_try_ident (parser, blend_modes[i].name)) + { + if (!parse_semicolon (parser)) + return FALSE; + *(GskBlendMode *) out_mode = blend_modes[i].mode; + return TRUE; + } + } + + return FALSE; +} + static gboolean parse_font (GtkCssParser *parser, gpointer out_font) @@ -827,6 +870,39 @@ parse_cross_fade_node (GtkCssParser *parser) return result; } +static GskRenderNode * +parse_blend_node (GtkCssParser *parser) +{ + GskRenderNode *bottom = NULL; + GskRenderNode *top = NULL; + GskBlendMode mode = GSK_BLEND_MODE_DEFAULT; + const Declaration declarations[] = { + { "mode", parse_blend_mode, &mode }, + { "bottom", parse_node, &bottom }, + { "top", parse_node, &top }, + }; + GskRenderNode *result; + + parse_declarations (parser, declarations, G_N_ELEMENTS(declarations)); + if (bottom == NULL || top == NULL) + { + if (bottom == NULL) + gtk_css_parser_error_syntax (parser, "Missing \"bottom\" property definition"); + if (top == NULL) + gtk_css_parser_error_syntax (parser, "Missing \"top\" property definition"); + g_clear_pointer (&bottom, gsk_render_node_unref); + g_clear_pointer (&top, gsk_render_node_unref); + return NULL; + } + + result = gsk_blend_node_new (bottom, top, mode); + + gsk_render_node_unref (bottom); + gsk_render_node_unref (top); + + return result; +} + static GskRenderNode * parse_text_node (GtkCssParser *parser) { @@ -1013,9 +1089,9 @@ parse_node (GtkCssParser *parser, { "cross-fade", parse_cross_fade_node }, { "text", parse_text_node }, { "blur", parse_blur_node }, - { "debug", parse_debug_node } -#if 0 + { "debug", parse_debug_node }, { "blend", parse_blend_node }, +#if 0 { "repeat", parse_repeat_node }, { "cairo", parse_cairo_node }, #endif @@ -1737,11 +1813,20 @@ render_node_print (Printer *p, case GSK_BLEND_NODE: { + GskBlendMode mode = gsk_blend_node_get_blend_mode (node); + guint i; + start_node (p, "blend"); _indent (p); - /* TODO: (de)serialize enums! */ - g_string_append_printf (p->str, "mode = %d\n", gsk_blend_node_get_blend_mode (node)); + for (i = 0; i < G_N_ELEMENTS (blend_modes); i++) + { + if (blend_modes[i].mode == mode) + { + g_string_append_printf (p->str, "mode: %s;\n", blend_modes[i].name); + break; + } + } append_node_param (p, "top", gsk_blend_node_get_top_child (node)); append_node_param (p, "bottom", gsk_blend_node_get_bottom_child (node)); diff --git a/testsuite/gsk/meson.build b/testsuite/gsk/meson.build index c89594afe1..6223866089 100644 --- a/testsuite/gsk/meson.build +++ b/testsuite/gsk/meson.build @@ -85,8 +85,9 @@ foreach test : node_parser_tests endforeach serialize_deserialize_tests = [ - 'color', + 'blend', 'border', + 'color', 'shadow', 'testswitch', 'widgetfactory', diff --git a/testsuite/gsk/serializedeserialize/blend.node b/testsuite/gsk/serializedeserialize/blend.node new file mode 100644 index 0000000000..0b228ade85 --- /dev/null +++ b/testsuite/gsk/serializedeserialize/blend.node @@ -0,0 +1,16 @@ +blend { + bottom: container { } + top: container { } +} + +blend { + top: container { } + mode: color-dodge; + bottom: container { } +} + +blend { + top: color { } + bottom: color { } + mode: difference; +}