[gimp] Bug 344684 - Greyscale (no alpha) clipboard brushes are of the wrong type



commit bcc3437f5f197d0ae4b359f44ba27199a7ac22d5
Author: Michael Natterer <mitch gimp org>
Date:   Wed Apr 19 17:33:44 2017 -0300

    Bug 344684 - Greyscale (no alpha) clipboard brushes are of the wrong type
    
    Add a "mask-only" property to GimpBrushClipboard. When TRUE, only
    create a brush mask (not a pixmap brush with mask and image).
    
    Keep two clipboard brushes around: one classic "Clipboard Image" one
    to be used as "stamp", and one new "Clipboard Mask" one that turns the
    clipboard into a brush mask.

 app/core/gimp-data-factories.c  |   29 ++++++-----
 app/core/gimpbrushclipboard.c   |  103 ++++++++++++++++++++++++++++-----------
 app/core/gimpbrushclipboard.h   |    4 +-
 app/core/gimppatternclipboard.c |    2 +-
 4 files changed, 95 insertions(+), 43 deletions(-)
---
diff --git a/app/core/gimp-data-factories.c b/app/core/gimp-data-factories.c
index 6adf49f..784906e 100644
--- a/app/core/gimp-data-factories.c
+++ b/app/core/gimp-data-factories.c
@@ -187,8 +187,7 @@ gimp_data_factories_init (Gimp *gimp)
 void
 gimp_data_factories_add_builtin (Gimp *gimp)
 {
-  GimpData *clipboard_brush;
-  GimpData *clipboard_pattern;
+  GimpData *data;
 
   g_return_if_fail (GIMP_IS_GIMP (gimp));
 
@@ -198,21 +197,25 @@ gimp_data_factories_add_builtin (Gimp *gimp)
   /*  add the color history palette  */
   gimp_palettes_init (gimp);
 
-  /*  add the clipboard brush  */
-  clipboard_brush = gimp_brush_clipboard_new (gimp);
-  gimp_data_make_internal (GIMP_DATA (clipboard_brush),
-                           "gimp-brush-clipboard");
+  /*  add the clipboard brushes  */
+  data = gimp_brush_clipboard_new (gimp, FALSE);
+  gimp_data_make_internal (data, "gimp-brush-clipboard-image");
   gimp_container_add (gimp_data_factory_get_container (gimp->brush_factory),
-                      GIMP_OBJECT (clipboard_brush));
-  g_object_unref (clipboard_brush);
+                      GIMP_OBJECT (data));
+  g_object_unref (data);
+
+  data = gimp_brush_clipboard_new (gimp, TRUE);
+  gimp_data_make_internal (data, "gimp-brush-clipboard-mask");
+  gimp_container_add (gimp_data_factory_get_container (gimp->brush_factory),
+                      GIMP_OBJECT (data));
+  g_object_unref (data);
 
   /*  add the clipboard pattern  */
-  clipboard_pattern = gimp_pattern_clipboard_new (gimp);
-  gimp_data_make_internal (GIMP_DATA (clipboard_pattern),
-                           "gimp-pattern-clipboard");
+  data = gimp_pattern_clipboard_new (gimp);
+  gimp_data_make_internal (data, "gimp-pattern-clipboard-image");
   gimp_container_add (gimp_data_factory_get_container (gimp->pattern_factory),
-                      GIMP_OBJECT (clipboard_pattern));
-  g_object_unref (clipboard_pattern);
+                      GIMP_OBJECT (data));
+  g_object_unref (data);
 }
 
 void
diff --git a/app/core/gimpbrushclipboard.c b/app/core/gimpbrushclipboard.c
index 3f9df75..7fc3c3e 100644
--- a/app/core/gimpbrushclipboard.c
+++ b/app/core/gimpbrushclipboard.c
@@ -41,7 +41,8 @@
 enum
 {
   PROP_0,
-  PROP_GIMP
+  PROP_GIMP,
+  PROP_MASK_ONLY
 };
 
 
@@ -90,6 +91,12 @@ gimp_brush_clipboard_class_init (GimpBrushClipboardClass *klass)
                                                         GIMP_TYPE_GIMP,
                                                         GIMP_PARAM_READWRITE |
                                                         G_PARAM_CONSTRUCT_ONLY));
+
+  g_object_class_install_property (object_class, PROP_MASK_ONLY,
+                                   g_param_spec_boolean ("mask-only", NULL, NULL,
+                                                         FALSE,
+                                                         GIMP_PARAM_READWRITE |
+                                                         G_PARAM_CONSTRUCT_ONLY));
 }
 
 static void
