static gboolean parse_border_radius (GtkCssShorthandProperty *shorthand, GtkCssValue **values, GtkCssParser *parser) { GtkCssValue *x[4] = { NULL, }, *y[4] = { NULL, }; guint i; for (i = 0; i < 4; i++) { if (!gtk_css_number_value_can_parse (parser)) break; x[i] = _gtk_css_number_value_parse (parser, GTK_CSS_POSITIVE_ONLY | GTK_CSS_PARSE_PERCENT | GTK_CSS_NUMBER_AS_PIXELS | GTK_CSS_PARSE_LENGTH); if (x[i] == NULL) goto fail; } if (i == 0) { _gtk_css_parser_error (parser, "Expected a number"); goto fail; } /* The magic (i - 1) >> 1 below makes it take the correct value * according to spec. Feel free to check the 4 cases */ for (; i < 4; i++) x[i] = _gtk_css_value_ref (x[(i - 1) >> 1]); if (_gtk_css_parser_try (parser, "/", TRUE)) { for (i = 0; i < 4; i++) { if (!gtk_css_number_value_can_parse (parser)) break; y[i] = _gtk_css_number_value_parse (parser, GTK_CSS_POSITIVE_ONLY | GTK_CSS_PARSE_PERCENT | GTK_CSS_NUMBER_AS_PIXELS | GTK_CSS_PARSE_LENGTH); if (y[i] == NULL) goto fail; } if (i == 0) { _gtk_css_parser_error (parser, "Expected a number"); goto fail; } for (; i < 4; i++) y[i] = _gtk_css_value_ref (y[(i - 1) >> 1]); } else { for (i = 0; i < 4; i++)
static gboolean parse_four_numbers (GtkCssShorthandProperty *shorthand, GtkCssValue **values, GtkCssParser *parser, GtkCssNumberParseFlags flags) { guint i; for (i = 0; i < 4; i++) { if (!gtk_css_number_value_can_parse (parser)) break; values[i] = _gtk_css_number_value_parse (parser, flags); if (values[i] == NULL) return FALSE; } if (i == 0) { _gtk_css_parser_error (parser, "Expected a length"); return FALSE; } for (; i < 4; i++) { values[i] = _gtk_css_value_ref (values[(i - 1) >> 1]); } return TRUE; }
GtkCssValue * _gtk_css_bg_size_value_parse (GtkCssParser *parser) { GtkCssValue *x, *y; if (_gtk_css_parser_try (parser, "cover", TRUE)) return _gtk_css_value_ref (&cover_singleton); else if (_gtk_css_parser_try (parser, "contain", TRUE)) return _gtk_css_value_ref (&contain_singleton); if (_gtk_css_parser_try (parser, "auto", TRUE)) x = NULL; else { x = _gtk_css_number_value_parse (parser, GTK_CSS_POSITIVE_ONLY | GTK_CSS_PARSE_PERCENT | GTK_CSS_PARSE_LENGTH); if (x == NULL) return NULL; } if (_gtk_css_parser_try (parser, "auto", TRUE)) y = NULL; else if (!gtk_css_number_value_can_parse (parser)) y = NULL; else { y = _gtk_css_number_value_parse (parser, GTK_CSS_POSITIVE_ONLY | GTK_CSS_PARSE_PERCENT | GTK_CSS_PARSE_LENGTH); if (y == NULL) { _gtk_css_value_unref (x); return NULL; } } return _gtk_css_bg_size_value_new (x, y); }
static gboolean gtk_css_image_linear_parse (GtkCssImage *image, GtkCssParser *parser) { GtkCssImageLinear *linear = GTK_CSS_IMAGE_LINEAR (image); guint i; if (_gtk_css_parser_try (parser, "repeating-linear-gradient(", TRUE)) linear->repeating = TRUE; else if (_gtk_css_parser_try (parser, "linear-gradient(", TRUE)) linear->repeating = FALSE; else { _gtk_css_parser_error (parser, "Not a linear gradient"); return FALSE; } if (_gtk_css_parser_try (parser, "to", TRUE)) { for (i = 0; i < 2; i++) { if (_gtk_css_parser_try (parser, "left", TRUE)) { if (linear->side & ((1 << GTK_CSS_LEFT) | (1 << GTK_CSS_RIGHT))) { _gtk_css_parser_error (parser, "Expected 'top', 'bottom' or comma"); return FALSE; } linear->side |= (1 << GTK_CSS_LEFT); } else if (_gtk_css_parser_try (parser, "right", TRUE)) { if (linear->side & ((1 << GTK_CSS_LEFT) | (1 << GTK_CSS_RIGHT))) { _gtk_css_parser_error (parser, "Expected 'top', 'bottom' or comma"); return FALSE; } linear->side |= (1 << GTK_CSS_RIGHT); } else if (_gtk_css_parser_try (parser, "top", TRUE)) { if (linear->side & ((1 << GTK_CSS_TOP) | (1 << GTK_CSS_BOTTOM))) { _gtk_css_parser_error (parser, "Expected 'left', 'right' or comma"); return FALSE; } linear->side |= (1 << GTK_CSS_TOP); } else if (_gtk_css_parser_try (parser, "bottom", TRUE)) { if (linear->side & ((1 << GTK_CSS_TOP) | (1 << GTK_CSS_BOTTOM))) { _gtk_css_parser_error (parser, "Expected 'left', 'right' or comma"); return FALSE; } linear->side |= (1 << GTK_CSS_BOTTOM); } else break; } if (linear->side == 0) { _gtk_css_parser_error (parser, "Expected side that gradient should go to"); return FALSE; } if (!_gtk_css_parser_try (parser, ",", TRUE)) { _gtk_css_parser_error (parser, "Expected a comma"); return FALSE; } } else if (gtk_css_number_value_can_parse (parser)) { linear->angle = _gtk_css_number_value_parse (parser, GTK_CSS_PARSE_ANGLE); if (linear->angle == NULL) return FALSE; if (!_gtk_css_parser_try (parser, ",", TRUE)) { _gtk_css_parser_error (parser, "Expected a comma"); return FALSE; } } else linear->side = 1 << GTK_CSS_BOTTOM; do { GtkCssImageLinearColorStop stop; stop.color = _gtk_css_color_value_parse (parser); if (stop.color == NULL) return FALSE; if (gtk_css_number_value_can_parse (parser)) { stop.offset = _gtk_css_number_value_parse (parser, GTK_CSS_PARSE_PERCENT | GTK_CSS_PARSE_LENGTH); if (stop.offset == NULL) { _gtk_css_value_unref (stop.color); return FALSE; } } else { stop.offset = NULL; } g_array_append_val (linear->stops, stop); } while (_gtk_css_parser_try (parser, ",", TRUE)); if (linear->stops->len < 2) { _gtk_css_parser_error_full (parser, GTK_CSS_PROVIDER_ERROR_DEPRECATED, "Using one color stop with %s() is deprecated.", linear->repeating ? "repeating-linear-gradient" : "linear-gradient"); } if (!_gtk_css_parser_try (parser, ")", TRUE)) { _gtk_css_parser_error (parser, "Missing closing bracket at end of linear gradient"); return FALSE; } return TRUE; }