mirror of https://github.com/GNOME/gimp.git
app, libgimp*: more GeglColor's space invasion.
- New function gimp_cairo_set_source_color() which is meant to replace gimp_cairo_set_source_rgb(a?)() eventually. This new function sets the Cairo source color, using the target monitor's profile of the widget where the Cairo surface is meant to be drawn on. It also uses the color management settings (such as whether a custom profile was set, instead of using system profile, or also simply whether color management was disabled at all). It doesn't soft-proof the color yet. - Padding and out-of-gamut colors drawing now use the new gimp_cairo_set_source_color(). These don't need any soft-proofing anyway. - Out-of-gamut color property in GimpColorConfig is now a GeglColor property.
This commit is contained in:
parent
b06fe36970
commit
559297a5cb
|
@ -1527,7 +1527,7 @@ prefs_dialog_new (Gimp *gimp,
|
|||
_("Mar_k out of gamut colors"));
|
||||
gtk_box_pack_start (GTK_BOX (hbox), button, TRUE, TRUE, 0);
|
||||
|
||||
button = gimp_prop_color_button_new (color_config, "out-of-gamut-color",
|
||||
button = gimp_prop_gegl_color_button_new (color_config, "out-of-gamut-color",
|
||||
_("Select Warning Color"),
|
||||
PREFS_COLOR_BUTTON_WIDTH,
|
||||
PREFS_COLOR_BUTTON_HEIGHT,
|
||||
|
|
|
@ -89,10 +89,13 @@ gimp_display_shell_draw_background (GimpDisplayShell *shell,
|
|||
|
||||
if (canvas->padding_mode != GIMP_CANVAS_PADDING_MODE_DEFAULT)
|
||||
{
|
||||
GimpRGB rgb;
|
||||
GimpColorConfig *config = gimp_display_shell_get_color_config (shell);
|
||||
|
||||
gegl_color_get_pixel (canvas->padding_color, babl_format ("R'G'B'A double"), &rgb);
|
||||
gimp_cairo_set_source_rgb (cr, &rgb);
|
||||
/* Padding color is color-managed to shell's monitor profile but not
|
||||
* soft-proofed.
|
||||
*/
|
||||
gimp_cairo_set_source_color (cr, canvas->padding_color, config, FALSE,
|
||||
GTK_WIDGET (shell));
|
||||
cairo_paint (cr);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -892,7 +892,6 @@ gimp_fg_bg_editor_draw_color_frame (GimpFgBgEditor *editor,
|
|||
gdouble srgb_color[4];
|
||||
gdouble transformed_color[4];
|
||||
gboolean is_out_of_gamut;
|
||||
const Babl *target_space = NULL;
|
||||
|
||||
if (editor->active_image)
|
||||
{
|
||||
|
@ -931,9 +930,8 @@ gimp_fg_bg_editor_draw_color_frame (GimpFgBgEditor *editor,
|
|||
cairo_fill (cr);
|
||||
|
||||
if (editor->active_image)
|
||||
target_space = gimp_image_get_layer_space (editor->active_image);
|
||||
else
|
||||
target_space = babl_space ("sRGB");
|
||||
{
|
||||
const Babl *target_space = gimp_image_get_layer_space (editor->active_image);
|
||||
|
||||
if (base_type == GIMP_GRAY)
|
||||
{
|
||||
|
@ -954,7 +952,7 @@ gimp_fg_bg_editor_draw_color_frame (GimpFgBgEditor *editor,
|
|||
* RGB with non-equal components.
|
||||
*/
|
||||
gegl_color_get_pixel (color,
|
||||
babl_format_with_space ("R'G'B' float", target_space),
|
||||
babl_format_with_space ("R'G'B' double", target_space),
|
||||
rgb);
|
||||
is_out_of_gamut = (ABS (rgb[0] - rgb[0]) > CHANNEL_EPSILON ||
|
||||
ABS (rgb[1] - rgb[1]) > CHANNEL_EPSILON ||
|
||||
|
@ -966,7 +964,7 @@ gimp_fg_bg_editor_draw_color_frame (GimpFgBgEditor *editor,
|
|||
gdouble rgb[3];
|
||||
|
||||
gegl_color_get_pixel (color,
|
||||
babl_format_with_space ("R'G'B' float", target_space),
|
||||
babl_format_with_space ("R'G'B' double", target_space),
|
||||
rgb);
|
||||
/* We make sure that each component is within [0; 1], but accept a small
|
||||
* error of margin (we don't want to show small precision errors as
|
||||
|
@ -979,6 +977,12 @@ gimp_fg_bg_editor_draw_color_frame (GimpFgBgEditor *editor,
|
|||
(rgb[2] < 0.0 && -rgb[2] > CHANNEL_EPSILON) ||
|
||||
(rgb[2] > 1.0 && rgb[2] - 1.0 > CHANNEL_EPSILON));
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Without active image, we are never out of gamut. */
|
||||
is_out_of_gamut = FALSE;
|
||||
}
|
||||
|
||||
if (editor->color_config &&
|
||||
/* Common out-of-gamut case */
|
||||
|
@ -987,20 +991,24 @@ gimp_fg_bg_editor_draw_color_frame (GimpFgBgEditor *editor,
|
|||
(colormap_palette &&
|
||||
! gimp_palette_find_entry (colormap_palette, color, NULL))))
|
||||
{
|
||||
GeglColor *out_of_gamut_color;
|
||||
gint corner_x = x + 0.5 * (1.0 - corner_dx) * width;
|
||||
gint corner_y = y + 0.5 * (1.0 - corner_dy) * height;
|
||||
gint side = MIN (width, height) * 2 / 3;
|
||||
GimpRGB out_of_gamut_color;
|
||||
|
||||
cairo_move_to (cr, corner_x, corner_y);
|
||||
cairo_line_to (cr, corner_x + side * corner_dx, corner_y);
|
||||
cairo_line_to (cr, corner_x, corner_y + side * corner_dy);
|
||||
cairo_close_path (cr);
|
||||
|
||||
gimp_color_config_get_out_of_gamut_color (editor->color_config,
|
||||
&out_of_gamut_color);
|
||||
gimp_cairo_set_source_rgb (cr, &out_of_gamut_color);
|
||||
out_of_gamut_color = gimp_color_config_get_out_of_gamut_color (editor->color_config);
|
||||
/* Out-of-gamut color is color-managed to FG/BG editor's monitor profile
|
||||
* but not soft-proofed.
|
||||
*/
|
||||
gimp_cairo_set_source_color (cr, out_of_gamut_color, editor->color_config, FALSE, GTK_WIDGET (editor));
|
||||
cairo_fill (cr);
|
||||
|
||||
g_object_unref (out_of_gamut_color);
|
||||
}
|
||||
|
||||
cairo_set_line_width (cr, 1.0);
|
||||
|
|
|
@ -160,7 +160,7 @@ struct _GimpColorConfigPrivate
|
|||
gboolean simulation_use_black_point_compensation;
|
||||
gboolean simulation_optimize;
|
||||
gboolean simulation_gamut_check;
|
||||
GimpRGB out_of_gamut_color;
|
||||
GeglColor *out_of_gamut_color;
|
||||
|
||||
gboolean show_rgb_u8;
|
||||
gboolean show_hsv;
|
||||
|
@ -209,9 +209,13 @@ static void
|
|||
gimp_color_config_class_init (GimpColorConfigClass *klass)
|
||||
{
|
||||
GObjectClass *object_class = G_OBJECT_CLASS (klass);
|
||||
GimpRGB color;
|
||||
GeglColor *magenta;
|
||||
|
||||
gimp_rgba_set (&color, 1.0, 0.0, 1.0, 1.0); /* magenta */
|
||||
babl_init ();
|
||||
|
||||
/* Magenta (sRGB space). */
|
||||
magenta = gegl_color_new (NULL);
|
||||
gegl_color_set_rgba (magenta, 1.0, 0.0, 1.0, 1.0);
|
||||
|
||||
object_class->finalize = gimp_color_config_finalize;
|
||||
object_class->set_property = gimp_color_config_set_property;
|
||||
|
@ -318,11 +322,11 @@ gimp_color_config_class_init (GimpColorConfigClass *klass)
|
|||
FALSE,
|
||||
GIMP_PARAM_STATIC_STRINGS);
|
||||
|
||||
GIMP_CONFIG_PROP_RGB (object_class, PROP_OUT_OF_GAMUT_COLOR,
|
||||
GIMP_CONFIG_PROP_COLOR (object_class, PROP_OUT_OF_GAMUT_COLOR,
|
||||
"out-of-gamut-color",
|
||||
_("Out of gamut warning color"),
|
||||
OUT_OF_GAMUT_COLOR_BLURB,
|
||||
FALSE, &color,
|
||||
magenta,
|
||||
GIMP_PARAM_STATIC_STRINGS);
|
||||
|
||||
GIMP_CONFIG_PROP_BOOLEAN (object_class, PROP_SHOW_RGB_U8,
|
||||
|
@ -338,12 +342,20 @@ gimp_color_config_class_init (GimpColorConfigClass *klass)
|
|||
_("Show HSV instead of LCH"),
|
||||
FALSE,
|
||||
GIMP_PARAM_STATIC_STRINGS);
|
||||
|
||||
g_object_unref (magenta);
|
||||
}
|
||||
|
||||
static void
|
||||
gimp_color_config_init (GimpColorConfig *config)
|
||||
{
|
||||
GeglColor *magenta = gegl_color_new (NULL);
|
||||
|
||||
config->priv = gimp_color_config_get_instance_private (config);
|
||||
|
||||
/* Magenta (sRGB space). */
|
||||
gegl_color_set_rgba (magenta, 1.0, 0.0, 1.0, 1.0);
|
||||
config->priv->out_of_gamut_color = magenta;
|
||||
}
|
||||
|
||||
static void
|
||||
|
@ -425,7 +437,8 @@ gimp_color_config_set_property (GObject *object,
|
|||
priv->simulation_gamut_check = g_value_get_boolean (value);
|
||||
break;
|
||||
case PROP_OUT_OF_GAMUT_COLOR:
|
||||
priv->out_of_gamut_color = *(GimpRGB *) g_value_get_boxed (value);
|
||||
g_clear_object (&priv->out_of_gamut_color);
|
||||
priv->out_of_gamut_color = gegl_color_duplicate (g_value_get_object (value));
|
||||
break;
|
||||
case PROP_SHOW_RGB_U8:
|
||||
priv->show_rgb_u8 = g_value_get_boolean (value);
|
||||
|
@ -499,7 +512,7 @@ gimp_color_config_get_property (GObject *object,
|
|||
g_value_set_boolean (value, priv->simulation_gamut_check);
|
||||
break;
|
||||
case PROP_OUT_OF_GAMUT_COLOR:
|
||||
g_value_set_boxed (value, &priv->out_of_gamut_color);
|
||||
g_value_set_object (value, priv->out_of_gamut_color);
|
||||
break;
|
||||
case PROP_SHOW_RGB_U8:
|
||||
g_value_set_boolean (value, priv->show_rgb_u8);
|
||||
|
@ -649,18 +662,17 @@ gimp_color_config_get_simulation_gamut_check (GimpColorConfig *config)
|
|||
/**
|
||||
* gimp_color_config_get_out_of_gamut_color:
|
||||
* @config: a #GimpColorConfig
|
||||
* @color: return location for a #GimpRGB
|
||||
*
|
||||
* Returns: (transfer full): the [class@Gegl.Color] to use to represent
|
||||
* out-of-gamut pixels.
|
||||
* Since: 3.0
|
||||
**/
|
||||
void
|
||||
gimp_color_config_get_out_of_gamut_color (GimpColorConfig *config,
|
||||
GimpRGB *color)
|
||||
GeglColor *
|
||||
gimp_color_config_get_out_of_gamut_color (GimpColorConfig *config)
|
||||
{
|
||||
g_return_if_fail (GIMP_IS_COLOR_CONFIG (config));
|
||||
g_return_if_fail (color != NULL);
|
||||
g_return_val_if_fail (GIMP_IS_COLOR_CONFIG (config), NULL);
|
||||
|
||||
*color = GET_PRIVATE (config)->out_of_gamut_color;
|
||||
return gegl_color_duplicate (GET_PRIVATE (config)->out_of_gamut_color);
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -75,8 +75,7 @@ GimpColorRenderingIntent
|
|||
gboolean gimp_color_config_get_simulation_bpc (GimpColorConfig *config);
|
||||
gboolean gimp_color_config_get_simulation_optimize (GimpColorConfig *config);
|
||||
gboolean gimp_color_config_get_simulation_gamut_check (GimpColorConfig *config);
|
||||
void gimp_color_config_get_out_of_gamut_color (GimpColorConfig *config,
|
||||
GimpRGB *color);
|
||||
GeglColor * gimp_color_config_get_out_of_gamut_color (GimpColorConfig *config);
|
||||
|
||||
GimpColorProfile * gimp_color_config_get_rgb_color_profile (GimpColorConfig *config,
|
||||
GError **error);
|
||||
|
|
|
@ -19,6 +19,8 @@
|
|||
#ifndef __GIMP_CONFIG_H__
|
||||
#define __GIMP_CONFIG_H__
|
||||
|
||||
#include <gegl.h>
|
||||
|
||||
#define __GIMP_CONFIG_H_INSIDE__
|
||||
|
||||
#include <libgimpconfig/gimpconfigtypes.h>
|
||||
|
|
|
@ -28,8 +28,10 @@
|
|||
|
||||
#include "libgimpbase/gimpbase.h"
|
||||
#include "libgimpcolor/gimpcolor.h"
|
||||
#include "libgimpconfig/gimpconfig.h"
|
||||
|
||||
#include "gimpcairo-utils.h"
|
||||
#include "gimpwidgetsutils.h"
|
||||
|
||||
|
||||
/**
|
||||
|
@ -200,3 +202,55 @@ gimp_cairo_surface_create_from_pixbuf (GdkPixbuf *pixbuf)
|
|||
|
||||
return surface;
|
||||
}
|
||||
|
||||
/**
|
||||
* gimp_cairo_set_source_color:
|
||||
* @cr: Cairo context.
|
||||
* @color: the [class@Gegl.Color] to use as source pattern within @cr.
|
||||
* @config: the color management settings.
|
||||
* @softproof: whether the color must also be soft-proofed.
|
||||
* @widget: (nullable): [class@Gtk.Widget] to draw the focus indicator on.
|
||||
*
|
||||
* Sets @color as the source pattern within @cr, taking into account the profile
|
||||
* of the [class@Gdk.Monitor] which @widget is displayed on.
|
||||
*
|
||||
* If @config is set, the color configuration as set by the user will be used,
|
||||
* in particular using any custom monitor profile set in preferences (overriding
|
||||
* system-set profile). If no such custom profile is set, it will use the
|
||||
* profile of the monitor @widget is displayed on and will default to sRGB if
|
||||
* @widget is %NULL.
|
||||
*
|
||||
* Use [func@Gimp.get_color_configuration] to retrieve the user
|
||||
* [class@Gimp.ColorConfig].
|
||||
*
|
||||
* TODO: @softproof is currently unused.
|
||||
*
|
||||
* Since: 3.0
|
||||
**/
|
||||
void
|
||||
gimp_cairo_set_source_color (cairo_t *cr,
|
||||
GeglColor *color,
|
||||
GimpColorConfig *config,
|
||||
gboolean softproof,
|
||||
GtkWidget *widget)
|
||||
{
|
||||
GimpColorProfile *proof_profile = NULL;
|
||||
GimpColorProfile *dest_profile = NULL;
|
||||
const Babl *space = NULL;
|
||||
gdouble rgba[4];
|
||||
|
||||
g_return_if_fail (GEGL_IS_COLOR (color));
|
||||
g_return_if_fail (widget == NULL || GTK_IS_WIDGET (widget));
|
||||
|
||||
_gimp_widget_get_profiles (widget, config,
|
||||
softproof ? &proof_profile : NULL,
|
||||
&dest_profile);
|
||||
|
||||
if (dest_profile)
|
||||
space = gimp_color_profile_get_space (dest_profile,
|
||||
GIMP_COLOR_RENDERING_INTENT_RELATIVE_COLORIMETRIC,
|
||||
NULL);
|
||||
gegl_color_get_pixel (color, babl_format_with_space ("R'G'B'A double", space), rgba);
|
||||
|
||||
cairo_set_source_rgba (cr, rgba[0], rgba[1], rgba[2], rgba[3]);
|
||||
}
|
||||
|
|
|
@ -32,5 +32,11 @@ gboolean gimp_cairo_set_focus_line_pattern (cairo_t *cr,
|
|||
|
||||
cairo_surface_t * gimp_cairo_surface_create_from_pixbuf (GdkPixbuf *pixbuf);
|
||||
|
||||
void gimp_cairo_set_source_color (cairo_t *cr,
|
||||
GeglColor *color,
|
||||
GimpColorConfig *config,
|
||||
gboolean softproof,
|
||||
GtkWidget *widget);
|
||||
|
||||
|
||||
#endif /* __GIMP_CAIRO_UTILS_H__ */
|
||||
|
|
|
@ -464,7 +464,7 @@ gimp_color_area_draw (GtkWidget *widget,
|
|||
priv->color.b < 0.0 || priv->color.b > 1.0) ||
|
||||
priv->out_of_gamut))
|
||||
{
|
||||
GimpRGB color;
|
||||
GeglColor *oog_color;
|
||||
gint side = MIN (priv->width, priv->height) * 2 / 3;
|
||||
|
||||
cairo_move_to (cr, priv->width, 0);
|
||||
|
@ -472,10 +472,12 @@ gimp_color_area_draw (GtkWidget *widget,
|
|||
cairo_line_to (cr, priv->width, side);
|
||||
cairo_line_to (cr, priv->width, 0);
|
||||
|
||||
gimp_color_config_get_out_of_gamut_color (priv->config, &color);
|
||||
gimp_cairo_set_source_rgb (cr, &color);
|
||||
oog_color = gimp_color_config_get_out_of_gamut_color (priv->config);
|
||||
gimp_cairo_set_source_color (cr, oog_color, priv->config, FALSE, widget);
|
||||
|
||||
cairo_fill (cr);
|
||||
|
||||
g_object_unref (oog_color);
|
||||
}
|
||||
|
||||
if (priv->draw_border)
|
||||
|
|
|
@ -969,14 +969,16 @@ gimp_color_scale_notify_config (GimpColorConfig *config,
|
|||
GimpColorScale *scale)
|
||||
{
|
||||
GimpColorScalePrivate *priv = GET_PRIVATE (scale);
|
||||
GimpRGB color;
|
||||
GeglColor *color;
|
||||
|
||||
gimp_color_scale_destroy_transform (scale);
|
||||
|
||||
gimp_color_config_get_out_of_gamut_color (config, &color);
|
||||
gimp_rgb_get_uchar (&color,
|
||||
priv->oog_color,
|
||||
priv->oog_color + 1,
|
||||
priv->oog_color + 2);
|
||||
color = gimp_color_config_get_out_of_gamut_color (config);
|
||||
/* TODO: shouldn't this be color-managed too, using the target space into
|
||||
* consideration?
|
||||
*/
|
||||
gegl_color_get_pixel (color, babl_format ("R'G'B' u8"), priv->oog_color);
|
||||
priv->needs_render = TRUE;
|
||||
|
||||
g_object_unref (color);
|
||||
}
|
||||
|
|
|
@ -1981,15 +1981,17 @@ gimp_color_select_notify_config (GimpColorConfig *config,
|
|||
const GParamSpec *pspec,
|
||||
GimpColorSelect *select)
|
||||
{
|
||||
GimpRGB color;
|
||||
GeglColor *color;
|
||||
|
||||
gimp_color_select_destroy_transform (select);
|
||||
|
||||
gimp_color_config_get_out_of_gamut_color (config, &color);
|
||||
gimp_rgb_get_uchar (&color,
|
||||
select->oog_color,
|
||||
select->oog_color + 1,
|
||||
select->oog_color + 2);
|
||||
color = gimp_color_config_get_out_of_gamut_color (config);
|
||||
/* TODO: shouldn't this be color-managed too, using the target space into
|
||||
* consideration?
|
||||
*/
|
||||
gegl_color_get_pixel (color, babl_format ("R'G'B' u8"), select->oog_color);
|
||||
select->xy_needs_render = TRUE;
|
||||
select->z_needs_render = TRUE;
|
||||
|
||||
g_object_unref (color);
|
||||
}
|
||||
|
|
|
@ -16,6 +16,7 @@ EXPORTS
|
|||
gimp_button_get_type
|
||||
gimp_button_new
|
||||
gimp_cairo_set_focus_line_pattern
|
||||
gimp_cairo_set_source_color
|
||||
gimp_cairo_surface_create_from_pixbuf
|
||||
gimp_cell_renderer_color_get_type
|
||||
gimp_cell_renderer_color_new
|
||||
|
|
|
@ -1005,20 +1005,19 @@ gimp_widget_get_color_transform (GtkWidget *widget,
|
|||
|
||||
if (gimp_color_config_get_simulation_gamut_check (config))
|
||||
{
|
||||
GimpRGB color;
|
||||
GeglColor *color;
|
||||
cmsUInt16Number alarmCodes[cmsMAXCHANNELS] = { 0, };
|
||||
guchar r, g, b;
|
||||
|
||||
flags |= GIMP_COLOR_TRANSFORM_FLAGS_GAMUT_CHECK;
|
||||
|
||||
gimp_color_config_get_out_of_gamut_color (config, &color);
|
||||
gimp_rgb_get_uchar (&color, &r, &g, &b);
|
||||
|
||||
alarmCodes[0] = (cmsUInt16Number) r * 256;
|
||||
alarmCodes[1] = (cmsUInt16Number) g * 256;
|
||||
alarmCodes[2] = (cmsUInt16Number) b * 256;
|
||||
|
||||
color = gimp_color_config_get_out_of_gamut_color (config);
|
||||
/* Little-CMS documentation doesn't say which space should the
|
||||
* out-of-gamut color be. Let's just give sRGB data.
|
||||
*/
|
||||
gegl_color_get_pixel (color, babl_format ("R'G'B' u16"), alarmCodes);
|
||||
cmsSetAlarmCodes (alarmCodes);
|
||||
|
||||
g_object_unref (color);
|
||||
}
|
||||
|
||||
cache->transform =
|
||||
|
@ -1107,6 +1106,35 @@ gimp_widget_set_native_handle (GtkWidget *widget,
|
|||
}
|
||||
|
||||
|
||||
/* Internal functions */
|
||||
|
||||
void
|
||||
_gimp_widget_get_profiles (GtkWidget *widget,
|
||||
GimpColorConfig *config,
|
||||
GimpColorProfile **proof_profile,
|
||||
GimpColorProfile **dest_profile)
|
||||
{
|
||||
g_return_if_fail (dest_profile != NULL && *dest_profile == NULL);
|
||||
g_return_if_fail (proof_profile == NULL || *proof_profile == NULL);
|
||||
|
||||
switch (gimp_color_config_get_mode (config))
|
||||
{
|
||||
case GIMP_COLOR_MANAGEMENT_OFF:
|
||||
return;
|
||||
|
||||
case GIMP_COLOR_MANAGEMENT_SOFTPROOF:
|
||||
if (proof_profile)
|
||||
*proof_profile = gimp_color_config_get_simulation_color_profile (config, NULL);
|
||||
|
||||
/* fallthru */
|
||||
|
||||
case GIMP_COLOR_MANAGEMENT_DISPLAY:
|
||||
*dest_profile = get_display_profile (widget, config);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/* Private functions */
|
||||
|
||||
#ifdef GDK_WINDOWING_WAYLAND
|
||||
|
|
|
@ -68,6 +68,15 @@ GimpColorTransform * gimp_widget_get_color_transform (GtkWidget *widget,
|
|||
void gimp_widget_set_native_handle (GtkWidget *widget,
|
||||
GBytes **handle);
|
||||
|
||||
|
||||
/* Internal use */
|
||||
|
||||
G_GNUC_INTERNAL void _gimp_widget_get_profiles (GtkWidget *widget,
|
||||
GimpColorConfig *config,
|
||||
GimpColorProfile **proof_profile,
|
||||
GimpColorProfile **dest_profile);
|
||||
|
||||
|
||||
G_END_DECLS
|
||||
|
||||
#endif /* __GIMP_WIDGETS_UTILS_H__ */
|
||||
|
|
Loading…
Reference in New Issue