[gimp] Bug 352823 - Changing image mode discards text layer information



commit a7223bbd2daf9ef56f25feef640b593b7f42136c
Author: Michael Natterer <mitch gimp org>
Date:   Sat Nov 10 18:56:44 2012 +0100

    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      |   62 +++++++++------
 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               |  137 ++++++++++++++++++++++---------
 app/text/gimptextlayer.h               |    2 +
 app/text/gimptextundo.c                |   20 +++++
 app/text/gimptextundo.h                |    1 +
 tools/pdbgen/pdb/convert.pdb           |    8 +-
 17 files changed, 280 insertions(+), 102 deletions(-)
---
diff --git a/app/actions/image-commands.c b/app/actions/image-commands.c
index e792198..3aead0a 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 fc0d650..1065058 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 8bbba37..d49ff76 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 327d75c..9e70a2d 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 617eea8..13140b3 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 e7d814e..319d294 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,43 +973,54 @@ 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;
+          if (gimp_item_is_text_layer (GIMP_ITEM (layer)))
+            quantize = text_layer_dither;
+          else
+            quantize = TRUE;
+          break;
+
+        default:
+          break;
+        }
 
-            has_alpha = gimp_drawable_has_alpha (GIMP_DRAWABLE (layer));
+      if (quantize)
+        {
+          GeglBuffer *new_buffer;
+          gboolean    has_alpha;
 
-            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));
+          has_alpha = gimp_drawable_has_alpha (GIMP_DRAWABLE (layer));
 
-            quantobj->nth_layer = nth_layer;
-            quantobj->second_pass (quantobj, layer, new_buffer);
+          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));
 
-            gimp_drawable_set_buffer (GIMP_DRAWABLE (layer), TRUE, NULL,
-                                      new_buffer);
-            g_object_unref (new_buffer);
-          }
-          break;
+          quantobj->nth_layer = nth_layer;
+          quantobj->second_pass (quantobj, layer, new_buffer);
 
-        default:
-          break;
+          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);
         }
     }
 
diff --git a/app/core/gimpimage-convert-type.h b/app/core/gimpimage-convert-type.h
index 893fcbc..69d4c2d 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 c226924..2440172 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 eb97208..6680c68 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 ade1817..1849099 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 20982b9..6c93b0a 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 93da3cd..24b4f91 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 a551b35..0a7cd55 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 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 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_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 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_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);
 
 
 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;
 
@@ -301,6 +311,42 @@ gimp_text_layer_rename (GimpItem     *item,
 }
 
 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,
                             const gchar  *undo_desc,
@@ -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 6d6e504..5b33193 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 934860b..efcbe6f 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 244c9b6..d81d962 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 116a82e..2e84f6f 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
     {



[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]