static GtkCssValue * gtk_css_ease_value_parse_cubic_bezier (GtkCssParser *parser) { double values[4]; guint i; for (i = 0; i < 4; i++) { if (!_gtk_css_parser_try (parser, i ? "," : "(", TRUE)) { _gtk_css_parser_error (parser, "Expected '%s'", i ? "," : "("); return NULL; } if (!_gtk_css_parser_try_double (parser, &values[i])) { _gtk_css_parser_error (parser, "Expected a number"); return NULL; } if ((i == 0 || i == 2) && (values[i] < 0 || values[i] > 1.0)) { _gtk_css_parser_error (parser, "value %g out of range. Must be from 0.0 to 1.0", values[i]); return NULL; } } if (!_gtk_css_parser_try (parser, ")", TRUE)) { _gtk_css_parser_error (parser, "Missing closing ')' for cubic-bezier"); return NULL; } return _gtk_css_ease_value_new_cubic_bezier (values[0], values[1], values[2], values[3]); }
static gboolean float_value_parse (GtkCssParser *parser, GValue *value) { gdouble d; if (!_gtk_css_parser_try_double (parser, &d)) { _gtk_css_parser_error (parser, "Expected a number"); return FALSE; } g_value_set_float (value, d); return TRUE; }
GtkGradient * _gtk_gradient_parse (GtkCssParser *parser) { GtkGradient *gradient; cairo_pattern_type_t type; gdouble coords[6]; guint i; g_return_val_if_fail (parser != NULL, NULL); if (!_gtk_css_parser_try (parser, "-gtk-gradient", TRUE)) { _gtk_css_parser_error (parser, "Expected '-gtk-gradient'"); return NULL; } if (!_gtk_css_parser_try (parser, "(", TRUE)) { _gtk_css_parser_error (parser, "Expected '(' after '-gtk-gradient'"); return NULL; } /* Parse gradient type */ if (_gtk_css_parser_try (parser, "linear", TRUE)) type = CAIRO_PATTERN_TYPE_LINEAR; else if (_gtk_css_parser_try (parser, "radial", TRUE)) type = CAIRO_PATTERN_TYPE_RADIAL; else { _gtk_css_parser_error (parser, "Gradient type must be 'radial' or 'linear'"); return NULL; } /* Parse start/stop position parameters */ for (i = 0; i < 2; i++) { if (! _gtk_css_parser_try (parser, ",", TRUE)) { _gtk_css_parser_error (parser, "Expected ','"); return NULL; } if (_gtk_css_parser_try (parser, "left", TRUE)) coords[i * 3] = 0; else if (_gtk_css_parser_try (parser, "right", TRUE)) coords[i * 3] = 1; else if (_gtk_css_parser_try (parser, "center", TRUE)) coords[i * 3] = 0.5; else if (!_gtk_css_parser_try_double (parser, &coords[i * 3])) { _gtk_css_parser_error (parser, "Expected a valid X coordinate"); return NULL; } if (_gtk_css_parser_try (parser, "top", TRUE)) coords[i * 3 + 1] = 0; else if (_gtk_css_parser_try (parser, "bottom", TRUE)) coords[i * 3 + 1] = 1; else if (_gtk_css_parser_try (parser, "center", TRUE)) coords[i * 3 + 1] = 0.5; else if (!_gtk_css_parser_try_double (parser, &coords[i * 3 + 1])) { _gtk_css_parser_error (parser, "Expected a valid Y coordinate"); return NULL; } if (type == CAIRO_PATTERN_TYPE_RADIAL) { /* Parse radius */ if (! _gtk_css_parser_try (parser, ",", TRUE)) { _gtk_css_parser_error (parser, "Expected ','"); return NULL; } if (! _gtk_css_parser_try_double (parser, &coords[(i * 3) + 2])) { _gtk_css_parser_error (parser, "Expected a numer for the radius"); return NULL; } } } if (type == CAIRO_PATTERN_TYPE_LINEAR) gradient = gtk_gradient_new_linear (coords[0], coords[1], coords[3], coords[4]); else gradient = gtk_gradient_new_radial (coords[0], coords[1], coords[2], coords[3], coords[4], coords[5]); while (_gtk_css_parser_try (parser, ",", TRUE)) { GtkSymbolicColor *color; gdouble position; if (_gtk_css_parser_try (parser, "from", TRUE)) { position = 0; if (!_gtk_css_parser_try (parser, "(", TRUE)) { gtk_gradient_unref (gradient); _gtk_css_parser_error (parser, "Expected '('"); return NULL; } } else if (_gtk_css_parser_try (parser, "to", TRUE)) { position = 1; if (!_gtk_css_parser_try (parser, "(", TRUE)) { gtk_gradient_unref (gradient); _gtk_css_parser_error (parser, "Expected '('"); return NULL; } } else if (_gtk_css_parser_try (parser, "color-stop", TRUE)) { if (!_gtk_css_parser_try (parser, "(", TRUE)) { gtk_gradient_unref (gradient); _gtk_css_parser_error (parser, "Expected '('"); return NULL; } if (!_gtk_css_parser_try_double (parser, &position)) { gtk_gradient_unref (gradient); _gtk_css_parser_error (parser, "Expected a valid number"); return NULL; } if (!_gtk_css_parser_try (parser, ",", TRUE)) { gtk_gradient_unref (gradient); _gtk_css_parser_error (parser, "Expected a comma"); return NULL; } } else { gtk_gradient_unref (gradient); _gtk_css_parser_error (parser, "Not a valid color-stop definition"); return NULL; } color = _gtk_css_parser_read_symbolic_color (parser); if (color == NULL) { gtk_gradient_unref (gradient); return NULL; } gtk_gradient_add_color_stop (gradient, position, color); gtk_symbolic_color_unref (color); if (!_gtk_css_parser_try (parser, ")", TRUE)) { gtk_gradient_unref (gradient); _gtk_css_parser_error (parser, "Expected ')'"); return NULL; } } if (!_gtk_css_parser_try (parser, ")", TRUE)) { gtk_gradient_unref (gradient); _gtk_css_parser_error (parser, "Expected ')'"); return NULL; } return gradient; }
static GtkSymbolicColor * gtk_css_parser_read_symbolic_color_function (GtkCssParser *parser, ColorType color) { GtkSymbolicColor *symbolic; GtkSymbolicColor *child1, *child2; double value; if (!_gtk_css_parser_try (parser, "(", TRUE)) { _gtk_css_parser_error (parser, "Missing opening bracket in color definition"); return NULL; } if (color == COLOR_RGB || color == COLOR_RGBA) { GdkRGBA rgba; double tmp; guint i; for (i = 0; i < 3; i++) { if (i > 0 && !_gtk_css_parser_try (parser, ",", TRUE)) { _gtk_css_parser_error (parser, "Expected ',' in color definition"); return NULL; } if (!_gtk_css_parser_try_double (parser, &tmp)) { _gtk_css_parser_error (parser, "Invalid number for color value"); return NULL; } if (_gtk_css_parser_try (parser, "%", TRUE)) tmp /= 100.0; else tmp /= 255.0; if (i == 0) rgba.red = tmp; else if (i == 1) rgba.green = tmp; else if (i == 2) rgba.blue = tmp; else g_assert_not_reached (); } if (color == COLOR_RGBA) { if (i > 0 && !_gtk_css_parser_try (parser, ",", TRUE)) { _gtk_css_parser_error (parser, "Expected ',' in color definition"); return NULL; } if (!_gtk_css_parser_try_double (parser, &rgba.alpha)) { _gtk_css_parser_error (parser, "Invalid number for alpha value"); return NULL; } } else rgba.alpha = 1.0; symbolic = gtk_symbolic_color_new_literal (&rgba); } else if (color == COLOR_WIN32) { symbolic = _gtk_win32_theme_color_parse (parser); if (symbolic == NULL) return NULL; } else { child1 = _gtk_css_parser_read_symbolic_color (parser); if (child1 == NULL) return NULL; if (color == COLOR_MIX) { if (!_gtk_css_parser_try (parser, ",", TRUE)) { _gtk_css_parser_error (parser, "Expected ',' in color definition"); gtk_symbolic_color_unref (child1); return NULL; } child2 = _gtk_css_parser_read_symbolic_color (parser); if (child2 == NULL) { gtk_symbolic_color_unref (child1); return NULL; } } else child2 = NULL; if (color == COLOR_LIGHTER) value = 1.3; else if (color == COLOR_DARKER) value = 0.7; else { if (!_gtk_css_parser_try (parser, ",", TRUE)) { _gtk_css_parser_error (parser, "Expected ',' in color definition"); gtk_symbolic_color_unref (child1); if (child2) gtk_symbolic_color_unref (child2); return NULL; } if (!_gtk_css_parser_try_double (parser, &value)) { _gtk_css_parser_error (parser, "Expected number in color definition"); gtk_symbolic_color_unref (child1); if (child2) gtk_symbolic_color_unref (child2); return NULL; } } switch (color) { case COLOR_LIGHTER: case COLOR_DARKER: case COLOR_SHADE: symbolic = gtk_symbolic_color_new_shade (child1, value); break; case COLOR_ALPHA: symbolic = gtk_symbolic_color_new_alpha (child1, value); break; case COLOR_MIX: symbolic = gtk_symbolic_color_new_mix (child1, child2, value); break; default: g_assert_not_reached (); symbolic = NULL; } gtk_symbolic_color_unref (child1); if (child2) gtk_symbolic_color_unref (child2); } if (!_gtk_css_parser_try (parser, ")", TRUE)) { _gtk_css_parser_error (parser, "Expected ')' in color definition"); gtk_symbolic_color_unref (symbolic); return NULL; } return symbolic; }
static gboolean gtk_css_image_win32_parse (GtkCssImage *image, GtkCssParser *parser) { GtkCssImageWin32 *wimage = GTK_CSS_IMAGE_WIN32 (image); if (!_gtk_css_parser_try (parser, "-gtk-win32-theme-part", TRUE)) { _gtk_css_parser_error (parser, "'-gtk-win32-theme-part'"); return FALSE; } if (!_gtk_css_parser_try (parser, "(", TRUE)) { _gtk_css_parser_error (parser, "Expected '(' after '-gtk-win32-theme-part'"); return FALSE; } wimage->theme = gtk_win32_theme_parse (parser); if (wimage->theme == NULL) return FALSE; if (! _gtk_css_parser_try (parser, ",", TRUE)) { _gtk_css_parser_error (parser, "Expected ','"); return FALSE; } if (!_gtk_css_parser_try_int (parser, &wimage->part)) { _gtk_css_parser_error (parser, "Expected a valid integer value"); return FALSE; } if (! _gtk_css_parser_try (parser, ",", TRUE)) { _gtk_css_parser_error (parser, "Expected ','"); return FALSE; } if (!_gtk_css_parser_try_int (parser, &wimage->state)) { _gtk_css_parser_error (parser, "Expected a valid integer value"); return FALSE; } while ( _gtk_css_parser_try (parser, ",", TRUE)) { if ( _gtk_css_parser_try (parser, "over", TRUE)) { if (!_gtk_css_parser_try (parser, "(", TRUE)) { _gtk_css_parser_error (parser, "Expected '(' after 'over'"); return FALSE; } if (!_gtk_css_parser_try_int (parser, &wimage->part2)) { _gtk_css_parser_error (parser, "Expected a valid integer value"); return FALSE; } if (! _gtk_css_parser_try (parser, ",", TRUE)) { _gtk_css_parser_error (parser, "Expected ','"); return FALSE; } if (!_gtk_css_parser_try_int (parser, &wimage->state2)) { _gtk_css_parser_error (parser, "Expected a valid integer value"); return FALSE; } if ( _gtk_css_parser_try (parser, ",", TRUE)) { if (!_gtk_css_parser_try_double (parser, &wimage->over_alpha)) { _gtk_css_parser_error (parser, "Expected a valid double value"); return FALSE; } } if (!_gtk_css_parser_try (parser, ")", TRUE)) { _gtk_css_parser_error (parser, "Expected ')' at end of 'over'"); return FALSE; } } else if ( _gtk_css_parser_try (parser, "margins", TRUE)) { guint i; if (!_gtk_css_parser_try (parser, "(", TRUE)) { _gtk_css_parser_error (parser, "Expected '(' after 'margins'"); return FALSE; } for (i = 0; i < 4; i++) { if (!_gtk_css_parser_try_int (parser, &wimage->margins[i])) break; } if (i == 0) { _gtk_css_parser_error (parser, "Expected valid margins"); return FALSE; } if (i == 1) wimage->margins[1] = wimage->margins[0]; if (i <= 2) wimage->margins[2] = wimage->margins[1]; if (i <= 3) wimage->margins[3] = wimage->margins[2]; if (!_gtk_css_parser_try (parser, ")", TRUE)) { _gtk_css_parser_error (parser, "Expected ')' at end of 'margins'"); return FALSE; } } else { _gtk_css_parser_error (parser, "Expected identifier"); return FALSE; } } if (!_gtk_css_parser_try (parser, ")", TRUE)) { _gtk_css_parser_error (parser, "Expected ')'"); return FALSE; } return TRUE; }
static gboolean slice_value_parse (GtkCssParser *parser, GFile *base, GValue *value) { gdouble distance_top, distance_bottom; gdouble distance_left, distance_right; GtkSliceSideModifier mods[2]; GdkPixbuf *pixbuf; Gtk9Slice *slice; GFile *file; GError *error = NULL; gint i; char *path; /* Parse image url */ file = _gtk_css_parse_url (parser, base); if (!file) return FALSE; if (!_gtk_css_parser_try_double (parser, &distance_top) || !_gtk_css_parser_try_double (parser, &distance_right) || !_gtk_css_parser_try_double (parser, &distance_bottom) || !_gtk_css_parser_try_double (parser, &distance_left)) { _gtk_css_parser_error (parser, "Expected a number"); g_object_unref (file); return FALSE; } for (i = 0; i < 2; i++) { if (_gtk_css_parser_try (parser, "stretch", TRUE)) mods[i] = GTK_SLICE_STRETCH; else if (_gtk_css_parser_try (parser, "repeat", TRUE)) mods[i] = GTK_SLICE_REPEAT; else if (i == 0) { mods[1] = mods[0] = GTK_SLICE_STRETCH; break; } else mods[i] = mods[0]; } path = g_file_get_path (file); g_object_unref (file); pixbuf = gdk_pixbuf_new_from_file (path, &error); g_free (path); if (!pixbuf) { _gtk_css_parser_take_error (parser, error); return FALSE; } slice = _gtk_9slice_new (pixbuf, distance_top, distance_bottom, distance_left, distance_right, mods[0], mods[1]); g_object_unref (pixbuf); g_value_take_boxed (value, slice); return TRUE; }