css: Split off GtkCssColor

Break out a GtkCssColor struct.
This commit is contained in:
Matthias Clasen
2024-05-31 15:46:51 -04:00
parent d506a5eea8
commit 5a85bc691e
5 changed files with 304 additions and 227 deletions

64
gtk/gtkcsscolor.c Normal file
View File

@@ -0,0 +1,64 @@
/* GTK - The GIMP Toolkit
* Copyright (C) 2024 Red Hat, Inc.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library. If not, see <http://www.gnu.org/licenses/>.
*/
#include "config.h"
#include "gtkcsscolorprivate.h"
#include "gtkcolorutilsprivate.h"
/* {{{ Initialization */
void
gtk_css_color_init (GtkCssColor *color,
GtkCssColorSpace color_space,
const float values[4])
{
gboolean missing[4] = { 0, };
/* look for powerless components */
switch (color_space)
{
case GTK_CSS_COLOR_SPACE_SRGB:
case GTK_CSS_COLOR_SPACE_SRGB_LINEAR:
case GTK_CSS_COLOR_SPACE_OKLAB:
break;
case GTK_CSS_COLOR_SPACE_HSL:
if (fabs (values[2]) < 0.001)
missing[0] = 1;
break;
case GTK_CSS_COLOR_SPACE_HWB:
if (values[1] + values[2] > 99.999)
missing[0] = 1;
break;
case GTK_CSS_COLOR_SPACE_OKLCH:
if (fabs (values[1]) < 0.001)
missing[2] = 1;
break;
default:
g_assert_not_reached ();
}
gtk_css_color_init_with_missing (color, color_space, values, missing);
}
/* }}} */
/* vim:set foldmethod=marker expandtab: */

87
gtk/gtkcsscolorprivate.h Normal file
View File

@@ -0,0 +1,87 @@
/* GTK - The GIMP Toolkit
* Copyright (C) 2040 Red Hat, Inc.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library. If not, see <http://www.gnu.org/licenses/>.
*/
#pragma once
#include <glib.h>
#include <math.h>
G_BEGIN_DECLS
typedef enum {
GTK_CSS_COLOR_SPACE_SRGB,
GTK_CSS_COLOR_SPACE_SRGB_LINEAR,
GTK_CSS_COLOR_SPACE_HSL,
GTK_CSS_COLOR_SPACE_HWB,
GTK_CSS_COLOR_SPACE_OKLAB,
GTK_CSS_COLOR_SPACE_OKLCH,
} GtkCssColorSpace;
typedef struct
{
GtkCssColorSpace color_space;
float values[4];
guint missing;
} GtkCssColor;
static inline gboolean
gtk_css_color_equal (const GtkCssColor *color1,
const GtkCssColor *color2)
{
return color1->color_space == color2->color_space &&
color1->missing == color2->missing &&
memcmp (color1->values, color2->values, sizeof (float) * 4) == 0;
}
static inline gboolean
gtk_css_color_component_missing (const GtkCssColor *color,
guint idx)
{
return (color->missing & (1 << idx)) != 0;
}
static inline float
gtk_css_color_get_component (const GtkCssColor *color,
guint idx)
{
return color->values[idx];
}
static inline void
gtk_css_color_init_with_missing (GtkCssColor *color,
GtkCssColorSpace color_space,
const float values[4],
gboolean missing[4])
{
color->color_space = color_space;
for (guint i = 0; i < 4; i++)
color->values[i] = missing[i] ? 0 : values[i];
color->missing = missing[0] | (missing[1] << 1) | (missing[2] << 2) | (missing[3] << 3);
}
static inline void
gtk_css_color_init_from_color (GtkCssColor *color,
const GtkCssColor *src)
{
memcpy (color, src, sizeof (GtkCssColor));
}
void gtk_css_color_init (GtkCssColor *color,
GtkCssColorSpace color_space,
const float values[4]);
G_END_DECLS

View File

