X-Git-Url: http://pileus.org/git/?a=blobdiff_plain;f=gtk%2Fgtkcssshorthandpropertyimpl.c;h=b01494b7da888fd165f144482b339b94423f49d6;hb=02e915273845b21af223e7e5e2425569afcf1b83;hp=3a26a28afdeb5236bf1492dbf81275d2d63ba661;hpb=56f79fecce885e05b7fe1677a70b98c64ea4a85c;p=~andy%2Fgtk diff --git a/gtk/gtkcssshorthandpropertyimpl.c b/gtk/gtkcssshorthandpropertyimpl.c index 3a26a28af..b01494b7d 100644 --- a/gtk/gtkcssshorthandpropertyimpl.c +++ b/gtk/gtkcssshorthandpropertyimpl.c @@ -25,20 +25,21 @@ #include #include "gtkcssarrayvalueprivate.h" +#include "gtkcssbgsizevalueprivate.h" #include "gtkcssbordervalueprivate.h" +#include "gtkcsscolorvalueprivate.h" #include "gtkcsscornervalueprivate.h" +#include "gtkcsseasevalueprivate.h" #include "gtkcssenumvalueprivate.h" #include "gtkcssimageprivate.h" #include "gtkcssimagevalueprivate.h" #include "gtkcssnumbervalueprivate.h" +#include "gtkcsspositionvalueprivate.h" #include "gtkcssrepeatvalueprivate.h" #include "gtkcssstringvalueprivate.h" #include "gtkcssstylefuncsprivate.h" -#include "gtkcsstypesprivate.h" #include "gtkcssvalueprivate.h" -#include "gtkprivatetypebuiltins.h" #include "gtkstylepropertiesprivate.h" -#include "gtksymboliccolorprivate.h" #include "gtktypebuiltins.h" /* this is in case round() is not provided by the compiler, @@ -52,6 +53,7 @@ static gboolean value_is_done_parsing (GtkCssParser *parser) { return _gtk_css_parser_is_eof (parser) || + _gtk_css_parser_begins_with (parser, ',') || _gtk_css_parser_begins_with (parser, ';') || _gtk_css_parser_begins_with (parser, '}'); } @@ -91,8 +93,7 @@ parse_four_numbers (GtkCssShorthandProperty *shorthand, static gboolean parse_margin (GtkCssShorthandProperty *shorthand, GtkCssValue **values, - GtkCssParser *parser, - GFile *base) + GtkCssParser *parser) { return parse_four_numbers (shorthand, values, @@ -104,8 +105,7 @@ parse_margin (GtkCssShorthandProperty *shorthand, static gboolean parse_padding (GtkCssShorthandProperty *shorthand, GtkCssValue **values, - GtkCssParser *parser, - GFile *base) + GtkCssParser *parser) { return parse_four_numbers (shorthand, values, @@ -118,8 +118,7 @@ parse_padding (GtkCssShorthandProperty *shorthand, static gboolean parse_border_width (GtkCssShorthandProperty *shorthand, GtkCssValue **values, - GtkCssParser *parser, - GFile *base) + GtkCssParser *parser) { return parse_four_numbers (shorthand, values, @@ -132,8 +131,7 @@ parse_border_width (GtkCssShorthandProperty *shorthand, static gboolean parse_border_radius (GtkCssShorthandProperty *shorthand, GtkCssValue **values, - GtkCssParser *parser, - GFile *base) + GtkCssParser *parser) { GtkCssValue *x[4] = { NULL, }, *y[4] = { NULL, }; guint i; @@ -213,26 +211,15 @@ fail: static gboolean parse_border_color (GtkCssShorthandProperty *shorthand, GtkCssValue **values, - GtkCssParser *parser, - GFile *base) + GtkCssParser *parser) { - GtkSymbolicColor *symbolic; guint i; for (i = 0; i < 4; i++) { - if (_gtk_css_parser_try (parser, "currentcolor", TRUE)) - { - symbolic = gtk_symbolic_color_ref (_gtk_symbolic_color_get_current_color ()); - } - else - { - symbolic = _gtk_css_parser_read_symbolic_color (parser); - if (symbolic == NULL) - return FALSE; - } - - values[i] = _gtk_css_value_new_take_symbolic_color (symbolic); + values[i] = _gtk_css_color_value_parse (parser); + if (values[i] == NULL) + return FALSE; if (value_is_done_parsing (parser)) break; @@ -249,8 +236,7 @@ parse_border_color (GtkCssShorthandProperty *shorthand, static gboolean parse_border_style (GtkCssShorthandProperty *shorthand, GtkCssValue **values, - GtkCssParser *parser, - GFile *base) + GtkCssParser *parser) { guint i; @@ -276,8 +262,7 @@ parse_border_style (GtkCssShorthandProperty *shorthand, static gboolean parse_border_image (GtkCssShorthandProperty *shorthand, GtkCssValue **values, - GtkCssParser *parser, - GFile *base) + GtkCssParser *parser) { do { @@ -291,7 +276,7 @@ parse_border_image (GtkCssShorthandProperty *shorthand, image = NULL; else { - image = _gtk_css_image_new_parse (parser, base); + image = _gtk_css_image_new_parse (parser); if (image == NULL) return FALSE; } @@ -316,13 +301,15 @@ parse_border_image (GtkCssShorthandProperty *shorthand, if (_gtk_css_parser_try (parser, "/", TRUE)) { - GValue value = G_VALUE_INIT; - - g_value_init (&value, GTK_TYPE_BORDER); - if (!_gtk_css_style_parse_value (&value, parser, base)) + values[2] = _gtk_css_border_value_parse (parser, + GTK_CSS_PARSE_PERCENT + | GTK_CSS_PARSE_LENGTH + | GTK_CSS_PARSE_NUMBER + | GTK_CSS_POSITIVE_ONLY, + TRUE, + FALSE); + if (values[2] == NULL) return FALSE; - values[2] = _gtk_css_value_new_from_gvalue (&value); - g_value_unset (&value); } } else @@ -341,8 +328,7 @@ parse_border_image (GtkCssShorthandProperty *shorthand, static gboolean parse_border_side (GtkCssShorthandProperty *shorthand, GtkCssValue **values, - GtkCssParser *parser, - GFile *base) + GtkCssParser *parser) { do { @@ -363,13 +349,9 @@ parse_border_side (GtkCssShorthandProperty *shorthand, } else if (values[2] == NULL) { - GtkSymbolicColor *symbolic; - - symbolic = _gtk_css_parser_read_symbolic_color (parser); - if (symbolic == NULL) + values[2] = _gtk_css_color_value_parse (parser); + if (values[2] == NULL) return FALSE; - - values[2] = _gtk_css_value_new_take_symbolic_color (symbolic); } } while (!value_is_done_parsing (parser)); @@ -380,8 +362,7 @@ parse_border_side (GtkCssShorthandProperty *shorthand, static gboolean parse_border (GtkCssShorthandProperty *shorthand, GtkCssValue **values, - GtkCssParser *parser, - GFile *base) + GtkCssParser *parser) { do { @@ -407,13 +388,10 @@ parse_border (GtkCssShorthandProperty *shorthand, } else if (!G_IS_VALUE (&values[8])) { - GtkSymbolicColor *symbolic; - - symbolic = _gtk_css_parser_read_symbolic_color (parser); - if (symbolic == NULL) + values[8] = _gtk_css_color_value_parse (parser); + if (values[8] == NULL) return FALSE; - values[8] = _gtk_css_value_new_take_symbolic_color (symbolic); values[9] = _gtk_css_value_ref (values[8]); values[10] = _gtk_css_value_ref (values[8]); values[11] = _gtk_css_value_ref (values[8]); @@ -437,8 +415,7 @@ parse_border (GtkCssShorthandProperty *shorthand, static gboolean parse_font (GtkCssShorthandProperty *shorthand, GtkCssValue **values, - GtkCssParser *parser, - GFile *base) + GtkCssParser *parser) { PangoFontDescription *desc; guint mask; @@ -480,11 +457,12 @@ parse_font (GtkCssShorthandProperty *shorthand, } static gboolean -parse_background (GtkCssShorthandProperty *shorthand, - GtkCssValue **values, - GtkCssParser *parser, - GFile *base) +parse_one_background (GtkCssShorthandProperty *shorthand, + GtkCssValue **values, + GtkCssParser *parser) { + GtkCssValue *value = NULL; + do { /* the image part */ @@ -498,7 +476,7 @@ parse_background (GtkCssShorthandProperty *shorthand, image = NULL; else { - image = _gtk_css_image_new_parse (parser, base); + image = _gtk_css_image_new_parse (parser); if (image == NULL) return FALSE; } @@ -506,28 +484,154 @@ parse_background (GtkCssShorthandProperty *shorthand, values[0] = _gtk_css_image_value_new (image); } else if (values[1] == NULL && - (values[1] = _gtk_css_background_repeat_value_try_parse (parser))) + (value = _gtk_css_position_value_try_parse (parser))) + { + values[1] = value; + value = NULL; + + if (_gtk_css_parser_try (parser, "/", TRUE) && + (value = _gtk_css_bg_size_value_parse (parser))) + { + values[2] = value; + value = NULL; + } + } + else if (values[3] == NULL && + (value = _gtk_css_background_repeat_value_try_parse (parser))) { - /* nothing to do here */ + values[3] = value; + value = NULL; } - else if ((values[2] == NULL || values[3] == NULL) && - (values[3] = _gtk_css_area_value_try_parse (parser))) + else if ((values[4] == NULL || values[5] == NULL) && + (value = _gtk_css_area_value_try_parse (parser))) { - if (values[2] == NULL) + values[4] = value; + + if (values[5] == NULL) { - values[2] = values[3]; - values[3] = NULL; + values[5] = values[4]; + values[4] = NULL; } + value = NULL; } - else if (values[4] == NULL) + else if (values[6] == NULL) { - GtkSymbolicColor *symbolic; - - symbolic = _gtk_css_parser_read_symbolic_color (parser); - if (symbolic == NULL) + value = _gtk_css_color_value_parse (parser); + if (value == NULL) + values[6] = _gtk_css_value_ref (_gtk_css_style_property_get_initial_value + (_gtk_css_shorthand_property_get_subproperty (shorthand, 6))); + else + values[6] = value; + + value = NULL; + } + else + { + /* We parsed everything and there's still stuff left? + * Pretend we didn't notice and let the normal code produce + * a 'junk at end of value' error */ + break; + } + } + while (!value_is_done_parsing (parser)); + + if (values[5] != NULL && values[4] == NULL) + values[4] = _gtk_css_value_ref (values[5]); + + return TRUE; +} + +static gboolean +parse_background (GtkCssShorthandProperty *shorthand, + GtkCssValue **values, + GtkCssParser *parser) +{ + GtkCssValue *step_values[7]; + GPtrArray *arrays[6]; + guint i; + + for (i = 0; i < 6; i++) + { + arrays[i] = g_ptr_array_new (); + step_values[i] = NULL; + } + + step_values[6] = NULL; + + do { + if (!parse_one_background (shorthand, step_values, parser)) + { + for (i = 0; i < 6; i++) + { + g_ptr_array_set_free_func (arrays[i], (GDestroyNotify) _gtk_css_value_unref); + g_ptr_array_unref (arrays[i]); + } + return FALSE; + } + + for (i = 0; i < 6; i++) + { + if (step_values[i] == NULL) + { + GtkCssValue *initial = _gtk_css_style_property_get_initial_value ( + _gtk_css_shorthand_property_get_subproperty (shorthand, i)); + step_values[i] = _gtk_css_value_ref (_gtk_css_array_value_get_nth (initial, 0)); + } + + g_ptr_array_add (arrays[i], step_values[i]); + step_values[i] = NULL; + } + } while (_gtk_css_parser_try (parser, ",", TRUE)); + + for (i = 0; i < 6; i++) + { + values[i] = _gtk_css_array_value_new_from_array ((GtkCssValue **) arrays[i]->pdata, arrays[i]->len); + g_ptr_array_unref (arrays[i]); + } + + values[6] = step_values[6]; + + return TRUE; +} + +static gboolean +parse_one_transition (GtkCssShorthandProperty *shorthand, + GtkCssValue **values, + GtkCssParser *parser) +{ + do + { + /* the image part */ + if (values[2] == NULL && + _gtk_css_parser_has_number (parser) && !_gtk_css_parser_begins_with (parser, '-')) + { + GtkCssValue *number = _gtk_css_number_value_parse (parser, GTK_CSS_PARSE_TIME); + + if (number == NULL) return FALSE; - values[4] = _gtk_css_value_new_take_symbolic_color (symbolic); + if (values[1] == NULL) + values[1] = number; + else + values[2] = number; + } + else if (values[3] == NULL && + _gtk_css_ease_value_can_parse (parser)) + { + values[3] = _gtk_css_ease_value_parse (parser); + + if (values[3] == NULL) + return FALSE; + } + else if (values[0] == NULL) + { + values[0] = _gtk_css_ident_value_try_parse (parser); + if (values[0] == NULL) + { + _gtk_css_parser_error (parser, "Unknown value for property"); + return FALSE; + } + } else { @@ -542,6 +646,173 @@ parse_background (GtkCssShorthandProperty *shorthand, return TRUE; } +static gboolean +parse_transition (GtkCssShorthandProperty *shorthand, + GtkCssValue **values, + GtkCssParser *parser) +{ + GtkCssValue *step_values[4]; + GPtrArray *arrays[4]; + guint i; + + for (i = 0; i < 4; i++) + { + arrays[i] = g_ptr_array_new (); + step_values[i] = NULL; + } + + do { + if (!parse_one_transition (shorthand, step_values, parser)) + { + for (i = 0; i < 4; i++) + { + g_ptr_array_set_free_func (arrays[i], (GDestroyNotify) _gtk_css_value_unref); + g_ptr_array_unref (arrays[i]); + } + return FALSE; + } + + for (i = 0; i < 4; i++) + { + if (step_values[i] == NULL) + { + GtkCssValue *initial = _gtk_css_style_property_get_initial_value ( + _gtk_css_shorthand_property_get_subproperty (shorthand, i)); + step_values[i] = _gtk_css_value_ref (_gtk_css_array_value_get_nth (initial, 0)); + } + + g_ptr_array_add (arrays[i], step_values[i]); + step_values[i] = NULL; + } + } while (_gtk_css_parser_try (parser, ",", TRUE)); + + for (i = 0; i < 4; i++) + { + values[i] = _gtk_css_array_value_new_from_array ((GtkCssValue **) arrays[i]->pdata, arrays[i]->len); + g_ptr_array_unref (arrays[i]); + } + + return TRUE; +} + +static gboolean +parse_one_animation (GtkCssShorthandProperty *shorthand, + GtkCssValue **values, + GtkCssParser *parser) +{ + do + { + if (values[1] == NULL && _gtk_css_parser_try (parser, "infinite", TRUE)) + { + values[1] = _gtk_css_number_value_new (HUGE_VAL, GTK_CSS_NUMBER); + } + else if ((values[1] == NULL || values[3] == NULL) && + _gtk_css_parser_has_number (parser)) + { + GtkCssValue *value; + + value = _gtk_css_number_value_parse (parser, + GTK_CSS_POSITIVE_ONLY + | (values[1] == NULL ? GTK_CSS_PARSE_NUMBER : 0) + | (values[3] == NULL ? GTK_CSS_PARSE_TIME : 0)); + if (_gtk_css_number_value_get_unit (value) == GTK_CSS_NUMBER) + values[1] = value; + else if (values[2] == NULL) + values[2] = value; + else + values[3] = value; + } + else if (values[4] == NULL && + _gtk_css_ease_value_can_parse (parser)) + { + values[4] = _gtk_css_ease_value_parse (parser); + + if (values[4] == NULL) + return FALSE; + } + else if (values[5] == NULL && + (values[5] = _gtk_css_direction_value_try_parse (parser))) + { + /* nothing to do */ + } + else if (values[6] == NULL && + (values[6] = _gtk_css_fill_mode_value_try_parse (parser))) + { + /* nothing to do */ + } + else if (values[0] == NULL && + (values[0] = _gtk_css_ident_value_try_parse (parser))) + { + /* nothing to do */ + /* keep in mind though that this needs to come last as fill modes, directions + * etc are valid idents */ + } + else + { + /* We parsed everything and there's still stuff left? + * Pretend we didn't notice and let the normal code produce + * a 'junk at end of value' error */ + break; + } + } + while (!value_is_done_parsing (parser)); + + return TRUE; +} + +static gboolean +parse_animation (GtkCssShorthandProperty *shorthand, + GtkCssValue **values, + GtkCssParser *parser) +{ + GtkCssValue *step_values[7]; + GPtrArray *arrays[6]; + guint i; + + for (i = 0; i < 6; i++) + { + arrays[i] = g_ptr_array_new (); + step_values[i] = NULL; + } + + step_values[6] = NULL; + + do { + if (!parse_one_animation (shorthand, step_values, parser)) + { + for (i = 0; i < 6; i++) + { + g_ptr_array_set_free_func (arrays[i], (GDestroyNotify) _gtk_css_value_unref); + g_ptr_array_unref (arrays[i]); + } + return FALSE; + } + + for (i = 0; i < 6; i++) + { + if (step_values[i] == NULL) + { + GtkCssValue *initial = _gtk_css_style_property_get_initial_value ( + _gtk_css_shorthand_property_get_subproperty (shorthand, i)); + step_values[i] = _gtk_css_value_ref (_gtk_css_array_value_get_nth (initial, 0)); + } + + g_ptr_array_add (arrays[i], step_values[i]); + step_values[i] = NULL; + } + } while (_gtk_css_parser_try (parser, ",", TRUE)); + + for (i = 0; i < 6; i++) + { + values[i] = _gtk_css_array_value_new_from_array ((GtkCssValue **) arrays[i]->pdata, arrays[i]->len); + g_ptr_array_unref (arrays[i]); + } + + values[6] = step_values[6]; + + return TRUE; +} + /*** PACKING ***/ static void @@ -575,24 +846,27 @@ pack_border (GtkCssShorthandProperty *shorthand, { GtkCssStyleProperty *prop; GtkBorder border; - GtkCssValue *v; + GValue v; prop = _gtk_css_shorthand_property_get_subproperty (shorthand, 0); - v = (* query_func) (_gtk_css_style_property_get_id (prop), query_data); - if (v) - border.top = _gtk_css_value_get_int (v); + _gtk_style_property_query (GTK_STYLE_PROPERTY (prop), &v, query_func, query_data); + border.top = g_value_get_int (&v); + g_value_unset (&v); + prop = _gtk_css_shorthand_property_get_subproperty (shorthand, 1); - v = (* query_func) (_gtk_css_style_property_get_id (prop), query_data); - if (v) - border.right = _gtk_css_value_get_int (v); + _gtk_style_property_query (GTK_STYLE_PROPERTY (prop), &v, query_func, query_data); + border.right = g_value_get_int (&v); + g_value_unset (&v); + prop = _gtk_css_shorthand_property_get_subproperty (shorthand, 2); - v = (* query_func) (_gtk_css_style_property_get_id (prop), query_data); - if (v) - border.bottom = _gtk_css_value_get_int (v); + _gtk_style_property_query (GTK_STYLE_PROPERTY (prop), &v, query_func, query_data); + border.bottom = g_value_get_int (&v); + g_value_unset (&v); + prop = _gtk_css_shorthand_property_get_subproperty (shorthand, 3); - v = (* query_func) (_gtk_css_style_property_get_id (prop), query_data); - if (v) - border.left = _gtk_css_value_get_int (v); + _gtk_style_property_query (GTK_STYLE_PROPERTY (prop), &v, query_func, query_data); + border.left = g_value_get_int (&v); + g_value_unset (&v); g_value_init (value, GTK_TYPE_BORDER); g_value_set_boxed (value, &border); @@ -837,8 +1111,11 @@ _gtk_css_shorthand_property_init_properties (void) "border-top-color", "border-right-color", "border-bottom-color", "border-left-color", "border-image-source", "border-image-slice", "border-image-width", "border-image-repeat", NULL }; const char *outline_subproperties[] = { "outline-width", "outline-style", "outline-color", NULL }; - const char *background_subproperties[] = { "background-image", "background-repeat", "background-clip", "background-origin", + const char *background_subproperties[] = { "background-image", "background-position", "background-size", "background-repeat", "background-clip", "background-origin", "background-color", NULL }; + const char *transition_subproperties[] = { "transition-property", "transition-duration", "transition-delay", "transition-timing-function", NULL }; + const char *animation_subproperties[] = { "animation-name", "animation-iteration-count", "animation-duration", "animation-delay", + "animation-timing-function", "animation-direction", "animation-fill-mode", NULL }; _gtk_css_shorthand_property_register ("font", PANGO_TYPE_FONT_DESCRIPTION, @@ -930,4 +1207,16 @@ _gtk_css_shorthand_property_init_properties (void) parse_background, NULL, NULL); + _gtk_css_shorthand_property_register ("transition", + G_TYPE_NONE, + transition_subproperties, + parse_transition, + NULL, + NULL); + _gtk_css_shorthand_property_register ("animation", + G_TYPE_NONE, + animation_subproperties, + parse_animation, + NULL, + NULL); }