Esempio n. 1
0
int
css_parse_background_value(struct css_property_info *propinfo,
			   union css_property_value *value,
			   struct scanner *scanner)
{
	int success = 0;

	assert(propinfo->value_type == CSS_VT_COLOR);

	/* This is pretty naive, we just jump space by space, trying to parse
	 * each token as a color. */

	while (scanner_has_tokens(scanner)) {
		struct scanner_token *token = get_scanner_token(scanner);

		if (!check_css_precedence(token->type, ';'))
			break;

		if (token->type == ','
		    || !css_parse_color_value(propinfo, value, scanner)) {
			skip_scanner_token(scanner);
			continue;
		}

		success++;
	}

	return success;
}
Esempio n. 2
0
static struct scanner_token *
scan_css_tokens(struct scanner *scanner)
{
	struct scanner_token *table_end = scanner->table + SCANNER_TOKENS;
	struct scanner_token *current;

	if (!begin_token_scanning(scanner))
		return get_scanner_token(scanner);

	/* Scan tokens until we fill the table */
	for (current = scanner->table + scanner->tokens;
	     current < table_end && scanner->position < scanner->end;
	     current++) {
		scan_css(scanner, scanner->position, CSS_CHAR_WHITESPACE);
		if (scanner->position >= scanner->end) break;

		scan_css_token(scanner, current);

		/* Did some one scream for us to end the madness? */
		if (current->type == CSS_TOKEN_NONE) {
			scanner->position = NULL;
			current--;
			break;
		}

		/* Shall we scratch this token? */
		if (current->type == CSS_TOKEN_SKIP) {
 			current--;
		}
	}

	return end_token_scanning(scanner, current);
}
Esempio n. 3
0
int
css_parse_display_value(struct css_property_info *propinfo,
			union css_property_value *value,
			struct scanner *scanner)
{
	struct scanner_token *token = get_scanner_token(scanner);

	assert(propinfo->value_type == CSS_VT_DISPLAY);

	if (token->type != CSS_TOKEN_IDENT) return 0;

	/* FIXME: This is _very_ simplistic */
	if (scanner_token_contains(token, "inline")) {
		value->display = CSS_DISP_INLINE;
	} else if (scanner_token_contains(token, "inline-block")) {
		value->display = CSS_DISP_INLINE; /* XXX */
	} else if (scanner_token_contains(token, "block")) {
		value->display = CSS_DISP_BLOCK;
	} else if (scanner_token_contains(token, "none")) {
		value->display = CSS_DISP_NONE;
	} else {
		return 0;
	}

	skip_css_tokens(scanner, CSS_TOKEN_IDENT);
	return 1;
}
Esempio n. 4
0
int
css_parse_text_decoration_value(struct css_property_info *propinfo,
				union css_property_value *value,
				struct scanner *scanner)
{
	struct scanner_token *token = get_scanner_token(scanner);

	assert(propinfo->value_type == CSS_VT_FONT_ATTRIBUTE);

	if (token->type != CSS_TOKEN_IDENT) return 0;

	/* TODO: It is possible to have multiple values here,
	 * 'background'-style. --pasky */
	if (scanner_token_contains(token, "underline")) {
		value->font_attribute.add |= AT_UNDERLINE;

	} else if (scanner_token_contains(token, "none")) {
		value->font_attribute.rem |= AT_UNDERLINE;

	} else {
		return 0;
	}

	skip_css_tokens(scanner, CSS_TOKEN_IDENT);
	return 1;
}
Esempio n. 5
0
int
css_parse_white_space_value(struct css_property_info *propinfo,
			    union css_property_value *value,
			    struct scanner *scanner)
{
	struct scanner_token *token = get_scanner_token(scanner);

	assert(propinfo->value_type == CSS_VT_FONT_ATTRIBUTE);

	if (token->type != CSS_TOKEN_IDENT) return 0;

	/* FIXME: nowrap */
	if (scanner_token_contains(token, "pre")) {
		value->font_attribute.add |= AT_PREFORMATTED;

	} else if (scanner_token_contains(token, "normal")) {
		value->font_attribute.rem |= AT_PREFORMATTED;

	} else {
		return 0;
	}

	skip_css_tokens(scanner, CSS_TOKEN_IDENT);
	return 1;
}
Esempio n. 6
0
int
css_parse_text_align_value(struct css_property_info *propinfo,
			   union css_property_value *value,
			   struct scanner *scanner)
{
	struct scanner_token *token = get_scanner_token(scanner);

	assert(propinfo->value_type == CSS_VT_TEXT_ALIGN);

	if (token->type != CSS_TOKEN_IDENT) return 0;