@@ -126,6 +133,11 @@ gimp_brush_clipboard_set_property (GObject      *object,
     case PROP_GIMP:
       brush->gimp = g_value_get_object (value);
       break;
+
+    case PROP_MASK_ONLY:
+      brush->mask_only = g_value_get_boolean (value);
+      break;
+
     default:
       G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
       break;
@@ -145,6 +157,11 @@ gimp_brush_clipboard_get_property (GObject    *object,
     case PROP_GIMP:
       g_value_set_object (value, brush->gimp);
       break;
+
+    case PROP_MASK_ONLY:
+      g_value_set_boolean (value, brush->mask_only);
+      break;
+
     default:
       G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
       break;
@@ -162,13 +179,22 @@ gimp_brush_clipboard_duplicate (GimpData *data)
 #endif
 
 GimpData *
-gimp_brush_clipboard_new (Gimp *gimp)
+gimp_brush_clipboard_new (Gimp     *gimp,
+                          gboolean  mask_only)
 {
+  const gchar *name;
+
   g_return_val_if_fail (GIMP_IS_GIMP (gimp), NULL);
 
+  if (mask_only)
+    name = _("Clipboard Mask");
+  else
+    name = _("Clipboard Image");
+
   return g_object_new (GIMP_TYPE_BRUSH_CLIPBOARD,
-                       "name", _("Clipboard"),
-                       "gimp", gimp,
+                       "name",      name,
+                       "gimp",      gimp,
+                       "mask-only", mask_only,
                        NULL);
 }
 
@@ -211,40 +237,61 @@ gimp_brush_clipboard_changed (Gimp      *gimp,
   if (buffer)
     {
       const Babl *format = gegl_buffer_get_format (buffer);
-      GeglBuffer *dest_buffer;
 
       width  = MIN (gegl_buffer_get_width  (buffer), BRUSH_MAX_SIZE);
       height = MIN (gegl_buffer_get_height (buffer), BRUSH_MAX_SIZE);
 
-      brush->priv->mask   = gimp_temp_buf_new (width, height,
-                                               babl_format ("Y u8"));
-      brush->priv->pixmap = gimp_temp_buf_new (width, height,
-                                               babl_format ("R'G'B' u8"));
+      brush->priv->mask = gimp_temp_buf_new (width, height,
+                                             babl_format ("Y u8"));
 
-      /*  copy the alpha channel into the brush's mask  */
-      if (babl_format_has_alpha (format))
+      if (GIMP_BRUSH_CLIPBOARD (brush)->mask_only)
         {
-          dest_buffer = gimp_temp_buf_create_buffer (brush->priv->mask);
-
-          gegl_buffer_set_format (dest_buffer, babl_format ("A u8"));
-          gegl_buffer_copy (buffer, NULL, GEGL_ABYSS_NONE,
-                            dest_buffer, NULL);
-
-          g_object_unref (dest_buffer);
+          guchar *p;
+          gint    i;
+
+          gegl_buffer_get (buffer,
+                           GEGL_RECTANGLE (0, 0, width, height), 1.0,
+                           babl_format ("Y u8"),
+                           gimp_temp_buf_get_data (brush->priv->mask),
+                           GEGL_AUTO_ROWSTRIDE, GEGL_ABYSS_NONE);
+
+          /*  invert the mask, it's more intuitive to think
+           *  "black on white" than the other way around
+           */
+          for (i = 0, p = gimp_temp_buf_get_data (brush->priv->mask);
+               i < width * height;
+               i++, p++)
+            {
+              *p = 255 - *p;
+            }
         }
       else
         {
-          memset (gimp_temp_buf_get_data (brush->priv->mask), 255,
-                  width * height);
+          brush->priv->pixmap = gimp_temp_buf_new (width, height,
+                                                   babl_format ("R'G'B' u8"));
+
+          /*  copy the alpha channel into the brush's mask  */
+          if (babl_format_has_alpha (format))
+            {
+              gegl_buffer_get (buffer,
+                               GEGL_RECTANGLE (0, 0, width, height), 1.0,
+                               babl_format ("A u8"),
+                               gimp_temp_buf_get_data (brush->priv->mask),
+                               GEGL_AUTO_ROWSTRIDE, GEGL_ABYSS_NONE);
+            }
+          else
+            {
+              memset (gimp_temp_buf_get_data (brush->priv->mask), 255,
+                      width * height);
+            }
+
+          /*  copy the color channels into the brush's pixmap  */
+          gegl_buffer_get (buffer,
+                           GEGL_RECTANGLE (0, 0, width, height), 1.0,
+                           babl_format ("R'G'B' u8"),
+                           gimp_temp_buf_get_data (brush->priv->pixmap),
+                           GEGL_AUTO_ROWSTRIDE, GEGL_ABYSS_NONE);
         }
-
-      /*  copy the color channels into the brush's pixmap  */
-      dest_buffer = gimp_temp_buf_create_buffer (brush->priv->pixmap);
-
-      gegl_buffer_copy (buffer, NULL, GEGL_ABYSS_NONE,
-                        dest_buffer, NULL);
-
-      g_object_unref (dest_buffer);
     }
   else
     {
diff --git a/app/core/gimpbrushclipboard.h b/app/core/gimpbrushclipboard.h
index cd531c3..b4677c7 100644
--- a/app/core/gimpbrushclipboard.h
+++ b/app/core/gimpbrushclipboard.h
@@ -40,6 +40,7 @@ struct _GimpBrushClipboard
   GimpBrush  parent_instance;
 
   Gimp      *gimp;
+  gboolean   mask_only;
 };
 
 struct _GimpBrushClipboardClass
@@ -50,7 +51,8 @@ struct _GimpBrushClipboardClass
 
 GType      gimp_brush_clipboard_get_type (void) G_GNUC_CONST;
 
-GimpData * gimp_brush_clipboard_new      (Gimp *gimp);
+GimpData * gimp_brush_clipboard_new      (Gimp     *gimp,
+                                          gboolean  mask_only);
 
 
 #endif  /*  __GIMP_BRUSH_CLIPBOARD_H__  */
diff --git a/app/core/gimppatternclipboard.c b/app/core/gimppatternclipboard.c
index 932755a..dbdac0f 100644
--- a/app/core/gimppatternclipboard.c
+++ b/app/core/gimppatternclipboard.c
@@ -166,7 +166,7 @@ gimp_pattern_clipboard_new (Gimp *gimp)
   g_return_val_if_fail (GIMP_IS_GIMP (gimp), NULL);
 
   return g_object_new (GIMP_TYPE_PATTERN_CLIPBOARD,
-                       "name", _("Clipboard"),
+                       "name", _("Clipboard Image"),
                        "gimp", gimp,
                        NULL);
 }


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