@@ -28,19 +28,14 @@
#include "gdk/gdkhslaprivate.h"
#include "gdk/gdkrgbaprivate.h"
#include "gtkcsscolorprivate.h"
#include "gtkcolorutilsprivate.h"
typedef enum {
GTK_CSS_COLOR_SPACE_SRGB,
GTK_CSS_COLOR_SPACE_SRGB_LINEAR,
} GtkCssColorSpace;
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,
gboolean missing[4]);
static GtkCssValue * gtk_css_color_value_new_literal (const GdkRGBA *color);
typedef enum {
COLOR_TYPE_LITERAL,
@@ -50,26 +45,19 @@ typedef enum {
COLOR_TYPE_ALPHA,
COLOR_TYPE_MIX,
COLOR_TYPE_CURRENT_COLOR,
COLOR_TYPE_OKLAB,
COLOR_TYPE_OKLCH,
} ColorType;
struct _GtkCssValue
{
GTK_CSS_VALUE_BASE
guint serialize_as_rgb: 1;
ColorType type;
guint missing;
union
{
char *name;
GdkRGBA rgba;
struct
{
GtkCssColorSpace color_space;
float values[4];
} color;
GtkCssColor color;
struct
{
@@ -83,16 +71,6 @@ struct _GtkCssValue
GtkCssValue *color2;
double factor;
} mix;
struct
{
float L, a, b, alpha;
} oklab;
struct
{
float L, C, H, alpha;
} oklch;
};
};
@@ -121,8 +99,6 @@ gtk_css_value_color_free (GtkCssValue *color)
case COLOR_TYPE_LITERAL:
case COLOR_TYPE_COLOR:
case COLOR_TYPE_CURRENT_COLOR:
case COLOR_TYPE_OKLAB:
case COLOR_TYPE_OKLCH:
default:
break;
}
@@ -220,13 +196,10 @@ gtk_css_value_color_equal (const GtkCssValue *value1,
switch (value1->type)
{
case COLOR_TYPE_LITERAL:
return gdk_rgba_equal (&value1->rgba, &value2->rgba) &&
value1->missing == value2->missing;
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 &&
value1->missing == value2->missing;
return gtk_css_color_equal (&value1->color, &value2->color);
case COLOR_TYPE_NAME:
return g_str_equal (value1->name, value2->name);
@@ -251,20 +224,6 @@ gtk_css_value_color_equal (const GtkCssValue *value1,
case COLOR_TYPE_CURRENT_COLOR:
return TRUE;
case COLOR_TYPE_OKLAB:
return value1->oklab.L == value2->oklab.L &&
value1->oklab.a == value2->oklab.a &&
value1->oklab.b == value2->oklab.b &&
value1->oklab.alpha == value2->oklab.alpha &&
value1->missing == value2->missing;
case COLOR_TYPE_OKLCH:
return value1->oklch.L == value2->oklch.L &&
value1->oklch.C == value2->oklch.C &&
value1->oklch.H == value2->oklch.H &&
value1->oklch.alpha == value2->oklch.alpha &&
value1->missing == value2->missing;
default:
g_assert_not_reached ();
return FALSE;
@@ -281,14 +240,93 @@ gtk_css_value_color_transition (GtkCssValue *start,
}
static inline void
append_color_component (GString *string,
float value,
gboolean missing)
append_color_component (GString *string,
const GtkCssColor *color,
guint idx)
{
if (missing)
if (gtk_css_color_component_missing (color, idx))
g_string_append (string, "none");
else
g_string_append_printf (string, "%g", value);
g_string_append_printf (string, "%g", gtk_css_color_get_component (color, idx));
}
static void
convert_to_rgba (const GtkCssValue *value,
GdkRGBA *rgba)
{
g_assert (value->type == COLOR_TYPE_COLOR);
switch (value->color.color_space)
{
case GTK_CSS_COLOR_SPACE_SRGB:
rgba->red = CLAMP (value->color.values[0], 0, 1);
rgba->green = CLAMP (value->color.values[1], 0, 1);
rgba->blue = CLAMP (value->color.values[2], 0, 1);
rgba->alpha = CLAMP (value->color.values[3], 0, 1);
break;
case GTK_CSS_COLOR_SPACE_SRGB_LINEAR:
gtk_linear_srgb_to_rgb (CLAMP (value->color.values[0], 0, 1),
CLAMP (value->color.values[1], 0, 1),
CLAMP (value->color.values[2], 0, 1),
&rgba->red,
&rgba->green,
&rgba->blue);
rgba->alpha = CLAMP (value->color.values[3], 0, 1);
break;
case GTK_CSS_COLOR_SPACE_HSL:
{
GdkHSLA hsla;
hsla.hue = value->color.values[0];
hsla.saturation = CLAMP (value->color.values[1] / 100, 0, 1);
hsla.lightness = CLAMP (value->color.values[2] / 100, 0, 1);
hsla.alpha = CLAMP (value->color.values[3], 0, 1);
_gdk_rgba_init_from_hsla (rgba, &hsla);
}
break;
case GTK_CSS_COLOR_SPACE_HWB:
{
float h, w, b;
h = value->color.values[0];
w = CLAMP (value->color.values[1] / 100, 0, 1);
b = CLAMP (value->color.values[2] / 100, 0, 1);
gtk_hwb_to_rgb (h, w, b, &rgba->red, &rgba->green, &rgba->blue);
rgba->alpha = value->color.values[3];
}
break;
case GTK_CSS_COLOR_SPACE_OKLAB:
gtk_oklab_to_rgb (CLAMP (value->color.values[0], 0, 1),
value->color.values[1],
value->color.values[2],
&rgba->red,
&rgba->green,
&rgba->blue);
rgba->alpha = value->color.values[3];
break;
case GTK_CSS_COLOR_SPACE_OKLCH:
{
float L, C, H, a, b;
L = CLAMP (value->color.values[0], 0, 1);
C = MAX (value->color.values[1], 0);
H = value->color.values[2];
gtk_oklch_to_oklab (L, C, H, &L, &a, &b);
gtk_oklab_to_rgb (L, a, b, &rgba->red, &rgba->green, &rgba->blue);
rgba->alpha = value->color.values[3];
}
break;
default:
g_assert_not_reached ();
}
}
static void
@@ -308,16 +346,39 @@ gtk_css_value_color_print (const GtkCssValue *value,
break;
case COLOR_TYPE_COLOR:
g_string_append (string, "color(");
switch (value->color.color_space)
{
case GTK_CSS_COLOR_SPACE_HSL:
case GTK_CSS_COLOR_SPACE_HWB:
{
print_rgb:
GdkRGBA rgba;
char *s;
convert_to_rgba (value, &rgba);
s = gdk_rgba_to_string (&rgba);
g_string_append (string, s);
g_free (s);
}
return;
case GTK_CSS_COLOR_SPACE_SRGB:
g_string_append (string, "srgb");
if (value->serialize_as_rgb)
goto print_rgb;
g_string_append (string, "color(srgb ");
break;
case GTK_CSS_COLOR_SPACE_SRGB_LINEAR:
g_string_append (string, "srgb-linear");
g_string_append (string, "color(srgb-linear ");
break;
case GTK_CSS_COLOR_SPACE_OKLAB:
g_string_append (string, "oklab(");
break;
case GTK_CSS_COLOR_SPACE_OKLCH:
g_string_append (string, "oklch(");
break;
default:
@@ -326,14 +387,16 @@ gtk_css_value_color_print (const GtkCssValue *value,
for (guint i = 0; i < 3; i++)
{
g_string_append_c (string, ' ');
append_color_component (string, value->color.values[i], value->missing & (1 << i));
if (i > 0)
g_string_append_c (string, ' ');
append_color_component (string, &value->color, i);
}
if ((value->missing & (1 << 3)) != 0 || value->color.values[3] < 0.999)
if (gtk_css_color_component_missing (&value->color, 3) ||
gtk_css_color_get_component (&value->color, 3) < 0.999)
{
g_string_append (string, " / ");
append_color_component (string, value->color.values[3], value->missing & (1 << 3));
append_color_component (string, &value->color, 3);
}
g_string_append_c (string, ')');
@@ -377,37 +440,6 @@ gtk_css_value_color_print (const GtkCssValue *value,
g_string_append (string, "currentcolor");
break;
case COLOR_TYPE_OKLAB:
g_string_append (string, "oklab(");
append_color_component (string, value->oklab.L, value->missing & (1 << 0));
g_string_append_c (string, ' ');
append_color_component (string, value->oklab.a, value->missing & (1 << 1));
g_string_append_c (string, ' ');
append_color_component (string, value->oklab.b, value->missing & (1 << 2));
if ((value->missing & (1 << 3)) != 0 || value->oklab.alpha < 0.999)
{
g_string_append (string, " / ");
append_color_component (string, value->oklab.alpha, value->missing & (1 << 3));
}
g_string_append_c (string, ')');
break;
case COLOR_TYPE_OKLCH:
g_string_append (string, "oklch(");
append_color_component (string, value->oklch.L, value->missing & (1 << 0));
g_string_append_c (string, ' ');
append_color_component (string, value->oklch.C, value->missing & (1 << 1));
g_string_append_c (string, ' ');
append_color_component (string, value->oklch.H, value->missing & (1 << 2));
if ((value->missing & (1 << 3)) != 0 || value->oklch.alpha < 0.999)
{
g_string_append (string, " / ");
append_color_component (string, value->oklab.alpha, value->missing & (1 << 3));
}
g_string_append_c (string, ')');
break;
default:
g_assert_not_reached ();
}
@@ -495,34 +527,8 @@ gtk_css_color_value_do_resolve (GtkCssValue *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 ();
}
value = gtk_css_color_value_new_literal (&rgba,
(gboolean []) {
(color->missing & (1 << 0)) != 0,
(color->missing & (1 << 1)) != 0,
(color->missing & (1 << 2)) != 0,
(color->missing & (1 << 3)) != 0,
});
convert_to_rgba (color, &rgba);
value = gtk_css_color_value_new_literal (&rgba);
}
break;
@@ -557,7 +563,7 @@ gtk_css_color_value_do_resolve (GtkCssValue *color,
apply_shade (c, &shade, color->shade.factor);
value = gtk_css_color_value_new_literal (&shade, NULL);
value = gtk_css_color_value_new_literal (&shade);
gtk_css_value_unref (val);
}
break;
@@ -575,7 +581,7 @@ gtk_css_color_value_do_resolve (GtkCssValue *color,
apply_alpha (c, &alpha, color->alpha.factor);
value = gtk_css_color_value_new_literal (&alpha, NULL);
value = gtk_css_color_value_new_literal (&alpha);
gtk_css_value_unref (val);
}
break;
@@ -598,7 +604,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, NULL);
value = gtk_css_color_value_new_literal (&res);
gtk_css_value_unref (val1);
gtk_css_value_unref (val2);
}
@@ -611,32 +617,6 @@ gtk_css_color_value_do_resolve (GtkCssValue *color,
value = gtk_css_value_ref (current);
break;
case COLOR_TYPE_OKLAB:
{
GdkRGBA rgba;
gtk_oklab_to_rgb (color->oklab.L, color->oklab.a, color->oklab.b,
&rgba.red, &rgba.green, &rgba.blue);
rgba.alpha = color->oklab.alpha;
value = gtk_css_color_value_new_literal (&rgba, NULL);
}
break;
case COLOR_TYPE_OKLCH:
{
float L, a, b;
GdkRGBA rgba;
gtk_oklch_to_oklab (color->oklch.L, color->oklch.C, color->oklch.H, &L, &a, &b);
gtk_oklab_to_rgb (L, a, b, &rgba.red, &rgba.green, &rgba.blue);
rgba.alpha = color->oklab.alpha;
value = gtk_css_color_value_new_literal (&rgba, NULL);
}
break;
default:
value = NULL;
g_assert_not_reached ();
@@ -653,9 +633,9 @@ gtk_css_color_value_resolve (GtkCssValue *color,
return gtk_css_color_value_do_resolve (color, provider, current, NULL);
}
static GtkCssValue transparent_black_singleton = { &GTK_CSS_VALUE_COLOR, 1, TRUE, FALSE, COLOR_TYPE_LITERAL,
static GtkCssValue transparent_black_singleton = { &GTK_CSS_VALUE_COLOR, 1, TRUE, FALSE, FALSE, COLOR_TYPE_LITERAL,
.rgba = {0, 0, 0, 0} };
static GtkCssValue white_singleton = { &GTK_CSS_VALUE_COLOR, 1, TRUE, FALSE, COLOR_TYPE_LITERAL,
static GtkCssValue white_singleton = { &GTK_CSS_VALUE_COLOR, 1, TRUE, FALSE, FALSE, COLOR_TYPE_LITERAL,
.rgba = {1, 1, 1, 1} };
@@ -672,8 +652,7 @@ gtk_css_color_value_new_white (void)
}
static GtkCssValue *
gtk_css_color_value_new_literal (const GdkRGBA *color,
gboolean missing[4])
gtk_css_color_value_new_literal (const GdkRGBA *color)
{
GtkCssValue *value;
@@ -687,8 +666,6 @@ gtk_css_color_value_new_literal (const GdkRGBA *color,
value = gtk_css_value_new (GtkCssValue, &GTK_CSS_VALUE_COLOR);
value->type = COLOR_TYPE_LITERAL;
if (missing)
value->missing = missing[0] | (missing[1] << 1) | (missing[2] << 2) | missing[3] << 3;
value->is_computed = TRUE;
value->rgba = *color;
@@ -696,7 +673,8 @@ gtk_css_color_value_new_literal (const GdkRGBA *color,
}
static GtkCssValue *
gtk_css_value_value_new_color (GtkCssColorSpace color_space,
gtk_css_color_value_new_color (GtkCssColorSpace color_space,
gboolean serialize_as_rgb,
float values[4],
gboolean missing[4])
{
@@ -704,9 +682,9 @@ gtk_css_value_value_new_color (GtkCssColorSpace color_space,
value = gtk_css_value_new (GtkCssValue, &GTK_CSS_VALUE_COLOR);
value->type = COLOR_TYPE_COLOR;
value->missing = missing[0] | (missing[1] << 1) | (missing[2] << 2) | missing[3] << 3;
value->color.color_space = color_space;
memcpy (value->color.values, values, sizeof (float) * 4);
value->serialize_as_rgb = serialize_as_rgb;
gtk_css_color_init_with_missing (&value->color, color_space, values, missing);
return value;
}
@@ -739,7 +717,7 @@ gtk_css_color_value_new_shade (GtkCssValue *color,
apply_shade (&color->rgba, &c, factor);
return gtk_css_color_value_new_literal (&c, (gboolean[]) { 0, 0, 0, 0 });
return gtk_css_color_value_new_literal (&c);
}
value = gtk_css_value_new (GtkCssValue, &GTK_CSS_VALUE_COLOR);
@@ -764,7 +742,7 @@ gtk_css_color_value_new_alpha (GtkCssValue *color,
apply_alpha (&color->rgba, &c, factor);
return gtk_css_color_value_new_literal (&c, NULL);
return gtk_css_color_value_new_literal (&c);
}
value = gtk_css_value_new (GtkCssValue, &GTK_CSS_VALUE_COLOR);
@@ -792,7 +770,7 @@ gtk_css_color_value_new_mix (GtkCssValue *color1,
apply_mix (&color1->rgba, &color2->rgba, &result, factor);
return gtk_css_color_value_new_literal (&result, NULL);
return gtk_css_color_value_new_literal (&result);
}
@@ -808,51 +786,11 @@ gtk_css_color_value_new_mix (GtkCssValue *color1,
GtkCssValue *
gtk_css_color_value_new_current_color (void)
{
static GtkCssValue current_color = { &GTK_CSS_VALUE_COLOR, 1, FALSE, FALSE, COLOR_TYPE_CURRENT_COLOR, };
static GtkCssValue current_color = { &GTK_CSS_VALUE_COLOR, 1, FALSE, FALSE, FALSE, COLOR_TYPE_CURRENT_COLOR, };
return gtk_css_value_ref (&current_color);
}
static GtkCssValue *
gtk_css_color_value_new_oklab (float L,
float a,
float b,
float alpha,
gboolean missing[4])
{
GtkCssValue *value;
value = gtk_css_value_new (GtkCssValue, &GTK_CSS_VALUE_COLOR);
value->type = COLOR_TYPE_OKLAB;
value->missing = missing[0] | (missing[1] << 1) | (missing[2] << 2) | missing[3] << 3;
value->oklab.L = L;
value->oklab.a = a;
value->oklab.b = b;
value->oklab.alpha = alpha;
return value;
}
static GtkCssValue *
gtk_css_color_value_new_oklch (float L,
float C,
float H,
float alpha,
gboolean missing[4])
{
GtkCssValue *value;
value = gtk_css_value_new (GtkCssValue, &GTK_CSS_VALUE_COLOR);
value->type = COLOR_TYPE_OKLCH;
value->missing = missing[0] | (missing[1] << 1) | (missing[2] << 2) | missing[3] << 3;
value->oklab.L = L;
value->oklab.a = C;
value->oklab.b = H;
value->oklab.alpha = alpha;
return value;
}
typedef struct
{
GtkCssValue *color;
@@ -1076,7 +1014,7 @@ parse_hsl_channel_value (GtkCssParser *parser,
return FALSE;
*value = gtk_css_number_value_get_canonical (val, 100);
*value = CLAMP (*value, 0.0, 100.0) / 100.0;
*value = CLAMP (*value, 0.0, 100.0);
gtk_css_value_unref (val);
}
@@ -1141,6 +1079,9 @@ parse_hue_value (GtkCssParser *parser,
return FALSE;
*value = gtk_css_number_value_get_canonical (hue, 360);
*value = fmod (*value, 360);
if (*value < 0)
*value += 360;
gtk_css_value_unref (hue);
}
@@ -1622,7 +1563,7 @@ gtk_css_color_value_parse (GtkCssParser *parser)
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, data.missing);
return gtk_css_color_value_new_color (GTK_CSS_COLOR_SPACE_SRGB, TRUE, (float *) &rgba, data.missing);
}
else if (gtk_css_parser_has_function (parser, "hsl") || gtk_css_parser_has_function (parser, "hsla"))
{
@@ -1633,30 +1574,16 @@ 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;
_gdk_rgba_init_from_hsla (&rgba, data.hsla);
/* FIXME */
return gtk_css_color_value_new_literal (&rgba, (gboolean[]) { 0, 0, 0, 0 } );
return gtk_css_color_value_new_color (GTK_CSS_COLOR_SPACE_HSL, FALSE, (float *) &hsla, data.missing);
}
else if (gtk_css_parser_has_function (parser, "hwb"))
{
HwbData hwb = { 0, 0, 0, 1, { FALSE, } };
float red, green, blue;
if (!parse_color_function (parser, COLOR_SYNTAX_MODERN, FALSE, TRUE, FALSE, parse_hwb_color_channel, &hwb))
return NULL;
hwb.white /= 100.0;
hwb.black /= 100.0;
gtk_hwb_to_rgb (hwb.hue, hwb.white, hwb.black, &red, &green, &blue);
rgba.red = red;
rgba.green = green;
rgba.blue = blue;
rgba.alpha = hwb.alpha;
return gtk_css_color_value_new_literal (&rgba, (gboolean[]) { 0, 0, 0, 0 } );
return gtk_css_color_value_new_color (GTK_CSS_COLOR_SPACE_HWB, FALSE, (float *) &hwb, hwb.missing);
}
else if (gtk_css_parser_has_function (parser, "oklab"))
{
@@ -1665,8 +1592,7 @@ gtk_css_color_value_parse (GtkCssParser *parser)
if (!parse_color_function (parser, COLOR_SYNTAX_MODERN, FALSE, TRUE, FALSE, parse_oklab_color_channel, &oklab))
return NULL;
return gtk_css_color_value_new_oklab (oklab.L, oklab.a, oklab.b, oklab.alpha,
oklab.missing);
return gtk_css_color_value_new_color (GTK_CSS_COLOR_SPACE_OKLAB, FALSE, (float *) &oklab, oklab.missing);
}
else if (gtk_css_parser_has_function (parser, "oklch"))
{
@@ -1675,8 +1601,7 @@ gtk_css_color_value_parse (GtkCssParser *parser)
if (!parse_color_function (parser, COLOR_SYNTAX_MODERN, FALSE, TRUE, FALSE, parse_oklch_color_channel, &oklch))
return NULL;
return gtk_css_color_value_new_oklch (oklch.L, oklch.C, oklch.H, oklch.alpha,
oklch.missing);
return gtk_css_color_value_new_color (GTK_CSS_COLOR_SPACE_OKLCH, FALSE, (float *) &oklch, oklch.missing);
}
else if (gtk_css_parser_has_function (parser, "color"))
{
@@ -1685,7 +1610,7 @@ gtk_css_color_value_parse (GtkCssParser *parser)
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, data.missing);
return gtk_css_color_value_new_color (data.color_space, FALSE, data.values, data.missing);
}
else if (gtk_css_parser_has_function (parser, "lighter"))
{
@@ -1750,7 +1675,7 @@ gtk_css_color_value_parse (GtkCssParser *parser)
}
if (gdk_rgba_parser_parse (parser, &rgba))
return gtk_css_color_value_new_literal (&rgba, (gboolean[]) { 0, 0, 0, 0 });
return gtk_css_color_value_new_literal (&rgba);
else
return NULL;
}

View File

@@ -51,6 +51,7 @@ gtk_private_sources = files([
'gtkcssbgsizevalue.c',
'gtkcssbordervalue.c',
'gtkcsscalcvalue.c',
'gtkcsscolor.c',
'gtkcsscolorvalue.c',
'gtkcsscornervalue.c',
'gtkcsscustompropertypool.c',

View File

@@ -113,11 +113,11 @@ ab {
}
ac {
color: oklab(0.80000001192092896 0 0.30000001192092896 / 0.5);
color: oklab(0.8 0 0.3 / 0.5);
}
ad {
color: oklch(0.80000001192092896 0.30000001192092896 200 / 0.5);
color: oklch(0.8 0.3 200 / 0.5);
}
ae {