mirror of
https://gitlab.gnome.org/GNOME/gtk.git
synced 2024-11-09 18:30:08 +00:00
3cd25516ab
Keep a linear and a non-linear rendering colorstate around. That way, we don't "return self;" from cicp colorstates and then end up with a cicp ccs.
218 lines
6.5 KiB
C
218 lines
6.5 KiB
C
#pragma once
|
|
|
|
#include "gdkcolorstate.h"
|
|
|
|
#include "gdkcicpparamsprivate.h"
|
|
#include "gdkdebugprivate.h"
|
|
#include "gdkmemoryformatprivate.h"
|
|
#include "gdkrgba.h"
|
|
|
|
typedef enum
|
|
{
|
|
GDK_COLOR_STATE_ID_SRGB,
|
|
GDK_COLOR_STATE_ID_SRGB_LINEAR,
|
|
GDK_COLOR_STATE_ID_REC2100_PQ,
|
|
GDK_COLOR_STATE_ID_REC2100_LINEAR,
|
|
|
|
GDK_COLOR_STATE_N_IDS
|
|
} GdkColorStateId;
|
|
|
|
typedef struct _GdkColorStateClass GdkColorStateClass;
|
|
|
|
struct _GdkColorState
|
|
{
|
|
const GdkColorStateClass *klass;
|
|
gatomicrefcount ref_count;
|
|
|
|
GdkMemoryDepth depth;
|
|
GdkColorState *rendering_color_state;
|
|
GdkColorState *rendering_color_state_linear;
|
|
};
|
|
|
|
/* Note: self may be the source or the target colorstate */
|
|
typedef void (* GdkFloatColorConvert)(GdkColorState *self,
|
|
float (*values)[4],
|
|
gsize n_values);
|
|
|
|
struct _GdkColorStateClass
|
|
{
|
|
void (* free) (GdkColorState *self);
|
|
gboolean (* equal) (GdkColorState *self,
|
|
GdkColorState *other);
|
|
const char * (* get_name) (GdkColorState *self);
|
|
GdkColorState * (* get_no_srgb_tf) (GdkColorState *self);
|
|
GdkFloatColorConvert (* get_convert_to) (GdkColorState *self,
|
|
GdkColorState *target);
|
|
GdkFloatColorConvert (* get_convert_from) (GdkColorState *self,
|
|
GdkColorState *source);
|
|
const GdkCicp * (* get_cicp) (GdkColorState *self);
|
|
};
|
|
|
|
typedef struct _GdkDefaultColorState GdkDefaultColorState;
|
|
|
|
struct _GdkDefaultColorState
|
|
{
|
|
GdkColorState parent;
|
|
|
|
const char *name;
|
|
GdkColorState *no_srgb;
|
|
GdkFloatColorConvert convert_to[GDK_COLOR_STATE_N_IDS];
|
|
|
|
GdkCicp cicp;
|
|
};
|
|
|
|
extern GdkDefaultColorState gdk_default_color_states[GDK_COLOR_STATE_N_IDS];
|
|
|
|
#define GDK_COLOR_STATE_SRGB ((GdkColorState *) &gdk_default_color_states[GDK_COLOR_STATE_ID_SRGB])
|
|
#define GDK_COLOR_STATE_SRGB_LINEAR ((GdkColorState *) &gdk_default_color_states[GDK_COLOR_STATE_ID_SRGB_LINEAR])
|
|
#define GDK_COLOR_STATE_REC2100_PQ ((GdkColorState *) &gdk_default_color_states[GDK_COLOR_STATE_ID_REC2100_PQ])
|
|
#define GDK_COLOR_STATE_REC2100_LINEAR ((GdkColorState *) &gdk_default_color_states[GDK_COLOR_STATE_ID_REC2100_LINEAR])
|
|
|
|
#define GDK_IS_DEFAULT_COLOR_STATE(c) ((GdkDefaultColorState *) (c) >= &gdk_default_color_states[0] && \
|
|
(GdkDefaultColorState *) (c) < &gdk_default_color_states[GDK_COLOR_STATE_N_IDS])
|
|
#define GDK_DEFAULT_COLOR_STATE_ID(c) ((GdkColorStateId) (((GdkDefaultColorState *) c) - gdk_default_color_states))
|
|
|
|
const char * gdk_color_state_get_name (GdkColorState *color_state);
|
|
GdkColorState * gdk_color_state_get_no_srgb_tf (GdkColorState *self);
|
|
|
|
GdkColorState * gdk_color_state_new_for_cicp (const GdkCicp *cicp,
|
|
GError **error);
|
|
|
|
static inline GdkColorState *
|
|
gdk_color_state_get_rendering_color_state (GdkColorState *self)
|
|
{
|
|
if (GDK_DEBUG_CHECK (HDR))
|
|
self = GDK_COLOR_STATE_REC2100_PQ;
|
|
|
|
if (!GDK_DEBUG_CHECK (LINEAR))
|
|
return self->rendering_color_state;
|
|
|
|
return self->rendering_color_state_linear;
|
|
}
|
|
|
|
static inline GdkMemoryDepth
|
|
gdk_color_state_get_depth (GdkColorState *self)
|
|
{
|
|
if (!GDK_DEBUG_CHECK (LINEAR) && self->depth == GDK_MEMORY_U8_SRGB)
|
|
return GDK_MEMORY_U8;
|
|
|
|
return self->depth;
|
|
}
|
|
|
|
static inline GdkColorState *
|
|
gdk_color_state_get_by_id (GdkColorStateId id)
|
|
{
|
|
return (GdkColorState *) &gdk_default_color_states[id];
|
|
}
|
|
|
|
#define gdk_color_state_ref(self) _gdk_color_state_ref (self)
|
|
static inline GdkColorState *
|
|
_gdk_color_state_ref (GdkColorState *self)
|
|
{
|
|
if (GDK_IS_DEFAULT_COLOR_STATE (self))
|
|
return self;
|
|
|
|
g_atomic_ref_count_inc (&self->ref_count);
|
|
|
|
return self;
|
|
}
|
|
|
|
#define gdk_color_state_unref(self) _gdk_color_state_unref (self)
|
|
static inline void
|
|
_gdk_color_state_unref (GdkColorState *self)
|
|
{
|
|
if (GDK_IS_DEFAULT_COLOR_STATE (self))
|
|
return;
|
|
|
|
if (g_atomic_ref_count_dec (&self->ref_count))
|
|
self->klass->free (self);
|
|
}
|
|
|
|
#define gdk_color_state_equal(a,b) _gdk_color_state_equal ((a), (b))
|
|
static inline gboolean
|
|
_gdk_color_state_equal (GdkColorState *self,
|
|
GdkColorState *other)
|
|
{
|
|
if (self == other)
|
|
return TRUE;
|
|
|
|
if (self->klass != other->klass)
|
|
return FALSE;
|
|
|
|
return self->klass->equal (self, other);
|
|
}
|
|
|
|
/* Note: the functions returned from this expect the source
|
|
* color state to be passed as self
|
|
*/
|
|
static inline GdkFloatColorConvert
|
|
gdk_color_state_get_convert_to (GdkColorState *self,
|
|
GdkColorState *target)
|
|
{
|
|
return self->klass->get_convert_to (self, target);
|
|
}
|
|
|
|
/* Note: the functions returned from this expect the target
|
|
* color state to be passed as self
|
|
*/
|
|
static inline GdkFloatColorConvert
|
|
gdk_color_state_get_convert_from (GdkColorState *self,
|
|
GdkColorState *source)
|
|
{
|
|
return self->klass->get_convert_from (self, source);
|
|
}
|
|
|
|
static inline const GdkCicp *
|
|
gdk_color_state_get_cicp (GdkColorState *self)
|
|
{
|
|
return self->klass->get_cicp (self);
|
|
}
|
|
|
|
static inline void
|
|
gdk_color_state_convert_color (GdkColorState *src_cs,
|
|
const float src[4],
|
|
GdkColorState *dest_cs,
|
|
float dest[4])
|
|
{
|
|
GdkFloatColorConvert convert = NULL;
|
|
GdkFloatColorConvert convert2 = NULL;
|
|
|
|
dest[0] = src[0];
|
|
dest[1] = src[1];
|
|
dest[2] = src[2];
|
|
dest[3] = src[3];
|
|
|
|
if (gdk_color_state_equal (src_cs, dest_cs))
|
|
return;
|
|
|
|
convert = gdk_color_state_get_convert_to (src_cs, dest_cs);
|
|
|
|
if (!convert)
|
|
convert2 = gdk_color_state_get_convert_from (dest_cs, src_cs);
|
|
|
|
if (!convert && !convert2)
|
|
{
|
|
GdkColorState *connection = GDK_COLOR_STATE_REC2100_LINEAR;
|
|
convert = gdk_color_state_get_convert_to (src_cs, connection);
|
|
convert2 = gdk_color_state_get_convert_from (dest_cs, connection);
|
|
}
|
|
|
|
if (convert)
|
|
convert (src_cs, (float(*)[4]) dest, 1);
|
|
|
|
if (convert2)
|
|
convert2 (dest_cs, (float(*)[4]) dest, 1);
|
|
}
|
|
|
|
static inline void
|
|
gdk_color_state_from_rgba (GdkColorState *self,
|
|
const GdkRGBA *rgba,
|
|
float out_color[4])
|
|
{
|
|
gdk_color_state_convert_color (GDK_COLOR_STATE_SRGB,
|
|
(const float *) rgba,
|
|
self,
|
|
out_color);
|
|
}
|
|
|