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.
This commit is contained in:
Michael Natterer
2012-11-10 18:56:44 +01:00
parent e71e12c5d7
commit a7223bbd2d
17 changed files with 277 additions and 99 deletions

View File

@ -181,7 +181,7 @@ image_convert_base_type_cmd_callback (GtkAction *action,
case GIMP_RGB: case GIMP_RGB:
case GIMP_GRAY: case GIMP_GRAY:
if (! gimp_image_convert_type (image, value, if (! gimp_image_convert_type (image, value,
0, 0, FALSE, FALSE, 0, NULL, 0, 0, FALSE, FALSE, FALSE, 0, NULL,
NULL, &error)) NULL, &error))
{ {
gimp_message_literal (image->gimp, gimp_message_literal (image->gimp,
@ -273,7 +273,7 @@ image_convert_precision_cmd_callback (GtkAction *action,
} }
else else
{ {
gimp_image_convert_precision (image, value, 0, 0, gimp_image_convert_precision (image, value, 0, 0, 0,
GIMP_PROGRESS (display)); GIMP_PROGRESS (display));
} }

View File

@ -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_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, "GIMP_UNDO_TEXT_LAYER", "text-layer" },
{ GIMP_UNDO_TEXT_LAYER_MODIFIED, "GIMP_UNDO_TEXT_LAYER_MODIFIED", "text-layer-modified" }, { 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_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_REMOVE, "GIMP_UNDO_LAYER_MASK_REMOVE", "layer-mask-remove" },
{ GIMP_UNDO_LAYER_MASK_APPLY, "GIMP_UNDO_LAYER_MASK_APPLY", "layer-mask-apply" }, { 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_GROUP_LAYER_CONVERT, NC_("undo-type", "Convert group layer"), NULL },
{ GIMP_UNDO_TEXT_LAYER, NC_("undo-type", "Text 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_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_ADD, NC_("undo-type", "Add layer mask"), NULL },
{ GIMP_UNDO_LAYER_MASK_REMOVE, NC_("undo-type", "Delete 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 }, { GIMP_UNDO_LAYER_MASK_APPLY, NC_("undo-type", "Apply layer mask"), NULL },

View File

@ -534,6 +534,7 @@ typedef enum /*< pdb-skip >*/
GIMP_UNDO_GROUP_LAYER_CONVERT, /*< desc="Convert group layer" >*/ GIMP_UNDO_GROUP_LAYER_CONVERT, /*< desc="Convert group layer" >*/
GIMP_UNDO_TEXT_LAYER, /*< desc="Text layer" >*/ GIMP_UNDO_TEXT_LAYER, /*< desc="Text layer" >*/
GIMP_UNDO_TEXT_LAYER_MODIFIED, /*< desc="Text layer modification" >*/ 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_ADD, /*< desc="Add layer mask" >*/
GIMP_UNDO_LAYER_MASK_REMOVE, /*< desc="Delete layer mask" >*/ GIMP_UNDO_LAYER_MASK_REMOVE, /*< desc="Delete layer mask" >*/
GIMP_UNDO_LAYER_MASK_APPLY, /*< desc="Apply layer mask" >*/ GIMP_UNDO_LAYER_MASK_APPLY, /*< desc="Apply layer mask" >*/

View File

@ -33,6 +33,8 @@
#include "gimpimage-undo-push.h" #include "gimpimage-undo-push.h"
#include "gimpprogress.h" #include "gimpprogress.h"
#include "text/gimptextlayer.h"
#include "gimp-intl.h" #include "gimp-intl.h"
@ -40,6 +42,7 @@ void
gimp_image_convert_precision (GimpImage *image, gimp_image_convert_precision (GimpImage *image,
GimpPrecision precision, GimpPrecision precision,
gint layer_dither_type, gint layer_dither_type,
gint text_layer_dither_type,
gint mask_dither_type, gint mask_dither_type,
GimpProgress *progress) GimpProgress *progress)
{ {
@ -101,11 +104,17 @@ gimp_image_convert_precision (GimpImage *image,
list = g_list_next (list), nth_drawable++) list = g_list_next (list), nth_drawable++)
{ {
GimpDrawable *drawable = list->data; 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_convert_type (drawable, image,
gimp_drawable_get_base_type (drawable), gimp_drawable_get_base_type (drawable),
precision, precision,
layer_dither_type, dither_type,
mask_dither_type, mask_dither_type,
TRUE); TRUE);

View File

@ -25,6 +25,7 @@
void gimp_image_convert_precision (GimpImage *image, void gimp_image_convert_precision (GimpImage *image,
GimpPrecision precision, GimpPrecision precision,
gint layer_dither_type, gint layer_dither_type,
gint text_layer_dither_type,
gint mask_dither_type, gint mask_dither_type,
GimpProgress *progress); GimpProgress *progress);

View File

@ -155,6 +155,8 @@
#include "gimppalette.h" #include "gimppalette.h"
#include "gimpprogress.h" #include "gimpprogress.h"
#include "text/gimptextlayer.h"
#include "gimpimage-convert-fsdither.h" #include "gimpimage-convert-fsdither.h"
#include "gimpimage-convert-data.h" #include "gimpimage-convert-data.h"
#include "gimpimage-convert-type.h" #include "gimpimage-convert-type.h"
@ -739,6 +741,7 @@ gimp_image_convert_type (GimpImage *image,
gint num_cols, gint num_cols,
GimpConvertDitherType dither, GimpConvertDitherType dither,
gboolean alpha_dither, gboolean alpha_dither,
gboolean text_layer_dither,
gboolean remove_dups, gboolean remove_dups,
GimpConvertPaletteType palette_type, GimpConvertPaletteType palette_type,
GimpPalette *custom_palette, GimpPalette *custom_palette,
@ -970,44 +973,55 @@ gimp_image_convert_type (GimpImage *image,
list; list;
list = g_list_next (list), nth_layer++) list = g_list_next (list), nth_layer++)
{ {
GimpLayer *layer = list->data; GimpLayer *layer = list->data;
gboolean quantize = FALSE;
switch (new_type) switch (new_type)
{ {
case GIMP_RGB: case GIMP_RGB:
case GIMP_GRAY: case GIMP_GRAY:
gimp_drawable_convert_type (GIMP_DRAWABLE (layer), image, new_type, quantize = FALSE;
gimp_drawable_get_precision (GIMP_DRAWABLE (layer)),
0, 0,
TRUE);
break; break;
case GIMP_INDEXED: case GIMP_INDEXED:
{ if (gimp_item_is_text_layer (GIMP_ITEM (layer)))
GeglBuffer *new_buffer; quantize = text_layer_dither;
gboolean has_alpha; else
quantize = TRUE;
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);
}
break; break;
default: default:
break; 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 */ /* Set the final palette on the image */

View File

@ -30,6 +30,7 @@ gboolean gimp_image_convert_type (GimpImage *image,
gint num_cols, gint num_cols,
GimpConvertDitherType dither, GimpConvertDitherType dither,
gboolean alpha_dither, gboolean alpha_dither,
gboolean text_layer_dither,
gboolean remove_dups, gboolean remove_dups,
GimpConvertPaletteType palette_type, GimpConvertPaletteType palette_type,
GimpPalette *custom_palette, GimpPalette *custom_palette,

View File

@ -653,6 +653,22 @@ gimp_image_undo_push_text_layer_modified (GimpImage *image,
NULL); 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 */ /* Layer Mask Undos */

View File

@ -158,6 +158,9 @@ GimpUndo * gimp_image_undo_push_text_layer (GimpImage *image,
GimpUndo * gimp_image_undo_push_text_layer_modified (GimpImage *image, GimpUndo * gimp_image_undo_push_text_layer_modified (GimpImage *image,
const gchar *undo_desc, const gchar *undo_desc,
GimpTextLayer *layer); GimpTextLayer *layer);
GimpUndo * gimp_image_undo_push_text_layer_convert (GimpImage *image,
const gchar *undo_desc,
GimpTextLayer *layer);
/* layer mask undos */ /* layer mask undos */

View File

@ -54,6 +54,7 @@ typedef struct
GimpPrecision precision; GimpPrecision precision;
gint layer_dither_type; gint layer_dither_type;
gint text_layer_dither_type;
gint mask_dither_type; gint mask_dither_type;
} ConvertDialog; } ConvertDialog;
@ -66,8 +67,9 @@ static void convert_precision_dialog_free (ConvertDialog *dialog);
/* defaults */ /* defaults */
static gint saved_layer_dither_type = 0; static gint saved_layer_dither_type = 0;
static gint saved_mask_dither_type = 0; static gint saved_text_layer_dither_type = 0;
static gint saved_mask_dither_type = 0;
/* public functions */ /* public functions */
@ -99,11 +101,12 @@ convert_precision_dialog_new (GimpImage *image,
dialog = g_slice_new0 (ConvertDialog); dialog = g_slice_new0 (ConvertDialog);
dialog->image = image; dialog->image = image;
dialog->precision = precision; dialog->precision = precision;
dialog->progress = progress; dialog->progress = progress;
dialog->layer_dither_type = saved_layer_dither_type; dialog->layer_dither_type = saved_layer_dither_type;
dialog->mask_dither_type = saved_mask_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, gimp_enum_get_value (GIMP_TYPE_PRECISION, precision,
NULL, NULL, &enum_desc, NULL); NULL, NULL, &enum_desc, NULL);
@ -190,7 +193,33 @@ convert_precision_dialog_new (GimpImage *image,
G_CALLBACK (gimp_int_combo_box_get_active), G_CALLBACK (gimp_int_combo_box_get_active),
&dialog->layer_dither_type); &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); hbox = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 6);
gtk_box_pack_start (GTK_BOX (vbox), hbox, FALSE, FALSE, 0); 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, gimp_image_convert_precision (dialog->image,
dialog->precision, dialog->precision,
dialog->layer_dither_type, dialog->layer_dither_type,
dialog->text_layer_dither_type,
dialog->mask_dither_type, dialog->mask_dither_type,
progress); progress);

View File

@ -56,6 +56,7 @@ typedef struct
GimpConvertDitherType dither_type; GimpConvertDitherType dither_type;
gboolean alpha_dither; gboolean alpha_dither;
gboolean text_layer_dither;
gboolean remove_dups; gboolean remove_dups;
gint num_colors; gint num_colors;
GimpConvertPaletteType palette_type; GimpConvertPaletteType palette_type;
@ -76,12 +77,13 @@ static void convert_dialog_free (IndexedDialog *dialog);
/* defaults */ /* defaults */
static GimpConvertDitherType saved_dither_type = GIMP_NO_DITHER; static GimpConvertDitherType saved_dither_type = GIMP_NO_DITHER;
static gboolean saved_alpha_dither = FALSE; static gboolean saved_alpha_dither = FALSE;
static gboolean saved_remove_dups = TRUE; static gboolean saved_text_layer_dither = FALSE;
static gint saved_num_colors = 256; static gboolean saved_remove_dups = TRUE;
static GimpConvertPaletteType saved_palette_type = GIMP_MAKE_PALETTE; static gint saved_num_colors = 256;
static GimpPalette *saved_palette = NULL; static GimpConvertPaletteType saved_palette_type = GIMP_MAKE_PALETTE;
static GimpPalette *saved_palette = NULL;
/* public functions */ /* public functions */
@ -112,13 +114,14 @@ convert_type_dialog_new (GimpImage *image,
dialog = g_slice_new0 (IndexedDialog); dialog = g_slice_new0 (IndexedDialog);
dialog->image = image; dialog->image = image;
dialog->progress = progress; dialog->progress = progress;
dialog->dither_type = saved_dither_type; dialog->dither_type = saved_dither_type;
dialog->alpha_dither = saved_alpha_dither; dialog->alpha_dither = saved_alpha_dither;
dialog->remove_dups = saved_remove_dups; dialog->text_layer_dither = saved_text_layer_dither;
dialog->num_colors = saved_num_colors; dialog->remove_dups = saved_remove_dups;
dialog->palette_type = saved_palette_type; dialog->num_colors = saved_num_colors;
dialog->palette_type = saved_palette_type;
dialog->dialog = dialog->dialog =
gimp_viewable_dialog_new (GIMP_VIEWABLE (image), context, gimp_viewable_dialog_new (GIMP_VIEWABLE (image), context,
@ -268,6 +271,22 @@ convert_type_dialog_new (GimpImage *image,
G_CALLBACK (gimp_toggle_button_update), G_CALLBACK (gimp_toggle_button_update),
&dialog->alpha_dither); &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; return dialog->dialog;
} }
@ -293,6 +312,7 @@ convert_dialog_response (GtkWidget *widget,
dialog->num_colors, dialog->num_colors,
dialog->dither_type, dialog->dither_type,
dialog->alpha_dither, dialog->alpha_dither,
dialog->text_layer_dither,
dialog->remove_dups, dialog->remove_dups,
dialog->palette_type, dialog->palette_type,
dialog->custom_palette, dialog->custom_palette,
@ -314,12 +334,13 @@ convert_dialog_response (GtkWidget *widget,
gimp_image_flush (dialog->image); gimp_image_flush (dialog->image);
/* Save defaults for next time */ /* Save defaults for next time */
saved_dither_type = dialog->dither_type; saved_dither_type = dialog->dither_type;
saved_alpha_dither = dialog->alpha_dither; saved_alpha_dither = dialog->alpha_dither;
saved_remove_dups = dialog->remove_dups; saved_text_layer_dither = dialog->text_layer_dither;
saved_num_colors = dialog->num_colors; saved_remove_dups = dialog->remove_dups;
saved_palette_type = dialog->palette_type; saved_num_colors = dialog->num_colors;
saved_palette = dialog->custom_palette; saved_palette_type = dialog->palette_type;
saved_palette = dialog->custom_palette;
} }
gtk_widget_destroy (dialog->dialog); gtk_widget_destroy (dialog->dialog);

View File

@ -64,7 +64,7 @@ image_convert_rgb_invoker (GimpProcedure *procedure,
if (gimp_pdb_image_is_not_base_type (image, GIMP_RGB, error)) if (gimp_pdb_image_is_not_base_type (image, GIMP_RGB, error))
{ {
success = gimp_image_convert_type (image, GIMP_RGB, success = gimp_image_convert_type (image, GIMP_RGB,
0, 0, FALSE, FALSE, 0, NULL, 0, 0, FALSE, FALSE, FALSE, 0, NULL,
NULL, error); NULL, error);
} }
else else
@ -95,7 +95,7 @@ image_convert_grayscale_invoker (GimpProcedure *procedure,
if (gimp_pdb_image_is_not_base_type (image, GIMP_GRAY, error)) if (gimp_pdb_image_is_not_base_type (image, GIMP_GRAY, error))
{ {
success = gimp_image_convert_type (image, GIMP_GRAY, success = gimp_image_convert_type (image, GIMP_GRAY,
0, 0, FALSE, FALSE, 0, NULL, 0, 0, FALSE, FALSE, FALSE, 0, NULL,
NULL, error); NULL, error);
} }
else else
@ -177,7 +177,7 @@ image_convert_indexed_invoker (GimpProcedure *procedure,
if (success) if (success)
success = gimp_image_convert_type (image, GIMP_INDEXED, success = gimp_image_convert_type (image, GIMP_INDEXED,
num_cols, dither_type, num_cols, dither_type,
alpha_dither, remove_unused, alpha_dither, FALSE, remove_unused,
palette_type, pal, palette_type, pal,
NULL, error); NULL, error);
} }
@ -247,7 +247,7 @@ image_convert_precision_invoker (GimpProcedure *procedure,
if (gimp_pdb_image_is_not_base_type (image, GIMP_INDEXED, error) && if (gimp_pdb_image_is_not_base_type (image, GIMP_INDEXED, error) &&
gimp_pdb_image_is_not_precision (image, precision, 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 else
{ {

View File

@ -33,6 +33,7 @@
#include "text-types.h" #include "text-types.h"
#include "gegl/gimp-babl.h"
#include "gegl/gimp-gegl-utils.h" #include "gegl/gimp-gegl-utils.h"
#include "core/gimp.h" #include "core/gimp.h"
@ -63,44 +64,52 @@ enum
}; };
static void gimp_text_layer_finalize (GObject *object); static void gimp_text_layer_finalize (GObject *object);
static void gimp_text_layer_get_property (GObject *object, static void gimp_text_layer_get_property (GObject *object,
guint property_id, guint property_id,
GValue *value, GValue *value,
GParamSpec *pspec); GParamSpec *pspec);
static void gimp_text_layer_set_property (GObject *object, static void gimp_text_layer_set_property (GObject *object,
guint property_id, guint property_id,
const GValue *value, const GValue *value,
GParamSpec *pspec); GParamSpec *pspec);
static gint64 gimp_text_layer_get_memsize (GimpObject *object, static gint64 gimp_text_layer_get_memsize (GimpObject *object,
gint64 *gui_size); gint64 *gui_size);
static GimpItem * gimp_text_layer_duplicate (GimpItem *item, static GimpItem * gimp_text_layer_duplicate (GimpItem *item,
GType new_type); GType new_type);
static gboolean gimp_text_layer_rename (GimpItem *item, static gboolean gimp_text_layer_rename (GimpItem *item,
const gchar *new_name, const gchar *new_name,
const gchar *undo_desc, const gchar *undo_desc,
GError **error); GError **error);
static void gimp_text_layer_set_buffer (GimpDrawable *drawable, static void gimp_text_layer_convert_type (GimpDrawable *drawable,
gboolean push_undo, GimpImage *dest_image,
const gchar *undo_desc, const Babl *new_format,
GeglBuffer *buffer, GimpImageBaseType new_base_type,
gint offset_x, GimpPrecision new_precision,
gint offset_y); gint layer_dither_type,
static void gimp_text_layer_push_undo (GimpDrawable *drawable, gint mask_dither_type,
const gchar *undo_desc, gboolean push_undo);
GeglBuffer *buffer, static void gimp_text_layer_set_buffer (GimpDrawable *drawable,
gint x, gboolean push_undo,
gint y, const gchar *undo_desc,
gint width, GeglBuffer *buffer,
gint height); 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 void gimp_text_layer_text_changed (GimpTextLayer *layer);
static gboolean gimp_text_layer_render (GimpTextLayer *layer); static gboolean gimp_text_layer_render (GimpTextLayer *layer);
static void gimp_text_layer_render_layout (GimpTextLayer *layer, static void gimp_text_layer_render_layout (GimpTextLayer *layer,
GimpTextLayout *layout); GimpTextLayout *layout);
G_DEFINE_TYPE (GimpTextLayer, gimp_text_layer, GIMP_TYPE_LAYER) 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->rotate_desc = _("Rotate Text Layer");
item_class->transform_desc = _("Transform 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->set_buffer = gimp_text_layer_set_buffer;
drawable_class->push_undo = gimp_text_layer_push_undo; drawable_class->push_undo = gimp_text_layer_push_undo;
@ -300,6 +310,42 @@ gimp_text_layer_rename (GimpItem *item,
return FALSE; 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 static void
gimp_text_layer_set_buffer (GimpDrawable *drawable, gimp_text_layer_set_buffer (GimpDrawable *drawable,
gboolean push_undo, gboolean push_undo,
@ -529,6 +575,15 @@ gimp_item_is_text_layer (GimpItem *item)
/* private functions */ /* 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 static void
gimp_text_layer_text_changed (GimpTextLayer *layer) 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) && if (gimp_text_layout_get_size (layout, &width, &height) &&
(width != gimp_item_get_width (item) || (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; GeglBuffer *new_buffer;
new_buffer = gegl_buffer_new (GEGL_RECTANGLE (0, 0, width, height), 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); gimp_drawable_set_buffer (drawable, FALSE, NULL, new_buffer);
g_object_unref (new_buffer); g_object_unref (new_buffer);

View File

@ -46,6 +46,8 @@ struct _GimpTextLayer
*/ */
gboolean auto_rename; gboolean auto_rename;
gboolean modified; gboolean modified;
const Babl *convert_format;
}; };
struct _GimpTextLayerClass struct _GimpTextLayerClass

View File

@ -23,6 +23,8 @@
#include "text-types.h" #include "text-types.h"
#include "gegl/gimp-babl.h"
#include "core/gimpitem.h" #include "core/gimpitem.h"
#include "core/gimpitemundo.h" #include "core/gimpitemundo.h"
#include "core/gimp-utils.h" #include "core/gimp-utils.h"
@ -128,6 +130,10 @@ gimp_text_undo_constructed (GObject *object)
text_undo->modified = layer->modified; text_undo->modified = layer->modified;
break; break;
case GIMP_UNDO_TEXT_LAYER_CONVERT:
text_undo->format = gimp_drawable_get_format (GIMP_DRAWABLE (layer));
break;
default: default:
g_assert_not_reached (); g_assert_not_reached ();
} }
@ -258,6 +264,20 @@ gimp_text_undo_pop (GimpUndo *undo,
} }
break; 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: default:
g_assert_not_reached (); g_assert_not_reached ();
} }

View File

@ -40,6 +40,7 @@ struct _GimpTextUndo
const GParamSpec *pspec; const GParamSpec *pspec;
GValue *value; GValue *value;
gboolean modified; gboolean modified;
const Babl *format;
}; };
struct _GimpTextUndoClass struct _GimpTextUndoClass

View File

@ -38,7 +38,7 @@ HELP
if (gimp_pdb_image_is_not_base_type (image, GIMP_RGB, error)) if (gimp_pdb_image_is_not_base_type (image, GIMP_RGB, error))
{ {
success = gimp_image_convert_type (image, GIMP_RGB, success = gimp_image_convert_type (image, GIMP_RGB,
0, 0, FALSE, FALSE, 0, NULL, 0, 0, FALSE, FALSE, FALSE, 0, NULL,
NULL, error); NULL, error);
} }
else else
@ -72,7 +72,7 @@ HELP
if (gimp_pdb_image_is_not_base_type (image, GIMP_GRAY, error)) if (gimp_pdb_image_is_not_base_type (image, GIMP_GRAY, error))
{ {
success = gimp_image_convert_type (image, GIMP_GRAY, success = gimp_image_convert_type (image, GIMP_GRAY,
0, 0, FALSE, FALSE, 0, NULL, 0, 0, FALSE, FALSE, FALSE, 0, NULL,
NULL, error); NULL, error);
} }
else else
@ -170,7 +170,7 @@ HELP
if (success) if (success)
success = gimp_image_convert_type (image, GIMP_INDEXED, success = gimp_image_convert_type (image, GIMP_INDEXED,
num_cols, dither_type, num_cols, dither_type,
alpha_dither, remove_unused, alpha_dither, FALSE, remove_unused,
palette_type, pal, palette_type, pal,
NULL, error); NULL, error);
} }
@ -246,7 +246,7 @@ HELP
if (gimp_pdb_image_is_not_base_type (image, GIMP_INDEXED, error) && if (gimp_pdb_image_is_not_base_type (image, GIMP_INDEXED, error) &&
gimp_pdb_image_is_not_precision (image, precision, 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 else
{ {