mirror of
https://gitlab.gnome.org/GNOME/gtk.git
synced 2024-11-10 02:40:11 +00:00
css: Add support for xyz colors
This is somewhat central, and we have all the pieces to support it, so we might as well add the css syntax for it.
This commit is contained in:
parent
d71fc41152
commit
2d1e978599
@ -424,18 +424,18 @@ gtk_linear_srgb_to_rgb (float linear_red, float linear_green, float linear_bl
|
||||
*blue = apply_gamma (linear_blue);
|
||||
}
|
||||
|
||||
static void
|
||||
gtk_linrgb_to_xyz (float r, float g, float b,
|
||||
float *x, float *y, float *z)
|
||||
void
|
||||
gtk_linear_srgb_to_xyz (float r, float g, float b,
|
||||
float *x, float *y, float *z)
|
||||
{
|
||||
*x = (506752.0 / 1228815.0) * r + (87881.0 / 245763.0) * g + (12673.0 / 70218.0) * b;
|
||||
*y = (87098.0 / 409605.0) * r + (175762.0 / 245763.0) * g + (12673.0 / 175545.0) * b;
|
||||
*z = ( 7918.0 / 409605.0) * r + (87881.0 / 737289.0) * g + (1001167.0 / 1053270.0) * b;
|
||||
}
|
||||
|
||||
static void
|
||||
gtk_xyz_to_linrgb (float x, float y, float z,
|
||||
float *r, float *g, float *b)
|
||||
void
|
||||
gtk_xyz_to_linear_srgb (float x, float y, float z,
|
||||
float *r, float *g, float *b)
|
||||
{
|
||||
*r = (12831.0 / 3959.0) * x - (329.0 / 214.0) * y - (1974.0 / 3959.0) * z;
|
||||
*g = - (851781.0 / 878810.0) * x + (1648619.0 / 878810.0) * y + (36519.0 / 878810.0) * z;
|
||||
@ -467,7 +467,7 @@ void gtk_rgb_to_p3 (float red, float green, float blue,
|
||||
float x, y, z;
|
||||
|
||||
gtk_rgb_to_linear_srgb (red, green, blue, &r, &g, &b);
|
||||
gtk_linrgb_to_xyz (r, g, b, &x, &y, &z);
|
||||
gtk_linear_srgb_to_xyz (r, g, b, &x, &y, &z);
|
||||
gtk_xyz_to_lin_p3 (x, y, z, &r, &g, &b);
|
||||
gtk_linear_srgb_to_rgb (r, g, b, pr, pg, pb);
|
||||
}
|
||||
@ -481,6 +481,6 @@ gtk_p3_to_rgb (float pr, float pg, float pb,
|
||||
|
||||
gtk_rgb_to_linear_srgb (pr, pg, pb, &r, &g, &b);
|
||||
gtk_lin_p3_to_xyz (r, g, b, &x, &y, &z);
|
||||
gtk_xyz_to_linrgb (x, y, z, &r, &g, &b);
|
||||
gtk_xyz_to_linear_srgb (x, y, z, &r, &g, &b);
|
||||
gtk_linear_srgb_to_rgb (r, g, b, red, green, blue);
|
||||
}
|
||||
|
@ -56,4 +56,10 @@ void gtk_rgb_to_p3 (float red, float green, float blue,
|
||||
void gtk_p3_to_rgb (float pr, float pg, float pb,
|
||||
float *red, float *green, float *blue);
|
||||
|
||||
void gtk_xyz_to_linear_srgb (float x, float y, float z,
|
||||
float *r, float *g, float *b);
|
||||
|
||||
void gtk_linear_srgb_to_xyz (float r, float g, float b,
|
||||
float *x, float *y, float *z);
|
||||
|
||||
G_END_DECLS
|
||||
|
@ -36,6 +36,7 @@ gtk_css_color_init (GtkCssColor *color,
|
||||
case GTK_CSS_COLOR_SPACE_SRGB_LINEAR:
|
||||
case GTK_CSS_COLOR_SPACE_OKLAB:
|
||||
case GTK_CSS_COLOR_SPACE_DISPLAY_P3:
|
||||
case GTK_CSS_COLOR_SPACE_XYZ:
|
||||
break;
|
||||
|
||||
case GTK_CSS_COLOR_SPACE_HSL:
|
||||
@ -141,6 +142,10 @@ gtk_css_color_print (const GtkCssColor *color,
|
||||
g_string_append (string, "color(display-p3 ");
|
||||
break;
|
||||
|
||||
case GTK_CSS_COLOR_SPACE_XYZ:
|
||||
g_string_append (string, "color(xyz ");
|
||||
break;
|
||||
|
||||
default:
|
||||
g_assert_not_reached ();
|
||||
}
|
||||
@ -194,6 +199,14 @@ gtk_css_color_space_get_coord_name (GtkCssColorSpace color_space,
|
||||
case 2: return "b";
|
||||
default: g_assert_not_reached ();
|
||||
}
|
||||
case GTK_CSS_COLOR_SPACE_XYZ:
|
||||
switch (coord)
|
||||
{
|
||||
case 0: return "x";
|
||||
case 1: return "y";
|
||||
case 2: return "z";
|
||||
default: g_assert_not_reached ();
|
||||
}
|
||||
case GTK_CSS_COLOR_SPACE_HSL:
|
||||
switch (coord)
|
||||
{
|
||||
@ -253,6 +266,7 @@ gtk_css_color_space_get_coord_range (GtkCssColorSpace color_space,
|
||||
return;
|
||||
case GTK_CSS_COLOR_SPACE_SRGB_LINEAR:
|
||||
case GTK_CSS_COLOR_SPACE_DISPLAY_P3:
|
||||
case GTK_CSS_COLOR_SPACE_XYZ:
|
||||
*lower = 0;
|
||||
*upper = 1;
|
||||
return;
|
||||
@ -295,6 +309,7 @@ color_space_is_polar (GtkCssColorSpace color_space)
|
||||
case GTK_CSS_COLOR_SPACE_SRGB_LINEAR:
|
||||
case GTK_CSS_COLOR_SPACE_OKLAB:
|
||||
case GTK_CSS_COLOR_SPACE_DISPLAY_P3:
|
||||
case GTK_CSS_COLOR_SPACE_XYZ:
|
||||
return FALSE;
|
||||
case GTK_CSS_COLOR_SPACE_HSL:
|
||||
case GTK_CSS_COLOR_SPACE_HWB:
|
||||
@ -320,6 +335,7 @@ convert_to_rectangular (GtkCssColor *output)
|
||||
case GTK_CSS_COLOR_SPACE_SRGB_LINEAR:
|
||||
case GTK_CSS_COLOR_SPACE_OKLAB:
|
||||
case GTK_CSS_COLOR_SPACE_DISPLAY_P3:
|
||||
case GTK_CSS_COLOR_SPACE_XYZ:
|
||||
break;
|
||||
|
||||
case GTK_CSS_COLOR_SPACE_HSL:
|
||||
@ -362,7 +378,8 @@ convert_to_linear (GtkCssColor *output)
|
||||
g_assert (output->color_space == GTK_CSS_COLOR_SPACE_SRGB ||
|
||||
output->color_space == GTK_CSS_COLOR_SPACE_SRGB_LINEAR ||
|
||||
output->color_space == GTK_CSS_COLOR_SPACE_OKLAB ||
|
||||
output->color_space == GTK_CSS_COLOR_SPACE_DISPLAY_P3);
|
||||
output->color_space == GTK_CSS_COLOR_SPACE_DISPLAY_P3 ||
|
||||
output->color_space == GTK_CSS_COLOR_SPACE_XYZ);
|
||||
|
||||
if (output->color_space == GTK_CSS_COLOR_SPACE_SRGB)
|
||||
{
|
||||
@ -384,6 +401,15 @@ convert_to_linear (GtkCssColor *output)
|
||||
v[3] = output->values[3];
|
||||
gtk_css_color_init (output, GTK_CSS_COLOR_SPACE_SRGB_LINEAR, v);
|
||||
}
|
||||
else if (output->color_space == GTK_CSS_COLOR_SPACE_XYZ)
|
||||
{
|
||||
gtk_xyz_to_linear_srgb (output->values[0],
|
||||
output->values[1],
|
||||
output->values[2],
|
||||
&v[0], &v[1], &v[2]);
|
||||
v[3] = output->values[3];
|
||||
gtk_css_color_init (output, GTK_CSS_COLOR_SPACE_SRGB_LINEAR, v);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
@ -409,6 +435,15 @@ convert_from_linear (GtkCssColor *output,
|
||||
gtk_css_color_init (output, GTK_CSS_COLOR_SPACE_SRGB, v);
|
||||
break;
|
||||
|
||||
case GTK_CSS_COLOR_SPACE_XYZ:
|
||||
gtk_linear_srgb_to_xyz (output->values[0],
|
||||
output->values[1],
|
||||
output->values[2],
|
||||
&v[0], &v[1], &v[2]);
|
||||
v[3] = output->values[3];
|
||||
gtk_css_color_init (output, GTK_CSS_COLOR_SPACE_XYZ, v);
|
||||
break;
|
||||
|
||||
case GTK_CSS_COLOR_SPACE_SRGB_LINEAR:
|
||||
case GTK_CSS_COLOR_SPACE_OKLAB:
|
||||
case GTK_CSS_COLOR_SPACE_OKLCH:
|
||||
@ -431,6 +466,7 @@ convert_from_rectangular (GtkCssColor *output,
|
||||
case GTK_CSS_COLOR_SPACE_SRGB_LINEAR:
|
||||
case GTK_CSS_COLOR_SPACE_OKLAB:
|
||||
case GTK_CSS_COLOR_SPACE_DISPLAY_P3:
|
||||
case GTK_CSS_COLOR_SPACE_XYZ:
|
||||
g_assert (output->color_space == dest);
|
||||
break;
|
||||
|
||||
@ -598,6 +634,7 @@ apply_hue_interpolation (GtkCssColor *from,
|
||||
case GTK_CSS_COLOR_SPACE_SRGB_LINEAR:
|
||||
case GTK_CSS_COLOR_SPACE_OKLAB:
|
||||
case GTK_CSS_COLOR_SPACE_DISPLAY_P3:
|
||||
case GTK_CSS_COLOR_SPACE_XYZ:
|
||||
break;
|
||||
|
||||
case GTK_CSS_COLOR_SPACE_HSL:
|
||||
@ -631,6 +668,7 @@ normalize_hue (GtkCssColor *color)
|
||||
case GTK_CSS_COLOR_SPACE_SRGB_LINEAR:
|
||||
case GTK_CSS_COLOR_SPACE_OKLAB:
|
||||
case GTK_CSS_COLOR_SPACE_DISPLAY_P3:
|
||||
case GTK_CSS_COLOR_SPACE_XYZ:
|
||||
break;
|
||||
|
||||
case GTK_CSS_COLOR_SPACE_HSL:
|
||||
@ -669,6 +707,7 @@ premultiply (GtkCssColor *color)
|
||||
case GTK_CSS_COLOR_SPACE_SRGB_LINEAR:
|
||||
case GTK_CSS_COLOR_SPACE_OKLAB:
|
||||
case GTK_CSS_COLOR_SPACE_DISPLAY_P3:
|
||||
case GTK_CSS_COLOR_SPACE_XYZ:
|
||||
premultiply_component (color, 0);
|
||||
premultiply_component (color, 1);
|
||||
premultiply_component (color, 2);
|
||||
@ -712,6 +751,7 @@ unpremultiply (GtkCssColor *color)
|
||||
case GTK_CSS_COLOR_SPACE_SRGB_LINEAR:
|
||||
case GTK_CSS_COLOR_SPACE_OKLAB:
|
||||
case GTK_CSS_COLOR_SPACE_DISPLAY_P3:
|
||||
case GTK_CSS_COLOR_SPACE_XYZ:
|
||||
unpremultiply_component (color, 0);
|
||||
unpremultiply_component (color, 1);
|
||||
unpremultiply_component (color, 2);
|
||||
@ -749,6 +789,7 @@ collect_analogous_missing (const GtkCssColor *color,
|
||||
{ -1, -1, -1, 0, -1, -1, 1, 2, 3 }, /* oklab */
|
||||
{ -1, -1, -1, 0, 1, 2, -1, -1, 3 }, /* oklch */
|
||||
{ 0, 1, 2, -1, -1, -1, -1, -1, 3 }, /* display-p3 */
|
||||
{ 0, 1, 2, -1, -1, -1, -1, -1, 3 }, /* xyz */
|
||||
};
|
||||
|
||||
int *src = analogous[color->color_space];
|
||||
@ -960,6 +1001,9 @@ gtk_css_color_interpolation_method_print (GtkCssColorSpace in,
|
||||
case GTK_CSS_COLOR_SPACE_DISPLAY_P3:
|
||||
g_string_append (string, "display-p3");
|
||||
break;
|
||||
case GTK_CSS_COLOR_SPACE_XYZ:
|
||||
g_string_append (string, "xyz");
|
||||
break;
|
||||
default:
|
||||
g_assert_not_reached ();
|
||||
}
|
||||
|
@ -32,6 +32,7 @@ typedef enum {
|
||||
GTK_CSS_COLOR_SPACE_OKLAB,
|
||||
GTK_CSS_COLOR_SPACE_OKLCH,
|
||||
GTK_CSS_COLOR_SPACE_DISPLAY_P3,
|
||||
GTK_CSS_COLOR_SPACE_XYZ,
|
||||
} GtkCssColorSpace;
|
||||
|
||||
typedef struct
|
||||
|
@ -363,6 +363,12 @@ gtk_css_value_color_print (const GtkCssValue *value,
|
||||
g_string_append (string, " display-p3");
|
||||
break;
|
||||
|
||||
case GTK_CSS_COLOR_SPACE_XYZ:
|
||||
g_string_append (string, "color(from ");
|
||||
gtk_css_value_print (value->relative.origin, string);
|
||||
g_string_append (string, " xyz");
|
||||
break;
|
||||
|
||||
case GTK_CSS_COLOR_SPACE_HSL:
|
||||
g_string_append (string, "hsl(from ");
|
||||
gtk_css_value_print (value->relative.origin, string);
|
||||
@ -1654,6 +1660,12 @@ parse_color_color_channel (GtkCssParser *parser,
|
||||
return 1;
|
||||
}
|
||||
|
||||
if (gtk_css_parser_try_ident (parser, "xyz"))
|
||||
{
|
||||
data->ctx.color_space = GTK_CSS_COLOR_SPACE_XYZ;
|
||||
return 1;
|
||||
}
|
||||
|
||||
gtk_css_parser_error_syntax (parser, "Invalid color space in color()");
|
||||
return 0;
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user