1 /*
2 * This file is part of LibCSS.
3 * Licensed under the MIT License,
4 * http://www.opensource.org/licenses/mit-license.php
5 * Copyright 2009 John-Mark Bell <jmb@netsurf-browser.org>
6 */
7
8 #include <assert.h>
9 #include <string.h>
10
11 #include "bytecode/bytecode.h"
12 #include "bytecode/opcodes.h"
13 #include "parse/properties/properties.h"
14 #include "parse/properties/utils.h"
15
16 /**
17 * Parse font-weight
18 *
19 * \param c Parsing context
20 * \param vector Vector of tokens to process
21 * \param ctx Pointer to vector iteration context
22 * \param result Pointer to location to receive resulting style
23 * \return CSS_OK on success,
24 * CSS_NOMEM on memory exhaustion,
25 * CSS_INVALID if the input is not valid
26 *
27 * Post condition: \a *ctx is updated with the next token to process
28 * If the input is invalid, then \a *ctx remains unchanged.
29 */
css__parse_font_weight(css_language * c,const parserutils_vector * vector,int * ctx,css_style * result)30 css_error css__parse_font_weight(css_language *c,
31 const parserutils_vector *vector, int *ctx,
32 css_style *result)
33 {
34 int orig_ctx = *ctx;
35 css_error error;
36 const css_token *token;
37 uint8_t flags = 0;
38 uint16_t value = 0;
39 bool match;
40
41 /* NUMBER (100, 200, 300, 400, 500, 600, 700, 800, 900) |
42 * IDENT (normal, bold, bolder, lighter, inherit) */
43 token = parserutils_vector_iterate(vector, ctx);
44 if (token == NULL || (token->type != CSS_TOKEN_IDENT &&
45 token->type != CSS_TOKEN_NUMBER)) {
46 *ctx = orig_ctx;
47 return CSS_INVALID;
48 }
49
50 if ((lwc_string_caseless_isequal(
51 token->idata, c->strings[INHERIT],
52 &match) == lwc_error_ok && match)) {
53 flags |= FLAG_INHERIT;
54 } else if (token->type == CSS_TOKEN_NUMBER) {
55 size_t consumed = 0;
56 css_fixed num = css__number_from_lwc_string(token->idata,
57 true, &consumed);
58 /* Invalid if there are trailing characters */
59 if (consumed != lwc_string_length(token->idata)) {
60 *ctx = orig_ctx;
61 return CSS_INVALID;
62 }
63
64 switch (FIXTOINT(num)) {
65 case 100: value = FONT_WEIGHT_100; break;
66 case 200: value = FONT_WEIGHT_200; break;
67 case 300: value = FONT_WEIGHT_300; break;
68 case 400: value = FONT_WEIGHT_400; break;
69 case 500: value = FONT_WEIGHT_500; break;
70 case 600: value = FONT_WEIGHT_600; break;
71 case 700: value = FONT_WEIGHT_700; break;
72 case 800: value = FONT_WEIGHT_800; break;
73 case 900: value = FONT_WEIGHT_900; break;
74 default: *ctx = orig_ctx; return CSS_INVALID;
75 }
76 } else if ((lwc_string_caseless_isequal(
77 token->idata, c->strings[NORMAL],
78 &match) == lwc_error_ok && match)) {
79 value = FONT_WEIGHT_NORMAL;
80 } else if ((lwc_string_caseless_isequal(
81 token->idata, c->strings[BOLD],
82 &match) == lwc_error_ok && match)) {
83 value = FONT_WEIGHT_BOLD;
84 } else if ((lwc_string_caseless_isequal(
85 token->idata, c->strings[BOLDER],
86 &match) == lwc_error_ok && match)) {
87 value = FONT_WEIGHT_BOLDER;
88 } else if ((lwc_string_caseless_isequal(
89 token->idata, c->strings[LIGHTER],
90 &match) == lwc_error_ok && match)) {
91 value = FONT_WEIGHT_LIGHTER;
92 } else {
93 *ctx = orig_ctx;
94 return CSS_INVALID;
95 }
96
97 error = css__stylesheet_style_appendOPV(result,
98 CSS_PROP_FONT_WEIGHT,
99 flags,
100 value);
101 if (error != CSS_OK)
102 *ctx = orig_ctx;
103
104
105 return error;
106 }
107