]> Pileus Git - ~andy/gtk/blob - gtk/gtkcsscomputedvalues.c
stylecontext: Do invalidation on first resize container
[~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_full (_gtk_css_style_property_get_n_properties (),
183                                            (GDestroyNotify)_gtk_css_value_unref);
184   if (id >= values->values->len)
185    g_ptr_array_set_size (values->values, id + 1);
186
187   if (g_ptr_array_index (values->values, id))
188     _gtk_css_value_unref (g_ptr_array_index (values->values, id));
189   g_ptr_array_index (values->values, id) = _gtk_css_value_ref (value);
190
191   if (dependencies & (GTK_CSS_DEPENDS_ON_PARENT | GTK_CSS_EQUALS_PARENT))
192     values->depends_on_parent = _gtk_bitmask_set (values->depends_on_parent, id, TRUE);
193   if (dependencies & (GTK_CSS_EQUALS_PARENT))
194     values->equals_parent = _gtk_bitmask_set (values->equals_parent, id, TRUE);
195   if (dependencies & (GTK_CSS_DEPENDS_ON_COLOR))
196     values->depends_on_color = _gtk_bitmask_set (values->depends_on_color, id, TRUE);
197   if (dependencies & (GTK_CSS_DEPENDS_ON_FONT_SIZE))
198     values->depends_on_font_size = _gtk_bitmask_set (values->depends_on_font_size, id, TRUE);
199
200   if (values->sections && values->sections->len > id && g_ptr_array_index (values->sections, id))
201     {
202       gtk_css_section_unref (g_ptr_array_index (values->sections, id));
203       g_ptr_array_index (values->sections, id) = NULL;
204     }
205
206   if (section)
207     {
208       if (values->sections == NULL)
209         values->sections = g_ptr_array_new_with_free_func (maybe_unref_section);
210       if (values->sections->len <= id)
211         g_ptr_array_set_size (values->sections, id + 1);
212
213       g_ptr_array_index (values->sections, id) = gtk_css_section_ref (section);
214     }
215 }
216
217 GtkCssValue *
218 _gtk_css_computed_values_get_value (GtkCssComputedValues *values,
219                                     guint                 id)
220 {
221   gtk_internal_return_val_if_fail (GTK_IS_CSS_COMPUTED_VALUES (values), NULL);
222
223   if (values->animated_values &&
224       id < values->animated_values->len &&
225       g_ptr_array_index (values->animated_values, id))
226     return g_ptr_array_index (values->animated_values, id);
227
228   return _gtk_css_computed_values_get_intrinsic_value (values, id);
229 }
230
231 GtkCssValue *
232 _gtk_css_computed_values_get_intrinsic_value (GtkCssComputedValues *values,
233                                               guint                 id)
234 {
235   gtk_internal_return_val_if_fail (GTK_IS_CSS_COMPUTED_VALUES (values), NULL);
236
237   if (values->values == NULL ||
238       id >= values->values->len)
239     return NULL;
240
241   return g_ptr_array_index (values->values, id);
242 }
243
244 GtkCssSection *
245 _gtk_css_computed_values_get_section (GtkCssComputedValues *values,
246                                       guint                 id)
247 {
248   gtk_internal_return_val_if_fail (GTK_IS_CSS_COMPUTED_VALUES (values), NULL);
249
250   if (values->sections == NULL ||
251       id >= values->sections->len)
252     return NULL;
253
254   return g_ptr_array_index (values->sections, id);
255 }
256
257 GtkBitmask *
258 _gtk_css_computed_values_get_difference (GtkCssComputedValues *values,
259                                          GtkCssComputedValues *other)
260 {
261   GtkBitmask *result;
262   guint i, len;
263
264   len = MIN (values->values->len, other->values->len);
265   result = _gtk_bitmask_new ();
266   if (values->values->len != other->values->len)
267     result = _gtk_bitmask_invert_range (result, len, MAX (values->values->len, other->values->len));
268   
269   for (i = 0; i < len; i++)
270     {
271       if (!_gtk_css_value_equal (g_ptr_array_index (values->values, i),
272                                  g_ptr_array_index (other->values, i)))
273         result = _gtk_bitmask_set (result, i, TRUE);
274     }
275
276   return result;
277 }
278
279 /* TRANSITIONS */
280
281 typedef struct _TransitionInfo TransitionInfo;
282 struct _TransitionInfo {
283   guint index;                  /* index into value arrays */
284   gboolean pending;             /* TRUE if we still need to handle it */
285 };
286
287 static void
288 transition_info_add (TransitionInfo    infos[GTK_CSS_PROPERTY_N_PROPERTIES],
289                      GtkStyleProperty *property,
290                      guint             index)
291 {
292   if (property == NULL)
293     {
294       guint i;
295
296       for (i = 0; i < _gtk_css_style_property_get_n_properties (); i++)
297         {
298           GtkCssStyleProperty *prop = _gtk_css_style_property_lookup_by_id (i);
299
300           transition_info_add (infos, GTK_STYLE_PROPERTY (prop), index);
301         }
302     }
303   else if (GTK_IS_CSS_SHORTHAND_PROPERTY (property))
304     {
305       GtkCssShorthandProperty *shorthand = GTK_CSS_SHORTHAND_PROPERTY (property);
306       guint i;
307
308       for (i = 0; i < _gtk_css_shorthand_property_get_n_subproperties (shorthand); i++)
309         {
310           GtkCssStyleProperty *prop = _gtk_css_shorthand_property_get_subproperty (shorthand, i);
311
312           transition_info_add (infos, GTK_STYLE_PROPERTY (prop), index);
313         }
314     }
315   else if (GTK_IS_CSS_STYLE_PROPERTY (property))
316     {
317       guint id;
318       
319       if (!_gtk_css_style_property_is_animated (GTK_CSS_STYLE_PROPERTY (property)))
320         return;
321
322       id = _gtk_css_style_property_get_id (GTK_CSS_STYLE_PROPERTY (property));
323       g_assert (id < GTK_CSS_PROPERTY_N_PROPERTIES);
324       infos[id].index = index;
325       infos[id].pending = TRUE;
326     }
327   else
328     {
329       g_assert_not_reached ();
330     }
331 }
332
333 static void
334 transition_infos_set (TransitionInfo  infos[GTK_CSS_PROPERTY_N_PROPERTIES],
335                       GtkCssValue    *transitions)
336 {
337   guint i;
338
339   for (i = 0; i < _gtk_css_array_value_get_n_values (transitions); i++)
340     {
341       GtkStyleProperty *property;
342       GtkCssValue *prop_value;
343
344       prop_value = _gtk_css_array_value_get_nth (transitions, i);
345       if (g_ascii_strcasecmp (_gtk_css_ident_value_get (prop_value), "all") == 0)
346         property = NULL;
347       else
348         {
349           property = _gtk_style_property_lookup (_gtk_css_ident_value_get (prop_value));
350           if (property == NULL)
351             continue;
352         }
353       
354       transition_info_add (infos, property, i);
355     }
356 }
357
358 static GtkStyleAnimation *
359 gtk_css_computed_values_find_transition (GtkCssComputedValues *values,
360                                          guint                 property_id)
361 {
362   GSList *list;
363
364   for (list = values->animations; list; list = list->next)
365     {
366       if (!GTK_IS_CSS_TRANSITION (list->data))
367         continue;
368
369       if (_gtk_css_transition_get_property (list->data) == property_id)
370         return list->data;
371     }
372
373   return NULL;
374 }
375
376 static void
377 gtk_css_computed_values_create_css_transitions (GtkCssComputedValues *values,
378                                                 gint64                timestamp,
379                                                 GtkCssComputedValues *source)
380 {
381   TransitionInfo transitions[GTK_CSS_PROPERTY_N_PROPERTIES] = { { 0, } };
382   GtkCssValue *durations, *delays, *timing_functions;
383   guint i;
384
385   transition_infos_set (transitions, _gtk_css_computed_values_get_value (values, GTK_CSS_PROPERTY_TRANSITION_PROPERTY));
386
387   durations = _gtk_css_computed_values_get_value (values, GTK_CSS_PROPERTY_TRANSITION_DURATION);
388   delays = _gtk_css_computed_values_get_value (values, GTK_CSS_PROPERTY_TRANSITION_DELAY);
389   timing_functions = _gtk_css_computed_values_get_value (values, GTK_CSS_PROPERTY_TRANSITION_TIMING_FUNCTION);
390
391   for (i = 0; i < GTK_CSS_PROPERTY_N_PROPERTIES; i++)
392     {
393       GtkStyleAnimation *animation;
394       GtkCssValue *start, *end;
395       double duration, delay;
396
397       if (!transitions[i].pending)
398         continue;
399
400       duration = _gtk_css_number_value_get (_gtk_css_array_value_get_nth (durations, transitions[i].index), 100);
401       delay = _gtk_css_number_value_get (_gtk_css_array_value_get_nth (delays, transitions[i].index), 100);
402       if (duration + delay == 0.0)
403         continue;
404
405       start = _gtk_css_computed_values_get_intrinsic_value (source, i);
406       end = _gtk_css_computed_values_get_intrinsic_value (values, i);
407       if (_gtk_css_value_equal (start, end))
408         {
409           animation = gtk_css_computed_values_find_transition (GTK_CSS_COMPUTED_VALUES (source), i);
410           if (animation)
411             values->animations = g_slist_prepend (values->animations, g_object_ref (animation));
412         }
413       else
414         {
415           animation = _gtk_css_transition_new (i,
416                                                _gtk_css_computed_values_get_value (source, i),
417                                                _gtk_css_array_value_get_nth (timing_functions, i),
418                                                timestamp + delay * G_USEC_PER_SEC,
419                                                timestamp + (delay + duration) * G_USEC_PER_SEC);
420           values->animations = g_slist_prepend (values->animations, animation);
421         }
422     }
423 }
424
425 static GtkStyleAnimation *
426 gtk_css_computed_values_find_animation (GtkCssComputedValues *values,
427                                         const char           *name)
428 {
429   GSList *list;
430
431   for (list = values->animations; list; list = list->next)
432     {
433       if (!GTK_IS_CSS_ANIMATION (list->data))
434         continue;
435
436       if (g_str_equal (_gtk_css_animation_get_name (list->data), name))
437         return list->data;
438     }
439
440   return NULL;
441 }
442
443 static void
444 gtk_css_computed_values_create_css_animations (GtkCssComputedValues    *values,
445                                                GtkCssComputedValues    *parent_values,
446                                                gint64                   timestamp,
447                                                GtkStyleProviderPrivate *provider,
448                                                GtkCssComputedValues    *source)
449 {
450   GtkCssValue *durations, *delays, *timing_functions, *animations;
451   GtkCssValue *iteration_counts, *directions, *play_states, *fill_modes;
452   guint i;
453
454   animations = _gtk_css_computed_values_get_value (values, GTK_CSS_PROPERTY_ANIMATION_NAME);
455   durations = _gtk_css_computed_values_get_value (values, GTK_CSS_PROPERTY_ANIMATION_DURATION);
456   delays = _gtk_css_computed_values_get_value (values, GTK_CSS_PROPERTY_ANIMATION_DELAY);
457   timing_functions = _gtk_css_computed_values_get_value (values, GTK_CSS_PROPERTY_ANIMATION_TIMING_FUNCTION);
458   iteration_counts = _gtk_css_computed_values_get_value (values, GTK_CSS_PROPERTY_ANIMATION_ITERATION_COUNT);
459   directions = _gtk_css_computed_values_get_value (values, GTK_CSS_PROPERTY_ANIMATION_DIRECTION);
460   play_states = _gtk_css_computed_values_get_value (values, GTK_CSS_PROPERTY_ANIMATION_PLAY_STATE);
461   fill_modes = _gtk_css_computed_values_get_value (values, GTK_CSS_PROPERTY_ANIMATION_FILL_MODE);
462
463   for (i = 0; i < _gtk_css_array_value_get_n_values (animations); i++)
464     {
465       GtkStyleAnimation *animation;
466       GtkCssKeyframes *keyframes;
467       const char *name;
468       
469       name = _gtk_css_ident_value_get (_gtk_css_array_value_get_nth (animations, i));
470       if (g_ascii_strcasecmp (name, "none") == 0)
471         continue;
472
473       animation = gtk_css_computed_values_find_animation (values, name);
474       if (animation)
475         continue;
476
477       if (source)
478         animation = gtk_css_computed_values_find_animation (source, name);
479
480       if (animation)
481         {
482           animation = _gtk_css_animation_copy (GTK_CSS_ANIMATION (animation),
483                                                timestamp,
484                                                _gtk_css_play_state_value_get (_gtk_css_array_value_get_nth (play_states, i)));
485         }
486       else
487         {
488           keyframes = _gtk_style_provider_private_get_keyframes (provider, name);
489           if (keyframes == NULL)
490             continue;
491
492           keyframes = _gtk_css_keyframes_compute (keyframes, provider, values, parent_values);
493
494           animation = _gtk_css_animation_new (name,
495                                               keyframes,
496                                               timestamp,
497                                               _gtk_css_number_value_get (_gtk_css_array_value_get_nth (delays, i), 100) * G_USEC_PER_SEC,
498                                               _gtk_css_number_value_get (_gtk_css_array_value_get_nth (durations, i), 100) * G_USEC_PER_SEC,
499                                               _gtk_css_array_value_get_nth (timing_functions, i),
500                                               _gtk_css_direction_value_get (_gtk_css_array_value_get_nth (directions, i)),
501                                               _gtk_css_play_state_value_get (_gtk_css_array_value_get_nth (play_states, i)),
502                                               _gtk_css_fill_mode_value_get (_gtk_css_array_value_get_nth (fill_modes, i)),
503                                               _gtk_css_number_value_get (_gtk_css_array_value_get_nth (iteration_counts, i), 100));
504           _gtk_css_keyframes_unref (keyframes);
505         }
506       values->animations = g_slist_prepend (values->animations, animation);
507     }
508 }
509
510 /* PUBLIC API */
511
512 void
513 _gtk_css_computed_values_create_animations (GtkCssComputedValues    *values,
514                                             GtkCssComputedValues    *parent_values,
515                                             gint64                   timestamp,
516                                             GtkStyleProviderPrivate *provider,
517                                             GtkCssComputedValues    *source)
518 {
519   if (source != NULL)
520     gtk_css_computed_values_create_css_transitions (values, timestamp, source);
521   gtk_css_computed_values_create_css_animations (values, parent_values, timestamp, provider, source);
522 }
523
524 GtkBitmask *
525 _gtk_css_computed_values_advance (GtkCssComputedValues *values,
526                                   gint64                timestamp)
527 {
528   GtkBitmask *changed;
529   GPtrArray *old_computed_values;
530   GSList *list;
531   guint i;
532
533   gtk_internal_return_val_if_fail (GTK_IS_CSS_COMPUTED_VALUES (values), NULL);
534   gtk_internal_return_val_if_fail (timestamp >= values->current_time, NULL);
535
536   values->current_time = timestamp;
537   old_computed_values = values->animated_values;
538   values->animated_values = NULL;
539
540   list = values->animations;
541   while (list)
542     {
543       GtkStyleAnimation *animation = list->data;
544       
545       list = list->next;
546
547       _gtk_style_animation_set_values (animation,
548                                        timestamp,
549                                        GTK_CSS_COMPUTED_VALUES (values));
550       
551       if (_gtk_style_animation_is_finished (animation, timestamp))
552         {
553           values->animations = g_slist_remove (values->animations, animation);
554           g_object_unref (animation);
555         }
556     }
557
558   /* figure out changes */
559   changed = _gtk_bitmask_new ();
560
561   for (i = 0; i < GTK_CSS_PROPERTY_N_PROPERTIES; i++)
562     {
563       GtkCssValue *old_animated, *new_animated;
564
565       old_animated = old_computed_values && i < old_computed_values->len ? g_ptr_array_index (old_computed_values, i) : NULL;
566       new_animated = values->animated_values && i < values->animated_values->len ? g_ptr_array_index (values->animated_values, i) : NULL;
567
568       if (!_gtk_css_value_equal0 (old_animated, new_animated))
569         changed = _gtk_bitmask_set (changed, i, TRUE);
570     }
571
572   if (old_computed_values)
573     g_ptr_array_unref (old_computed_values);
574
575   return changed;
576 }
577
578 gboolean
579 _gtk_css_computed_values_is_static (GtkCssComputedValues *values)
580 {
581   GSList *list;
582
583   gtk_internal_return_val_if_fail (GTK_IS_CSS_COMPUTED_VALUES (values), TRUE);
584
585   for (list = values->animations; list; list = list->next)
586     {
587       if (!_gtk_style_animation_is_static (list->data, values->current_time))
588         return FALSE;
589     }
590
591   return TRUE;
592 }
593
594 void
595 _gtk_css_computed_values_cancel_animations (GtkCssComputedValues *values)
596 {
597   gtk_internal_return_if_fail (GTK_IS_CSS_COMPUTED_VALUES (values));
598
599   if (values->animated_values)
600     {
601       g_ptr_array_unref (values->animated_values);
602       values->animated_values = NULL;
603     }
604
605   g_slist_free_full (values->animations, g_object_unref);
606   values->animations = NULL;
607 }
608
609 GtkBitmask *
610 _gtk_css_computed_values_compute_dependencies (GtkCssComputedValues *values,
611                                                const GtkBitmask     *parent_changes)
612 {
613   GtkBitmask *changes;
614
615   gtk_internal_return_val_if_fail (GTK_IS_CSS_COMPUTED_VALUES (values), _gtk_bitmask_new ());
616
617   changes = _gtk_bitmask_copy (parent_changes);
618   changes = _gtk_bitmask_intersect (changes, values->depends_on_parent);
619   if (_gtk_bitmask_get (changes, GTK_CSS_PROPERTY_COLOR))
620     changes = _gtk_bitmask_union (changes, values->depends_on_color);
621   if (_gtk_bitmask_get (changes, GTK_CSS_PROPERTY_FONT_SIZE))
622     changes = _gtk_bitmask_union (changes, values->depends_on_font_size);
623
624   return changes;
625 }
626