diff --git a/app/core/gimpimage-color-profile.c b/app/core/gimpimage-color-profile.c
index bcf8f2d604..56deec69f0 100644
--- a/app/core/gimpimage-color-profile.c
+++ b/app/core/gimpimage-color-profile.c
@@ -815,20 +815,6 @@ gimp_image_get_color_transform_to_srgb_u8 (GimpImage *image)
return private->transform_to_srgb_u8;
}
-GimpColorTransform *
-gimp_image_get_color_transform_from_srgb_u8 (GimpImage *image)
-{
- GimpImagePrivate *private;
-
- g_return_val_if_fail (GIMP_IS_IMAGE (image), NULL);
-
- private = GIMP_IMAGE_GET_PRIVATE (image);
-
- gimp_image_create_color_transforms (image);
-
- return private->transform_from_srgb_u8;
-}
-
GimpColorTransform *
gimp_image_get_color_transform_to_srgb_double (GimpImage *image)
{
@@ -938,7 +924,6 @@ _gimp_image_free_color_transforms (GimpImage *image)
GimpImagePrivate *private = GIMP_IMAGE_GET_PRIVATE (image);
g_clear_object (&private->transform_to_srgb_u8);
- g_clear_object (&private->transform_from_srgb_u8);
g_clear_object (&private->transform_to_srgb_double);
g_clear_object (&private->transform_from_srgb_double);
@@ -1162,14 +1147,6 @@ gimp_image_create_color_transforms (GimpImage *image)
GIMP_COLOR_RENDERING_INTENT_PERCEPTUAL,
flags);
- private->transform_from_srgb_u8 =
- gimp_color_transform_new (srgb_profile,
- babl_format ("R'G'B'A u8"),
- private->color_profile,
- gimp_image_get_layer_format (image, TRUE),
- GIMP_COLOR_RENDERING_INTENT_PERCEPTUAL,
- flags);
-
private->transform_to_srgb_double =
gimp_color_transform_new (private->color_profile,
gimp_image_get_layer_format (image, TRUE),
diff --git a/app/core/gimpimage-color-profile.h b/app/core/gimpimage-color-profile.h
index 607b9af531..1ad617217c 100644
--- a/app/core/gimpimage-color-profile.h
+++ b/app/core/gimpimage-color-profile.h
@@ -110,8 +110,6 @@ void gimp_image_import_color_profile (GimpImage *ima
GimpColorTransform * gimp_image_get_color_transform_to_srgb_u8
(GimpImage *image);
-GimpColorTransform * gimp_image_get_color_transform_from_srgb_u8
- (GimpImage *image);
GimpColorTransform * gimp_image_get_color_transform_to_srgb_double
(GimpImage *image);
diff --git a/app/core/gimpimage-private.h b/app/core/gimpimage-private.h
index b2f3d9448c..187d95ae5e 100644
--- a/app/core/gimpimage-private.h
+++ b/app/core/gimpimage-private.h
@@ -74,7 +74,6 @@ struct _GimpImagePrivate
/* Cached color transforms: from layer to sRGB u8 and double, and back */
gboolean color_transforms_created;
GimpColorTransform *transform_to_srgb_u8;
- GimpColorTransform *transform_from_srgb_u8;
GimpColorTransform *transform_to_srgb_double;
GimpColorTransform *transform_from_srgb_double;
diff --git a/app/display/gimpdisplayshell-dnd.c b/app/display/gimpdisplayshell-dnd.c
index 89663fa717..d7aad98815 100644
--- a/app/display/gimpdisplayshell-dnd.c
+++ b/app/display/gimpdisplayshell-dnd.c
@@ -389,17 +389,14 @@ gimp_display_shell_dnd_fill (GimpDisplayShell *shell,
gimp_fill_options_get_style (options) == GIMP_FILL_STYLE_BG_COLOR))
{
GeglColor *color;
- GimpRGB rgb;
if (gimp_fill_options_get_style (options) == GIMP_FILL_STYLE_FG_COLOR)
color = gimp_context_get_foreground (GIMP_CONTEXT (options));
else
color = gimp_context_get_background (GIMP_CONTEXT (options));
- gegl_color_get_rgba_with_space (color, &rgb.r, &rgb.g, &rgb.b, &rgb.a, NULL);
-
gimp_text_layer_set (iter->data, NULL,
- "color", &rgb,
+ "color", color,
NULL);
}
else
diff --git a/app/pdb/text-layer-cmds.c b/app/pdb/text-layer-cmds.c
index fef0f974c1..9da53abd3d 100644
--- a/app/pdb/text-layer-cmds.c
+++ b/app/pdb/text-layer-cmds.c
@@ -734,20 +734,20 @@ text_layer_get_color_invoker (GimpProcedure *procedure,
gboolean success = TRUE;
GimpValueArray *return_vals;
GimpTextLayer *layer;
- GimpRGB color = { 0.0, 0.0, 0.0, 1.0 };
+ GeglColor *color = NULL;
layer = g_value_get_object (gimp_value_array_index (args, 0));
if (success)
{
- color = gimp_text_layer_get_text (layer)->color;
+ color = gegl_color_duplicate (gimp_text_layer_get_text (layer)->color);
}
return_vals = gimp_procedure_get_return_values (procedure, success,
error ? *error : NULL);
if (success)
- gimp_value_set_rgb (gimp_value_array_index (return_vals, 1), &color);
+ g_value_take_object (gimp_value_array_index (return_vals, 1), color);
return return_vals;
}
@@ -1685,12 +1685,11 @@ register_text_layer_procs (GimpPDB *pdb)
FALSE,
GIMP_PARAM_READWRITE));
gimp_procedure_add_return_value (procedure,
- gimp_param_spec_rgb ("color",
- "color",
- "The color of the text.",
- FALSE,
- NULL,
- GIMP_PARAM_READWRITE));
+ gegl_param_spec_color ("color",
+ "color",
+ "The color of the text.",
+ NULL,
+ GIMP_PARAM_READWRITE));
gimp_pdb_register_procedure (pdb, procedure);
g_object_unref (procedure);
diff --git a/app/text/gimptext-vectors.c b/app/text/gimptext-vectors.c
index 3a6901e9da..b6414cb507 100644
--- a/app/text/gimptext-vectors.c
+++ b/app/text/gimptext-vectors.c
@@ -82,7 +82,7 @@ gimp_text_vectors_new (GimpImage *image,
gimp_image_get_resolution (image, &xres, &yres);
- layout = gimp_text_layout_new (text, xres, yres, &error);
+ layout = gimp_text_layout_new (text, image, xres, yres, &error);
if (error)
{
gimp_message_literal (image->gimp, NULL, GIMP_MESSAGE_ERROR, error->message);
diff --git a/app/text/gimptext.c b/app/text/gimptext.c
index 7e72fecbd6..e4d607e4a9 100644
--- a/app/text/gimptext.c
+++ b/app/text/gimptext.c
@@ -141,8 +141,8 @@ gimp_text_class_init (GimpTextClass *klass)
{
GObjectClass *object_class = G_OBJECT_CLASS (klass);
GimpObjectClass *gimp_object_class = GIMP_OBJECT_CLASS (klass);
- GimpRGB black;
- GimpRGB gray;
+ GeglColor *black = gegl_color_new ("black");
+ GeglColor *gray = gegl_color_new ("gray");
GimpMatrix2 identity;
gchar *language;
GParamSpec *array_spec;
@@ -162,8 +162,6 @@ gimp_text_class_init (GimpTextClass *klass)
gimp_object_class->get_memsize = gimp_text_get_memsize;
- gimp_rgba_set (&black, 0.0, 0.0, 0.0, GIMP_OPACITY_OPAQUE);
- gimp_rgba_set (&gray, 0.75, 0.75, 0.75, GIMP_OPACITY_OPAQUE);
gimp_matrix2_identity (&identity);
GIMP_CONFIG_PROP_STRING (object_class, PROP_TEXT,
@@ -235,11 +233,11 @@ gimp_text_class_init (GimpTextClass *klass)
GIMP_TEXT_DIRECTION_LTR,
GIMP_PARAM_STATIC_STRINGS);
- GIMP_CONFIG_PROP_RGB (object_class, PROP_COLOR,
- "color",
- NULL, NULL,
- FALSE, &black,
- GIMP_PARAM_STATIC_STRINGS);
+ GIMP_CONFIG_PROP_COLOR (object_class, PROP_COLOR,
+ "color",
+ NULL, NULL,
+ black,
+ GIMP_PARAM_STATIC_STRINGS);
GIMP_CONFIG_PROP_ENUM (object_class, PROP_OUTLINE,
"outline",
@@ -341,10 +339,10 @@ gimp_text_class_init (GimpTextClass *klass)
"outline-pattern", NULL, NULL,
GIMP_TYPE_PATTERN,
GIMP_PARAM_STATIC_STRINGS);
- GIMP_CONFIG_PROP_RGB (object_class, PROP_OUTLINE_FOREGROUND,
- "outline-foreground", NULL, NULL,
- FALSE, &gray,
- GIMP_PARAM_STATIC_STRINGS);
+ GIMP_CONFIG_PROP_COLOR (object_class, PROP_OUTLINE_FOREGROUND,
+ "outline-foreground", NULL, NULL,
+ gray,
+ GIMP_PARAM_STATIC_STRINGS);
GIMP_CONFIG_PROP_DOUBLE (object_class, PROP_OUTLINE_WIDTH,
"outline-width", NULL, NULL,
0.0, 8192.0, 4.0,
@@ -394,6 +392,8 @@ gimp_text_class_init (GimpTextClass *klass)
GIMP_PARAM_READWRITE |
G_PARAM_CONSTRUCT_ONLY));
+ g_object_unref (black);
+ g_object_unref (gray);
}
static void
@@ -417,6 +417,8 @@ gimp_text_finalize (GObject *object)
g_clear_pointer (&text->markup, g_free);
g_clear_pointer (&text->language, g_free);
g_clear_object (&text->font);
+ g_clear_object (&text->color);
+ g_clear_object (&text->outline_foreground);
G_OBJECT_CLASS (parent_class)->finalize (object);
}
@@ -462,7 +464,7 @@ gimp_text_get_property (GObject *object,
g_value_set_string (value, text->language);
break;
case PROP_COLOR:
- g_value_set_boxed (value, &text->color);
+ g_value_set_object (value, text->color);
break;
case PROP_OUTLINE:
g_value_set_enum (value, text->outline);
@@ -504,7 +506,7 @@ gimp_text_get_property (GObject *object,
g_value_set_enum (value, text->outline_style);
break;
case PROP_OUTLINE_FOREGROUND:
- g_value_set_boxed (value, &text->outline_foreground);
+ g_value_set_object (value, text->outline_foreground);
break;
case PROP_OUTLINE_PATTERN:
g_value_set_object (value, text->outline_pattern);
@@ -555,7 +557,6 @@ gimp_text_set_property (GObject *object,
GParamSpec *pspec)
{
GimpText *text = GIMP_TEXT (object);
- GimpRGB *color;
GimpMatrix2 *matrix;
switch (property_id)
@@ -609,8 +610,7 @@ gimp_text_set_property (GObject *object,
text->base_dir = g_value_get_enum (value);
break;
case PROP_COLOR:
- color = g_value_get_boxed (value);
- text->color = *color;
+ g_set_object (&text->color, g_value_get_object (value));;
break;
case PROP_OUTLINE:
text->outline = g_value_get_enum (value);
@@ -653,8 +653,7 @@ gimp_text_set_property (GObject *object,
text->outline_style = g_value_get_enum (value);
break;
case PROP_OUTLINE_FOREGROUND:
- color = g_value_get_boxed (value);
- text->outline_foreground = *color;
+ g_set_object (&text->outline_foreground, g_value_get_object (value));;
break;
case PROP_OUTLINE_PATTERN:
{
diff --git a/app/text/gimptext.h b/app/text/gimptext.h
index 6b6434edd1..c013a949a0 100644
--- a/app/text/gimptext.h
+++ b/app/text/gimptext.h
@@ -49,10 +49,10 @@ struct _GimpText
gboolean kerning;
gchar *language;
GimpTextDirection base_dir;
- GimpRGB color;
+ GeglColor *color;
GimpCustomStyle outline_style;
GimpPattern *outline_pattern;
- GimpRGB outline_foreground;
+ GeglColor *outline_foreground;
gdouble outline_width;
GimpCapStyle outline_cap_style;
GimpJoinStyle outline_join_style;
diff --git a/app/text/gimptextlayer.c b/app/text/gimptextlayer.c
index a5d728f0df..82af355a31 100644
--- a/app/text/gimptextlayer.c
+++ b/app/text/gimptextlayer.c
@@ -53,7 +53,6 @@
#include "gimptext.h"
#include "gimptextlayer.h"
-#include "gimptextlayer-transform.h"
#include "gimptextlayout.h"
#include "gimptextlayout-render.h"
@@ -725,7 +724,7 @@ gimp_text_layer_render (GimpTextLayer *layer)
gimp_image_get_resolution (image, &xres, &yres);
- layout = gimp_text_layout_new (layer->text, xres, yres, &error);
+ layout = gimp_text_layout_new (layer->text, image, xres, yres, &error);
if (error)
{
gimp_message_literal (image->gimp, NULL, GIMP_MESSAGE_ERROR, error->message);
@@ -927,9 +926,8 @@ gimp_text_layer_render_layout (GimpTextLayer *layer,
{
GimpDrawable *drawable = GIMP_DRAWABLE (layer);
GimpItem *item = GIMP_ITEM (layer);
- GimpImage *image = gimp_item_get_image (item);
+ const Babl *format;
GeglBuffer *buffer;
- GimpColorTransform *transform;
cairo_t *cr;
cairo_surface_t *surface;
gint width;
@@ -941,7 +939,11 @@ gimp_text_layer_render_layout (GimpTextLayer *layer,
width = gimp_item_get_width (item);
height = gimp_item_get_height (item);
+#if CAIRO_VERSION >= CAIRO_VERSION_ENCODE(1, 17, 2)
+ surface = cairo_image_surface_create (CAIRO_FORMAT_RGBA128F, width, height);
+#else
surface = cairo_image_surface_create (CAIRO_FORMAT_ARGB32, width, height);
+#endif
status = cairo_surface_status (surface);
if (status != CAIRO_STATUS_SUCCESS)
@@ -968,7 +970,6 @@ gimp_text_layer_render_layout (GimpTextLayer *layer,
if (layer->text->outline != GIMP_TEXT_OUTLINE_NONE)
{
GimpText *text = layer->text;
- GimpRGB col = text->outline_foreground;
cairo_save (cr);
@@ -998,7 +999,16 @@ gimp_text_layer_render_layout (GimpTextLayer *layer,
}
else
{
- cairo_set_source_rgba (cr, col.r, col.g, col.b, col.a);
+ GeglColor *col = text->outline_foreground;
+ gdouble color[3];
+
+ format = gimp_text_layout_get_format (layout, "double");
+ gegl_color_get_pixel (col, format, color);
+ /* Text layout can be either grayscale or RGB without alpha. */
+ if (! babl_space_is_gray (babl_format_get_space (format)))
+ cairo_set_source_rgba (cr, color[0], color[1], color[2], 1.0);
+ else
+ cairo_set_source_rgba (cr, color[0], color[0], color[0], 1.0);
}
cairo_set_line_width (cr, text->outline_width * 2);
@@ -1014,23 +1024,29 @@ gimp_text_layer_render_layout (GimpTextLayer *layer,
cairo_surface_flush (surface);
- buffer = gimp_cairo_surface_create_buffer (surface);
-
- transform = gimp_image_get_color_transform_from_srgb_u8 (image);
-
- if (transform)
+#if CAIRO_VERSION >= CAIRO_VERSION_ENCODE(1, 17, 2)
+ /* The CAIRO_FORMAT_RGBA128F surface maps to the layout TRC and space. */
+ switch (gimp_text_layout_get_trc (layout))
{
- gimp_color_transform_process_buffer (transform,
- buffer,
- NULL,
- gimp_drawable_get_buffer (drawable),
- NULL);
- }
- else
- {
- gimp_gegl_buffer_copy (buffer, NULL, GEGL_ABYSS_NONE,
- gimp_drawable_get_buffer (drawable), NULL);
+ case GIMP_TRC_LINEAR:
+ format = babl_format_with_space ("RGBA float", gimp_text_layout_get_space (layout));
+ break;
+ case GIMP_TRC_NON_LINEAR:
+ format = babl_format_with_space ("R'G'B'A float", gimp_text_layout_get_space (layout));
+ break;
+ case GIMP_TRC_PERCEPTUAL:
+ format = babl_format_with_space ("R~G~B~A float", gimp_text_layout_get_space (layout));
+ break;
+ default:
+ g_return_if_reached ();
}
+#else
+ format = babl_format_with_space ("cairo-ARGB32", gimp_text_layout_get_space (layout));
+#endif
+ buffer = gimp_cairo_surface_create_buffer (surface, format);
+
+ gimp_gegl_buffer_copy (buffer, NULL, GEGL_ABYSS_NONE,
+ gimp_drawable_get_buffer (drawable), NULL);
g_object_unref (buffer);
cairo_surface_destroy (surface);
diff --git a/app/text/gimptextlayout.c b/app/text/gimptextlayout.c
index 50cd670d8d..7869e38327 100644
--- a/app/text/gimptextlayout.c
+++ b/app/text/gimptextlayout.c
@@ -32,7 +32,10 @@
#include "text-types.h"
+#include "gegl/gimp-babl.h"
+
#include "core/gimperror.h"
+#include "core/gimpimage.h"
#include "gimpfont.h"
@@ -50,6 +53,8 @@ struct _GimpTextLayout
gdouble yres;
PangoLayout *layout;
PangoRectangle extents;
+ const Babl *layout_space;
+ GimpTRCType layout_trc;
};
@@ -105,18 +110,21 @@ gimp_text_layout_finalize (GObject *object)
GimpTextLayout *
-gimp_text_layout_new (GimpText *text,
- gdouble xres,
- gdouble yres,
- GError **error)
+gimp_text_layout_new (GimpText *text,
+ GimpImage *target_image,
+ gdouble xres,
+ gdouble yres,
+ GError **error)
{
GimpTextLayout *layout;
+ const Babl *target_space;
PangoContext *context;
PangoFontDescription *font_desc;
PangoAlignment alignment = PANGO_ALIGN_LEFT;
gint size;
g_return_val_if_fail (GIMP_IS_TEXT (text), NULL);
+ g_return_val_if_fail (GIMP_IS_IMAGE (target_image), NULL);
font_desc = pango_font_description_from_string (gimp_font_get_lookup_name (text->font));
g_return_val_if_fail (font_desc != NULL, NULL);
@@ -141,6 +149,25 @@ gimp_text_layout_new (GimpText *text,
pango_layout_set_font_description (layout->layout, font_desc);
pango_font_description_free (font_desc);
+ target_space = gimp_image_get_layer_space (target_image);
+#if BABL_MINOR_VERSION > 1 || (BABL_MINOR_VERSION == 1 && BABL_MICRO_VERSION >= 107)
+ if (babl_space_is_rgb (target_space) || babl_space_is_gray (target_space))
+#else
+ if (! babl_space_is_cmyk (target_space))
+#endif
+ layout->layout_space = target_space;
+ else
+ layout->layout_space = NULL;
+
+#if CAIRO_VERSION >= CAIRO_VERSION_ENCODE(1, 17, 2)
+ layout->layout_trc = gimp_babl_trc (gimp_image_get_precision (target_image));
+#else
+ /* With older Cairo, we just use cairo-ARGB32 with no linear or perceptual
+ * option.
+ */
+ layout->layout_trc = GIMP_TRC_NON_LINEAR;
+#endif
+
gimp_text_layout_set_markup (layout, error);
switch (text->justify)
@@ -221,6 +248,72 @@ gimp_text_layout_new (GimpText *text,
return layout;
}
+const GimpTRCType
+gimp_text_layout_get_trc (GimpTextLayout *layout)
+{
+ g_return_val_if_fail (GIMP_IS_TEXT_LAYOUT (layout), GIMP_TRC_NON_LINEAR);
+
+ return layout->layout_trc;
+}
+
+const Babl *
+gimp_text_layout_get_format (GimpTextLayout *layout,
+ const gchar *babl_type)
+{
+ const Babl *format;
+ gchar *format_name;
+
+ g_return_val_if_fail (GIMP_IS_TEXT_LAYOUT (layout), NULL);
+
+ if (! babl_space_is_gray (layout->layout_space))
+ {
+ switch (layout->layout_trc)
+ {
+ case GIMP_TRC_LINEAR:
+ format_name = g_strdup_printf ("RGB %s", babl_type);
+ break;
+ case GIMP_TRC_NON_LINEAR:
+ format_name = g_strdup_printf ("R'G'B' %s", babl_type);
+ break;
+ case GIMP_TRC_PERCEPTUAL:
+ format_name = g_strdup_printf ("R~G~B~ %s", babl_type);
+ break;
+ default:
+ g_return_val_if_reached (NULL);
+ }
+ }
+ else
+ {
+ switch (layout->layout_trc)
+ {
+ case GIMP_TRC_LINEAR:
+ format_name = g_strdup_printf ("Y %s", babl_type);
+ break;
+ case GIMP_TRC_NON_LINEAR:
+ format_name = g_strdup_printf ("Y' %s", babl_type);
+ break;
+ case GIMP_TRC_PERCEPTUAL:
+ format_name = g_strdup_printf ("Y~ %s", babl_type);
+ break;
+ default:
+ g_return_val_if_reached (NULL);
+ }
+ }
+
+ format = babl_format_with_space (format_name, layout->layout_space);
+ g_free (format_name);
+
+ return format;
+}
+
+const Babl *
+gimp_text_layout_get_space (GimpTextLayout *layout)
+{
+ g_return_val_if_fail (GIMP_IS_TEXT_LAYOUT (layout), NULL);
+
+ return layout->layout_space;
+}
+
gboolean
gimp_text_layout_get_size (GimpTextLayout *layout,
gint *width,
@@ -499,17 +592,31 @@ static gchar *
gimp_text_layout_apply_tags (GimpTextLayout *layout,
const gchar *markup)
{
- GimpText *text = layout->text;
- gchar *result;
-
- {
- guchar r, g, b;
-
- gimp_rgb_get_uchar (&text->color, &r, &g, &b);
+ const Babl *format;
+ GimpText *text = layout->text;
+ gchar *result;
+ guchar color[3];
+ /* Unfortunately Pango markup are very limited, color-wise. Colors are
+ * written in hexadecimal, so they are u8 as maximum precision, and
+ * unbounded colors are not accessible.
+ * At the very least, what we do is to write color values in the target
+ * space in the PangoLayout, so that we don't end up stuck to sRGB text
+ * colors even in images with wider gamut spaces.
+ *
+ * Moreover this is limited to RGB and Grayscale spaces. Therefore, images
+ * with other backends will be limited to the sRGB gamut, for as long as Pango
+ * do not evolve (or unless we changed our rendering backend).
+ */
+ format = gimp_text_layout_get_format (layout, "u8");
+ gegl_color_get_pixel (text->color, format, color);
+ if (! babl_space_is_gray (babl_format_get_space (format)))
result = g_strdup_printf ("%s",
- r, g, b, markup);
- }
+ color[0], color[1], color[2], markup);
+ else
+ result = g_strdup_printf ("%s",
+ color[0], color[0], color[0], markup);
+
/* Updating font 'locl' (if supported) with 'lang' feature tag */
if (text->language)
{
@@ -598,7 +705,9 @@ gimp_text_layout_set_markup (GimpTextLayout *layout,
}
}
else
- pango_layout_set_markup (layout->layout, markup, -1);
+ {
+ pango_layout_set_markup (layout->layout, markup, -1);
+ }
g_free (markup);
}
diff --git a/app/text/gimptextlayout.h b/app/text/gimptextlayout.h
index 042751b21d..ed7fd89ed8 100644
--- a/app/text/gimptextlayout.h
+++ b/app/text/gimptextlayout.h
@@ -38,9 +38,16 @@ struct _GimpTextLayoutClass
GType gimp_text_layout_get_type (void) G_GNUC_CONST;
GimpTextLayout * gimp_text_layout_new (GimpText *text,
+ GimpImage *target_image,
gdouble xres,
gdouble yres,
GError **error);
+
+const Babl * gimp_text_layout_get_space (GimpTextLayout *layout);
+const GimpTRCType gimp_text_layout_get_trc (GimpTextLayout *layout);
+const Babl * gimp_text_layout_get_format (GimpTextLayout *layout,
+ const gchar *babl_type);
+
gboolean gimp_text_layout_get_size (GimpTextLayout *layout,
gint *width,
gint *height);
diff --git a/app/tools/gimptextoptions.c b/app/tools/gimptextoptions.c
index 15879b7f92..4ca43a6747 100644
--- a/app/tools/gimptextoptions.c
+++ b/app/tools/gimptextoptions.c
@@ -152,10 +152,9 @@ static void
gimp_text_options_class_init (GimpTextOptionsClass *klass)
{
GObjectClass *object_class = G_OBJECT_CLASS (klass);
- GimpRGB gray;
+ GeglColor *gray = gegl_color_new ("gray");
GParamSpec *array_spec;
- gimp_rgba_set (&gray, 0.75, 0.75, 0.75, GIMP_OPACITY_OPAQUE);
object_class->finalize = gimp_text_options_finalize;
object_class->set_property = gimp_text_options_set_property;
object_class->get_property = gimp_text_options_get_property;
@@ -286,11 +285,11 @@ gimp_text_options_class_init (GimpTextOptionsClass *klass)
GIMP_TYPE_CUSTOM_STYLE,
GIMP_CUSTOM_STYLE_SOLID_COLOR,
GIMP_PARAM_STATIC_STRINGS);
- GIMP_CONFIG_PROP_RGB (object_class, PROP_OUTLINE_FOREGROUND,
- "outline-foreground",
- NULL, NULL,
- FALSE, &gray,
- GIMP_PARAM_STATIC_STRINGS);
+ GIMP_CONFIG_PROP_COLOR (object_class, PROP_OUTLINE_FOREGROUND,
+ "outline-foreground",
+ NULL, NULL,
+ gray,
+ GIMP_PARAM_STATIC_STRINGS);
GIMP_CONFIG_PROP_OBJECT (object_class, PROP_OUTLINE_PATTERN,
"outline-pattern",
NULL, NULL,
@@ -349,6 +348,8 @@ gimp_text_options_class_init (GimpTextOptionsClass *klass)
array_spec,
GIMP_PARAM_STATIC_STRINGS |
GIMP_CONFIG_PARAM_FLAGS));
+
+ g_object_unref (gray);
}
static void
@@ -365,7 +366,10 @@ gimp_text_options_config_iface_init (GimpConfigInterface *config_iface)
static void
gimp_text_options_init (GimpTextOptions *options)
{
- options->size_entry = NULL;
+ GeglColor *gray = gegl_color_new ("gray");
+
+ options->size_entry = NULL;
+ options->outline_foreground = gray;
}
static void
@@ -374,6 +378,7 @@ gimp_text_options_finalize (GObject *object)
GimpTextOptions *options = GIMP_TEXT_OPTIONS (object);
g_clear_pointer (&options->language, g_free);
+ g_clear_object (&options->outline_foreground);
G_OBJECT_CLASS (parent_class)->finalize (object);
}
@@ -429,7 +434,7 @@ gimp_text_options_get_property (GObject *object,
g_value_set_enum (value, options->outline_style);
break;
case PROP_OUTLINE_FOREGROUND:
- g_value_set_boxed (value, &options->outline_foreground);
+ g_value_set_object (value, options->outline_foreground);
break;
case PROP_OUTLINE_PATTERN:
g_value_set_object (value, options->outline_pattern);
@@ -491,7 +496,6 @@ gimp_text_options_set_property (GObject *object,
GParamSpec *pspec)
{
GimpTextOptions *options = GIMP_TEXT_OPTIONS (object);
- GimpRGB *color;
switch (property_id)
{
@@ -537,8 +541,7 @@ gimp_text_options_set_property (GObject *object,
options->outline_style = g_value_get_enum (value);
break;
case PROP_OUTLINE_FOREGROUND:
- color = g_value_get_boxed (value);
- options->outline_foreground = *color;
+ g_set_object (&options->outline_foreground, g_value_get_object (value));;
break;
case PROP_OUTLINE_PATTERN:
{
@@ -683,17 +686,11 @@ gimp_text_options_notify_color (GimpContext *context,
GParamSpec *pspec,
GimpText *text)
{
- GeglColor *color;
- GimpRGB rgb;
-
- color = gimp_context_get_foreground (context);
- gegl_color_get_pixel (color, babl_format ("R'G'B'A double"), &rgb);
-
g_signal_handlers_block_by_func (text,
gimp_text_options_notify_text_color,
context);
- g_object_set (text, "color", &rgb, NULL);
+ g_object_set (text, "color", gimp_context_get_foreground (context), NULL);
g_signal_handlers_unblock_by_func (text,
gimp_text_options_notify_text_color,
@@ -705,18 +702,13 @@ gimp_text_options_notify_text_color (GimpText *text,
GParamSpec *pspec,
GimpContext *context)
{
- GeglColor *color = gegl_color_new ("black");
-
g_signal_handlers_block_by_func (context,
gimp_text_options_notify_color, text);
- gegl_color_set_rgba_with_space (color, text->color.r, text->color.g, text->color.b, text->color.a, NULL);
- gimp_context_set_foreground (context, color);
+ gimp_context_set_foreground (context, text->color);
g_signal_handlers_unblock_by_func (context,
gimp_text_options_notify_color, text);
-
- g_object_unref (color);
}
/* This function could live in gimptexttool.c also.
@@ -727,21 +719,16 @@ gimp_text_options_connect_text (GimpTextOptions *options,
GimpText *text)
{
GimpContext *context;
- GeglColor *color;
- GimpRGB rgb;
g_return_if_fail (GIMP_IS_TEXT_OPTIONS (options));
g_return_if_fail (GIMP_IS_TEXT (text));
context = GIMP_CONTEXT (options);
- color = gimp_context_get_foreground (context);
- gegl_color_get_pixel (color, babl_format ("R'G'B'A double"), &rgb);
-
gimp_config_sync (G_OBJECT (options), G_OBJECT (text), 0);
g_object_set (text,
- "color", &rgb,
+ "color", gimp_context_get_foreground (context),
"font", gimp_context_get_font (context),
NULL);
diff --git a/app/tools/gimptextoptions.h b/app/tools/gimptextoptions.h
index d004fcd35e..c1a6cc10d0 100644
--- a/app/tools/gimptextoptions.h
+++ b/app/tools/gimptextoptions.h
@@ -51,7 +51,7 @@ struct _GimpTextOptions
GimpTextOutline outline;
GimpCustomStyle outline_style;
- GimpRGB outline_foreground;
+ GeglColor *outline_foreground;
GimpPattern *outline_pattern;
gdouble outline_width;
GimpUnit outline_unit;
diff --git a/app/tools/gimptexttool.c b/app/tools/gimptexttool.c
index 2e49bfc6a9..f98a62e95e 100644
--- a/app/tools/gimptexttool.c
+++ b/app/tools/gimptexttool.c
@@ -2031,7 +2031,7 @@ gimp_text_tool_ensure_layout (GimpTextTool *text_tool)
gimp_image_get_resolution (image, &xres, &yres);
text_tool->layout = gimp_text_layout_new (text_tool->layer->text,
- xres, yres, &error);
+ image, xres, yres, &error);
if (error)
{
gimp_message_literal (image->gimp, NULL, GIMP_MESSAGE_ERROR, error->message);
diff --git a/app/widgets/gimptextstyleeditor.c b/app/widgets/gimptextstyleeditor.c
index 68062227b1..bece227ce5 100644
--- a/app/widgets/gimptextstyleeditor.c
+++ b/app/widgets/gimptextstyleeditor.c
@@ -781,12 +781,14 @@ gimp_text_style_editor_set_color (GimpTextStyleEditor *editor,
static void
gimp_text_style_editor_set_default_color (GimpTextStyleEditor *editor)
{
+ GimpRGB rgb;
+
g_signal_handlers_block_by_func (editor->color_button,
gimp_text_style_editor_color_changed,
editor);
- gimp_color_button_set_color (GIMP_COLOR_BUTTON (editor->color_button),
- &editor->text->color);
+ gegl_color_get_pixel (editor->text->color, babl_format ("R'G'B'A double"), &rgb);
+ gimp_color_button_set_color (GIMP_COLOR_BUTTON (editor->color_button), &rgb);
g_signal_handlers_unblock_by_func (editor->color_button,
gimp_text_style_editor_color_changed,
diff --git a/app/widgets/gimpviewrenderer.c b/app/widgets/gimpviewrenderer.c
index f5214e7bbb..18e128e4df 100644
--- a/app/widgets/gimpviewrenderer.c
+++ b/app/widgets/gimpviewrenderer.c
@@ -1209,7 +1209,7 @@ gimp_view_render_temp_buf_to_surface (GimpViewRenderer *renderer,
width, height);
src_buffer = gimp_temp_buf_create_buffer (temp_buf);
- dest_buffer = gimp_cairo_surface_create_buffer (alpha_surface);
+ dest_buffer = gimp_cairo_surface_create_buffer (alpha_surface, NULL);
transform =
gimp_view_renderer_get_color_transform (renderer, widget,
@@ -1258,7 +1258,7 @@ gimp_view_render_temp_buf_to_surface (GimpViewRenderer *renderer,
cairo_surface_flush (surface);
src_buffer = gimp_temp_buf_create_buffer (temp_buf);
- dest_buffer = gimp_cairo_surface_create_buffer (surface);
+ dest_buffer = gimp_cairo_surface_create_buffer (surface, NULL);
transform =
gimp_view_renderer_get_color_transform (renderer, widget,
diff --git a/libgimp/gimplayer.c b/libgimp/gimplayer.c
index 86275235c1..a6f3ccbc15 100644
--- a/libgimp/gimplayer.c
+++ b/libgimp/gimplayer.c
@@ -285,7 +285,7 @@ gimp_layer_new_from_surface (GimpImage *image,
if (layer == NULL)
return NULL;
- src_buffer = gimp_cairo_surface_create_buffer (surface);
+ src_buffer = gimp_cairo_surface_create_buffer (surface, NULL);
dest_buffer = gimp_drawable_get_buffer (GIMP_DRAWABLE (layer));
gegl_buffer_copy (src_buffer, NULL, GEGL_ABYSS_NONE,
diff --git a/libgimp/gimptextlayer_pdb.c b/libgimp/gimptextlayer_pdb.c
index a40a8a8f93..eb3416e21d 100644
--- a/libgimp/gimptextlayer_pdb.c
+++ b/libgimp/gimptextlayer_pdb.c
@@ -869,23 +869,21 @@ gimp_text_layer_set_justification (GimpTextLayer *layer,
/**
* gimp_text_layer_get_color:
* @layer: The text layer.
- * @color: (out caller-allocates): The color of the text.
*
* Get the color of the text in a text layer.
*
* This procedure returns the color of the text in a text layer.
*
- * Returns: TRUE on success.
+ * Returns: (transfer full): The color of the text.
*
* Since: 2.6
**/
-gboolean
-gimp_text_layer_get_color (GimpTextLayer *layer,
- GimpRGB *color)
+GeglColor *
+gimp_text_layer_get_color (GimpTextLayer *layer)
{
GimpValueArray *args;
GimpValueArray *return_vals;
- gboolean success = TRUE;
+ GeglColor *color = NULL;
args = gimp_value_array_new_from_types (NULL,
GIMP_TYPE_TEXT_LAYER, layer,
@@ -896,14 +894,12 @@ gimp_text_layer_get_color (GimpTextLayer *layer,
args);
gimp_value_array_unref (args);
- success = GIMP_VALUES_GET_ENUM (return_vals, 0) == GIMP_PDB_SUCCESS;
-
- if (success)
- GIMP_VALUES_GET_RGB (return_vals, 1, &*color);
+ if (GIMP_VALUES_GET_ENUM (return_vals, 0) == GIMP_PDB_SUCCESS)
+ color = g_value_dup_object (gimp_value_array_index (return_vals, 1));
gimp_value_array_unref (return_vals);
- return success;
+ return color;
}
/**
diff --git a/libgimp/gimptextlayer_pdb.h b/libgimp/gimptextlayer_pdb.h
index a5c0a88480..15a80a6a0a 100644
--- a/libgimp/gimptextlayer_pdb.h
+++ b/libgimp/gimptextlayer_pdb.h
@@ -69,8 +69,7 @@ gboolean gimp_text_layer_set_base_direction (GimpTextLayer
GimpTextJustification gimp_text_layer_get_justification (GimpTextLayer *layer);
gboolean gimp_text_layer_set_justification (GimpTextLayer *layer,
GimpTextJustification justify);
-gboolean gimp_text_layer_get_color (GimpTextLayer *layer,
- GimpRGB *color);
+GeglColor* gimp_text_layer_get_color (GimpTextLayer *layer);
gboolean gimp_text_layer_set_color (GimpTextLayer *layer,
const GimpRGB *color);
gdouble gimp_text_layer_get_indent (GimpTextLayer *layer);
diff --git a/libgimpcolor/gimpcairo.c b/libgimpcolor/gimpcairo.c
index 756b62fcf8..850ad22bbf 100644
--- a/libgimpcolor/gimpcairo.c
+++ b/libgimpcolor/gimpcairo.c
@@ -162,9 +162,14 @@ gimp_cairo_surface_get_format (cairo_surface_t *surface)
switch (cairo_image_surface_get_format (surface))
{
- case CAIRO_FORMAT_RGB24: return babl_format ("cairo-RGB24");
- case CAIRO_FORMAT_ARGB32: return babl_format ("cairo-ARGB32");
- case CAIRO_FORMAT_A8: return babl_format ("cairo-A8");
+ case CAIRO_FORMAT_RGB24: return babl_format ("cairo-RGB24");
+ case CAIRO_FORMAT_ARGB32: return babl_format ("cairo-ARGB32");
+ case CAIRO_FORMAT_A8: return babl_format ("cairo-A8");
+#if CAIRO_VERSION >= CAIRO_VERSION_ENCODE(1, 17, 2)
+ /* Since Cairo 1.17.2 */
+ case CAIRO_FORMAT_RGB96F: return babl_format ("R'B'B' float");
+ case CAIRO_FORMAT_RGBA128F: return babl_format ("R'G'B'A float");
+#endif
default:
break;
@@ -176,27 +181,37 @@ gimp_cairo_surface_get_format (cairo_surface_t *surface)
/**
* gimp_cairo_surface_create_buffer:
* @surface: a Cairo surface
+ * @format: a Babl format.
*
* This function returns a #GeglBuffer which wraps @surface's pixels.
* It must only be called on image surfaces, calling it on other surface
* types is an error.
*
+ * If @format is set, the returned [class@Gegl.Buffer] will use it. It has to
+ * map with @surface Cairo format. If unset, the buffer format will be
+ * determined from @surface. The main difference is that automatically
+ * determined format has sRGB space and TRC by default.
+ *
* Returns: (transfer full): a #GeglBuffer
*
* Since: 2.10
**/
GeglBuffer *
-gimp_cairo_surface_create_buffer (cairo_surface_t *surface)
+gimp_cairo_surface_create_buffer (cairo_surface_t *surface,
+ const Babl *format)
{
- const Babl *format;
- gint width;
- gint height;
+ gint width;
+ gint height;
g_return_val_if_fail (surface != NULL, NULL);
g_return_val_if_fail (cairo_surface_get_type (surface) ==
CAIRO_SURFACE_TYPE_IMAGE, NULL);
+ g_return_val_if_fail (format == NULL ||
+ babl_format_get_bytes_per_pixel (format) == babl_format_get_bytes_per_pixel (gimp_cairo_surface_get_format (surface)),
+ NULL);
- format = gimp_cairo_surface_get_format (surface);
+ if (format == NULL)
+ format = gimp_cairo_surface_get_format (surface);
width = cairo_image_surface_get_width (surface);
height = cairo_image_surface_get_height (surface);
diff --git a/libgimpcolor/gimpcairo.h b/libgimpcolor/gimpcairo.h
index d96e963aad..a88ab5a496 100644
--- a/libgimpcolor/gimpcairo.h
+++ b/libgimpcolor/gimpcairo.h
@@ -35,7 +35,8 @@ cairo_pattern_t * gimp_cairo_checkerboard_create (cairo_t *cr,
const GimpRGB *dark);
const Babl * gimp_cairo_surface_get_format (cairo_surface_t *surface);
-GeglBuffer * gimp_cairo_surface_create_buffer (cairo_surface_t *surface);
+GeglBuffer * gimp_cairo_surface_create_buffer (cairo_surface_t *surface,
+ const Babl *format);
/* some useful macros for writing directly to a Cairo surface */
diff --git a/meson.build b/meson.build
index 6f4e0172e3..fb22530dcc 100644
--- a/meson.build
+++ b/meson.build
@@ -351,6 +351,9 @@ if not babl.found()
# because it would be a newer version.
babl = dependency('babl', version: '>='+babl_minver)
endif
+# TODO: we want to bump to Cairo 1.17.2 when possible in order to use
+# CAIRO_FORMAT_RGBA128F unconditionally. At time of writing, it's not possible
+# because of our bookworm availability requirement.
cairo_minver = '1.14.0'
cairo = dependency('cairo', version: '>='+cairo_minver)
diff --git a/pdb/groups/text_layer.pdb b/pdb/groups/text_layer.pdb
index 7ce06bb692..6b6f639d75 100644
--- a/pdb/groups/text_layer.pdb
+++ b/pdb/groups/text_layer.pdb
@@ -732,14 +732,14 @@ HELP
);
@outargs = (
- { name => 'color', type => 'color', void_ret => 1,
+ { name => 'color', type => 'geglcolor',
desc => 'The color of the text.' }
);
%invoke = (
code => <<'CODE'
{
- color = gimp_text_layer_get_text (layer)->color;
+ color = gegl_color_duplicate (gimp_text_layer_get_text (layer)->color);
}
CODE
);
diff --git a/plug-ins/common/file-pdf-save.c b/plug-ins/common/file-pdf-save.c
index ffa72aacd0..9753357bc1 100644
--- a/plug-ins/common/file-pdf-save.c
+++ b/plug-ins/common/file-pdf-save.c
@@ -1438,7 +1438,7 @@ get_cairo_surface (GimpDrawable *drawable,
return NULL;
}
- dest_buffer = gimp_cairo_surface_create_buffer (surface);
+ dest_buffer = gimp_cairo_surface_create_buffer (surface, NULL);
if (as_mask)
{
/* src_buffer represents a mask in "Y u8", "Y u16", etc. formats.
@@ -1555,7 +1555,8 @@ drawText (GimpLayer *layer,
cairo_font_options_t *options;
gint x;
gint y;
- GimpRGB rgb;
+ GeglColor *color;
+ gdouble rgb[3];
GimpUnit unit;
gdouble size;
GimpTextHintStyle hinting;
@@ -1588,20 +1589,18 @@ drawText (GimpLayer *layer,
/* When dealing with a gray/indexed image, the viewed color of the text layer
* can be different than the one kept in the memory */
if (type == GIMP_RGBA_IMAGE)
- {
- gimp_text_layer_get_color (GIMP_TEXT_LAYER (layer), &rgb);
- }
+ color = gimp_text_layer_get_color (GIMP_TEXT_LAYER (layer));
else
- {
- GeglColor *color;
+ gimp_image_pick_color (gimp_item_get_image (GIMP_ITEM (layer)), 1,
+ (const GimpItem**) &layer, x, y, FALSE, FALSE, 0,
+ &color);
- gimp_image_pick_color (gimp_item_get_image (GIMP_ITEM (layer)), 1,
- (const GimpItem**) &layer, x, y, FALSE, FALSE, 0,
- &color);
- gegl_color_get_rgba_with_space (color, &rgb.r, &rgb.g, &rgb.b, &rgb.a, NULL);
- }
-
- cairo_set_source_rgba (cr, rgb.r, rgb.g, rgb.b, opacity);
+ /* TODO: this export plug-in is not space-aware yet, so we draw everything as
+ * sRGB for the time being.
+ */
+ gegl_color_get_pixel (color, babl_format_with_space ("R'G'B' double", NULL), rgb);
+ cairo_set_source_rgba (cr, rgb[0], rgb[1], rgb[2], opacity);
+ g_object_unref (color);
/* Hinting */
hinting = gimp_text_layer_get_hint_style (GIMP_TEXT_LAYER (layer));