diff options
-rw-r--r-- | include/libcss/stylesheet.h | 34 | ||||
-rw-r--r-- | include/libcss/types.h | 2 | ||||
-rw-r--r-- | src/parse/properties/font.c | 172 | ||||
-rw-r--r-- | src/stylesheet.c | 3 | ||||
-rw-r--r-- | src/stylesheet.h | 4 |
5 files changed, 215 insertions, 0 deletions
diff --git a/include/libcss/stylesheet.h b/include/libcss/stylesheet.h index 3c5b92e..9284658 100644 --- a/include/libcss/stylesheet.h +++ b/include/libcss/stylesheet.h @@ -15,6 +15,7 @@ extern "C" #include <libcss/errors.h> #include <libcss/types.h> +#include <libcss/properties.h> /** * Callback to resolve an URL @@ -59,6 +60,34 @@ typedef css_error (*css_import_notification_fn)(void *pw, typedef css_error (*css_color_resolution_fn)(void *pw, lwc_string *name, css_color *color); +/** System font callback result data. */ +struct css_system_font { + enum css_font_style_e style; + enum css_font_variant_e variant; + enum css_font_weight_e weight; + struct { + css_fixed size; + css_unit unit; + } size; + struct { + css_fixed size; + css_unit unit; + } line_height; + lwc_string *family; +}; + +/** + * Callback use to resolve system font names to font values + * + * \param pw Client data + * \param name System colour name + * \param color Pointer to system font to be filled + * \return CSS_OK on success, + * CSS_INVALID if the name is unknown. + */ +typedef css_error (*css_font_resolution_fn)(void *pw, + lwc_string *name, css_system_font *system_font); + /** * Parameter block for css_stylesheet_create() */ @@ -92,6 +121,11 @@ typedef struct css_stylesheet_params { css_color_resolution_fn color; /** Client private data for color */ void *color_pw; + + /** Font resolution function */ + css_font_resolution_fn font; + /** Client private data for color */ + void *font_pw; } css_stylesheet_params; css_error css_stylesheet_create(css_stylesheet_params *params, diff --git a/include/libcss/types.h b/include/libcss/types.h index 8bc65a9..d1f0d51 100644 --- a/include/libcss/types.h +++ b/include/libcss/types.h @@ -106,6 +106,8 @@ typedef struct css_select_ctx css_select_ctx; typedef struct css_computed_style css_computed_style; +typedef struct css_system_font css_system_font; + #ifdef __cplusplus } #endif diff --git a/src/parse/properties/font.c b/src/parse/properties/font.c index 25ce096..c08d6e6 100644 --- a/src/parse/properties/font.c +++ b/src/parse/properties/font.c @@ -13,6 +13,161 @@ #include "parse/properties/properties.h" #include "parse/properties/utils.h" + +static css_error parse_system_font(css_language *c, + css_style *result, css_system_font *system_font) +{ + css_error error; + bool match; + + /* style */ + switch (system_font->style) { + case CSS_FONT_STYLE_NORMAL: + error = css__stylesheet_style_appendOPV(result, CSS_PROP_FONT_STYLE, 0, FONT_STYLE_NORMAL); + break; + + case CSS_FONT_STYLE_ITALIC: + error = css__stylesheet_style_appendOPV(result, CSS_PROP_FONT_STYLE, 0, FONT_STYLE_ITALIC); + break; + + case CSS_FONT_STYLE_OBLIQUE: + error = css__stylesheet_style_appendOPV(result, CSS_PROP_FONT_STYLE, 0, FONT_STYLE_OBLIQUE); + break; + + default: + error = CSS_BADPARM; + break; + } + if (error != CSS_OK) + return error; + + /* variant */ + switch (system_font->variant) { + case CSS_FONT_VARIANT_NORMAL: + error = css__stylesheet_style_appendOPV(result, CSS_PROP_FONT_VARIANT, 0, FONT_VARIANT_NORMAL); + break; + + case CSS_FONT_VARIANT_SMALL_CAPS: + error = css__stylesheet_style_appendOPV(result, CSS_PROP_FONT_VARIANT, 0, FONT_VARIANT_SMALL_CAPS); + break; + + default: + error = CSS_BADPARM; + break; + } + if (error != CSS_OK) + return error; + + /* weight */ + switch(system_font->weight) { + case CSS_FONT_WEIGHT_NORMAL: + error = css__stylesheet_style_appendOPV(result, CSS_PROP_FONT_WEIGHT, 0, FONT_WEIGHT_NORMAL); + break; + + case CSS_FONT_WEIGHT_BOLD: + error = css__stylesheet_style_appendOPV(result, CSS_PROP_FONT_WEIGHT, 0, FONT_WEIGHT_BOLD); + break; + + case CSS_FONT_WEIGHT_BOLDER: + error = css__stylesheet_style_appendOPV(result, CSS_PROP_FONT_WEIGHT, 0, FONT_WEIGHT_BOLDER); + break; + + case CSS_FONT_WEIGHT_LIGHTER: + error = css__stylesheet_style_appendOPV(result, CSS_PROP_FONT_WEIGHT, 0, FONT_WEIGHT_LIGHTER); + break; + + case CSS_FONT_WEIGHT_100: + error = css__stylesheet_style_appendOPV(result, CSS_PROP_FONT_WEIGHT, 0, FONT_WEIGHT_100); + break; + + case CSS_FONT_WEIGHT_200: + error = css__stylesheet_style_appendOPV(result, CSS_PROP_FONT_WEIGHT, 0, FONT_WEIGHT_200); + break; + + case CSS_FONT_WEIGHT_300: + error = css__stylesheet_style_appendOPV(result, CSS_PROP_FONT_WEIGHT, 0, FONT_WEIGHT_300); + break; + + case CSS_FONT_WEIGHT_400: + error = css__stylesheet_style_appendOPV(result, CSS_PROP_FONT_WEIGHT, 0, FONT_WEIGHT_400); + break; + + case CSS_FONT_WEIGHT_500: + error = css__stylesheet_style_appendOPV(result, CSS_PROP_FONT_WEIGHT, 0, FONT_WEIGHT_500); + break; + + case CSS_FONT_WEIGHT_600: + error = css__stylesheet_style_appendOPV(result, CSS_PROP_FONT_WEIGHT, 0, FONT_WEIGHT_600); + break; + + case CSS_FONT_WEIGHT_700: + error = css__stylesheet_style_appendOPV(result, CSS_PROP_FONT_WEIGHT, 0, FONT_WEIGHT_700); + break; + + case CSS_FONT_WEIGHT_800: + error = css__stylesheet_style_appendOPV(result, CSS_PROP_FONT_WEIGHT, 0, FONT_WEIGHT_800); + break; + + case CSS_FONT_WEIGHT_900: + error = css__stylesheet_style_appendOPV(result, CSS_PROP_FONT_WEIGHT, 0, FONT_WEIGHT_900); + break; + + default: + error = CSS_BADPARM; + break; + } + if (error != CSS_OK) + return error; + + /* size */ + error = css__stylesheet_style_appendOPV(result, CSS_PROP_FONT_SIZE, 0, FONT_SIZE_DIMENSION); + if (error != CSS_OK) + return error; + + error = css__stylesheet_style_vappend(result, 2, system_font->size.size, system_font->size.unit); + if (error != CSS_OK) + return error; + + /* line height */ + error = css__stylesheet_style_appendOPV(result, CSS_PROP_LINE_HEIGHT, 0, LINE_HEIGHT_DIMENSION); + if (error != CSS_OK) + return error; + + error = css__stylesheet_style_vappend(result, 2, system_font->line_height.size, system_font->line_height.unit); + if (error != CSS_OK) + return error; + + /* font family */ + if ((lwc_string_caseless_isequal(system_font->family, c->strings[SERIF], &match) == lwc_error_ok && match)) + error = css__stylesheet_style_appendOPV(result, CSS_PROP_FONT_FAMILY, 0, FONT_FAMILY_SERIF); + else if ((lwc_string_caseless_isequal(system_font->family, c->strings[SANS_SERIF], &match) == lwc_error_ok && match)) + error = css__stylesheet_style_appendOPV(result, CSS_PROP_FONT_FAMILY, 0, FONT_FAMILY_SANS_SERIF); + else if ((lwc_string_caseless_isequal(system_font->family, c->strings[CURSIVE], &match) == lwc_error_ok && match)) + error = css__stylesheet_style_appendOPV(result, CSS_PROP_FONT_FAMILY, 0, FONT_FAMILY_CURSIVE); + else if ((lwc_string_caseless_isequal(system_font->family, c->strings[FANTASY], &match) == lwc_error_ok && match)) + error = css__stylesheet_style_appendOPV(result, CSS_PROP_FONT_FAMILY, 0, FONT_FAMILY_FANTASY); + else if ((lwc_string_caseless_isequal(system_font->family, c->strings[MONOSPACE], &match) == lwc_error_ok && match)) + error = css__stylesheet_style_appendOPV(result, CSS_PROP_FONT_FAMILY, 0, FONT_FAMILY_MONOSPACE); + else { + uint32_t snumber; + + error = css__stylesheet_string_add(c->sheet, lwc_string_ref(system_font->family), &snumber); + if (error != CSS_OK) + return error; + + error = css__stylesheet_style_appendOPV(result, CSS_PROP_FONT_FAMILY, 0, FONT_FAMILY_STRING); + if (error != CSS_OK) + return error; + + error = css__stylesheet_style_append(result, snumber); + if (error != CSS_OK) + return error; + } + error = css__stylesheet_style_append(result, FONT_FAMILY_END); + + return error; +} + /** * Parse font * @@ -35,6 +190,8 @@ css_error css__parse_font(css_language *c, css_error error; int orig_ctx = *ctx; int prev_ctx; + css_system_font system_font; + bool style = true; bool variant = true; bool weight = true; @@ -82,6 +239,21 @@ css_error css__parse_font(css_language *c, return error; } + /* Perhaps an unknown font name; ask the client */ + if ((token->type == CSS_TOKEN_IDENT) && + (c->sheet->font != NULL) && + (c->sheet->font(c->sheet->font_pw, + token->idata, + &system_font) == CSS_OK)) { + + error = parse_system_font(c, result, &system_font); + + if (error == CSS_OK) + parserutils_vector_iterate(vector, ctx); + + return error; + } + /* allocate styles */ error = css__stylesheet_style_create(c->sheet, &style_style); diff --git a/src/stylesheet.c b/src/stylesheet.c index d8c3113..382260a 100644 --- a/src/stylesheet.c +++ b/src/stylesheet.c @@ -224,6 +224,9 @@ css_error css_stylesheet_create(css_stylesheet_params *params, sheet->color = params->color; sheet->color_pw = params->color_pw; + sheet->font = params->font; + sheet->font_pw = params->font_pw; + sheet->alloc = alloc; sheet->pw = alloc_pw; diff --git a/src/stylesheet.h b/src/stylesheet.h index 5d4eeb9..9734f02 100644 --- a/src/stylesheet.h +++ b/src/stylesheet.h @@ -199,6 +199,10 @@ struct css_stylesheet { css_color_resolution_fn color; /**< Colour resolution function */ void *color_pw; /**< Private word */ + /** System font resolution function */ + css_font_resolution_fn font; + void *font_pw; /**< Private word */ + css_allocator_fn alloc; /**< Allocation function */ void *pw; /**< Private word */ |