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 "gtkcssdimensionvalueprivate.h"
21
22GtkCssValue *
23gtk_css_dimension_value_parse (GtkCssParser *parser,
24 GtkCssNumberParseFlags flags)
25{
26 static const struct {
27 const char *name;
28 GtkCssUnit unit;
29 GtkCssNumberParseFlags required_flags;
30 } units[] = {
31 { "px", GTK_CSS_PX, GTK_CSS_PARSE_LENGTH },
32 { "pt", GTK_CSS_PT, GTK_CSS_PARSE_LENGTH },
33 { "em", GTK_CSS_EM, GTK_CSS_PARSE_LENGTH },
34 { "ex", GTK_CSS_EX, GTK_CSS_PARSE_LENGTH },
35 { "rem", GTK_CSS_REM, GTK_CSS_PARSE_LENGTH },
36 { "pc", GTK_CSS_PC, GTK_CSS_PARSE_LENGTH },
37 { "in", GTK_CSS_IN, GTK_CSS_PARSE_LENGTH },
38 { "cm", GTK_CSS_CM, GTK_CSS_PARSE_LENGTH },
39 { "mm", GTK_CSS_MM, GTK_CSS_PARSE_LENGTH },
40 { "rad", GTK_CSS_RAD, GTK_CSS_PARSE_ANGLE },
41 { "deg", GTK_CSS_DEG, GTK_CSS_PARSE_ANGLE },
42 { "grad", GTK_CSS_GRAD, GTK_CSS_PARSE_ANGLE },
43 { "turn", GTK_CSS_TURN, GTK_CSS_PARSE_ANGLE },
44 { "s", GTK_CSS_S, GTK_CSS_PARSE_TIME },
45 { "ms", GTK_CSS_MS, GTK_CSS_PARSE_TIME }
46 };
47 const GtkCssToken *token;
48 GtkCssValue *result;
49 GtkCssUnit unit;
50 double number;
51
52 token = gtk_css_parser_get_token (self: parser);
53
54 /* Handle percentages first */
55 if (gtk_css_token_is (token, GTK_CSS_TOKEN_PERCENTAGE))
56 {
57 if (!(flags & GTK_CSS_PARSE_PERCENT))
58 {
59 gtk_css_parser_error_value (self: parser, format: "Percentages are not allowed here");
60 return NULL;
61 }
62 number = token->number.number;
63 unit = GTK_CSS_PERCENT;
64 }
65 else if (gtk_css_token_is (token, GTK_CSS_TOKEN_SIGNED_INTEGER) ||
66 gtk_css_token_is (token, GTK_CSS_TOKEN_SIGNLESS_INTEGER) ||
67 gtk_css_token_is (token, GTK_CSS_TOKEN_SIGNED_NUMBER) ||
68 gtk_css_token_is (token, GTK_CSS_TOKEN_SIGNLESS_NUMBER))
69 {
70 number = token->number.number;
71 if (number == 0.0)
72 {
73 if (flags & GTK_CSS_PARSE_NUMBER)
74 unit = GTK_CSS_NUMBER;
75 else if (flags & GTK_CSS_PARSE_LENGTH)
76 unit = GTK_CSS_PX;
77 else if (flags & GTK_CSS_PARSE_ANGLE)
78 unit = GTK_CSS_DEG;
79 else if (flags & GTK_CSS_PARSE_TIME)
80 unit = GTK_CSS_S;
81 else
82 unit = GTK_CSS_PERCENT;
83 }
84 else if (flags & GTK_CSS_PARSE_NUMBER)
85 {
86 unit = GTK_CSS_NUMBER;
87 }
88 else
89 {
90 gtk_css_parser_error_syntax (self: parser, format: "Unit is missing.");
91 return NULL;
92 }
93 }
94 else if (gtk_css_token_is (token, GTK_CSS_TOKEN_SIGNED_INTEGER_DIMENSION) ||
95 gtk_css_token_is (token, GTK_CSS_TOKEN_SIGNLESS_INTEGER_DIMENSION) ||
96 gtk_css_token_is (token, GTK_CSS_TOKEN_SIGNED_DIMENSION) ||
97 gtk_css_token_is (token, GTK_CSS_TOKEN_SIGNLESS_DIMENSION))
98 {
99 guint i;
100
101 for (i = 0; i < G_N_ELEMENTS (units); i++)
102 {
103 if (flags & units[i].required_flags &&
104 g_ascii_strcasecmp (s1: token->dimension.dimension, s2: units[i].name) == 0)
105 break;
106 }
107
108 if (i >= G_N_ELEMENTS (units))
109 {
110 gtk_css_parser_error_syntax (self: parser, format: "'%s' is not a valid unit", token->dimension.dimension);
111 return NULL;
112 }
113
114 unit = units[i].unit;
115 number = token->dimension.value;
116 }
117 else
118 {
119 gtk_css_parser_error_syntax (self: parser, format: "Expected a number");
120 return NULL;
121 }
122
123 if (flags & GTK_CSS_POSITIVE_ONLY &&
124 number < 0)
125 {
126 gtk_css_parser_error_value (self: parser, format: "Negative values are not allowed");
127 return NULL;
128 }
129
130 result = gtk_css_dimension_value_new (value: number, unit);
131 gtk_css_parser_consume_token (self: parser);
132
133 return result;
134}
135

source code of gtk/gtk/gtkcssdimensionvalue.c