]> Pileus Git - ~andy/gtk/blob - gtk/gtkcsscomputedvalues.c
css: Use internal return_if_fail in some commonly called code
[~andy/gtk] / gtk / gtkcsscomputedvalues.c
1 /*
2  * Copyright © 2012 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.1 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  * Authors: Benjamin Otte <otte@gnome.org>
18  */
19
20 #include "config.h"
21
22 #include "gtkprivate.h"
23 #include "gtkcsscomputedvaluesprivate.h"
24
25 #include "gtkcssanimationprivate.h"
26 #include "gtkcssarrayvalueprivate.h"
27 #include "gtkcssenumvalueprivate.h"
28 #include "gtkcssinheritvalueprivate.h"
29 #include "gtkcssinitialvalueprivate.h"
30 #include "gtkcssnumbervalueprivate.h"
31 #include "gtkcssshorthandpropertyprivate.h"
32 #include "gtkcssstringvalueprivate.h"
33 #include "gtkcssstylepropertyprivate.h"
34 #include "gtkcsstransitionprivate.h"
35 #include "gtkstyleanimationprivate.h"
36 #include "gtkstylepropertiesprivate.h"
37 #include "gtkstylepropertyprivate.h"
38 #include "gtkstyleproviderprivate.h"
39
40 G_DEFINE_TYPE (GtkCssComputedValues, _gtk_css_computed_values, G_TYPE_OBJECT)
41
42 static void
43 gtk_css_computed_values_dispose (GObject *object)
44 {
45   GtkCssComputedValues *values = GTK_CSS_COMPUTED_VALUES (object);
46
47   if (values->values)
48     {
49       g_ptr_array_unref (values->values);
50       values->values = NULL;
51     }
52   if (values->sections)
53     {
54       g_ptr_array_unref (values->sections);
55       values->sections = NULL;
56     }
57   if (values->animated_values)
58     {
59       g_ptr_array_unref (values->animated_values);
60       values->animated_values = NULL;
61     }
62
63   g_slist_free_full (values->animations, g_object_unref);
64   values->animations = NULL;
65
66   G_OBJECT_CLASS (_gtk_css_computed_values_parent_class)->dispose (object);
67 }
68
69 static void
70 gtk_css_computed_values_finalize (GObject *object)
71 {
72   GtkCssComputedValues *values = GTK_CSS_COMPUTED_VALUES (object);
73
74   _gtk_bitmask_free (values->depends_on_parent);
75   _gtk_bitmask_free (values->equals_parent);
76   _gtk_bitmask_free (values->depends_on_color);
77   _gtk_bitmask_free (values->depends_on_font_size);
78
79   G_OBJECT_CLASS (_gtk_css_computed_values_parent_class)->finalize (object);
80 }
81
82 static void
83 _gtk_css_computed_values_class_init (GtkCssComputedValuesClass *klass)
84 {
85   GObjectClass *object_class = G_OBJECT_CLASS (klass);
86
87   object_class->dispose = gtk_css_computed_values_dispose;
88   object_class->finalize = gtk_css_computed_values_finalize;
89 }
90
91 static void
92 _gtk_css_computed_values_init (GtkCssComputedValues *values)
93 {
94   values->depends_on_parent = _gtk_bitmask_new ();
95   values->equals_parent = _gtk_bitmask_new ();
96   values->depends_on_color = _gtk_bitmask_new ();
97   values->depends_on_font_size = _gtk_bitmask_new ();
98 }
99
100 GtkCssComputedValues *
101 _gtk_css_computed_values_new (void)
102 {
103   return g_object_new (GTK_TYPE_CSS_COMPUTED_VALUES, NULL);
104 }
105
106 static void
107 maybe_unref_section (gpointer section)
108 {
109   if (section)
110     gtk_css_section_unref (section);
111 }
112
113 void
114 _gtk_css_computed_values_compute_value (GtkCssComputedValues    *values,
115                                         GtkStyleProviderPrivate *provider,
116                                         GtkCssComputedValues    *parent_values,
117                                         guint                    id,
118                                         GtkCssValue             *specified,
119                                         GtkCssSection           *section)
120 {
121   GtkCssDependencies dependencies;
122   GtkCssValue *value;
123
124   gtk_internal_return_if_fail (GTK_IS_CSS_COMPUTED_VALUES (values));
125   gtk_internal_return_if_fail (GTK_IS_STYLE_PROVIDER_PRIVATE (provider));
126   gtk_internal_return_if_fail (parent_values == NULL || GTK_IS_CSS_COMPUTED_VALUES (parent_values));
127
128   /* http://www.w3.org/TR/css3-cascade/#cascade
129    * Then, for every element, the value for each property can be found
130    * by following this pseudo-algorithm:
131    * 1) Identify all declarations that apply to the element
132    */
133   if (specified == NULL)
134     {
135       GtkCssStyleProperty *prop = _gtk_css_style_property_lookup_by_id (id);
136
137       if (_gtk_css_style_property_is_inherit (prop))
138         specified = _gtk_css_inherit_value_new ();
139       else
140         specified = _gtk_css_initial_value_new ();
141     }
142   else
143     _gtk_css_value_ref (specified);
144
145   value = _gtk_css_value_compute (specified, id, provider, values, parent_values, &dependencies);
146
147   _gtk_css_computed_values_set_value (values, id, value, dependencies, section);
148
149   _gtk_css_value_unref (value);
150   _gtk_css_value_unref (specified);
151 }
152
153 void
154 _gtk_css_computed_values_set_animated_value (GtkCssComputedValues *values,
155                                              guint                 id,
156                                              GtkCssValue          *value)
157 {
158   gtk_internal_return_if_fail (GTK_IS_CSS_COMPUTED_VALUES (values));
159   gtk_internal_return_if_fail (value != NULL);
160
161   if (values->animated_values == NULL)
162     values->animated_values = g_ptr_array_new_with_free_func ((GDestroyNotify)_gtk_css_value_unref);
163   if (id >= values->animated_values->len)
164    g_ptr_array_set_size (values->animated_values, id + 1);
165
166   if (g_ptr_array_index (values->animated_values, id))
167     _gtk_css_value_unref (g_ptr_array_index (values->animated_values, id));
168   g_ptr_array_index (values->animated_values, id) = _gtk_css_value_ref (value);
169
170 }
171
172 void
173 _gtk_css_computed_values_set_value (GtkCssComputedValues *values,
174                                     guint                 id,
175                                     GtkCssValue          *value,
176                                     GtkCssDependencies    dependencies,
177                                     GtkCssSection        *section)
178 {
179   gtk_internal_return_if_fail (GTK_IS_CSS_COMPUTED_VALUES (values));
180
181   if (values->values == NULL)
182     values->values = g_ptr_array_new_with_free_func ((GDestroyNotify)_gtk_css_value_unref);
183   if (id >= values->values->len)
184    g_ptr_array_set_size (values->values, id + 1);
185
186   if (g_ptr_array_index (values->values, id))
187     _gtk_css_value_unref (g_ptr_array_index (values->values, id));
188   g_ptr_array_index (values->values, id) = _gtk_css_value_ref (value);
189
190   if (dependencies & (GTK_CSS_DEPENDS_ON_PARENT | GTK_CSS_EQUALS_PARENT))
191     values->depends_on_parent = _gtk_bitmask_set (values->depends_on_parent, id, TRUE);
192   if (dependencies & (GTK_CSS_EQUALS_PARENT))
193     values->equals_parent = _gtk_bitmask_set (values->equals_parent, id, TRUE);
194   if (dependencies & (GTK_CSS_DEPENDS_ON_COLOR))
195     values->depends_on_color = _gtk_bitmask_set (values->depends_on_color, id, TRUE);
196   if (dependencies & (GTK_CSS_DEPENDS_ON_FONT_SIZE))
197     values->depends_on_font_size = _gtk_bitmask_set (values->depends_on_font_size, id, TRUE);
198
199   if (values->sections && values->sections->len > id && g_ptr_array_index (values->sections, id))
200     {
201       gtk_css_section_unref (g_ptr_array_index (values->sections, id));
202       g_ptr_array_index (values->sections, id) = NULL;
203     }
204
205   if (section)
206     {
207       if (values->sections == NULL)
208         values->sections = g_ptr_array_new_with_free_func (maybe_unref_section);
209       if (values->sections->len <= id)
210         g_ptr_array_set_size (values->sections, id + 1);
211
212       g_ptr_array_index (values->sections, id) = gtk_css_section_ref (section);
213     }
214 }
215
216 GtkCssValue *
217 _gtk_css_computed_values_get_value (GtkCssComputedValues *values,
218                                     guint                 id)
219 {
220   gtk_internal_return_val_if_fail (GTK_IS_CSS_COMPUTED_VALUES (values), NULL);
221
222   if (values->animated_values &&
223       id < values->animated_values->len &&
224       g_ptr_array_index (values->animated_values, id))
225     return g_ptr_array_index (values->animated_values, id);
226
227   return _gtk_css_computed_values_get_intrinsic_value (values, id);
228 }
229
230 GtkCssValue *
231 _gtk_css_computed_values_get_intrinsic_value (GtkCssComputedValues *values,
232                                               guint                 id)
233 {
234   gtk_internal_return_val_if_fail (GTK_IS_CSS_COMPUTED_VALUES (values), NULL);
235
236   if (values->values == NULL ||
237       id >= values->values->len)
238     return NULL;
239
240   return g_ptr_array_index (values->values, id);
241 }
242
243 GtkCssSection *
244 _gtk_css_computed_values_get_section (GtkCssComputedValues *values,
245                                       guint                 id)
246 {
247   gtk_internal_return_val_if_fail (GTK_IS_CSS_COMPUTED_VALUES (values), NULL);
248
249   if (values->sections == NULL ||
250       id >= values->sections->len)
251     return NULL;
252
253   return g_ptr_array_index (values->sections, id);
254 }
255
256 GtkBitmask *
257 _gtk_css_computed_values_get_difference (GtkCssComputedValues *values,
258                                          GtkCssComputedValues *other)
259 {
260   GtkBitmask *result;
261   guint i, len;
262
263   len = MIN (values->values->len, other->values->len);
264   result = _gtk_bitmask_new ();
265   if (values->values->len != other->values->len)
266     result = _gtk_bitmask_invert_range (result, len, MAX (values->values->len, other->values->len));
267   
268   for (i = 0; i < len; i++)
269     {
270       if (!_gtk_css_value_equal (g_ptr_array_index (values->values, i),
271                                  g_ptr_array_index (other->values, i)))
272         result = _gtk_bitmask_set (result, i, TRUE);
273     }
274
275   return result;
276 }
277
278 /* TRANSITIONS */
279
280 typedef struct _TransitionInfo TransitionInfo;
281 struct _TransitionInfo {
282   guint index;                  /* index into value arrays */
283   gboolean pending;             /* TRUE if we still need to handle it */
284 };
285
286 static void
287 transition_info_add (TransitionInfo    infos[GTK_CSS_PROPERTY_N_PROPERTIES],
288                      GtkStyleProperty *property,
289                      guint             index)
290 {
291   if (property == NULL)
292     {
293       guint i;
294
295       for (i = 0; i < _gtk_css_style_property_get_n_properties (); i++)
296         {
297           GtkCssStyleProperty *prop = _gtk_css_style_property_lookup_by_id (i);
298
299           transition_info_add (infos, GTK_STYLE_PROPERTY (prop), index);
300         }
301     }
302   else if (GTK_IS_CSS_SHORTHAND_PROPERTY (property))
303     {
304       GtkCssShorthandProperty *shorthand = GTK_CSS_SHORTHAND_PROPERTY (property);
305       guint i;
306
307       for (i = 0; i < _gtk_css_shorthand_property_get_n_subproperties (shorthand); i++)
308         {
309           GtkCssStyleProperty *prop = _gtk_css_shorthand_property_get_subproperty (shorthand, i);
310
311           transition_info_add (infos, GTK_STYLE_PROPERTY (prop), index);
312         }
313     }
314   else if (GTK_IS_CSS_STYLE_PROPERTY (property))
315     {
316       guint id;
317       
318       if (!_gtk_css_style_property_is_animated (GTK_CSS_STYLE_PROPERTY (property)))
319         return;
320
321       id = _gtk_css_style_property_get_id (GTK_CSS_STYLE_PROPERTY (property));
322       g_assert (id < GTK_CSS_PROPERTY_N_PROPERTIES);
323       infos[id].index = index;
324       infos[id].pending = TRUE;
325     }
326   else
327     {
328       g_assert_not_reached ();
329     }
330 }
331
332 static void
333 transition_infos_set (TransitionInfo  infos[GTK_CSS_PROPERTY_N_PROPERTIES],
334                       GtkCssValue    *transitions)
335 {
336   guint i;
337
338   for (i = 0; i < _gtk_css_array_value_get_n_values (transitions); i++)
339     {
340       GtkStyleProperty *property;
341       GtkCssValue *prop_value;
342
343       prop_value = _gtk_css_array_value_get_nth (transitions, i);
344       if (g_ascii_strcasecmp (_gtk_css_ident_value_get (prop_value), "all") == 0)
345         property = NULL;
346       else
347         {
348           property = _gtk_style_property_lookup (_gtk_css_ident_value_get (prop_value));
349           if (property == NULL)
350             continue;
351         }
352       
353       transition_info_add (infos, property, i);
354     }
355 }
356
357 static GtkStyleAnimation *
358 gtk_css_computed_values_find_transition (GtkCssComputedValues *values,
359                                          guint                 property_id)
360 {
361   GSList *list;
362
363   for (list = values->animations; list; list = list->next)
364     {
365       if (!GTK_IS_CSS_TRANSITION (list->data))
366         continue;
367
368       if (_gtk_css_transition_get_property (list->data) == property_id)
369         return list->data;
370     }
371
372   return NULL;
373 }
374
375 static void
376 gtk_css_computed_values_create_css_transitions (GtkCssComputedValues *values,
377                                                 gint64                timestamp,
378                                                 GtkCssComputedValues *source)
379 {
380   TransitionInfo transitions[GTK_CSS_PROPERTY_N_PROPERTIES] = { { 0, } };
381   GtkCssValue *durations, *delays, *timing_functions;
382   guint i;
383
384   transition_infos_set (transitions, _gtk_css_computed_values_get_value (values, GTK_CSS_PROPERTY_TRANSITION_PROPERTY));
385
386   durations = _gtk_css_computed_values_get_value (values, GTK_CSS_PROPERTY_TRANSITION_DURATION);
387   delays = _gtk_css_computed_values_get_value (values, GTK_CSS_PROPERTY_TRANSITION_DELAY);
388   timing_functions = _gtk_css_computed_values_get_value (values, GTK_CSS_PROPERTY_TRANSITION_TIMING_FUNCTION);
389
390   for (i = 0; i < GTK_CSS_PROPERTY_N_PROPERTIES; i++)
391     {
392       GtkStyleAnimation *animation;
393       GtkCssValue *start, *end;
394       double duration, delay;
395
396       if (!transitions[i].pending)
397         continue;
398
399       duration = _gtk_css_number_value_get (_gtk_css_array_value_get_nth (durations, transitions[i].index), 100);
400       delay = _gtk_css_number_value_get (_gtk_css_array_value_get_nth (delays, transitions[i].index), 100);
401       if (duration + delay == 0.0)
402         continue;
403
404       start = _gtk_css_computed_values_get_intrinsic_value (source, i);
405       end = _gtk_css_computed_values_get_intrinsic_value (values, i);
406       if (_gtk_css_value_equal (start, end))
407         {
408           animation = gtk_css_computed_values_find_transition (GTK_CSS_COMPUTED_VALUES (source), i);
409           if (animation)
410             values->animations = g_slist_prepend (values->animations, g_object_ref (animation));
411         }
412       else
413         {
414           animation = _gtk_css_transition_new (i,
415                                                _gtk_css_computed_values_get_value (source, i),
416                                                _gtk_css_array_value_get_nth (timing_functions, i),
417                                                timestamp + delay * G_USEC_PER_SEC,
418                                                timestamp + (delay + duration) * G_USEC_PER_SEC);
419           values->animations = g_slist_prepend (values->animations, animation);
420         }
421     }
422 }
423
424 static GtkStyleAnimation *
425 gtk_css_computed_values_find_animation (GtkCssComputedValues *values,
426                                         const char           *name)
427 {
428   GSList *list;
429
430   for (list = values->animations; list; list = list->next)
431     {
432       if (!GTK_IS_CSS_ANIMATION (list->data))
433         continue;
434
435       if (g_str_equal (_gtk_css_animation_get_name (list->data), name))
436         return list->data;
437     }
438
439   return NULL;
440 }
441
442 static void
443 gtk_css_computed_values_create_css_animations (GtkCssComputedValues    *values,
444                                                GtkCssComputedValues    *parent_values,
445                                                gint64                   timestamp,
446                                                GtkStyleProviderPrivate *provider,
447                                                GtkCssComputedValues    *source)
448 {
449   GtkCssValue *durations, *delays, *timing_functions, *animations;
450   GtkCssValue *iteration_counts, *directions, *play_states, *fill_modes;
451   guint i;
452
453   animations = _gtk_css_computed_values_get_value (values, GTK_CSS_PROPERTY_ANIMATION_NAME);
454   durations = _gtk_css_computed_values_get_value (values, GTK_CSS_PROPERTY_ANIMATION_DURATION);
455   delays = _gtk_css_computed_values_get_value (values, GTK_CSS_PROPERTY_ANIMATION_DELAY);
456   timing_functions = _gtk_css_computed_values_get_value (values, GTK_CSS_PROPERTY_ANIMATION_TIMING_FUNCTION);
457   iteration_counts = _gtk_css_computed_values_get_value (values, GTK_CSS_PROPERTY_ANIMATION_ITERATION_COUNT);
458   directions = _gtk_css_computed_values_get_value (values, GTK_CSS_PROPERTY_ANIMATION_DIRECTION);
459   play_states = _gtk_css_computed_values_get_value (values, GTK_CSS_PROPERTY_ANIMATION_PLAY_STATE);
460   fill_modes = _gtk_css_computed_values_get_value (values, GTK_CSS_PROPERTY_ANIMATION_FILL_MODE);
461
462   for (i = 0; i < _gtk_css_array_value_get_n_values (animations); i++)
463     {
464       GtkStyleAnimation *animation;
465       GtkCssKeyframes *keyframes;
466       const char *name;
467       
468       name = _gtk_css_ident_value_get (_gtk_css_array_value_get_nth (animations, i));
469       if (g_ascii_strcasecmp (name, "none") == 0)
470         continue;
471
472       animation = gtk_css_computed_values_find_animation (values, name);
473       if (animation)
474         continue;
475
476       if (source)
477         animation = gtk_css_computed_values_find_animation (source, name);
478
479       if (animation)
480         {
481           animation = _gtk_css_animation_copy (GTK_CSS_ANIMATION (animation),
482                                                timestamp,
483                                                _gtk_css_play_state_value_get (_gtk_css_array_value_get_nth (play_states, i)));
484         }
485       else
486         {
487           keyframes = _gtk_style_provider_private_get_keyframes (provider, name);
488           if (keyframes == NULL)
489             continue;
490
491           keyframes = _gtk_css_keyframes_compute (keyframes, provider, values, parent_values);
492
493           animation = _gtk_css_animation_new (name,
494                                               keyframes,
495                                               timestamp,
496                                               _gtk_css_number_value_get (_gtk_css_array_value_get_nth (delays, i), 100) * G_USEC_PER_SEC,
497                                               _gtk_css_number_value_get (_gtk_css_array_value_get_nth (durations, i), 100) * G_USEC_PER_SEC,
498                                               _gtk_css_array_value_get_nth (timing_functions, i),
499                                               _gtk_css_direction_value_get (_gtk_css_array_value_get_nth (directions, i)),
500                                               _gtk_css_play_state_value_get (_gtk_css_array_value_get_nth (play_states, i)),
501                                               _gtk_css_fill_mode_value_get (_gtk_css_array_value_get_nth (fill_modes, i)),
502                                               _gtk_css_number_value_get (_gtk_css_array_value_get_nth (iteration_counts, i), 100));
503           _gtk_css_keyframes_unref (keyframes);
504         }
505       values->animations = g_slist_prepend (values->animations, animation);
506     }
507 }
508
509 /* PUBLIC API */
510
511 void
512 _gtk_css_computed_values_create_animations (GtkCssComputedValues    *values,
513                                             GtkCssComputedValues    *parent_values,
514                                             gint64                   timestamp,
515                                             GtkStyleProviderPrivate *provider,
516                                             GtkCssComputedValues    *source)
517 {
518   if (source != NULL)
519     gtk_css_computed_values_create_css_transitions (values, timestamp, source);
520   gtk_css_computed_values_create_css_animations (values, parent_values, timestamp, provider, source);
521 }
522
523 GtkBitmask *
524 _gtk_css_computed_values_advance (GtkCssComputedValues *values,
525                                   gint64                timestamp)
526 {
527   GtkBitmask *changed;
528   GPtrArray *old_computed_values;
529   GSList *list;
530   guint i;
531
532   gtk_internal_return_val_if_fail (GTK_IS_CSS_COMPUTED_VALUES (values), NULL);
533   gtk_internal_return_val_if_fail (timestamp >= values->current_time, NULL);
534
535   values->current_time = timestamp;
536   old_computed_values = values->animated_values;
537   values->animated_values = NULL;
538
539   list = values->animations;
540   while (list)
541     {
542       GtkStyleAnimation *animation = list->data;
543       
544       list = list->next;
545
546       _gtk_style_animation_set_values (animation,
547                                        timestamp,
548                                        GTK_CSS_COMPUTED_VALUES (values));
549       
550       if (_gtk_style_animation_is_finished (animation, timestamp))
551         {
552           values->animations = g_slist_remove (values->animations, animation);
553           g_object_unref (animation);
554         }
555     }
556
557   /* figure out changes */
558   changed = _gtk_bitmask_new ();
559
560   for (i = 0; i < GTK_CSS_PROPERTY_N_PROPERTIES; i++)
561     {
562       GtkCssValue *old_animated, *new_animated;
563
564       old_animated = old_computed_values && i < old_computed_values->len ? g_ptr_array_index (old_computed_values, i) : NULL;
565       new_animated = values->animated_values && i < values->animated_values->len ? g_ptr_array_index (values->animated_values, i) : NULL;
566
567       if (!_gtk_css_value_equal0 (old_animated, new_animated))
568         changed = _gtk_bitmask_set (changed, i, TRUE);
569     }
570
571   if (old_computed_values)
572     g_ptr_array_unref (old_computed_values);
573
574   return changed;
575 }
576
577 gboolean
578 _gtk_css_computed_values_is_static (GtkCssComputedValues *values)
579 {
580   GSList *list;
581
582   gtk_internal_return_val_if_fail (GTK_IS_CSS_COMPUTED_VALUES (values), TRUE);
583
584   for (list = values->animations; list; list = list->next)
585     {
586       if (!_gtk_style_animation_is_static (list->data, values->current_time))
587         return FALSE;
588     }
589
590   return TRUE;
591 }
592
593 void
594 _gtk_css_computed_values_cancel_animations (GtkCssComputedValues *values)
595 {
596   gtk_internal_return_if_fail (GTK_IS_CSS_COMPUTED_VALUES (values));
597
598   if (values->animated_values)
599     {
600       g_ptr_array_unref (values->animated_values);
601       values->animated_values = NULL;
602     }
603
604   g_slist_free_full (values->animations, g_object_unref);
605   values->animations = NULL;
606 }
607
608 GtkBitmask *
609 _gtk_css_computed_values_compute_dependencies (GtkCssComputedValues *values,
610                                                const GtkBitmask     *parent_changes)
611 {
612   GtkBitmask *changes;
613
614   gtk_internal_return_val_if_fail (GTK_IS_CSS_COMPUTED_VALUES (values), _gtk_bitmask_new ());
615
616   changes = _gtk_bitmask_copy (parent_changes);
617   changes = _gtk_bitmask_intersect (changes, values->depends_on_parent);
618   if (_gtk_bitmask_get (changes, GTK_CSS_PROPERTY_COLOR))
619     changes = _gtk_bitmask_union (changes, values->depends_on_color);
620   if (_gtk_bitmask_get (changes, GTK_CSS_PROPERTY_FONT_SIZE))
621     changes = _gtk_bitmask_union (changes, values->depends_on_font_size);
622
623   return changes;
624 }
625