From d810646b94eab2f00592bb4476b8f32937f7c2c5 Mon Sep 17 00:00:00 2001 From: Michael Drake Date: Sun, 5 Dec 2010 00:05:01 +0000 Subject: Add support for rgba() colours. Thanks jmb. svn path=/trunk/libcss/; revision=10993 --- src/parse/properties/utils.c | 49 +++++++++++++++++++++++++++++++++++--------- src/parse/propstrings.c | 1 + src/parse/propstrings.h | 3 ++- test/data/parse/colours.dat | 16 +++++++++++++++ 4 files changed, 58 insertions(+), 11 deletions(-) diff --git a/src/parse/properties/utils.c b/src/parse/properties/utils.c index 7d0da45..c1c8b16 100644 --- a/src/parse/properties/utils.c +++ b/src/parse/properties/utils.c @@ -39,6 +39,7 @@ css_error parse_colour_specifier(css_language *c, /* IDENT() | HASH(rgb | rrggbb) | * FUNCTION(rgb) [ [ NUMBER | PERCENTAGE ] ',' ] {3} ')' + * FUNCTION(rgba) [ [ NUMBER | PERCENTAGE ] ',' ] {4} ')' * * For quirks, NUMBER | DIMENSION | IDENT, too * I.E. "123456" -> NUMBER, "1234f0" -> DIMENSION, "f00000" -> IDENT @@ -91,18 +92,31 @@ css_error parse_colour_specifier(css_language *c, return error; } else if (token->type == CSS_TOKEN_FUNCTION) { + int colour_channels = 0; + if ((lwc_string_caseless_isequal( token->idata, c->strings[RGB], &match) == lwc_error_ok && match)) { + colour_channels = 3; + } else if ((lwc_string_caseless_isequal( + token->idata, c->strings[RGBA], + &match) == lwc_error_ok && match)) { + colour_channels = 4; + } + + if (colour_channels == 3 || colour_channels == 4) { int i; css_token_type valid = CSS_TOKEN_NUMBER; + uint8_t *components[4] = { &r, &g, &b, &a }; - for (i = 0; i < 3; i++) { + for (i = 0; i < colour_channels; i++) { + uint8_t *component; css_fixed num; size_t consumed = 0; - uint8_t *component = i == 0 ? &r - : i == 1 ? &g : &b; int32_t intval; + bool int_only; + + component = components[i]; consumeWhitespace(vector, ctx); @@ -115,17 +129,29 @@ css_error parse_colour_specifier(css_language *c, if (i == 0) valid = token->type; - else if (token->type != valid) + else if (i < 3 && token->type != valid) goto invalid; + /* The alpha channel may be a float */ + if (i < 3) + int_only = (valid == CSS_TOKEN_NUMBER); + else + int_only = false; + num = number_from_lwc_string(token->idata, - valid == CSS_TOKEN_NUMBER, - &consumed); + int_only, &consumed); if (consumed != lwc_string_length(token->idata)) goto invalid; if (valid == CSS_TOKEN_NUMBER) { - intval = FIXTOINT(num); + if (i == 3) { + /* alpha channel */ + intval = FIXTOINT( + FMULI(num, 255)); + } else { + /* colour channels */ + intval = FIXTOINT(num); + } } else { intval = FIXTOINT( FDIVI(FMULI(num, 255), 100)); @@ -146,12 +172,15 @@ css_error parse_colour_specifier(css_language *c, if (token == NULL) goto invalid; - if (i != 2 && tokenIsChar(token, ',')) + if (i != (colour_channels - 1) && + tokenIsChar(token, ',')) { parserutils_vector_iterate(vector, ctx); - else if (i == 2 && tokenIsChar(token, ')')) + } else if (i == (colour_channels - 1) && + tokenIsChar(token, ')')) { parserutils_vector_iterate(vector, ctx); - else + } else { goto invalid; + } } } else goto invalid; diff --git a/src/parse/propstrings.c b/src/parse/propstrings.c index 699b750..ef71235 100644 --- a/src/parse/propstrings.c +++ b/src/parse/propstrings.c @@ -330,6 +330,7 @@ const stringmap_entry stringmap[LAST_KNOWN] = { { "line-through", SLEN("line-through") }, { "blink", SLEN("blink") }, { "rgb", SLEN("rgb") }, + { "rgba", SLEN("rgba") }, { "-libcss-left", SLEN("-libcss-left") }, { "-libcss-center", SLEN("-libcss-center") }, { "-libcss-right", SLEN("-libcss-right") }, diff --git a/src/parse/propstrings.h b/src/parse/propstrings.h index f33fe78..ea16b44 100644 --- a/src/parse/propstrings.h +++ b/src/parse/propstrings.h @@ -84,7 +84,8 @@ enum { NE_RESIZE, NW_RESIZE, N_RESIZE, SE_RESIZE, SW_RESIZE, S_RESIZE, W_RESIZE, TEXT, WAIT, HELP, PROGRESS, SERIF, SANS_SERIF, CURSIVE, FANTASY, MONOSPACE, MALE, FEMALE, CHILD, MIX, UNDERLINE, OVERLINE, - LINE_THROUGH, BLINK, RGB, LIBCSS_LEFT, LIBCSS_CENTER, LIBCSS_RIGHT, + LINE_THROUGH, BLINK, RGB, RGBA, LIBCSS_LEFT, LIBCSS_CENTER, + LIBCSS_RIGHT, /* Named colours */ FIRST_COLOUR, diff --git a/test/data/parse/colours.dat b/test/data/parse/colours.dat index 1e7b940..f359a68 100644 --- a/test/data/parse/colours.dat +++ b/test/data/parse/colours.dat @@ -74,3 +74,19 @@ | 0x02000018 0xff000000 #reset +#data +* { color: rgba(255, 0, 0, 0) } +#errors +#expected +| 1 * +| 0x02000018 0x00ff0000 +#reset + +#data +* { color: rgba(255, 0, 0, 0.5) } +#errors +#expected +| 1 * +| 0x02000018 0x7fff0000 +#reset + -- cgit v1.2.3