[gimp] app: improve line art filling when clicking on a line art closure.
- From: Jehan <jehanp src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gimp] app: improve line art filling when clicking on a line art closure.
- Date: Mon, 4 Mar 2019 17:32:55 +0000 (UTC)
commit f310db6c2154cdbfae8dea929042ddfc73280e1e
Author: Jehan <jehan girinstud io>
Date: Mon Mar 4 18:28:11 2019 +0100
app: improve line art filling when clicking on a line art closure.
When clicking on a line art pixel, only this pixel gets colored, which
is fine for actual (original) line art pixels. But on generated ones
(closure pixels, which are internal only), you end up with a single
pixel colored while the whole surrounding area is empty. This feels like
a bug (even though it was not one technically) as you have no way to
guess you are clicking on a closure pixel.
Instead, when this happens, simulate clicks on all neighbour pixels,
hence potentially coloring all surrounding regions, which is most likely
what you wanted.
app/core/gimplineart.c | 4 +-
app/core/gimppickable-contiguous-region.cc | 116 ++++++++++++++++++++++++-----
2 files changed, 98 insertions(+), 22 deletions(-)
---
diff --git a/app/core/gimplineart.c b/app/core/gimplineart.c
index 9008caabf5..b63c40aa05 100644
--- a/app/core/gimplineart.c
+++ b/app/core/gimplineart.c
@@ -1056,7 +1056,7 @@ gimp_line_art_close (GeglBuffer *buffer,
if (p.x >= 0 && p.x < gegl_buffer_get_width (closed) &&
p.y >= 0 && p.y < gegl_buffer_get_height (closed))
{
- guchar val = 1;
+ guchar val = 2;
gegl_buffer_set (closed, GEGL_RECTANGLE ((gint) p.x, (gint) p.y, 1, 1), 0,
NULL, &val, GEGL_AUTO_ROWSTRIDE);
@@ -1112,7 +1112,7 @@ gimp_line_art_close (GeglBuffer *buffer,
for (j = 0; j < segment->len; j++)
{
Pixel p2 = g_array_index (segment, Pixel, j);
- guchar val = 1;
+ guchar val = 2;
gegl_buffer_set (closed, GEGL_RECTANGLE ((gint) p2.x, (gint) p2.y, 1, 1), 0,
NULL, &val, GEGL_AUTO_ROWSTRIDE);
diff --git a/app/core/gimppickable-contiguous-region.cc b/app/core/gimppickable-contiguous-region.cc
index c2fc9915f9..817ba31e55 100644
--- a/app/core/gimppickable-contiguous-region.cc
+++ b/app/core/gimppickable-contiguous-region.cc
@@ -297,9 +297,9 @@ gimp_pickable_contiguous_region_by_line_art (GimpPickable *pickable,
const Babl *format = babl_format ("Y float");
gfloat *distmap = NULL;
GeglRectangle extent;
- gfloat start_col;
- gboolean free_line_art = FALSE;
- gint line_art_max_grow;
+ gboolean free_line_art = FALSE;
+ gboolean filled = FALSE;
+ guchar start_col;
g_return_val_if_fail (GIMP_IS_PICKABLE (pickable) || GIMP_IS_LINE_ART (line_art), NULL);
@@ -317,40 +317,116 @@ gimp_pickable_contiguous_region_by_line_art (GimpPickable *pickable,
src_buffer = gimp_line_art_get (line_art, &distmap);
g_return_val_if_fail (src_buffer && distmap, NULL);
- gegl_buffer_sample (src_buffer, x, y, NULL, &start_col, format,
+ gegl_buffer_sample (src_buffer, x, y, NULL, &start_col, NULL,
GEGL_SAMPLER_NEAREST, GEGL_ABYSS_NONE);
extent = *gegl_buffer_get_extent (src_buffer);
- mask_buffer = gegl_buffer_new (&extent, babl_format ("Y float"));
+ mask_buffer = gegl_buffer_new (&extent, format);
if (start_col)
{
- /* As a special exception, if you fill over a line art pixel, only
- * fill the pixel and exit
- */
- start_col = 1.0;
- gegl_buffer_set (mask_buffer, GEGL_RECTANGLE (x, y, 1, 1),
- 0, babl_format ("Y float"), &start_col,
- GEGL_AUTO_ROWSTRIDE);
+ if (start_col == 1)
+ {
+ /* As a special exception, if you fill over a line art pixel, only
+ * fill the pixel and exit
+ */
+ gfloat col = 1.0;
+
+ gegl_buffer_set (mask_buffer, GEGL_RECTANGLE (x, y, 1, 1),
+ 0, format, &col, GEGL_AUTO_ROWSTRIDE);
+ }
+ else /* start_col == 2 */
+ {
+ /* If you fill over a closure pixel, let's fill on all sides
+ * of the start point. Otherwise we get a very weird result
+ * with only a single pixel filled in the middle of an empty
+ * region (since closure pixels are invisible by nature).
+ */
+ gfloat col = 0.0;
+
+ if (x - 1 >= extent.x && x - 1 < extent.x + extent.width &&
+ y - 1 >= extent.y && y - 1 < (extent.y + extent.height))
+ find_contiguous_region (src_buffer, mask_buffer,
+ format, 1, FALSE,
+ FALSE, GIMP_SELECT_CRITERION_COMPOSITE,
+ FALSE, 0.0, FALSE,
+ x - 1, y - 1, &col);
+ if (x - 1 >= extent.x && x - 1 < extent.x + extent.width &&
+ y >= extent.y && y < (extent.y + extent.height))
+ find_contiguous_region (src_buffer, mask_buffer,
+ format, 1, FALSE,
+ FALSE, GIMP_SELECT_CRITERION_COMPOSITE,
+ FALSE, 0.0, FALSE,
+ x - 1, y, &col);
+ if (x - 1 >= extent.x && x - 1 < extent.x + extent.width &&
+ y + 1 >= extent.y && y + 1 < (extent.y + extent.height))
+ find_contiguous_region (src_buffer, mask_buffer,
+ format, 1, FALSE,
+ FALSE, GIMP_SELECT_CRITERION_COMPOSITE,
+ FALSE, 0.0, FALSE,
+ x - 1, y + 1, &col);
+ if (x >= extent.x && x < extent.x + extent.width &&
+ y - 1 >= extent.y && y - 1 < (extent.y + extent.height))
+ find_contiguous_region (src_buffer, mask_buffer,
+ format, 1, FALSE,
+ FALSE, GIMP_SELECT_CRITERION_COMPOSITE,
+ FALSE, 0.0, FALSE,
+ x, y - 1, &col);
+ if (x >= extent.x && x < extent.x + extent.width &&
+ y + 1 >= extent.y && y + 1 < (extent.y + extent.height))
+ find_contiguous_region (src_buffer, mask_buffer,
+ format, 1, FALSE,
+ FALSE, GIMP_SELECT_CRITERION_COMPOSITE,
+ FALSE, 0.0, FALSE,
+ x, y + 1, &col);
+ if (x + 1 >= extent.x && x + 1 < extent.x + extent.width &&
+ y - 1 >= extent.y && y - 1 < (extent.y + extent.height))
+ find_contiguous_region (src_buffer, mask_buffer,
+ format, 1, FALSE,
+ FALSE, GIMP_SELECT_CRITERION_COMPOSITE,
+ FALSE, 0.0, FALSE,
+ x + 1, y - 1, &col);
+ if (x + 1 >= extent.x && x + 1 < extent.x + extent.width &&
+ y >= extent.y && y < (extent.y + extent.height))
+ find_contiguous_region (src_buffer, mask_buffer,
+ format, 1, FALSE,
+ FALSE, GIMP_SELECT_CRITERION_COMPOSITE,
+ FALSE, 0.0, FALSE,
+ x + 1, y, &col);
+ if (x + 1 >= extent.x && x + 1 < extent.x + extent.width &&
+ y + 1 >= extent.y && y + 1 < (extent.y + extent.height))
+ find_contiguous_region (src_buffer, mask_buffer,
+ format, 1, FALSE,
+ FALSE, GIMP_SELECT_CRITERION_COMPOSITE,
+ FALSE, 0.0, FALSE,
+ x + 1, y + 1, &col);
+ filled = TRUE;
+ }
}
else if (x >= extent.x && x < (extent.x + extent.width) &&
y >= extent.y && y < (extent.y + extent.height))
{
- gfloat *mask;
- GQueue *queue = g_queue_new ();
- gint width = gegl_buffer_get_width (src_buffer);
- gint height = gegl_buffer_get_height (src_buffer);
- gint nx, ny;
-
- GIMP_TIMER_START();
+ gfloat col = 0.0;
find_contiguous_region (src_buffer, mask_buffer,
format, 1, FALSE,
FALSE, GIMP_SELECT_CRITERION_COMPOSITE,
FALSE, 0.0, FALSE,
- x, y, &start_col);
+ x, y, &col);
+ filled = TRUE;
+ }
+
+ if (filled)
+ {
+ GQueue *queue = g_queue_new ();
+ gfloat *mask;
+ gint width = gegl_buffer_get_width (src_buffer);
+ gint height = gegl_buffer_get_height (src_buffer);
+ gint line_art_max_grow;
+ gint nx, ny;
+ GIMP_TIMER_START();
/* The last step of the line art algorithm is to make sure that
* selections does not leave "holes" between its borders and the
* line arts, while not stepping over as well.
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]