mirror of
https://gitlab.gnome.org/GNOME/gtk.git
synced 2025-01-15 23:00:08 +00:00
Merge branch 'wip/otte/for-main' into 'main'
gsk: Don't print any sRGB color as rgb() or rgba() See merge request GNOME/gtk!7619
This commit is contained in:
commit
0815359a20
@ -331,6 +331,68 @@ gdk_default_color_state_get_cicp (GdkColorState *color_state)
|
||||
return &self->cicp;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
gdk_color_state_check_inf_nan (const float src[4],
|
||||
float dest[4])
|
||||
{
|
||||
if (isnan (src[0]) ||
|
||||
isnan (src[1]) ||
|
||||
isnan (src[2]) ||
|
||||
isnan (src[3]))
|
||||
{
|
||||
dest = (float[4]) { 1.0, 0.0, 0.8, 1.0 };
|
||||
return TRUE;
|
||||
}
|
||||
if (isinf (src[0]) ||
|
||||
isinf (src[1]) ||
|
||||
isinf (src[2]) ||
|
||||
isinf (src[3]))
|
||||
{
|
||||
dest = (float[4]) { 0.0, 0.8, 1.0, 1.0 };
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
static void
|
||||
gdk_color_state_clamp_0_1 (GdkColorState *self,
|
||||
const float src[4],
|
||||
float dest[4])
|
||||
{
|
||||
if (gdk_color_state_check_inf_nan (src, dest))
|
||||
return;
|
||||
|
||||
dest[0] = CLAMP (src[0], 0.0f, 1.0f);
|
||||
dest[1] = CLAMP (src[1], 0.0f, 1.0f);
|
||||
dest[2] = CLAMP (src[2], 0.0f, 1.0f);
|
||||
dest[3] = CLAMP (src[3], 0.0f, 1.0f);
|
||||
}
|
||||
|
||||
static void
|
||||
gdk_color_state_clamp_unbounded (GdkColorState *self,
|
||||
const float src[4],
|
||||
float dest[4])
|
||||
{
|
||||
if (gdk_color_state_check_inf_nan (src, dest))
|
||||
return;
|
||||
|
||||
dest[0] = src[0];
|
||||
dest[1] = src[1];
|
||||
dest[2] = src[2];
|
||||
dest[3] = CLAMP (src[3], 0.0f, 1.0f);
|
||||
}
|
||||
|
||||
static void
|
||||
gdk_default_color_state_clamp (GdkColorState *color_state,
|
||||
const float in[4],
|
||||
float out[4])
|
||||
{
|
||||
GdkDefaultColorState *self = (GdkDefaultColorState *) color_state;
|
||||
|
||||
self->clamp (color_state, in, out);
|
||||
}
|
||||
|
||||
/* }}} */
|
||||
|
||||
static const
|
||||
@ -342,6 +404,7 @@ GdkColorStateClass GDK_DEFAULT_COLOR_STATE_CLASS = {
|
||||
.get_convert_to = gdk_default_color_state_get_convert_to,
|
||||
.get_convert_from = gdk_default_color_state_get_convert_from,
|
||||
.get_cicp = gdk_default_color_state_get_cicp,
|
||||
.clamp = gdk_default_color_state_clamp,
|
||||
};
|
||||
|
||||
GdkDefaultColorState gdk_default_color_states[] = {
|
||||
@ -360,6 +423,7 @@ GdkDefaultColorState gdk_default_color_states[] = {
|
||||
[GDK_COLOR_STATE_ID_REC2100_PQ] = gdk_default_srgb_to_rec2100_pq,
|
||||
[GDK_COLOR_STATE_ID_REC2100_LINEAR] = gdk_default_srgb_to_rec2100_linear,
|
||||
},
|
||||
.clamp = gdk_color_state_clamp_0_1,
|
||||
.cicp = { 1, 13, 0, 1 },
|
||||
},
|
||||
[GDK_COLOR_STATE_ID_SRGB_LINEAR] = {
|
||||
@ -377,6 +441,7 @@ GdkDefaultColorState gdk_default_color_states[] = {
|
||||
[GDK_COLOR_STATE_ID_REC2100_PQ] = gdk_default_srgb_linear_to_rec2100_pq,
|
||||
[GDK_COLOR_STATE_ID_REC2100_LINEAR] = gdk_default_srgb_linear_to_rec2100_linear,
|
||||
},
|
||||
.clamp = gdk_color_state_clamp_0_1,
|
||||
.cicp = { 1, 8, 0, 1 },
|
||||
},
|
||||
[GDK_COLOR_STATE_ID_REC2100_PQ] = {
|
||||
@ -394,6 +459,7 @@ GdkDefaultColorState gdk_default_color_states[] = {
|
||||
[GDK_COLOR_STATE_ID_SRGB_LINEAR] = gdk_default_rec2100_pq_to_srgb_linear,
|
||||
[GDK_COLOR_STATE_ID_REC2100_LINEAR] = gdk_default_rec2100_pq_to_rec2100_linear,
|
||||
},
|
||||
.clamp = gdk_color_state_clamp_0_1,
|
||||
.cicp = { 9, 16, 0, 1 },
|
||||
},
|
||||
[GDK_COLOR_STATE_ID_REC2100_LINEAR] = {
|
||||
@ -411,6 +477,7 @@ GdkDefaultColorState gdk_default_color_states[] = {
|
||||
[GDK_COLOR_STATE_ID_SRGB_LINEAR] = gdk_default_rec2100_linear_to_srgb_linear,
|
||||
[GDK_COLOR_STATE_ID_REC2100_PQ] = gdk_default_rec2100_linear_to_rec2100_pq,
|
||||
},
|
||||
.clamp = gdk_color_state_clamp_unbounded,
|
||||
.cicp = { 9, 8, 0, 1 },
|
||||
},
|
||||
};
|
||||
@ -566,6 +633,7 @@ GdkColorStateClass GDK_CICP_COLOR_STATE_CLASS = {
|
||||
.get_convert_to = gdk_cicp_color_state_get_convert_to,
|
||||
.get_convert_from = gdk_cicp_color_state_get_convert_from,
|
||||
.get_cicp = gdk_cicp_color_state_get_cicp,
|
||||
.clamp = gdk_color_state_clamp_0_1,
|
||||
};
|
||||
|
||||
static inline float *
|
||||
@ -770,6 +838,24 @@ gdk_color_state_get_no_srgb_tf (GdkColorState *self)
|
||||
return self->klass->get_no_srgb_tf (self);
|
||||
}
|
||||
|
||||
/*< private >
|
||||
* gdk_color_state_clamp:
|
||||
* @self: a `GdkColorState`
|
||||
* @src: the values to clamp
|
||||
* @dest: (out): location to store the result, may be identical to
|
||||
* the src argument
|
||||
*
|
||||
* Clamps the values to be within the allowed ranges for the given
|
||||
* color state.
|
||||
*/
|
||||
void
|
||||
gdk_color_state_clamp (GdkColorState *self,
|
||||
const float src[4],
|
||||
float dest[4])
|
||||
{
|
||||
self->klass->clamp (self, src, dest);
|
||||
}
|
||||
|
||||
/* }}} */
|
||||
|
||||
/* vim:set foldmethod=marker expandtab: */
|
||||
|
@ -46,6 +46,9 @@ struct _GdkColorStateClass
|
||||
GdkFloatColorConvert (* get_convert_from) (GdkColorState *self,
|
||||
GdkColorState *source);
|
||||
const GdkCicp * (* get_cicp) (GdkColorState *self);
|
||||
void (* clamp) (GdkColorState *self,
|
||||
const float src[4],
|
||||
float dest[4]);
|
||||
};
|
||||
|
||||
typedef struct _GdkDefaultColorState GdkDefaultColorState;
|
||||
@ -57,6 +60,9 @@ struct _GdkDefaultColorState
|
||||
const char *name;
|
||||
GdkColorState *no_srgb;
|
||||
GdkFloatColorConvert convert_to[GDK_COLOR_STATE_N_IDS];
|
||||
void (* clamp) (GdkColorState *self,
|
||||
const float src[4],
|
||||
float dest[4]);
|
||||
|
||||
GdkCicp cicp;
|
||||
};
|
||||
@ -78,6 +84,10 @@ GdkColorState * gdk_color_state_get_no_srgb_tf (GdkColorState
|
||||
GdkColorState * gdk_color_state_new_for_cicp (const GdkCicp *cicp,
|
||||
GError **error);
|
||||
|
||||
void gdk_color_state_clamp (GdkColorState *self,
|
||||
const float src[4],
|
||||
float dest[4]);
|
||||
|
||||
static inline GdkColorState *
|
||||
gdk_color_state_get_rendering_color_state (GdkColorState *self)
|
||||
{
|
||||
@ -214,4 +224,3 @@ gdk_color_state_from_rgba (GdkColorState *self,
|
||||
self,
|
||||
out_color);
|
||||
}
|
||||
|
||||
|
@ -712,9 +712,130 @@ parse_float4 (GtkCssParser *parser,
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static gboolean parse_color2 (GtkCssParser *parser,
|
||||
Context *context,
|
||||
gpointer color);
|
||||
static gboolean
|
||||
parse_color_state (GtkCssParser *parser,
|
||||
Context *context,
|
||||
gpointer color_state)
|
||||
{
|
||||
GdkColorState *cs = NULL;
|
||||
|
||||
if (gtk_css_parser_try_ident (parser, "srgb"))
|
||||
cs = gdk_color_state_get_srgb ();
|
||||
else if (gtk_css_parser_try_ident (parser, "srgb-linear"))
|
||||
cs = gdk_color_state_get_srgb_linear ();
|
||||
else if (gtk_css_parser_try_ident (parser, "rec2100-pq"))
|
||||
cs = gdk_color_state_get_rec2100_pq ();
|
||||
else if (gtk_css_parser_try_ident (parser, "rec2100-linear"))
|
||||
cs = gdk_color_state_get_rec2100_linear ();
|
||||
else if (gtk_css_token_is (gtk_css_parser_get_token (parser), GTK_CSS_TOKEN_STRING))
|
||||
{
|
||||
char *name = gtk_css_parser_consume_string (parser);
|
||||
|
||||
if (context->named_color_states)
|
||||
cs = g_hash_table_lookup (context->named_color_states, name);
|
||||
|
||||
if (!cs)
|
||||
{
|
||||
gtk_css_parser_error_value (parser, "No color state named \"%s\"", name);
|
||||
g_free (name);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
g_free (name);
|
||||
}
|
||||
else
|
||||
{
|
||||
gtk_css_parser_error_syntax (parser, "Expected a valid color state");
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
*(GdkColorState **) color_state = gdk_color_state_ref (cs);
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
typedef struct {
|
||||
Context *context;
|
||||
GdkColor *color;
|
||||
} ColorArgData;
|
||||
|
||||
static guint
|
||||
parse_color_arg (GtkCssParser *parser,
|
||||
guint arg,
|
||||
gpointer data)
|
||||
{
|
||||
ColorArgData *d = data;
|
||||
GdkColorState *color_state;
|
||||
float values[4], clamped[4];
|
||||
|
||||
if (!parse_color_state (parser, d->context, &color_state))
|
||||
return 0;
|
||||
|
||||
for (int i = 0; i < 3; i++)
|
||||
{
|
||||
double number;
|
||||
|
||||
if (!gtk_css_parser_consume_number_or_percentage (parser, 0, 1, &number))
|
||||
return 0;
|
||||
|
||||
values[i] = number;
|
||||
}
|
||||
|
||||
if (gtk_css_parser_try_delim (parser, '/'))
|
||||
{
|
||||
double number;
|
||||
|
||||
if (!gtk_css_parser_consume_number_or_percentage (parser, 0, 1, &number))
|
||||
return 0;
|
||||
|
||||
values[3] = number;
|
||||
}
|
||||
else
|
||||
{
|
||||
values[3] = 1;
|
||||
}
|
||||
|
||||
gdk_color_state_clamp (color_state, values, clamped);
|
||||
if (values[0] != clamped[0] ||
|
||||
values[1] != clamped[1] ||
|
||||
values[2] != clamped[2] ||
|
||||
values[3] != clamped[3])
|
||||
{
|
||||
gtk_css_parser_error (parser,
|
||||
GTK_CSS_PARSER_ERROR_UNKNOWN_VALUE,
|
||||
gtk_css_parser_get_block_location (parser),
|
||||
gtk_css_parser_get_end_location (parser),
|
||||
"Color values out of range for color state");
|
||||
}
|
||||
|
||||
gdk_color_init (d->color, color_state, clamped);
|
||||
return 1;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
parse_color (GtkCssParser *parser,
|
||||
Context *context,
|
||||
gpointer color)
|
||||
{
|
||||
GdkRGBA rgba;
|
||||
|
||||
if (gtk_css_parser_has_function (parser, "color"))
|
||||
{
|
||||
ColorArgData data = { context, color };
|
||||
|
||||
if (!gtk_css_parser_consume_function (parser, 1, 1, parse_color_arg, &data))
|
||||
return FALSE;
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
else if (gdk_rgba_parser_parse (parser, &rgba))
|
||||
{
|
||||
gdk_color_init_from_rgba ((GdkColor *) color, &rgba);
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
|
||||
static gboolean
|
||||
parse_shadows (GtkCssParser *parser,
|
||||
@ -729,7 +850,7 @@ parse_shadows (GtkCssParser *parser,
|
||||
GdkColor color = GDK_COLOR_SRGB (0, 0, 0, 1);
|
||||
double dx = 0, dy = 0, radius = 0;
|
||||
|
||||
if (!parse_color2 (parser, context, &color))
|
||||
if (!parse_color (parser, context, &color))
|
||||
gtk_css_parser_error_value (parser, "Expected shadow color");
|
||||
|
||||
if (!gtk_css_parser_consume_number (parser, &dx))
|
||||
@ -1565,117 +1686,6 @@ parse_color_state_rule (GtkCssParser *parser,
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
parse_color_state (GtkCssParser *parser,
|
||||
Context *context,
|
||||
gpointer color_state)
|
||||
{
|
||||
GdkColorState *cs = NULL;
|
||||
|
||||
if (gtk_css_parser_try_ident (parser, "srgb"))
|
||||
cs = gdk_color_state_get_srgb ();
|
||||
else if (gtk_css_parser_try_ident (parser, "srgb-linear"))
|
||||
cs = gdk_color_state_get_srgb_linear ();
|
||||
else if (gtk_css_parser_try_ident (parser, "rec2100-pq"))
|
||||
cs = gdk_color_state_get_rec2100_pq ();
|
||||
else if (gtk_css_parser_try_ident (parser, "rec2100-linear"))
|
||||
cs = gdk_color_state_get_rec2100_linear ();
|
||||
else if (gtk_css_token_is (gtk_css_parser_get_token (parser), GTK_CSS_TOKEN_STRING))
|
||||
{
|
||||
char *name = gtk_css_parser_consume_string (parser);
|
||||
|
||||
if (context->named_color_states)
|
||||
cs = g_hash_table_lookup (context->named_color_states, name);
|
||||
|
||||
if (!cs)
|
||||
{
|
||||
gtk_css_parser_error_value (parser, "No color state named \"%s\"", name);
|
||||
g_free (name);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
g_free (name);
|
||||
}
|
||||
else
|
||||
{
|
||||
gtk_css_parser_error_syntax (parser, "Expected a valid color state");
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
*(GdkColorState **) color_state = gdk_color_state_ref (cs);
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
typedef struct {
|
||||
Context *context;
|
||||
GdkColor *color;
|
||||
} ColorArgData;
|
||||
|
||||
static guint
|
||||
parse_color_arg (GtkCssParser *parser,
|
||||
guint arg,
|
||||
gpointer data)
|
||||
{
|
||||
ColorArgData *d = data;
|
||||
GdkColorState *color_state;
|
||||
float values[4];
|
||||
|
||||
if (!parse_color_state (parser, d->context, &color_state))
|
||||
return 0;
|
||||
|
||||
for (int i = 0; i < 3; i++)
|
||||
{
|
||||
double number;
|
||||
|
||||
if (!gtk_css_parser_consume_number_or_percentage (parser, 0, 1, &number))
|
||||
return 0;
|
||||
|
||||
values[i] = number;
|
||||
}
|
||||
|
||||
if (gtk_css_parser_try_delim (parser, '/'))
|
||||
{
|
||||
double number;
|
||||
|
||||
if (!gtk_css_parser_consume_number_or_percentage (parser, 0, 1, &number))
|
||||
return 0;
|
||||
|
||||
values[3] = number;
|
||||
}
|
||||
else
|
||||
{
|
||||
values[3] = 1;
|
||||
}
|
||||
|
||||
gdk_color_init (d->color, color_state, values);
|
||||
return 1;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
parse_color2 (GtkCssParser *parser,
|
||||
Context *context,
|
||||
gpointer color)
|
||||
{
|
||||
GdkRGBA rgba;
|
||||
|
||||
if (gtk_css_parser_has_function (parser, "color"))
|
||||
{
|
||||
ColorArgData data = { context, color };
|
||||
|
||||
if (!gtk_css_parser_consume_function (parser, 1, 1, parse_color_arg, &data))
|
||||
return FALSE;
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
else if (gdk_rgba_parser_parse (parser, &rgba))
|
||||
{
|
||||
gdk_color_init_from_rgba ((GdkColor *) color, &rgba);
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
parse_colors4 (GtkCssParser *parser,
|
||||
Context *context,
|
||||
@ -1686,7 +1696,7 @@ parse_colors4 (GtkCssParser *parser,
|
||||
|
||||
for (i = 0; i < 4 && !gtk_css_parser_has_token (parser, GTK_CSS_TOKEN_EOF); i ++)
|
||||
{
|
||||
if (!parse_color2 (parser, context, &colors[i]))
|
||||
if (!parse_color (parser, context, &colors[i]))
|
||||
return FALSE;
|
||||
}
|
||||
if (i == 0)
|
||||
@ -1712,7 +1722,7 @@ parse_color_node (GtkCssParser *parser,
|
||||
GdkColor color = GDK_COLOR_SRGB (1, 0, 0.8, 1);
|
||||
const Declaration declarations[] = {
|
||||
{ "bounds", parse_rect, NULL, &bounds },
|
||||
{ "color", parse_color2, NULL, &color },
|
||||
{ "color", parse_color, NULL, &color },
|
||||
};
|
||||
GskRenderNode *node;
|
||||
|
||||
@ -1890,7 +1900,7 @@ parse_inset_shadow_node (GtkCssParser *parser,
|
||||
double dx = 1, dy = 1, blur = 0, spread = 0;
|
||||
const Declaration declarations[] = {
|
||||
{ "outline", parse_rounded_rect, NULL, &outline },
|
||||
{ "color", parse_color2, NULL, &color },
|
||||
{ "color", parse_color, NULL, &color },
|
||||
{ "dx", parse_double, NULL, &dx },
|
||||
{ "dy", parse_double, NULL, &dy },
|
||||
{ "spread", parse_double, NULL, &spread },
|
||||
@ -2304,7 +2314,7 @@ parse_outset_shadow_node (GtkCssParser *parser,
|
||||
double dx = 1, dy = 1, blur = 0, spread = 0;
|
||||
const Declaration declarations[] = {
|
||||
{ "outline", parse_rounded_rect, NULL, &outline },
|
||||
{ "color", parse_color2, NULL, &color },
|
||||
{ "color", parse_color, NULL, &color },
|
||||
{ "dx", parse_double, NULL, &dx },
|
||||
{ "dy", parse_double, NULL, &dy },
|
||||
{ "spread", parse_double, NULL, &spread },
|
||||
@ -2615,7 +2625,7 @@ parse_text_node (GtkCssParser *parser,
|
||||
const Declaration declarations[] = {
|
||||
{ "font", parse_font, clear_font, &font },
|
||||
{ "offset", parse_point, NULL, &offset },
|
||||
{ "color", parse_color2, NULL, &color },
|
||||
{ "color", parse_color, NULL, &color },
|
||||
{ "glyphs", parse_glyphs, clear_glyphs, &glyphs },
|
||||
{ "hint-style", parse_hint_style, NULL, &hint_style },
|
||||
{ "antialias", parse_antialias, NULL, &antialias },
|
||||
@ -3668,7 +3678,10 @@ static void
|
||||
print_color (Printer *p,
|
||||
const GdkColor *color)
|
||||
{
|
||||
if (gdk_color_state_equal (color->color_state, GDK_COLOR_STATE_SRGB))
|
||||
if (gdk_color_state_equal (color->color_state, GDK_COLOR_STATE_SRGB) &&
|
||||
round (CLAMP (color->red, 0, 1) * 255) == color->red * 255 &&
|
||||
round (CLAMP (color->green, 0, 1) * 255) == color->green * 255 &&
|
||||
round (CLAMP (color->blue, 0, 1) * 255) == color->blue * 255)
|
||||
{
|
||||
gdk_rgba_print ((const GdkRGBA *) color->values, p->str);
|
||||
}
|
||||
|
@ -431,6 +431,7 @@ node_parser_tests = [
|
||||
'shadow-fail.node',
|
||||
'shadow-fail.ref.node',
|
||||
'shadow-fail.errors',
|
||||
'srgb-high-accuracy.node',
|
||||
'string-error.errors',
|
||||
'string-error.node',
|
||||
'string-error.ref.node',
|
||||
|
@ -4,7 +4,7 @@ color {
|
||||
}
|
||||
color {
|
||||
bounds: 100 100 200 300;
|
||||
color: rgb(1,1,0);
|
||||
color: color(srgb 0.00392157 0.00196078 0.00117647);
|
||||
}
|
||||
color {
|
||||
bounds: 100 100 200 300;
|
||||
|
@ -1 +1,2 @@
|
||||
<data>:2:27-28: error: GTK_CSS_PARSER_ERROR_SYNTAX
|
||||
<data>:2:10-27: error: GTK_CSS_PARSER_ERROR_UNKNOWN_VALUE
|
||||
<data>:6:27-28: error: GTK_CSS_PARSER_ERROR_SYNTAX
|
||||
|
@ -1,3 +1,7 @@
|
||||
color {
|
||||
color: color(srgb 1 2 3 4 5 6);
|
||||
color: color(srgb 1 2 3);
|
||||
}
|
||||
|
||||
color {
|
||||
color: color(srgb 1 1 1 1 1 1);
|
||||
}
|
||||
|
@ -2,3 +2,7 @@ color {
|
||||
bounds: 0 0 50 50;
|
||||
color: rgb(255,255,255);
|
||||
}
|
||||
color {
|
||||
bounds: 0 0 50 50;
|
||||
color: rgb(255,255,255);
|
||||
}
|
||||
|
4
testsuite/gsk/nodeparser/srgb-high-accuracy.node
Normal file
4
testsuite/gsk/nodeparser/srgb-high-accuracy.node
Normal file
@ -0,0 +1,4 @@
|
||||
color {
|
||||
bounds: 0 0 50 50;
|
||||
color: color(srgb 0.999 0 0);
|
||||
}
|
Loading…
Reference in New Issue
Block a user