	if (scanner_token_contains(token, "left")) {
		value->text_align = ALIGN_LEFT;

	} else 	if (scanner_token_contains(token, "right")) {
		value->text_align = ALIGN_RIGHT;

	} else 	if (scanner_token_contains(token, "center")) {
		value->text_align = ALIGN_CENTER;

	} else 	if (scanner_token_contains(token, "justify")) {
		value->text_align = ALIGN_JUSTIFY;

	} else {
		return 0;
	}

	skip_css_tokens(scanner, CSS_TOKEN_IDENT);
	return 1;
}
Esempio n. 7
0
int
css_parse_font_style_value(struct css_property_info *propinfo,
			   union css_property_value *value,
			   struct scanner *scanner)
{
	struct scanner_token *token = get_scanner_token(scanner);

	assert(propinfo->value_type == CSS_VT_FONT_ATTRIBUTE);

	if (token->type != CSS_TOKEN_IDENT) return 0;

	if (scanner_token_contains(token, "italic")
	    || scanner_token_contains(token, "oblique")) {
		value->font_attribute.add |= AT_ITALIC;

	} else if (scanner_token_contains(token, "underline")) {
		value->font_attribute.add |= AT_UNDERLINE;

	} else if (scanner_token_contains(token, "normal")) {
		value->font_attribute.rem |= AT_ITALIC;

	} else {
		return 0;
	}

	skip_css_tokens(scanner, CSS_TOKEN_IDENT);
	return 1;
}
Esempio n. 8
0
struct scanner_token *
get_scanner_token_debug(struct scanner *scanner)
{
	if (!scanner_has_tokens(scanner)) return NULL;

	dump_scanner(scanner);

	/* Make sure we do not return invalid tokens */
	assert(!scanner_has_tokens(scanner)
		|| scanner->current->type != 0);

	return get_scanner_token(scanner);
}
Esempio n. 9
0
int
css_parse_font_weight_value(struct css_property_info *propinfo,
			    union css_property_value *value,
			    struct scanner *scanner)
{
	struct scanner_token *token = get_scanner_token(scanner);
	unsigned char *nstring;
	int weight;

	assert(propinfo->value_type == CSS_VT_FONT_ATTRIBUTE);

	if (token->type == CSS_TOKEN_IDENT) {
		if (scanner_token_contains(token, "bolder")) {
			value->font_attribute.add |= AT_BOLD;

		} else if (scanner_token_contains(token, "lighter")) {
			value->font_attribute.rem |= AT_BOLD;

		} else if (scanner_token_contains(token, "bold")) {
			value->font_attribute.add |= AT_BOLD;

		} else if (scanner_token_contains(token, "normal")) {
			value->font_attribute.rem |= AT_BOLD;

		} else {
			return 0;
		}

		skip_css_tokens(scanner, CSS_TOKEN_IDENT);
		return 1;
	}

	if (token->type != CSS_TOKEN_NUMBER) return 0;

	/* TODO: Comma separated list of weights?! */
	weight = strtol(token->string, (char **) &nstring, 10);
	if (token->string == nstring) return 0;

	skip_css_tokens(scanner, CSS_TOKEN_NUMBER);
	/* The font weight(s) have values between 100 to 900.  These
	 * values form an ordered sequence, where each number indicates
	 * a weight that is at least as dark as its predecessor.
	 *
	 * normal -> Same as '400'.  bold Same as '700'.
	 */
	int_bounds(&weight, 100, 900);
	if (weight >= 700) value->font_attribute.add |= AT_BOLD;
	return 1;
}
Esempio n. 10
0
int
css_parse_value(struct css_property_info *propinfo,
		union css_property_value *value,
		struct scanner *scanner)
{
	struct scanner_token *token;

	assert(scanner && value && propinfo);
	assert(propinfo->parser);

	/* Check that we actually have some token to pass on */
	token = get_scanner_token(scanner);
	if (!token) return 0;

	return propinfo->parser(propinfo, value, scanner);
}
Esempio n. 11
0
struct scanner_token *
skip_scanner_tokens(struct scanner *scanner, int skipto, int precedence)
{
	struct scanner_token *token = get_scanner_token(scanner);

	/* Skip tokens while handling some basic precedens of special chars
	 * so we don't skip to long. */
	while (token) {
		if (token->type == skipto
		    || token->precedence > precedence)
			break;
		token = get_next_scanner_token(scanner);
	}

	return (token && token->type == skipto)
		? get_next_scanner_token(scanner) : NULL;
}
Esempio n. 12
0
int
css_parse_color_value(struct css_property_info *propinfo,
		      union css_property_value *value,
		      struct scanner *scanner)
{
	struct scanner_token *token = get_scanner_token(scanner);

	assert(propinfo->value_type == CSS_VT_COLOR);

