[gimp] app: change antialias feature in fill by line art into Feather Edges.



commit d821b088e2e40c46498aca13c938700bf48e5521
Author: Jehan <jehan girinstud io>
Date:   Thu Mar 28 14:06:17 2019 +0100

    app: change antialias feature in fill by line art into Feather Edges.
    
    This was actually more of a feathering feature I added earlier, and we
    already have a function for that: gimp_gegl_apply_feather(). This is
    using a gaussian blur, just as what I was doing anyway. This commit also
    adds the "Feather Radius" scale, similar to other tools with the
    "Feather Edges". So that makes it consistent (and more useful as you can
    adapt to your needs).

 app/core/gimpdrawable-bucket-fill.c | 36 +++++++------------------
 app/core/gimpfilloptions.c          | 53 +++++++++++++++++++++++++++++++++++++
 app/core/gimpfilloptions.h          |  6 +++++
 app/tools/gimpbucketfilloptions.c   | 40 +++++++++++++++++++++++++---
 app/tools/gimpbucketfilloptions.h   |  2 ++
 app/tools/gimpbucketfilltool.c      |  4 +++
 6 files changed, 110 insertions(+), 31 deletions(-)
---
diff --git a/app/core/gimpdrawable-bucket-fill.c b/app/core/gimpdrawable-bucket-fill.c
index 2a8deaacfc..c5c3ccd367 100644
--- a/app/core/gimpdrawable-bucket-fill.c
+++ b/app/core/gimpdrawable-bucket-fill.c
@@ -338,6 +338,7 @@ gimp_drawable_get_line_art_fill_buffer (GimpDrawable     *drawable,
   gint        mask_offset_x = 0;
   gint        mask_offset_y = 0;
   gint        sel_x, sel_y, sel_width, sel_height;
+  gdouble     feather_radius;
 
   g_return_val_if_fail (GIMP_IS_DRAWABLE (drawable), NULL);
   g_return_val_if_fail (gimp_item_is_attached (GIMP_ITEM (drawable)), NULL);
@@ -452,33 +453,14 @@ gimp_drawable_get_line_art_fill_buffer (GimpDrawable     *drawable,
   gimp_gegl_apply_opacity (buffer, NULL, NULL, buffer, new_mask,
                            -mask_offset_x, -mask_offset_y, 1.0);
 
-  if (gimp_fill_options_get_antialias (options))
-    {
-      /* Antialias for the line art algorithm is not applied during mask
-       * creation because it is not based on individual pixel colors.
-       * Instead we just want to apply it on the borders of the mask at
-       * the end (since the mask can evolve, we don't want to actually
-       * touch it, but only the intermediate results).
-       */
-      GeglNode   *graph;
-      GeglNode   *input;
-      GeglNode   *op;
-
-      graph = gegl_node_new ();
-      input = gegl_node_new_child (graph,
-                                   "operation", "gegl:buffer-source",
-                                   "buffer", buffer,
-                                   NULL);
-      op  = gegl_node_new_child (graph,
-                                 "operation", "gegl:gaussian-blur",
-                                 "std-dev-x", 0.5,
-                                 "std-dev-y", 0.5,
-                                 NULL);
-      gegl_node_connect_to (input, "output", op, "input");
-      gegl_node_blit_buffer (op, buffer, NULL, 0,
-                             GEGL_ABYSS_NONE);
-      g_object_unref (graph);
-    }
+  if (gimp_fill_options_get_feather (options, &feather_radius))
+    /* Feathering for the line art algorithm is not applied during
+     * mask creation because we just want to apply it on the borders
+     * of the mask at the end (since the mask can evolve, we don't
+     * want to actually touch it, but only the intermediate results).
+     */
+    gimp_gegl_apply_feather (buffer, NULL, NULL, buffer, NULL,
+                             feather_radius, feather_radius);
 
   if (mask_x)
     *mask_x = x;
diff --git a/app/core/gimpfilloptions.c b/app/core/gimpfilloptions.c
index 6c232ce906..fc87149e98 100644
--- a/app/core/gimpfilloptions.c
+++ b/app/core/gimpfilloptions.c
@@ -47,6 +47,8 @@ enum
   PROP_0,
   PROP_STYLE,
   PROP_ANTIALIAS,
+  PROP_FEATHER,
+  PROP_FEATHER_RADIUS,
   PROP_PATTERN_VIEW_TYPE,
   PROP_PATTERN_VIEW_SIZE
 };
@@ -58,6 +60,8 @@ struct _GimpFillOptionsPrivate
 {
   GimpFillStyle style;
   gboolean      antialias;
+  gboolean      feather;
+  gdouble       feather_radius;
 
   GimpViewType  pattern_view_type;
   GimpViewSize  pattern_view_size;
@@ -114,6 +118,20 @@ gimp_fill_options_class_init (GimpFillOptionsClass *klass)
                             TRUE,
                             GIMP_PARAM_STATIC_STRINGS);
 
+  GIMP_CONFIG_PROP_BOOLEAN (object_class, PROP_FEATHER,
+                            "feather",
+                            _("Feather edges"),
+                            _("Enable feathering of fill edges"),
+                            FALSE,
+                            GIMP_PARAM_STATIC_STRINGS);
+
+  GIMP_CONFIG_PROP_DOUBLE (object_class, PROP_FEATHER_RADIUS,
+                           "feather-radius",
+                           _("Radius"),
+                           _("Radius of feathering"),
+                           0.0, 100.0, 10.0,
+                           GIMP_PARAM_STATIC_STRINGS);
+
   g_object_class_install_property (object_class, PROP_PATTERN_VIEW_TYPE,
                                    g_param_spec_enum ("pattern-view-type",
                                                       NULL, NULL,
@@ -160,6 +178,12 @@ gimp_fill_options_set_property (GObject      *object,
     case PROP_ANTIALIAS:
       private->antialias = g_value_get_boolean (value);
       break;
+    case PROP_FEATHER:
+      private->feather = g_value_get_boolean (value);
+      break;
+    case PROP_FEATHER_RADIUS:
+      private->feather_radius = g_value_get_double (value);
+      break;
 
     case PROP_PATTERN_VIEW_TYPE:
       private->pattern_view_type = g_value_get_enum (value);
@@ -190,6 +214,12 @@ gimp_fill_options_get_property (GObject    *object,
     case PROP_ANTIALIAS:
       g_value_set_boolean (value, private->antialias);
       break;
+    case PROP_FEATHER:
+      g_value_set_boolean (value, private->feather);
+      break;
+    case PROP_FEATHER_RADIUS:
+      g_value_set_double (value, private->feather_radius);
+      break;
 
     case PROP_PATTERN_VIEW_TYPE:
       g_value_set_enum (value, private->pattern_view_type);
@@ -277,6 +307,29 @@ gimp_fill_options_set_antialias (GimpFillOptions *options,
   g_object_set (options, "antialias", antialias, NULL);
 }
 
+gboolean
+gimp_fill_options_get_feather (GimpFillOptions *options,
+                               gdouble         *radius)
+{
+  g_return_val_if_fail (GIMP_IS_FILL_OPTIONS (options), FALSE);
+
+  if (radius)
+    *radius = GET_PRIVATE (options)->feather_radius;
+
+  return GET_PRIVATE (options)->feather;
+}
+
+void
+gimp_fill_options_set_feather (GimpFillOptions *options,
+                               gboolean         feather,
+                               gdouble          radius)
+{
+  g_return_if_fail (GIMP_IS_FILL_OPTIONS (options));
+
+  g_object_set (options, "feather", feather, NULL);
+  g_object_set (options, "feather-radius", radius, NULL);
+}
+
 gboolean
 gimp_fill_options_set_by_fill_type (GimpFillOptions  *options,
                                     GimpContext      *context,
diff --git a/app/core/gimpfilloptions.h b/app/core/gimpfilloptions.h
index 2d183a129f..434530be0e 100644
--- a/app/core/gimpfilloptions.h
+++ b/app/core/gimpfilloptions.h
@@ -60,6 +60,12 @@ gboolean          gimp_fill_options_get_antialias    (GimpFillOptions     *optio
 void              gimp_fill_options_set_antialias    (GimpFillOptions     *options,
                                                       gboolean             antialias);
 
+gboolean          gimp_fill_options_get_feather      (GimpFillOptions     *options,
+                                                      gdouble             *radius);
+void              gimp_fill_options_set_feather      (GimpFillOptions     *options,
+                                                      gboolean             feather,
+                                                      gdouble              radius);
+
 gboolean          gimp_fill_options_set_by_fill_type (GimpFillOptions     *options,
                                                       GimpContext         *context,
                                                       GimpFillType         fill_type,
diff --git a/app/tools/gimpbucketfilloptions.c b/app/tools/gimpbucketfilloptions.c
index e8b2fbf54d..f5615c23fd 100644
--- a/app/tools/gimpbucketfilloptions.c
+++ b/app/tools/gimpbucketfilloptions.c
@@ -52,6 +52,8 @@ enum
   PROP_SAMPLE_MERGED,
   PROP_DIAGONAL_NEIGHBORS,
   PROP_ANTIALIAS,
+  PROP_FEATHER,
+  PROP_FEATHER_RADIUS,
   PROP_THRESHOLD,
   PROP_LINE_ART_SOURCE,
   PROP_LINE_ART_THRESHOLD,
@@ -152,6 +154,20 @@ gimp_bucket_fill_options_class_init (GimpBucketFillOptionsClass *klass)
                             TRUE,
                             GIMP_PARAM_STATIC_STRINGS);
 
+  GIMP_CONFIG_PROP_BOOLEAN (object_class, PROP_FEATHER,
+                            "feather",
+                            _("Feather edges"),
+                            _("Enable feathering of fill edges"),
+                            FALSE,
+                            GIMP_PARAM_STATIC_STRINGS);
+
+  GIMP_CONFIG_PROP_DOUBLE (object_class, PROP_FEATHER_RADIUS,
+                           "feather-radius",
+                           _("Radius"),
+                           _("Radius of feathering"),
+                           0.0, 100.0, 10.0,
+                           GIMP_PARAM_STATIC_STRINGS);
+
   GIMP_CONFIG_PROP_DOUBLE (object_class, PROP_THRESHOLD,
                            "threshold",
                            _("Threshold"),
@@ -240,6 +256,12 @@ gimp_bucket_fill_options_set_property (GObject      *object,
     case PROP_ANTIALIAS:
       options->antialias = g_value_get_boolean (value);
       break;
+    case PROP_FEATHER:
+      options->feather = g_value_get_boolean (value);
+      break;
+    case PROP_FEATHER_RADIUS:
+      options->feather_radius = g_value_get_double (value);
+      break;
     case PROP_THRESHOLD:
       options->threshold = g_value_get_double (value);
       break;
@@ -293,6 +315,12 @@ gimp_bucket_fill_options_get_property (GObject    *object,
     case PROP_ANTIALIAS:
       g_value_set_boolean (value, options->antialias);
       break;
+    case PROP_FEATHER:
+      g_value_set_boolean (value, options->feather);
+      break;
+    case PROP_FEATHER_RADIUS:
+      g_value_set_double (value, options->feather_radius);
+      break;
     case PROP_THRESHOLD:
       g_value_set_double (value, options->threshold);
       break;
@@ -483,10 +511,14 @@ gimp_bucket_fill_options_gui (GimpToolOptions *tool_options)
   gtk_box_pack_start (GTK_BOX (box2), widget, FALSE, FALSE, 0);
   gtk_widget_show (widget);
 
-  /*  the antialias toggle  */
-  widget = gimp_prop_check_button_new (config, "antialias", NULL);
-  gtk_box_pack_start (GTK_BOX (box2), widget, FALSE, FALSE, 0);
-  gtk_widget_show (widget);
+  /*  Line Art: feather radius scale  */
+  scale = gimp_prop_spin_scale_new (config, "feather-radius", NULL,
+                                    1.0, 10.0, 1);
+
+  frame = gimp_prop_expanding_frame_new (config, "feather", NULL,
+                                         scale, NULL);
+  gtk_box_pack_start (GTK_BOX (box2), frame, FALSE, FALSE, 0);
+  gtk_widget_show (frame);
 
   /*  Line Art: max growing size */
   scale = gimp_prop_spin_scale_new (config, "line-art-max-grow", NULL,
diff --git a/app/tools/gimpbucketfilloptions.h b/app/tools/gimpbucketfilloptions.h
index 1a6cf020cd..8c001fb2d3 100644
--- a/app/tools/gimpbucketfilloptions.h
+++ b/app/tools/gimpbucketfilloptions.h
@@ -44,6 +44,8 @@ struct _GimpBucketFillOptions
   gboolean                      sample_merged;
   gboolean                      diagonal_neighbors;
   gboolean                      antialias;
+  gboolean                      feather;
+  gdouble                       feather_radius;
   gdouble                       threshold;
 
   GtkWidget                    *line_art_busy_box;
diff --git a/app/tools/gimpbucketfilltool.c b/app/tools/gimpbucketfilltool.c
index 547c7dacc4..8248850d14 100644
--- a/app/tools/gimpbucketfilltool.c
+++ b/app/tools/gimpbucketfilltool.c
@@ -529,6 +529,8 @@ gimp_bucket_fill_tool_button_press (GimpTool            *tool,
                                               &error))
         {
           gimp_fill_options_set_antialias (fill_options, options->antialias);
+          gimp_fill_options_set_feather (fill_options, options->feather,
+                                         options->feather_radius);
 
           gimp_context_set_opacity (GIMP_CONTEXT (fill_options),
                                     gimp_context_get_opacity (context));
@@ -596,6 +598,8 @@ gimp_bucket_fill_tool_motion (GimpTool         *tool,
                                               &error))
         {
           gimp_fill_options_set_antialias (fill_options, options->antialias);
+          gimp_fill_options_set_feather (fill_options, options->feather,
+                                         options->feather_radius);
 
           gimp_context_set_opacity (GIMP_CONTEXT (fill_options),
                                     gimp_context_get_opacity (context));


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