diff --git a/gtk/gtkcsscolorvalue.c b/gtk/gtkcsscolorvalue.c index 5903e49ad1..2ed4804654 100644 --- a/gtk/gtkcsscolorvalue.c +++ b/gtk/gtkcsscolorvalue.c @@ -593,6 +593,41 @@ apply_color_mix (GtkCssColorSpace in, missing); } +static GtkCssValue * +resolve_relative (GtkCssValue *values[4], + GtkCssColorSpace color_space, + gboolean legacy_rgb_scale) +{ + float v[4]; + gboolean m[4]; + + for (guint i = 0; i < 4; i++) + { + if (values[i]) + { + m[i] = FALSE; + v[i] = gtk_css_number_value_get_canonical (values[i], 1); + } + else + { + m[i] = TRUE; + v[i] = 0; + } + } + + if (color_space == GTK_CSS_COLOR_SPACE_SRGB && + legacy_rgb_scale) + { + v[0] /= 255.; + v[1] /= 255.; + v[2] /= 255.; + } + + v[3] = CLAMP (v[3], 0, 1); /* clamp alpha */ + + return gtk_css_color_value_new_color (color_space, FALSE, v, m); +} + static GtkCssValue * gtk_css_color_value_do_resolve (GtkCssValue *color, guint property_id, @@ -613,39 +648,23 @@ gtk_css_color_value_do_resolve (GtkCssValue *color, case COLOR_TYPE_RELATIVE: { - float v[4]; - gboolean m[4]; + GtkCssValue *vals[4]; for (guint i = 0; i < 4; i++) { if (color->relative.values[i]) - { - GtkCssValue *val; - - m[i] = FALSE; - val = gtk_css_value_compute (color->relative.values[i], property_id, context); - v[i] = gtk_css_number_value_get_canonical (val, 1); - - gtk_css_value_unref (val); - } + vals[i] = gtk_css_value_compute (color->relative.values[i], property_id, context); else - { - m[i] = TRUE; - v[i] = 0; - } + vals[i] = NULL; } - if (color->relative.color_space == GTK_CSS_COLOR_SPACE_SRGB && - color->relative.legacy_srgb) + value = resolve_relative (vals, color->relative.color_space, color->relative.legacy_srgb); + + for (guint i = 0; i < 4; i++) { - v[0] /= 255.; - v[1] /= 255.; - v[2] /= 255.; + if (vals[i]) + gtk_css_value_unref (vals[i]); } - - v[3] = CLAMP (v[3], 0, 1); /* clamp alpha */ - - value = gtk_css_color_value_new_color (color->relative.color_space, FALSE, v, m); } break; @@ -852,6 +871,25 @@ gtk_css_color_value_new_relative (GtkCssValue *origin, GtkCssValue *values[4]) { GtkCssValue *value; + gboolean computed = TRUE; + + if (!gtk_css_value_is_computed (origin)) + computed = FALSE; + + if (!computed) + { + for (guint i = 0; i < 4; i++) + { + if (values[i] && !gtk_css_value_is_computed (values[i])) + { + computed = FALSE; + break; + } + } + } + + if (computed) + return resolve_relative (values, color_space, legacy_srgb); value = gtk_css_value_alloc (>K_CSS_VALUE_COLOR, sizeof (GtkCssValue) + sizeof (GtkCssValue *) * 3); diff --git a/testsuite/css/parser/relative-color.css b/testsuite/css/parser/relative-color.css index 0edd44f797..974f7924ba 100644 --- a/testsuite/css/parser/relative-color.css +++ b/testsuite/css/parser/relative-color.css @@ -22,3 +22,7 @@ e { f { color: rgb(from rgba(30,40,50,60) r g 100 / alpha); } + +g { + color: rgb(from currentColor r g 100 / 50%); +} diff --git a/testsuite/css/parser/relative-color.ref.css b/testsuite/css/parser/relative-color.ref.css index 04ce8a59d1..e48c0ce02f 100644 --- a/testsuite/css/parser/relative-color.ref.css +++ b/testsuite/css/parser/relative-color.ref.css @@ -12,9 +12,13 @@ c { } e { - color: color(from rgb(184,134,11) srgb 184 134 100 / 50%); + color: color(srgb 0.721569 0.52549 0.392157 / 0.5); } f { color: color(srgb 0.117647 0.156863 0.392157); } + +g { + color: color(from currentcolor srgb r g 100 / 50%); +}