1 /* GTK - The GIMP Toolkit
2  * Copyright (C) 2016 Benjamin Otte <otte@gnome.org>
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 "gtkcssnumbervalueprivate.h"
21 
22 #include "gtkcsscalcvalueprivate.h"
23 #include "gtkcssdimensionvalueprivate.h"
24 #include "gtkcsswin32sizevalueprivate.h"
25 
26 struct _GtkCssValue {
27   GTK_CSS_VALUE_BASE
28 };
29 
30 GtkCssDimension
gtk_css_number_value_get_dimension(const GtkCssValue * value)31 gtk_css_number_value_get_dimension (const GtkCssValue *value)
32 {
33   GtkCssNumberValueClass *number_value_class = (GtkCssNumberValueClass *) value->class;
34 
35   return number_value_class->get_dimension (value);
36 }
37 
38 gboolean
gtk_css_number_value_has_percent(const GtkCssValue * value)39 gtk_css_number_value_has_percent (const GtkCssValue *value)
40 {
41   GtkCssNumberValueClass *number_value_class = (GtkCssNumberValueClass *) value->class;
42 
43   return number_value_class->has_percent (value);
44 }
45 
46 GtkCssValue *
gtk_css_number_value_multiply(const GtkCssValue * value,double factor)47 gtk_css_number_value_multiply (const GtkCssValue *value,
48                                double             factor)
49 {
50   GtkCssNumberValueClass *number_value_class = (GtkCssNumberValueClass *) value->class;
51 
52   return number_value_class->multiply (value, factor);
53 }
54 
55 GtkCssValue *
gtk_css_number_value_add(GtkCssValue * value1,GtkCssValue * value2)56 gtk_css_number_value_add (GtkCssValue *value1,
57                           GtkCssValue *value2)
58 {
59   GtkCssValue *sum;
60 
61   sum = gtk_css_number_value_try_add (value1, value2);
62   if (sum == NULL)
63     sum = gtk_css_calc_value_new_sum (value1, value2);
64 
65   return sum;
66 }
67 
68 GtkCssValue *
gtk_css_number_value_try_add(const GtkCssValue * value1,const GtkCssValue * value2)69 gtk_css_number_value_try_add (const GtkCssValue *value1,
70                               const GtkCssValue *value2)
71 {
72   GtkCssNumberValueClass *number_value_class;
73 
74   if (value1->class != value2->class)
75     return NULL;
76 
77   number_value_class = (GtkCssNumberValueClass *) value1->class;
78 
79   return number_value_class->try_add (value1, value2);
80 }
81 
82 /*
83  * gtk_css_number_value_get_calc_term_order:
84  * @value: Value to compute order for
85  *
86  * Determines the position of @value when printed as part of a calc()
87  * expression. Values with lower numbers are printed first. Note that
88  * these numbers are arbitrary, so when adding new types of values to
89  * print, feel free to change them in implementations so that they
90  * match.
91  *
92  * Returns: Magic value determining placement when printing calc()
93  *     expression.
94  */
95 gint
gtk_css_number_value_get_calc_term_order(const GtkCssValue * value)96 gtk_css_number_value_get_calc_term_order (const GtkCssValue *value)
97 {
98   GtkCssNumberValueClass *number_value_class = (GtkCssNumberValueClass *) value->class;
99 
100   return number_value_class->get_calc_term_order (value);
101 }
102 
103 GtkCssValue *
_gtk_css_number_value_new(double value,GtkCssUnit unit)104 _gtk_css_number_value_new (double     value,
105                            GtkCssUnit unit)
106 {
107   return gtk_css_dimension_value_new (value, unit);
108 }
109 
110 GtkCssValue *
gtk_css_number_value_transition(GtkCssValue * start,GtkCssValue * end,guint property_id,double progress)111 gtk_css_number_value_transition (GtkCssValue *start,
112                                  GtkCssValue *end,
113                                  guint        property_id,
114                                  double       progress)
115 {
116   GtkCssValue *result, *mul_start, *mul_end;
117 
118   mul_start = gtk_css_number_value_multiply (start, 1 - progress);
119   mul_end = gtk_css_number_value_multiply (end, progress);
120 
121   result = gtk_css_number_value_add (mul_start, mul_end);
122 
123   _gtk_css_value_unref (mul_start);
124   _gtk_css_value_unref (mul_end);
125 
126   return result;
127 }
128 
129 gboolean
gtk_css_number_value_can_parse(GtkCssParser * parser)130 gtk_css_number_value_can_parse (GtkCssParser *parser)
131 {
132   return _gtk_css_parser_has_number (parser)
133       || _gtk_css_parser_has_prefix (parser, "calc")
134       || _gtk_css_parser_has_prefix (parser, "-gtk-win32-size")
135       || _gtk_css_parser_has_prefix (parser, "-gtk-win32-part-width")
136       || _gtk_css_parser_has_prefix (parser, "-gtk-win32-part-height")
137       || _gtk_css_parser_has_prefix (parser, "-gtk-win32-part-border-top")
138       || _gtk_css_parser_has_prefix (parser, "-gtk-win32-part-border-left")
139       || _gtk_css_parser_has_prefix (parser, "-gtk-win32-part-border-bottom")
140       || _gtk_css_parser_has_prefix (parser, "-gtk-win32-part-border-right");
141 }
142 
143 GtkCssValue *
_gtk_css_number_value_parse(GtkCssParser * parser,GtkCssNumberParseFlags flags)144 _gtk_css_number_value_parse (GtkCssParser           *parser,
145                              GtkCssNumberParseFlags  flags)
146 {
147   if (_gtk_css_parser_has_prefix (parser, "calc"))
148     return gtk_css_calc_value_parse (parser, flags);
149   if (_gtk_css_parser_has_prefix (parser, "-gtk-win32-size") ||
150       _gtk_css_parser_has_prefix (parser, "-gtk-win32-part-width") ||
151       _gtk_css_parser_has_prefix (parser, "-gtk-win32-part-height") ||
152       _gtk_css_parser_has_prefix (parser, "-gtk-win32-part-border-top") ||
153       _gtk_css_parser_has_prefix (parser, "-gtk-win32-part-border-left") ||
154       _gtk_css_parser_has_prefix (parser, "-gtk-win32-part-border-bottom") ||
155       _gtk_css_parser_has_prefix (parser, "-gtk-win32-part-border-right"))
156     return gtk_css_win32_size_value_parse (parser, flags);
157 
158   return gtk_css_dimension_value_parse (parser, flags);
159 }
160 
161 double
_gtk_css_number_value_get(const GtkCssValue * number,double one_hundred_percent)162 _gtk_css_number_value_get (const GtkCssValue *number,
163                            double             one_hundred_percent)
164 {
165   GtkCssNumberValueClass *number_value_class;
166 
167   g_return_val_if_fail (number != NULL, 0.0);
168 
169   number_value_class = (GtkCssNumberValueClass *) number->class;
170 
171   return number_value_class->get (number, one_hundred_percent);
172 }
173 
174