From 9838246d69a3d48a8d0d286ecbfcd1faa199ae91 Mon Sep 17 00:00:00 2001 From: John Mark Bell Date: Sat, 29 Jan 2011 14:45:05 +0000 Subject: Provide hook for system colour name -> RGB conversion svn path=/trunk/libcss/; revision=11522 --- include/libcss/stylesheet.h | 53 ++++++++++++++++++++++++++++--- src/parse/properties/utils.c | 21 ++++++++----- src/stylesheet.c | 75 ++++++++++++++++++++------------------------ src/stylesheet.h | 3 ++ test/css21.c | 26 ++++++++++----- test/parse-auto.c | 29 ++++++++++++----- test/parse2-auto.c | 19 +++++++++-- test/select-auto.c | 19 +++++++++-- 8 files changed, 170 insertions(+), 75 deletions(-) diff --git a/include/libcss/stylesheet.h b/include/libcss/stylesheet.h index 33d2a5c..3c5b92e 100644 --- a/include/libcss/stylesheet.h +++ b/include/libcss/stylesheet.h @@ -47,12 +47,55 @@ typedef css_error (*css_url_resolution_fn)(void *pw, typedef css_error (*css_import_notification_fn)(void *pw, css_stylesheet *parent, lwc_string *url, uint64_t media); -css_error css_stylesheet_create(css_language_level level, - const char *charset, const char *url, const char *title, - bool allow_quirks, bool inline_style, +/** + * Callback use to resolve system colour names to RGB values + * + * \param pw Client data + * \param name System colour name + * \param color Pointer to location to receive color value + * \return CSS_OK on success, + * CSS_INVALID if the name is unknown. + */ +typedef css_error (*css_color_resolution_fn)(void *pw, + lwc_string *name, css_color *color); + +/** + * Parameter block for css_stylesheet_create() + */ +typedef struct css_stylesheet_params { + /** The language level of the stylesheet */ + css_language_level level; + + /** The charset of the stylesheet data, or NULL to detect */ + const char *charset; + /** URL of stylesheet */ + const char *url; + /** Title of stylesheet */ + const char *title; + + /** Permit quirky parsing of stylesheet */ + bool allow_quirks; + /** This stylesheet is an inline style */ + bool inline_style; + + /** URL resolution function */ + css_url_resolution_fn resolve; + /** Client private data for resolve */ + void *resolve_pw; + + /** Import notification function */ + css_import_notification_fn import; + /** Client private data for import */ + void *import_pw; + + /** Colour resolution function */ + css_color_resolution_fn color; + /** Client private data for color */ + void *color_pw; +} css_stylesheet_params; + +css_error css_stylesheet_create(css_stylesheet_params *params, css_allocator_fn alloc, void *alloc_pw, - css_url_resolution_fn resolve, void *resolve_pw, - css_import_notification_fn, void *import_pw, css_stylesheet **stylesheet); css_error css_stylesheet_destroy(css_stylesheet *sheet); diff --git a/src/parse/properties/utils.c b/src/parse/properties/utils.c index 85c0e2d..860712d 100644 --- a/src/parse/properties/utils.c +++ b/src/parse/properties/utils.c @@ -628,7 +628,6 @@ css_error css__parse_colour_specifier(css_language *c, goto invalid; /* have a valid HSV entry, convert to RGB */ - HSL_to_RGB(hue, sat, lit, &r, &g, &b); /* apply alpha */ @@ -821,17 +820,23 @@ css_error css__parse_named_colour(css_language *c, lwc_string *data, bool match; for (i = FIRST_COLOUR; i <= LAST_COLOUR; i++) { - if (lwc_string_caseless_isequal(data, c->strings[i], - &match) == lwc_error_ok && - match) + if (lwc_string_caseless_isequal(data, c->strings[i], + &match) == lwc_error_ok && match) break; } - if (i == LAST_COLOUR + 1) - return CSS_INVALID; - *result = colourmap[i - FIRST_COLOUR]; + if (i <= LAST_COLOUR) { + /* Known named colour */ + *result = colourmap[i - FIRST_COLOUR]; + return CSS_OK; + } + + /* We don't know this colour name; ask the client */ + if (c->sheet->color != NULL) + return c->sheet->color(c->sheet->color_pw, data, result); - return CSS_OK; + /* Invalid colour name */ + return CSS_INVALID; } /** diff --git a/src/stylesheet.c b/src/stylesheet.c index 9a8cae7..b983190 100644 --- a/src/stylesheet.c +++ b/src/stylesheet.c @@ -112,38 +112,25 @@ css_error css__stylesheet_string_get(css_stylesheet *sheet, uint32_t string_numb /** * Create a stylesheet * - * \param level The language level of the stylesheet - * \param charset The charset of the stylesheet data, or NULL to detect - * \param url URL of stylesheet - * \param title Title of stylesheet - * \param allow_quirks Permit quirky parsing of stylesheets - * \param inline_style This stylesheet is an inline style - * \param alloc Memory (de)allocation function - * \param alloc_pw Client private data for alloc - * \param resolve URL resolution function - * \param resolve_pw Client private data for resolve - * \param import Import notification function - * \param import_pw Client private data for import - * \param stylesheet Pointer to location to receive stylesheet + * \param params Stylesheet parameters + * \param alloc Memory (de)allocation function + * \param alloc_pw Client private data for alloc + * \param stylesheet Pointer to location to receive stylesheet * \return CSS_OK on success, * CSS_BADPARM on bad parameters, * CSS_NOMEM on memory exhaustion */ -css_error css_stylesheet_create(css_language_level level, - const char *charset, const char *url, const char *title, - bool allow_quirks, bool inline_style, +css_error css_stylesheet_create(css_stylesheet_params *params, css_allocator_fn alloc, void *alloc_pw, - css_url_resolution_fn resolve, void *resolve_pw, - css_import_notification_fn import, void *import_pw, css_stylesheet **stylesheet) { - css_parser_optparams params; + css_parser_optparams optparams; css_error error; css_stylesheet *sheet; size_t len; - if (url == NULL || alloc == NULL || - resolve == NULL || stylesheet == NULL) + if (params == NULL || params->url == NULL || alloc == NULL || + params->resolve == NULL || stylesheet == NULL) return CSS_BADPARM; sheet = alloc(NULL, sizeof(css_stylesheet), alloc_pw); @@ -152,15 +139,17 @@ css_error css_stylesheet_create(css_language_level level, memset(sheet, 0, sizeof(css_stylesheet)); - sheet->inline_style = inline_style; + sheet->inline_style = params->inline_style; - if (inline_style) { - error = css__parser_create_for_inline_style(charset, - charset ? CSS_CHARSET_DICTATED : CSS_CHARSET_DEFAULT, + if (params->inline_style) { + error = css__parser_create_for_inline_style(params->charset, + params->charset != NULL + ? CSS_CHARSET_DICTATED : CSS_CHARSET_DEFAULT, alloc, alloc_pw, &sheet->parser); } else { - error = css__parser_create(charset, - charset ? CSS_CHARSET_DICTATED : CSS_CHARSET_DEFAULT, + error = css__parser_create(params->charset, + params->charset != NULL + ? CSS_CHARSET_DICTATED : CSS_CHARSET_DEFAULT, alloc, alloc_pw, &sheet->parser); } @@ -169,12 +158,13 @@ css_error css_stylesheet_create(css_language_level level, return error; } - sheet->quirks_allowed = allow_quirks; - if (allow_quirks) { - params.quirks = true; + sheet->quirks_allowed = params->allow_quirks; + + if (params->allow_quirks) { + optparams.quirks = true; error = css__parser_setopt(sheet->parser, CSS_PARSER_QUIRKS, - ¶ms); + &optparams); if (error != CSS_OK) { css__parser_destroy(sheet->parser); alloc(sheet, 0, alloc_pw); @@ -182,7 +172,7 @@ css_error css_stylesheet_create(css_language_level level, } } - sheet->level = level; + sheet->level = params->level; error = css__language_create(sheet, sheet->parser, alloc, alloc_pw, &sheet->parser_frontend); if (error != CSS_OK) { @@ -200,7 +190,7 @@ css_error css_stylesheet_create(css_language_level level, return error; } - len = strlen(url) + 1; + len = strlen(params->url) + 1; sheet->url = alloc(NULL, len, alloc_pw); if (sheet->url == NULL) { css__selector_hash_destroy(sheet->selectors); @@ -209,10 +199,10 @@ css_error css_stylesheet_create(css_language_level level, alloc(sheet, 0, alloc_pw); return CSS_NOMEM; } - memcpy(sheet->url, url, len); + memcpy(sheet->url, params->url, len); - if (title != NULL) { - len = strlen(title) + 1; + if (params->title != NULL) { + len = strlen(params->title) + 1; sheet->title = alloc(NULL, len, alloc_pw); if (sheet->title == NULL) { alloc(sheet->url, 0, alloc_pw); @@ -222,14 +212,17 @@ css_error css_stylesheet_create(css_language_level level, alloc(sheet, 0, alloc_pw); return CSS_NOMEM; } - memcpy(sheet->title, title, len); + memcpy(sheet->title, params->title, len); } - sheet->resolve = resolve; - sheet->resolve_pw = resolve_pw; + sheet->resolve = params->resolve; + sheet->resolve_pw = params->resolve_pw; + + sheet->import = params->import; + sheet->import_pw = params->import_pw; - sheet->import = import; - sheet->import_pw = import_pw; + sheet->color = params->color; + sheet->color_pw = params->color_pw; sheet->alloc = alloc; sheet->pw = alloc_pw; diff --git a/src/stylesheet.h b/src/stylesheet.h index 827d8d6..6296f9a 100644 --- a/src/stylesheet.h +++ b/src/stylesheet.h @@ -177,6 +177,9 @@ struct css_stylesheet { css_url_resolution_fn resolve; /**< URL resolution function */ void *resolve_pw; /**< Private word */ + css_color_resolution_fn color; /**< Colour resolution function */ + void *color_pw; /**< Private word */ + css_allocator_fn alloc; /**< Allocation function */ void *pw; /**< Private word */ diff --git a/test/css21.c b/test/css21.c index 2ce4ebc..929362e 100644 --- a/test/css21.c +++ b/test/css21.c @@ -34,6 +34,7 @@ static css_error resolve_url(void *pw, int main(int argc, char **argv) { + css_stylesheet_params params; css_stylesheet *sheet; FILE *fp; size_t len, origlen; @@ -47,11 +48,22 @@ int main(int argc, char **argv) return 1; } + params.level = CSS_LEVEL_21; + params.charset = "UTF-8"; + params.url = argv[1]; + params.title = NULL; + params.allow_quirks = false; + params.inline_style = false; + params.resolve = resolve_url; + params.resolve_pw = NULL; + params.import = NULL; + params.import_pw = NULL; + params.color = NULL; + params.color_pw = NULL; + for (count = 0; count < ITERATIONS; count++) { - assert(css_stylesheet_create(CSS_LEVEL_21, "UTF-8", argv[1], - NULL, false, false, myrealloc, NULL, - resolve_url, NULL, NULL, NULL, + assert(css_stylesheet_create(¶ms, myrealloc, NULL, &sheet) == CSS_OK); fp = fopen(argv[1], "rb"); @@ -106,10 +118,10 @@ int main(int argc, char **argv) lwc_string_length(url)); buf[lwc_string_length(url)] = '\0'; - assert(css_stylesheet_create(CSS_LEVEL_21, - "UTF-8", buf, NULL, false, false, - myrealloc, NULL, resolve_url, NULL, - NULL, NULL, &import) == CSS_OK); + params.url = buf; + + assert(css_stylesheet_create(¶ms, + myrealloc, NULL, &import) == CSS_OK); assert(css_stylesheet_data_done(import) == CSS_OK); diff --git a/test/parse-auto.c b/test/parse-auto.c index 84bce9b..e268c3b 100644 --- a/test/parse-auto.c +++ b/test/parse-auto.c @@ -363,16 +363,29 @@ static void report_fail(const uint8_t *data, size_t datalen, exp_entry *e) void run_test(const uint8_t *data, size_t len, exp_entry *exp, size_t explen) { + css_stylesheet_params params; css_stylesheet *sheet; css_rule *rule; css_error error; size_t e; static int testnum; bool failed; - - assert(css_stylesheet_create(CSS_LEVEL_21, "UTF-8", "foo", NULL, - false, false, myrealloc, NULL, resolve_url, NULL, - NULL, NULL, &sheet) == CSS_OK); + + params.level = CSS_LEVEL_21; + params.charset = "UTF-8"; + params.url = "foo"; + params.title = NULL; + params.allow_quirks = false; + params.inline_style = false; + params.resolve = resolve_url; + params.resolve_pw = NULL; + params.import = NULL; + params.import_pw = NULL; + params.color = NULL; + params.color_pw = NULL; + + assert(css_stylesheet_create(¶ms, myrealloc, NULL, + &sheet) == CSS_OK); error = css_stylesheet_append_data(sheet, data, len); if (error != CSS_OK && error != CSS_NEEDDATA) { @@ -399,10 +412,10 @@ void run_test(const uint8_t *data, size_t len, exp_entry *exp, size_t explen) lwc_string_length(url)); buf[lwc_string_length(url)] = '\0'; - assert(css_stylesheet_create(CSS_LEVEL_21, - "UTF-8", buf, NULL, false, false, - myrealloc, NULL, resolve_url, NULL, - NULL, NULL, &import) == CSS_OK); + params.url = buf; + + assert(css_stylesheet_create(¶ms, + myrealloc, NULL, &import) == CSS_OK); assert(css_stylesheet_register_import(sheet, import) == CSS_OK); diff --git a/test/parse2-auto.c b/test/parse2-auto.c index 877c0f5..cbf6730 100644 --- a/test/parse2-auto.c +++ b/test/parse2-auto.c @@ -183,6 +183,7 @@ void css__parse_expected(line_ctx *ctx, const char *data, size_t len) void run_test(const uint8_t *data, size_t len, const char *exp, size_t explen) { + css_stylesheet_params params; css_stylesheet *sheet; css_error error; char *buf; @@ -195,9 +196,21 @@ void run_test(const uint8_t *data, size_t len, const char *exp, size_t explen) } buflen = 2 * explen; - assert(css_stylesheet_create(CSS_LEVEL_21, "UTF-8", "foo", NULL, - false, false, myrealloc, NULL, resolve_url, NULL, - NULL, NULL, &sheet) == CSS_OK); + params.level = CSS_LEVEL_21; + params.charset = "UTF-8"; + params.url = "foo"; + params.title = NULL; + params.allow_quirks = false; + params.inline_style = false; + params.resolve = resolve_url; + params.resolve_pw = NULL; + params.import = NULL; + params.import_pw = NULL; + params.color = NULL; + params.color_pw = NULL; + + assert(css_stylesheet_create(¶ms, myrealloc, NULL, + &sheet) == CSS_OK); error = css_stylesheet_append_data(sheet, data, len); if (error != CSS_OK && error != CSS_NEEDDATA) { diff --git a/test/select-auto.c b/test/select-auto.c index c81d097..12fdb5f 100644 --- a/test/select-auto.c +++ b/test/select-auto.c @@ -457,6 +457,7 @@ void css__parse_tree_data(line_ctx *ctx, const char *data, size_t len) void css__parse_sheet(line_ctx *ctx, const char *data, size_t len) { + css_stylesheet_params params; const char *p; const char *end = data + len; css_origin origin = CSS_ORIGIN_AUTHOR; @@ -491,10 +492,22 @@ void css__parse_sheet(line_ctx *ctx, const char *data, size_t len) css__parse_media_list(&p, &ignored, &media); } + params.level = CSS_LEVEL_21; + params.charset = "UTF-8"; + params.url = "foo"; + params.title = "foo"; + params.allow_quirks = false; + params.inline_style = false; + params.resolve = resolve_url; + params.resolve_pw = NULL; + params.import = NULL; + params.import_pw = NULL; + params.color = NULL; + params.color_pw = NULL; + /** \todo How are we going to handle @import? */ - assert(css_stylesheet_create(CSS_LEVEL_21, "UTF-8", "foo", "foo", - false, false, myrealloc, NULL, - resolve_url, NULL, NULL, NULL, &sheet) == CSS_OK); + assert(css_stylesheet_create(¶ms, myrealloc, NULL, + &sheet) == CSS_OK); /* Extend array of sheets and append new sheet to it */ temp = realloc(ctx->sheets, -- cgit v1.2.3