gdk: Add gdk_color_state_clamp()

Allows clamping values into the correct range to construct valid colors.
This commit is contained in:
Matthias Clasen 2024-08-06 16:15:53 -04:00 committed by Benjamin Otte
parent 585f31fa2e
commit 4e9ebb5299
2 changed files with 96 additions and 1 deletions

View File

@ -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: */

View File

@ -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);
}