diff --git a/gdk/gdkcolorstate.c b/gdk/gdkcolorstate.c index f6493de173..35f5c23402 100644 --- a/gdk/gdkcolorstate.c +++ b/gdk/gdkcolorstate.c @@ -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: */ diff --git a/gdk/gdkcolorstateprivate.h b/gdk/gdkcolorstateprivate.h index f2bfb93bf6..be98807f0c 100644 --- a/gdk/gdkcolorstateprivate.h +++ b/gdk/gdkcolorstateprivate.h @@ -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); } -