From a7223bbd2daf9ef56f25feef640b593b7f42136c Mon Sep 17 00:00:00 2001 From: Michael Natterer Date: Sat, 10 Nov 2012 18:56:44 +0100 Subject: [PATCH] Bug 352823 - Changing image mode discards text layer information For conversions that have no dither options (like RGB -> GRAY or u8 -> u16), always preserve text editability, for conversions that have dither options (like RGB -> INDEXED or u16 -> u8), give the user the choice whether to enable dithering. --- app/actions/image-commands.c | 4 +- app/core/core-enums.c | 2 + app/core/core-enums.h | 1 + app/core/gimpimage-convert-precision.c | 11 ++- app/core/gimpimage-convert-precision.h | 1 + app/core/gimpimage-convert-type.c | 64 +++++++----- app/core/gimpimage-convert-type.h | 1 + app/core/gimpimage-undo-push.c | 16 +++ app/core/gimpimage-undo-push.h | 3 + app/dialogs/convert-precision-dialog.c | 46 +++++++-- app/dialogs/convert-type-dialog.c | 59 +++++++---- app/pdb/convert-cmds.c | 8 +- app/text/gimptextlayer.c | 129 ++++++++++++++++++------- app/text/gimptextlayer.h | 2 + app/text/gimptextundo.c | 20 ++++ app/text/gimptextundo.h | 1 + tools/pdbgen/pdb/convert.pdb | 8 +- 17 files changed, 277 insertions(+), 99 deletions(-) diff --git a/app/actions/image-commands.c b/app/actions/image-commands.c index e792198d32..3aead0a1f9 100644 --- a/app/actions/image-commands.c +++ b/app/actions/image-commands.c @@ -181,7 +181,7 @@ image_convert_base_type_cmd_callback (GtkAction *action, case GIMP_RGB: case GIMP_GRAY: if (! gimp_image_convert_type (image, value, - 0, 0, FALSE, FALSE, 0, NULL, + 0, 0, FALSE, FALSE, FALSE, 0, NULL, NULL, &error)) { gimp_message_literal (image->gimp, @@ -273,7 +273,7 @@ image_convert_precision_cmd_callback (GtkAction *action, } else { - gimp_image_convert_precision (image, value, 0, 0, + gimp_image_convert_precision (image, value, 0, 0, 0, GIMP_PROGRESS (display)); } diff --git a/app/core/core-enums.c b/app/core/core-enums.c index fc0d650f71..1065058217 100644 --- a/app/core/core-enums.c +++ b/app/core/core-enums.c @@ -1093,6 +1093,7 @@ gimp_undo_type_get_type (void) { GIMP_UNDO_GROUP_LAYER_CONVERT, "GIMP_UNDO_GROUP_LAYER_CONVERT", "group-layer-convert" }, { GIMP_UNDO_TEXT_LAYER, "GIMP_UNDO_TEXT_LAYER", "text-layer" }, { GIMP_UNDO_TEXT_LAYER_MODIFIED, "GIMP_UNDO_TEXT_LAYER_MODIFIED", "text-layer-modified" }, + { GIMP_UNDO_TEXT_LAYER_CONVERT, "GIMP_UNDO_TEXT_LAYER_CONVERT", "text-layer-convert" }, { GIMP_UNDO_LAYER_MASK_ADD, "GIMP_UNDO_LAYER_MASK_ADD", "layer-mask-add" }, { GIMP_UNDO_LAYER_MASK_REMOVE, "GIMP_UNDO_LAYER_MASK_REMOVE", "layer-mask-remove" }, { GIMP_UNDO_LAYER_MASK_APPLY, "GIMP_UNDO_LAYER_MASK_APPLY", "layer-mask-apply" }, @@ -1182,6 +1183,7 @@ gimp_undo_type_get_type (void) { GIMP_UNDO_GROUP_LAYER_CONVERT, NC_("undo-type", "Convert group layer"), NULL }, { GIMP_UNDO_TEXT_LAYER, NC_("undo-type", "Text layer"), NULL }, { GIMP_UNDO_TEXT_LAYER_MODIFIED, NC_("undo-type", "Text layer modification"), NULL }, + { GIMP_UNDO_TEXT_LAYER_CONVERT, NC_("undo-type", "Convert text layer"), NULL }, { GIMP_UNDO_LAYER_MASK_ADD, NC_("undo-type", "Add layer mask"), NULL }, { GIMP_UNDO_LAYER_MASK_REMOVE, NC_("undo-type", "Delete layer mask"), NULL }, { GIMP_UNDO_LAYER_MASK_APPLY, NC_("undo-type", "Apply layer mask"), NULL }, diff --git a/app/core/core-enums.h b/app/core/core-enums.h index 8bbba37837..d49ff761ff 100644 --- a/app/core/core-enums.h +++ b/app/core/core-enums.h @@ -534,6 +534,7 @@ typedef enum /*< pdb-skip >*/ GIMP_UNDO_GROUP_LAYER_CONVERT, /*< desc="Convert group layer" >*/ GIMP_UNDO_TEXT_LAYER, /*< desc="Text layer" >*/ GIMP_UNDO_TEXT_LAYER_MODIFIED, /*< desc="Text layer modification" >*/ + GIMP_UNDO_TEXT_LAYER_CONVERT, /*< desc="Convert text layer" >*/ GIMP_UNDO_LAYER_MASK_ADD, /*< desc="Add layer mask" >*/ GIMP_UNDO_LAYER_MASK_REMOVE, /*< desc="Delete layer mask" >*/ GIMP_UNDO_LAYER_MASK_APPLY, /*< desc="Apply layer mask" >*/ diff --git a/app/core/gimpimage-convert-precision.c b/app/core/gimpimage-convert-precision.c index 327d75cc14..9e70a2dcbb 100644 --- a/app/core/gimpimage-convert-precision.c +++ b/app/core/gimpimage-convert-precision.c @@ -33,6 +33,8 @@ #include "gimpimage-undo-push.h" #include "gimpprogress.h" +#include "text/gimptextlayer.h" + #include "gimp-intl.h" @@ -40,6 +42,7 @@ void gimp_image_convert_precision (GimpImage *image, GimpPrecision precision, gint layer_dither_type, + gint text_layer_dither_type, gint mask_dither_type, GimpProgress *progress) { @@ -101,11 +104,17 @@ gimp_image_convert_precision (GimpImage *image, list = g_list_next (list), nth_drawable++) { GimpDrawable *drawable = list->data; + gint dither_type; + + if (gimp_item_is_text_layer (GIMP_ITEM (drawable))) + dither_type = text_layer_dither_type; + else + dither_type = layer_dither_type; gimp_drawable_convert_type (drawable, image, gimp_drawable_get_base_type (drawable), precision, - layer_dither_type, + dither_type, mask_dither_type, TRUE); diff --git a/app/core/gimpimage-convert-precision.h b/app/core/gimpimage-convert-precision.h index 617eea8130..13140b3a66 100644 --- a/app/core/gimpimage-convert-precision.h +++ b/app/core/gimpimage-convert-precision.h @@ -25,6 +25,7 @@ void gimp_image_convert_precision (GimpImage *image, GimpPrecision precision, gint layer_dither_type, + gint text_layer_dither_type, gint mask_dither_type, GimpProgress *progress); diff --git a/app/core/gimpimage-convert-type.c b/app/core/gimpimage-convert-type.c index e7d814e5d3..319d294611 100644 --- a/app/core/gimpimage-convert-type.c +++ b/app/core/gimpimage-convert-type.c @@ -155,6 +155,8 @@ #include "gimppalette.h" #include "gimpprogress.h" +#include "text/gimptextlayer.h" + #include "gimpimage-convert-fsdither.h" #include "gimpimage-convert-data.h" #include "gimpimage-convert-type.h" @@ -739,6 +741,7 @@ gimp_image_convert_type (GimpImage *image, gint num_cols, GimpConvertDitherType dither, gboolean alpha_dither, + gboolean text_layer_dither, gboolean remove_dups, GimpConvertPaletteType palette_type, GimpPalette *custom_palette, @@ -970,44 +973,55 @@ gimp_image_convert_type (GimpImage *image, list; list = g_list_next (list), nth_layer++) { - GimpLayer *layer = list->data; + GimpLayer *layer = list->data; + gboolean quantize = FALSE; switch (new_type) { case GIMP_RGB: case GIMP_GRAY: - gimp_drawable_convert_type (GIMP_DRAWABLE (layer), image, new_type, - gimp_drawable_get_precision (GIMP_DRAWABLE (layer)), - 0, 0, - TRUE); + quantize = FALSE; break; case GIMP_INDEXED: - { - GeglBuffer *new_buffer; - gboolean has_alpha; - - has_alpha = gimp_drawable_has_alpha (GIMP_DRAWABLE (layer)); - - new_buffer = - gegl_buffer_new (GEGL_RECTANGLE (0, 0, - gimp_item_get_width (GIMP_ITEM (layer)), - gimp_item_get_height (GIMP_ITEM (layer))), - gimp_image_get_layer_format (image, - has_alpha)); - - quantobj->nth_layer = nth_layer; - quantobj->second_pass (quantobj, layer, new_buffer); - - gimp_drawable_set_buffer (GIMP_DRAWABLE (layer), TRUE, NULL, - new_buffer); - g_object_unref (new_buffer); - } + if (gimp_item_is_text_layer (GIMP_ITEM (layer))) + quantize = text_layer_dither; + else + quantize = TRUE; break; default: break; } + + if (quantize) + { + GeglBuffer *new_buffer; + gboolean has_alpha; + + has_alpha = gimp_drawable_has_alpha (GIMP_DRAWABLE (layer)); + + new_buffer = + gegl_buffer_new (GEGL_RECTANGLE (0, 0, + gimp_item_get_width (GIMP_ITEM (layer)), + gimp_item_get_height (GIMP_ITEM (layer))), + gimp_image_get_layer_format (image, + has_alpha)); + + quantobj->nth_layer = nth_layer; + quantobj->second_pass (quantobj, layer, new_buffer); + + gimp_drawable_set_buffer (GIMP_DRAWABLE (layer), TRUE, NULL, + new_buffer); + g_object_unref (new_buffer); + } + else + { + gimp_drawable_convert_type (GIMP_DRAWABLE (layer), image, new_type, + gimp_drawable_get_precision (GIMP_DRAWABLE (layer)), + 0, 0, + TRUE); + } } /* Set the final palette on the image */ diff --git a/app/core/gimpimage-convert-type.h b/app/core/gimpimage-convert-type.h index 893fcbc90f..69d4c2d0e7 100644 --- a/app/core/gimpimage-convert-type.h +++ b/app/core/gimpimage-convert-type.h @@ -30,6 +30,7 @@ gboolean gimp_image_convert_type (GimpImage *image, gint num_cols, GimpConvertDitherType dither, gboolean alpha_dither, + gboolean text_layer_dither, gboolean remove_dups, GimpConvertPaletteType palette_type, GimpPalette *custom_palette, diff --git a/app/core/gimpimage-undo-push.c b/app/core/gimpimage-undo-push.c index c226924429..2440172c8d 100644 --- a/app/core/gimpimage-undo-push.c +++ b/app/core/gimpimage-undo-push.c @@ -653,6 +653,22 @@ gimp_image_undo_push_text_layer_modified (GimpImage *image, NULL); } +GimpUndo * +gimp_image_undo_push_text_layer_convert (GimpImage *image, + const gchar *undo_desc, + GimpTextLayer *layer) +{ + g_return_val_if_fail (GIMP_IS_IMAGE (image), NULL); + g_return_val_if_fail (GIMP_IS_TEXT_LAYER (layer), NULL); + g_return_val_if_fail (gimp_item_is_attached (GIMP_ITEM (layer)), NULL); + + return gimp_image_undo_push (image, GIMP_TYPE_TEXT_UNDO, + GIMP_UNDO_TEXT_LAYER_CONVERT, undo_desc, + GIMP_DIRTY_ITEM, + "item", layer, + NULL); +} + /**********************/ /* Layer Mask Undos */ diff --git a/app/core/gimpimage-undo-push.h b/app/core/gimpimage-undo-push.h index eb97208b6f..6680c6885c 100644 --- a/app/core/gimpimage-undo-push.h +++ b/app/core/gimpimage-undo-push.h @@ -158,6 +158,9 @@ GimpUndo * gimp_image_undo_push_text_layer (GimpImage *image, GimpUndo * gimp_image_undo_push_text_layer_modified (GimpImage *image, const gchar *undo_desc, GimpTextLayer *layer); +GimpUndo * gimp_image_undo_push_text_layer_convert (GimpImage *image, + const gchar *undo_desc, + GimpTextLayer *layer); /* layer mask undos */ diff --git a/app/dialogs/convert-precision-dialog.c b/app/dialogs/convert-precision-dialog.c index ade1817b23..1849099a40 100644 --- a/app/dialogs/convert-precision-dialog.c +++ b/app/dialogs/convert-precision-dialog.c @@ -54,6 +54,7 @@ typedef struct GimpPrecision precision; gint layer_dither_type; + gint text_layer_dither_type; gint mask_dither_type; } ConvertDialog; @@ -66,8 +67,9 @@ static void convert_precision_dialog_free (ConvertDialog *dialog); /* defaults */ -static gint saved_layer_dither_type = 0; -static gint saved_mask_dither_type = 0; +static gint saved_layer_dither_type = 0; +static gint saved_text_layer_dither_type = 0; +static gint saved_mask_dither_type = 0; /* public functions */ @@ -99,11 +101,12 @@ convert_precision_dialog_new (GimpImage *image, dialog = g_slice_new0 (ConvertDialog); - dialog->image = image; - dialog->precision = precision; - dialog->progress = progress; - dialog->layer_dither_type = saved_layer_dither_type; - dialog->mask_dither_type = saved_mask_dither_type; + dialog->image = image; + dialog->precision = precision; + dialog->progress = progress; + dialog->layer_dither_type = saved_layer_dither_type; + dialog->text_layer_dither_type = saved_text_layer_dither_type; + dialog->mask_dither_type = saved_mask_dither_type; gimp_enum_get_value (GIMP_TYPE_PRECISION, precision, NULL, NULL, &enum_desc, NULL); @@ -190,7 +193,33 @@ convert_precision_dialog_new (GimpImage *image, G_CALLBACK (gimp_int_combo_box_get_active), &dialog->layer_dither_type); - /* layers */ + /* text layers */ + + hbox = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 6); + gtk_box_pack_start (GTK_BOX (vbox), hbox, FALSE, FALSE, 0); + gtk_widget_show (hbox); + + label = gtk_label_new_with_mnemonic (_("_Text Layers:")); + gtk_misc_set_alignment (GTK_MISC (label), 0.0, 0.5); + gtk_box_pack_start (GTK_BOX (hbox), label, FALSE, FALSE, 0); + gtk_size_group_add_widget (size_group, label); + gtk_widget_show (label); + + combo = gimp_enum_combo_box_new (dither_type); + gtk_label_set_mnemonic_widget (GTK_LABEL (label), combo); + gtk_box_pack_start (GTK_BOX (hbox), combo, TRUE, TRUE, 0); + gtk_widget_show (combo); + + gimp_int_combo_box_connect (GIMP_INT_COMBO_BOX (combo), + dialog->text_layer_dither_type, + G_CALLBACK (gimp_int_combo_box_get_active), + &dialog->text_layer_dither_type); + + gimp_help_set_help_data (combo, + _("Dithering text layers will make them uneditable"), + NULL); + + /* channels */ hbox = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 6); gtk_box_pack_start (GTK_BOX (vbox), hbox, FALSE, FALSE, 0); @@ -235,6 +264,7 @@ convert_precision_dialog_response (GtkWidget *widget, gimp_image_convert_precision (dialog->image, dialog->precision, dialog->layer_dither_type, + dialog->text_layer_dither_type, dialog->mask_dither_type, progress); diff --git a/app/dialogs/convert-type-dialog.c b/app/dialogs/convert-type-dialog.c index 20982b9234..6c93b0ab72 100644 --- a/app/dialogs/convert-type-dialog.c +++ b/app/dialogs/convert-type-dialog.c @@ -56,6 +56,7 @@ typedef struct GimpConvertDitherType dither_type; gboolean alpha_dither; + gboolean text_layer_dither; gboolean remove_dups; gint num_colors; GimpConvertPaletteType palette_type; @@ -76,12 +77,13 @@ static void convert_dialog_free (IndexedDialog *dialog); /* defaults */ -static GimpConvertDitherType saved_dither_type = GIMP_NO_DITHER; -static gboolean saved_alpha_dither = FALSE; -static gboolean saved_remove_dups = TRUE; -static gint saved_num_colors = 256; -static GimpConvertPaletteType saved_palette_type = GIMP_MAKE_PALETTE; -static GimpPalette *saved_palette = NULL; +static GimpConvertDitherType saved_dither_type = GIMP_NO_DITHER; +static gboolean saved_alpha_dither = FALSE; +static gboolean saved_text_layer_dither = FALSE; +static gboolean saved_remove_dups = TRUE; +static gint saved_num_colors = 256; +static GimpConvertPaletteType saved_palette_type = GIMP_MAKE_PALETTE; +static GimpPalette *saved_palette = NULL; /* public functions */ @@ -112,13 +114,14 @@ convert_type_dialog_new (GimpImage *image, dialog = g_slice_new0 (IndexedDialog); - dialog->image = image; - dialog->progress = progress; - dialog->dither_type = saved_dither_type; - dialog->alpha_dither = saved_alpha_dither; - dialog->remove_dups = saved_remove_dups; - dialog->num_colors = saved_num_colors; - dialog->palette_type = saved_palette_type; + dialog->image = image; + dialog->progress = progress; + dialog->dither_type = saved_dither_type; + dialog->alpha_dither = saved_alpha_dither; + dialog->text_layer_dither = saved_text_layer_dither; + dialog->remove_dups = saved_remove_dups; + dialog->num_colors = saved_num_colors; + dialog->palette_type = saved_palette_type; dialog->dialog = gimp_viewable_dialog_new (GIMP_VIEWABLE (image), context, @@ -268,6 +271,22 @@ convert_type_dialog_new (GimpImage *image, G_CALLBACK (gimp_toggle_button_update), &dialog->alpha_dither); + + toggle = + gtk_check_button_new_with_mnemonic (_("Enable dithering of text layers")); + gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (toggle), + dialog->text_layer_dither); + gtk_box_pack_start (GTK_BOX (vbox), toggle, FALSE, FALSE, 0); + gtk_widget_show (toggle); + + g_signal_connect (toggle, "toggled", + G_CALLBACK (gimp_toggle_button_update), + &dialog->text_layer_dither); + + gimp_help_set_help_data (toggle, + _("Dithering text layers will make them uneditable"), + NULL); + return dialog->dialog; } @@ -293,6 +312,7 @@ convert_dialog_response (GtkWidget *widget, dialog->num_colors, dialog->dither_type, dialog->alpha_dither, + dialog->text_layer_dither, dialog->remove_dups, dialog->palette_type, dialog->custom_palette, @@ -314,12 +334,13 @@ convert_dialog_response (GtkWidget *widget, gimp_image_flush (dialog->image); /* Save defaults for next time */ - saved_dither_type = dialog->dither_type; - saved_alpha_dither = dialog->alpha_dither; - saved_remove_dups = dialog->remove_dups; - saved_num_colors = dialog->num_colors; - saved_palette_type = dialog->palette_type; - saved_palette = dialog->custom_palette; + saved_dither_type = dialog->dither_type; + saved_alpha_dither = dialog->alpha_dither; + saved_text_layer_dither = dialog->text_layer_dither; + saved_remove_dups = dialog->remove_dups; + saved_num_colors = dialog->num_colors; + saved_palette_type = dialog->palette_type; + saved_palette = dialog->custom_palette; } gtk_widget_destroy (dialog->dialog); diff --git a/app/pdb/convert-cmds.c b/app/pdb/convert-cmds.c index 93da3cdecb..24b4f911ad 100644 --- a/app/pdb/convert-cmds.c +++ b/app/pdb/convert-cmds.c @@ -64,7 +64,7 @@ image_convert_rgb_invoker (GimpProcedure *procedure, if (gimp_pdb_image_is_not_base_type (image, GIMP_RGB, error)) { success = gimp_image_convert_type (image, GIMP_RGB, - 0, 0, FALSE, FALSE, 0, NULL, + 0, 0, FALSE, FALSE, FALSE, 0, NULL, NULL, error); } else @@ -95,7 +95,7 @@ image_convert_grayscale_invoker (GimpProcedure *procedure, if (gimp_pdb_image_is_not_base_type (image, GIMP_GRAY, error)) { success = gimp_image_convert_type (image, GIMP_GRAY, - 0, 0, FALSE, FALSE, 0, NULL, + 0, 0, FALSE, FALSE, FALSE, 0, NULL, NULL, error); } else @@ -177,7 +177,7 @@ image_convert_indexed_invoker (GimpProcedure *procedure, if (success) success = gimp_image_convert_type (image, GIMP_INDEXED, num_cols, dither_type, - alpha_dither, remove_unused, + alpha_dither, FALSE, remove_unused, palette_type, pal, NULL, error); } @@ -247,7 +247,7 @@ image_convert_precision_invoker (GimpProcedure *procedure, if (gimp_pdb_image_is_not_base_type (image, GIMP_INDEXED, error) && gimp_pdb_image_is_not_precision (image, precision, error)) { - gimp_image_convert_precision (image, precision, 0, 0, NULL); + gimp_image_convert_precision (image, precision, 0, 0, 0, NULL); } else { diff --git a/app/text/gimptextlayer.c b/app/text/gimptextlayer.c index a551b35388..0a7cd55e75 100644 --- a/app/text/gimptextlayer.c +++ b/app/text/gimptextlayer.c @@ -33,6 +33,7 @@ #include "text-types.h" +#include "gegl/gimp-babl.h" #include "gegl/gimp-gegl-utils.h" #include "core/gimp.h" @@ -63,44 +64,52 @@ enum }; -static void gimp_text_layer_finalize (GObject *object); -static void gimp_text_layer_get_property (GObject *object, - guint property_id, - GValue *value, - GParamSpec *pspec); -static void gimp_text_layer_set_property (GObject *object, - guint property_id, - const GValue *value, - GParamSpec *pspec); +static void gimp_text_layer_finalize (GObject *object); +static void gimp_text_layer_get_property (GObject *object, + guint property_id, + GValue *value, + GParamSpec *pspec); +static void gimp_text_layer_set_property (GObject *object, + guint property_id, + const GValue *value, + GParamSpec *pspec); -static gint64 gimp_text_layer_get_memsize (GimpObject *object, - gint64 *gui_size); +static gint64 gimp_text_layer_get_memsize (GimpObject *object, + gint64 *gui_size); -static GimpItem * gimp_text_layer_duplicate (GimpItem *item, - GType new_type); -static gboolean gimp_text_layer_rename (GimpItem *item, - const gchar *new_name, - const gchar *undo_desc, - GError **error); +static GimpItem * gimp_text_layer_duplicate (GimpItem *item, + GType new_type); +static gboolean gimp_text_layer_rename (GimpItem *item, + const gchar *new_name, + const gchar *undo_desc, + GError **error); -static void gimp_text_layer_set_buffer (GimpDrawable *drawable, - gboolean push_undo, - const gchar *undo_desc, - GeglBuffer *buffer, - gint offset_x, - gint offset_y); -static void gimp_text_layer_push_undo (GimpDrawable *drawable, - const gchar *undo_desc, - GeglBuffer *buffer, - gint x, - gint y, - gint width, - gint height); +static void gimp_text_layer_convert_type (GimpDrawable *drawable, + GimpImage *dest_image, + const Babl *new_format, + GimpImageBaseType new_base_type, + GimpPrecision new_precision, + gint layer_dither_type, + gint mask_dither_type, + gboolean push_undo); +static void gimp_text_layer_set_buffer (GimpDrawable *drawable, + gboolean push_undo, + const gchar *undo_desc, + GeglBuffer *buffer, + gint offset_x, + gint offset_y); +static void gimp_text_layer_push_undo (GimpDrawable *drawable, + const gchar *undo_desc, + GeglBuffer *buffer, + gint x, + gint y, + gint width, + gint height); -static void gimp_text_layer_text_changed (GimpTextLayer *layer); -static gboolean gimp_text_layer_render (GimpTextLayer *layer); -static void gimp_text_layer_render_layout (GimpTextLayer *layer, - GimpTextLayout *layout); +static void gimp_text_layer_text_changed (GimpTextLayer *layer); +static gboolean gimp_text_layer_render (GimpTextLayer *layer); +static void gimp_text_layer_render_layout (GimpTextLayer *layer, + GimpTextLayout *layout); G_DEFINE_TYPE (GimpTextLayer, gimp_text_layer, GIMP_TYPE_LAYER) @@ -144,6 +153,7 @@ gimp_text_layer_class_init (GimpTextLayerClass *klass) item_class->rotate_desc = _("Rotate Text Layer"); item_class->transform_desc = _("Transform Text Layer"); + drawable_class->convert_type = gimp_text_layer_convert_type; drawable_class->set_buffer = gimp_text_layer_set_buffer; drawable_class->push_undo = gimp_text_layer_push_undo; @@ -300,6 +310,42 @@ gimp_text_layer_rename (GimpItem *item, return FALSE; } +static void +gimp_text_layer_convert_type (GimpDrawable *drawable, + GimpImage *dest_image, + const Babl *new_format, + GimpImageBaseType new_base_type, + GimpPrecision new_precision, + gint layer_dither_type, + gint mask_dither_type, + gboolean push_undo) +{ + GimpTextLayer *layer = GIMP_TEXT_LAYER (drawable); + GimpImage *image = gimp_item_get_image (GIMP_ITEM (layer)); + + if (! layer->text || layer->modified || layer_dither_type != 0) + { + GIMP_DRAWABLE_CLASS (parent_class)->convert_type (drawable, dest_image, + new_format, + new_base_type, + new_precision, + layer_dither_type, + mask_dither_type, + push_undo); + } + else + { + if (push_undo) + gimp_image_undo_push_text_layer_convert (image, NULL, layer); + + layer->convert_format = new_format; + + gimp_text_layer_render (layer); + + layer->convert_format = NULL; + } +} + static void gimp_text_layer_set_buffer (GimpDrawable *drawable, gboolean push_undo, @@ -529,6 +575,15 @@ gimp_item_is_text_layer (GimpItem *item) /* private functions */ +static const Babl * +gimp_text_layer_get_format (GimpTextLayer *layer) +{ + if (layer->convert_format) + return layer->convert_format; + + return gimp_drawable_get_format (GIMP_DRAWABLE (layer)); +} + static void gimp_text_layer_text_changed (GimpTextLayer *layer) { @@ -583,12 +638,14 @@ gimp_text_layer_render (GimpTextLayer *layer) if (gimp_text_layout_get_size (layout, &width, &height) && (width != gimp_item_get_width (item) || - height != gimp_item_get_height (item))) + height != gimp_item_get_height (item) || + gimp_text_layer_get_format (layer) != + gimp_drawable_get_format (drawable))) { GeglBuffer *new_buffer; new_buffer = gegl_buffer_new (GEGL_RECTANGLE (0, 0, width, height), - gimp_drawable_get_format (drawable)); + gimp_text_layer_get_format (layer)); gimp_drawable_set_buffer (drawable, FALSE, NULL, new_buffer); g_object_unref (new_buffer); diff --git a/app/text/gimptextlayer.h b/app/text/gimptextlayer.h index 6d6e504143..5b331933dc 100644 --- a/app/text/gimptextlayer.h +++ b/app/text/gimptextlayer.h @@ -46,6 +46,8 @@ struct _GimpTextLayer */ gboolean auto_rename; gboolean modified; + + const Babl *convert_format; }; struct _GimpTextLayerClass diff --git a/app/text/gimptextundo.c b/app/text/gimptextundo.c index 934860b091..efcbe6fe88 100644 --- a/app/text/gimptextundo.c +++ b/app/text/gimptextundo.c @@ -23,6 +23,8 @@ #include "text-types.h" +#include "gegl/gimp-babl.h" + #include "core/gimpitem.h" #include "core/gimpitemundo.h" #include "core/gimp-utils.h" @@ -128,6 +130,10 @@ gimp_text_undo_constructed (GObject *object) text_undo->modified = layer->modified; break; + case GIMP_UNDO_TEXT_LAYER_CONVERT: + text_undo->format = gimp_drawable_get_format (GIMP_DRAWABLE (layer)); + break; + default: g_assert_not_reached (); } @@ -258,6 +264,20 @@ gimp_text_undo_pop (GimpUndo *undo, } break; + case GIMP_UNDO_TEXT_LAYER_CONVERT: + { + const Babl *format; + + format = gimp_drawable_get_format (GIMP_DRAWABLE (layer)); + gimp_drawable_convert_type (GIMP_DRAWABLE (layer), + gimp_item_get_image (GIMP_ITEM (layer)), + gimp_babl_format_get_base_type (text_undo->format), + gimp_babl_format_get_precision (text_undo->format), + 0, 0, FALSE); + text_undo->format = format; + } + break; + default: g_assert_not_reached (); } diff --git a/app/text/gimptextundo.h b/app/text/gimptextundo.h index 244c9b6dd2..d81d962d56 100644 --- a/app/text/gimptextundo.h +++ b/app/text/gimptextundo.h @@ -40,6 +40,7 @@ struct _GimpTextUndo const GParamSpec *pspec; GValue *value; gboolean modified; + const Babl *format; }; struct _GimpTextUndoClass diff --git a/tools/pdbgen/pdb/convert.pdb b/tools/pdbgen/pdb/convert.pdb index 116a82e172..2e84f6fba6 100644 --- a/tools/pdbgen/pdb/convert.pdb +++ b/tools/pdbgen/pdb/convert.pdb @@ -38,7 +38,7 @@ HELP if (gimp_pdb_image_is_not_base_type (image, GIMP_RGB, error)) { success = gimp_image_convert_type (image, GIMP_RGB, - 0, 0, FALSE, FALSE, 0, NULL, + 0, 0, FALSE, FALSE, FALSE, 0, NULL, NULL, error); } else @@ -72,7 +72,7 @@ HELP if (gimp_pdb_image_is_not_base_type (image, GIMP_GRAY, error)) { success = gimp_image_convert_type (image, GIMP_GRAY, - 0, 0, FALSE, FALSE, 0, NULL, + 0, 0, FALSE, FALSE, FALSE, 0, NULL, NULL, error); } else @@ -170,7 +170,7 @@ HELP if (success) success = gimp_image_convert_type (image, GIMP_INDEXED, num_cols, dither_type, - alpha_dither, remove_unused, + alpha_dither, FALSE, remove_unused, palette_type, pal, NULL, error); } @@ -246,7 +246,7 @@ HELP if (gimp_pdb_image_is_not_base_type (image, GIMP_INDEXED, error) && gimp_pdb_image_is_not_precision (image, precision, error)) { - gimp_image_convert_precision (image, precision, 0, 0, NULL); + gimp_image_convert_precision (image, precision, 0, 0, 0, NULL); } else {