Subversion Repositories Kolibri OS

Rev

Go to most recent revision | Details | Last modification | View Log | RSS feed

Rev Author Line No. Line
3584 sourcerer 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 
6
 */
7
 
8
#include 
9
#include 
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 elevation
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
 */
30
css_error css__parse_elevation(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
	css_fixed length = 0;
40
	uint32_t unit = 0;
41
	bool match;
42
 
43
	/* angle | IDENT(below, level, above, higher, lower, inherit) */
44
	token = parserutils_vector_peek(vector, *ctx);
45
	if (token == NULL) {
46
		*ctx = orig_ctx;
47
		return CSS_INVALID;
48
	}
49
 
50
	if (token->type == CSS_TOKEN_IDENT &&
51
		(lwc_string_caseless_isequal(
52
			token->idata, c->strings[INHERIT],
53
			&match) == lwc_error_ok && match)) {
54
		parserutils_vector_iterate(vector, ctx);
55
		flags = FLAG_INHERIT;
56
	} else if (token->type == CSS_TOKEN_IDENT &&
57
		(lwc_string_caseless_isequal(
58
			token->idata, c->strings[BELOW],
59
			&match) == lwc_error_ok && match)) {
60
		parserutils_vector_iterate(vector, ctx);
61
		value = ELEVATION_BELOW;
62
	} else if (token->type == CSS_TOKEN_IDENT &&
63
		(lwc_string_caseless_isequal(
64
			token->idata, c->strings[LEVEL],
65
			&match) == lwc_error_ok && match)) {
66
		parserutils_vector_iterate(vector, ctx);
67
		value = ELEVATION_LEVEL;
68
	} else if (token->type == CSS_TOKEN_IDENT &&
69
		(lwc_string_caseless_isequal(
70
			token->idata, c->strings[ABOVE],
71
			&match) == lwc_error_ok && match)) {
72
		parserutils_vector_iterate(vector, ctx);
73
		value = ELEVATION_ABOVE;
74
	} else if (token->type == CSS_TOKEN_IDENT &&
75
		(lwc_string_caseless_isequal(
76
			token->idata, c->strings[HIGHER],
77
			&match) == lwc_error_ok && match)) {
78
		parserutils_vector_iterate(vector, ctx);
79
		value = ELEVATION_HIGHER;
80
	} else if (token->type == CSS_TOKEN_IDENT &&
81
		(lwc_string_caseless_isequal(
82
			token->idata, c->strings[LOWER],
83
			&match) == lwc_error_ok && match)) {
84
		parserutils_vector_iterate(vector, ctx);
85
		value = ELEVATION_LOWER;
86
	} else {
87
		error = css__parse_unit_specifier(c, vector, ctx, UNIT_DEG,
88
				&length, &unit);
89
		if (error != CSS_OK) {
90
			*ctx = orig_ctx;
91
			return error;
92
		}
93
 
94
		if ((unit & UNIT_ANGLE) == false) {
95
			*ctx = orig_ctx;
96
			return CSS_INVALID;
97
		}
98
 
99
		/* Valid angles lie between -90 and 90 degrees */
100
		if (unit == UNIT_DEG) {
101
			if (length < -F_90 || length > F_90) {
102
				*ctx = orig_ctx;
103
				return CSS_INVALID;
104
			}
105
		} else if (unit == UNIT_GRAD) {
106
			if (length < -F_100 || length > F_100) {
107
				*ctx = orig_ctx;
108
				return CSS_INVALID;
109
			}
110
		} else if (unit == UNIT_RAD) {
111
			if (length < -F_PI_2 || length > F_PI_2) {
112
				*ctx = orig_ctx;
113
				return CSS_INVALID;
114
			}
115
		}
116
 
117
		value = ELEVATION_ANGLE;
118
	}
119
 
120
	error = css__stylesheet_style_appendOPV(result, CSS_PROP_ELEVATION, flags, value);
121
	if (error != CSS_OK) {
122
		*ctx = orig_ctx;
123
		return error;
124
	}
125
 
126
	if (((flags & FLAG_INHERIT) == false) && (value == ELEVATION_ANGLE)) {
127
		error = css__stylesheet_style_vappend(result, 2, length, unit);
128
		if (error != CSS_OK) {
129
			*ctx = orig_ctx;
130
			return error;
131
		}
132
	}
133
 
134
	return CSS_OK;
135
}