diff --git a/gdk/gdkvulkancontext.c b/gdk/gdkvulkancontext.c index 6b55e64b78..076a62ac46 100644 --- a/gdk/gdkvulkancontext.c +++ b/gdk/gdkvulkancontext.c @@ -648,7 +648,7 @@ gdk_vulkan_context_begin_frame (GdkDrawContext *draw_context, { if (priv->formats[depth].gdk_format != priv->formats[priv->current_format].gdk_format) { - GdkMemoryFormat old_format = priv->current_format; + GdkMemoryDepth old_format = priv->current_format; GError *error = NULL; priv->current_format = depth; diff --git a/gtk/gtkcolorutils.c b/gtk/gtkcolorutils.c index f165022225..e5a8600fa3 100644 --- a/gtk/gtkcolorutils.c +++ b/gtk/gtkcolorutils.c @@ -423,3 +423,209 @@ gtk_linear_srgb_to_rgb (float linear_red, float linear_green, float linear_bl *green = apply_gamma (linear_green); *blue = apply_gamma (linear_blue); } + +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; +} + +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; + *b = (705.0 / 12673.0) * x - (2585.0 / 12673.0) * y + (705.0 / 667.0) * z; +} + +static void +gtk_lin_p3_to_xyz (float r, float g, float b, + float *x, float *y, float *z) +{ + *x = (608311.0 / 1250200.0) * r + (189793.0 / 714400.0) * g + (198249.0 / 1000160.0) * b; + *y = (35783.0 / 156275.0) * r + (247089.0 / 357200.0) * g + (198249.0 / 2500400.0) * b; + *z = ( 0 / 1) * r + (32229.0 / 714400.0) * g + (5220557.0 / 5000800.0) * b; +} + +static void +gtk_xyz_to_lin_p3 (float x, float y, float z, + float *r, float *g, float *b) +{ + *r = (446124.0 / 178915.0) * x - (333277.0 / 357830.0) * y - (72051.0 / 178915.0) * z; + *g = - (14852.0 / 17905.0) * x + (63121.0 / 35810.0) * y + (423.0 / 17905.0) * z; + *b = (11844.0 / 330415.0) * x - (50337.0 / 660830.0) * y + (316169.0 / 330415.0) * z; +} + +void gtk_rgb_to_p3 (float red, float green, float blue, + float *pr, float *pg, float *pb) +{ + float r, g, b; + float x, y, z; + + gtk_rgb_to_linear_srgb (red, green, blue, &r, &g, &b); + 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); +} + +void +gtk_p3_to_rgb (float pr, float pg, float pb, + float *red, float *green, float *blue) +{ + float r, g, b; + float x, y, z; + + 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_linear_srgb (x, y, z, &r, &g, &b); + gtk_linear_srgb_to_rgb (r, g, b, red, green, blue); +} + +static inline float +linearize_one (float val) +{ + float alpha = 1.09929682680944 ; + float beta = 0.018053968510807; + + int sign = val < 0 ? -1 : 1; + float abs = fabs (val); + + if (abs < beta * 4.5 ) + return val / 4.5; + else + return sign * powf ((abs + alpha - 1) / alpha, 1.0 / 0.45); +} + +void +gtk_rec2020_to_rec2020_linear (float r, float g , float b, + float *rr, float *gg, float *bb) +{ + *rr = linearize_one (r); + *gg = linearize_one (g); + *bb = linearize_one (b); +} + +void +gtk_rec2020_linear_to_xyz (float r, float g, float b, + float *x, float *y, float *z) +{ + *x = (63426534.0 / 99577255.0) * r + (20160776.0 / 139408157.0) * g + (47086771.0 / 278816314.0) * b; + *y = (26158966.0 / 99577255.0) * r + (472592308.0 / 697040785.0) * g + (8267143.0 / 139408157.0) * b; + *z = ( 0 / 1) * r + (19567812.0 / 697040785.0) * g + (295819943.0 / 278816314.0) * b; +} + +void +gtk_rec2020_to_xyz (float r, float g, float b, + float *x, float *y, float *z) +{ + gtk_rec2020_to_rec2020_linear (r, g, b, &r, &g, &b); + gtk_rec2020_linear_to_xyz (r, g, b, x, y, z); +} + +static inline float +delinearize_one (float val) +{ + float alpha = 1.09929682680944; + float beta = 0.018053968510807; + int sign = val < 0 ? -1 : 1; + float abs = fabsf (val); + + if (abs > beta) + return sign * (alpha * powf (abs, 0.45) - (alpha - 1)); + else + return 4.5 * val; +} + +void +gtk_rec2020_linear_to_rec2020 (float r, float g, float b, + float *rr, float *gg, float *bb) +{ + *rr = delinearize_one (r); + *gg = delinearize_one (g); + *bb = delinearize_one (b); +} + +void +gtk_xyz_to_rec2020_linear (float x, float y, float z, + float *r, float *g, float *b) +{ + *r = (30757411.0 / 17917100.0) * x - (6372589.0 / 17917100.0) * y - (4539589.0 / 17917100.0) * z; + *g = - (19765991.0 / 29648200.0) * x + (47925759.0 / 29648200.0) * y + (467509.0 / 29648200.0) *z; + *b = (792561.0 / 44930125.0) * x - (1921689.0 / 44930125.0) * y + (42328811.0 / 44930125.0) * z; +} + +void +gtk_xyz_to_rec2020 (float x, float y, float z, + float *r, float *g, float *b) +{ + gtk_xyz_to_rec2020_linear (x, y, z, r, g, b); + gtk_rec2020_linear_to_rec2020 (*r, *g, *b, r, g, b); +} + +/* maps [0, 1] to [0, 70] */ +static inline float +pq_to_linear (float v) +{ + float ninv = (1 << 14) / 2610.0; + float minv = (1 << 5) / 2523.0; + float c1 = 3424.0 / (1 << 12); + float c2 = 2413.0 / (1 << 7); + float c3 = 2392.0 / (1 << 7); + + float x = powf (MAX ((powf (v, minv) - c1), 0) / (c2 - (c3 * (powf (v, minv)))), ninv); + return x * 10000 / 203.0; +} + +/* maps [0, 70] to [0, 1] */ +void +gtk_rec2100_pq_to_rec2100_linear (float r, float g, float b, + float *rr, float *gg, float *bb) +{ + *rr = pq_to_linear (r); + *gg = pq_to_linear (g); + *bb = pq_to_linear (b); +} + +static inline float +linear_to_pq (float v) +{ + float x = v * 203.0 / 10000.0; + float n = 2610.0 / (1 << 14); + float m = 2523.0 / (1 << 5); + float c1 = 3424.0 / (1 << 12); + float c2 = 2413.0 / (1 << 7); + float c3 = 2392.0 / (1 << 7); + + return powf (((c1 + (c2 * powf (x, n))) / (1 + (c3 * powf (x, n)))), m); +} + +void +gtk_rec2100_linear_to_rec2100_pq (float r, float g, float b, + float *rr, float *gg, float *bb) +{ + *rr = linear_to_pq (r); + *gg = linear_to_pq (g); + *bb = linear_to_pq (b); +} + +void +gtk_rec2100_linear_to_rec2020_linear (float r, float g, float b, + float *rr, float *gg, float *bb) +{ + *rr = r; + *gg = g; + *bb = b; +} + +void +gtk_rec2020_linear_to_rec2100_linear (float r, float g, float b, + float *rr, float *gg, float *bb) +{ + *rr = r; + *gg = g; + *bb = b; +} diff --git a/gtk/gtkcolorutilsprivate.h b/gtk/gtkcolorutilsprivate.h index 2478559890..9172e76f0c 100644 --- a/gtk/gtkcolorutilsprivate.h +++ b/gtk/gtkcolorutilsprivate.h @@ -51,5 +51,39 @@ void gtk_rgb_to_linear_srgb (float red, float green, float blue void gtk_linear_srgb_to_rgb (float linear_red, float linear_green, float linear_blue, float *red, float *green, float *blue); +void gtk_rgb_to_p3 (float red, float green, float blue, + float *pr, float *pg, float *pb); +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); + +void gtk_rec2020_to_xyz (float r, float g, float b, + float *x, float *y, float *z); +void gtk_xyz_to_rec2020 (float x, float y, float z, + float *r, float *g, float *b); + +void gtk_rec2020_to_rec2020_linear (float r, float g , float b, + float *rr, float *gg, float *bb); +void gtk_rec2020_linear_to_rec2020 (float r, float g, float b, + float *rr, float *gg, float *bb); + +void gtk_rec2020_linear_to_xyz (float r, float g, float b, + float *x, float *y, float *z); +void gtk_xyz_to_rec2020_linear (float x, float y, float z, + float *r, float *g, float *b); + +void gtk_rec2100_pq_to_rec2100_linear (float r, float g, float b, + float *rr, float *gg, float *bb); +void gtk_rec2100_linear_to_rec2100_pq (float r, float g, float b, + float *rr, float *gg, float *bb); + +void gtk_rec2100_linear_to_rec2020_linear (float r, float g, float b, + float *rr, float *gg, float *bb); +void gtk_rec2020_linear_to_rec2100_linear (float r, float g, float b, + float *rr, float *gg, float *bb); G_END_DECLS diff --git a/gtk/gtkcsscolor.c b/gtk/gtkcsscolor.c index e260bb1dae..b76b1f855a 100644 --- a/gtk/gtkcsscolor.c +++ b/gtk/gtkcsscolor.c @@ -35,6 +35,10 @@ gtk_css_color_init (GtkCssColor *color, case GTK_CSS_COLOR_SPACE_SRGB: 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: + case GTK_CSS_COLOR_SPACE_REC2020: + case GTK_CSS_COLOR_SPACE_REC2100_PQ: break; case GTK_CSS_COLOR_SPACE_HSL: @@ -136,6 +140,22 @@ gtk_css_color_print (const GtkCssColor *color, g_string_append (string, "oklch("); break; + case GTK_CSS_COLOR_SPACE_DISPLAY_P3: + g_string_append (string, "color(display-p3 "); + break; + + case GTK_CSS_COLOR_SPACE_XYZ: + g_string_append (string, "color(xyz "); + break; + + case GTK_CSS_COLOR_SPACE_REC2020: + g_string_append (string, "color(rec2020 "); + break; + + case GTK_CSS_COLOR_SPACE_REC2100_PQ: + g_string_append (string, "color(rec2100-pq "); + break; + default: g_assert_not_reached (); } @@ -181,6 +201,9 @@ gtk_css_color_space_get_coord_name (GtkCssColorSpace color_space, { case GTK_CSS_COLOR_SPACE_SRGB: case GTK_CSS_COLOR_SPACE_SRGB_LINEAR: + case GTK_CSS_COLOR_SPACE_DISPLAY_P3: + case GTK_CSS_COLOR_SPACE_REC2020: + case GTK_CSS_COLOR_SPACE_REC2100_PQ: switch (coord) { case 0: return "r"; @@ -188,6 +211,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) { @@ -246,6 +277,10 @@ gtk_css_color_space_get_coord_range (GtkCssColorSpace color_space, *upper = legacy_rgb_scale ? 255 : 1; return; case GTK_CSS_COLOR_SPACE_SRGB_LINEAR: + case GTK_CSS_COLOR_SPACE_DISPLAY_P3: + case GTK_CSS_COLOR_SPACE_XYZ: + case GTK_CSS_COLOR_SPACE_REC2020: + case GTK_CSS_COLOR_SPACE_REC2100_PQ: *lower = 0; *upper = 1; return; @@ -287,11 +322,17 @@ color_space_is_polar (GtkCssColorSpace color_space) case GTK_CSS_COLOR_SPACE_SRGB: 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: + case GTK_CSS_COLOR_SPACE_REC2020: + case GTK_CSS_COLOR_SPACE_REC2100_PQ: 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 (); } @@ -311,6 +352,10 @@ convert_to_rectangular (GtkCssColor *output) case GTK_CSS_COLOR_SPACE_SRGB: 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: + case GTK_CSS_COLOR_SPACE_REC2020: + case GTK_CSS_COLOR_SPACE_REC2100_PQ: break; case GTK_CSS_COLOR_SPACE_HSL: @@ -352,7 +397,11 @@ 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_OKLAB || + output->color_space == GTK_CSS_COLOR_SPACE_DISPLAY_P3 || + output->color_space == GTK_CSS_COLOR_SPACE_XYZ || + output->color_space == GTK_CSS_COLOR_SPACE_REC2020 || + output->color_space == GTK_CSS_COLOR_SPACE_REC2100_PQ); if (output->color_space == GTK_CSS_COLOR_SPACE_SRGB) { @@ -363,6 +412,52 @@ 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_DISPLAY_P3) + { + gtk_p3_to_rgb (output->values[0], + output->values[1], + output->values[2], + &v[0], &v[1], &v[2]); + gtk_rgb_to_linear_srgb (v[0], v[1], v[2], + &v[0], &v[1], &v[2]); + 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); + } + else if (output->color_space == GTK_CSS_COLOR_SPACE_REC2020) + { + gtk_rec2020_to_xyz (output->values[0], + output->values[1], + output->values[2], + &v[0], &v[1], &v[2]); + gtk_xyz_to_linear_srgb (v[0], v[1], v[2], + &v[0], &v[1], &v[2]); + 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_REC2100_PQ) + { + gtk_rec2100_pq_to_rec2100_linear (output->values[0], + output->values[1], + output->values[2], + &v[0], &v[1], &v[2]); + gtk_rec2100_linear_to_rec2020_linear (v[0], v[1], v[2], + &v[0], &v[1], &v[2]); + gtk_rec2020_linear_to_xyz (v[0], v[1], v[2], + &v[0], &v[1], &v[2]); + gtk_xyz_to_linear_srgb (v[0], v[1], v[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 @@ -387,6 +482,52 @@ convert_from_linear (GtkCssColor *output, gtk_css_color_init (output, GTK_CSS_COLOR_SPACE_SRGB, v); break; + case GTK_CSS_COLOR_SPACE_DISPLAY_P3: + gtk_linear_srgb_to_rgb (output->values[0], + output->values[1], + output->values[2], + &v[0], &v[1], &v[2]); + gtk_rgb_to_p3 (v[0], v[1], v[2], + &v[0], &v[1], &v[2]); + v[3] = output->values[3]; + gtk_css_color_init (output, GTK_CSS_COLOR_SPACE_DISPLAY_P3, 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_REC2020: + gtk_linear_srgb_to_xyz (output->values[0], + output->values[1], + output->values[2], + &v[0], &v[1], &v[2]); + gtk_xyz_to_rec2020 (v[0], v[1], v[2], + &v[0], &v[1], &v[2]); + v[3] = output->values[3]; + gtk_css_color_init (output, GTK_CSS_COLOR_SPACE_REC2020, v); + break; + + case GTK_CSS_COLOR_SPACE_REC2100_PQ: + gtk_linear_srgb_to_xyz (output->values[0], + output->values[1], + output->values[2], + &v[0], &v[1], &v[2]); + gtk_xyz_to_rec2020_linear (v[0], v[1], v[2], + &v[0], &v[1], &v[2]); + gtk_rec2020_linear_to_rec2100_linear (v[0], v[1], v[2], + &v[0], &v[1], &v[2]); + gtk_rec2100_linear_to_rec2100_pq (v[0], v[1], v[2], + &v[0], &v[1], &v[2]); + v[3] = output->values[3]; + gtk_css_color_init (output, GTK_CSS_COLOR_SPACE_REC2100_PQ, v); + break; + case GTK_CSS_COLOR_SPACE_SRGB_LINEAR: case GTK_CSS_COLOR_SPACE_OKLAB: case GTK_CSS_COLOR_SPACE_OKLCH: @@ -408,6 +549,10 @@ convert_from_rectangular (GtkCssColor *output, case GTK_CSS_COLOR_SPACE_SRGB: 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: + case GTK_CSS_COLOR_SPACE_REC2020: + case GTK_CSS_COLOR_SPACE_REC2100_PQ: g_assert (output->color_space == dest); break; @@ -574,6 +719,10 @@ apply_hue_interpolation (GtkCssColor *from, case GTK_CSS_COLOR_SPACE_SRGB: 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: + case GTK_CSS_COLOR_SPACE_REC2020: + case GTK_CSS_COLOR_SPACE_REC2100_PQ: break; case GTK_CSS_COLOR_SPACE_HSL: @@ -606,6 +755,10 @@ normalize_hue (GtkCssColor *color) case GTK_CSS_COLOR_SPACE_SRGB: 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: + case GTK_CSS_COLOR_SPACE_REC2020: + case GTK_CSS_COLOR_SPACE_REC2100_PQ: break; case GTK_CSS_COLOR_SPACE_HSL: @@ -643,6 +796,10 @@ premultiply (GtkCssColor *color) case GTK_CSS_COLOR_SPACE_SRGB: 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: + case GTK_CSS_COLOR_SPACE_REC2020: + case GTK_CSS_COLOR_SPACE_REC2100_PQ: premultiply_component (color, 0); premultiply_component (color, 1); premultiply_component (color, 2); @@ -685,6 +842,10 @@ unpremultiply (GtkCssColor *color) case GTK_CSS_COLOR_SPACE_SRGB: 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: + case GTK_CSS_COLOR_SPACE_REC2020: + case GTK_CSS_COLOR_SPACE_REC2100_PQ: unpremultiply_component (color, 0); unpremultiply_component (color, 1); unpremultiply_component (color, 2); @@ -721,7 +882,10 @@ collect_analogous_missing (const GtkCssColor *color, { -1, -1, -1, -1, -1, 0, -1, -1, 3 }, /* hwb */ { -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 */ + { 0, 1, 2, -1, -1, -1, -1, -1, 3 }, /* rec2020 */ + { 0, 1, 2, -1, -1, -1, -1, -1, 3 }, /* rec2100-pq */ }; int *src = analogous[color->color_space]; @@ -930,6 +1094,18 @@ gtk_css_color_interpolation_method_print (GtkCssColorSpace in, case GTK_CSS_COLOR_SPACE_OKLAB: g_string_append (string, "oklab"); break; + 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; + case GTK_CSS_COLOR_SPACE_REC2020: + g_string_append (string, "rec2020"); + break; + case GTK_CSS_COLOR_SPACE_REC2100_PQ: + g_string_append (string, "rec2100-pq"); + break; default: g_assert_not_reached (); } diff --git a/gtk/gtkcsscolorprivate.h b/gtk/gtkcsscolorprivate.h index 0fa1a518de..27f16372ff 100644 --- a/gtk/gtkcsscolorprivate.h +++ b/gtk/gtkcsscolorprivate.h @@ -31,6 +31,10 @@ typedef enum { GTK_CSS_COLOR_SPACE_HWB, GTK_CSS_COLOR_SPACE_OKLAB, GTK_CSS_COLOR_SPACE_OKLCH, + GTK_CSS_COLOR_SPACE_DISPLAY_P3, + GTK_CSS_COLOR_SPACE_XYZ, + GTK_CSS_COLOR_SPACE_REC2020, + GTK_CSS_COLOR_SPACE_REC2100_PQ, } GtkCssColorSpace; typedef struct diff --git a/gtk/gtkcsscolorvalue.c b/gtk/gtkcsscolorvalue.c index c7b29aa7d2..5f8d830bb4 100644 --- a/gtk/gtkcsscolorvalue.c +++ b/gtk/gtkcsscolorvalue.c @@ -357,6 +357,30 @@ gtk_css_value_color_print (const GtkCssValue *value, g_string_append (string, " srgb-linear"); break; + case GTK_CSS_COLOR_SPACE_DISPLAY_P3: + g_string_append (string, "color(from "); + gtk_css_value_print (value->relative.origin, string); + 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_REC2020: + g_string_append (string, "color(from "); + gtk_css_value_print (value->relative.origin, string); + g_string_append (string, " rec2020"); + break; + + case GTK_CSS_COLOR_SPACE_REC2100_PQ: + g_string_append (string, "color(from "); + gtk_css_value_print (value->relative.origin, string); + g_string_append (string, " rec2100-pq"); + break; + case GTK_CSS_COLOR_SPACE_HSL: g_string_append (string, "hsl(from "); gtk_css_value_print (value->relative.origin, string); @@ -1642,6 +1666,30 @@ parse_color_color_channel (GtkCssParser *parser, return 1; } + if (gtk_css_parser_try_ident (parser, "display-p3")) + { + data->ctx.color_space = GTK_CSS_COLOR_SPACE_DISPLAY_P3; + return 1; + } + + if (gtk_css_parser_try_ident (parser, "xyz")) + { + data->ctx.color_space = GTK_CSS_COLOR_SPACE_XYZ; + return 1; + } + + if (gtk_css_parser_try_ident (parser, "rec2020")) + { + data->ctx.color_space = GTK_CSS_COLOR_SPACE_REC2020; + return 1; + } + + if (gtk_css_parser_try_ident (parser, "rec2100-pq")) + { + data->ctx.color_space = GTK_CSS_COLOR_SPACE_REC2100_PQ; + return 1; + } + gtk_css_parser_error_syntax (parser, "Invalid color space in color()"); return 0; diff --git a/testsuite/css/color.c b/testsuite/css/color.c index daef958c49..8e22982ff5 100644 --- a/testsuite/css/color.c +++ b/testsuite/css/color.c @@ -27,7 +27,7 @@ #include "gtk/gtkcssstylepropertyprivate.h" #include "gtk/gtkcssstaticstyleprivate.h" -#define EPSILON 0.001 +#define EPSILON 0.005 static gboolean color_is_near (const GtkCssColor *color1, @@ -116,8 +116,15 @@ static ColorConversionTest conversion_tests[] = { { "oklch(0.66016 0.15546 134.231)", GTK_CSS_COLOR_SPACE_SRGB, "rgb(40.73% 65.12% 22.35%)" }, { "oklch(72.322% 0.12403 247.996)", GTK_CSS_COLOR_SPACE_SRGB, "rgb(38.29% 67.27% 93.85%)" }, { "oklch(42.1% 48.25% 328.4)", GTK_CSS_COLOR_SPACE_SRGB, "color(srgb 0.501808 0.00257216 0.501403)" }, - /* more random tests */ + /* some self-conversions */ { "oklch(0.392 0.4 none)", GTK_CSS_COLOR_SPACE_OKLCH, "oklch(0.392 0.4 0)" }, + { "color(display-p3 1 1 1)", GTK_CSS_COLOR_SPACE_DISPLAY_P3, "color(display-p3 1 1 1)" }, + { "color(rec2020 1 1 1)", GTK_CSS_COLOR_SPACE_REC2020, "color(rec2020 1 1 1)" }, + { "color(rec2100-pq 0.58 0.58 0.58)", GTK_CSS_COLOR_SPACE_REC2100_PQ, "color(rec2100-pq 0.58 0.58 0.58)" }, + /* more random tests */ + { "color(rec2100-pq 0.58 0.58 0.58)", GTK_CSS_COLOR_SPACE_REC2020, "color(rec2020 1 1 1)" }, + { "color(xyz 0.5 0.7 99%)", GTK_CSS_COLOR_SPACE_DISPLAY_P3, "color(display-p3 0.48 0.93 0.96)" }, + { "hsl(250 100 20)", GTK_CSS_COLOR_SPACE_REC2020, "color(rec2020 0.042 0.008 0.3226)" }, }; static void