1 /* GTK - The GIMP Toolkit
2 * Copyright (C) 2010 Carlos Garnacho <carlosg@gnome.org>
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.
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.
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/>.
20 #include "gtkstylepropertyprivate.h"
22 #include <gobject/gvaluecollector.h>
23 #include <gdk-pixbuf/gdk-pixbuf.h>
24 #include <cairo-gobject.h>
27 #include "gtkcssparserprivate.h"
28 #include "gtkcssstylefuncsprivate.h"
29 #include "gtkcssstylepropertyprivate.h"
30 #include "gtkcsstypesprivate.h"
32 #include "gtkprivatetypebuiltins.h"
33 #include "gtkstylepropertiesprivate.h"
35 /* this is in case round() is not provided by the compiler,
36 * such as in the case of C89 compilers, like MSVC
38 #include "fallback-c89.c"
40 /* the actual parsers we have */
41 #include "gtkanimationdescription.h"
42 #include "gtkbindings.h"
43 #include "gtkcssimageprivate.h"
44 #include "gtkgradient.h"
45 #include "gtkshadowprivate.h"
46 #include "gtksymboliccolorprivate.h"
47 #include "gtkthemingengine.h"
48 #include "gtktypebuiltins.h"
49 #include "gtkwin32themeprivate.h"
51 /*** REGISTRATION ***/
54 gtk_css_style_property_register (const char * name,
58 GtkStylePropertyFlags flags,
59 GtkCssStylePropertyParseFunc parse_value,
60 GtkCssStylePropertyPrintFunc print_value,
61 GtkCssStylePropertyComputeFunc compute_value,
62 GtkCssStylePropertyEqualFunc equal_func,
63 GtkCssValue * initial_value)
65 GtkCssStyleProperty *node;
67 g_assert (initial_value != NULL);
69 node = g_object_new (GTK_TYPE_CSS_STYLE_PROPERTY,
70 "value-type", value_type,
71 "computed-type", computed_type,
72 "inherit", (flags & GTK_STYLE_PROPERTY_INHERIT) ? TRUE : FALSE,
73 "initial-value", initial_value,
78 node->parse_value = parse_value;
80 node->print_value = print_value;
82 node->compute_value = compute_value;
84 node->equal_func = equal_func;
86 _gtk_css_value_unref (initial_value);
92 string_append_string (GString *str,
97 g_string_append_c (str, '"');
100 len = strcspn (string, "\"\n\r\f");
101 g_string_append (str, string);
108 g_string_append (str, "\\A ");
111 g_string_append (str, "\\D ");
114 g_string_append (str, "\\C ");
117 g_string_append (str, "\\\"");
120 g_assert_not_reached ();
125 g_string_append_c (str, '"');
128 /*** IMPLEMENTATIONS ***/
131 color_parse (GtkCssStyleProperty *property,
132 GtkCssParser *parser,
135 GtkSymbolicColor *symbolic;
137 if (_gtk_css_parser_try (parser, "currentcolor", TRUE))
139 symbolic = gtk_symbolic_color_ref (_gtk_symbolic_color_get_current_color ());
143 symbolic = _gtk_css_parser_read_symbolic_color (parser);
144 if (symbolic == NULL)
148 return _gtk_css_value_new_take_symbolic_color (symbolic);
152 color_compute (GtkCssStyleProperty *property,
153 GtkStyleContext *context,
154 GtkCssValue *specified)
156 GtkSymbolicColor *symbolic = _gtk_css_value_get_symbolic_color (specified);
157 GtkCssValue *resolved;
159 if (symbolic == _gtk_symbolic_color_get_current_color ())
161 /* The computed value of the ‘currentColor’ keyword is the computed
162 * value of the ‘color’ property. If the ‘currentColor’ keyword is
163 * set on the ‘color’ property itself, it is treated as ‘color: inherit’.
165 if (g_str_equal (_gtk_style_property_get_name (GTK_STYLE_PROPERTY (property)), "color"))
167 GtkStyleContext *parent = gtk_style_context_get_parent (context);
170 return _gtk_css_value_ref (_gtk_style_context_peek_property (parent, "color"));
172 return _gtk_css_style_compute_value (context,
174 _gtk_css_style_property_get_initial_value (property));
178 return _gtk_css_value_ref (_gtk_style_context_peek_property (context, "color"));
181 else if ((resolved = _gtk_style_context_resolve_color_value (context,
188 return color_compute (property,
190 _gtk_css_style_property_get_initial_value (property));
195 font_family_parse (GtkCssStyleProperty *property,
196 GtkCssParser *parser,
202 /* We don't special case generic families. Pango should do
205 names = g_ptr_array_new ();
208 name = _gtk_css_parser_try_ident (parser, TRUE);
211 GString *string = g_string_new (name);
213 while ((name = _gtk_css_parser_try_ident (parser, TRUE)))
215 g_string_append_c (string, ' ');
216 g_string_append (string, name);
219 name = g_string_free (string, FALSE);
223 name = _gtk_css_parser_read_string (parser);
226 g_ptr_array_free (names, TRUE);
231 g_ptr_array_add (names, name);
232 } while (_gtk_css_parser_try (parser, ",", TRUE));
234 /* NULL-terminate array */
235 g_ptr_array_add (names, NULL);
236 return _gtk_css_value_new_take_strv ((char **) g_ptr_array_free (names, FALSE));
240 font_family_value_print (GtkCssStyleProperty *property,
241 const GtkCssValue *value,
244 const char **names = _gtk_css_value_get_strv (value);
246 if (names == NULL || *names == NULL)
248 g_string_append (string, "none");
252 string_append_string (string, *names);
256 g_string_append (string, ", ");
257 string_append_string (string, *names);
263 bindings_value_parse (GtkCssStyleProperty *property,
264 GtkCssParser *parser,
268 GtkBindingSet *binding_set;
271 array = g_ptr_array_new ();
274 name = _gtk_css_parser_try_ident (parser, TRUE);
277 _gtk_css_parser_error (parser, "Not a valid binding name");
278 g_ptr_array_free (array, TRUE);
282 binding_set = gtk_binding_set_find (name);
286 _gtk_css_parser_error (parser, "No binding set named '%s'", name);
291 g_ptr_array_add (array, binding_set);
294 while (_gtk_css_parser_try (parser, ",", TRUE));
296 return _gtk_css_value_new_take_binding_sets (array);
300 bindings_value_print (GtkCssStyleProperty *property,
301 const GtkCssValue *value,
307 array = _gtk_css_value_get_boxed (value);
309 for (i = 0; i < array->len; i++)
311 GtkBindingSet *binding_set = g_ptr_array_index (array, i);
314 g_string_append (string, ", ");
315 g_string_append (string, binding_set->set_name);
320 border_corner_radius_value_parse (GtkCssStyleProperty *property,
321 GtkCssParser *parser,
324 GtkCssBorderCornerRadius corner;
326 if (!_gtk_css_parser_read_number (parser,
328 GTK_CSS_POSITIVE_ONLY
329 | GTK_CSS_PARSE_PERCENT
330 | GTK_CSS_NUMBER_AS_PIXELS
331 | GTK_CSS_PARSE_LENGTH))
334 if (!_gtk_css_parser_has_number (parser))
335 corner.vertical = corner.horizontal;
336 else if (!_gtk_css_parser_read_number (parser,
338 GTK_CSS_POSITIVE_ONLY
339 | GTK_CSS_PARSE_PERCENT
340 | GTK_CSS_NUMBER_AS_PIXELS
341 | GTK_CSS_PARSE_LENGTH))
344 return _gtk_css_value_new_from_border_corner_radius (&corner);
348 border_corner_radius_value_print (GtkCssStyleProperty *property,
349 const GtkCssValue *value,
352 const GtkCssBorderCornerRadius *corner;
354 corner = _gtk_css_value_get_border_corner_radius (value);
356 _gtk_css_number_print (&corner->horizontal, string);
358 if (!_gtk_css_number_equal (&corner->horizontal, &corner->vertical))
360 g_string_append_c (string, ' ');
361 _gtk_css_number_print (&corner->vertical, string);
366 css_image_value_parse (GtkCssStyleProperty *property,
367 GtkCssParser *parser,
372 if (_gtk_css_parser_try (parser, "none", TRUE))
376 image = _gtk_css_image_new_parse (parser, base);
381 return _gtk_css_value_new_take_image (image);
385 css_image_value_print (GtkCssStyleProperty *property,
386 const GtkCssValue *value,
389 GtkCssImage *image = _gtk_css_value_get_image (value);
392 _gtk_css_image_print (image, string);
394 g_string_append (string, "none");
398 css_image_value_compute (GtkCssStyleProperty *property,
399 GtkStyleContext *context,
400 GtkCssValue *specified)
402 GtkCssImage *image, *computed;
404 image = _gtk_css_value_get_image (specified);
407 return _gtk_css_value_ref (specified);
409 computed = _gtk_css_image_compute (image, context);
411 if (computed == image)
413 g_object_unref (computed);
414 return _gtk_css_value_ref (specified);
417 return _gtk_css_value_new_take_image (computed);
421 parse_margin (GtkCssStyleProperty *property,
422 GtkCssParser *parser,
427 if (!_gtk_css_parser_read_number (parser,
429 GTK_CSS_NUMBER_AS_PIXELS
430 | GTK_CSS_PARSE_LENGTH))
433 return _gtk_css_value_new_from_number (&number);
437 compute_margin (GtkCssStyleProperty *property,
438 GtkStyleContext *context,
439 GtkCssValue *specified)
443 if (_gtk_css_number_compute (&number,
444 _gtk_css_value_get_number (specified),
447 return _gtk_css_value_new_from_number (&number);
449 return _gtk_css_value_ref (specified);
453 parse_padding (GtkCssStyleProperty *property,
454 GtkCssParser *parser,
459 if (!_gtk_css_parser_read_number (parser,
461 GTK_CSS_POSITIVE_ONLY
462 | GTK_CSS_NUMBER_AS_PIXELS
463 | GTK_CSS_PARSE_LENGTH))
466 return _gtk_css_value_new_from_number (&number);
470 compute_padding (GtkCssStyleProperty *property,
471 GtkStyleContext *context,
472 GtkCssValue *specified)
476 if (_gtk_css_number_compute (&number,
477 _gtk_css_value_get_number (specified),
479 return _gtk_css_value_new_from_number (&number);
480 return _gtk_css_value_ref (specified);
484 parse_border_width (GtkCssStyleProperty *property,
485 GtkCssParser *parser,
490 if (!_gtk_css_parser_read_number (parser,
492 GTK_CSS_POSITIVE_ONLY
493 | GTK_CSS_NUMBER_AS_PIXELS
494 | GTK_CSS_PARSE_LENGTH))
497 return _gtk_css_value_new_from_number (&number);
501 compute_border_width (GtkCssStyleProperty *property,
502 GtkStyleContext *context,
503 GtkCssValue *specified)
505 GtkCssStyleProperty *style;
506 GtkBorderStyle border_style;
510 /* The -1 is magic that is only true because we register the style
511 * properties directly after the width properties.
513 style = _gtk_css_style_property_lookup_by_id (_gtk_css_style_property_get_id (property) - 1);
515 border_style = _gtk_css_value_get_border_style (_gtk_style_context_peek_property (context, _gtk_style_property_get_name (GTK_STYLE_PROPERTY (style))));
517 if (border_style == GTK_BORDER_STYLE_NONE ||
518 border_style == GTK_BORDER_STYLE_HIDDEN)
524 _gtk_css_number_compute (&number,
525 _gtk_css_value_get_number (specified),
527 value = round (number.value);
529 return _gtk_css_value_new_from_int (value);
533 background_repeat_value_parse (GtkCssStyleProperty *property,
534 GtkCssParser *parser,
537 int repeat, vertical;
539 if (!_gtk_css_parser_try_enum (parser, GTK_TYPE_CSS_BACKGROUND_REPEAT, &repeat))
541 _gtk_css_parser_error (parser, "Not a valid value");
545 if (repeat <= GTK_CSS_BACKGROUND_REPEAT_MASK)
547 if (_gtk_css_parser_try_enum (parser, GTK_TYPE_CSS_BACKGROUND_REPEAT, &vertical))
549 if (vertical >= GTK_CSS_BACKGROUND_REPEAT_MASK)
551 _gtk_css_parser_error (parser, "Not a valid 2nd value");
555 repeat |= vertical << GTK_CSS_BACKGROUND_REPEAT_SHIFT;
558 repeat |= repeat << GTK_CSS_BACKGROUND_REPEAT_SHIFT;
561 return _gtk_css_value_new_from_enum (GTK_TYPE_CSS_BACKGROUND_REPEAT, repeat);
565 background_repeat_value_print (GtkCssStyleProperty *property,
566 const GtkCssValue *value,
569 GEnumClass *enum_class;
570 GEnumValue *enum_value;
571 GtkCssBackgroundRepeat repeat;
573 repeat = _gtk_css_value_get_enum (value);
574 enum_class = g_type_class_ref (GTK_TYPE_CSS_BACKGROUND_REPEAT);
575 enum_value = g_enum_get_value (enum_class, repeat);
577 /* only triggers for 'repeat-x' and 'repeat-y' */
579 g_string_append (string, enum_value->value_nick);
582 enum_value = g_enum_get_value (enum_class, GTK_CSS_BACKGROUND_HORIZONTAL (repeat));
583 g_string_append (string, enum_value->value_nick);
585 if (GTK_CSS_BACKGROUND_HORIZONTAL (repeat) != GTK_CSS_BACKGROUND_VERTICAL (repeat))
587 enum_value = g_enum_get_value (enum_class, GTK_CSS_BACKGROUND_VERTICAL (repeat));
588 g_string_append (string, " ");
589 g_string_append (string, enum_value->value_nick);
593 g_type_class_unref (enum_class);
597 background_size_parse (GtkCssStyleProperty *property,
598 GtkCssParser *parser,
601 GtkCssBackgroundSize size = { GTK_CSS_NUMBER_INIT (0, GTK_CSS_PX), GTK_CSS_NUMBER_INIT (0, GTK_CSS_PX), FALSE, FALSE};
603 if (_gtk_css_parser_try (parser, "cover", TRUE))
605 else if (_gtk_css_parser_try (parser, "contain", TRUE))
609 if (_gtk_css_parser_try (parser, "auto", TRUE))
610 _gtk_css_number_init (&size.width, 0, GTK_CSS_PX);
611 else if (!_gtk_css_parser_read_number (parser,
613 GTK_CSS_POSITIVE_ONLY
614 | GTK_CSS_PARSE_PERCENT
615 | GTK_CSS_PARSE_LENGTH))
618 if (_gtk_css_parser_try (parser, "auto", TRUE))
619 _gtk_css_number_init (&size.height, 0, GTK_CSS_PX);
620 else if (_gtk_css_parser_has_number (parser))
622 if (!_gtk_css_parser_read_number (parser,
624 GTK_CSS_POSITIVE_ONLY
625 | GTK_CSS_PARSE_PERCENT
626 | GTK_CSS_PARSE_LENGTH))
630 _gtk_css_number_init (&size.height, 0, GTK_CSS_PX);
633 return _gtk_css_value_new_from_background_size (&size);
637 background_size_print (GtkCssStyleProperty *property,
638 const GtkCssValue *value,
641 const GtkCssBackgroundSize *size = _gtk_css_value_get_background_size (value);
644 g_string_append (string, "cover");
645 else if (size->contain)
646 g_string_append (string, "contain");
649 if (size->width.value == 0)
650 g_string_append (string, "auto");
652 _gtk_css_number_print (&size->width, string);
654 if (size->height.value != 0)
656 g_string_append (string, " ");
657 _gtk_css_number_print (&size->height, string);
663 background_size_compute (GtkCssStyleProperty *property,
664 GtkStyleContext *context,
665 GtkCssValue *specified)
667 const GtkCssBackgroundSize *ssize = _gtk_css_value_get_background_size (specified);
668 GtkCssBackgroundSize csize;
671 csize.cover = ssize->cover;
672 csize.contain = ssize->contain;
673 changed = _gtk_css_number_compute (&csize.width,
676 changed |= _gtk_css_number_compute (&csize.height,
680 return _gtk_css_value_new_from_background_size (&csize);
681 return _gtk_css_value_ref (specified);
685 background_position_parse (GtkCssStyleProperty *property,
686 GtkCssParser *parser,
689 static const struct {
695 { "left", 0, TRUE, FALSE },
696 { "right", 100, TRUE, FALSE },
697 { "center", 50, TRUE, TRUE },
698 { "top", 0, FALSE, TRUE },
699 { "bottom", 100, FALSE, TRUE },
700 { NULL , 0, TRUE, FALSE }, /* used for numbers */
701 { NULL , 50, TRUE, TRUE } /* used for no value */
703 GtkCssBackgroundPosition pos;
704 GtkCssNumber *missing;
707 for (first = 0; names[first].name != NULL; first++)
709 if (_gtk_css_parser_try (parser, names[first].name, TRUE))
711 if (names[first].horizontal)
713 _gtk_css_number_init (&pos.x, names[first].percentage, GTK_CSS_PERCENT);
718 _gtk_css_number_init (&pos.y, names[first].percentage, GTK_CSS_PERCENT);
724 if (names[first].name == NULL)
727 if (!_gtk_css_parser_read_number (parser,
729 GTK_CSS_PARSE_PERCENT
730 | GTK_CSS_PARSE_LENGTH))
734 for (second = 0; names[second].name != NULL; second++)
736 if (_gtk_css_parser_try (parser, names[second].name, TRUE))
738 _gtk_css_number_init (missing, names[second].percentage, GTK_CSS_PERCENT);
743 if (names[second].name == NULL)
745 if (_gtk_css_parser_has_number (parser))
747 if (missing != &pos.y)
749 _gtk_css_parser_error (parser, "Invalid combination of values");
752 if (!_gtk_css_parser_read_number (parser,
754 GTK_CSS_PARSE_PERCENT
755 | GTK_CSS_PARSE_LENGTH))
761 _gtk_css_number_init (missing, 50, GTK_CSS_PERCENT);
766 if ((names[first].horizontal && !names[second].vertical) ||
767 (!names[first].horizontal && !names[second].horizontal))
769 _gtk_css_parser_error (parser, "Invalid combination of values");
774 return _gtk_css_value_new_from_background_position (&pos);
778 background_position_print (GtkCssStyleProperty *property,
779 const GtkCssValue *value,
782 const GtkCssBackgroundPosition *pos = _gtk_css_value_get_background_position (value);
783 static const GtkCssNumber center = GTK_CSS_NUMBER_INIT (50, GTK_CSS_PERCENT);
784 static const struct {
789 { "left", "top", GTK_CSS_NUMBER_INIT (0, GTK_CSS_PERCENT) },
790 { "right", "bottom", GTK_CSS_NUMBER_INIT (100, GTK_CSS_PERCENT) }
794 if (_gtk_css_number_equal (&pos->x, ¢er))
796 if (_gtk_css_number_equal (&pos->y, ¢er))
798 g_string_append (string, "center");
804 for (i = 0; i < G_N_ELEMENTS (values); i++)
806 if (_gtk_css_number_equal (&pos->x, &values[i].number))
808 g_string_append (string, values[i].x_name);
812 if (i == G_N_ELEMENTS (values))
813 _gtk_css_number_print (&pos->x, string);
815 if (_gtk_css_number_equal (&pos->y, ¢er))
818 g_string_append_c (string, ' ');
821 for (i = 0; i < G_N_ELEMENTS (values); i++)
823 if (_gtk_css_number_equal (&pos->y, &values[i].number))
825 g_string_append (string, values[i].y_name);
829 if (i == G_N_ELEMENTS (values))
831 if (_gtk_css_number_equal (&pos->x, ¢er))
832 g_string_append (string, "center ");
833 _gtk_css_number_print (&pos->y, string);
838 background_position_compute (GtkCssStyleProperty *property,
839 GtkStyleContext *context,
840 GtkCssValue *specified)
842 const GtkCssBackgroundPosition *spos = _gtk_css_value_get_background_position (specified);
843 GtkCssBackgroundPosition cpos;
846 changed = _gtk_css_number_compute (&cpos.x,
849 changed |= _gtk_css_number_compute (&cpos.y,
853 return _gtk_css_value_new_from_background_position (&cpos);
854 return _gtk_css_value_ref (specified);
857 /*** REGISTRATION ***/
859 static GtkSymbolicColor *
860 gtk_symbolic_color_new_rgba (double red,
865 GdkRGBA rgba = { red, green, blue, alpha };
867 return gtk_symbolic_color_new_literal (&rgba);
871 _gtk_css_style_property_init_properties (void)
873 char *default_font_family[] = { "Sans", NULL };
875 GtkCssBackgroundSize default_background_size = { GTK_CSS_NUMBER_INIT (0, GTK_CSS_PX), GTK_CSS_NUMBER_INIT (0, GTK_CSS_PX), FALSE, FALSE };
876 GtkCssBackgroundPosition default_background_position = { GTK_CSS_NUMBER_INIT (0, GTK_CSS_PERCENT), GTK_CSS_NUMBER_INIT (0, GTK_CSS_PERCENT)};
877 GtkCssBorderCornerRadius no_corner_radius = { GTK_CSS_NUMBER_INIT (0, GTK_CSS_PX), GTK_CSS_NUMBER_INIT (0, GTK_CSS_PX) };
878 GtkBorder border_of_ones = { 1, 1, 1, 1 };
879 GtkCssBorderImageRepeat border_image_repeat = { GTK_CSS_REPEAT_STYLE_STRETCH, GTK_CSS_REPEAT_STYLE_STRETCH };
881 /* Initialize "color" and "font-size" first,
882 * so that when computing values later they are
883 * done first. That way, 'currentColor' and font
884 * sizes in em can be looked up properly */
885 gtk_css_style_property_register ("color",
886 GTK_TYPE_SYMBOLIC_COLOR,
889 GTK_STYLE_PROPERTY_INHERIT,
894 _gtk_css_value_new_take_symbolic_color (
895 gtk_symbolic_color_new_rgba (1, 1, 1, 1)));
896 gtk_css_style_property_register ("font-size",
900 GTK_STYLE_PROPERTY_INHERIT,
905 _gtk_css_value_new_from_double (10.0));
907 /* properties that aren't referenced when computing values
909 gtk_css_style_property_register ("background-color",
910 GTK_TYPE_SYMBOLIC_COLOR,
918 _gtk_css_value_new_take_symbolic_color (
919 gtk_symbolic_color_new_rgba (0, 0, 0, 0)));
921 gtk_css_style_property_register ("font-family",
925 GTK_STYLE_PROPERTY_INHERIT,
927 font_family_value_print,
930 _gtk_css_value_new_take_strv (g_strdupv (default_font_family)));
931 gtk_css_style_property_register ("font-style",
935 GTK_STYLE_PROPERTY_INHERIT,
940 _gtk_css_value_new_from_enum (PANGO_TYPE_STYLE,
941 PANGO_STYLE_NORMAL));
942 gtk_css_style_property_register ("font-variant",
946 GTK_STYLE_PROPERTY_INHERIT,
951 _gtk_css_value_new_from_enum (PANGO_TYPE_VARIANT,
952 PANGO_VARIANT_NORMAL));
953 /* xxx: need to parse this properly, ie parse the numbers */
954 gtk_css_style_property_register ("font-weight",
958 GTK_STYLE_PROPERTY_INHERIT,
963 _gtk_css_value_new_from_enum (PANGO_TYPE_WEIGHT,
964 PANGO_WEIGHT_NORMAL));
966 gtk_css_style_property_register ("text-shadow",
970 GTK_STYLE_PROPERTY_INHERIT,
975 _gtk_css_value_new_take_shadow (NULL));
977 gtk_css_style_property_register ("icon-shadow",
981 GTK_STYLE_PROPERTY_INHERIT,
986 _gtk_css_value_new_take_shadow (NULL));
988 gtk_css_style_property_register ("box-shadow",
997 _gtk_css_value_new_take_shadow (NULL));
999 _gtk_css_number_init (&number, 0, GTK_CSS_PX);
1000 gtk_css_style_property_register ("margin-top",
1001 GTK_TYPE_CSS_NUMBER,
1002 GTK_TYPE_CSS_NUMBER,
1009 _gtk_css_value_new_from_number (&number));
1010 gtk_css_style_property_register ("margin-left",
1011 GTK_TYPE_CSS_NUMBER,
1012 GTK_TYPE_CSS_NUMBER,
1019 _gtk_css_value_new_from_number (&number));
1020 gtk_css_style_property_register ("margin-bottom",
1021 GTK_TYPE_CSS_NUMBER,
1022 GTK_TYPE_CSS_NUMBER,
1029 _gtk_css_value_new_from_number (&number));
1030 gtk_css_style_property_register ("margin-right",
1031 GTK_TYPE_CSS_NUMBER,
1032 GTK_TYPE_CSS_NUMBER,
1039 _gtk_css_value_new_from_number (&number));
1040 gtk_css_style_property_register ("padding-top",
1041 GTK_TYPE_CSS_NUMBER,
1042 GTK_TYPE_CSS_NUMBER,
1049 _gtk_css_value_new_from_number (&number));
1050 gtk_css_style_property_register ("padding-left",
1051 GTK_TYPE_CSS_NUMBER,
1052 GTK_TYPE_CSS_NUMBER,
1059 _gtk_css_value_new_from_number (&number));
1060 gtk_css_style_property_register ("padding-bottom",
1061 GTK_TYPE_CSS_NUMBER,
1062 GTK_TYPE_CSS_NUMBER,
1069 _gtk_css_value_new_from_number (&number));
1070 gtk_css_style_property_register ("padding-right",
1071 GTK_TYPE_CSS_NUMBER,
1072 GTK_TYPE_CSS_NUMBER,
1079 _gtk_css_value_new_from_number (&number));
1080 /* IMPORTANT: compute_border_width() requires that the border-width
1081 * properties be immeditaly followed by the border-style properties
1083 gtk_css_style_property_register ("border-top-style",
1084 GTK_TYPE_BORDER_STYLE,
1085 GTK_TYPE_BORDER_STYLE,
1086 GTK_TYPE_BORDER_STYLE,
1092 _gtk_css_value_new_from_border_style (GTK_BORDER_STYLE_NONE));
1093 gtk_css_style_property_register ("border-top-width",
1094 GTK_TYPE_CSS_NUMBER,
1100 compute_border_width,
1102 _gtk_css_value_new_from_number (&number));
1103 gtk_css_style_property_register ("border-left-style",
1104 GTK_TYPE_BORDER_STYLE,
1105 GTK_TYPE_BORDER_STYLE,
1106 GTK_TYPE_BORDER_STYLE,
1112 _gtk_css_value_new_from_border_style (GTK_BORDER_STYLE_NONE));
1113 gtk_css_style_property_register ("border-left-width",
1114 GTK_TYPE_CSS_NUMBER,
1120 compute_border_width,
1122 _gtk_css_value_new_from_number (&number));
1123 gtk_css_style_property_register ("border-bottom-style",
1124 GTK_TYPE_BORDER_STYLE,
1125 GTK_TYPE_BORDER_STYLE,
1126 GTK_TYPE_BORDER_STYLE,
1132 _gtk_css_value_new_from_border_style (GTK_BORDER_STYLE_NONE));
1133 gtk_css_style_property_register ("border-bottom-width",
1134 GTK_TYPE_CSS_NUMBER,
1140 compute_border_width,
1142 _gtk_css_value_new_from_number (&number));
1143 gtk_css_style_property_register ("border-right-style",
1144 GTK_TYPE_BORDER_STYLE,
1145 GTK_TYPE_BORDER_STYLE,
1146 GTK_TYPE_BORDER_STYLE,
1152 _gtk_css_value_new_from_border_style (GTK_BORDER_STYLE_NONE));
1153 gtk_css_style_property_register ("border-right-width",
1154 GTK_TYPE_CSS_NUMBER,
1160 compute_border_width,
1162 _gtk_css_value_new_from_number (&number));
1164 gtk_css_style_property_register ("border-top-left-radius",
1165 GTK_TYPE_CSS_BORDER_CORNER_RADIUS,
1166 GTK_TYPE_CSS_BORDER_CORNER_RADIUS,
1167 GTK_TYPE_CSS_BORDER_CORNER_RADIUS,
1169 border_corner_radius_value_parse,
1170 border_corner_radius_value_print,
1173 _gtk_css_value_new_from_border_corner_radius (&no_corner_radius));
1174 gtk_css_style_property_register ("border-top-right-radius",
1175 GTK_TYPE_CSS_BORDER_CORNER_RADIUS,
1176 GTK_TYPE_CSS_BORDER_CORNER_RADIUS,
1177 GTK_TYPE_CSS_BORDER_CORNER_RADIUS,
1179 border_corner_radius_value_parse,
1180 border_corner_radius_value_print,
1183 _gtk_css_value_new_from_border_corner_radius (&no_corner_radius));
1184 gtk_css_style_property_register ("border-bottom-right-radius",
1185 GTK_TYPE_CSS_BORDER_CORNER_RADIUS,
1186 GTK_TYPE_CSS_BORDER_CORNER_RADIUS,
1187 GTK_TYPE_CSS_BORDER_CORNER_RADIUS,
1189 border_corner_radius_value_parse,
1190 border_corner_radius_value_print,
1193 _gtk_css_value_new_from_border_corner_radius (&no_corner_radius));
1194 gtk_css_style_property_register ("border-bottom-left-radius",
1195 GTK_TYPE_CSS_BORDER_CORNER_RADIUS,
1196 GTK_TYPE_CSS_BORDER_CORNER_RADIUS,
1197 GTK_TYPE_CSS_BORDER_CORNER_RADIUS,
1199 border_corner_radius_value_parse,
1200 border_corner_radius_value_print,
1203 _gtk_css_value_new_from_border_corner_radius (&no_corner_radius));
1205 gtk_css_style_property_register ("outline-style",
1206 GTK_TYPE_BORDER_STYLE,
1207 GTK_TYPE_BORDER_STYLE,
1208 GTK_TYPE_BORDER_STYLE,
1214 _gtk_css_value_new_from_border_style (GTK_BORDER_STYLE_NONE));
1215 gtk_css_style_property_register ("outline-width",
1216 GTK_TYPE_CSS_NUMBER,
1222 compute_border_width,
1224 _gtk_css_value_new_from_number (&number));
1225 gtk_css_style_property_register ("outline-offset",
1234 _gtk_css_value_new_from_int (0));
1236 gtk_css_style_property_register ("background-clip",
1245 _gtk_css_value_new_from_enum (GTK_TYPE_CSS_AREA, GTK_CSS_AREA_BORDER_BOX));
1246 gtk_css_style_property_register ("background-origin",
1255 _gtk_css_value_new_from_enum (GTK_TYPE_CSS_AREA, GTK_CSS_AREA_PADDING_BOX));
1256 gtk_css_style_property_register ("background-size",
1257 GTK_TYPE_CSS_BACKGROUND_SIZE,
1258 GTK_TYPE_CSS_BACKGROUND_SIZE,
1261 background_size_parse,
1262 background_size_print,
1263 background_size_compute,
1265 _gtk_css_value_new_from_background_size (&default_background_size));
1266 gtk_css_style_property_register ("background-position",
1267 GTK_TYPE_CSS_BACKGROUND_POSITION,
1268 GTK_TYPE_CSS_BACKGROUND_POSITION,
1271 background_position_parse,
1272 background_position_print,
1273 background_position_compute,
1275 _gtk_css_value_new_from_background_position (&default_background_position));
1277 gtk_css_style_property_register ("border-top-color",
1278 GTK_TYPE_SYMBOLIC_COLOR,
1286 _gtk_css_value_new_take_symbolic_color (
1287 gtk_symbolic_color_ref (
1288 _gtk_symbolic_color_get_current_color ())));
1289 gtk_css_style_property_register ("border-right-color",
1290 GTK_TYPE_SYMBOLIC_COLOR,
1298 _gtk_css_value_new_take_symbolic_color (
1299 gtk_symbolic_color_ref (
1300 _gtk_symbolic_color_get_current_color ())));
1301 gtk_css_style_property_register ("border-bottom-color",
1302 GTK_TYPE_SYMBOLIC_COLOR,
1310 _gtk_css_value_new_take_symbolic_color (
1311 gtk_symbolic_color_ref (
1312 _gtk_symbolic_color_get_current_color ())));
1313 gtk_css_style_property_register ("border-left-color",
1314 GTK_TYPE_SYMBOLIC_COLOR,
1322 _gtk_css_value_new_take_symbolic_color (
1323 gtk_symbolic_color_ref (
1324 _gtk_symbolic_color_get_current_color ())));
1325 gtk_css_style_property_register ("outline-color",
1326 GTK_TYPE_SYMBOLIC_COLOR,
1334 _gtk_css_value_new_take_symbolic_color (
1335 gtk_symbolic_color_ref (
1336 _gtk_symbolic_color_get_current_color ())));
1338 gtk_css_style_property_register ("background-repeat",
1339 GTK_TYPE_CSS_BACKGROUND_REPEAT,
1340 GTK_TYPE_CSS_BACKGROUND_REPEAT,
1341 GTK_TYPE_CSS_BACKGROUND_REPEAT,
1343 background_repeat_value_parse,
1344 background_repeat_value_print,
1347 _gtk_css_value_new_from_enum (GTK_TYPE_CSS_BACKGROUND_REPEAT,
1348 GTK_CSS_BACKGROUND_REPEAT |
1349 (GTK_CSS_BACKGROUND_REPEAT << GTK_CSS_BACKGROUND_REPEAT_SHIFT)));
1350 gtk_css_style_property_register ("background-image",
1353 CAIRO_GOBJECT_TYPE_PATTERN,
1355 css_image_value_parse,
1356 css_image_value_print,
1357 css_image_value_compute,
1359 _gtk_css_value_new_take_image (NULL));
1361 gtk_css_style_property_register ("border-image-source",
1364 CAIRO_GOBJECT_TYPE_PATTERN,
1366 css_image_value_parse,
1367 css_image_value_print,
1368 css_image_value_compute,
1370 _gtk_css_value_new_take_image (NULL));
1371 gtk_css_style_property_register ("border-image-repeat",
1372 GTK_TYPE_CSS_BORDER_IMAGE_REPEAT,
1373 GTK_TYPE_CSS_BORDER_IMAGE_REPEAT,
1374 GTK_TYPE_CSS_BORDER_IMAGE_REPEAT,
1380 _gtk_css_value_new_from_border_image_repeat (&border_image_repeat));
1382 /* XXX: The initial value is wrong, it should be 100% */
1383 gtk_css_style_property_register ("border-image-slice",
1392 _gtk_css_value_new_from_boxed (GTK_TYPE_BORDER, &border_of_ones));
1393 gtk_css_style_property_register ("border-image-width",
1402 _gtk_css_value_new_from_boxed (GTK_TYPE_BORDER, NULL));
1403 gtk_css_style_property_register ("engine",
1404 GTK_TYPE_THEMING_ENGINE,
1405 GTK_TYPE_THEMING_ENGINE,
1406 GTK_TYPE_THEMING_ENGINE,
1412 _gtk_css_value_new_from_theming_engine (gtk_theming_engine_load (NULL)));
1413 gtk_css_style_property_register ("transition",
1414 GTK_TYPE_ANIMATION_DESCRIPTION,
1415 GTK_TYPE_ANIMATION_DESCRIPTION,
1416 GTK_TYPE_ANIMATION_DESCRIPTION,
1422 _gtk_css_value_new_from_boxed (GTK_TYPE_ANIMATION_DESCRIPTION, NULL));
1424 /* Private property holding the binding sets */
1425 gtk_css_style_property_register ("gtk-key-bindings",
1430 bindings_value_parse,
1431 bindings_value_print,
1434 _gtk_css_value_new_take_binding_sets (NULL));