GtkGradient * _gtk_gradient_transition (GtkGradient *start, GtkGradient *end, guint property_id, double progress) { GtkGradient *gradient; guint i; g_return_val_if_fail (start != NULL, NULL); if (end == NULL) return gtk_gradient_fade (start, 1.0 - CLAMP (progress, 0.0, 1.0)); if (start->stops->len != end->stops->len) return NULL; /* check both are radial/linear */ if ((start->radius0 == 0 && start->radius1 == 0) != (end->radius0 == 0 && end->radius1 == 0)) return NULL; gradient = g_slice_new (GtkGradient); gradient->stops = g_array_new (FALSE, FALSE, sizeof (ColorStop)); gradient->x0 = (1 - progress) * start->x0 + progress * end->x0; gradient->y0 = (1 - progress) * start->y0 + progress * end->y0; gradient->x1 = (1 - progress) * start->x1 + progress * end->x1; gradient->y1 = (1 - progress) * start->y1 + progress * end->y1; gradient->radius0 = (1 - progress) * start->radius0 + progress * end->radius0; gradient->radius1 = (1 - progress) * start->radius1 + progress * end->radius1; gradient->ref_count = 1; for (i = 0; i < start->stops->len; i++) { ColorStop *start_stop, *end_stop; GtkSymbolicColor *color; double offset; start_stop = &g_array_index (start->stops, ColorStop, i); end_stop = &g_array_index (end->stops, ColorStop, i); offset = (1 - progress) * start_stop->offset + progress * end_stop->offset; color = gtk_symbolic_color_new_mix (start_stop->color, end_stop->color, progress); gtk_gradient_add_color_stop (gradient, offset, color); gtk_symbolic_color_unref (color); } 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; }