[gtk/wip/otte/css: 28/28] rgba: Add gdk_rgba_parser_parse()
- From: Benjamin Otte <otte src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gtk/wip/otte/css: 28/28] rgba: Add gdk_rgba_parser_parse()
- Date: Sat, 6 Apr 2019 00:52:57 +0000 (UTC)
commit 8182658258c4c7c4e570cc1fa9c3c2ee3a2810dc
Author: Benjamin Otte <otte redhat com>
Date: Sat Apr 6 02:40:29 2019 +0200
rgba: Add gdk_rgba_parser_parse()
This function is a (private) function to parse a GdkRGBA accoridng to
the CSS specs. We should probably use it for gdk_rgba_parse(), but that
would change the syntax we accept there...
This also introduces a dependency of libgdk on libgtkcss.
So far, no users for this function exist.
gdk/gdkrgba.c | 170 ++++++++++++++++++++++++++++++++++++++++++++++++++-
gdk/gdkrgbaprivate.h | 33 ++++++++++
gdk/meson.build | 5 +-
3 files changed, 205 insertions(+), 3 deletions(-)
---
diff --git a/gdk/gdkrgba.c b/gdk/gdkrgba.c
index 8e36523dc2..7e59548739 100644
--- a/gdk/gdkrgba.c
+++ b/gdk/gdkrgba.c
@@ -23,7 +23,9 @@
*/
#include "config.h"
-#include "gdkrgba.h"
+
+#include "gdkrgbaprivate.h"
+
#include <string.h>
#include <errno.h>
#include <math.h>
@@ -393,3 +395,169 @@ gdk_rgba_to_string (const GdkRGBA *rgba)
alpha);
}
}
+
+static gboolean
+parse_color_channel_value (GtkCssParser *parser,
+ double *value,
+ gboolean is_percentage)
+{
+ if (is_percentage)
+ {
+ if (!gtk_css_parser_consume_percentage (parser, value))
+ return FALSE;
+
+ *value = CLAMP (*value, 0.0, 100.0) / 100.0;
+ return TRUE;
+ }
+ else
+ {
+ if (!gtk_css_parser_consume_number (parser, value))
+ return FALSE;
+
+ *value = CLAMP (*value, 0.0, 255.0) / 255.0;
+ return TRUE;
+ }
+}
+
+static guint
+parse_color_channel (GtkCssParser *parser,
+ guint arg,
+ gpointer data)
+{
+ GdkRGBA *rgba = data;
+
+ if (arg == 0)
+ {
+ /* We abuse rgba->alpha to store if we use percentages or numbers */
+ if (gtk_css_token_is (gtk_css_parser_get_token (parser), GTK_CSS_TOKEN_PERCENTAGE))
+ rgba->alpha = 1.0;
+ else
+ rgba->alpha = 0.0;
+
+ if (!parse_color_channel_value (parser, &rgba->red, rgba->alpha != 0.0))
+ return 0;
+ }
+ else if (arg == 1)
+ {
+ if (!parse_color_channel_value (parser, &rgba->green, rgba->alpha != 0.0))
+ return 0;
+ }
+ else if (arg == 2)
+ {
+ if (!parse_color_channel_value (parser, &rgba->blue, rgba->alpha != 0.0))
+ return 0;
+ }
+ else if (arg == 3)
+ {
+ if (!gtk_css_parser_consume_number (parser, &rgba->alpha))
+ return FALSE;
+
+ rgba->alpha = CLAMP (rgba->alpha, 0.0, 1.0);
+ }
+ else
+ {
+ g_assert_not_reached ();
+ }
+
+ return 1;
+}
+
+static gboolean
+rgba_init_chars (GdkRGBA *rgba,
+ const char s[8])
+{
+ guint i;
+
+ for (i = 0; i < 8; i++)
+ {
+ if (!g_ascii_isxdigit (s[i]))
+ return FALSE;
+ }
+
+ rgba->red = (g_ascii_xdigit_value (s[0]) * 16 + g_ascii_xdigit_value (s[1])) / 255.0;
+ rgba->green = (g_ascii_xdigit_value (s[2]) * 16 + g_ascii_xdigit_value (s[3])) / 255.0;
+ rgba->blue = (g_ascii_xdigit_value (s[4]) * 16 + g_ascii_xdigit_value (s[5])) / 255.0;
+ rgba->alpha = (g_ascii_xdigit_value (s[6]) * 16 + g_ascii_xdigit_value (s[7])) / 255.0;
+
+ return TRUE;
+}
+
+gboolean
+gdk_rgba_parser_parse (GtkCssParser *parser,
+ GdkRGBA *rgba)
+{
+ const GtkCssToken *token;
+
+ token = gtk_css_parser_get_token (parser);
+ if (gtk_css_token_is_function (token, "rgb"))
+ {
+ if (!gtk_css_parser_consume_function (parser, 3, 3, parse_color_channel, rgba))
+ return FALSE;
+
+ rgba->alpha = 1.0;
+ return TRUE;
+ }
+ else if (gtk_css_token_is_function (token, "rgba"))
+ {
+ return gtk_css_parser_consume_function (parser, 4, 4, parse_color_channel, rgba);
+ }
+ else if (gtk_css_token_is (token, GTK_CSS_TOKEN_HASH_ID) ||
+ gtk_css_token_is (token, GTK_CSS_TOKEN_HASH_UNRESTRICTED))
+ {
+ const char *s = token->string.string;
+
+ switch (strlen (s))
+ {
+ case 3:
+ if (rgba_init_chars (rgba, (char[8]) {s[0], s[0], s[1], s[1], s[2], s[2], 'F', 'F' }))
+ return TRUE;
+ break;
+
+ case 4:
+ if (rgba_init_chars (rgba, (char[8]) {s[0], s[0], s[1], s[1], s[2], s[2], s[3], s[3] }))
+ return TRUE;
+ break;
+
+ case 6:
+ if (rgba_init_chars (rgba, (char[8]) {s[0], s[1], s[2], s[3], s[4], s[5], 'F', 'F' }))
+ return TRUE;
+ break;
+
+ case 8:
+ if (rgba_init_chars (rgba, s))
+ return TRUE;
+ break;
+
+ default:
+ break;
+ }
+
+ gtk_css_parser_error_value (parser, "Hash code is not a valid hex color.");
+ return FALSE;
+ }
+ else if (gtk_css_token_is (token, GTK_CSS_TOKEN_IDENT))
+ {
+ if (gtk_css_token_is_ident (token, "transparent"))
+ {
+ rgba = &(GdkRGBA) { 0, 0, 0, 0 };
+ }
+ else if (gdk_rgba_parse (rgba, token->string.string))
+ {
+ /* everything's fine */
+ }
+ else
+ {
+ gtk_css_parser_error_value (parser, "\"%s\" is not a known color name.", token->string.string);
+ return FALSE;
+ }
+
+ gtk_css_parser_consume_token (parser);
+ return TRUE;
+ }
+ else
+ {
+ gtk_css_parser_error_syntax (parser, "Expected a valid color.");
+ return FALSE;
+ }
+}
+
diff --git a/gdk/gdkrgbaprivate.h b/gdk/gdkrgbaprivate.h
new file mode 100644
index 0000000000..58470e04c9
--- /dev/null
+++ b/gdk/gdkrgbaprivate.h
@@ -0,0 +1,33 @@
+/* GDK - The GIMP Drawing Kit
+ * Copyright (C) 2010, Red Hat, Inc
+ *
+ * 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 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/>.
+ */
+
+#ifndef __GDK_RGBA_PRIVATE_H__
+#define __GDK_RGBA_PRIVATE_H__
+
+#include "gdkrgba.h"
+
+#include <gtk/css/gtkcss.h>
+
+#include "gtk/css/gtkcssparserprivate.h"
+
+
+gboolean gdk_rgba_parser_parse (GtkCssParser *parser,
+ GdkRGBA *rgba);
+
+G_END_DECLS
+
+#endif
diff --git a/gdk/meson.build b/gdk/meson.build
index 44170dbae8..b2bf69620a 100644
--- a/gdk/meson.build
+++ b/gdk/meson.build
@@ -224,7 +224,8 @@ endif
# FIXME: might have to add '-xobjective-c' to c_args for quartz backend?
libgdk = static_library('gdk',
sources: [gdk_sources, gdk_backends_gen_headers, gdkconfig],
- dependencies: gdk_deps,
+ dependencies: gdk_deps + [libgtk_css_dep],
+ link_with: [libgtk_css, ],
include_directories: [confinc, gdkx11_inc, wlinc],
c_args: [
'-DGDK_COMPILATION',
@@ -239,4 +240,4 @@ libgdk = static_library('gdk',
libgdk_dep = declare_dependency(
sources: ['gdk.h', gdkconfig, gdkenum_h],
include_directories: [confinc, gdkx11_inc, wlinc],
- dependencies: gdk_deps)
+ dependencies: gdk_deps + [libgtk_css_dep])
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]