[gimp] app: add GimpItem::fill() which fills what is outlined by ::stroke()



commit ff1c67805800388ba29942a1786139ad39b104a1
Author: Michael Natterer <mitch gimp org>
Date:   Mon Mar 14 19:02:18 2016 +0100

    app: add GimpItem::fill() which fills what is outlined by ::stroke()
    
    For selections, it's different from gimp_edit_fill() because it
    ignores the selection while filling, just as stroking does. Currently
    unused, stay tuned...

 app/core/gimpchannel.c    |   46 ++++++++++++++++++++++++++++++++++++++++++++-
 app/core/gimpitem.c       |   42 +++++++++++++++++++++++++++++++++++++++++
 app/core/gimpitem.h       |   13 ++++++++++++
 app/core/gimpselection.c  |   44 +++++++++++++++++++++++++++++++++++++++++++
 app/vectors/gimpvectors.c |   33 ++++++++++++++++++++++++++++++-
 5 files changed, 175 insertions(+), 3 deletions(-)
---
diff --git a/app/core/gimpchannel.c b/app/core/gimpchannel.c
index 5e4a8bc..9da77e8 100644
--- a/app/core/gimpchannel.c
+++ b/app/core/gimpchannel.c
@@ -47,6 +47,7 @@
 #include "gimpchannel.h"
 #include "gimpchannel-select.h"
 #include "gimpcontext.h"
+#include "gimpdrawable-fill.h"
 #include "gimpdrawable-stroke.h"
 #include "gimpmarshal.h"
 #include "gimppaintinfo.h"
@@ -122,6 +123,12 @@ static void       gimp_channel_transform     (GimpItem          *item,
                                               GimpInterpolationType interpolation_type,
                                               GimpTransformResize clip_result,
                                               GimpProgress      *progress);
