mirror of
https://gitlab.gnome.org/GNOME/gtk.git
synced 2024-11-09 18:30:08 +00:00
Merge branch 'wip/alice/colors-2' into 'main'
Implement color-mix() See merge request GNOME/gtk!7336
This commit is contained in:
commit
130485a583
@ -73,46 +73,54 @@ append_color_component (GString *string,
|
||||
g_string_append_printf (string, "%g", gtk_css_color_get_component (color, idx));
|
||||
}
|
||||
|
||||
static void
|
||||
print_as_rgb (const GtkCssColor *color,
|
||||
GString *string)
|
||||
{
|
||||
GtkCssColor tmp;
|
||||
|
||||
gtk_css_color_convert (color, GTK_CSS_COLOR_SPACE_SRGB, &tmp);
|
||||
if (tmp.values[3] > 0.999)
|
||||
{
|
||||
g_string_append_printf (string, "rgb(%d,%d,%d)",
|
||||
(int)(0.5 + CLAMP (tmp.values[0], 0., 1.) * 255.),
|
||||
(int)(0.5 + CLAMP (tmp.values[1], 0., 1.) * 255.),
|
||||
(int)(0.5 + CLAMP (tmp.values[2], 0., 1.) * 255.));
|
||||
}
|
||||
else
|
||||
{
|
||||
char alpha[G_ASCII_DTOSTR_BUF_SIZE];
|
||||
|
||||
g_ascii_formatd (alpha, G_ASCII_DTOSTR_BUF_SIZE, "%g", CLAMP (tmp.values[3], 0, 1));
|
||||
|
||||
g_string_append_printf (string, "rgba(%d,%d,%d,%s)",
|
||||
(int)(0.5 + CLAMP (tmp.values[0], 0., 1.) * 255.),
|
||||
(int)(0.5 + CLAMP (tmp.values[1], 0., 1.) * 255.),
|
||||
(int)(0.5 + CLAMP (tmp.values[2], 0., 1.) * 255.),
|
||||
alpha);
|
||||
}
|
||||
}
|
||||
|
||||
GString *
|
||||
gtk_css_color_print (const GtkCssColor *color,
|
||||
gboolean serialize_as_rgb,
|
||||
GString *string)
|
||||
{
|
||||
GtkCssColorSpace print_color_space = color->color_space;
|
||||
GtkCssColor tmp;
|
||||
|
||||
switch (color->color_space)
|
||||
{
|
||||
case GTK_CSS_COLOR_SPACE_SRGB:
|
||||
case GTK_CSS_COLOR_SPACE_HSL:
|
||||
case GTK_CSS_COLOR_SPACE_HWB:
|
||||
print_rgb:
|
||||
{
|
||||
GtkCssColor tmp;
|
||||
|
||||
gtk_css_color_convert (color, GTK_CSS_COLOR_SPACE_SRGB, &tmp);
|
||||
if (tmp.values[3] > 0.999)
|
||||
{
|
||||
g_string_append_printf (string, "rgb(%d,%d,%d)",
|
||||
(int)(0.5 + CLAMP (tmp.values[0], 0., 1.) * 255.),
|
||||
(int)(0.5 + CLAMP (tmp.values[1], 0., 1.) * 255.),
|
||||
(int)(0.5 + CLAMP (tmp.values[2], 0., 1.) * 255.));
|
||||
}
|
||||
else
|
||||
{
|
||||
char alpha[G_ASCII_DTOSTR_BUF_SIZE];
|
||||
|
||||
g_ascii_formatd (alpha, G_ASCII_DTOSTR_BUF_SIZE, "%g", CLAMP (tmp.values[3], 0, 1));
|
||||
|
||||
g_string_append_printf (string, "rgba(%d,%d,%d,%s)",
|
||||
(int)(0.5 + CLAMP (tmp.values[0], 0., 1.) * 255.),
|
||||
(int)(0.5 + CLAMP (tmp.values[1], 0., 1.) * 255.),
|
||||
(int)(0.5 + CLAMP (tmp.values[2], 0., 1.) * 255.),
|
||||
alpha);
|
||||
}
|
||||
}
|
||||
return string;
|
||||
|
||||
case GTK_CSS_COLOR_SPACE_SRGB:
|
||||
if (serialize_as_rgb)
|
||||
goto print_rgb;
|
||||
{
|
||||
print_as_rgb (color, string);
|
||||
return string;
|
||||
}
|
||||
|
||||
print_color_space = GTK_CSS_COLOR_SPACE_SRGB;
|
||||
g_string_append (string, "color(srgb ");
|
||||
break;
|
||||
|
||||
@ -132,18 +140,23 @@ print_rgb:
|
||||
g_assert_not_reached ();
|
||||
}
|
||||
|
||||
if (print_color_space != color->color_space)
|
||||
gtk_css_color_convert (color, print_color_space, &tmp);
|
||||
else
|
||||
tmp = *color;
|
||||
|
||||
for (guint i = 0; i < 3; i++)
|
||||
{
|
||||
if (i > 0)
|
||||
g_string_append_c (string, ' ');
|
||||
append_color_component (string, color, i);
|
||||
append_color_component (string, &tmp, i);
|
||||
}
|
||||
|
||||
if (gtk_css_color_component_missing (color, 3) ||
|
||||
color->values[3] < 0.999)
|
||||
if (gtk_css_color_component_missing (&tmp, 3) ||
|
||||
tmp.values[3] < 0.999)
|
||||
{
|
||||
g_string_append (string, " / ");
|
||||
append_color_component (string, color, 3);
|
||||
append_color_component (string, &tmp, 3);
|
||||
}
|
||||
|
||||
g_string_append_c (string, ')');
|
||||
@ -212,6 +225,24 @@ gtk_css_color_space_get_coord_name (GtkCssColorSpace color_space,
|
||||
}
|
||||
}
|
||||
|
||||
static gboolean
|
||||
color_space_is_polar (GtkCssColorSpace color_space)
|
||||
{
|
||||
switch (color_space)
|
||||
{
|
||||
case GTK_CSS_COLOR_SPACE_SRGB:
|
||||
case GTK_CSS_COLOR_SPACE_SRGB_LINEAR:
|
||||
case GTK_CSS_COLOR_SPACE_OKLAB:
|
||||
return FALSE;
|
||||
case GTK_CSS_COLOR_SPACE_HSL:
|
||||
case GTK_CSS_COLOR_SPACE_HWB:
|
||||
case GTK_CSS_COLOR_SPACE_OKLCH:
|
||||
return TRUE;
|
||||
default:
|
||||
g_assert_not_reached ();
|
||||
}
|
||||
}
|
||||
|
||||
/* }}} */
|
||||
/* {{{ Color conversion */
|
||||
|
||||
@ -719,5 +750,157 @@ gtk_css_color_interpolate (const GtkCssColor *from,
|
||||
unpremultiply (output);
|
||||
}
|
||||
|
||||
static gboolean
|
||||
parse_hue_interpolation (GtkCssParser *parser,
|
||||
GtkCssHueInterpolation *interp)
|
||||
{
|
||||
const GtkCssToken *token = gtk_css_parser_get_token (parser);
|
||||
|
||||
if (gtk_css_token_is_ident (token, "shorter"))
|
||||
{
|
||||
gtk_css_parser_consume_token (parser);
|
||||
*interp = GTK_CSS_HUE_INTERPOLATION_SHORTER;
|
||||
}
|
||||
else if (gtk_css_token_is_ident (token, "longer"))
|
||||
{
|
||||
gtk_css_parser_consume_token (parser);
|
||||
*interp = GTK_CSS_HUE_INTERPOLATION_LONGER;
|
||||
}
|
||||
else if (gtk_css_token_is_ident (token, "increasing"))
|
||||
{
|
||||
gtk_css_parser_consume_token (parser);
|
||||
*interp = GTK_CSS_HUE_INTERPOLATION_INCREASING;
|
||||
}
|
||||
else if (gtk_css_token_is_ident (token, "decreasing"))
|
||||
{
|
||||
gtk_css_parser_consume_token (parser);
|
||||
*interp = GTK_CSS_HUE_INTERPOLATION_DECREASING;
|
||||
}
|
||||
else
|
||||
{
|
||||
*interp = GTK_CSS_HUE_INTERPOLATION_SHORTER;
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
if (!gtk_css_parser_try_ident (parser, "hue"))
|
||||
{
|
||||
gtk_css_parser_error_syntax (parser, "Expected 'hue'");
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
gboolean
|
||||
gtk_css_color_interpolation_method_parse (GtkCssParser *parser,
|
||||
GtkCssColorSpace *in,
|
||||
GtkCssHueInterpolation *interp)
|
||||
{
|
||||
const GtkCssToken *token;
|
||||
|
||||
if (!gtk_css_parser_try_ident (parser, "in"))
|
||||
{
|
||||
gtk_css_parser_error_syntax (parser, "Expected 'in'");
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
token = gtk_css_parser_get_token (parser);
|
||||
|
||||
if (gtk_css_token_is_ident (token, "srgb"))
|
||||
{
|
||||
gtk_css_parser_consume_token (parser);
|
||||
*in = GTK_CSS_COLOR_SPACE_SRGB;
|
||||
}
|
||||
else if (gtk_css_token_is_ident (token, "srgb-linear"))
|
||||
{
|
||||
gtk_css_parser_consume_token (parser);
|
||||
*in = GTK_CSS_COLOR_SPACE_SRGB_LINEAR;
|
||||
}
|
||||
else if (gtk_css_token_is_ident (token, "hsl"))
|
||||
{
|
||||
gtk_css_parser_consume_token (parser);
|
||||
*in = GTK_CSS_COLOR_SPACE_HSL;
|
||||
}
|
||||
else if (gtk_css_token_is_ident (token, "hwb"))
|
||||
{
|
||||
gtk_css_parser_consume_token (parser);
|
||||
*in = GTK_CSS_COLOR_SPACE_HWB;
|
||||
}
|
||||
else if (gtk_css_token_is_ident (token, "oklch"))
|
||||
{
|
||||
gtk_css_parser_consume_token (parser);
|
||||
*in = GTK_CSS_COLOR_SPACE_OKLCH;
|
||||
}
|
||||
else if (gtk_css_token_is_ident (token, "oklab"))
|
||||
{
|
||||
gtk_css_parser_consume_token (parser);
|
||||
*in = GTK_CSS_COLOR_SPACE_OKLAB;
|
||||
}
|
||||
else
|
||||
{
|
||||
gtk_css_parser_error_syntax (parser, "Invalid color space");
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
if (color_space_is_polar (*in))
|
||||
return parse_hue_interpolation (parser, interp);
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
gtk_css_color_interpolation_method_print (GtkCssColorSpace in,
|
||||
GtkCssHueInterpolation interp,
|
||||
GString *string)
|
||||
{
|
||||
g_string_append (string, "in ");
|
||||
|
||||
switch (in)
|
||||
{
|
||||
case GTK_CSS_COLOR_SPACE_SRGB:
|
||||
g_string_append (string, "srgb");
|
||||
break;
|
||||
case GTK_CSS_COLOR_SPACE_SRGB_LINEAR:
|
||||
g_string_append (string, "srgb-linear");
|
||||
break;
|
||||
case GTK_CSS_COLOR_SPACE_HSL:
|
||||
g_string_append (string, "hsl");
|
||||
break;
|
||||
case GTK_CSS_COLOR_SPACE_HWB:
|
||||
g_string_append (string, "hwb");
|
||||
break;
|
||||
case GTK_CSS_COLOR_SPACE_OKLCH:
|
||||
g_string_append (string, "oklch");
|
||||
break;
|
||||
case GTK_CSS_COLOR_SPACE_OKLAB:
|
||||
g_string_append (string, "oklab");
|
||||
break;
|
||||
default:
|
||||
g_assert_not_reached ();
|
||||
}
|
||||
|
||||
if (!color_space_is_polar (in))
|
||||
return;
|
||||
|
||||
switch (interp)
|
||||
{
|
||||
case GTK_CSS_HUE_INTERPOLATION_SHORTER:
|
||||
/* shorter is the default mode, don't print it */
|
||||
break;
|
||||
case GTK_CSS_HUE_INTERPOLATION_LONGER:
|
||||
g_string_append (string, " longer hue");
|
||||
break;
|
||||
case GTK_CSS_HUE_INTERPOLATION_INCREASING:
|
||||
g_string_append (string, " increasing hue");
|
||||
break;
|
||||
case GTK_CSS_HUE_INTERPOLATION_DECREASING:
|
||||
g_string_append (string, " decreasing hue");
|
||||
break;
|
||||
default:
|
||||
g_assert_not_reached ();
|
||||
}
|
||||
}
|
||||
|
||||
/* }}} */
|
||||
/* vim:set foldmethod=marker expandtab: */
|
||||
|
@ -20,6 +20,8 @@
|
||||
#include <glib.h>
|
||||
#include <math.h>
|
||||
|
||||
#include "gtk/css/gtkcssparserprivate.h"
|
||||
|
||||
G_BEGIN_DECLS
|
||||
|
||||
typedef enum {
|
||||
@ -112,4 +114,12 @@ void gtk_css_color_interpolate (const GtkCssColor *from,
|
||||
const char * gtk_css_color_space_get_coord_name (GtkCssColorSpace color_space,
|
||||
guint coord);
|
||||
|
||||
gboolean gtk_css_color_interpolation_method_parse (GtkCssParser *parser,
|
||||
GtkCssColorSpace *in,
|
||||
GtkCssHueInterpolation *interp);
|
||||
|
||||
void gtk_css_color_interpolation_method_print (GtkCssColorSpace in,
|
||||
GtkCssHueInterpolation interp,
|
||||
GString *string);
|
||||
|
||||
G_END_DECLS
|
||||
|
@ -35,12 +35,12 @@
|
||||
static GtkCssValue * gtk_css_color_value_new_mix (GtkCssValue *color1,
|
||||
GtkCssValue *color2,
|
||||
double factor);
|
||||
static GtkCssValue * gtk_css_color_value_new_literal (const GdkRGBA *color);
|
||||
static GtkCssValue * gtk_css_color_value_new_color_from_rgba (const GdkRGBA *rgba);
|
||||
|
||||
typedef enum {
|
||||
COLOR_TYPE_LITERAL,
|
||||
COLOR_TYPE_COLOR,
|
||||
COLOR_TYPE_NAME,
|
||||
COLOR_TYPE_COLOR_MIX,
|
||||
COLOR_TYPE_SHADE,
|
||||
COLOR_TYPE_ALPHA,
|
||||
COLOR_TYPE_MIX,
|
||||
@ -59,6 +59,16 @@ struct _GtkCssValue
|
||||
char *name;
|
||||
GtkCssColor color;
|
||||
|
||||
struct
|
||||
{
|
||||
GtkCssColorSpace color_space;
|
||||
GtkCssHueInterpolation hue_interpolation;
|
||||
GtkCssValue *color1;
|
||||
GtkCssValue *color2;
|
||||
float percentage1;
|
||||
float percentage2;
|
||||
} color_mix;
|
||||
|
||||
struct
|
||||
{
|
||||
GtkCssValue *color;
|
||||
@ -85,6 +95,11 @@ gtk_css_value_color_free (GtkCssValue *color)
|
||||
g_free (color->name);
|
||||
break;
|
||||
|
||||
case COLOR_TYPE_COLOR_MIX:
|
||||
gtk_css_value_unref (color->color_mix.color1);
|
||||
gtk_css_value_unref (color->color_mix.color2);
|
||||
break;
|
||||
|
||||
case COLOR_TYPE_SHADE:
|
||||
gtk_css_value_unref (color->shade.color);
|
||||
break;
|
||||
@ -98,7 +113,6 @@ gtk_css_value_color_free (GtkCssValue *color)
|
||||
gtk_css_value_unref (color->mix.color2);
|
||||
break;
|
||||
|
||||
case COLOR_TYPE_LITERAL:
|
||||
case COLOR_TYPE_COLOR:
|
||||
case COLOR_TYPE_CURRENT_COLOR:
|
||||
default:
|
||||
@ -169,7 +183,7 @@ gtk_css_value_color_compute (GtkCssValue *value,
|
||||
context->provider,
|
||||
current);
|
||||
}
|
||||
else if (value->type == COLOR_TYPE_LITERAL)
|
||||
else if (value->type == COLOR_TYPE_COLOR)
|
||||
{
|
||||
resolved = gtk_css_value_ref (value);
|
||||
}
|
||||
@ -192,28 +206,27 @@ static gboolean
|
||||
gtk_css_value_color_equal (const GtkCssValue *value1,
|
||||
const GtkCssValue *value2)
|
||||
{
|
||||
if (value1->type == COLOR_TYPE_COLOR && value1->color.missing == 0 &&
|
||||
value2->type == COLOR_TYPE_LITERAL)
|
||||
return gdk_rgba_equal (&value1->rgba, &value2->rgba);
|
||||
|
||||
if (value2->type == COLOR_TYPE_COLOR && value2->color.missing == 0 &&
|
||||
value1->type == COLOR_TYPE_LITERAL)
|
||||
return gdk_rgba_equal (&value1->rgba, &value2->rgba);
|
||||
|
||||
if (value1->type != value2->type)
|
||||
return FALSE;
|
||||
|
||||
switch (value1->type)
|
||||
{
|
||||
case COLOR_TYPE_LITERAL:
|
||||
return gdk_rgba_equal (&value1->rgba, &value2->rgba);
|
||||
|
||||
case COLOR_TYPE_COLOR:
|
||||
return gtk_css_color_equal (&value1->color, &value2->color);
|
||||
|
||||
case COLOR_TYPE_NAME:
|
||||
return g_str_equal (value1->name, value2->name);
|
||||
|
||||
case COLOR_TYPE_COLOR_MIX:
|
||||
return value1->color_mix.color_space == value2->color_mix.color_space &&
|
||||
value1->color_mix.hue_interpolation == value2->color_mix.hue_interpolation &&
|
||||
value1->color_mix.percentage1 == value2->color_mix.percentage1 &&
|
||||
value1->color_mix.percentage2 == value2->color_mix.percentage2 &&
|
||||
gtk_css_value_equal (value1->color_mix.color1,
|
||||
value2->color_mix.color1) &&
|
||||
gtk_css_value_equal (value1->color_mix.color2,
|
||||
value2->color_mix.color2);
|
||||
|
||||
case COLOR_TYPE_SHADE:
|
||||
return value1->shade.factor == value2->shade.factor &&
|
||||
gtk_css_value_equal (value1->shade.color,
|
||||
@ -240,6 +253,50 @@ gtk_css_value_color_equal (const GtkCssValue *value1,
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
normalize_color_mix_percentages (float p1,
|
||||
float p2,
|
||||
float *out_p1,
|
||||
float *out_p2,
|
||||
float *alpha_multiplier)
|
||||
{
|
||||
*alpha_multiplier = 1;
|
||||
|
||||
if (p1 < -0.5 && p2 < -0.5)
|
||||
{
|
||||
if (out_p1)
|
||||
*out_p1 = 50;
|
||||
if (out_p2)
|
||||
*out_p2 = 50;
|
||||
return;
|
||||
}
|
||||
|
||||
if (p1 < -0.5)
|
||||
{
|
||||
if (out_p1)
|
||||
*out_p1 = 100 - p2;
|
||||
if (out_p2)
|
||||
*out_p2 = p2;
|
||||
return;
|
||||
}
|
||||
|
||||
if (p2 < -0.5)
|
||||
{
|
||||
if (out_p1)
|
||||
*out_p1 = p1;
|
||||
if (out_p2)
|
||||
*out_p2 = 100 - p1;
|
||||
return;
|
||||
}
|
||||
|
||||
if (out_p1)
|
||||
*out_p1 = p1 / (p1 + p2) * 100;
|
||||
if (out_p2)
|
||||
*out_p2 = p2 / (p1 + p2) * 100;
|
||||
if (alpha_multiplier)
|
||||
*alpha_multiplier = MIN (1, (p1 + p2) * 0.01);
|
||||
}
|
||||
|
||||
static GtkCssValue *
|
||||
gtk_css_value_color_transition (GtkCssValue *start,
|
||||
GtkCssValue *end,
|
||||
@ -257,10 +314,6 @@ gtk_css_value_color_print (const GtkCssValue *value,
|
||||
|
||||
switch (value->type)
|
||||
{
|
||||
case COLOR_TYPE_LITERAL:
|
||||
gdk_rgba_print (&value->rgba, string);
|
||||
break;
|
||||
|
||||
case COLOR_TYPE_COLOR:
|
||||
gtk_css_color_print (&value->color, value->serialize_as_rgb, string);
|
||||
break;
|
||||
@ -270,6 +323,56 @@ gtk_css_value_color_print (const GtkCssValue *value,
|
||||
g_string_append (string, value->name);
|
||||
break;
|
||||
|
||||
case COLOR_TYPE_COLOR_MIX:
|
||||
{
|
||||
char percent[G_ASCII_DTOSTR_BUF_SIZE];
|
||||
float p1 = value->color_mix.percentage1;
|
||||
float p2 = value->color_mix.percentage2;
|
||||
gboolean p1_present = p1 > -0.5;
|
||||
gboolean p2_present = p2 > -0.5;
|
||||
gboolean defaults = (!p1_present || G_APPROX_VALUE (p1, 50, FLT_EPSILON)) &&
|
||||
(!p2_present || G_APPROX_VALUE (p2, 50, FLT_EPSILON));
|
||||
|
||||
if (!p1_present && p2_present && !defaults)
|
||||
{
|
||||
p1 = 100 - p2;
|
||||
p1_present = TRUE;
|
||||
p2_present = FALSE;
|
||||
}
|
||||
|
||||
g_string_append (string, "color-mix(");
|
||||
gtk_css_color_interpolation_method_print (value->color_mix.color_space,
|
||||
value->color_mix.hue_interpolation,
|
||||
string);
|
||||
|
||||
g_string_append (string, ", ");
|
||||
|
||||
gtk_css_value_print (value->color_mix.color1, string);
|
||||
|
||||
if (p1_present && !defaults)
|
||||
{
|
||||
g_ascii_dtostr (percent, sizeof (percent), p1);
|
||||
g_string_append_c (string, ' ');
|
||||
g_string_append (string, percent);
|
||||
g_string_append_c (string, '%');
|
||||
}
|
||||
|
||||
g_string_append (string, ", ");
|
||||
|
||||
gtk_css_value_print (value->color_mix.color2, string);
|
||||
|
||||
if (p2_present && !defaults)
|
||||
{
|
||||
g_ascii_dtostr (percent, sizeof (percent), p2);
|
||||
g_string_append_c (string, ' ');
|
||||
g_string_append (string, percent);
|
||||
g_string_append_c (string, '%');
|
||||
}
|
||||
|
||||
g_string_append (string, ")");
|
||||
}
|
||||
break;
|
||||
|
||||
case COLOR_TYPE_SHADE:
|
||||
g_string_append (string, "shade(");
|
||||
gtk_css_value_print (value->shade.color, string);
|
||||
@ -373,6 +476,36 @@ apply_mix (const GdkRGBA *in1,
|
||||
}
|
||||
}
|
||||
|
||||
static GtkCssValue *
|
||||
apply_color_mix (GtkCssColorSpace in,
|
||||
GtkCssHueInterpolation interp,
|
||||
const GtkCssValue *value1,
|
||||
const GtkCssValue *value2,
|
||||
float percentage1,
|
||||
float percentage2)
|
||||
{
|
||||
float p2, alpha_multiplier;
|
||||
GtkCssColor output;
|
||||
gboolean missing[4];
|
||||
int i;
|
||||
|
||||
normalize_color_mix_percentages (percentage1, percentage2,
|
||||
NULL, &p2, &alpha_multiplier);
|
||||
|
||||
gtk_css_color_interpolate (&value1->color, &value2->color,
|
||||
p2 * 0.01, in, interp, &output);
|
||||
|
||||
output.values[3] *= alpha_multiplier;
|
||||
|
||||
for (i = 0; i < 4; i++)
|
||||
missing[i] = gtk_css_color_component_missing (&output, i);
|
||||
|
||||
return gtk_css_color_value_new_color (output.color_space,
|
||||
FALSE,
|
||||
output.values,
|
||||
missing);
|
||||
}
|
||||
|
||||
static GtkCssValue *
|
||||
gtk_css_color_value_do_resolve (GtkCssValue *color,
|
||||
GtkStyleProvider *provider,
|
||||
@ -385,7 +518,6 @@ gtk_css_color_value_do_resolve (GtkCssValue *color,
|
||||
|
||||
switch (color->type)
|
||||
{
|
||||
case COLOR_TYPE_LITERAL:
|
||||
case COLOR_TYPE_COLOR:
|
||||
value = gtk_css_value_ref (color);
|
||||
break;
|
||||
@ -408,6 +540,24 @@ gtk_css_color_value_do_resolve (GtkCssValue *color,
|
||||
}
|
||||
break;
|
||||
|
||||
case COLOR_TYPE_COLOR_MIX:
|
||||
{
|
||||
GtkCssValue *val1, *val2;
|
||||
|
||||
val1 = gtk_css_color_value_do_resolve (color->color_mix.color1, provider, current, cycle_list);
|
||||
val2 = gtk_css_color_value_do_resolve (color->color_mix.color2, provider, current, cycle_list);
|
||||
|
||||
value = apply_color_mix (color->color_mix.color_space,
|
||||
color->color_mix.hue_interpolation,
|
||||
val1, val2,
|
||||
color->color_mix.percentage1,
|
||||
color->color_mix.percentage2);
|
||||
|
||||
gtk_css_value_unref (val1);
|
||||
gtk_css_value_unref (val2);
|
||||
}
|
||||
break;
|
||||
|
||||
case COLOR_TYPE_SHADE:
|
||||
{
|
||||
const GdkRGBA *c;
|
||||
@ -421,7 +571,7 @@ gtk_css_color_value_do_resolve (GtkCssValue *color,
|
||||
|
||||
apply_shade (c, &shade, color->shade.factor);
|
||||
|
||||
value = gtk_css_color_value_new_literal (&shade);
|
||||
value = gtk_css_color_value_new_color_from_rgba (&shade);
|
||||
gtk_css_value_unref (val);
|
||||
}
|
||||
break;
|
||||
@ -439,7 +589,7 @@ gtk_css_color_value_do_resolve (GtkCssValue *color,
|
||||
|
||||
apply_alpha (c, &alpha, color->alpha.factor);
|
||||
|
||||
value = gtk_css_color_value_new_literal (&alpha);
|
||||
value = gtk_css_color_value_new_color_from_rgba (&alpha);
|
||||
gtk_css_value_unref (val);
|
||||
}
|
||||
break;
|
||||
@ -462,7 +612,7 @@ gtk_css_color_value_do_resolve (GtkCssValue *color,
|
||||
|
||||
apply_mix (color1, color2, &res, color->mix.factor);
|
||||
|
||||
value = gtk_css_color_value_new_literal (&res);
|
||||
value = gtk_css_color_value_new_color_from_rgba (&res);
|
||||
gtk_css_value_unref (val1);
|
||||
gtk_css_value_unref (val2);
|
||||
}
|
||||
@ -494,10 +644,12 @@ gtk_css_color_value_resolve (GtkCssValue *color,
|
||||
/* }}} */
|
||||
/* {{{ Constructors */
|
||||
|
||||
static GtkCssValue transparent_black_singleton = { >K_CSS_VALUE_COLOR, 1, TRUE, FALSE, FALSE, COLOR_TYPE_LITERAL,
|
||||
.rgba = {0, 0, 0, 0} };
|
||||
static GtkCssValue white_singleton = { >K_CSS_VALUE_COLOR, 1, TRUE, FALSE, FALSE, COLOR_TYPE_LITERAL,
|
||||
.rgba = {1, 1, 1, 1} };
|
||||
static GtkCssValue transparent_black_singleton = { >K_CSS_VALUE_COLOR, 1, TRUE, FALSE, TRUE, COLOR_TYPE_COLOR,
|
||||
.rgba = {0, 0, 0, 0},
|
||||
.color = { GTK_CSS_COLOR_SPACE_SRGB, {0, 0, 0, 0}, 0 } };
|
||||
static GtkCssValue white_singleton = { >K_CSS_VALUE_COLOR, 1, TRUE, FALSE, TRUE, COLOR_TYPE_COLOR,
|
||||
.rgba = {1, 1, 1, 1},
|
||||
.color = { GTK_CSS_COLOR_SPACE_SRGB, {1, 1, 1, 1}, 0 } };
|
||||
|
||||
|
||||
GtkCssValue *
|
||||
@ -512,27 +664,6 @@ gtk_css_color_value_new_white (void)
|
||||
return gtk_css_value_ref (&white_singleton);
|
||||
}
|
||||
|
||||
static GtkCssValue *
|
||||
gtk_css_color_value_new_literal (const GdkRGBA *color)
|
||||
{
|
||||
GtkCssValue *value;
|
||||
|
||||
g_return_val_if_fail (color != NULL, NULL);
|
||||
|
||||
if (gdk_rgba_equal (color, &white_singleton.rgba))
|
||||
return gtk_css_value_ref (&white_singleton);
|
||||
|
||||
if (gdk_rgba_equal (color, &transparent_black_singleton.rgba))
|
||||
return gtk_css_value_ref (&transparent_black_singleton);
|
||||
|
||||
value = gtk_css_value_new (GtkCssValue, >K_CSS_VALUE_COLOR);
|
||||
value->type = COLOR_TYPE_LITERAL;
|
||||
value->is_computed = TRUE;
|
||||
value->rgba = *color;
|
||||
|
||||
return value;
|
||||
}
|
||||
|
||||
GtkCssValue *
|
||||
gtk_css_color_value_new_color (GtkCssColorSpace color_space,
|
||||
gboolean serialize_as_rgb,
|
||||
@ -559,6 +690,33 @@ gtk_css_color_value_new_color (GtkCssColorSpace color_space,
|
||||
return value;
|
||||
}
|
||||
|
||||
static GtkCssValue *
|
||||
gtk_css_color_value_new_color_from_rgba (const GdkRGBA *rgba)
|
||||
{
|
||||
GtkCssValue *value;
|
||||
|
||||
g_return_val_if_fail (rgba != NULL, NULL);
|
||||
|
||||
if (gdk_rgba_equal (rgba, &white_singleton.rgba))
|
||||
return gtk_css_value_ref (&white_singleton);
|
||||
|
||||
if (gdk_rgba_equal (rgba, &transparent_black_singleton.rgba))
|
||||
return gtk_css_value_ref (&transparent_black_singleton);
|
||||
|
||||
value = gtk_css_value_new (GtkCssValue, >K_CSS_VALUE_COLOR);
|
||||
value->color.color_space = GTK_CSS_COLOR_SPACE_SRGB;
|
||||
value->is_computed = TRUE;
|
||||
value->serialize_as_rgb = TRUE;
|
||||
value->type = COLOR_TYPE_COLOR;
|
||||
gtk_css_color_init (&value->color,
|
||||
GTK_CSS_COLOR_SPACE_SRGB,
|
||||
(float[4]) { rgba->red, rgba->green, rgba->blue, rgba->alpha });
|
||||
|
||||
value->rgba = *rgba;
|
||||
|
||||
return value;
|
||||
}
|
||||
|
||||
GtkCssValue *
|
||||
gtk_css_color_value_new_name (const char *name)
|
||||
{
|
||||
@ -581,13 +739,13 @@ gtk_css_color_value_new_shade (GtkCssValue *color,
|
||||
|
||||
gtk_internal_return_val_if_fail (color->class == >K_CSS_VALUE_COLOR, NULL);
|
||||
|
||||
if (color->type == COLOR_TYPE_LITERAL || color->type == COLOR_TYPE_COLOR)
|
||||
if (color->is_computed)
|
||||
{
|
||||
GdkRGBA c;
|
||||
|
||||
apply_shade (&color->rgba, &c, factor);
|
||||
|
||||
return gtk_css_color_value_new_literal (&c);
|
||||
return gtk_css_color_value_new_color_from_rgba (&c);
|
||||
}
|
||||
|
||||
value = gtk_css_value_new (GtkCssValue, >K_CSS_VALUE_COLOR);
|
||||
@ -606,13 +764,13 @@ gtk_css_color_value_new_alpha (GtkCssValue *color,
|
||||
|
||||
gtk_internal_return_val_if_fail (color->class == >K_CSS_VALUE_COLOR, NULL);
|
||||
|
||||
if (color->type == COLOR_TYPE_LITERAL || color->type == COLOR_TYPE_COLOR)
|
||||
if (color->is_computed)
|
||||
{
|
||||
GdkRGBA c;
|
||||
|
||||
apply_alpha (&color->rgba, &c, factor);
|
||||
|
||||
return gtk_css_color_value_new_literal (&c);
|
||||
return gtk_css_color_value_new_color_from_rgba (&c);
|
||||
}
|
||||
|
||||
value = gtk_css_value_new (GtkCssValue, >K_CSS_VALUE_COLOR);
|
||||
@ -623,6 +781,41 @@ gtk_css_color_value_new_alpha (GtkCssValue *color,
|
||||
return value;
|
||||
}
|
||||
|
||||
static GtkCssValue *
|
||||
gtk_css_color_value_new_color_mix (GtkCssColorSpace color_space,
|
||||
GtkCssHueInterpolation hue_interpolation,
|
||||
GtkCssValue *color1,
|
||||
GtkCssValue *color2,
|
||||
float percentage1,
|
||||
float percentage2)
|
||||
{
|
||||
GtkCssValue *value;
|
||||
|
||||
gtk_internal_return_val_if_fail (color1->class == >K_CSS_VALUE_COLOR, NULL);
|
||||
gtk_internal_return_val_if_fail (color2->class == >K_CSS_VALUE_COLOR, NULL);
|
||||
|
||||
if (percentage1 > -0.5 && percentage2 > -0.5 && fabs (percentage1 + percentage2) < 0.001)
|
||||
return NULL;
|
||||
|
||||
if (color1->is_computed && color2->is_computed)
|
||||
{
|
||||
return apply_color_mix (color_space, hue_interpolation,
|
||||
color1, color2,
|
||||
percentage1, percentage2);
|
||||
}
|
||||
|
||||
value = gtk_css_value_new (GtkCssValue, >K_CSS_VALUE_COLOR);
|
||||
value->type = COLOR_TYPE_COLOR_MIX;
|
||||
value->color_mix.color_space = color_space;
|
||||
value->color_mix.hue_interpolation = hue_interpolation;
|
||||
value->color_mix.color1 = gtk_css_value_ref (color1);
|
||||
value->color_mix.color2 = gtk_css_value_ref (color2);
|
||||
value->color_mix.percentage1 = percentage1;
|
||||
value->color_mix.percentage2 = percentage2;
|
||||
|
||||
return value;
|
||||
}
|
||||
|
||||
static GtkCssValue *
|
||||
gtk_css_color_value_new_mix (GtkCssValue *color1,
|
||||
GtkCssValue *color2,
|
||||
@ -633,14 +826,13 @@ gtk_css_color_value_new_mix (GtkCssValue *color1,
|
||||
gtk_internal_return_val_if_fail (color1->class == >K_CSS_VALUE_COLOR, NULL);
|
||||
gtk_internal_return_val_if_fail (color2->class == >K_CSS_VALUE_COLOR, NULL);
|
||||
|
||||
if ((color1->type == COLOR_TYPE_LITERAL || color1->type == COLOR_TYPE_COLOR) &&
|
||||
(color2->type == COLOR_TYPE_LITERAL || color2->type == COLOR_TYPE_COLOR))
|
||||
if (color1->is_computed && color2->is_computed)
|
||||
{
|
||||
GdkRGBA result;
|
||||
|
||||
apply_mix (&color1->rgba, &color2->rgba, &result, factor);
|
||||
|
||||
return gtk_css_color_value_new_literal (&result);
|
||||
return gtk_css_color_value_new_color_from_rgba (&result);
|
||||
|
||||
}
|
||||
|
||||
@ -684,7 +876,90 @@ gtk_css_color_value_can_parse (GtkCssParser *parser)
|
||||
|| gtk_css_parser_has_function (parser, "hwb")
|
||||
|| gtk_css_parser_has_function (parser, "oklab")
|
||||
|| gtk_css_parser_has_function (parser, "oklch")
|
||||
|| gtk_css_parser_has_function (parser, "color");
|
||||
|| gtk_css_parser_has_function (parser, "color")
|
||||
|| gtk_css_parser_has_function (parser, "color-mix");
|
||||
}
|
||||
|
||||
typedef struct
|
||||
{
|
||||
GtkCssColorSpace color_space;
|
||||
GtkCssHueInterpolation hue_interpolation;
|
||||
GtkCssValue *color1;
|
||||
GtkCssValue *color2;
|
||||
float percentage1;
|
||||
float percentage2;
|
||||
} ColorMixData;
|
||||
|
||||
static gboolean
|
||||
parse_color_mix_component (GtkCssParser *parser,
|
||||
GtkCssValue **value,
|
||||
float *percentage)
|
||||
{
|
||||
*percentage = -1;
|
||||
|
||||
if (gtk_css_color_value_can_parse (parser))
|
||||
{
|
||||
*value = gtk_css_color_value_parse (parser);
|
||||
if (*value == NULL)
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
if (gtk_css_number_value_can_parse (parser))
|
||||
{
|
||||
GtkCssValue *val;
|
||||
val = gtk_css_number_value_parse (parser, GTK_CSS_PARSE_PERCENT | GTK_CSS_POSITIVE_ONLY);
|
||||
if (val == NULL)
|
||||
return FALSE;
|
||||
|
||||
*percentage = gtk_css_number_value_get_canonical (val, 100);
|
||||
|
||||
if (*percentage > 100)
|
||||
{
|
||||
gtk_css_parser_error_syntax (parser, "Values above 100%% are not allowed");
|
||||
gtk_css_value_unref (val);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
gtk_css_value_unref (val);
|
||||
}
|
||||
|
||||
if (*value == NULL)
|
||||
{
|
||||
*value = gtk_css_color_value_parse (parser);
|
||||
if (*value == NULL)
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static guint
|
||||
parse_color_mix (GtkCssParser *parser,
|
||||
guint arg,
|
||||
gpointer data_)
|
||||
{
|
||||
ColorMixData *data = data_;
|
||||
|
||||
switch (arg)
|
||||
{
|
||||
case 0:
|
||||
if (!gtk_css_color_interpolation_method_parse (parser, &data->color_space, &data->hue_interpolation))
|
||||
return 0;
|
||||
return 1;
|
||||
|
||||
case 1:
|
||||
if (!parse_color_mix_component (parser, &data->color1, &data->percentage1))
|
||||
return 0;
|
||||
return 1;
|
||||
|
||||
case 2:
|
||||
if (!parse_color_mix_component (parser, &data->color2, &data->percentage2))
|
||||
return 0;
|
||||
return 1;
|
||||
|
||||
default:
|
||||
g_assert_not_reached ();
|
||||
}
|
||||
}
|
||||
|
||||
typedef struct
|
||||
@ -695,9 +970,9 @@ typedef struct
|
||||
} ColorFunctionData;
|
||||
|
||||
static guint
|
||||
parse_color_mix (GtkCssParser *parser,
|
||||
guint arg,
|
||||
gpointer data_)
|
||||
parse_legacy_mix (GtkCssParser *parser,
|
||||
guint arg,
|
||||
gpointer data_)
|
||||
{
|
||||
ColorFunctionData *data = data_;
|
||||
|
||||
@ -1447,7 +1722,7 @@ gtk_css_color_value_parse (GtkCssParser *parser)
|
||||
if (!parse_color_function (parser, COLOR_SYNTAX_DETECTING, FALSE, TRUE, FALSE, parse_hsla_color_channel, &data))
|
||||
return NULL;
|
||||
|
||||
return gtk_css_color_value_new_color (GTK_CSS_COLOR_SPACE_HSL, FALSE, (float *) &hsla, data.missing);
|
||||
return gtk_css_color_value_new_color (GTK_CSS_COLOR_SPACE_HSL, TRUE, (float *) &hsla, data.missing);
|
||||
}
|
||||
else if (gtk_css_parser_has_function (parser, "hwb"))
|
||||
{
|
||||
@ -1456,7 +1731,7 @@ gtk_css_color_value_parse (GtkCssParser *parser)
|
||||
if (!parse_color_function (parser, COLOR_SYNTAX_MODERN, FALSE, TRUE, FALSE, parse_hwb_color_channel, &hwb))
|
||||
return NULL;
|
||||
|
||||
return gtk_css_color_value_new_color (GTK_CSS_COLOR_SPACE_HWB, FALSE, (float *) &hwb, hwb.missing);
|
||||
return gtk_css_color_value_new_color (GTK_CSS_COLOR_SPACE_HWB, TRUE, (float *) &hwb, hwb.missing);
|
||||
}
|
||||
else if (gtk_css_parser_has_function (parser, "oklab"))
|
||||
{
|
||||
@ -1485,6 +1760,31 @@ gtk_css_color_value_parse (GtkCssParser *parser)
|
||||
|
||||
return gtk_css_color_value_new_color (data.color_space, FALSE, data.values, data.missing);
|
||||
}
|
||||
else if (gtk_css_parser_has_function (parser, "color-mix"))
|
||||
{
|
||||
ColorMixData data;
|
||||
|
||||
data.color1 = NULL;
|
||||
data.color2 = NULL;
|
||||
|
||||
if (gtk_css_parser_consume_function (parser, 3, 3, parse_color_mix, &data))
|
||||
{
|
||||
value = gtk_css_color_value_new_color_mix (data.color_space,
|
||||
data.hue_interpolation,
|
||||
data.color1,
|
||||
data.color2,
|
||||
data.percentage1,
|
||||
data.percentage2);
|
||||
}
|
||||
else
|
||||
{
|
||||
value = NULL;
|
||||
}
|
||||
|
||||
g_clear_pointer (&data.color1, gtk_css_value_unref);
|
||||
g_clear_pointer (&data.color2, gtk_css_value_unref);
|
||||
return value;
|
||||
}
|
||||
else if (gtk_css_parser_has_function (parser, "lighter"))
|
||||
{
|
||||
ColorFunctionData data = { NULL, };
|
||||
@ -1537,7 +1837,7 @@ gtk_css_color_value_parse (GtkCssParser *parser)
|
||||
{
|
||||
ColorFunctionData data = { NULL, };
|
||||
|
||||
if (gtk_css_parser_consume_function (parser, 3, 3, parse_color_mix, &data))
|
||||
if (gtk_css_parser_consume_function (parser, 3, 3, parse_legacy_mix, &data))
|
||||
value = gtk_css_color_value_new_mix (data.color, data.color2, data.value);
|
||||
else
|
||||
value = NULL;
|
||||
@ -1548,7 +1848,7 @@ gtk_css_color_value_parse (GtkCssParser *parser)
|
||||
}
|
||||
|
||||
if (gdk_rgba_parser_parse (parser, &rgba))
|
||||
return gtk_css_color_value_new_literal (&rgba);
|
||||
return gtk_css_color_value_new_color_from_rgba (&rgba);
|
||||
else
|
||||
return NULL;
|
||||
}
|
||||
@ -1560,7 +1860,7 @@ const GdkRGBA *
|
||||
gtk_css_color_value_get_rgba (const GtkCssValue *color)
|
||||
{
|
||||
g_assert (color->class == >K_CSS_VALUE_COLOR);
|
||||
g_assert (color->type == COLOR_TYPE_LITERAL || color->type == COLOR_TYPE_COLOR);
|
||||
g_assert (color->type == COLOR_TYPE_COLOR);
|
||||
|
||||
return &color->rgba;
|
||||
}
|
||||
|
127
testsuite/css/parser/color-mix.css
Normal file
127
testsuite/css/parser/color-mix.css
Normal file
@ -0,0 +1,127 @@
|
||||
a {
|
||||
color: color-mix(in srgb, red, blue);
|
||||
}
|
||||
|
||||
b {
|
||||
color: color-mix(in srgb, red 50%, blue 50%);
|
||||
}
|
||||
|
||||
c {
|
||||
color: color-mix(in srgb, red 25%, blue);
|
||||
}
|
||||
|
||||
d {
|
||||
color: color-mix(in srgb, red, blue 25%);
|
||||
}
|
||||
|
||||
e {
|
||||
color: color-mix(in srgb, red 20%, blue 30%);
|
||||
}
|
||||
|
||||
f {
|
||||
color: color-mix(in srgb, red 60%, blue 90%);
|
||||
}
|
||||
|
||||
g {
|
||||
color: color-mix(in srgb-linear, red, blue);
|
||||
}
|
||||
|
||||
h {
|
||||
color: color-mix(in hsl, red, blue);
|
||||
}
|
||||
|
||||
i {
|
||||
color: color-mix(in hsl shorter hue, red, blue);
|
||||
}
|
||||
|
||||
j {
|
||||
color: color-mix(in hsl longer hue, red, blue);
|
||||
}
|
||||
|
||||
k {
|
||||
color: color-mix(in hsl increasing hue, red, blue);
|
||||
}
|
||||
|
||||
l {
|
||||
color: color-mix(in hsl decreasing hue, red, blue);
|
||||
}
|
||||
|
||||
m {
|
||||
color: color-mix(in hwb shorter hue, red, blue);
|
||||
}
|
||||
|
||||
n {
|
||||
color: color-mix(in oklch shorter hue, red, blue);
|
||||
}
|
||||
|
||||
o {
|
||||
color: color-mix(in oklab, red, blue);
|
||||
}
|
||||
|
||||
p {
|
||||
color: color-mix(in);
|
||||
}
|
||||
|
||||
q {
|
||||
color: color-mix(in srgb);
|
||||
}
|
||||
|
||||
r {
|
||||
color: color-mix(in srgb longer hue, red, blue);
|
||||
}
|
||||
|
||||
s {
|
||||
color: color-mix(in hsl wider hue, red, blue);
|
||||
}
|
||||
|
||||
t {
|
||||
color: color-mix(in hsl, red);
|
||||
}
|
||||
|
||||
u {
|
||||
color: color-mix(in hsl, red, 50%);
|
||||
}
|
||||
|
||||
v {
|
||||
color: color-mix(in hsl, white, black calc(20% + 30%));
|
||||
}
|
||||
|
||||
w {
|
||||
color: color-mix(in srgb, currentColor 50%, transparent 50%);
|
||||
}
|
||||
|
||||
x {
|
||||
color: color-mix(in srgb-linear, currentColor 25%, transparent);
|
||||
}
|
||||
|
||||
y {
|
||||
color: color-mix(in hsl, currentColor, transparent 25%);
|
||||
}
|
||||
|
||||
z {
|
||||
color: color-mix(in srgb-linear, currentColor 50%, transparent);
|
||||
}
|
||||
|
||||
aa {
|
||||
color: color-mix(in hsl, currentColor, transparent 50%);
|
||||
}
|
||||
|
||||
ab {
|
||||
color: color-mix(in hsl longer hue, currentColor 20%, transparent 30%);
|
||||
}
|
||||
|
||||
ac {
|
||||
color: color-mix(in hwb, currentColor 60%, transparent 90%);
|
||||
}
|
||||
|
||||
ad {
|
||||
color: color-mix(in oklch, currentColor 60%, transparent 90%);
|
||||
}
|
||||
|
||||
ae {
|
||||
color: color-mix(in oklab, currentColor 60%, transparent 90%);
|
||||
}
|
||||
|
||||
af {
|
||||
color: color-mix(in srgb, 30% red, 70% blue);
|
||||
}
|
6
testsuite/css/parser/color-mix.errors
Normal file
6
testsuite/css/parser/color-mix.errors
Normal file
@ -0,0 +1,6 @@
|
||||
color-mix.css:62:22-23: error: GTK_CSS_PARSER_ERROR_SYNTAX
|
||||
color-mix.css:66:27-28: error: GTK_CSS_PARSER_ERROR_SYNTAX
|
||||
color-mix.css:70:28-34: error: GTK_CSS_PARSER_ERROR_SYNTAX
|
||||
color-mix.css:74:27-32: error: GTK_CSS_PARSER_ERROR_SYNTAX
|
||||
color-mix.css:78:31-32: error: GTK_CSS_PARSER_ERROR_SYNTAX
|
||||
color-mix.css:82:36-37: error: GTK_CSS_PARSER_ERROR_SYNTAX
|
103
testsuite/css/parser/color-mix.ref.css
Normal file
103
testsuite/css/parser/color-mix.ref.css
Normal file
@ -0,0 +1,103 @@
|
||||
a {
|
||||
color: color(srgb 0.5 0 0.5);
|
||||
}
|
||||
|
||||
b {
|
||||
color: color(srgb 0.5 0 0.5);
|
||||
}
|
||||
|
||||
c {
|
||||
color: color(srgb 0.25 0 0.75);
|
||||
}
|
||||
|
||||
d {
|
||||
color: color(srgb 0.75 0 0.25);
|
||||
}
|
||||
|
||||
e {
|
||||
color: color(srgb 0.4 0 0.6 / 0.5);
|
||||
}
|
||||
|
||||
f {
|
||||
color: color(srgb 0.4 0 0.6);
|
||||
}
|
||||
|
||||
g {
|
||||
color: color(srgb-linear 0.5 0 0.5);
|
||||
}
|
||||
|
||||
h {
|
||||
color: color(srgb 1 0 1);
|
||||
}
|
||||
|
||||
i {
|
||||
color: color(srgb 1 0 1);
|
||||
}
|
||||
|
||||
j {
|
||||
color: color(srgb 0 1 0);
|
||||
}
|
||||
|
||||
k {
|
||||
color: color(srgb 0 1 0);
|
||||
}
|
||||
|
||||
l {
|
||||
color: color(srgb 1 0 1);
|
||||
}
|
||||
|
||||
m {
|
||||
color: color(srgb 1 0 1);
|
||||
}
|
||||
|
||||
n {
|
||||
color: oklch(0.539985 0.285449 326.643);
|
||||
}
|
||||
|
||||
o {
|
||||
color: oklab(0.539985 0.096203 -0.0928409);
|
||||
}
|
||||
|
||||
v {
|
||||
color: color(srgb 0.5 0.5 0.5);
|
||||
}
|
||||
|
||||
w {
|
||||
color: color-mix(in srgb, currentcolor, rgba(0,0,0,0));
|
||||
}
|
||||
|
||||
x {
|
||||
color: color-mix(in srgb-linear, currentcolor 25%, rgba(0,0,0,0));
|
||||
}
|
||||
|
||||
y {
|
||||
color: color-mix(in hsl, currentcolor 75%, rgba(0,0,0,0));
|
||||
}
|
||||
|
||||
z {
|
||||
color: color-mix(in srgb-linear, currentcolor, rgba(0,0,0,0));
|
||||
}
|
||||
|
||||
aa {
|
||||
color: color-mix(in hsl, currentcolor, rgba(0,0,0,0));
|
||||
}
|
||||
|
||||
ab {
|
||||
color: color-mix(in hsl longer hue, currentcolor 20%, rgba(0,0,0,0) 30%);
|
||||
}
|
||||
|
||||
ac {
|
||||
color: color-mix(in hwb, currentcolor 60%, rgba(0,0,0,0) 90%);
|
||||
}
|
||||
|
||||
ad {
|
||||
color: color-mix(in oklch, currentcolor 60%, rgba(0,0,0,0) 90%);
|
||||
}
|
||||
|
||||
ae {
|
||||
color: color-mix(in oklab, currentcolor 60%, rgba(0,0,0,0) 90%);
|
||||
}
|
||||
|
||||
af {
|
||||
color: color(srgb 0.3 0 0.7);
|
||||
}
|
@ -204,6 +204,9 @@ test_data = [
|
||||
'colors-errors.css',
|
||||
'colors-errors.errors',
|
||||
'colors-errors.ref.css',
|
||||
'color-mix.css',
|
||||
'color-mix.errors',
|
||||
'color-mix.ref.css',
|
||||
'colors-red.css',
|
||||
'colors-red.ref.css',
|
||||
'comment-detection.css',
|
||||
|
@ -10,6 +10,7 @@ common_env = [
|
||||
'G_ENABLE_DIAGNOSTIC=0',
|
||||
'GSETTINGS_SCHEMA_DIR=@0@'.format(gtk_schema_build_dir),
|
||||
'GDK_DEBUG=default-settings',
|
||||
'GTK_DEBUG=css',
|
||||
]
|
||||
exclude_unstable = ['flaky', 'failing']
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user