1 | /* GTK - The GIMP Toolkit |
2 | * Copyright (C) 2021 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 "gtkcsslineheightvalueprivate.h" |
21 | #include "gtkcssnumbervalueprivate.h" |
22 | #include "gtkcssstyleprivate.h" |
23 | |
24 | struct _GtkCssValue { |
25 | GTK_CSS_VALUE_BASE |
26 | GtkCssValue *height; |
27 | }; |
28 | |
29 | static GtkCssValue *default_line_height; |
30 | |
31 | static GtkCssValue *gtk_css_value_line_height_new_empty (void); |
32 | static GtkCssValue *gtk_css_value_line_height_new (GtkCssValue *height); |
33 | |
34 | static void |
35 | gtk_css_value_line_height_free (GtkCssValue *value) |
36 | { |
37 | _gtk_css_value_unref (value: value->height); |
38 | g_slice_free (GtkCssValue, value); |
39 | } |
40 | |
41 | static GtkCssValue * |
42 | gtk_css_value_line_height_compute (GtkCssValue *value, |
43 | guint property_id, |
44 | GtkStyleProvider *provider, |
45 | GtkCssStyle *style, |
46 | GtkCssStyle *parent_style) |
47 | { |
48 | GtkCssValue *height; |
49 | |
50 | height = _gtk_css_value_compute (value: value->height, property_id, provider, style, parent_style); |
51 | |
52 | if (gtk_css_number_value_get_dimension (value: height) == GTK_CSS_DIMENSION_PERCENTAGE) |
53 | { |
54 | double factor; |
55 | GtkCssValue *computed; |
56 | |
57 | factor = _gtk_css_number_value_get (number: height, one_hundred_percent: 1); |
58 | computed = gtk_css_number_value_multiply (value: style->core->font_size, factor); |
59 | |
60 | _gtk_css_value_unref (value: height); |
61 | |
62 | return computed; |
63 | } |
64 | else |
65 | { |
66 | return height; |
67 | } |
68 | } |
69 | |
70 | static gboolean |
71 | gtk_css_value_line_height_equal (const GtkCssValue *value1, |
72 | const GtkCssValue *value2) |
73 | { |
74 | if (value1->height == NULL || value2->height == NULL) |
75 | return FALSE; |
76 | |
77 | return _gtk_css_value_equal (value1: value1->height, value2: value2->height); |
78 | } |
79 | |
80 | static GtkCssValue * |
81 | gtk_css_value_line_height_transition (GtkCssValue *start, |
82 | GtkCssValue *end, |
83 | guint property_id, |
84 | double progress) |
85 | { |
86 | GtkCssValue *height; |
87 | |
88 | if (start->height == NULL || end->height == NULL) |
89 | return NULL; |
90 | |
91 | height = _gtk_css_value_transition (start: start->height, end: end->height, property_id, progress); |
92 | if (height == NULL) |
93 | return NULL; |
94 | |
95 | return gtk_css_value_line_height_new (height); |
96 | } |
97 | |
98 | static void |
99 | gtk_css_value_line_height_print (const GtkCssValue *value, |
100 | GString *string) |
101 | { |
102 | if (value->height == NULL) |
103 | g_string_append (string, val: "normal" ); |
104 | else |
105 | _gtk_css_value_print (value: value->height, string); |
106 | } |
107 | |
108 | static const GtkCssValueClass GTK_CSS_VALUE_LINE_HEIGHT = { |
109 | "GtkCssLineHeightValue" , |
110 | gtk_css_value_line_height_free, |
111 | gtk_css_value_line_height_compute, |
112 | gtk_css_value_line_height_equal, |
113 | gtk_css_value_line_height_transition, |
114 | NULL, |
115 | NULL, |
116 | gtk_css_value_line_height_print |
117 | }; |
118 | |
119 | static GtkCssValue * |
120 | gtk_css_value_line_height_new_empty (void) |
121 | { |
122 | GtkCssValue *result; |
123 | |
124 | result = _gtk_css_value_new (GtkCssValue, >K_CSS_VALUE_LINE_HEIGHT); |
125 | result->height = NULL; |
126 | result->is_computed = TRUE; |
127 | |
128 | return result; |
129 | } |
130 | |
131 | static GtkCssValue * |
132 | gtk_css_value_line_height_new (GtkCssValue *height) |
133 | { |
134 | GtkCssValue *result; |
135 | |
136 | result = _gtk_css_value_new (GtkCssValue, >K_CSS_VALUE_LINE_HEIGHT); |
137 | result->height = height; |
138 | |
139 | return result; |
140 | } |
141 | |
142 | GtkCssValue * |
143 | gtk_css_line_height_value_get_default (void) |
144 | { |
145 | if (default_line_height == NULL) |
146 | default_line_height = gtk_css_value_line_height_new_empty (); |
147 | |
148 | return default_line_height; |
149 | } |
150 | |
151 | GtkCssValue * |
152 | gtk_css_line_height_value_parse (GtkCssParser *parser) |
153 | { |
154 | GtkCssValue *height; |
155 | |
156 | if (gtk_css_parser_try_ident (self: parser, ident: "normal" )) |
157 | return _gtk_css_value_ref (value: gtk_css_line_height_value_get_default ()); |
158 | |
159 | height = _gtk_css_number_value_parse (parser, flags: GTK_CSS_PARSE_NUMBER | |
160 | GTK_CSS_PARSE_PERCENT | |
161 | GTK_CSS_PARSE_LENGTH | |
162 | GTK_CSS_POSITIVE_ONLY); |
163 | if (!height) |
164 | return NULL; |
165 | |
166 | return gtk_css_value_line_height_new (height); |
167 | } |
168 | |
169 | double |
170 | gtk_css_line_height_value_get (const GtkCssValue *value) |
171 | { |
172 | if (value->class == >K_CSS_VALUE_LINE_HEIGHT) |
173 | return 0.0; |
174 | |
175 | return _gtk_css_number_value_get (number: value, one_hundred_percent: 1); |
176 | } |
177 | |