[gimp] app: add a new feature to stroke the line art fill borders.
- From: Jehan <jehanp src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gimp] app: add a new feature to stroke the line art fill borders.
- Date: Thu, 3 Mar 2022 17:45:42 +0000 (UTC)
commit 76699e89ac32455230fe0e7ab30c4d38006b6828
Author: Jehan <jehan girinstud io>
Date: Mon Feb 28 15:39:52 2022 +0100
app: add a new feature to stroke the line art fill borders.
Currently the option is quite simple. What should happen to make it more
usable:
* Right now, it uses the last stroke options (e.g. as used in a
previously run "Stroke Selection" or "Stroke Path"). We should have
some dedicated GUI in the bucket fill options.
* The bucket fill options GUI should really be redesigned. The more we
add options, the less understandable it is.
* There is a question whether we want to just use whatever brush size is
being set or if we want to have it vary and follow the line art width
(since we have proper distance map, we could use this to tweak the
stroke per-coords).
As usual, this feature was suggested by Aryeom who was still very
saddened that despite all the fancy features in this tool, it is not
able to produce nice rendering. So she proposed that the tool could
stroke the fill region borders.
app/core/gimpchannel.c | 6 ++--
app/core/gimpdrawable-bucket-fill.c | 68 ++++++++++++++++++++++++++++++++++---
app/core/gimpdrawable-bucket-fill.h | 1 +
app/tools/gimpbucketfilloptions.c | 19 +++++++++++
app/tools/gimpbucketfilloptions.h | 1 +
app/tools/gimpbucketfilltool.c | 1 +
6 files changed, 90 insertions(+), 6 deletions(-)
---
diff --git a/app/core/gimpchannel.c b/app/core/gimpchannel.c
index 12bc985cd1..7b6a9851ae 100644
--- a/app/core/gimpchannel.c
+++ b/app/core/gimpchannel.c
@@ -826,7 +826,8 @@ gimp_channel_stroke (GimpItem *item,
case GIMP_STROKE_LINE:
gimp_drawable_stroke_boundary (drawable,
stroke_options,
- segs_in, n_segs_in,
+ n_segs_in > 0 ? segs_in : segs_out,
+ n_segs_in > 0 ? n_segs_in : n_segs_out,
offset_x, offset_y,
push_undo);
retval = TRUE;
@@ -849,7 +850,8 @@ gimp_channel_stroke (GimpItem *item,
retval = gimp_paint_core_stroke_boundary (core, drawable,
paint_options,
emulate_dynamics,
- segs_in, n_segs_in,
+ n_segs_in > 0 ? segs_in : segs_out,
+ n_segs_in > 0 ? n_segs_in : n_segs_out,
offset_x, offset_y,
push_undo, error);
diff --git a/app/core/gimpdrawable-bucket-fill.c b/app/core/gimpdrawable-bucket-fill.c
index 319887cc82..7af371c6ef 100644
--- a/app/core/gimpdrawable-bucket-fill.c
+++ b/app/core/gimpdrawable-bucket-fill.c
@@ -23,9 +23,12 @@
#include "libgimpbase/gimpbase.h"
#include "libgimpcolor/gimpcolor.h"
+#include "libgimpconfig/gimpconfig.h"
#include "core-types.h"
+#include "config/gimpdialogconfig.h"
+
#include "gegl/gimp-gegl-apply-operation.h"
#include "gegl/gimp-gegl-mask.h"
#include "gegl/gimp-gegl-mask-combine.h"
@@ -38,6 +41,7 @@
#include "gimpdrawable.h"
#include "gimpdrawable-bucket-fill.h"
#include "gimpfilloptions.h"
+#include "gimpstrokeoptions.h"
#include "gimpimage.h"
#include "gimplineart.h"
#include "gimppickable.h"
@@ -325,7 +329,7 @@ gimp_drawable_get_bucket_fill_buffer (GimpDrawable *drawable,
* filling process. Set to NULL if you need a one-time
* fill.
* @mask_x: returned x bound of @mask_buffer.
- * @mask_y: returned x bound of @mask_buffer.
+ * @mask_y: returned y bound of @mask_buffer.
* @mask_width: returned width bound of @mask_buffer.
* @mask_height: returned height bound of @mask_buffer.
*
@@ -333,7 +337,7 @@ gimp_drawable_get_bucket_fill_buffer (GimpDrawable *drawable,
* based on @line_art and @options, without actually applying it.
* If @mask_buffer is not NULL, the intermediate fill mask will also be
* returned. This fill mask can later be reused in successive calls to
- * gimp_drawable_get_bucket_fill_buffer() for interactive filling.
+ * gimp_drawable_get_line_art_fill_buffer() for interactive filling.
*
* The @fill_color_as_line_art option is a special feature where we
* consider pixels in @drawable already in the fill color as part of the
@@ -351,6 +355,7 @@ gimp_drawable_get_line_art_fill_buffer (GimpDrawable *drawable,
gboolean sample_merged,
gboolean fill_color_as_line_art,
gdouble fill_color_threshold,
+ gboolean line_art_stroke,
gdouble seed_x,
gdouble seed_y,
GeglBuffer **mask_buffer,
@@ -362,6 +367,7 @@ gimp_drawable_get_line_art_fill_buffer (GimpDrawable *drawable,
GimpImage *image;
GeglBuffer *buffer;
GeglBuffer *new_mask;
+ GeglBuffer *stroke_mask;
GeglBuffer *fill_buffer = NULL;
GimpRGB fill_color;
gint fill_offset_x = 0;
@@ -438,7 +444,59 @@ gimp_drawable_get_line_art_fill_buffer (GimpDrawable *drawable,
if (mask_buffer)
*mask_buffer = new_mask;
- gimp_gegl_mask_bounds (new_mask, &x, &y, &width, &height);
+ if (line_art_stroke)
+ {
+ GimpChannel *channel;
+ GList *drawables;
+ GimpStrokeOptions *stroke_options;
+ GimpContext *context = gimp_get_user_context (image->gimp);
+ GError *error = NULL;
+ const GimpRGB white = {1.0, 1.0, 1.0, 1.0};
+
+ context = gimp_config_duplicate (GIMP_CONFIG (context));
+ /* As we are stroking a mask, we need to set color to white. */
+ gimp_context_set_foreground (GIMP_CONTEXT (context),
+ &white);
+
+ /* This initial version uses the stroke option as used in other
+ * stroke features. A future version should allow to set the
+ * stroke directly from bucket fill tool options.
+ */
+ stroke_options = GIMP_DIALOG_CONFIG (image->gimp->config)->stroke_options;
+ stroke_options = gimp_config_duplicate (GIMP_CONFIG (stroke_options));
+
+ channel = gimp_channel_new_from_buffer (image, new_mask, NULL, NULL);
+ gimp_image_add_hidden_item (image, GIMP_ITEM (channel));
+ drawables = g_list_prepend (NULL, channel);
+
+ if (! gimp_item_stroke (GIMP_ITEM (channel), drawables,
+ context,
+ stroke_options,
+ NULL, FALSE, NULL, &error))
+ {
+ g_warning ("%s: stroking failed with: %s\n",
+ G_STRFUNC, error ? error->message : "no error message");
+ g_clear_error (&error);
+ }
+
+ g_list_free (drawables);
+
+ gimp_pickable_flush (GIMP_PICKABLE (channel));
+ stroke_mask = gimp_drawable_get_buffer (GIMP_DRAWABLE (channel));
+ g_object_ref (stroke_mask);
+
+ gimp_image_remove_hidden_item (image, GIMP_ITEM (channel));
+ g_object_unref (channel);
+
+ g_object_unref (stroke_options);
+ g_object_unref (context);
+ }
+ else
+ {
+ stroke_mask = g_object_ref (new_mask);
+ }
+
+ gimp_gegl_mask_bounds (stroke_mask, &x, &y, &width, &height);
width -= x;
height -= y;
@@ -508,7 +566,7 @@ gimp_drawable_get_line_art_fill_buffer (GimpDrawable *drawable,
width, height),
-x, -y);
- gimp_gegl_apply_opacity (buffer, NULL, NULL, buffer, new_mask,
+ gimp_gegl_apply_opacity (buffer, NULL, NULL, buffer, stroke_mask,
-mask_offset_x, -mask_offset_y, 1.0);
if (gimp_fill_options_get_feather (options, &feather_radius))
@@ -534,6 +592,8 @@ gimp_drawable_get_line_art_fill_buffer (GimpDrawable *drawable,
if (! mask_buffer)
g_object_unref (new_mask);
+ g_object_unref (stroke_mask);
+
gimp_unset_busy (image->gimp);
return buffer;
diff --git a/app/core/gimpdrawable-bucket-fill.h b/app/core/gimpdrawable-bucket-fill.h
index 0339d6c70f..ffbf891c47 100644
--- a/app/core/gimpdrawable-bucket-fill.h
+++ b/app/core/gimpdrawable-bucket-fill.h
@@ -50,6 +50,7 @@ GeglBuffer * gimp_drawable_get_line_art_fill_buffer (GimpDrawable *drawa
gboolean sample_merged,
gboolean fill_color_as_line_art,
gdouble fill_color_threshold,
+ gboolean line_art_stroke,
gdouble seed_x,
gdouble seed_y,
GeglBuffer **mask_buffer,
diff --git a/app/tools/gimpbucketfilloptions.c b/app/tools/gimpbucketfilloptions.c
index 0328b59d5f..fd9567d379 100644
--- a/app/tools/gimpbucketfilloptions.c
+++ b/app/tools/gimpbucketfilloptions.c
@@ -59,6 +59,7 @@ enum
PROP_LINE_ART_SOURCE,
PROP_LINE_ART_THRESHOLD,
PROP_LINE_ART_MAX_GROW,
+ PROP_LINE_ART_STROKE,
PROP_LINE_ART_MAX_GAP_LENGTH,
PROP_FILL_CRITERION,
PROP_FILL_COLOR_AS_LINE_ART,
@@ -215,6 +216,14 @@ gimp_bucket_fill_options_class_init (GimpBucketFillOptionsClass *klass)
1, 100, 3,
GIMP_PARAM_STATIC_STRINGS);
+ /* TODO: we should be able to choose which tool to stroke with. */
+ GIMP_CONFIG_PROP_BOOLEAN (object_class, PROP_LINE_ART_STROKE,
+ "line-art-stroke-border",
+ _("Stroke borders"),
+ _("Stroke fill borders with last stroke options"),
+ FALSE,
+ GIMP_PARAM_STATIC_STRINGS);
+
GIMP_CONFIG_PROP_INT (object_class, PROP_LINE_ART_MAX_GAP_LENGTH,
"line-art-max-gap-length",
_("Maximum gap length"),
@@ -294,6 +303,9 @@ gimp_bucket_fill_options_set_property (GObject *object,
case PROP_LINE_ART_MAX_GROW:
options->line_art_max_grow = g_value_get_int (value);
break;
+ case PROP_LINE_ART_STROKE:
+ options->line_art_stroke = g_value_get_boolean (value);
+ break;
case PROP_LINE_ART_MAX_GAP_LENGTH:
options->line_art_max_gap_length = g_value_get_int (value);
break;
@@ -359,6 +371,9 @@ gimp_bucket_fill_options_get_property (GObject *object,
case PROP_LINE_ART_MAX_GROW:
g_value_set_int (value, options->line_art_max_grow);
break;
+ case PROP_LINE_ART_STROKE:
+ g_value_set_boolean (value, options->line_art_stroke);
+ break;
case PROP_LINE_ART_MAX_GAP_LENGTH:
g_value_set_int (value, options->line_art_max_gap_length);
break;
@@ -560,6 +575,10 @@ gimp_bucket_fill_options_gui (GimpToolOptions *tool_options)
1, 5, 0);
gtk_box_pack_start (GTK_BOX (box2), scale, FALSE, FALSE, 0);
+ /* Line Art: stroke border with paint brush */
+ widget = gimp_prop_check_button_new (config, "line-art-stroke-border", NULL);
+ gtk_box_pack_start (GTK_BOX (box2), widget, FALSE, FALSE, 0);
+
/* Line Art: stroke threshold */
scale = gimp_prop_spin_scale_new (config, "line-art-threshold",
0.05, 0.1, 2);
diff --git a/app/tools/gimpbucketfilloptions.h b/app/tools/gimpbucketfilloptions.h
index 30bb594cbb..84345011f8 100644
--- a/app/tools/gimpbucketfilloptions.h
+++ b/app/tools/gimpbucketfilloptions.h
@@ -52,6 +52,7 @@ struct _GimpBucketFillOptions
GimpLineArtSource line_art_source;
gdouble line_art_threshold;
gint line_art_max_grow;
+ gboolean line_art_stroke;
gint line_art_max_gap_length;
gboolean fill_as_line_art;
diff --git a/app/tools/gimpbucketfilltool.c b/app/tools/gimpbucketfilltool.c
index 40f04e84e1..5478b61538 100644
--- a/app/tools/gimpbucketfilltool.c
+++ b/app/tools/gimpbucketfilltool.c
@@ -457,6 +457,7 @@ gimp_bucket_fill_tool_preview (GimpBucketFillTool *tool,
GIMP_LINE_ART_SOURCE_SAMPLE_MERGED,
options->fill_as_line_art,
options->fill_as_line_art_threshold / 255.0,
+ options->line_art_stroke,
x, y,
&tool->priv->fill_mask,
&x, &y, NULL, NULL);
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]