	if (token->type == CSS_TOKEN_RGB) {
		/* RGB function */
		int shift;

		token = get_next_scanner_token(scanner);

		/* First color component is shifted 16, next is shifted 8 and
		 * last is not shifted. */
		for (shift = 16; token && shift >= 0; shift -= 8) {
			/* The first two args are terminated by ',' and the
			 * last one by ')'. */
			unsigned char paskynator = shift ? ',' : ')';
			const unsigned char *nstring = token->string;
			int part;

			/* Are the current and next token valid? */
			if ((token->type != CSS_TOKEN_NUMBER
			     && token->type != CSS_TOKEN_PERCENTAGE)
			    || !check_next_scanner_token(scanner, paskynator))
				return 0;

			/* Parse the digit */
			part = strtol(token->string, (char **) &nstring, 10);
			if (token->string == nstring)
				return 0;

			/* Adjust percentage values */
			if (token->type == CSS_TOKEN_PERCENTAGE) {
				int_bounds(&part, 0, 100);
				part *= 255;
				part /= 100;
			}

			/* Adjust color component value and add it */
			int_bounds(&part, 0, 255);
			value->color |= part << shift;

			/* Paskynate the token arg and separator */
			token = skip_css_tokens(scanner, paskynator);
		}

		return 1;
	}

	/* Just a color value we already know how to parse. */
	if (token->type != CSS_TOKEN_IDENT
	    && token->type != CSS_TOKEN_HEX_COLOR)
		return 0;

	if (decode_color(token->string, token->length, &value->color) < 0) {
		return 0;
	}

	skip_css_tokens(scanner, token->type);
	return 1;
}
Esempio n. 13
0
int
css_parse_list_style_value(struct css_property_info *propinfo,
			   union css_property_value *value,
			   struct scanner *scanner)
{
	struct scanner_token *token = get_scanner_token(scanner);

	assert(propinfo->value_type == CSS_VT_LIST_STYLE);

	if (token->type != CSS_TOKEN_IDENT) return 0;

	if (scanner_token_contains(token, "none")) {
		value->list_style = CSS_LIST_NONE;

	} else if (scanner_token_contains(token, "disc")) {
		value->list_style = CSS_LIST_DISC;

	} else if (scanner_token_contains(token, "circle")) {
		value->list_style = CSS_LIST_CIRCLE;

	} else if (scanner_token_contains(token, "square")) {
		value->list_style = CSS_LIST_SQUARE;

	} else if (scanner_token_contains(token, "decimal")) {
		value->list_style = CSS_LIST_DECIMAL;

	} else if (scanner_token_contains(token, "decimal-leading-zero")) {
		value->list_style = CSS_LIST_DECIMAL_LEADING_ZERO;

	} else if (scanner_token_contains(token, "lower-roman")) {
		value->list_style = CSS_LIST_LOWER_ROMAN;

	} else if (scanner_token_contains(token, "upper-roman")) {
		value->list_style = CSS_LIST_UPPER_ROMAN;

	} else if (scanner_token_contains(token, "lower-alpha")) {
		value->list_style = CSS_LIST_LOWER_ALPHA;

	} else if (scanner_token_contains(token, "upper-alpha")) {
		value->list_style = CSS_LIST_UPPER_ALPHA;

	} else if (scanner_token_contains(token, "lower-greek")) {
		value->list_style = CSS_LIST_LOWER_GREEK;

	} else if (scanner_token_contains(token, "lower-latin")) {
		value->list_style = CSS_LIST_LOWER_LATIN;

	} else if (scanner_token_contains(token, "upper-latin")) {
		value->list_style = CSS_LIST_UPPER_LATIN;

	} else if (scanner_token_contains(token, "hebrew")) {
		value->list_style = CSS_LIST_HEBREW;

	} else if (scanner_token_contains(token, "armenian")) {
		value->list_style = CSS_LIST_ARMENIAN;

	} else if (scanner_token_contains(token, "georgian")) {
		value->list_style = CSS_LIST_GEORGIAN;

	} else if (scanner_token_contains(token, "cjk-ideographic")) {
		value->list_style = CSS_LIST_CJK_IDEOGRAPHIC;

	} else if (scanner_token_contains(token, "hiragana")) {
		value->list_style = CSS_LIST_HIRAGANA;

	} else if (scanner_token_contains(token, "katakana")) {
		value->list_style = CSS_LIST_KATAKANA;

	} else if (scanner_token_contains(token, "hiragana-iroha")) {
		value->list_style = CSS_LIST_HIRAGANA_IROHA;

	} else if (scanner_token_contains(token, "katakana-iroha")) {
		value->list_style = CSS_LIST_KATAKANA_IROHA;

	} else {
		return 0;
	}

	skip_css_tokens(scanner, CSS_TOKEN_IDENT);
	return 1;
}