From 51af89dc9d475cf40751eaee8401fbc8a272a0da Mon Sep 17 00:00:00 2001 From: John Mark Bell Date: Sun, 11 Jan 2009 13:00:33 +0000 Subject: Beginnings of a colour specifier parser. svn path=/trunk/libcss/; revision=6037 --- src/lex/lex.c | 41 --------------------------- src/parse/properties.c | 75 ++++++++++++++++++++++++++++++++++++++++++++----- src/parse/propstrings.h | 5 ++-- src/utils/utils.h | 40 ++++++++++++++++++++++++++ 4 files changed, 111 insertions(+), 50 deletions(-) diff --git a/src/lex/lex.c b/src/lex/lex.c index 3ee01a7..ad513c9 100644 --- a/src/lex/lex.c +++ b/src/lex/lex.c @@ -159,7 +159,6 @@ static inline css_error consumeUnicode(css_lexer *lexer, uint32_t ucs); static inline css_error consumeURLChars(css_lexer *lexer); static inline css_error consumeWChars(css_lexer *lexer); -static inline uint32_t charToHex(uint8_t c); static inline bool startNMChar(uint8_t c); static inline bool startNMStart(uint8_t c); static inline bool startStringChar(uint8_t c); @@ -2112,46 +2111,6 @@ css_error consumeWChars(css_lexer *lexer) * More utility routines * ******************************************************************************/ -uint32_t charToHex(uint8_t c) -{ - switch (c) { - case 'a': case 'A': - return 0xa; - case 'b': case 'B': - return 0xb; - case 'c': case 'C': - return 0xc; - case 'd': case 'D': - return 0xd; - case 'e': case 'E': - return 0xe; - case 'f': case 'F': - return 0xf; - case '0': - return 0x0; - case '1': - return 0x1; - case '2': - return 0x2; - case '3': - return 0x3; - case '4': - return 0x4; - case '5': - return 0x5; - case '6': - return 0x6; - case '7': - return 0x7; - case '8': - return 0x8; - case '9': - return 0x9; - } - - return 0; -} - bool startNMChar(uint8_t c) { return c == '_' || ('a' <= c && c <= 'z') || ('A' <= c && c <= 'Z') || diff --git a/src/parse/properties.c b/src/parse/properties.c index 383fe04..2c3e29d 100644 --- a/src/parse/properties.c +++ b/src/parse/properties.c @@ -6399,9 +6399,11 @@ css_error parse_colour_specifier(css_language *c, uint32_t *result) { const css_token *token; + uint8_t r = 0, g = 0, b = 0; UNUSED(c); - UNUSED(result); + + consumeWhitespace(vector, ctx); /* IDENT() | HASH(rgb | rrggbb) | * FUNCTION(rgb) [ [ NUMBER | PERCENTAGE ] ',' ] {3} ')' @@ -6409,14 +6411,73 @@ css_error parse_colour_specifier(css_language *c, * For quirks, NUMBER | DIMENSION | IDENT, too * I.E. "123456" -> NUMBER, "1234f0" -> DIMENSION, "f00000" -> IDENT */ + token = parserutils_vector_iterate(vector, ctx); + if (token == NULL || (token->type != CSS_TOKEN_IDENT && + token->type != CSS_TOKEN_HASH && + token->type != CSS_TOKEN_FUNCTION)) + return CSS_INVALID; - /** \todo Parse colours */ + if (token->type == CSS_TOKEN_IDENT) { + /** \todo Parse colour names */ + } else if (token->type == CSS_TOKEN_HASH) { + if (token->idata->len == 3) { + r = charToHex(token->idata->data[0]); + g = charToHex(token->idata->data[1]); + b = charToHex(token->idata->data[2]); + + r |= (r << 4); + g |= (g << 4); + b |= (b << 4); + } else if (token->idata->len == 6) { + r = (charToHex(token->idata->data[0]) << 4); + r |= charToHex(token->idata->data[1]); + g = (charToHex(token->idata->data[2]) << 4); + g |= charToHex(token->idata->data[3]); + b = (charToHex(token->idata->data[4]) << 4); + b |= charToHex(token->idata->data[5]); + } else + return CSS_INVALID; + } else if (token->type == CSS_TOKEN_FUNCTION) { + if (token->ilower == c->strings[RGB]) { + css_token_type valid = CSS_TOKEN_NUMBER; - /* For now, consume everything up to the end of the declaration or !, - * whichever comes first */ - while ((token = parserutils_vector_peek(vector, *ctx)) != NULL && - tokenIsChar(token, '!') == false) - parserutils_vector_iterate(vector, ctx); + for (int i = 0; i < 3; i++) { + consumeWhitespace(vector, ctx); + + token = parserutils_vector_peek(vector, *ctx); + if (token == NULL || (token->type != + CSS_TOKEN_NUMBER && + token->type != + CSS_TOKEN_PERCENTAGE)) + return CSS_INVALID; + + if (i == 0) + valid = token->type; + else if (token->type != valid) + return CSS_INVALID; + + /** \todo extract values */ + + parserutils_vector_iterate(vector, ctx); + + consumeWhitespace(vector, ctx); + + token = parserutils_vector_peek(vector, *ctx); + if (token == NULL) + return CSS_INVALID; + + if (i != 2 && tokenIsChar(token, ',')) + parserutils_vector_iterate(vector, ctx); + else if (i == 2 && tokenIsChar(token, ')')) + parserutils_vector_iterate(vector, ctx); + else + return CSS_INVALID; + } + } else + return CSS_INVALID; + } + + *result = (r << 24) | (g << 16) | (b << 8); return CSS_OK; } diff --git a/src/parse/propstrings.h b/src/parse/propstrings.h index 98fb869..fc7e4c6 100644 --- a/src/parse/propstrings.h +++ b/src/parse/propstrings.h @@ -68,7 +68,7 @@ enum { DEFAULT, POINTER, MOVE, E_RESIZE, 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, + MIX, UNDERLINE, OVERLINE, LINE_THROUGH, BLINK, RGB, LAST_KNOWN }; @@ -353,7 +353,8 @@ static struct { { "underline", SLEN("underline") }, { "overline", SLEN("overline") }, { "line-through", SLEN("line-through") }, - { "blink", SLEN("blink") } + { "blink", SLEN("blink") }, + { "rgb", SLEN("rgb") } }; #endif diff --git a/src/utils/utils.h b/src/utils/utils.h index a8848e3..9fc4424 100644 --- a/src/utils/utils.h +++ b/src/utils/utils.h @@ -124,4 +124,44 @@ static inline fixed number_from_css_string(const css_string *string, return FMULI(((intpart << 10) | fracpart), sign); } +static inline uint32_t charToHex(uint8_t c) +{ + switch (c) { + case 'a': case 'A': + return 0xa; + case 'b': case 'B': + return 0xb; + case 'c': case 'C': + return 0xc; + case 'd': case 'D': + return 0xd; + case 'e': case 'E': + return 0xe; + case 'f': case 'F': + return 0xf; + case '0': + return 0x0; + case '1': + return 0x1; + case '2': + return 0x2; + case '3': + return 0x3; + case '4': + return 0x4; + case '5': + return 0x5; + case '6': + return 0x6; + case '7': + return 0x7; + case '8': + return 0x8; + case '9': + return 0x9; + } + + return 0; +} + #endif -- cgit v1.2.3