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 "bytecode/bytecode.h"
9
#include "bytecode/opcodes.h"
10
#include "select/propset.h"
11
#include "select/propget.h"
12
#include "utils/utils.h"
13
 
14
#include "select/properties/properties.h"
15
#include "select/properties/helpers.h"
16
 
17
css_error css__cascade_content(uint32_t opv, css_style *style,
18
		css_select_state *state)
19
{
20
	uint16_t value = CSS_CONTENT_INHERIT;
21
	css_computed_content_item *content = NULL;
22
	uint32_t n_contents = 0;
23
 
24
	if (isInherit(opv) == false) {
25
		uint32_t v = getValue(opv);
26
 
27
		if (v == CONTENT_NORMAL) {
28
			value = CSS_CONTENT_NORMAL;
29
		} else if (v == CONTENT_NONE) {
30
			value = CSS_CONTENT_NONE;
31
		} else {
32
			value = CSS_CONTENT_SET;
33
 
34
			while (v != CONTENT_NORMAL) {
35
				lwc_string *he;
36
				css_computed_content_item *temp;
37
 
38
				css__stylesheet_string_get(style->sheet, *((css_code_t *) style->bytecode), &he);
39
 
40
				temp = state->computed->alloc(content,
41
						(n_contents + 1) *
42
						sizeof(css_computed_content_item),
43
						state->computed->pw);
44
				if (temp == NULL) {
45
					if (content != NULL) {
46
						state->computed->alloc(content,
47
							0, state->computed->pw);
48
					}
49
					return CSS_NOMEM;
50
				}
51
 
52
				content = temp;
53
 
54
				switch (v & 0xff) {
55
				case CONTENT_COUNTER:
56
					advance_bytecode(style, sizeof(css_code_t));
57
 
58
					content[n_contents].type =
59
						CSS_COMPUTED_CONTENT_COUNTER;
60
					content[n_contents].data.counter.name = he;
61
					content[n_contents].data.counter.style = v >> CONTENT_COUNTER_STYLE_SHIFT;
62
					break;
63
				case CONTENT_COUNTERS:
64
				{
65
					lwc_string *sep;
66
 
67
					advance_bytecode(style, sizeof(css_code_t));
68
 
69
					css__stylesheet_string_get(style->sheet, *((css_code_t *) style->bytecode), &sep);
70
					advance_bytecode(style, sizeof(css_code_t));
71
 
72
					content[n_contents].type =
73
						CSS_COMPUTED_CONTENT_COUNTERS;
74
					content[n_contents].data.counters.name = he;
75
					content[n_contents].data.counters.sep = sep;
76
					content[n_contents].data.counters.style = v >> CONTENT_COUNTERS_STYLE_SHIFT;
77
				}
78
					break;
79
				case CONTENT_URI:
80
					advance_bytecode(style, sizeof(css_code_t));
81
 
82
					content[n_contents].type =
83
						CSS_COMPUTED_CONTENT_URI;
84
					content[n_contents].data.uri = he;
85
					break;
86
				case CONTENT_ATTR:
87
					advance_bytecode(style, sizeof(css_code_t));
88
 
89
					content[n_contents].type =
90
						CSS_COMPUTED_CONTENT_ATTR;
91
					content[n_contents].data.attr = he;
92
					break;
93
				case CONTENT_STRING:
94
					advance_bytecode(style, sizeof(css_code_t));
95
 
96
					content[n_contents].type =
97
						CSS_COMPUTED_CONTENT_STRING;
98
					content[n_contents].data.string = he;
99
					break;
100
				case CONTENT_OPEN_QUOTE:
101
					content[n_contents].type =
102
						CSS_COMPUTED_CONTENT_OPEN_QUOTE;
103
					break;
104
				case CONTENT_CLOSE_QUOTE:
105
					content[n_contents].type =
106
						CSS_COMPUTED_CONTENT_CLOSE_QUOTE;
107
					break;
108
				case CONTENT_NO_OPEN_QUOTE:
109
					content[n_contents].type =
110
						CSS_COMPUTED_CONTENT_NO_OPEN_QUOTE;
111
					break;
112
				case CONTENT_NO_CLOSE_QUOTE:
113
					content[n_contents].type =
114
						CSS_COMPUTED_CONTENT_NO_CLOSE_QUOTE;
115
					break;
116
				}
117
 
118
				n_contents++;
119
 
120
				v = *((uint32_t *) style->bytecode);
121
				advance_bytecode(style, sizeof(v));
122
			}
123
		}
124
	}
125
 
126
	/* If we have some content, terminate the array with a blank entry */
127
	if (n_contents > 0) {
128
		css_computed_content_item *temp;
129
 
130
		temp = state->computed->alloc(content,
131
				(n_contents + 1) * sizeof(css_computed_content_item),
132
				state->computed->pw);
133
		if (temp == NULL) {
134
			state->computed->alloc(content, 0, state->computed->pw);
135
			return CSS_NOMEM;
136
		}
137
 
138
		content = temp;
139
 
140
		content[n_contents].type = CSS_COMPUTED_CONTENT_NONE;
141
	}
142
 
143
	if (css__outranks_existing(getOpcode(opv), isImportant(opv), state,
144
			isInherit(opv))) {
145
		css_error error;
146
 
147
		error = set_content(state->computed, value, content);
148
		if (error != CSS_OK && content != NULL)
149
			state->computed->alloc(content, 0, state->computed->pw);
150
 
151
		return error;
152
	} else if (content != NULL) {
153
		state->computed->alloc(content, 0, state->computed->pw);
154
	}
155
 
156
	return CSS_OK;
157
}
158
 
