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.
This commit is contained in:
184
gdk/gdkrgba.c
184
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,183 @@ 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;
|
||||
|
||||
switch (arg)
|
||||
{
|
||||
case 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;
|
||||
return 1;
|
||||
|
||||
case 1:
|
||||
if (!parse_color_channel_value (parser, &rgba->green, rgba->alpha != 0.0))
|
||||
return 0;
|
||||
return 1;
|
||||
|
||||
case 2:
|
||||
if (!parse_color_channel_value (parser, &rgba->blue, rgba->alpha != 0.0))
|
||||
return 0;
|
||||
return 1;
|
||||
|
||||
case 3:
|
||||
if (!gtk_css_parser_consume_number (parser, &rgba->alpha))
|
||||
return 0;
|
||||
|
||||
rgba->alpha = CLAMP (rgba->alpha, 0.0, 1.0);
|
||||
return 1;
|
||||
|
||||
default:
|
||||
g_assert_not_reached ();
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
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' }))
|
||||
{
|
||||
gtk_css_parser_error_value (parser, "Hash code is not a valid hex color.");
|
||||
return FALSE;
|
||||
}
|
||||
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] }))
|
||||
{
|
||||
gtk_css_parser_error_value (parser, "Hash code is not a valid hex color.");
|
||||
return FALSE;
|
||||
}
|
||||
break;
|
||||
|
||||
case 6:
|
||||
if (!rgba_init_chars (rgba, (char[8]) {s[0], s[1], s[2], s[3], s[4], s[5], 'F', 'F' }))
|
||||
{
|
||||
gtk_css_parser_error_value (parser, "Hash code is not a valid hex color.");
|
||||
return FALSE;
|
||||
}
|
||||
break;
|
||||
|
||||
case 8:
|
||||
if (!rgba_init_chars (rgba, s))
|
||||
{
|
||||
gtk_css_parser_error_value (parser, "Hash code is not a valid hex color.");
|
||||
return FALSE;
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
gtk_css_parser_error_value (parser, "Hash code is not a valid hex color.");
|
||||
return FALSE;
|
||||
break;
|
||||
}
|
||||
|
||||
gtk_css_parser_consume_token (parser);
|
||||
return TRUE;
|
||||
}
|
||||
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_syntax (parser, "\"%s\" is not a valid 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;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
33
gdk/gdkrgbaprivate.h
Normal file
33
gdk/gdkrgbaprivate.h
Normal file
@@ -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
|
||||
@@ -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])
|
||||
|
||||
Reference in New Issue
Block a user