diff options
author | John Mark Bell <jmb@netsurf-browser.org> | 2008-12-04 23:43:43 +0000 |
---|---|---|
committer | John Mark Bell <jmb@netsurf-browser.org> | 2008-12-04 23:43:43 +0000 |
commit | cea9d48a81f8f93e199ccbbe2e4ac9fdc40a0389 (patch) | |
tree | b929badbed9dc6472447ef9a697b388684d6f08c /src | |
parent | ef8a15f3dd5dc483376ac4a9fe5acc5acc1e9122 (diff) | |
download | libcss-cea9d48a81f8f93e199ccbbe2e4ac9fdc40a0389.tar.gz libcss-cea9d48a81f8f93e199ccbbe2e4ac9fdc40a0389.tar.bz2 |
Beginnings of font-family
svn path=/trunk/libcss/; revision=5882
Diffstat (limited to 'src')
-rw-r--r-- | src/bytecode/opcodes.h | 1 | ||||
-rw-r--r-- | src/parse/properties.c | 198 |
2 files changed, 193 insertions, 6 deletions
diff --git a/src/bytecode/opcodes.h b/src/bytecode/opcodes.h index 1bdd823..d6e5baf 100644 --- a/src/bytecode/opcodes.h +++ b/src/bytecode/opcodes.h @@ -244,6 +244,7 @@ enum op_float { enum op_font_family { FONT_FAMILY_STRING = 0x0080, + FONT_FAMILY_IDENT_LIST = 0x0081, FONT_FAMILY_END = 0x0000, diff --git a/src/parse/properties.c b/src/parse/properties.c index bcab556..b6f3d6d 100644 --- a/src/parse/properties.c +++ b/src/parse/properties.c @@ -2561,17 +2561,203 @@ css_error parse_font_family(css_language *c, const parserutils_vector *vector, int *ctx, css_style **result) { - /* [ IDENT+ | STRING ] [ ','? [ IDENT+ | STRING ] ]* + css_error error; + const css_token *token; + uint8_t flags = 0; + uint16_t value = 0; + uint32_t opv; + uint32_t required_size = sizeof(opv); + int temp_ctx = *ctx; + uint8_t *ptr; + + /* [ IDENT+ | STRING ] [ ','? [ IDENT+ | STRING ] ]* | IDENT(inherit) * * In the case of IDENT+, any whitespace between tokens is collapsed to * a single space */ - /** \todo font-family */ - UNUSED(c); - UNUSED(vector); - UNUSED(ctx); - UNUSED(result); + /* Pass 1: validate input and calculate space */ + token = parserutils_vector_iterate(vector, &temp_ctx); + if (token == NULL || (token->type != CSS_TOKEN_IDENT && + token->type != CSS_TOKEN_STRING)) + return CSS_INVALID; + + if (token->type == CSS_TOKEN_IDENT && + token->ilower == c->strings[INHERIT]) { + flags = FLAG_INHERIT; + } else { + bool first = true; + + while (token != NULL) { + if (token->type == CSS_TOKEN_IDENT) { + if (first == false) { + required_size += sizeof(opv); + } else { + value = FONT_FAMILY_IDENT_LIST; + } + + required_size += + sizeof(parserutils_hash_entry *); + + /* Skip past [ IDENT* S* ]* */ + while (token != NULL) { + token = parserutils_vector_peek( + vector, temp_ctx); + if (token != NULL && + token->type != + CSS_TOKEN_IDENT && + token->type != + CSS_TOKEN_S) { + break; + } + + token = parserutils_vector_iterate( + vector, &temp_ctx); + } + } else if (token->type == CSS_TOKEN_STRING) { + if (first == false) { + required_size += sizeof(opv); + } else { + value = FONT_FAMILY_STRING; + } + + required_size += + sizeof(parserutils_hash_entry *); + } else { + return CSS_INVALID; + } + + consumeWhitespace(vector, &temp_ctx); + + token = parserutils_vector_peek(vector, temp_ctx); + if (token != NULL && tokenIsChar(token, ',')) { + parserutils_vector_iterate(vector, &temp_ctx); + + consumeWhitespace(vector, &temp_ctx); + + token = parserutils_vector_peek(vector, + temp_ctx); + if (token == NULL || tokenIsChar(token, '!')) + return CSS_INVALID; + } + + first = false; + + token = parserutils_vector_peek(vector, temp_ctx); + if (token != NULL && tokenIsChar(token, '!')) + break; + + token = parserutils_vector_iterate(vector, &temp_ctx); + } + + required_size += sizeof(opv); + } + + error = parse_important(c, vector, &temp_ctx, &flags); + if (error != CSS_OK) + return error; + + opv = buildOPV(OP_FONT_FAMILY, flags, value); + + /* Allocate result */ + error = css_stylesheet_style_create(c->sheet, required_size, result); + if (error != CSS_OK) + return error; + + /* Copy OPV to bytecode */ + ptr = (*result)->bytecode; + memcpy(ptr, &opv, sizeof(opv)); + ptr += sizeof(opv); + + /* Pass 2: populate bytecode */ + token = parserutils_vector_iterate(vector, ctx); + if (token == NULL || (token->type != CSS_TOKEN_IDENT && + token->type != CSS_TOKEN_STRING)) + return CSS_INVALID; + + if (token->type == CSS_TOKEN_IDENT && + token->ilower == c->strings[INHERIT]) { + /* Nothing to do */ + } else { + bool first = true; + + while (token != NULL) { + if (token->type == CSS_TOKEN_IDENT) { + /** \todo need to build string from idents */ + const parserutils_hash_entry *name = + token->idata; + + opv = FONT_FAMILY_IDENT_LIST; + + if (first == false) { + memcpy(ptr, &opv, sizeof(opv)); + ptr += sizeof(opv); + } + + /* Skip past [ IDENT* S* ]* */ + while (token != NULL) { + token = parserutils_vector_peek( + vector, temp_ctx); + if (token != NULL && + token->type != + CSS_TOKEN_IDENT && + token->type != + CSS_TOKEN_S) { + break; + } + + token = parserutils_vector_iterate( + vector, ctx); + } + + memcpy(ptr, &name, sizeof(name)); + ptr += sizeof(name); + } else if (token->type == CSS_TOKEN_STRING) { + opv = FONT_FAMILY_STRING; + + if (first == false) { + memcpy(ptr, &opv, sizeof(opv)); + ptr += sizeof(opv); + } + + memcpy(ptr, &token->idata, + sizeof(token->idata)); + ptr += sizeof(token->idata); + } else { + return CSS_INVALID; + } + + consumeWhitespace(vector, ctx); + + token = parserutils_vector_peek(vector, temp_ctx); + if (token != NULL && tokenIsChar(token, ',')) { + parserutils_vector_iterate(vector, ctx); + + consumeWhitespace(vector, ctx); + + token = parserutils_vector_peek(vector, *ctx); + if (token == NULL || tokenIsChar(token, '!')) + return CSS_INVALID; + } + + first = false; + + token = parserutils_vector_peek(vector, *ctx); + if (token != NULL && tokenIsChar(token, '!')) + break; + + token = parserutils_vector_iterate(vector, ctx); + } + + /* Write terminator */ + opv = FONT_FAMILY_END; + memcpy(ptr, &opv, sizeof(opv)); + ptr += sizeof(opv); + } + + error = parse_important(c, vector, ctx, &flags); + if (error != CSS_OK) + return error; return CSS_OK; } |