+static gboolean   gimp_channel_fill          (GimpItem          *item,
+                                              GimpDrawable      *drawable,
+                                              GimpFillOptions   *fill_options,
+                                              gboolean           push_undo,
+                                              GimpProgress      *progress,
+                                              GError           **error);
 static gboolean   gimp_channel_stroke        (GimpItem          *item,
                                               GimpDrawable      *drawable,
                                               GimpStrokeOptions *stroke_options,
@@ -276,6 +283,7 @@ gimp_channel_class_init (GimpChannelClass *klass)
   item_class->flip                 = gimp_channel_flip;
   item_class->rotate               = gimp_channel_rotate;
   item_class->transform            = gimp_channel_transform;
+  item_class->fill                 = gimp_channel_fill;
   item_class->stroke               = gimp_channel_stroke;
   item_class->to_selection         = gimp_channel_to_selection;
   item_class->default_name         = _("Channel");
@@ -286,6 +294,7 @@ gimp_channel_class_init (GimpChannelClass *klass)
   item_class->flip_desc            = C_("undo-type", "Flip Channel");
   item_class->rotate_desc          = C_("undo-type", "Rotate Channel");
   item_class->transform_desc       = C_("undo-type", "Transform Channel");
+  item_class->fill_desc            = C_("undo-type", "Fill Channel");
   item_class->stroke_desc          = C_("undo-type", "Stroke Channel");
   item_class->to_selection_desc    = C_("undo-type", "Channel to Selection");
   item_class->reorder_desc         = C_("undo-type", "Reorder Channel");
@@ -805,6 +814,41 @@ gimp_channel_transform (GimpItem               *item,
 }
 
 static gboolean
+gimp_channel_fill (GimpItem         *item,
+                   GimpDrawable     *drawable,
+                   GimpFillOptions  *fill_options,
+                   gboolean          push_undo,
+                   GimpProgress     *progress,
+                   GError          **error)
+{
+  GimpChannel        *channel = GIMP_CHANNEL (item);
+  const GimpBoundSeg *segs_in;
+  const GimpBoundSeg *segs_out;
+  gint                n_segs_in;
+  gint                n_segs_out;
+  gint                offset_x, offset_y;
+
+  if (! gimp_channel_boundary (channel, &segs_in, &segs_out,
+                               &n_segs_in, &n_segs_out,
+                               0, 0, 0, 0))
+    {
+      g_set_error_literal (error, GIMP_ERROR, GIMP_FAILED,
+                          _("Cannot fill empty channel."));
+      return FALSE;
+    }
+
+  gimp_item_get_offset (item, &offset_x, &offset_y);
+
+  gimp_drawable_fill_boundary (drawable,
+                               fill_options,
+                               segs_in, n_segs_in,
+                               offset_x, offset_y,
+                               push_undo);
+
+  return TRUE;
+}
+
+static gboolean
 gimp_channel_stroke (GimpItem           *item,
                      GimpDrawable       *drawable,
                      GimpStrokeOptions  *stroke_options,
@@ -829,7 +873,7 @@ gimp_channel_stroke (GimpItem           *item,
       return FALSE;
     }
 
-  gimp_item_get_offset (GIMP_ITEM (channel), &offset_x, &offset_y);
+  gimp_item_get_offset (item, &offset_x, &offset_y);
 
   switch (gimp_stroke_options_get_method (stroke_options))
     {
diff --git a/app/core/gimpitem.c b/app/core/gimpitem.c
index cd0a24d..56fd475 100644
--- a/app/core/gimpitem.c
+++ b/app/core/gimpitem.c
@@ -248,6 +248,7 @@ gimp_item_class_init (GimpItemClass *klass)
   klass->flip                      = NULL;
   klass->rotate                    = NULL;
   klass->transform                 = NULL;
+  klass->fill                      = NULL;
   klass->stroke                    = NULL;
   klass->to_selection              = NULL;
 
@@ -259,6 +260,8 @@ gimp_item_class_init (GimpItemClass *klass)
   klass->flip_desc                 = NULL;
   klass->rotate_desc               = NULL;
   klass->transform_desc            = NULL;
+  klass->fill_desc                 = NULL;
+  klass->stroke_desc               = NULL;
 
   g_object_class_install_property (object_class, PROP_IMAGE,
                                    g_param_spec_object ("image", NULL, NULL,
@@ -1564,6 +1567,45 @@ gimp_item_transform (GimpItem               *item,
 }
 
 gboolean
+gimp_item_fill (GimpItem        *item,
+                GimpDrawable    *drawable,
+                GimpFillOptions *fill_options,
+                gboolean         push_undo,
+                GimpProgress    *progress,
+                GError         **error)
+{
+  GimpItemClass *item_class;
+  gboolean       retval = FALSE;
+
+  g_return_val_if_fail (GIMP_IS_ITEM (item), FALSE);
+  g_return_val_if_fail (gimp_item_is_attached (item), FALSE);
+  g_return_val_if_fail (GIMP_IS_DRAWABLE (drawable), FALSE);
+  g_return_val_if_fail (gimp_item_is_attached (GIMP_ITEM (drawable)), FALSE);
+  g_return_val_if_fail (GIMP_IS_FILL_OPTIONS (fill_options), FALSE);
+  g_return_val_if_fail (progress == NULL || GIMP_IS_PROGRESS (progress), FALSE);
+  g_return_val_if_fail (error == NULL || *error == NULL, FALSE);
+
+  item_class = GIMP_ITEM_GET_CLASS (item);
+
+  if (item_class->fill)
+    {
+      GimpImage *image = gimp_item_get_image (item);
+
+      if (push_undo)
+        gimp_image_undo_group_start (image, GIMP_UNDO_GROUP_PAINT,
+                                     item_class->fill_desc);
+
+      retval = item_class->fill (item, drawable, fill_options, push_undo,
+                                 progress, error);
+
+      if (push_undo)
+        gimp_image_undo_group_end (image);
+    }
+
+  return retval;
+}
+
+gboolean
 gimp_item_stroke (GimpItem          *item,
                   GimpDrawable      *drawable,
                   GimpContext       *context,
diff --git a/app/core/gimpitem.h b/app/core/gimpitem.h
index 844b321..3f9fc33 100644
--- a/app/core/gimpitem.h
+++ b/app/core/gimpitem.h
@@ -103,6 +103,12 @@ struct _GimpItemClass
                                           GimpInterpolationType   interpolation_type,
                                           GimpTransformResize     clip_result,
                                           GimpProgress           *progress);
+  gboolean        (* fill)               (GimpItem               *item,
+                                          GimpDrawable           *drawable,
+                                          GimpFillOptions        *fill_options,
+                                          gboolean                push_undo,
+                                          GimpProgress           *progress,
+                                          GError                **error);
   gboolean        (* stroke)             (GimpItem               *item,
                                           GimpDrawable           *drawable,
                                           GimpStrokeOptions      *stroke_options,
@@ -125,6 +131,7 @@ struct _GimpItemClass
   const gchar *rotate_desc;
   const gchar *transform_desc;
   const gchar *to_selection_desc;
+  const gchar *fill_desc;
   const gchar *stroke_desc;
 
   const gchar *reorder_desc;
@@ -251,6 +258,12 @@ void            gimp_item_transform          (GimpItem           *item,
                                               GimpTransformResize clip_result,
                                               GimpProgress       *progress);
 
+gboolean        gimp_item_fill               (GimpItem           *item,
+                                              GimpDrawable       *drawable,
+                                              GimpFillOptions    *fill_options,
+                                              gboolean            push_undo,
+                                              GimpProgress       *progress,
+                                              GError            **error);
 gboolean        gimp_item_stroke             (GimpItem           *item,
                                               GimpDrawable       *drawable,
                                               GimpContext        *context,
diff --git a/app/core/gimpselection.c b/app/core/gimpselection.c
index 0ae9a68..9c773cc 100644
--- a/app/core/gimpselection.c
+++ b/app/core/gimpselection.c
@@ -75,6 +75,12 @@ static void       gimp_selection_rotate        (GimpItem            *item,
                                                 gdouble              center_x,
                                                 gdouble              center_y,
                                                 gboolean             clip_result);
+static gboolean   gimp_selection_fill          (GimpItem            *item,
+                                                GimpDrawable        *drawable,
+                                                GimpFillOptions     *fill_options,
+                                                gboolean             push_undo,
+                                                GimpProgress        *progress,
+                                                GError             **error);
 static gboolean   gimp_selection_stroke        (GimpItem            *item,
                                                 GimpDrawable        *drawable,
                                                 GimpStrokeOptions   *stroke_options,
@@ -157,9 +163,11 @@ gimp_selection_class_init (GimpSelectionClass *klass)
   item_class->resize                  = gimp_selection_resize;
   item_class->flip                    = gimp_selection_flip;
   item_class->rotate                  = gimp_selection_rotate;
+  item_class->fill                    = gimp_selection_fill;
   item_class->stroke                  = gimp_selection_stroke;
   item_class->default_name            = _("Selection Mask");
   item_class->translate_desc          = C_("undo-type", "Move Selection");
+  item_class->fill_desc               = C_("undo-type", "Fill Selection");
   item_class->stroke_desc             = C_("undo-type", "Stroke Selection");
 
   drawable_class->convert_type        = gimp_selection_convert_type;
@@ -271,6 +279,42 @@ gimp_selection_rotate (GimpItem         *item,
 }
 
 static gboolean
+gimp_selection_fill (GimpItem         *item,
+                     GimpDrawable     *drawable,
+                     GimpFillOptions  *fill_options,
+                     gboolean          push_undo,
+                     GimpProgress     *progress,
+                     GError          **error)
+{
+  GimpSelection      *selection = GIMP_SELECTION (item);
+  const GimpBoundSeg *dummy_in;
+  const GimpBoundSeg *dummy_out;
+  gint                num_dummy_in;
+  gint                num_dummy_out;
+  gboolean            retval;
+
+  if (! gimp_channel_boundary (GIMP_CHANNEL (selection),
+                               &dummy_in, &dummy_out,
+                               &num_dummy_in, &num_dummy_out,
+                               0, 0, 0, 0))
+    {
+      g_set_error_literal (error, GIMP_ERROR, GIMP_FAILED,
+                          _("There is no selection to fill."));
+      return FALSE;
+    }
+
+  gimp_selection_suspend (selection);
+
+  retval = GIMP_ITEM_CLASS (parent_class)->fill (item, drawable,
+                                                 fill_options,
+                                                 push_undo, progress, error);
+
+  gimp_selection_resume (selection);
+
+  return retval;
+}
+
+static gboolean
 gimp_selection_stroke (GimpItem           *item,
                        GimpDrawable       *drawable,
                        GimpStrokeOptions  *stroke_options,
diff --git a/app/vectors/gimpvectors.c b/app/vectors/gimpvectors.c
index b2841a5..95fddcd 100644
--- a/app/vectors/gimpvectors.c
+++ b/app/vectors/gimpvectors.c
@@ -35,6 +35,7 @@
 #include "core/gimpchannel-select.h"
 #include "core/gimpcontainer.h"
 #include "core/gimpcontext.h"
+#include "core/gimpdrawable-fill.h"
 #include "core/gimpdrawable-stroke.h"
 #include "core/gimperror.h"
 #include "core/gimpimage.h"
@@ -114,6 +115,12 @@ static void       gimp_vectors_transform     (GimpItem          *item,
                                               GimpInterpolationType interp_type,
                                               GimpTransformResize   clip_result,
                                               GimpProgress      *progress);
+static gboolean   gimp_vectors_fill          (GimpItem          *item,
+                                              GimpDrawable      *drawable,
+                                              GimpFillOptions   *fill_options,
+                                              gboolean           push_undo,
+                                              GimpProgress      *progress,
+                                              GError           **error);
 static gboolean   gimp_vectors_stroke        (GimpItem          *item,
                                               GimpDrawable      *drawable,
                                               GimpStrokeOptions *stroke_options,
@@ -209,6 +216,7 @@ gimp_vectors_class_init (GimpVectorsClass *klass)
   item_class->flip                  = gimp_vectors_flip;
   item_class->rotate                = gimp_vectors_rotate;
   item_class->transform             = gimp_vectors_transform;
+  item_class->fill                  = gimp_vectors_fill;
   item_class->stroke                = gimp_vectors_stroke;
   item_class->to_selection          = gimp_vectors_to_selection;
   item_class->default_name          = _("Path");
@@ -219,6 +227,7 @@ gimp_vectors_class_init (GimpVectorsClass *klass)
   item_class->flip_desc             = C_("undo-type", "Flip Path");
   item_class->rotate_desc           = C_("undo-type", "Rotate Path");
   item_class->transform_desc        = C_("undo-type", "Transform Path");
+  item_class->fill_desc             = C_("undo-type", "Fill Path");
   item_class->stroke_desc           = C_("undo-type", "Stroke Path");
   item_class->to_selection_desc     = C_("undo-type", "Path to Selection");
   item_class->reorder_desc          = C_("undo-type", "Reorder Path");
@@ -620,6 +629,27 @@ gimp_vectors_transform (GimpItem               *item,
 }
 
 static gboolean
+gimp_vectors_fill (GimpItem         *item,
+                   GimpDrawable     *drawable,
+                   GimpFillOptions  *fill_options,
+                   gboolean          push_undo,
+                   GimpProgress     *progress,
+                   GError          **error)
+{
+  GimpVectors *vectors = GIMP_VECTORS (item);
+
+  if (g_queue_is_empty (vectors->strokes))
+    {
+      g_set_error_literal (error, GIMP_ERROR, GIMP_FAILED,
+                           _("Not enough points to fill"));
+      return FALSE;
+    }
+
+  return gimp_drawable_fill_vectors (drawable, fill_options,
+                                     vectors, push_undo, error);
+}
+
+static gboolean
 gimp_vectors_stroke (GimpItem           *item,
                      GimpDrawable       *drawable,
                      GimpStrokeOptions  *stroke_options,
@@ -640,8 +670,7 @@ gimp_vectors_stroke (GimpItem           *item,
   switch (gimp_stroke_options_get_method (stroke_options))
     {
     case GIMP_STROKE_LINE:
-      retval = gimp_drawable_stroke_vectors (drawable,
-                                             stroke_options,
+      retval = gimp_drawable_stroke_vectors (drawable, stroke_options,
                                              vectors, push_undo, error);
       break;
 


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