summaryrefslogtreecommitdiff
path: root/src/parse
diff options
context:
space:
mode:
Diffstat (limited to 'src/parse')
-rw-r--r--src/parse/Makefile2
-rw-r--r--src/parse/font_face.c413
-rw-r--r--src/parse/font_face.h22
-rw-r--r--src/parse/language.c42
-rw-r--r--src/parse/properties/utils.c45
-rw-r--r--src/parse/properties/utils.h14
-rw-r--r--src/parse/propstrings.c10
-rw-r--r--src/parse/propstrings.h5
8 files changed, 540 insertions, 13 deletions
diff --git a/src/parse/Makefile b/src/parse/Makefile
index a7548a8..3d1df42 100644
--- a/src/parse/Makefile
+++ b/src/parse/Makefile
@@ -1,4 +1,4 @@
# Sources
-DIR_SOURCES := parse.c language.c important.c propstrings.c
+DIR_SOURCES := parse.c language.c important.c propstrings.c font_face.c
include build/makefiles/Makefile.subdir
diff --git a/src/parse/font_face.c b/src/parse/font_face.c
new file mode 100644
index 0000000..14a715d
--- /dev/null
+++ b/src/parse/font_face.c
@@ -0,0 +1,413 @@
+/*
+ * This file is part of LibCSS.
+ * Licensed under the MIT License,
+ * http://www.opensource.org/licenses/mit-license.php
+ * Copyright 2011 Things Made Out Of Other Things Ltd.
+ * Written by James Montgomerie <jamie@th.ingsmadeoutofotherthin.gs>
+ */
+
+#include "parse/font_face.h"
+
+#include <assert.h>
+#include <string.h>
+
+#include "parse/propstrings.h"
+#include "parse/properties/utils.h"
+#include "select/font_face.h"
+
+static bool font_rule_font_family_reserved(css_language *c,
+ const css_token *ident)
+{
+ bool match;
+
+ return (lwc_string_caseless_isequal(ident->idata, c->strings[SERIF],
+ &match) == lwc_error_ok && match) ||
+ (lwc_string_caseless_isequal(ident->idata,
+ c->strings[SANS_SERIF], &match) == lwc_error_ok &&
+ match) ||
+ (lwc_string_caseless_isequal(ident->idata, c->strings[CURSIVE],
+ &match) == lwc_error_ok && match) ||
+ (lwc_string_caseless_isequal(ident->idata, c->strings[FANTASY],
+ &match) == lwc_error_ok && match) ||
+ (lwc_string_caseless_isequal(ident->idata,
+ c->strings[MONOSPACE], &match) == lwc_error_ok &&
+ match) ||
+ (lwc_string_caseless_isequal(ident->idata, c->strings[INHERIT],
+ &match) == lwc_error_ok && match) ||
+ (lwc_string_caseless_isequal(ident->idata, c->strings[INITIAL],
+ &match) == lwc_error_ok && match) ||
+ (lwc_string_caseless_isequal(ident->idata, c->strings[DEFAULT],
+ &match) == lwc_error_ok && match);
+}
+
+static css_error font_face_parse_font_family(css_language *c,
+ const parserutils_vector *vector, int *ctx,
+ css_font_face *font_face)
+{
+ css_error error;
+ lwc_string *string;
+
+ error = css__ident_list_or_string_to_string(c, vector, ctx,
+ font_rule_font_family_reserved, &string);
+ if (error != CSS_OK)
+ return error;
+
+ css__font_face_set_font_family(font_face, string);
+
+ lwc_string_unref(string);
+
+ return CSS_OK;
+}
+
+static css_error font_face_src_parse_format(css_language *c,
+ const parserutils_vector *vector, int *ctx,
+ css_font_face_format *format)
+{
+ bool match;
+ const css_token *token;
+
+ *format = CSS_FONT_FACE_FORMAT_UNSPECIFIED;
+
+ /* 'format(' STRING [ ',' STRING ]* ')'
+ *
+ * 'format(' already consumed
+ */
+
+ do {
+ consumeWhitespace(vector, ctx);
+
+ token = parserutils_vector_iterate(vector, ctx);
+ if (token == NULL || token->type != CSS_TOKEN_STRING)
+ return CSS_INVALID;
+
+ if (lwc_string_isequal(token->idata,
+ c->strings[WOFF], &match) == lwc_error_ok &&
+ match) {
+ *format |= CSS_FONT_FACE_FORMAT_WOFF;
+ } else if ((lwc_string_isequal(token->idata,
+ c->strings[TRUETYPE], &match) == lwc_error_ok &&
+ match) ||
+ (lwc_string_isequal(token->idata,
+ c->strings[OPENTYPE], &match) == lwc_error_ok &&
+ match)) {
+ *format |= CSS_FONT_FACE_FORMAT_OPENTYPE;
+ } else if (lwc_string_isequal(token->idata,
+ c->strings[EMBEDDED_OPENTYPE],
+ &match) == lwc_error_ok && match) {
+ *format |= CSS_FONT_FACE_FORMAT_EMBEDDED_OPENTYPE;
+ } else if (lwc_string_isequal(token->idata,
+ c->strings[SVG], &match) == lwc_error_ok &&
+ match) {
+ *format |= CSS_FONT_FACE_FORMAT_SVG;
+ } else {
+ /* The spec gives a list of possible strings, which
+ * hints that unknown strings should be parse errors,
+ * but it also talks about "unknown font formats",
+ * so we treat any string we don't know not as a parse
+ * error, but as indicating an "unknown font format".
+ */
+ *format |= CSS_FONT_FACE_FORMAT_UNKNOWN;
+ }
+
+ consumeWhitespace(vector, ctx);
+ token = parserutils_vector_iterate(vector, ctx);
+ } while (token != NULL && tokenIsChar(token, ','));
+
+ if (token == NULL || tokenIsChar(token, ')') == false)
+ return CSS_INVALID;
+
+ return CSS_OK;
+}
+
+static css_error font_face_src_parse_spec_or_name(css_language *c,
+ const parserutils_vector *vector, int *ctx,
+ lwc_string **location,
+ css_font_face_location_type *location_type,
+ css_font_face_format *format)
+{
+ const css_token *token;
+ css_error error;
+ bool match;
+
+ /* spec-or-name ::= font-face-spec | font-face-name
+ * font-face-spec ::= URI [ 'format(' STRING [ ',' STRING ]* ')' ]?
+ * font-face-name ::= 'local(' ident-list-or-string ')'
+ * ident-list-or-string ::= IDENT IDENT* | STRING
+ */
+
+ consumeWhitespace(vector, ctx);
+
+ token = parserutils_vector_iterate(vector, ctx);
+ if (token == NULL)
+ return CSS_INVALID;
+
+ if (token->type == CSS_TOKEN_URI) {
+ error = c->sheet->resolve(c->sheet->resolve_pw,
+ c->sheet->url, token->idata,
+ location);
+ if (error != CSS_OK)
+ return error;
+
+ *location_type = CSS_FONT_FACE_LOCATION_TYPE_URI;
+
+ consumeWhitespace(vector, ctx);
+
+ token = parserutils_vector_peek(vector, *ctx);
+ if (token != NULL && token->type == CSS_TOKEN_FUNCTION &&
+ lwc_string_caseless_isequal(token->idata,
+ c->strings[FORMAT], &match) == lwc_error_ok &&
+ match) {
+ parserutils_vector_iterate(vector, ctx);
+
+ error = font_face_src_parse_format(c, vector, ctx,
+ format);
+ if (error != CSS_OK) {
+ lwc_string_unref(*location);
+ return error;
+ }
+ }
+ } else if (token->type == CSS_TOKEN_FUNCTION &&
+ lwc_string_caseless_isequal(token->idata,
+ c->strings[LOCAL],
+ &match) == lwc_error_ok && match) {
+ consumeWhitespace(vector, ctx);
+
+ error = css__ident_list_or_string_to_string(
+ c, vector, ctx, NULL, location);
+ if (error != CSS_OK)
+ return error;
+
+ consumeWhitespace(vector, ctx);
+
+ token = parserutils_vector_iterate(vector, ctx);
+ if (token == NULL || tokenIsChar(token, ')') == false) {
+ lwc_string_unref(*location);
+ return CSS_INVALID;
+ }
+
+ *location_type = CSS_FONT_FACE_LOCATION_TYPE_LOCAL;
+ } else {
+ return CSS_INVALID;
+ }
+
+ return CSS_OK;
+}
+
+static css_error font_face_parse_src(css_language *c,
+ const parserutils_vector *vector, int *ctx,
+ css_font_face *font_face)
+{
+ int orig_ctx = *ctx;
+ css_error error = CSS_OK;
+ const css_token *token;
+ css_font_face_src *srcs = NULL, *new_srcs = NULL;
+ uint32_t n_srcs = 0;
+
+ /* src ::= spec-or-name [ ',' spec-or-name ]*
+ * spec-or-name ::= font-face-spec | font-face-name
+ * font-face-spec ::= URI [ 'format(' STRING [ ',' STRING ]* ')' ]?
+ * font-face-name ::= 'local(' ident-list-or-string ')'
+ * ident-list-or-string ::= IDENT IDENT* | STRING
+ */
+
+ /* Create one css_font_face_src for each consecutive location and
+ * [potentially] type pair in the comma-separated list
+ */
+ do {
+ lwc_string *location;
+ css_font_face_location_type location_type =
+ CSS_FONT_FACE_LOCATION_TYPE_UNSPECIFIED;
+ css_font_face_format format =
+ CSS_FONT_FACE_FORMAT_UNSPECIFIED;
+
+ error = font_face_src_parse_spec_or_name(c, vector, ctx,
+ &location, &location_type, &format);
+ if (error != CSS_OK)
+ goto cleanup;
+
+ /* This will be inefficient if there are a lot of locations -
+ * probably not a problem in practice.
+ */
+ new_srcs = c->alloc(srcs,
+ (n_srcs + 1) * sizeof(css_font_face_src),
+ c->pw);
+ if (new_srcs == NULL) {
+ error = CSS_NOMEM;
+ goto cleanup;
+ }
+ srcs = new_srcs;
+
+ srcs[n_srcs].location = location;
+ srcs[n_srcs].bits[0] = format << 2 | location_type;
+
+ ++n_srcs;
+
+ consumeWhitespace(vector, ctx);
+ token = parserutils_vector_iterate(vector, ctx);
+ } while (token != NULL && tokenIsChar(token, ','));
+
+ error = css__font_face_set_srcs(font_face, srcs, n_srcs);
+
+cleanup:
+ if (error != CSS_OK) {
+ *ctx = orig_ctx;
+ if (srcs != NULL)
+ c->alloc(srcs, 0, c->pw);
+ }
+
+ return error;
+}
+
+static css_error font_face_parse_font_style(css_language *c,
+ const parserutils_vector *vector, int *ctx,
+ css_font_face *font_face)
+{
+ int orig_ctx = *ctx;
+ css_error error = CSS_OK;
+ const css_token *token;
+ enum css_font_style_e style = 0;
+ bool match;
+
+ /* IDENT(normal, italic, oblique) */
+
+ token = parserutils_vector_iterate(vector, ctx);
+ if ((token == NULL) || ((token->type != CSS_TOKEN_IDENT))) {
+ *ctx = orig_ctx;
+ return CSS_INVALID;
+ }
+
+ if ((lwc_string_caseless_isequal(token->idata,
+ c->strings[NORMAL], &match) == lwc_error_ok && match)) {
+ style = CSS_FONT_STYLE_NORMAL;
+ } else if ((lwc_string_caseless_isequal(token->idata,
+ c->strings[ITALIC], &match) == lwc_error_ok && match)) {
+ style = CSS_FONT_STYLE_ITALIC;
+ } else if ((lwc_string_caseless_isequal(token->idata,
+ c->strings[OBLIQUE], &match) == lwc_error_ok &&
+ match)) {
+ style = CSS_FONT_STYLE_OBLIQUE;
+ } else {
+ error = CSS_INVALID;
+ }
+
+ if (error == CSS_OK) {
+ font_face->bits[0] = (font_face->bits[0] & 0xfc) | style;
+ } else {
+ *ctx = orig_ctx;
+ }
+
+ return error;
+}
+
+static css_error font_face_parse_font_weight(css_language *c,
+ const parserutils_vector *vector, int *ctx,
+ css_font_face *font_face)
+{
+ int orig_ctx = *ctx;
+ css_error error = CSS_OK;
+ const css_token *token;
+ enum css_font_weight_e weight = 0;
+ bool match;
+
+ /* NUMBER (100, 200, 300, 400, 500, 600, 700, 800, 900) |
+ * IDENT (normal, bold) */
+ token = parserutils_vector_iterate(vector, ctx);
+ if (token == NULL || (token->type != CSS_TOKEN_IDENT &&
+ token->type != CSS_TOKEN_NUMBER)) {
+ *ctx = orig_ctx;
+ return CSS_INVALID;
+ }
+
+ if (token->type == CSS_TOKEN_NUMBER) {
+ size_t consumed = 0;
+ css_fixed num = css__number_from_lwc_string(token->idata,
+ true, &consumed);
+ /* Invalid if there are trailing characters */
+ if (consumed != lwc_string_length(token->idata)) {
+ *ctx = orig_ctx;
+ return CSS_INVALID;
+ }
+
+ switch (FIXTOINT(num)) {
+ case 100: weight = CSS_FONT_WEIGHT_100; break;
+ case 200: weight = CSS_FONT_WEIGHT_200; break;
+ case 300: weight = CSS_FONT_WEIGHT_300; break;
+ case 400: weight = CSS_FONT_WEIGHT_400; break;
+ case 500: weight = CSS_FONT_WEIGHT_500; break;
+ case 600: weight = CSS_FONT_WEIGHT_600; break;
+ case 700: weight = CSS_FONT_WEIGHT_700; break;
+ case 800: weight = CSS_FONT_WEIGHT_800; break;
+ case 900: weight = CSS_FONT_WEIGHT_900; break;
+ default: error = CSS_INVALID;
+ }
+ } else if ((lwc_string_caseless_isequal(token->idata,
+ c->strings[NORMAL], &match) == lwc_error_ok && match)) {
+ weight = CSS_FONT_WEIGHT_NORMAL;
+ } else if ((lwc_string_caseless_isequal(token->idata,
+ c->strings[BOLD], &match) == lwc_error_ok && match)) {
+ weight = CSS_FONT_WEIGHT_BOLD;
+ } else {
+ error = CSS_INVALID;
+ }
+
+ if (error == CSS_OK) {
+ font_face->bits[0] = (font_face->bits[0] & 0xc3) |
+ (weight << 2);
+ } else {
+ *ctx = orig_ctx;
+ }
+
+ return error;
+}
+
+/**
+ * Parse a descriptor in an @font-face rule
+ *
+ * \param c Parsing context
+ * \param descriptor Token for this descriptor
+ * \param vector Vector of tokens to process
+ * \param ctx Pointer to vector iteration context
+ * \param rule Rule to process descriptor into
+ * \return CSS_OK on success,
+ * CSS_BADPARM on bad parameters,
+ * CSS_INVALID on invalid syntax,
+ * CSS_NOMEM on memory exhaustion
+ */
+css_error css__parse_font_descriptor(css_language *c,
+ const css_token *descriptor, const parserutils_vector *vector,
+ int *ctx, css_rule_font_face *rule)
+{
+ css_font_face *font_face = rule->font_face;
+ css_error error;
+ bool match;
+
+ if (font_face == NULL) {
+ error = css__font_face_create(c->sheet->alloc,
+ c->sheet->pw, &font_face);
+ if (error != CSS_OK) {
+ return error;
+ }
+
+ rule->font_face = font_face;
+ }
+
+ if (lwc_string_caseless_isequal(descriptor->idata,
+ c->strings[FONT_FAMILY], &match) == lwc_error_ok &&
+ match) {
+ return font_face_parse_font_family(c, vector, ctx, font_face);
+ } else if (lwc_string_caseless_isequal(descriptor->idata,
+ c->strings[SRC], &match) == lwc_error_ok && match) {
+ return font_face_parse_src(c, vector, ctx, font_face);
+ } else if (lwc_string_caseless_isequal(descriptor->idata,
+ c->strings[FONT_STYLE], &match) == lwc_error_ok &&
+ match) {
+ return font_face_parse_font_style(c, vector, ctx, font_face);
+ } else if (lwc_string_caseless_isequal(descriptor->idata,
+ c->strings[FONT_WEIGHT], &match) == lwc_error_ok &&
+ match) {
+ return font_face_parse_font_weight(c, vector, ctx, font_face);
+ }
+
+ return CSS_INVALID;
+}
+
diff --git a/src/parse/font_face.h b/src/parse/font_face.h
new file mode 100644
index 0000000..435380e
--- /dev/null
+++ b/src/parse/font_face.h
@@ -0,0 +1,22 @@
+/*
+ * This file is part of LibCSS.
+ * Licensed under the MIT License,
+ * http://www.opensource.org/licenses/mit-license.php
+ * Copyright 2011 Things Made Out Of Other Things Ltd.
+ * Written by James Montgomerie <jamie@th.ingsmadeoutofotherthin.gs>
+ */
+
+#ifndef css_parse_font_face_h_
+#define css_parse_font_face_h_
+
+#include <parserutils/utils/vector.h>
+
+#include "stylesheet.h"
+#include "lex/lex.h"
+#include "parse/language.h"
+
+css_error css__parse_font_descriptor(css_language *c,
+ const css_token *descriptor, const parserutils_vector *vector,
+ int *ctx, struct css_rule_font_face *rule);
+
+#endif
diff --git a/src/parse/language.c b/src/parse/language.c
index 0436c22..a5fce0e 100644
--- a/src/parse/language.c
+++ b/src/parse/language.c
@@ -12,6 +12,7 @@
#include "stylesheet.h"
#include "lex/lex.h"
+#include "parse/font_face.h"
#include "parse/important.h"
#include "parse/language.h"
#include "parse/parse.h"
@@ -558,6 +559,26 @@ css_error handleStartAtRule(css_language *c, const parserutils_vector *vector)
* so no need to destroy it */
c->state = HAD_RULE;
+ } else if (lwc_string_caseless_isequal(atkeyword->idata,
+ c->strings[FONT_FACE], &match) == lwc_error_ok &&
+ match) {
+ error = css__stylesheet_rule_create(c->sheet,
+ CSS_RULE_FONT_FACE, &rule);
+ if (error != CSS_OK)
+ return error;
+
+ consumeWhitespace(vector, &ctx);
+
+ error = css__stylesheet_add_rule(c->sheet, rule, NULL);
+ if (error != CSS_OK) {
+ css__stylesheet_rule_destroy(c->sheet, rule);
+ return error;
+ }
+
+ /* Rule is now owned by the sheet,
+ * so no need to destroy it */
+
+ c->state = HAD_RULE;
} else if (lwc_string_caseless_isequal(atkeyword->idata, c->strings[PAGE],
&match) == lwc_error_ok && match) {
const css_token *token;
@@ -693,9 +714,9 @@ css_error handleBlockContent(css_language *c, const parserutils_vector *vector)
context_entry *entry;
css_rule *rule;
- /* In CSS 2.1, block content comprises either declarations (if the
- * current block is associated with @page or a selector), or rulesets
- * (if the current block is associated with @media). */
+ /* Block content comprises either declarations (if the current block is
+ * associated with @page, @font-face or a selector), or rulesets (if the
+ * current block is associated with @media). */
entry = parserutils_stack_get_current(c->context);
if (entry == NULL || entry->data == NULL)
@@ -704,7 +725,8 @@ css_error handleBlockContent(css_language *c, const parserutils_vector *vector)
rule = entry->data;
if (rule == NULL || (rule->type != CSS_RULE_SELECTOR &&
rule->type != CSS_RULE_PAGE &&
- rule->type != CSS_RULE_MEDIA))
+ rule->type != CSS_RULE_MEDIA &&
+ rule->type != CSS_RULE_FONT_FACE))
return CSS_INVALID;
if (rule->type == CSS_RULE_MEDIA) {
@@ -729,6 +751,7 @@ css_error handleDeclaration(css_language *c, const parserutils_vector *vector)
/* Locations where declarations are permitted:
*
* + In @page
+ * + In @font-face
* + In ruleset
*/
entry = parserutils_stack_get_current(c->context);
@@ -737,7 +760,8 @@ css_error handleDeclaration(css_language *c, const parserutils_vector *vector)
rule = entry->data;
if (rule == NULL || (rule->type != CSS_RULE_SELECTOR &&
- rule->type != CSS_RULE_PAGE))
+ rule->type != CSS_RULE_PAGE &&
+ rule->type != CSS_RULE_FONT_FACE))
return CSS_INVALID;
/* Strip any leading whitespace (can happen if in nested block) */
@@ -759,7 +783,13 @@ css_error handleDeclaration(css_language *c, const parserutils_vector *vector)
consumeWhitespace(vector, &ctx);
- error = parseProperty(c, ident, vector, &ctx, rule);
+ if (rule->type == CSS_RULE_FONT_FACE) {
+ css_rule_font_face * ff_rule = (css_rule_font_face *) rule;
+ error = css__parse_font_descriptor(
+ c, ident, vector, &ctx, ff_rule);
+ } else {
+ error = parseProperty(c, ident, vector, &ctx, rule);
+ }
if (error != CSS_OK)
return error;
diff --git a/src/parse/properties/utils.c b/src/parse/properties/utils.c
index bf7e212..4eca6fc 100644
--- a/src/parse/properties/utils.c
+++ b/src/parse/properties/utils.c
@@ -1044,6 +1044,45 @@ css_error css__parse_unit_keyword(const char *ptr, size_t len, css_unit *unit)
}
/**
+ * Create a string from a list of IDENT/S tokens if the next token is IDENT
+ * or references the next token's string if it is a STRING
+ *
+ * \param c Parsing context
+ * \param vector Vector containing tokens
+ * \param ctx Vector iteration context
+ * \param reserved Callback to determine if an identifier is reserved
+ * \param result Pointer to location to receive resulting string
+ * \return CSS_OK on success, appropriate error otherwise.
+ *
+ * Post condition: \a *ctx is updated with the next token to process
+ * If the input is invalid, then \a *ctx remains unchanged.
+ *
+ * The resulting string's reference is passed to the caller
+ */
+css_error css__ident_list_or_string_to_string(css_language *c,
+ const parserutils_vector *vector, int *ctx,
+ bool (*reserved)(css_language *c, const css_token *ident),
+ lwc_string **result)
+{
+ const css_token *token;
+
+ token = parserutils_vector_peek(vector, *ctx);
+ if (token == NULL)
+ return CSS_INVALID;
+
+ if (token->type == CSS_TOKEN_STRING) {
+ token = parserutils_vector_iterate(vector, ctx);
+ *result = lwc_string_ref(token->idata);
+ return CSS_OK;
+ } else if(token->type == CSS_TOKEN_IDENT) {
+ return css__ident_list_to_string(c, vector, ctx, reserved,
+ result);
+ }
+
+ return CSS_INVALID;
+}
+
+/**
* Create a string from a list of IDENT/S tokens
*
* \param c Parsing context
@@ -1058,7 +1097,7 @@ css_error css__parse_unit_keyword(const char *ptr, size_t len, css_unit *unit)
*
* The resulting string's reference is passed to the caller
*/
-static css_error ident_list_to_string(css_language *c,
+css_error css__ident_list_to_string(css_language *c,
const parserutils_vector *vector, int *ctx,
bool (*reserved)(css_language *c, const css_token *ident),
lwc_string **result)
@@ -1084,7 +1123,7 @@ static css_error ident_list_to_string(css_language *c,
token->type == CSS_TOKEN_S)) {
if (token->type == CSS_TOKEN_IDENT) {
/* IDENT -- if reserved, reject style */
- if (reserved(c, token)) {
+ if (reserved != NULL && reserved(c, token)) {
error = CSS_INVALID;
goto cleanup;
}
@@ -1175,7 +1214,7 @@ css_error css__comma_list_to_style(css_language *c,
*ctx = prev_ctx;
- error = ident_list_to_string(c, vector, ctx,
+ error = css__ident_list_to_string(c, vector, ctx,
reserved, &str);
if (error != CSS_OK)
goto cleanup;
diff --git a/src/parse/properties/utils.h b/src/parse/properties/utils.h
index ab045bd..be903ee 100644
--- a/src/parse/properties/utils.h
+++ b/src/parse/properties/utils.h
@@ -181,10 +181,22 @@ css_error css__parse_unit_specifier(css_language *c,
css_error css__parse_unit_keyword(const char *ptr, size_t len,
css_unit *unit);
+css_error css__ident_list_or_string_to_string(css_language *c,
+ const parserutils_vector *vector, int *ctx,
+ bool (*reserved)(css_language *c, const css_token *ident),
+ lwc_string **result);
+
+css_error css__ident_list_to_string(css_language *c,
+ const parserutils_vector *vector, int *ctx,
+ bool (*reserved)(css_language *c, const css_token *ident),
+ lwc_string **result);
+
css_error css__comma_list_to_style(css_language *c,
const parserutils_vector *vector, int *ctx,
bool (*reserved)(css_language *c, const css_token *ident),
- css_code_t (*get_value)(css_language *c, const css_token *token, bool first),
+ css_code_t (*get_value)(css_language *c,
+ const css_token *token,
+ bool first),
css_style *result);
#endif
diff --git a/src/parse/propstrings.c b/src/parse/propstrings.c
index bf1fcd0..dea8816 100644
--- a/src/parse/propstrings.c
+++ b/src/parse/propstrings.c
@@ -30,6 +30,7 @@ const stringmap_entry stringmap[LAST_KNOWN] = {
{ "import", SLEN("import") },
{ "media", SLEN("media") },
{ "namespace", SLEN("namespace") },
+ { "font-face", SLEN("font-face") },
{ "page", SLEN("page") },
{ "aural", SLEN("aural") },
@@ -372,6 +373,15 @@ const stringmap_entry stringmap[LAST_KNOWN] = {
{ "currentColor", SLEN("currentColor") },
{ "odd", SLEN("odd") },
{ "even", SLEN("even") },
+ { "src", SLEN("src") },
+ { "local", SLEN("local") },
+ { "initial", SLEN("initial") },
+ { "format", SLEN("format") },
+ { "woff", SLEN("woff") },
+ { "truetype", SLEN("truetype") },
+ { "opentype", SLEN("opentype") },
+ { "embedded-opentype", SLEN("embedded-opentype") },
+ { "svg", SLEN("svg") },
{ "aliceblue", SLEN("aliceblue") },
{ "antiquewhite", SLEN("antiquewhite") },
diff --git a/src/parse/propstrings.h b/src/parse/propstrings.h
index 7c7b693..16affcd 100644
--- a/src/parse/propstrings.h
+++ b/src/parse/propstrings.h
@@ -15,7 +15,7 @@ enum {
UNIVERSAL,
/* At-rules */
- CHARSET, LIBCSS_IMPORT, MEDIA, NAMESPACE, PAGE,
+ CHARSET, LIBCSS_IMPORT, MEDIA, NAMESPACE, FONT_FACE, PAGE,
/* Media types */
AURAL, BRAILLE, EMBOSSED, HANDHELD, PRINT, PROJECTION,
@@ -88,7 +88,8 @@ enum {
W_RESIZE, LIBCSS_TEXT, WAIT, HELP, PROGRESS, SERIF, SANS_SERIF, CURSIVE,
FANTASY, MONOSPACE, MALE, FEMALE, CHILD, MIX, UNDERLINE, OVERLINE,
LINE_THROUGH, BLINK, RGB, RGBA, HSL, HSLA, LIBCSS_LEFT, LIBCSS_CENTER,
- LIBCSS_RIGHT, CURRENTCOLOR, ODD, EVEN,
+ LIBCSS_RIGHT, CURRENTCOLOR, ODD, EVEN, SRC, LOCAL, INITIAL,
+ FORMAT, WOFF, TRUETYPE, OPENTYPE, EMBEDDED_OPENTYPE, SVG,
/* Named colours */
FIRST_COLOUR,