csscolorvalue: Fix percentage ranges for relative colors

Add tests as well, now that they can be computed at parse time.
This commit is contained in:
Alice Mikhaylenko 2024-06-06 00:16:23 +04:00
parent 82d1fdb714
commit 171bfde133
5 changed files with 141 additions and 1 deletions

View File

@ -225,6 +225,60 @@ gtk_css_color_space_get_coord_name (GtkCssColorSpace color_space,
} }
} }
void
gtk_css_color_space_get_coord_range (GtkCssColorSpace color_space,
gboolean legacy_rgb_scale,
guint coord,
float *lower,
float *upper)
{
if (coord == 3)
{
*lower = 0;
*upper = 1;
return;
}
switch (color_space)
{
case GTK_CSS_COLOR_SPACE_SRGB:
*lower = 0;
*upper = legacy_rgb_scale ? 255 : 1;
return;
case GTK_CSS_COLOR_SPACE_SRGB_LINEAR:
*lower = 0;
*upper = 1;
return;
case GTK_CSS_COLOR_SPACE_HSL:
case GTK_CSS_COLOR_SPACE_HWB:
switch (coord)
{
case 0: *lower = *upper = NAN; return;
case 1:
case 2: *lower = 0; *upper = 100; return;
default: g_assert_not_reached ();
}
case GTK_CSS_COLOR_SPACE_OKLAB:
switch (coord)
{
case 0: *lower = 0; *upper = 1; return;
case 1:
case 2: *lower = -0.4; *upper = 0.4; return;
default: g_assert_not_reached ();
}
case GTK_CSS_COLOR_SPACE_OKLCH:
switch (coord)
{
case 0: *lower = 0; *upper = 1; return;
case 1: *lower = 0; *upper = 0.4; return;
case 2: *lower = *upper = NAN; return;
default: g_assert_not_reached ();
}
default:
g_assert_not_reached ();
}
}
static gboolean static gboolean
color_space_is_polar (GtkCssColorSpace color_space) color_space_is_polar (GtkCssColorSpace color_space)
{ {

View File

@ -114,6 +114,12 @@ void gtk_css_color_interpolate (const GtkCssColor *from,
const char * gtk_css_color_space_get_coord_name (GtkCssColorSpace color_space, const char * gtk_css_color_space_get_coord_name (GtkCssColorSpace color_space,
guint coord); guint coord);
void gtk_css_color_space_get_coord_range (GtkCssColorSpace color_space,
gboolean legacy_rgb_scale,
guint coord,
float *lower,
float *upper);
gboolean gtk_css_color_interpolation_method_parse (GtkCssParser *parser, gboolean gtk_css_color_interpolation_method_parse (GtkCssParser *parser,
GtkCssColorSpace *in, GtkCssColorSpace *in,
GtkCssHueInterpolation *interp); GtkCssHueInterpolation *interp);

View File

@ -605,8 +605,16 @@ resolve_relative (GtkCssValue *values[4],
{ {
if (values[i]) if (values[i])
{ {
float lower, upper;
gtk_css_color_space_get_coord_range (color_space, legacy_rgb_scale,
i, &lower, &upper);
m[i] = FALSE; m[i] = FALSE;
v[i] = gtk_css_number_value_get_canonical (values[i], 1); v[i] = gtk_css_number_value_get_canonical (values[i], upper - lower);
if (gtk_css_number_value_has_percent (values[i]))
v[i] += lower;
} }
else else
{ {

View File

@ -26,3 +26,39 @@ f {
g { g {
color: rgb(from currentColor r g 100 / 50%); color: rgb(from currentColor r g 100 / 50%);
} }
h {
color: rgb(from white 100% 100% 100% / 100%);
}
i {
color: color(from white srgb 100% 100% 100% / 100%);
}
j {
color: color(from white srgb-linear 100% 100% 100% / 100%);
}
k {
color: hsl(from white 0 100% 100% / 100%);
}
l {
color: hwb(from white 0 100% 0% / 100%);
}
m {
color: hwb(from white 0 0% 100% / 100%);
}
n {
color: oklch(from white 100% 100% 0 / 100%);
}
o {
color: oklab(from white 100% 0% 0% / 100%);
}
p {
color: oklab(from white 100% 100% 100% / 100%);
}

View File

@ -22,3 +22,39 @@ f {
g { g {
color: color(from currentcolor srgb r g 100 / 50%); color: color(from currentcolor srgb r g 100 / 50%);
} }
h {
color: color(srgb 1 1 1);
}
i {
color: color(srgb 1 1 1);
}
j {
color: color(srgb-linear 1 1 1);
}
k {
color: color(srgb 1 1 1);
}
l {
color: color(srgb 1 1 1);
}
m {
color: color(srgb 0 0 0);
}
n {
color: oklch(1 0.4 0);
}
o {
color: oklab(1 -0.4 -0.4);
}
p {
color: oklab(1 0.4 0.4);
}