1 | /* GTK - The GIMP Toolkit |
2 | * Copyright (C) 2011 Red Hat, Inc. |
3 | * |
4 | * This library is free software; you can redistribute it and/or |
5 | * modify it under the terms of the GNU Lesser General Public |
6 | * License as published by the Free Software Foundation; either |
7 | * version 2 of the License, or (at your option) any later version. |
8 | * |
9 | * This library is distributed in the hope that it will be useful, |
10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of |
11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU |
12 | * Lesser General Public License for more details. |
13 | * |
14 | * You should have received a copy of the GNU Lesser General Public |
15 | * License along with this library. If not, see <http://www.gnu.org/licenses/>. |
16 | */ |
17 | |
18 | #include "config.h" |
19 | |
20 | #include "gtkcssenumvalueprivate.h" |
21 | |
22 | #include "gtkcssstyleprivate.h" |
23 | #include "gtkcssnumbervalueprivate.h" |
24 | #include "gtkstyleproviderprivate.h" |
25 | #include "gtksettingsprivate.h" |
26 | |
27 | #include "gtkpopcountprivate.h" |
28 | |
29 | /* repeated API */ |
30 | |
31 | struct _GtkCssValue { |
32 | GTK_CSS_VALUE_BASE |
33 | int value; |
34 | const char *name; |
35 | }; |
36 | |
37 | static void |
38 | gtk_css_value_enum_free (GtkCssValue *value) |
39 | { |
40 | g_slice_free (GtkCssValue, value); |
41 | } |
42 | |
43 | static GtkCssValue * |
44 | gtk_css_value_enum_compute (GtkCssValue *value, |
45 | guint property_id, |
46 | GtkStyleProvider *provider, |
47 | GtkCssStyle *style, |
48 | GtkCssStyle *parent_style) |
49 | { |
50 | return _gtk_css_value_ref (value); |
51 | } |
52 | |
53 | static gboolean |
54 | gtk_css_value_enum_equal (const GtkCssValue *enum1, |
55 | const GtkCssValue *enum2) |
56 | { |
57 | return enum1 == enum2; |
58 | } |
59 | |
60 | static GtkCssValue * |
61 | gtk_css_value_enum_transition (GtkCssValue *start, |
62 | GtkCssValue *end, |
63 | guint property_id, |
64 | double progress) |
65 | { |
66 | return NULL; |
67 | } |
68 | |
69 | static void |
70 | gtk_css_value_enum_print (const GtkCssValue *value, |
71 | GString *string) |
72 | { |
73 | g_string_append (string, val: value->name); |
74 | } |
75 | |
76 | /* GtkBorderStyle */ |
77 | |
78 | static const GtkCssValueClass GTK_CSS_VALUE_BORDER_STYLE = { |
79 | "GtkCssBorderStyleValue" , |
80 | gtk_css_value_enum_free, |
81 | gtk_css_value_enum_compute, |
82 | gtk_css_value_enum_equal, |
83 | gtk_css_value_enum_transition, |
84 | NULL, |
85 | NULL, |
86 | gtk_css_value_enum_print |
87 | }; |
88 | |
89 | static GtkCssValue border_style_values[] = { |
90 | { .class: >K_CSS_VALUE_BORDER_STYLE, .ref_count: 1, TRUE, .value: GTK_BORDER_STYLE_NONE, .name: "none" }, |
91 | { >K_CSS_VALUE_BORDER_STYLE, 1, TRUE, GTK_BORDER_STYLE_SOLID, "solid" }, |
92 | { >K_CSS_VALUE_BORDER_STYLE, 1, TRUE, GTK_BORDER_STYLE_INSET, "inset" }, |
93 | { >K_CSS_VALUE_BORDER_STYLE, 1, TRUE, GTK_BORDER_STYLE_OUTSET, "outset" }, |
94 | { >K_CSS_VALUE_BORDER_STYLE, 1, TRUE, GTK_BORDER_STYLE_HIDDEN, "hidden" }, |
95 | { >K_CSS_VALUE_BORDER_STYLE, 1, TRUE, GTK_BORDER_STYLE_DOTTED, "dotted" }, |
96 | { >K_CSS_VALUE_BORDER_STYLE, 1, TRUE, GTK_BORDER_STYLE_DASHED, "dashed" }, |
97 | { >K_CSS_VALUE_BORDER_STYLE, 1, TRUE, GTK_BORDER_STYLE_DOUBLE, "double" }, |
98 | { >K_CSS_VALUE_BORDER_STYLE, 1, TRUE, GTK_BORDER_STYLE_GROOVE, "groove" }, |
99 | { >K_CSS_VALUE_BORDER_STYLE, 1, TRUE, GTK_BORDER_STYLE_RIDGE, "ridge" } |
100 | }; |
101 | |
102 | GtkCssValue * |
103 | _gtk_css_border_style_value_new (GtkBorderStyle border_style) |
104 | { |
105 | g_return_val_if_fail (border_style < G_N_ELEMENTS (border_style_values), NULL); |
106 | |
107 | return _gtk_css_value_ref (value: &border_style_values[border_style]); |
108 | } |
109 | |
110 | GtkCssValue * |
111 | _gtk_css_border_style_value_try_parse (GtkCssParser *parser) |
112 | { |
113 | guint i; |
114 | |
115 | g_return_val_if_fail (parser != NULL, NULL); |
116 | |
117 | for (i = 0; i < G_N_ELEMENTS (border_style_values); i++) |
118 | { |
119 | if (gtk_css_parser_try_ident (self: parser, ident: border_style_values[i].name)) |
120 | return _gtk_css_value_ref (value: &border_style_values[i]); |
121 | } |
122 | |
123 | return NULL; |
124 | } |
125 | |
126 | GtkBorderStyle |
127 | _gtk_css_border_style_value_get (const GtkCssValue *value) |
128 | { |
129 | g_return_val_if_fail (value->class == >K_CSS_VALUE_BORDER_STYLE, GTK_BORDER_STYLE_NONE); |
130 | |
131 | return value->value; |
132 | } |
133 | |
134 | /* GtkCssBlendMode */ |
135 | |
136 | static const GtkCssValueClass GTK_CSS_VALUE_BLEND_MODE = { |
137 | "GtkCssBlendModeValue" , |
138 | gtk_css_value_enum_free, |
139 | gtk_css_value_enum_compute, |
140 | gtk_css_value_enum_equal, |
141 | gtk_css_value_enum_transition, |
142 | NULL, |
143 | NULL, |
144 | gtk_css_value_enum_print |
145 | }; |
146 | |
147 | static GtkCssValue blend_mode_values[] = { |
148 | { .class: >K_CSS_VALUE_BLEND_MODE, .ref_count: 1, TRUE, .value: GSK_BLEND_MODE_DEFAULT, .name: "normal" }, |
149 | { >K_CSS_VALUE_BLEND_MODE, 1, TRUE, GSK_BLEND_MODE_MULTIPLY, "multiply" }, |
150 | { >K_CSS_VALUE_BLEND_MODE, 1, TRUE, GSK_BLEND_MODE_SCREEN, "screen" }, |
151 | { >K_CSS_VALUE_BLEND_MODE, 1, TRUE, GSK_BLEND_MODE_OVERLAY, "overlay" }, |
152 | { >K_CSS_VALUE_BLEND_MODE, 1, TRUE, GSK_BLEND_MODE_DARKEN, "darken" }, |
153 | { >K_CSS_VALUE_BLEND_MODE, 1, TRUE, GSK_BLEND_MODE_LIGHTEN, "lighten" }, |
154 | { >K_CSS_VALUE_BLEND_MODE, 1, TRUE, GSK_BLEND_MODE_COLOR_DODGE, "color-dodge" }, |
155 | { >K_CSS_VALUE_BLEND_MODE, 1, TRUE, GSK_BLEND_MODE_COLOR_BURN, "color-burn" }, |
156 | { >K_CSS_VALUE_BLEND_MODE, 1, TRUE, GSK_BLEND_MODE_HARD_LIGHT, "hard-light" }, |
157 | { >K_CSS_VALUE_BLEND_MODE, 1, TRUE, GSK_BLEND_MODE_SOFT_LIGHT, "soft-light" }, |
158 | { >K_CSS_VALUE_BLEND_MODE, 1, TRUE, GSK_BLEND_MODE_DIFFERENCE, "difference" }, |
159 | { >K_CSS_VALUE_BLEND_MODE, 1, TRUE, GSK_BLEND_MODE_EXCLUSION, "exclusion" }, |
160 | { >K_CSS_VALUE_BLEND_MODE, 1, TRUE, GSK_BLEND_MODE_COLOR, "color" }, |
161 | { >K_CSS_VALUE_BLEND_MODE, 1, TRUE, GSK_BLEND_MODE_HUE, "hue" }, |
162 | { >K_CSS_VALUE_BLEND_MODE, 1, TRUE, GSK_BLEND_MODE_SATURATION, "saturation" }, |
163 | { >K_CSS_VALUE_BLEND_MODE, 1, TRUE, GSK_BLEND_MODE_LUMINOSITY, "luminosity" } |
164 | }; |
165 | |
166 | GtkCssValue * |
167 | _gtk_css_blend_mode_value_new (GskBlendMode blend_mode) |
168 | { |
169 | g_return_val_if_fail (blend_mode < G_N_ELEMENTS (blend_mode_values), NULL); |
170 | |
171 | return _gtk_css_value_ref (value: &blend_mode_values[blend_mode]); |
172 | } |
173 | |
174 | GtkCssValue * |
175 | _gtk_css_blend_mode_value_try_parse (GtkCssParser *parser) |
176 | { |
177 | guint i; |
178 | |
179 | g_return_val_if_fail (parser != NULL, NULL); |
180 | |
181 | for (i = 0; i < G_N_ELEMENTS (blend_mode_values); i++) |
182 | { |
183 | if (gtk_css_parser_try_ident (self: parser, ident: blend_mode_values[i].name)) |
184 | return _gtk_css_value_ref (value: &blend_mode_values[i]); |
185 | } |
186 | |
187 | return NULL; |
188 | } |
189 | |
190 | GskBlendMode |
191 | _gtk_css_blend_mode_value_get (const GtkCssValue *value) |
192 | { |
193 | g_return_val_if_fail (value->class == >K_CSS_VALUE_BLEND_MODE, GSK_BLEND_MODE_DEFAULT); |
194 | |
195 | return value->value; |
196 | } |
197 | |
198 | /* GtkCssFontSize */ |
199 | |
200 | static double |
201 | get_dpi (GtkCssStyle *style) |
202 | { |
203 | return _gtk_css_number_value_get (number: style->core->dpi, one_hundred_percent: 96); |
204 | } |
205 | |
206 | /* XXX: Kinda bad to have that machinery here, nobody expects vital font |
207 | * size code to appear in gtkcssvalueenum.c. |
208 | */ |
209 | #define DEFAULT_FONT_SIZE_PT 10 |
210 | |
211 | double |
212 | gtk_css_font_size_get_default_px (GtkStyleProvider *provider, |
213 | GtkCssStyle *style) |
214 | { |
215 | GtkSettings *settings; |
216 | int font_size; |
217 | |
218 | settings = gtk_style_provider_get_settings (provider); |
219 | if (settings == NULL) |
220 | return DEFAULT_FONT_SIZE_PT * get_dpi (style) / 72.0; |
221 | |
222 | font_size = gtk_settings_get_font_size (settings); |
223 | if (font_size == 0) |
224 | return DEFAULT_FONT_SIZE_PT * get_dpi (style) / 72.0; |
225 | else if (gtk_settings_get_font_size_is_absolute (settings)) |
226 | return (double) font_size / PANGO_SCALE; |
227 | else |
228 | return ((double) font_size / PANGO_SCALE) * get_dpi (style) / 72.0; |
229 | } |
230 | |
231 | static GtkCssValue * |
232 | gtk_css_value_font_size_compute (GtkCssValue *value, |
233 | guint property_id, |
234 | GtkStyleProvider *provider, |
235 | GtkCssStyle *style, |
236 | GtkCssStyle *parent_style) |
237 | { |
238 | double font_size; |
239 | |
240 | switch (value->value) |
241 | { |
242 | case GTK_CSS_FONT_SIZE_XX_SMALL: |
243 | font_size = gtk_css_font_size_get_default_px (provider, style) * 3. / 5; |
244 | break; |
245 | case GTK_CSS_FONT_SIZE_X_SMALL: |
246 | font_size = gtk_css_font_size_get_default_px (provider, style) * 3. / 4; |
247 | break; |
248 | case GTK_CSS_FONT_SIZE_SMALL: |
249 | font_size = gtk_css_font_size_get_default_px (provider, style) * 8. / 9; |
250 | break; |
251 | default: |
252 | g_assert_not_reached (); |
253 | /* fall thru */ |
254 | case GTK_CSS_FONT_SIZE_MEDIUM: |
255 | font_size = gtk_css_font_size_get_default_px (provider, style); |
256 | break; |
257 | case GTK_CSS_FONT_SIZE_LARGE: |
258 | font_size = gtk_css_font_size_get_default_px (provider, style) * 6. / 5; |
259 | break; |
260 | case GTK_CSS_FONT_SIZE_X_LARGE: |
261 | font_size = gtk_css_font_size_get_default_px (provider, style) * 3. / 2; |
262 | break; |
263 | case GTK_CSS_FONT_SIZE_XX_LARGE: |
264 | font_size = gtk_css_font_size_get_default_px (provider, style) * 2; |
265 | break; |
266 | case GTK_CSS_FONT_SIZE_SMALLER: |
267 | if (parent_style) |
268 | font_size = _gtk_css_number_value_get (number: parent_style->core->font_size, one_hundred_percent: 100); |
269 | else |
270 | font_size = gtk_css_font_size_get_default_px (provider, style); |
271 | /* This is what WebKit does... */ |
272 | font_size /= 1.2; |
273 | break; |
274 | case GTK_CSS_FONT_SIZE_LARGER: |
275 | if (parent_style) |
276 | font_size = _gtk_css_number_value_get (number: parent_style->core->font_size, one_hundred_percent: 100); |
277 | else |
278 | font_size = gtk_css_font_size_get_default_px (provider, style); |
279 | /* This is what WebKit does... */ |
280 | font_size *= 1.2; |
281 | break; |
282 | } |
283 | |
284 | return _gtk_css_number_value_new (value: font_size, unit: GTK_CSS_PX); |
285 | } |
286 | |
287 | static const GtkCssValueClass GTK_CSS_VALUE_FONT_SIZE = { |
288 | "GtkCssFontSizeValue" , |
289 | gtk_css_value_enum_free, |
290 | gtk_css_value_font_size_compute, |
291 | gtk_css_value_enum_equal, |
292 | gtk_css_value_enum_transition, |
293 | NULL, |
294 | NULL, |
295 | gtk_css_value_enum_print |
296 | }; |
297 | |
298 | static GtkCssValue font_size_values[] = { |
299 | { .class: >K_CSS_VALUE_FONT_SIZE, .ref_count: 1, FALSE, .value: GTK_CSS_FONT_SIZE_SMALLER, .name: "smaller" }, |
300 | { >K_CSS_VALUE_FONT_SIZE, 1, FALSE, GTK_CSS_FONT_SIZE_LARGER, "larger" }, |
301 | { >K_CSS_VALUE_FONT_SIZE, 1, FALSE, GTK_CSS_FONT_SIZE_XX_SMALL, "xx-small" }, |
302 | { >K_CSS_VALUE_FONT_SIZE, 1, FALSE, GTK_CSS_FONT_SIZE_X_SMALL, "x-small" }, |
303 | { >K_CSS_VALUE_FONT_SIZE, 1, FALSE, GTK_CSS_FONT_SIZE_SMALL, "small" }, |
304 | { >K_CSS_VALUE_FONT_SIZE, 1, FALSE, GTK_CSS_FONT_SIZE_MEDIUM, "medium" }, |
305 | { >K_CSS_VALUE_FONT_SIZE, 1, FALSE, GTK_CSS_FONT_SIZE_LARGE, "large" }, |
306 | { >K_CSS_VALUE_FONT_SIZE, 1, FALSE, GTK_CSS_FONT_SIZE_X_LARGE, "x-large" }, |
307 | { >K_CSS_VALUE_FONT_SIZE, 1, FALSE, GTK_CSS_FONT_SIZE_XX_LARGE, "xx-large" } |
308 | }; |
309 | |
310 | GtkCssValue * |
311 | _gtk_css_font_size_value_new (GtkCssFontSize font_size) |
312 | { |
313 | g_return_val_if_fail (font_size < G_N_ELEMENTS (font_size_values), NULL); |
314 | |
315 | return _gtk_css_value_ref (value: &font_size_values[font_size]); |
316 | } |
317 | |
318 | GtkCssValue * |
319 | _gtk_css_font_size_value_try_parse (GtkCssParser *parser) |
320 | { |
321 | guint i; |
322 | |
323 | g_return_val_if_fail (parser != NULL, NULL); |
324 | |
325 | for (i = 0; i < G_N_ELEMENTS (font_size_values); i++) |
326 | { |
327 | if (gtk_css_parser_try_ident (self: parser, ident: font_size_values[i].name)) |
328 | return _gtk_css_value_ref (value: &font_size_values[i]); |
329 | } |
330 | |
331 | return NULL; |
332 | } |
333 | |
334 | GtkCssFontSize |
335 | _gtk_css_font_size_value_get (const GtkCssValue *value) |
336 | { |
337 | g_return_val_if_fail (value->class == >K_CSS_VALUE_FONT_SIZE, GTK_CSS_FONT_SIZE_MEDIUM); |
338 | |
339 | return value->value; |
340 | } |
341 | |
342 | /* PangoStyle */ |
343 | |
344 | static const GtkCssValueClass GTK_CSS_VALUE_FONT_STYLE = { |
345 | "GtkCssFontStyleValue" , |
346 | gtk_css_value_enum_free, |
347 | gtk_css_value_enum_compute, |
348 | gtk_css_value_enum_equal, |
349 | gtk_css_value_enum_transition, |
350 | NULL, |
351 | NULL, |
352 | gtk_css_value_enum_print |
353 | }; |
354 | |
355 | static GtkCssValue font_style_values[] = { |
356 | { .class: >K_CSS_VALUE_FONT_STYLE, .ref_count: 1, TRUE, .value: PANGO_STYLE_NORMAL, .name: "normal" }, |
357 | { >K_CSS_VALUE_FONT_STYLE, 1, TRUE, PANGO_STYLE_OBLIQUE, "oblique" }, |
358 | { >K_CSS_VALUE_FONT_STYLE, 1, TRUE, PANGO_STYLE_ITALIC, "italic" } |
359 | }; |
360 | |
361 | GtkCssValue * |
362 | _gtk_css_font_style_value_new (PangoStyle font_style) |
363 | { |
364 | g_return_val_if_fail (font_style < G_N_ELEMENTS (font_style_values), NULL); |
365 | |
366 | return _gtk_css_value_ref (value: &font_style_values[font_style]); |
367 | } |
368 | |
369 | GtkCssValue * |
370 | _gtk_css_font_style_value_try_parse (GtkCssParser *parser) |
371 | { |
372 | guint i; |
373 | |
374 | g_return_val_if_fail (parser != NULL, NULL); |
375 | |
376 | for (i = 0; i < G_N_ELEMENTS (font_style_values); i++) |
377 | { |
378 | if (gtk_css_parser_try_ident (self: parser, ident: font_style_values[i].name)) |
379 | return _gtk_css_value_ref (value: &font_style_values[i]); |
380 | } |
381 | |
382 | return NULL; |
383 | } |
384 | |
385 | PangoStyle |
386 | _gtk_css_font_style_value_get (const GtkCssValue *value) |
387 | { |
388 | g_return_val_if_fail (value->class == >K_CSS_VALUE_FONT_STYLE, PANGO_STYLE_NORMAL); |
389 | |
390 | return value->value; |
391 | } |
392 | |
393 | /* PangoWeight */ |
394 | |
395 | #define BOLDER -1 |
396 | #define LIGHTER -2 |
397 | |
398 | static GtkCssValue * |
399 | gtk_css_value_font_weight_compute (GtkCssValue *value, |
400 | guint property_id, |
401 | GtkStyleProvider *provider, |
402 | GtkCssStyle *style, |
403 | GtkCssStyle *parent_style) |
404 | { |
405 | PangoWeight new_weight; |
406 | int parent_value; |
407 | |
408 | if (value->value >= 0) |
409 | return _gtk_css_value_ref (value); |
410 | |
411 | if (parent_style) |
412 | parent_value = _gtk_css_number_value_get (number: parent_style->font->font_weight, one_hundred_percent: 100); |
413 | else |
414 | parent_value = 400; |
415 | |
416 | if (value->value == BOLDER) |
417 | { |
418 | if (parent_value < 350) |
419 | new_weight = 400; |
420 | else if (parent_value < 550) |
421 | new_weight = 700; |
422 | else |
423 | new_weight = 900; |
424 | } |
425 | else if (value->value == LIGHTER) |
426 | { |
427 | if (parent_value > 750) |
428 | new_weight = 700; |
429 | else if (parent_value > 550) |
430 | new_weight = 400; |
431 | else |
432 | new_weight = 100; |
433 | } |
434 | else |
435 | { |
436 | g_assert_not_reached (); |
437 | new_weight = PANGO_WEIGHT_NORMAL; |
438 | } |
439 | |
440 | return _gtk_css_number_value_new (value: new_weight, unit: GTK_CSS_NUMBER); |
441 | } |
442 | |
443 | static const GtkCssValueClass GTK_CSS_VALUE_FONT_WEIGHT = { |
444 | "GtkCssFontWeightValue" , |
445 | gtk_css_value_enum_free, |
446 | gtk_css_value_font_weight_compute, |
447 | gtk_css_value_enum_equal, |
448 | NULL, |
449 | NULL, |
450 | NULL, |
451 | gtk_css_value_enum_print |
452 | }; |
453 | |
454 | static GtkCssValue font_weight_values[] = { |
455 | { .class: >K_CSS_VALUE_FONT_WEIGHT, .ref_count: 1, FALSE, BOLDER, .name: "bolder" }, |
456 | { >K_CSS_VALUE_FONT_WEIGHT, 1, FALSE, LIGHTER, "lighter" }, |
457 | }; |
458 | |
459 | GtkCssValue * |
460 | gtk_css_font_weight_value_try_parse (GtkCssParser *parser) |
461 | { |
462 | guint i; |
463 | |
464 | g_return_val_if_fail (parser != NULL, NULL); |
465 | |
466 | for (i = 0; i < G_N_ELEMENTS (font_weight_values); i++) |
467 | { |
468 | if (gtk_css_parser_try_ident (self: parser, ident: font_weight_values[i].name)) |
469 | return _gtk_css_value_ref (value: &font_weight_values[i]); |
470 | } |
471 | |
472 | if (gtk_css_parser_try_ident (self: parser, ident: "normal" )) |
473 | return _gtk_css_number_value_new (value: PANGO_WEIGHT_NORMAL, unit: GTK_CSS_NUMBER); |
474 | if (gtk_css_parser_try_ident (self: parser, ident: "bold" )) |
475 | return _gtk_css_number_value_new (value: PANGO_WEIGHT_BOLD, unit: GTK_CSS_NUMBER); |
476 | |
477 | return NULL; |
478 | } |
479 | |
480 | PangoWeight |
481 | gtk_css_font_weight_value_get (const GtkCssValue *value) |
482 | { |
483 | g_return_val_if_fail (value->class == >K_CSS_VALUE_FONT_WEIGHT, PANGO_WEIGHT_NORMAL); |
484 | |
485 | return value->value; |
486 | } |
487 | |
488 | #undef BOLDER |
489 | #undef LIGHTER |
490 | |
491 | /* PangoStretch */ |
492 | |
493 | static const GtkCssValueClass GTK_CSS_VALUE_FONT_STRETCH = { |
494 | "GtkCssFontStretchValue" , |
495 | gtk_css_value_enum_free, |
496 | gtk_css_value_enum_compute, |
497 | gtk_css_value_enum_equal, |
498 | gtk_css_value_enum_transition, |
499 | NULL, |
500 | NULL, |
501 | gtk_css_value_enum_print |
502 | }; |
503 | |
504 | static GtkCssValue font_stretch_values[] = { |
505 | { .class: >K_CSS_VALUE_FONT_STRETCH, .ref_count: 1, TRUE, .value: PANGO_STRETCH_ULTRA_CONDENSED, .name: "ultra-condensed" }, |
506 | { >K_CSS_VALUE_FONT_STRETCH, 1, TRUE, PANGO_STRETCH_EXTRA_CONDENSED, "extra-condensed" }, |
507 | { >K_CSS_VALUE_FONT_STRETCH, 1, TRUE, PANGO_STRETCH_CONDENSED, "condensed" }, |
508 | { >K_CSS_VALUE_FONT_STRETCH, 1, TRUE, PANGO_STRETCH_SEMI_CONDENSED, "semi-condensed" }, |
509 | { >K_CSS_VALUE_FONT_STRETCH, 1, TRUE, PANGO_STRETCH_NORMAL, "normal" }, |
510 | { >K_CSS_VALUE_FONT_STRETCH, 1, TRUE, PANGO_STRETCH_SEMI_EXPANDED, "semi-expanded" }, |
511 | { >K_CSS_VALUE_FONT_STRETCH, 1, TRUE, PANGO_STRETCH_EXPANDED, "expanded" }, |
512 | { >K_CSS_VALUE_FONT_STRETCH, 1, TRUE, PANGO_STRETCH_EXTRA_EXPANDED, "extra-expanded" }, |
513 | { >K_CSS_VALUE_FONT_STRETCH, 1, TRUE, PANGO_STRETCH_ULTRA_EXPANDED, "ultra-expanded" }, |
514 | }; |
515 | |
516 | GtkCssValue * |
517 | _gtk_css_font_stretch_value_new (PangoStretch font_stretch) |
518 | { |
519 | g_return_val_if_fail (font_stretch < G_N_ELEMENTS (font_stretch_values), NULL); |
520 | |
521 | return _gtk_css_value_ref (value: &font_stretch_values[font_stretch]); |
522 | } |
523 | |
524 | GtkCssValue * |
525 | _gtk_css_font_stretch_value_try_parse (GtkCssParser *parser) |
526 | { |
527 | guint i; |
528 | |
529 | g_return_val_if_fail (parser != NULL, NULL); |
530 | |
531 | for (i = 0; i < G_N_ELEMENTS (font_stretch_values); i++) |
532 | { |
533 | if (gtk_css_parser_try_ident (self: parser, ident: font_stretch_values[i].name)) |
534 | return _gtk_css_value_ref (value: &font_stretch_values[i]); |
535 | } |
536 | |
537 | return NULL; |
538 | } |
539 | |
540 | PangoStretch |
541 | _gtk_css_font_stretch_value_get (const GtkCssValue *value) |
542 | { |
543 | g_return_val_if_fail (value->class == >K_CSS_VALUE_FONT_STRETCH, PANGO_STRETCH_NORMAL); |
544 | |
545 | return value->value; |
546 | } |
547 | |
548 | /* GtkTextDecorationStyle */ |
549 | |
550 | static const GtkCssValueClass GTK_CSS_VALUE_TEXT_DECORATION_STYLE = { |
551 | "GtkCssTextDecorationStyleValue" , |
552 | gtk_css_value_enum_free, |
553 | gtk_css_value_enum_compute, |
554 | gtk_css_value_enum_equal, |
555 | gtk_css_value_enum_transition, |
556 | NULL, |
557 | NULL, |
558 | gtk_css_value_enum_print |
559 | }; |
560 | |
561 | static GtkCssValue text_decoration_style_values[] = { |
562 | { .class: >K_CSS_VALUE_TEXT_DECORATION_STYLE, .ref_count: 1, TRUE, .value: GTK_CSS_TEXT_DECORATION_STYLE_SOLID, .name: "solid" }, |
563 | { >K_CSS_VALUE_TEXT_DECORATION_STYLE, 1, TRUE, GTK_CSS_TEXT_DECORATION_STYLE_DOUBLE, "double" }, |
564 | { >K_CSS_VALUE_TEXT_DECORATION_STYLE, 1, TRUE, GTK_CSS_TEXT_DECORATION_STYLE_WAVY, "wavy" }, |
565 | }; |
566 | |
567 | GtkCssValue * |
568 | _gtk_css_text_decoration_style_value_new (GtkTextDecorationStyle style) |
569 | { |
570 | g_return_val_if_fail (style < G_N_ELEMENTS (text_decoration_style_values), NULL); |
571 | |
572 | return _gtk_css_value_ref (value: &text_decoration_style_values[style]); |
573 | } |
574 | |
575 | GtkCssValue * |
576 | _gtk_css_text_decoration_style_value_try_parse (GtkCssParser *parser) |
577 | { |
578 | guint i; |
579 | |
580 | g_return_val_if_fail (parser != NULL, NULL); |
581 | |
582 | for (i = 0; i < G_N_ELEMENTS (text_decoration_style_values); i++) |
583 | { |
584 | if (gtk_css_parser_try_ident (self: parser, ident: text_decoration_style_values[i].name)) |
585 | return _gtk_css_value_ref (value: &text_decoration_style_values[i]); |
586 | } |
587 | |
588 | return NULL; |
589 | } |
590 | |
591 | GtkTextDecorationStyle |
592 | _gtk_css_text_decoration_style_value_get (const GtkCssValue *value) |
593 | { |
594 | g_return_val_if_fail (value->class == >K_CSS_VALUE_TEXT_DECORATION_STYLE, GTK_CSS_TEXT_DECORATION_STYLE_SOLID); |
595 | |
596 | return value->value; |
597 | } |
598 | |
599 | /* GtkCssArea */ |
600 | |
601 | static const GtkCssValueClass GTK_CSS_VALUE_AREA = { |
602 | "GtkCssAreaValue" , |
603 | gtk_css_value_enum_free, |
604 | gtk_css_value_enum_compute, |
605 | gtk_css_value_enum_equal, |
606 | gtk_css_value_enum_transition, |
607 | NULL, |
608 | NULL, |
609 | gtk_css_value_enum_print |
610 | }; |
611 | |
612 | static GtkCssValue area_values[] = { |
613 | { .class: >K_CSS_VALUE_AREA, .ref_count: 1, TRUE, .value: GTK_CSS_AREA_BORDER_BOX, .name: "border-box" }, |
614 | { >K_CSS_VALUE_AREA, 1, TRUE, GTK_CSS_AREA_PADDING_BOX, "padding-box" }, |
615 | { >K_CSS_VALUE_AREA, 1, TRUE, GTK_CSS_AREA_CONTENT_BOX, "content-box" } |
616 | }; |
617 | |
618 | GtkCssValue * |
619 | _gtk_css_area_value_new (GtkCssArea area) |
620 | { |
621 | guint i; |
622 | |
623 | for (i = 0; i < G_N_ELEMENTS (area_values); i++) |
624 | { |
625 | if (area_values[i].value == area) |
626 | return _gtk_css_value_ref (value: &area_values[i]); |
627 | } |
628 | |
629 | g_return_val_if_reached (NULL); |
630 | } |
631 | |
632 | GtkCssValue * |
633 | _gtk_css_area_value_try_parse (GtkCssParser *parser) |
634 | { |
635 | guint i; |
636 | |
637 | g_return_val_if_fail (parser != NULL, NULL); |
638 | |
639 | for (i = 0; i < G_N_ELEMENTS (area_values); i++) |
640 | { |
641 | if (gtk_css_parser_try_ident (self: parser, ident: area_values[i].name)) |
642 | return _gtk_css_value_ref (value: &area_values[i]); |
643 | } |
644 | |
645 | return NULL; |
646 | } |
647 | |
648 | GtkCssArea |
649 | _gtk_css_area_value_get (const GtkCssValue *value) |
650 | { |
651 | g_return_val_if_fail (value->class == >K_CSS_VALUE_AREA, GTK_CSS_AREA_BORDER_BOX); |
652 | |
653 | return value->value; |
654 | } |
655 | |
656 | /* GtkCssDirection */ |
657 | |
658 | static const GtkCssValueClass GTK_CSS_VALUE_DIRECTION = { |
659 | "GtkCssDirectionValue" , |
660 | gtk_css_value_enum_free, |
661 | gtk_css_value_enum_compute, |
662 | gtk_css_value_enum_equal, |
663 | gtk_css_value_enum_transition, |
664 | NULL, |
665 | NULL, |
666 | gtk_css_value_enum_print |
667 | }; |
668 | |
669 | static GtkCssValue direction_values[] = { |
670 | { .class: >K_CSS_VALUE_DIRECTION, .ref_count: 1, TRUE, .value: GTK_CSS_DIRECTION_NORMAL, .name: "normal" }, |
671 | { >K_CSS_VALUE_DIRECTION, 1, TRUE, GTK_CSS_DIRECTION_REVERSE, "reverse" }, |
672 | { >K_CSS_VALUE_DIRECTION, 1, TRUE, GTK_CSS_DIRECTION_ALTERNATE, "alternate" }, |
673 | { >K_CSS_VALUE_DIRECTION, 1, TRUE, GTK_CSS_DIRECTION_ALTERNATE_REVERSE, "alternate-reverse" } |
674 | }; |
675 | |
676 | GtkCssValue * |
677 | _gtk_css_direction_value_new (GtkCssDirection direction) |
678 | { |
679 | guint i; |
680 | |
681 | for (i = 0; i < G_N_ELEMENTS (direction_values); i++) |
682 | { |
683 | if (direction_values[i].value == direction) |
684 | return _gtk_css_value_ref (value: &direction_values[i]); |
685 | } |
686 | |
687 | g_return_val_if_reached (NULL); |
688 | } |
689 | |
690 | GtkCssValue * |
691 | _gtk_css_direction_value_try_parse (GtkCssParser *parser) |
692 | { |
693 | int i; |
694 | |
695 | g_return_val_if_fail (parser != NULL, NULL); |
696 | |
697 | /* need to parse backwards here, otherwise "alternate" will also match "alternate-reverse". |
698 | * Our parser rocks! |
699 | */ |
700 | for (i = G_N_ELEMENTS (direction_values) - 1; i >= 0; i--) |
701 | { |
702 | if (gtk_css_parser_try_ident (self: parser, ident: direction_values[i].name)) |
703 | return _gtk_css_value_ref (value: &direction_values[i]); |
704 | } |
705 | |
706 | return NULL; |
707 | } |
708 | |
709 | GtkCssDirection |
710 | _gtk_css_direction_value_get (const GtkCssValue *value) |
711 | { |
712 | g_return_val_if_fail (value->class == >K_CSS_VALUE_DIRECTION, GTK_CSS_DIRECTION_NORMAL); |
713 | |
714 | return value->value; |
715 | } |
716 | |
717 | /* GtkCssPlayState */ |
718 | |
719 | static const GtkCssValueClass GTK_CSS_VALUE_PLAY_STATE = { |
720 | "GtkCssPlayStateValue" , |
721 | gtk_css_value_enum_free, |
722 | gtk_css_value_enum_compute, |
723 | gtk_css_value_enum_equal, |
724 | gtk_css_value_enum_transition, |
725 | NULL, |
726 | NULL, |
727 | gtk_css_value_enum_print |
728 | }; |
729 | |
730 | static GtkCssValue play_state_values[] = { |
731 | { .class: >K_CSS_VALUE_PLAY_STATE, .ref_count: 1, TRUE, .value: GTK_CSS_PLAY_STATE_RUNNING, .name: "running" }, |
732 | { >K_CSS_VALUE_PLAY_STATE, 1, TRUE, GTK_CSS_PLAY_STATE_PAUSED, "paused" } |
733 | }; |
734 | |
735 | GtkCssValue * |
736 | _gtk_css_play_state_value_new (GtkCssPlayState play_state) |
737 | { |
738 | guint i; |
739 | |
740 | for (i = 0; i < G_N_ELEMENTS (play_state_values); i++) |
741 | { |
742 | if (play_state_values[i].value == play_state) |
743 | return _gtk_css_value_ref (value: &play_state_values[i]); |
744 | } |
745 | |
746 | g_return_val_if_reached (NULL); |
747 | } |
748 | |
749 | GtkCssValue * |
750 | _gtk_css_play_state_value_try_parse (GtkCssParser *parser) |
751 | { |
752 | guint i; |
753 | |
754 | g_return_val_if_fail (parser != NULL, NULL); |
755 | |
756 | for (i = 0; i < G_N_ELEMENTS (play_state_values); i++) |
757 | { |
758 | if (gtk_css_parser_try_ident (self: parser, ident: play_state_values[i].name)) |
759 | return _gtk_css_value_ref (value: &play_state_values[i]); |
760 | } |
761 | |
762 | return NULL; |
763 | } |
764 | |
765 | GtkCssPlayState |
766 | _gtk_css_play_state_value_get (const GtkCssValue *value) |
767 | { |
768 | g_return_val_if_fail (value->class == >K_CSS_VALUE_PLAY_STATE, GTK_CSS_PLAY_STATE_RUNNING); |
769 | |
770 | return value->value; |
771 | } |
772 | |
773 | /* GtkCssFillMode */ |
774 | |
775 | static const GtkCssValueClass GTK_CSS_VALUE_FILL_MODE = { |
776 | "GtkCssFillModeValue" , |
777 | gtk_css_value_enum_free, |
778 | gtk_css_value_enum_compute, |
779 | gtk_css_value_enum_equal, |
780 | gtk_css_value_enum_transition, |
781 | NULL, |
782 | NULL, |
783 | gtk_css_value_enum_print |
784 | }; |
785 | |
786 | static GtkCssValue fill_mode_values[] = { |
787 | { .class: >K_CSS_VALUE_FILL_MODE, .ref_count: 1, TRUE, .value: GTK_CSS_FILL_NONE, .name: "none" }, |
788 | { >K_CSS_VALUE_FILL_MODE, 1, TRUE, GTK_CSS_FILL_FORWARDS, "forwards" }, |
789 | { >K_CSS_VALUE_FILL_MODE, 1, TRUE, GTK_CSS_FILL_BACKWARDS, "backwards" }, |
790 | { >K_CSS_VALUE_FILL_MODE, 1, TRUE, GTK_CSS_FILL_BOTH, "both" } |
791 | }; |
792 | |
793 | GtkCssValue * |
794 | _gtk_css_fill_mode_value_new (GtkCssFillMode fill_mode) |
795 | { |
796 | guint i; |
797 | |
798 | for (i = 0; i < G_N_ELEMENTS (fill_mode_values); i++) |
799 | { |
800 | if (fill_mode_values[i].value == fill_mode) |
801 | return _gtk_css_value_ref (value: &fill_mode_values[i]); |
802 | } |
803 | |
804 | g_return_val_if_reached (NULL); |
805 | } |
806 | |
807 | GtkCssValue * |
808 | _gtk_css_fill_mode_value_try_parse (GtkCssParser *parser) |
809 | { |
810 | guint i; |
811 | |
812 | g_return_val_if_fail (parser != NULL, NULL); |
813 | |
814 | for (i = 0; i < G_N_ELEMENTS (fill_mode_values); i++) |
815 | { |
816 | if (gtk_css_parser_try_ident (self: parser, ident: fill_mode_values[i].name)) |
817 | return _gtk_css_value_ref (value: &fill_mode_values[i]); |
818 | } |
819 | |
820 | return NULL; |
821 | } |
822 | |
823 | GtkCssFillMode |
824 | _gtk_css_fill_mode_value_get (const GtkCssValue *value) |
825 | { |
826 | g_return_val_if_fail (value->class == >K_CSS_VALUE_FILL_MODE, GTK_CSS_FILL_NONE); |
827 | |
828 | return value->value; |
829 | } |
830 | |
831 | /* GtkCssIconStyle */ |
832 | |
833 | static const GtkCssValueClass GTK_CSS_VALUE_ICON_STYLE = { |
834 | "GtkCssIconStyleValue" , |
835 | gtk_css_value_enum_free, |
836 | gtk_css_value_enum_compute, |
837 | gtk_css_value_enum_equal, |
838 | gtk_css_value_enum_transition, |
839 | NULL, |
840 | NULL, |
841 | gtk_css_value_enum_print |
842 | }; |
843 | |
844 | static GtkCssValue icon_style_values[] = { |
845 | { .class: >K_CSS_VALUE_ICON_STYLE, .ref_count: 1, TRUE, .value: GTK_CSS_ICON_STYLE_REQUESTED, .name: "requested" }, |
846 | { >K_CSS_VALUE_ICON_STYLE, 1, TRUE, GTK_CSS_ICON_STYLE_REGULAR, "regular" }, |
847 | { >K_CSS_VALUE_ICON_STYLE, 1, TRUE, GTK_CSS_ICON_STYLE_SYMBOLIC, "symbolic" } |
848 | }; |
849 | |
850 | GtkCssValue * |
851 | _gtk_css_icon_style_value_new (GtkCssIconStyle icon_style) |
852 | { |
853 | guint i; |
854 | |
855 | for (i = 0; i < G_N_ELEMENTS (icon_style_values); i++) |
856 | { |
857 | if (icon_style_values[i].value == icon_style) |
858 | return _gtk_css_value_ref (value: &icon_style_values[i]); |
859 | } |
860 | |
861 | g_return_val_if_reached (NULL); |
862 | } |
863 | |
864 | GtkCssValue * |
865 | _gtk_css_icon_style_value_try_parse (GtkCssParser *parser) |
866 | { |
867 | guint i; |
868 | |
869 | g_return_val_if_fail (parser != NULL, NULL); |
870 | |
871 | for (i = 0; i < G_N_ELEMENTS (icon_style_values); i++) |
872 | { |
873 | if (gtk_css_parser_try_ident (self: parser, ident: icon_style_values[i].name)) |
874 | return _gtk_css_value_ref (value: &icon_style_values[i]); |
875 | } |
876 | |
877 | return NULL; |
878 | } |
879 | |
880 | GtkCssIconStyle |
881 | _gtk_css_icon_style_value_get (const GtkCssValue *value) |
882 | { |
883 | g_return_val_if_fail (value->class == >K_CSS_VALUE_ICON_STYLE, GTK_CSS_ICON_STYLE_REQUESTED); |
884 | |
885 | return value->value; |
886 | } |
887 | |
888 | /* GtkCssFontKerning */ |
889 | |
890 | static const GtkCssValueClass GTK_CSS_VALUE_FONT_KERNING = { |
891 | "GtkCssFontKerningValue" , |
892 | gtk_css_value_enum_free, |
893 | gtk_css_value_enum_compute, |
894 | gtk_css_value_enum_equal, |
895 | gtk_css_value_enum_transition, |
896 | NULL, |
897 | NULL, |
898 | gtk_css_value_enum_print |
899 | }; |
900 | |
901 | static GtkCssValue font_kerning_values[] = { |
902 | { .class: >K_CSS_VALUE_FONT_KERNING, .ref_count: 1, TRUE, .value: GTK_CSS_FONT_KERNING_AUTO, .name: "auto" }, |
903 | { >K_CSS_VALUE_FONT_KERNING, 1, TRUE, GTK_CSS_FONT_KERNING_NORMAL, "normal" }, |
904 | { >K_CSS_VALUE_FONT_KERNING, 1, TRUE, GTK_CSS_FONT_KERNING_NONE, "none" } |
905 | }; |
906 | |
907 | GtkCssValue * |
908 | _gtk_css_font_kerning_value_new (GtkCssFontKerning kerning) |
909 | { |
910 | guint i; |
911 | |
912 | for (i = 0; i < G_N_ELEMENTS (font_kerning_values); i++) |
913 | { |
914 | if (font_kerning_values[i].value == kerning) |
915 | return _gtk_css_value_ref (value: &font_kerning_values[i]); |
916 | } |
917 | |
918 | g_return_val_if_reached (NULL); |
919 | } |
920 | |
921 | GtkCssValue * |
922 | _gtk_css_font_kerning_value_try_parse (GtkCssParser *parser) |
923 | { |
924 | guint i; |
925 | |
926 | g_return_val_if_fail (parser != NULL, NULL); |
927 | |
928 | for (i = 0; i < G_N_ELEMENTS (font_kerning_values); i++) |
929 | { |
930 | if (gtk_css_parser_try_ident (self: parser, ident: font_kerning_values[i].name)) |
931 | return _gtk_css_value_ref (value: &font_kerning_values[i]); |
932 | } |
933 | |
934 | return NULL; |
935 | } |
936 | |
937 | GtkCssFontKerning |
938 | _gtk_css_font_kerning_value_get (const GtkCssValue *value) |
939 | { |
940 | g_return_val_if_fail (value->class == >K_CSS_VALUE_FONT_KERNING, GTK_CSS_FONT_KERNING_AUTO); |
941 | |
942 | return value->value; |
943 | } |
944 | |
945 | /* GtkCssFontVariantPos */ |
946 | |
947 | static const GtkCssValueClass GTK_CSS_VALUE_FONT_VARIANT_POSITION = { |
948 | "GtkCssFontVariationPositionValue" , |
949 | gtk_css_value_enum_free, |
950 | gtk_css_value_enum_compute, |
951 | gtk_css_value_enum_equal, |
952 | gtk_css_value_enum_transition, |
953 | NULL, |
954 | NULL, |
955 | gtk_css_value_enum_print |
956 | }; |
957 | |
958 | static GtkCssValue font_variant_position_values[] = { |
959 | { .class: >K_CSS_VALUE_FONT_VARIANT_POSITION, .ref_count: 1, TRUE, .value: GTK_CSS_FONT_VARIANT_POSITION_NORMAL, .name: "normal" }, |
960 | { >K_CSS_VALUE_FONT_VARIANT_POSITION, 1, TRUE, GTK_CSS_FONT_VARIANT_POSITION_SUB, "sub" }, |
961 | { >K_CSS_VALUE_FONT_VARIANT_POSITION, 1, TRUE, GTK_CSS_FONT_VARIANT_POSITION_SUPER, "super" } |
962 | }; |
963 | |
964 | GtkCssValue * |
965 | _gtk_css_font_variant_position_value_new (GtkCssFontVariantPosition position) |
966 | { |
967 | guint i; |
968 | |
969 | for (i = 0; i < G_N_ELEMENTS (font_variant_position_values); i++) |
970 | { |
971 | if (font_variant_position_values[i].value == position) |
972 | return _gtk_css_value_ref (value: &font_variant_position_values[i]); |
973 | } |
974 | |
975 | g_return_val_if_reached (NULL); |
976 | } |
977 | |
978 | GtkCssValue * |
979 | _gtk_css_font_variant_position_value_try_parse (GtkCssParser *parser) |
980 | { |
981 | guint i; |
982 | |
983 | g_return_val_if_fail (parser != NULL, NULL); |
984 | |
985 | for (i = 0; i < G_N_ELEMENTS (font_variant_position_values); i++) |
986 | { |
987 | if (gtk_css_parser_try_ident (self: parser, ident: font_variant_position_values[i].name)) |
988 | return _gtk_css_value_ref (value: &font_variant_position_values[i]); |
989 | } |
990 | |
991 | return NULL; |
992 | } |
993 | |
994 | GtkCssFontVariantPosition |
995 | _gtk_css_font_variant_position_value_get (const GtkCssValue *value) |
996 | { |
997 | g_return_val_if_fail (value->class == >K_CSS_VALUE_FONT_VARIANT_POSITION, GTK_CSS_FONT_VARIANT_POSITION_NORMAL); |
998 | |
999 | return value->value; |
1000 | } |
1001 | |
1002 | /* GtkCssFontVariantCaps */ |
1003 | |
1004 | static const GtkCssValueClass GTK_CSS_VALUE_FONT_VARIANT_CAPS = { |
1005 | "GtkCssFontVariantCapsValue" , |
1006 | gtk_css_value_enum_free, |
1007 | gtk_css_value_enum_compute, |
1008 | gtk_css_value_enum_equal, |
1009 | gtk_css_value_enum_transition, |
1010 | NULL, |
1011 | NULL, |
1012 | gtk_css_value_enum_print |
1013 | }; |
1014 | |
1015 | static GtkCssValue font_variant_caps_values[] = { |
1016 | { .class: >K_CSS_VALUE_FONT_VARIANT_CAPS, .ref_count: 1, TRUE, .value: GTK_CSS_FONT_VARIANT_CAPS_NORMAL, .name: "normal" }, |
1017 | { >K_CSS_VALUE_FONT_VARIANT_CAPS, 1, TRUE, GTK_CSS_FONT_VARIANT_CAPS_SMALL_CAPS, "small-caps" }, |
1018 | { >K_CSS_VALUE_FONT_VARIANT_CAPS, 1, TRUE, GTK_CSS_FONT_VARIANT_CAPS_ALL_SMALL_CAPS, "all-small-caps" }, |
1019 | { >K_CSS_VALUE_FONT_VARIANT_CAPS, 1, TRUE, GTK_CSS_FONT_VARIANT_CAPS_PETITE_CAPS, "petite-caps" }, |
1020 | { >K_CSS_VALUE_FONT_VARIANT_CAPS, 1, TRUE, GTK_CSS_FONT_VARIANT_CAPS_ALL_PETITE_CAPS, "all-petite-caps" }, |
1021 | { >K_CSS_VALUE_FONT_VARIANT_CAPS, 1, TRUE, GTK_CSS_FONT_VARIANT_CAPS_UNICASE, "unicase" }, |
1022 | { >K_CSS_VALUE_FONT_VARIANT_CAPS, 1, TRUE, GTK_CSS_FONT_VARIANT_CAPS_TITLING_CAPS, "titling-caps" } |
1023 | }; |
1024 | |
1025 | GtkCssValue * |
1026 | _gtk_css_font_variant_caps_value_new (GtkCssFontVariantCaps caps) |
1027 | { |
1028 | guint i; |
1029 | |
1030 | for (i = 0; i < G_N_ELEMENTS (font_variant_caps_values); i++) |
1031 | { |
1032 | if (font_variant_caps_values[i].value == caps) |
1033 | return _gtk_css_value_ref (value: &font_variant_caps_values[i]); |
1034 | } |
1035 | |
1036 | g_return_val_if_reached (NULL); |
1037 | } |
1038 | |
1039 | GtkCssValue * |
1040 | _gtk_css_font_variant_caps_value_try_parse (GtkCssParser *parser) |
1041 | { |
1042 | guint i; |
1043 | |
1044 | g_return_val_if_fail (parser != NULL, NULL); |
1045 | |
1046 | for (i = 0; i < G_N_ELEMENTS (font_variant_caps_values); i++) |
1047 | { |
1048 | if (gtk_css_parser_try_ident (self: parser, ident: font_variant_caps_values[i].name)) |
1049 | return _gtk_css_value_ref (value: &font_variant_caps_values[i]); |
1050 | } |
1051 | |
1052 | return NULL; |
1053 | } |
1054 | |
1055 | GtkCssFontVariantCaps |
1056 | _gtk_css_font_variant_caps_value_get (const GtkCssValue *value) |
1057 | { |
1058 | g_return_val_if_fail (value->class == >K_CSS_VALUE_FONT_VARIANT_CAPS, GTK_CSS_FONT_VARIANT_CAPS_NORMAL); |
1059 | |
1060 | return value->value; |
1061 | } |
1062 | |
1063 | /* GtkCssFontVariantAlternate */ |
1064 | |
1065 | static const GtkCssValueClass GTK_CSS_VALUE_FONT_VARIANT_ALTERNATE = { |
1066 | "GtkCssFontVariantAlternateValue" , |
1067 | gtk_css_value_enum_free, |
1068 | gtk_css_value_enum_compute, |
1069 | gtk_css_value_enum_equal, |
1070 | gtk_css_value_enum_transition, |
1071 | NULL, |
1072 | NULL, |
1073 | gtk_css_value_enum_print |
1074 | }; |
1075 | |
1076 | static GtkCssValue font_variant_alternate_values[] = { |
1077 | { .class: >K_CSS_VALUE_FONT_VARIANT_ALTERNATE, .ref_count: 1, TRUE, .value: GTK_CSS_FONT_VARIANT_ALTERNATE_NORMAL, .name: "normal" }, |
1078 | { >K_CSS_VALUE_FONT_VARIANT_ALTERNATE, 1, TRUE, GTK_CSS_FONT_VARIANT_ALTERNATE_HISTORICAL_FORMS, "historical-forms" } |
1079 | }; |
1080 | |
1081 | GtkCssValue * |
1082 | _gtk_css_font_variant_alternate_value_new (GtkCssFontVariantAlternate alternate) |
1083 | { |
1084 | guint i; |
1085 | |
1086 | for (i = 0; i < G_N_ELEMENTS (font_variant_alternate_values); i++) |
1087 | { |
1088 | if (font_variant_alternate_values[i].value == alternate) |
1089 | return _gtk_css_value_ref (value: &font_variant_alternate_values[i]); |
1090 | } |
1091 | |
1092 | g_return_val_if_reached (NULL); |
1093 | } |
1094 | |
1095 | GtkCssValue * |
1096 | _gtk_css_font_variant_alternate_value_try_parse (GtkCssParser *parser) |
1097 | { |
1098 | guint i; |
1099 | |
1100 | g_return_val_if_fail (parser != NULL, NULL); |
1101 | |
1102 | for (i = 0; i < G_N_ELEMENTS (font_variant_alternate_values); i++) |
1103 | { |
1104 | if (gtk_css_parser_try_ident (self: parser, ident: font_variant_alternate_values[i].name)) |
1105 | return _gtk_css_value_ref (value: &font_variant_alternate_values[i]); |
1106 | } |
1107 | |
1108 | return NULL; |
1109 | } |
1110 | |
1111 | GtkCssFontVariantAlternate |
1112 | _gtk_css_font_variant_alternate_value_get (const GtkCssValue *value) |
1113 | { |
1114 | g_return_val_if_fail (value->class == >K_CSS_VALUE_FONT_VARIANT_ALTERNATE, GTK_CSS_FONT_VARIANT_ALTERNATE_NORMAL); |
1115 | |
1116 | return value->value; |
1117 | } |
1118 | |
1119 | /* below are flags, which are handle a bit differently. We allocate values dynamically, |
1120 | * and we parse one bit at a time, while allowing for detection of invalid combinations. |
1121 | */ |
1122 | |
1123 | typedef struct { |
1124 | int value; |
1125 | const char *name; |
1126 | } FlagsValue; |
1127 | |
1128 | static gboolean |
1129 | gtk_css_value_flags_equal (const GtkCssValue *enum1, |
1130 | const GtkCssValue *enum2) |
1131 | { |
1132 | return enum1->value == enum2->value; |
1133 | } |
1134 | |
1135 | static void |
1136 | gtk_css_value_flags_print (const FlagsValue *values, |
1137 | guint n_values, |
1138 | const GtkCssValue *value, |
1139 | GString *string) |
1140 | { |
1141 | guint i; |
1142 | const char *sep = "" ; |
1143 | |
1144 | for (i = 0; i < n_values; i++) |
1145 | { |
1146 | if (value->value & values[i].value) |
1147 | { |
1148 | g_string_append (string, val: sep); |
1149 | g_string_append (string, val: values[i].name); |
1150 | sep = " " ; |
1151 | } |
1152 | } |
1153 | } |
1154 | |
1155 | /* GtkTextDecorationLine */ |
1156 | |
1157 | static FlagsValue text_decoration_line_values[] = { |
1158 | { GTK_CSS_TEXT_DECORATION_LINE_NONE, "none" }, |
1159 | { GTK_CSS_TEXT_DECORATION_LINE_UNDERLINE, "underline" }, |
1160 | { GTK_CSS_TEXT_DECORATION_LINE_OVERLINE, "overline" }, |
1161 | { GTK_CSS_TEXT_DECORATION_LINE_LINE_THROUGH, "line-through" }, |
1162 | }; |
1163 | |
1164 | static void |
1165 | gtk_css_text_decoration_line_value_print (const GtkCssValue *value, |
1166 | GString *string) |
1167 | { |
1168 | gtk_css_value_flags_print (values: text_decoration_line_values, |
1169 | G_N_ELEMENTS (text_decoration_line_values), |
1170 | value, string); |
1171 | } |
1172 | |
1173 | static const GtkCssValueClass GTK_CSS_VALUE_TEXT_DECORATION_LINE = { |
1174 | "GtkCssTextDecorationLine" , |
1175 | gtk_css_value_enum_free, |
1176 | gtk_css_value_enum_compute, |
1177 | gtk_css_value_flags_equal, |
1178 | gtk_css_value_enum_transition, |
1179 | NULL, |
1180 | NULL, |
1181 | gtk_css_text_decoration_line_value_print |
1182 | }; |
1183 | |
1184 | static gboolean |
1185 | text_decoration_line_is_valid (GtkTextDecorationLine line) |
1186 | { |
1187 | if ((line & GTK_CSS_TEXT_DECORATION_LINE_NONE) && |
1188 | (line != GTK_CSS_TEXT_DECORATION_LINE_NONE)) |
1189 | return FALSE; |
1190 | |
1191 | return TRUE; |
1192 | } |
1193 | |
1194 | GtkCssValue * |
1195 | _gtk_css_text_decoration_line_value_new (GtkTextDecorationLine line) |
1196 | { |
1197 | GtkCssValue *value; |
1198 | |
1199 | if (!text_decoration_line_is_valid (line)) |
1200 | return NULL; |
1201 | |
1202 | value = _gtk_css_value_new (GtkCssValue, >K_CSS_VALUE_TEXT_DECORATION_LINE); |
1203 | value->value = line; |
1204 | value->name = NULL; |
1205 | value->is_computed = TRUE; |
1206 | |
1207 | return value; |
1208 | } |
1209 | |
1210 | GtkTextDecorationLine |
1211 | _gtk_css_text_decoration_line_try_parse_one (GtkCssParser *parser, |
1212 | GtkTextDecorationLine base) |
1213 | { |
1214 | guint i; |
1215 | GtkTextDecorationLine value = 0; |
1216 | |
1217 | g_return_val_if_fail (parser != NULL, 0); |
1218 | |
1219 | for (i = 0; i < G_N_ELEMENTS (text_decoration_line_values); i++) |
1220 | { |
1221 | if (gtk_css_parser_try_ident (self: parser, ident: text_decoration_line_values[i].name)) |
1222 | { |
1223 | value = text_decoration_line_values[i].value; |
1224 | break; |
1225 | } |
1226 | } |
1227 | |
1228 | if (value == 0) |
1229 | return base; /* not parsing this value */ |
1230 | |
1231 | if ((base | value) == base) |
1232 | return 0; /* repeated value */ |
1233 | |
1234 | if (!text_decoration_line_is_valid (line: base | value)) |
1235 | return 0; /* bad combination */ |
1236 | |
1237 | return base | value; |
1238 | } |
1239 | |
1240 | GtkTextDecorationLine |
1241 | _gtk_css_text_decoration_line_value_get (const GtkCssValue *value) |
1242 | { |
1243 | g_return_val_if_fail (value->class == >K_CSS_VALUE_TEXT_DECORATION_LINE, GTK_CSS_TEXT_DECORATION_LINE_NONE); |
1244 | |
1245 | return value->value; |
1246 | } |
1247 | |
1248 | /* GtkCssFontVariantLigature */ |
1249 | |
1250 | static FlagsValue font_variant_ligature_values[] = { |
1251 | { GTK_CSS_FONT_VARIANT_LIGATURE_NORMAL, "normal" }, |
1252 | { GTK_CSS_FONT_VARIANT_LIGATURE_NONE, "none" }, |
1253 | { GTK_CSS_FONT_VARIANT_LIGATURE_COMMON_LIGATURES, "common-ligatures" }, |
1254 | { GTK_CSS_FONT_VARIANT_LIGATURE_NO_COMMON_LIGATURES, "no-common-ligatures" }, |
1255 | { GTK_CSS_FONT_VARIANT_LIGATURE_DISCRETIONARY_LIGATURES, "discretionary-ligatures" }, |
1256 | { GTK_CSS_FONT_VARIANT_LIGATURE_NO_DISCRETIONARY_LIGATURES, "no-discretionary-ligatures" }, |
1257 | { GTK_CSS_FONT_VARIANT_LIGATURE_HISTORICAL_LIGATURES, "historical-ligatures" }, |
1258 | { GTK_CSS_FONT_VARIANT_LIGATURE_NO_HISTORICAL_LIGATURES, "no-historical-ligatures" }, |
1259 | { GTK_CSS_FONT_VARIANT_LIGATURE_CONTEXTUAL, "contextual" }, |
1260 | { GTK_CSS_FONT_VARIANT_LIGATURE_NO_CONTEXTUAL, "no-contextual" } |
1261 | }; |
1262 | |
1263 | static void |
1264 | gtk_css_font_variant_ligature_value_print (const GtkCssValue *value, |
1265 | GString *string) |
1266 | { |
1267 | gtk_css_value_flags_print (values: font_variant_ligature_values, |
1268 | G_N_ELEMENTS (font_variant_ligature_values), |
1269 | value, string); |
1270 | } |
1271 | |
1272 | static const GtkCssValueClass GTK_CSS_VALUE_FONT_VARIANT_LIGATURE = { |
1273 | "GtkCssFontVariantLigatureValue" , |
1274 | gtk_css_value_enum_free, |
1275 | gtk_css_value_enum_compute, |
1276 | gtk_css_value_flags_equal, |
1277 | gtk_css_value_enum_transition, |
1278 | NULL, |
1279 | NULL, |
1280 | gtk_css_font_variant_ligature_value_print |
1281 | }; |
1282 | |
1283 | static gboolean |
1284 | ligature_value_is_valid (GtkCssFontVariantLigature ligatures) |
1285 | { |
1286 | if (((ligatures & GTK_CSS_FONT_VARIANT_LIGATURE_NORMAL) && |
1287 | (ligatures != GTK_CSS_FONT_VARIANT_LIGATURE_NORMAL)) || |
1288 | ((ligatures & GTK_CSS_FONT_VARIANT_LIGATURE_NONE) && |
1289 | (ligatures != GTK_CSS_FONT_VARIANT_LIGATURE_NONE)) || |
1290 | ((ligatures & GTK_CSS_FONT_VARIANT_LIGATURE_COMMON_LIGATURES) && |
1291 | (ligatures & GTK_CSS_FONT_VARIANT_LIGATURE_NO_COMMON_LIGATURES)) || |
1292 | ((ligatures & GTK_CSS_FONT_VARIANT_LIGATURE_DISCRETIONARY_LIGATURES) && |
1293 | (ligatures & GTK_CSS_FONT_VARIANT_LIGATURE_NO_DISCRETIONARY_LIGATURES)) || |
1294 | ((ligatures & GTK_CSS_FONT_VARIANT_LIGATURE_HISTORICAL_LIGATURES) && |
1295 | (ligatures & GTK_CSS_FONT_VARIANT_LIGATURE_NO_HISTORICAL_LIGATURES)) || |
1296 | ((ligatures & GTK_CSS_FONT_VARIANT_LIGATURE_CONTEXTUAL) && |
1297 | (ligatures & GTK_CSS_FONT_VARIANT_LIGATURE_NO_CONTEXTUAL))) |
1298 | return FALSE; |
1299 | |
1300 | return TRUE; |
1301 | } |
1302 | |
1303 | GtkCssValue * |
1304 | _gtk_css_font_variant_ligature_value_new (GtkCssFontVariantLigature ligatures) |
1305 | { |
1306 | GtkCssValue *value; |
1307 | |
1308 | if (!ligature_value_is_valid (ligatures)) |
1309 | return NULL; |
1310 | |
1311 | value = _gtk_css_value_new (GtkCssValue, >K_CSS_VALUE_FONT_VARIANT_LIGATURE); |
1312 | value->value = ligatures; |
1313 | value->name = NULL; |
1314 | value->is_computed = TRUE; |
1315 | |
1316 | return value; |
1317 | } |
1318 | |
1319 | GtkCssFontVariantLigature |
1320 | _gtk_css_font_variant_ligature_try_parse_one (GtkCssParser *parser, |
1321 | GtkCssFontVariantLigature base) |
1322 | { |
1323 | guint i; |
1324 | GtkCssFontVariantLigature value = 0; |
1325 | |
1326 | g_return_val_if_fail (parser != NULL, 0); |
1327 | |
1328 | for (i = 0; i < G_N_ELEMENTS (font_variant_ligature_values); i++) |
1329 | { |
1330 | if (gtk_css_parser_try_ident (self: parser, ident: font_variant_ligature_values[i].name)) |
1331 | { |
1332 | value = font_variant_ligature_values[i].value; |
1333 | break; |
1334 | } |
1335 | } |
1336 | |
1337 | if (value == 0) |
1338 | return base; /* not parsing this value */ |
1339 | |
1340 | if ((base | value) == base) |
1341 | return 0; /* repeated value */ |
1342 | |
1343 | if (!ligature_value_is_valid (ligatures: base | value)) |
1344 | return 0; /* bad combination */ |
1345 | |
1346 | return base | value; |
1347 | } |
1348 | |
1349 | GtkCssFontVariantLigature |
1350 | _gtk_css_font_variant_ligature_value_get (const GtkCssValue *value) |
1351 | { |
1352 | g_return_val_if_fail (value->class == >K_CSS_VALUE_FONT_VARIANT_LIGATURE, GTK_CSS_FONT_VARIANT_LIGATURE_NORMAL); |
1353 | |
1354 | return value->value; |
1355 | } |
1356 | |
1357 | /* GtkCssFontVariantNumeric */ |
1358 | |
1359 | static FlagsValue font_variant_numeric_values[] = { |
1360 | { GTK_CSS_FONT_VARIANT_NUMERIC_NORMAL, "normal" }, |
1361 | { GTK_CSS_FONT_VARIANT_NUMERIC_LINING_NUMS, "lining-nums" }, |
1362 | { GTK_CSS_FONT_VARIANT_NUMERIC_OLDSTYLE_NUMS, "oldstyle-nums" }, |
1363 | { GTK_CSS_FONT_VARIANT_NUMERIC_PROPORTIONAL_NUMS, "proportional-nums" }, |
1364 | { GTK_CSS_FONT_VARIANT_NUMERIC_TABULAR_NUMS, "tabular-nums" }, |
1365 | { GTK_CSS_FONT_VARIANT_NUMERIC_DIAGONAL_FRACTIONS, "diagonal-fractions" }, |
1366 | { GTK_CSS_FONT_VARIANT_NUMERIC_STACKED_FRACTIONS, "stacked-fractions" }, |
1367 | { GTK_CSS_FONT_VARIANT_NUMERIC_ORDINAL, "ordinal" }, |
1368 | { GTK_CSS_FONT_VARIANT_NUMERIC_SLASHED_ZERO, "slashed-zero" } |
1369 | }; |
1370 | |
1371 | static void |
1372 | gtk_css_font_variant_numeric_value_print (const GtkCssValue *value, |
1373 | GString *string) |
1374 | { |
1375 | gtk_css_value_flags_print (values: font_variant_numeric_values, |
1376 | G_N_ELEMENTS (font_variant_numeric_values), |
1377 | value, string); |
1378 | } |
1379 | |
1380 | static const GtkCssValueClass GTK_CSS_VALUE_FONT_VARIANT_NUMERIC = { |
1381 | "GtkCssFontVariantNumbericValue" , |
1382 | gtk_css_value_enum_free, |
1383 | gtk_css_value_enum_compute, |
1384 | gtk_css_value_flags_equal, |
1385 | gtk_css_value_enum_transition, |
1386 | NULL, |
1387 | NULL, |
1388 | gtk_css_font_variant_numeric_value_print |
1389 | }; |
1390 | |
1391 | static gboolean |
1392 | numeric_value_is_valid (GtkCssFontVariantNumeric numeric) |
1393 | { |
1394 | if (((numeric & GTK_CSS_FONT_VARIANT_NUMERIC_NORMAL) && |
1395 | (numeric != GTK_CSS_FONT_VARIANT_NUMERIC_NORMAL)) || |
1396 | ((numeric & GTK_CSS_FONT_VARIANT_NUMERIC_LINING_NUMS) && |
1397 | (numeric & GTK_CSS_FONT_VARIANT_NUMERIC_OLDSTYLE_NUMS)) || |
1398 | ((numeric & GTK_CSS_FONT_VARIANT_NUMERIC_PROPORTIONAL_NUMS) && |
1399 | (numeric & GTK_CSS_FONT_VARIANT_NUMERIC_TABULAR_NUMS)) || |
1400 | ((numeric & GTK_CSS_FONT_VARIANT_NUMERIC_DIAGONAL_FRACTIONS) && |
1401 | (numeric & GTK_CSS_FONT_VARIANT_NUMERIC_STACKED_FRACTIONS))) |
1402 | return FALSE; |
1403 | |
1404 | return TRUE; |
1405 | } |
1406 | |
1407 | GtkCssValue * |
1408 | _gtk_css_font_variant_numeric_value_new (GtkCssFontVariantNumeric numeric) |
1409 | { |
1410 | GtkCssValue *value; |
1411 | |
1412 | if (!numeric_value_is_valid (numeric)) |
1413 | return NULL; |
1414 | |
1415 | value = _gtk_css_value_new (GtkCssValue, >K_CSS_VALUE_FONT_VARIANT_NUMERIC); |
1416 | value->value = numeric; |
1417 | value->name = NULL; |
1418 | value->is_computed = TRUE; |
1419 | |
1420 | return value; |
1421 | } |
1422 | |
1423 | GtkCssFontVariantNumeric |
1424 | _gtk_css_font_variant_numeric_try_parse_one (GtkCssParser *parser, |
1425 | GtkCssFontVariantNumeric base) |
1426 | { |
1427 | guint i; |
1428 | GtkCssFontVariantNumeric value = 0; |
1429 | |
1430 | g_return_val_if_fail (parser != NULL, 0); |
1431 | |
1432 | for (i = 0; i < G_N_ELEMENTS (font_variant_numeric_values); i++) |
1433 | { |
1434 | if (gtk_css_parser_try_ident (self: parser, ident: font_variant_numeric_values[i].name)) |
1435 | { |
1436 | value = font_variant_numeric_values[i].value; |
1437 | break; |
1438 | } |
1439 | } |
1440 | |
1441 | if (value == 0) |
1442 | return base; /* not parsing this value */ |
1443 | |
1444 | if ((base | value) == base) |
1445 | return 0; /* repeated value */ |
1446 | |
1447 | if (!numeric_value_is_valid (numeric: base | value)) |
1448 | return 0; /* bad combination */ |
1449 | |
1450 | return base | value; |
1451 | } |
1452 | |
1453 | GtkCssFontVariantNumeric |
1454 | _gtk_css_font_variant_numeric_value_get (const GtkCssValue *value) |
1455 | { |
1456 | g_return_val_if_fail (value->class == >K_CSS_VALUE_FONT_VARIANT_NUMERIC, GTK_CSS_FONT_VARIANT_NUMERIC_NORMAL); |
1457 | |
1458 | return value->value; |
1459 | } |
1460 | |
1461 | /* GtkCssFontVariantEastAsian */ |
1462 | |
1463 | static FlagsValue font_variant_east_asian_values[] = { |
1464 | { GTK_CSS_FONT_VARIANT_EAST_ASIAN_NORMAL, "normal" }, |
1465 | { GTK_CSS_FONT_VARIANT_EAST_ASIAN_JIS78, "jis78" }, |
1466 | { GTK_CSS_FONT_VARIANT_EAST_ASIAN_JIS83, "jis83" }, |
1467 | { GTK_CSS_FONT_VARIANT_EAST_ASIAN_JIS90, "jis90" }, |
1468 | { GTK_CSS_FONT_VARIANT_EAST_ASIAN_JIS04, "jis04" }, |
1469 | { GTK_CSS_FONT_VARIANT_EAST_ASIAN_SIMPLIFIED, "simplified" }, |
1470 | { GTK_CSS_FONT_VARIANT_EAST_ASIAN_TRADITIONAL, "traditional" }, |
1471 | { GTK_CSS_FONT_VARIANT_EAST_ASIAN_FULL_WIDTH, "full-width" }, |
1472 | { GTK_CSS_FONT_VARIANT_EAST_ASIAN_PROPORTIONAL, "proportional-width" }, |
1473 | { GTK_CSS_FONT_VARIANT_EAST_ASIAN_RUBY, "ruby" } |
1474 | }; |
1475 | |
1476 | static void |
1477 | gtk_css_font_variant_east_asian_value_print (const GtkCssValue *value, |
1478 | GString *string) |
1479 | { |
1480 | gtk_css_value_flags_print (values: font_variant_east_asian_values, |
1481 | G_N_ELEMENTS (font_variant_east_asian_values), |
1482 | value, string); |
1483 | } |
1484 | |
1485 | static const GtkCssValueClass GTK_CSS_VALUE_FONT_VARIANT_EAST_ASIAN = { |
1486 | "GtkCssFontVariantEastAsianValue" , |
1487 | gtk_css_value_enum_free, |
1488 | gtk_css_value_enum_compute, |
1489 | gtk_css_value_flags_equal, |
1490 | gtk_css_value_enum_transition, |
1491 | NULL, |
1492 | NULL, |
1493 | gtk_css_font_variant_east_asian_value_print |
1494 | }; |
1495 | |
1496 | static gboolean |
1497 | east_asian_value_is_valid (GtkCssFontVariantEastAsian east_asian) |
1498 | { |
1499 | if ((east_asian & GTK_CSS_FONT_VARIANT_EAST_ASIAN_NORMAL) && |
1500 | (east_asian != GTK_CSS_FONT_VARIANT_EAST_ASIAN_NORMAL)) |
1501 | return FALSE; |
1502 | |
1503 | if (gtk_popcount (east_asian & (GTK_CSS_FONT_VARIANT_EAST_ASIAN_JIS78 | |
1504 | GTK_CSS_FONT_VARIANT_EAST_ASIAN_JIS83 | |
1505 | GTK_CSS_FONT_VARIANT_EAST_ASIAN_JIS90 | |
1506 | GTK_CSS_FONT_VARIANT_EAST_ASIAN_JIS04 | |
1507 | GTK_CSS_FONT_VARIANT_EAST_ASIAN_SIMPLIFIED | |
1508 | GTK_CSS_FONT_VARIANT_EAST_ASIAN_TRADITIONAL)) > 1) |
1509 | return FALSE; |
1510 | |
1511 | if (gtk_popcount (east_asian & (GTK_CSS_FONT_VARIANT_EAST_ASIAN_FULL_WIDTH | |
1512 | GTK_CSS_FONT_VARIANT_EAST_ASIAN_PROPORTIONAL)) > 1) |
1513 | return FALSE; |
1514 | |
1515 | return TRUE; |
1516 | } |
1517 | |
1518 | GtkCssValue * |
1519 | _gtk_css_font_variant_east_asian_value_new (GtkCssFontVariantEastAsian east_asian) |
1520 | { |
1521 | GtkCssValue *value; |
1522 | |
1523 | if (!east_asian_value_is_valid (east_asian)) |
1524 | return NULL; |
1525 | |
1526 | value = _gtk_css_value_new (GtkCssValue, >K_CSS_VALUE_FONT_VARIANT_EAST_ASIAN); |
1527 | value->value = east_asian; |
1528 | value->name = NULL; |
1529 | value->is_computed = TRUE; |
1530 | |
1531 | return value; |
1532 | } |
1533 | |
1534 | GtkCssFontVariantEastAsian |
1535 | _gtk_css_font_variant_east_asian_try_parse_one (GtkCssParser *parser, |
1536 | GtkCssFontVariantEastAsian base) |
1537 | { |
1538 | guint i; |
1539 | GtkCssFontVariantEastAsian value = 0; |
1540 | |
1541 | g_return_val_if_fail (parser != NULL, 0); |
1542 | |
1543 | for (i = 0; i < G_N_ELEMENTS (font_variant_east_asian_values); i++) |
1544 | { |
1545 | if (gtk_css_parser_try_ident (self: parser, ident: font_variant_east_asian_values[i].name)) |
1546 | { |
1547 | value = font_variant_east_asian_values[i].value; |
1548 | break; |
1549 | } |
1550 | } |
1551 | |
1552 | if (value == 0) |
1553 | return base; /* not parsing this value */ |
1554 | |
1555 | if ((base | value) == base) |
1556 | return 0; /* repeated value */ |
1557 | |
1558 | if (!east_asian_value_is_valid (east_asian: base | value)) |
1559 | return 0; /* bad combination */ |
1560 | |
1561 | return base | value; |
1562 | } |
1563 | |
1564 | GtkCssFontVariantEastAsian |
1565 | _gtk_css_font_variant_east_asian_value_get (const GtkCssValue *value) |
1566 | { |
1567 | g_return_val_if_fail (value->class == >K_CSS_VALUE_FONT_VARIANT_EAST_ASIAN, GTK_CSS_FONT_VARIANT_EAST_ASIAN_NORMAL); |
1568 | |
1569 | return value->value; |
1570 | } |
1571 | |
1572 | /* GtkTextTransform */ |
1573 | |
1574 | static const GtkCssValueClass GTK_CSS_VALUE_TEXT_TRANSFORM = { |
1575 | "GtkCssTextTransformValue" , |
1576 | gtk_css_value_enum_free, |
1577 | gtk_css_value_enum_compute, |
1578 | gtk_css_value_enum_equal, |
1579 | gtk_css_value_enum_transition, |
1580 | NULL, |
1581 | NULL, |
1582 | gtk_css_value_enum_print |
1583 | }; |
1584 | |
1585 | static GtkCssValue text_transform_values[] = { |
1586 | { .class: >K_CSS_VALUE_TEXT_TRANSFORM, .ref_count: 1, TRUE, .value: GTK_CSS_TEXT_TRANSFORM_NONE, .name: "none" }, |
1587 | { >K_CSS_VALUE_TEXT_TRANSFORM, 1, TRUE, GTK_CSS_TEXT_TRANSFORM_LOWERCASE, "lowercase" }, |
1588 | { >K_CSS_VALUE_TEXT_TRANSFORM, 1, TRUE, GTK_CSS_TEXT_TRANSFORM_UPPERCASE, "uppercase" }, |
1589 | { >K_CSS_VALUE_TEXT_TRANSFORM, 1, TRUE, GTK_CSS_TEXT_TRANSFORM_CAPITALIZE, "capitalize" }, |
1590 | }; |
1591 | |
1592 | GtkCssValue * |
1593 | _gtk_css_text_transform_value_new (GtkTextTransform transform) |
1594 | { |
1595 | g_return_val_if_fail (transform < G_N_ELEMENTS (text_transform_values), NULL); |
1596 | |
1597 | return _gtk_css_value_ref (value: &text_transform_values[transform]); |
1598 | } |
1599 | |
1600 | GtkCssValue * |
1601 | _gtk_css_text_transform_value_try_parse (GtkCssParser *parser) |
1602 | { |
1603 | guint i; |
1604 | |
1605 | g_return_val_if_fail (parser != NULL, NULL); |
1606 | |
1607 | for (i = 0; i < G_N_ELEMENTS (text_transform_values); i++) |
1608 | { |
1609 | if (gtk_css_parser_try_ident (self: parser, ident: text_transform_values[i].name)) |
1610 | return _gtk_css_value_ref (value: &text_transform_values[i]); |
1611 | } |
1612 | |
1613 | return NULL; |
1614 | } |
1615 | |
1616 | GtkTextTransform |
1617 | _gtk_css_text_transform_value_get (const GtkCssValue *value) |
1618 | { |
1619 | g_return_val_if_fail (value->class == >K_CSS_VALUE_TEXT_TRANSFORM, GTK_CSS_TEXT_TRANSFORM_NONE); |
1620 | |
1621 | return value->value; |
1622 | } |
1623 | |