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