summaryrefslogtreecommitdiff
path: root/pango/pango-color.c
diff options
context:
space:
mode:
authorMatthias Clasen <matthiasc@src.gnome.org>2002-09-22 22:42:47 +0000
committerMatthias Clasen <matthiasc@src.gnome.org>2002-09-22 22:42:47 +0000
commit9534f3311d23e1ff48fd747b8568064946350e4d (patch)
tree5f4c1cfb04006ee7913ea4079de77b757b3875e1 /pango/pango-color.c
parentcd8f626345fdf182a927e36eb1af613590a9bdce (diff)
downloadpango-9534f3311d23e1ff48fd747b8568064946350e4d.tar.gz
Make color parsing more robust and correct. (#93804)
* pango/pango-color.c (pango_color_parse): Make color parsing more robust and correct. (#93804) * tests/testcolor.c: Tests for pango_color_parse. * tests/Makefile.am: Build testcolor. * tests/runtests.sh: Run testcolor.
Diffstat (limited to 'pango/pango-color.c')
-rw-r--r--pango/pango-color.c84
1 files changed, 42 insertions, 42 deletions
diff --git a/pango/pango-color.c b/pango/pango-color.c
index b9d8b357..9e831587 100644
--- a/pango/pango-color.c
+++ b/pango/pango-color.c
@@ -914,6 +914,21 @@ find_color(const char *name,
return TRUE;
}
+static gboolean
+hex (const char *spec,
+ int len,
+ unsigned int *c)
+{
+ const char *end;
+ *c = 0;
+ for (end = spec + len; spec != end; spec++)
+ if (g_ascii_isxdigit (*spec))
+ *c = (*c << 4) | g_ascii_xdigit_value (*spec);
+ else
+ return FALSE;
+ return TRUE;
+}
+
/**
* pango_color_parse:
* @color: a #PangoColor structure in which to store the result
@@ -934,55 +949,41 @@ gboolean
pango_color_parse (PangoColor *color,
const char *spec)
{
+ g_return_val_if_fail (spec != NULL, FALSE);
+
if (spec[0] == '#')
{
- char fmt[16];
- int i, r, g, b;
+ size_t len;
+ unsigned int r, g, b;
- if ((i = strlen (spec+1)) % 3)
+ spec++;
+ len = strlen (spec);
+ if (len % 3 || len < 3 || len > 12)
return FALSE;
+
+ len /= 3;
- i /= 3;
+ if (!hex (spec, len, &r) ||
+ !hex (spec + len, len, &g) ||
+ !hex (spec + len * 2, len, &b))
+ return FALSE;
- sprintf (fmt, "%%%dx%%%dx%%%dx", i, i, i);
- if (sscanf (spec+1, fmt, &r, &g, &b) != 3)
- return FALSE;
-
- if (i == 4)
- {
- if (color)
+ if (color)
+ {
+ int bits = len * 4;
+ r <<= 16 - bits;
+ g <<= 16 - bits;
+ b <<= 16 - bits;
+ while (bits < 16)
{
- color->red = r;
- color->green = g;
- color->blue = b;
- }
- }
- else if (i == 1)
- {
- if (color)
- {
- color->red = (r * 65535) / 15;
- color->green = (g * 65535) / 15;
- color->blue = (b * 65535) / 15;
- }
- }
- else if (i == 2)
- {
- if (color)
- {
- color->red = (r * 65535) / 255;
- color->green = (g * 65535) / 255;
- color->blue = (b * 65535) / 255;
- }
- }
- else /* if (i == 3) */
- {
- if (color)
- {
- color->red = (r * 65535) / 4095;
- color->green = (g * 65535) / 4095;
- color->blue = (b * 65535) / 4095;
+ r |= (r >> bits);
+ g |= (g >> bits);
+ b |= (b >> bits);
+ bits *= 2;
}
+ color->red = r;
+ color->green = g;
+ color->blue = b;
}
}
else
@@ -990,6 +991,5 @@ pango_color_parse (PangoColor *color,
if (!find_color (spec, color))
return FALSE;
}
-
return TRUE;
}