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 "gtkcsscornervalueprivate.h"
21#include "gtkcssnumbervalueprivate.h"
22#include "gtkcssdimensionvalueprivate.h"
23
24struct _GtkCssValue {
25 GTK_CSS_VALUE_BASE
26 GtkCssValue *x;
27 GtkCssValue *y;
28};
29
30static void
31gtk_css_value_corner_free (GtkCssValue *value)
32{
33 _gtk_css_value_unref (value: value->x);
34 _gtk_css_value_unref (value: value->y);
35
36 g_slice_free (GtkCssValue, value);
37}
38
39static GtkCssValue *
40gtk_css_value_corner_compute (GtkCssValue *corner,
41 guint property_id,
42 GtkStyleProvider *provider,
43 GtkCssStyle *style,
44 GtkCssStyle *parent_style)
45{
46 GtkCssValue *x, *y;
47
48 x = _gtk_css_value_compute (value: corner->x, property_id, provider, style, parent_style);
49 y = _gtk_css_value_compute (value: corner->y, property_id, provider, style, parent_style);
50 if (x == corner->x && y == corner->y)
51 {
52 _gtk_css_value_unref (value: x);
53 _gtk_css_value_unref (value: y);
54 return _gtk_css_value_ref (value: corner);
55 }
56
57 return _gtk_css_corner_value_new (x, y);
58}
59
60static gboolean
61gtk_css_value_corner_equal (const GtkCssValue *corner1,
62 const GtkCssValue *corner2)
63{
64 return _gtk_css_value_equal (value1: corner1->x, value2: corner2->x)
65 && _gtk_css_value_equal (value1: corner1->y, value2: corner2->y);
66}
67
68static GtkCssValue *
69gtk_css_value_corner_transition (GtkCssValue *start,
70 GtkCssValue *end,
71 guint property_id,
72 double progress)
73{
74 GtkCssValue *x, *y;
75
76 x = _gtk_css_value_transition (start: start->x, end: end->x, property_id, progress);
77 if (x == NULL)
78 return NULL;
79 y = _gtk_css_value_transition (start: start->y, end: end->y, property_id, progress);
80 if (y == NULL)
81 {
82 _gtk_css_value_unref (value: x);
83 return NULL;
84 }
85
86 return _gtk_css_corner_value_new (x, y);
87}
88
89static void
90gtk_css_value_corner_print (const GtkCssValue *corner,
91 GString *string)
92{
93 _gtk_css_value_print (value: corner->x, string);
94 if (!_gtk_css_value_equal (value1: corner->x, value2: corner->y))
95 {
96 g_string_append_c (string, ' ');
97 _gtk_css_value_print (value: corner->y, string);
98 }
99}
100
101static const GtkCssValueClass GTK_CSS_VALUE_CORNER = {
102 "GtkCssCornerValue",
103 gtk_css_value_corner_free,
104 gtk_css_value_corner_compute,
105 gtk_css_value_corner_equal,
106 gtk_css_value_corner_transition,
107 NULL,
108 NULL,
109 gtk_css_value_corner_print
110};
111
112GtkCssValue *
113_gtk_css_corner_value_new (GtkCssValue *x,
114 GtkCssValue *y)
115{
116 GtkCssValue *result;
117
118 if (_gtk_css_value_equal (value1: x, value2: y))
119 {
120 _gtk_css_value_unref (value: y);
121 return x;
122 }
123
124 result = _gtk_css_value_new (GtkCssValue, &GTK_CSS_VALUE_CORNER);
125 result->x = x;
126 result->y = y;
127
128 return result;
129}
130
131GtkCssValue *
132_gtk_css_corner_value_parse (GtkCssParser *parser)
133{
134 GtkCssValue *x, *y;
135
136 x = _gtk_css_number_value_parse (parser,
137 flags: GTK_CSS_POSITIVE_ONLY
138 | GTK_CSS_PARSE_PERCENT
139 | GTK_CSS_PARSE_LENGTH);
140 if (x == NULL)
141 return NULL;
142
143 if (!gtk_css_number_value_can_parse (parser))
144 y = _gtk_css_value_ref (value: x);
145 else
146 {
147 y = _gtk_css_number_value_parse (parser,
148 flags: GTK_CSS_POSITIVE_ONLY
149 | GTK_CSS_PARSE_PERCENT
150 | GTK_CSS_PARSE_LENGTH);
151 if (y == NULL)
152 {
153 _gtk_css_value_unref (value: x);
154 return NULL;
155 }
156 }
157
158 return _gtk_css_corner_value_new (x, y);
159}
160
161double
162_gtk_css_corner_value_get_x (const GtkCssValue *corner,
163 double one_hundred_percent)
164{
165 if (corner->class != &GTK_CSS_VALUE_CORNER)
166 return _gtk_css_number_value_get (number: corner, one_hundred_percent);
167
168 g_return_val_if_fail (corner != NULL, 0.0);
169 g_return_val_if_fail (corner->class == &GTK_CSS_VALUE_CORNER, 0.0);
170
171 return _gtk_css_number_value_get (number: corner->x, one_hundred_percent);
172}
173
174double
175_gtk_css_corner_value_get_y (const GtkCssValue *corner,
176 double one_hundred_percent)
177{
178 if (corner->class != &GTK_CSS_VALUE_CORNER)
179 return _gtk_css_number_value_get (number: corner, one_hundred_percent);
180
181 g_return_val_if_fail (corner != NULL, 0.0);
182 g_return_val_if_fail (corner->class == &GTK_CSS_VALUE_CORNER, 0.0);
183
184 return _gtk_css_number_value_get (number: corner->y, one_hundred_percent);
185}
186
187gboolean
188gtk_css_corner_value_is_zero (const GtkCssValue *corner)
189{
190 if (corner->class != &GTK_CSS_VALUE_CORNER)
191 return gtk_css_dimension_value_is_zero (value: corner);
192
193 return gtk_css_dimension_value_is_zero (value: corner->x) &&
194 gtk_css_dimension_value_is_zero (value: corner->y);
195}
196

source code of gtk/gtk/gtkcsscornervalue.c