159
css_error css__set_content_from_hint(const css_hint *hint,
160
		css_computed_style *style)
161
{
162
	css_computed_content_item *item;
163
	css_error error;
164
 
165
	error = set_content(style, hint->status, hint->data.content);
166
 
167
	for (item = hint->data.content; item != NULL &&
168
			item->type != CSS_COMPUTED_CONTENT_NONE;
169
			item++) {
170
		switch (item->type) {
171
		case CSS_COMPUTED_CONTENT_STRING:
172
			lwc_string_unref(item->data.string);
173
			break;
174
		case CSS_COMPUTED_CONTENT_URI:
175
			lwc_string_unref(item->data.uri);
176
			break;
177
		case CSS_COMPUTED_CONTENT_COUNTER:
178
			lwc_string_unref(item->data.counter.name);
179
			break;
180
		case CSS_COMPUTED_CONTENT_COUNTERS:
181
			lwc_string_unref(item->data.counters.name);
182
			lwc_string_unref(item->data.counters.sep);
183
			break;
184
		case CSS_COMPUTED_CONTENT_ATTR:
185
			lwc_string_unref(item->data.attr);
186
			break;
187
		default:
188
			break;
189
		}
190
	}
191
 
192
	if (error != CSS_OK && hint->data.content != NULL)
193
		style->alloc(hint->data.content, 0, style->pw);
194
 
195
	return error;
196
}
197
 
198
css_error css__initial_content(css_select_state *state)
199
{
200
	return set_content(state->computed, CSS_CONTENT_NORMAL, NULL);
201
}
202
 
203
css_error css__compose_content(const css_computed_style *parent,
204
		const css_computed_style *child,
205
		css_computed_style *result)
206
{
207
	css_error error;
208
	const css_computed_content_item *items = NULL;
209
	uint8_t type = get_content(child, &items);
210
 
211
	if ((child->uncommon == NULL && parent->uncommon != NULL) ||
212
			type == CSS_CONTENT_INHERIT ||
213
			(child->uncommon != NULL && result != child)) {
214
		size_t n_items = 0;
215
		css_computed_content_item *copy = NULL;
216
 
217
		if ((child->uncommon == NULL && parent->uncommon != NULL) ||
218
				type == CSS_CONTENT_INHERIT) {
219
			type = get_content(parent, &items);
220
		}
221
 
222
		if (type == CSS_CONTENT_SET) {
223
			const css_computed_content_item *i;
224
 
225
			for (i = items; i->type != CSS_COMPUTED_CONTENT_NONE;
226
					i++)
227
				n_items++;
228
 
229
			copy = result->alloc(NULL, (n_items + 1) *
230
					sizeof(css_computed_content_item),
231
					result->pw);
232
			if (copy == NULL)
233
				return CSS_NOMEM;
234
 
235
			memcpy(copy, items, (n_items + 1) *
236
					sizeof(css_computed_content_item));
237
		}
238
 
239
		error = set_content(result, type, copy);
240
		if (error != CSS_OK && copy != NULL)
241
			result->alloc(copy, 0, result->pw);
242
 
243
		return error;
244
	}
245
 
246
	return CSS_OK;
247
}
248