summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--include/libcss/stylesheet.h53
-rw-r--r--src/parse/properties/utils.c21
-rw-r--r--src/stylesheet.c75
-rw-r--r--src/stylesheet.h3
-rw-r--r--test/css21.c26
-rw-r--r--test/parse-auto.c29
-rw-r--r--test/parse2-auto.c19
-rw-r--r--test/select-auto.c19
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,
- &params);
+ &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(&params, 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(&params,
+ 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(&params, 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(&params,
+ 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(&params, 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(&params, myrealloc, NULL,
+ &sheet) == CSS_OK);
/* Extend array of sheets and append new sheet to it */
temp = realloc(ctx->sheets,