Merge branch 'wip/alice/color-func' into 'main'
csscolorvalue: Add color() support See merge request GNOME/gtk!7286
This commit is contained in:
@@ -335,18 +335,16 @@ gtk_oklab_to_rgb (float L, float a, float b,
|
||||
float linear_green = -1.2684380046f * l + 2.6097574011f * m - 0.3413193965f * s;
|
||||
float linear_blue = -0.0041960863f * l - 0.7034186147f * m + 1.7076147010f * s;
|
||||
|
||||
*red = apply_gamma (linear_red);
|
||||
*green = apply_gamma (linear_green);
|
||||
*blue = apply_gamma (linear_blue);
|
||||
gtk_linear_srgb_to_rgb (linear_red, linear_green, linear_blue, red, green, blue);
|
||||
}
|
||||
|
||||
void
|
||||
gtk_rgb_to_oklab (float red, float green, float blue,
|
||||
float *L, float *a, float *b)
|
||||
{
|
||||
float linear_red = unapply_gamma (red);
|
||||
float linear_green = unapply_gamma (green);
|
||||
float linear_blue = unapply_gamma (blue);
|
||||
float linear_red, linear_green, linear_blue;
|
||||
|
||||
gtk_rgb_to_linear_srgb (red, green, blue, &linear_red, &linear_green, &linear_blue);
|
||||
|
||||
float l = 0.4122214708f * linear_red + 0.5363325363f * linear_green + 0.0514459929f * linear_blue;
|
||||
float m = 0.2119034982f * linear_red + 0.6806995451f * linear_green + 0.1073969566f * linear_blue;
|
||||
@@ -360,3 +358,21 @@ gtk_rgb_to_oklab (float red, float green, float blue,
|
||||
*a = 1.9779984951f*l - 2.4285922050f*m + 0.4505937099f*s;
|
||||
*b = 0.0259040371f*l + 0.7827717662f*m - 0.8086757660f*s;
|
||||
}
|
||||
|
||||
void
|
||||
gtk_rgb_to_linear_srgb (float red, float green, float blue,
|
||||
float *linear_red, float *linear_green, float *linear_blue)
|
||||
{
|
||||
*linear_red = unapply_gamma (red);
|
||||
*linear_green = unapply_gamma (green);
|
||||
*linear_blue = unapply_gamma (blue);
|
||||
}
|
||||
|
||||
void
|
||||
gtk_linear_srgb_to_rgb (float linear_red, float linear_green, float linear_blue,
|
||||
float *red, float *green, float *blue)
|
||||
{
|
||||
*red = apply_gamma (linear_red);
|
||||
*green = apply_gamma (linear_green);
|
||||
*blue = apply_gamma (linear_blue);
|
||||
}
|
||||
|
||||
@@ -36,5 +36,10 @@ void gtk_oklab_to_rgb (float L, float a, float b,
|
||||
void gtk_rgb_to_oklab (float red, float green, float blue,
|
||||
float *L, float *a, float *b);
|
||||
|
||||
void gtk_rgb_to_linear_srgb (float red, float green, float blue,
|
||||
float *linear_red, float *linear_green, float *linear_blue);
|
||||
void gtk_linear_srgb_to_rgb (float linear_red, float linear_green, float linear_blue,
|
||||
float *red, float *green, float *blue);
|
||||
|
||||
G_END_DECLS
|
||||
|
||||
|
||||
@@ -32,6 +32,7 @@
|
||||
|
||||
typedef enum {
|
||||
COLOR_TYPE_LITERAL,
|
||||
COLOR_TYPE_COLOR,
|
||||
COLOR_TYPE_NAME,
|
||||
COLOR_TYPE_SHADE,
|
||||
COLOR_TYPE_ALPHA,
|
||||
@@ -50,6 +51,12 @@ struct _GtkCssValue
|
||||
char *name;
|
||||
GdkRGBA rgba;
|
||||
|
||||
struct
|
||||
{
|
||||
GtkCssColorSpace color_space;
|
||||
float values[4];
|
||||
} color;
|
||||
|
||||
struct
|
||||
{
|
||||
GtkCssValue *color;
|
||||
@@ -87,6 +94,7 @@ 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:
|
||||
break;
|
||||
@@ -183,6 +191,9 @@ gtk_css_value_color_equal (const GtkCssValue *value1,
|
||||
{
|
||||
case COLOR_TYPE_LITERAL:
|
||||
return gdk_rgba_equal (&value1->rgba, &value2->rgba);
|
||||
case COLOR_TYPE_COLOR:
|
||||
return value1->color.color_space == value2->color.color_space &&
|
||||
memcmp (value1->color.values, value2->color.values, sizeof(float) * 4) == 0;
|
||||
case COLOR_TYPE_NAME:
|
||||
return g_str_equal (value1->name, value2->name);
|
||||
case COLOR_TYPE_SHADE:
|
||||
@@ -229,6 +240,50 @@ gtk_css_value_color_print (const GtkCssValue *value,
|
||||
g_free (s);
|
||||
}
|
||||
break;
|
||||
case COLOR_TYPE_COLOR:
|
||||
{
|
||||
char fmt[G_ASCII_DTOSTR_BUF_SIZE];
|
||||
|
||||
g_string_append (string, "color(");
|
||||
|
||||
switch (value->color.color_space)
|
||||
{
|
||||
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;
|
||||
default:
|
||||
g_assert_not_reached ();
|
||||
}
|
||||
|
||||
g_string_append_c (string, ' ');
|
||||
|
||||
g_ascii_formatd (fmt, G_ASCII_DTOSTR_BUF_SIZE, "%g", value->color.values[0]);
|
||||
g_string_append (string, fmt);
|
||||
|
||||
g_string_append_c (string, ' ');
|
||||
|
||||
g_ascii_formatd (fmt, G_ASCII_DTOSTR_BUF_SIZE, "%g", value->color.values[1]);
|
||||
g_string_append (string, fmt);
|
||||
|
||||
g_string_append_c (string, ' ');
|
||||
|
||||
g_ascii_formatd (fmt, G_ASCII_DTOSTR_BUF_SIZE, "%g", value->color.values[2]);
|
||||
g_string_append (string, fmt);
|
||||
|
||||
if (value->color.values[3] < 0.999)
|
||||
{
|
||||
g_ascii_formatd (fmt, G_ASCII_DTOSTR_BUF_SIZE, "%g", value->color.values[3]);
|
||||
|
||||
g_string_append (string, " / ");
|
||||
g_string_append (string, fmt);
|
||||
}
|
||||
|
||||
g_string_append_c (string, ')');
|
||||
}
|
||||
break;
|
||||
case COLOR_TYPE_NAME:
|
||||
g_string_append (string, "@");
|
||||
g_string_append (string, value->name);
|
||||
@@ -355,6 +410,33 @@ gtk_css_color_value_do_resolve (GtkCssValue *color,
|
||||
{
|
||||
case COLOR_TYPE_LITERAL:
|
||||
return gtk_css_value_ref (color);
|
||||
case COLOR_TYPE_COLOR:
|
||||
{
|
||||
GdkRGBA rgba;
|
||||
|
||||
switch (color->color.color_space)
|
||||
{
|
||||
case GTK_CSS_COLOR_SPACE_SRGB:
|
||||
rgba.red = CLAMP (color->color.values[0], 0, 1);
|
||||
rgba.green = CLAMP (color->color.values[1], 0, 1);
|
||||
rgba.blue = CLAMP (color->color.values[2], 0, 1);
|
||||
rgba.alpha = color->color.values[3];
|
||||
break;
|
||||
|
||||
case GTK_CSS_COLOR_SPACE_SRGB_LINEAR:
|
||||
gtk_linear_srgb_to_rgb (CLAMP (color->color.values[0], 0, 1),
|
||||
CLAMP (color->color.values[1], 0, 1),
|
||||
CLAMP (color->color.values[2], 0, 1),
|
||||
&rgba.red, &rgba.green, &rgba.blue);
|
||||
rgba.alpha = color->color.values[3];
|
||||
break;
|
||||
|
||||
default:
|
||||
g_assert_not_reached ();
|
||||
}
|
||||
|
||||
return gtk_css_color_value_new_literal (&rgba);
|
||||
}
|
||||
case COLOR_TYPE_NAME:
|
||||
{
|
||||
GtkCssValue *named;
|
||||
@@ -514,6 +596,20 @@ gtk_css_color_value_new_literal (const GdkRGBA *color)
|
||||
return value;
|
||||
}
|
||||
|
||||
GtkCssValue *
|
||||
gtk_css_value_value_new_color (GtkCssColorSpace color_space,
|
||||
float values[4])
|
||||
{
|
||||
GtkCssValue *value;
|
||||
|
||||
value = gtk_css_value_new (GtkCssValue, >K_CSS_VALUE_COLOR);
|
||||
value->type = COLOR_TYPE_COLOR;
|
||||
value->color.color_space = color_space;
|
||||
memcpy (value->color.values, values, sizeof(float) * 4);
|
||||
|
||||
return value;
|
||||
}
|
||||
|
||||
GtkCssValue *
|
||||
gtk_css_color_value_new_name (const char *name)
|
||||
{
|
||||
@@ -698,7 +794,8 @@ gtk_css_color_value_can_parse (GtkCssParser *parser)
|
||||
|| gtk_css_parser_has_function (parser, "rgba")
|
||||
|| 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, "oklch")
|
||||
|| gtk_css_parser_has_function (parser, "color");
|
||||
}
|
||||
|
||||
typedef struct
|
||||
@@ -1089,9 +1186,85 @@ parse_oklch_color_channel (GtkCssParser *parser,
|
||||
}
|
||||
}
|
||||
|
||||
typedef struct {
|
||||
GtkCssColorSpace color_space;
|
||||
float values[4];
|
||||
} ParseColorData;
|
||||
|
||||
static gboolean
|
||||
parse_color_channel_value (GtkCssParser *parser,
|
||||
float *value)
|
||||
{
|
||||
GtkCssNumberParseFlags flags = GTK_CSS_PARSE_NUMBER | GTK_CSS_PARSE_PERCENT;
|
||||
GtkCssValue *val;
|
||||
|
||||
val = gtk_css_number_value_parse (parser, flags);
|
||||
if (val == NULL)
|
||||
return FALSE;
|
||||
|
||||
*value = gtk_css_number_value_get_canonical (val, 1);
|
||||
|
||||
gtk_css_value_unref (val);
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static guint
|
||||
parse_color_color_channel (GtkCssParser *parser,
|
||||
guint arg,
|
||||
ColorSyntax syntax,
|
||||
gpointer data)
|
||||
{
|
||||
ParseColorData *color_data = data;
|
||||
|
||||
switch (arg)
|
||||
{
|
||||
case 0:
|
||||
if (gtk_css_parser_try_ident (parser, "srgb"))
|
||||
{
|
||||
color_data->color_space = GTK_CSS_COLOR_SPACE_SRGB;
|
||||
return 1;
|
||||
}
|
||||
|
||||
if (gtk_css_parser_try_ident (parser, "srgb-linear"))
|
||||
{
|
||||
color_data->color_space = GTK_CSS_COLOR_SPACE_SRGB_LINEAR;
|
||||
return 1;
|
||||
}
|
||||
|
||||
gtk_css_parser_error_syntax (parser, "Invalid color space in color()");
|
||||
return 0;
|
||||
|
||||
case 1:
|
||||
if (!parse_color_channel_value (parser, &color_data->values[0]))
|
||||
return 0;
|
||||
return 1;
|
||||
|
||||
case 2:
|
||||
if (!parse_color_channel_value (parser, &color_data->values[1]))
|
||||
return 0;
|
||||
return 1;
|
||||
|
||||
case 3:
|
||||
if (!parse_color_channel_value (parser, &color_data->values[2]))
|
||||
return 0;
|
||||
return 1;
|
||||
|
||||
case 4:
|
||||
if (!parse_alpha_value (parser, &color_data->values[3], syntax))
|
||||
return 0;
|
||||
return 1;
|
||||
|
||||
default:
|
||||
g_assert_not_reached ();
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
static gboolean
|
||||
parse_color_function (GtkCssParser *self,
|
||||
ColorSyntax syntax,
|
||||
gboolean parse_color_space,
|
||||
gboolean allow_alpha,
|
||||
gboolean require_alpha,
|
||||
guint (* parse_func) (GtkCssParser *, guint, ColorSyntax, gpointer),
|
||||
@@ -1104,6 +1277,12 @@ parse_color_function (GtkCssParser *self,
|
||||
guint min_args = 3;
|
||||
guint max_args = 4;
|
||||
|
||||
if (parse_color_space)
|
||||
{
|
||||
min_args++;
|
||||
max_args++;
|
||||
}
|
||||
|
||||
token = gtk_css_parser_get_token (self);
|
||||
g_return_val_if_fail (gtk_css_token_is (token, GTK_CSS_TOKEN_FUNCTION), FALSE);
|
||||
|
||||
@@ -1168,7 +1347,7 @@ parse_color_function (GtkCssParser *self,
|
||||
gtk_css_parser_error_syntax (self, "Unexpected data at end of %s() argument", function_name);
|
||||
break;
|
||||
}
|
||||
else if (arg == 3)
|
||||
else if (arg == min_args)
|
||||
{
|
||||
if (gtk_css_token_is_delim (token, '/'))
|
||||
{
|
||||
@@ -1228,7 +1407,7 @@ gtk_css_color_value_parse (GtkCssParser *parser)
|
||||
|
||||
has_alpha = gtk_css_parser_has_function (parser, "rgba");
|
||||
|
||||
if (!parse_color_function (parser, COLOR_SYNTAX_DETECTING, has_alpha, has_alpha, parse_rgba_color_channel, &data))
|
||||
if (!parse_color_function (parser, COLOR_SYNTAX_DETECTING, FALSE, has_alpha, has_alpha, parse_rgba_color_channel, &data))
|
||||
return NULL;
|
||||
|
||||
return gtk_css_color_value_new_literal (&rgba);
|
||||
@@ -1239,7 +1418,7 @@ gtk_css_color_value_parse (GtkCssParser *parser)
|
||||
|
||||
hsla.alpha = 1.0;
|
||||
|
||||
if (!parse_color_function (parser, COLOR_SYNTAX_DETECTING, TRUE, FALSE, parse_hsla_color_channel, &hsla))
|
||||
if (!parse_color_function (parser, COLOR_SYNTAX_DETECTING, FALSE, TRUE, FALSE, parse_hsla_color_channel, &hsla))
|
||||
return NULL;
|
||||
|
||||
_gdk_rgba_init_from_hsla (&rgba, &hsla);
|
||||
@@ -1253,7 +1432,7 @@ gtk_css_color_value_parse (GtkCssParser *parser)
|
||||
|
||||
hwb.alpha = 1.0;
|
||||
|
||||
if (!parse_color_function (parser, COLOR_SYNTAX_MODERN, TRUE, FALSE, parse_hwb_color_channel, &hwb))
|
||||
if (!parse_color_function (parser, COLOR_SYNTAX_MODERN, FALSE, TRUE, FALSE, parse_hwb_color_channel, &hwb))
|
||||
return NULL;
|
||||
|
||||
hwb.white /= 100.0;
|
||||
@@ -1274,7 +1453,7 @@ gtk_css_color_value_parse (GtkCssParser *parser)
|
||||
|
||||
oklab.alpha = 1.0;
|
||||
|
||||
if (!parse_color_function (parser, COLOR_SYNTAX_MODERN, TRUE, FALSE, parse_oklab_color_channel, &oklab))
|
||||
if (!parse_color_function (parser, COLOR_SYNTAX_MODERN, FALSE, TRUE, FALSE, parse_oklab_color_channel, &oklab))
|
||||
return NULL;
|
||||
|
||||
gtk_oklab_to_rgb (oklab.L, oklab.a, oklab.b, &rgba.red, &rgba.green, &rgba.blue);
|
||||
@@ -1290,7 +1469,7 @@ gtk_css_color_value_parse (GtkCssParser *parser)
|
||||
|
||||
oklch.alpha = 1.0;
|
||||
|
||||
if (!parse_color_function (parser, COLOR_SYNTAX_MODERN, TRUE, FALSE, parse_oklch_color_channel, &oklch))
|
||||
if (!parse_color_function (parser, COLOR_SYNTAX_MODERN, FALSE, TRUE, FALSE, parse_oklch_color_channel, &oklch))
|
||||
return NULL;
|
||||
|
||||
gtk_oklch_to_oklab (oklch.L, oklch.C, oklch.H, &L, &a, &b);
|
||||
@@ -1300,6 +1479,17 @@ gtk_css_color_value_parse (GtkCssParser *parser)
|
||||
|
||||
return gtk_css_color_value_new_literal (&rgba);
|
||||
}
|
||||
else if (gtk_css_parser_has_function (parser, "color"))
|
||||
{
|
||||
ParseColorData data;
|
||||
|
||||
data.values[3] = 1.0;
|
||||
|
||||
if (!parse_color_function (parser, COLOR_SYNTAX_MODERN, TRUE, TRUE, FALSE, parse_color_color_channel, &data))
|
||||
return NULL;
|
||||
|
||||
return gtk_css_value_value_new_color (data.color_space, data.values);
|
||||
}
|
||||
else if (gtk_css_parser_has_function (parser, "lighter"))
|
||||
{
|
||||
ColorFunctionData data = { NULL, };
|
||||
|
||||
@@ -24,10 +24,16 @@
|
||||
|
||||
G_BEGIN_DECLS
|
||||
|
||||
typedef enum {
|
||||
GTK_CSS_COLOR_SPACE_SRGB,
|
||||
GTK_CSS_COLOR_SPACE_SRGB_LINEAR,
|
||||
} GtkCssColorSpace;
|
||||
|
||||
GtkCssValue * gtk_css_color_value_new_transparent (void) G_GNUC_PURE;
|
||||
GtkCssValue * gtk_css_color_value_new_white (void) G_GNUC_PURE;
|
||||
GtkCssValue * gtk_css_color_value_new_literal (const GdkRGBA *color) G_GNUC_PURE;
|
||||
GtkCssValue * gtk_css_value_value_new_color (GtkCssColorSpace color_space,
|
||||
float values[4]) G_GNUC_PURE;
|
||||
GtkCssValue * gtk_css_color_value_new_name (const char *name) G_GNUC_PURE;
|
||||
GtkCssValue * gtk_css_color_value_new_shade (GtkCssValue *color,
|
||||
double factor) G_GNUC_PURE;
|
||||
|
||||
@@ -95,3 +95,19 @@ w {
|
||||
x {
|
||||
color: rgba(255 0 0 / 0.5);
|
||||
}
|
||||
|
||||
y {
|
||||
color: color(srgb 1 0 0);
|
||||
}
|
||||
|
||||
z {
|
||||
color: color(srgb 99% 98.5% 98% / 0.5);
|
||||
}
|
||||
|
||||
aa {
|
||||
color: color(srgb 1.5 -150% 0 / 200%);
|
||||
}
|
||||
|
||||
ab {
|
||||
color: color(srgb-linear 1 0.5 0 / 50%);
|
||||
}
|
||||
|
||||
@@ -95,3 +95,19 @@ w {
|
||||
x {
|
||||
color: rgba(255,0,0,0.5);
|
||||
}
|
||||
|
||||
y {
|
||||
color: color(srgb 1 0 0);
|
||||
}
|
||||
|
||||
z {
|
||||
color: color(srgb 0.99 0.985 0.98 / 0.5);
|
||||
}
|
||||
|
||||
aa {
|
||||
color: color(srgb 1.5 -1.5 0);
|
||||
}
|
||||
|
||||
ab {
|
||||
color: color(srgb-linear 1 0.5 0 / 0.5);
|
||||
}
|
||||
|
||||
@@ -65,3 +65,23 @@ p {
|
||||
q {
|
||||
color: rgba(1, 2 3 / 4);
|
||||
}
|
||||
|
||||
r {
|
||||
color: color(not-a-color-space 255 0 0 / 0.5);
|
||||
}
|
||||
|
||||
s {
|
||||
color: color(srgb 255);
|
||||
}
|
||||
|
||||
t {
|
||||
color: color(srgb 1 0 0 0.5);
|
||||
}
|
||||
|
||||
u {
|
||||
color: color(srgb 1 0 / 0 0.5);
|
||||
}
|
||||
|
||||
v {
|
||||
color: color(srgb, 1, 0, 0);
|
||||
}
|
||||
|
||||
@@ -15,3 +15,8 @@ colors-errors.css:54:21-22: error: GTK_CSS_PARSER_ERROR_SYNTAX
|
||||
colors-errors.css:58:22-23: error: GTK_CSS_PARSER_ERROR_SYNTAX
|
||||
colors-errors.css:62:19-20: error: GTK_CSS_PARSER_ERROR_SYNTAX
|
||||
colors-errors.css:66:20-21: error: GTK_CSS_PARSER_ERROR_SYNTAX
|
||||
colors-errors.css:70:16-33: error: GTK_CSS_PARSER_ERROR_SYNTAX
|
||||
colors-errors.css:74:24-25: error: GTK_CSS_PARSER_ERROR_SYNTAX
|
||||
colors-errors.css:78:27-30: error: GTK_CSS_PARSER_ERROR_SYNTAX
|
||||
colors-errors.css:82:25-26: error: GTK_CSS_PARSER_ERROR_SYNTAX
|
||||
colors-errors.css:86:20-21: error: GTK_CSS_PARSER_ERROR_SYNTAX
|
||||
|
||||
@@ -123,6 +123,40 @@ test_roundtrips_rgb_oklab (void)
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
test_roundtrips_rgb_linear_srgb (void)
|
||||
{
|
||||
struct {
|
||||
float red, green, blue;
|
||||
float linear_red, linear_green, linear_blue;
|
||||
} tests[] = {
|
||||
{ 0, 0, 0, 0, 0, 0 },
|
||||
{ 1, 1, 1, 1, 1, 1 },
|
||||
{ 0.691, 0.139, 0.26, 0.435, 0.017, 0.055 },
|
||||
{ 0.25, 0.5, 0.75, 0.0508, 0.214, 0.522 },
|
||||
};
|
||||
const float EPSILON = 1e-3;
|
||||
|
||||
for (unsigned int i = 0; i < G_N_ELEMENTS (tests); i++)
|
||||
{
|
||||
float red, green, blue;
|
||||
|
||||
gtk_linear_srgb_to_rgb (tests[i].linear_red,
|
||||
tests[i].linear_green,
|
||||
tests[i].linear_blue,
|
||||
&red, &green, &blue);
|
||||
g_assert_cmpfloat_with_epsilon (red, tests[i].red, EPSILON);
|
||||
g_assert_cmpfloat_with_epsilon (green, tests[i].green, EPSILON);
|
||||
g_assert_cmpfloat_with_epsilon (blue, tests[i].blue, EPSILON);
|
||||
|
||||
gtk_rgb_to_linear_srgb (tests[i].red, tests[i].green, tests[i].blue,
|
||||
&red, &green, &blue);
|
||||
g_assert_cmpfloat_with_epsilon (red, tests[i].linear_red, EPSILON);
|
||||
g_assert_cmpfloat_with_epsilon (green, tests[i].linear_green, EPSILON);
|
||||
g_assert_cmpfloat_with_epsilon (blue, tests[i].linear_blue, EPSILON);
|
||||
}
|
||||
}
|
||||
|
||||
int
|
||||
main (int argc,
|
||||
char *argv[])
|
||||
@@ -132,6 +166,7 @@ main (int argc,
|
||||
g_test_add_func ("/color/roundtrips/rgb-hsv", test_roundtrips_rgb_hsv);
|
||||
g_test_add_func ("/color/roundtrips/rgb-hwb", test_roundtrips_rgb_hwb);
|
||||
g_test_add_func ("/color/roundtrips/rgb-oklab", test_roundtrips_rgb_oklab);
|
||||
g_test_add_func ("/color/roundtrips/rgb-linear-srgb", test_roundtrips_rgb_linear_srgb);
|
||||
|
||||
return g_test_run();
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user