mirror of https://github.com/GNOME/gimp.git
app: add "line-art-max-grow" property to the bucket fill options.
When flooding the line art, we may overflood it in sample merge (which would use color in the line art computation). And if having all colors on the same layer, this would go over other colors (making the wrong impression that the line art leaked). This new option is mostly to keep some control over the mask growth. Usually a few pixels is enough for most styles of drawing (though we could technically allow for very wide strokes).
This commit is contained in:
parent
dd3d9ab3dd
commit
eb042e6c87
|
@ -522,7 +522,7 @@ gimp_channel_select_fuzzy (GimpChannel *channel,
|
|||
select_transparent,
|
||||
select_criterion,
|
||||
diagonal_neighbors,
|
||||
0.92, /* TODO */
|
||||
0.92, 3, /* TODO */
|
||||
x, y);
|
||||
|
||||
if (! sample_merged)
|
||||
|
|
|
@ -58,7 +58,8 @@ gimp_drawable_bucket_fill (GimpDrawable *drawable,
|
|||
gdouble threshold,
|
||||
gboolean sample_merged,
|
||||
gboolean diagonal_neighbors,
|
||||
gfloat stroke_threshold,
|
||||
gfloat line_art_stroke_threshold,
|
||||
gint line_art_max_grow,
|
||||
gdouble seed_x,
|
||||
gdouble seed_y)
|
||||
{
|
||||
|
@ -79,7 +80,8 @@ gimp_drawable_bucket_fill (GimpDrawable *drawable,
|
|||
fill_transparent, fill_criterion,
|
||||
threshold, sample_merged,
|
||||
diagonal_neighbors,
|
||||
stroke_threshold,
|
||||
line_art_stroke_threshold,
|
||||
line_art_max_grow,
|
||||
seed_x, seed_y, NULL,
|
||||
&mask_x, &mask_y, &width, &height);
|
||||
|
||||
|
@ -146,6 +148,7 @@ gimp_drawable_get_bucket_fill_buffer (GimpDrawable *drawable,
|
|||
gboolean sample_merged,
|
||||
gboolean diagonal_neighbors,
|
||||
gfloat stroke_threshold,
|
||||
gint max_grow,
|
||||
gdouble seed_x,
|
||||
gdouble seed_y,
|
||||
GeglBuffer **mask_buffer,
|
||||
|
@ -208,6 +211,7 @@ gimp_drawable_get_bucket_fill_buffer (GimpDrawable *drawable,
|
|||
fill_criterion,
|
||||
diagonal_neighbors,
|
||||
stroke_threshold,
|
||||
max_grow,
|
||||
(gint) seed_x,
|
||||
(gint) seed_y);
|
||||
if (mask_buffer && *mask_buffer)
|
||||
|
|
|
@ -29,7 +29,8 @@ void gimp_drawable_bucket_fill (GimpDrawable *drawabl
|
|||
gdouble threshold,
|
||||
gboolean sample_merged,
|
||||
gboolean diagonal_neighbors,
|
||||
gfloat stroke_threshold,
|
||||
gfloat line_art_stroke_threshold,
|
||||
gint line_art_max_grow,
|
||||
gdouble x,
|
||||
gdouble y);
|
||||
GeglBuffer * gimp_drawable_get_bucket_fill_buffer (GimpDrawable *drawable,
|
||||
|
@ -42,7 +43,8 @@ GeglBuffer * gimp_drawable_get_bucket_fill_buffer (GimpDrawable *drawabl
|
|||
gdouble threshold,
|
||||
gboolean sample_merged,
|
||||
gboolean diagonal_neighbors,
|
||||
gfloat stroke_threshold,
|
||||
gfloat line_art_stroke_threshold,
|
||||
gint line_art_max_grow,
|
||||
gdouble seed_x,
|
||||
gdouble seed_y,
|
||||
GeglBuffer **mask_buffer,
|
||||
|
|
|
@ -50,7 +50,8 @@ typedef struct
|
|||
{
|
||||
gint x;
|
||||
gint y;
|
||||
gfloat dist;
|
||||
gfloat radius;
|
||||
gint level;
|
||||
} BorderPixel;
|
||||
|
||||
|
||||
|
@ -126,7 +127,8 @@ static void line_art_result_free (GimpPickableLineArtAsyncResult
|
|||
static void line_art_queue_pixel (GQueue *queue,
|
||||
gint x,
|
||||
gint y,
|
||||
gfloat dist);
|
||||
gfloat radius,
|
||||
gint level);
|
||||
|
||||
|
||||
/* public functions */
|
||||
|
@ -311,6 +313,7 @@ gimp_pickable_contiguous_region_by_seed (GimpPickable *pickable,
|
|||
GimpSelectCriterion select_criterion,
|
||||
gboolean diagonal_neighbors,
|
||||
gfloat stroke_threshold,
|
||||
gint flooding_max,
|
||||
gint x,
|
||||
gint y)
|
||||
{
|
||||
|
@ -449,14 +452,14 @@ gimp_pickable_contiguous_region_by_seed (GimpPickable *pickable,
|
|||
ny = y - 1;
|
||||
if (mask[nx + ny * width] != 0.0)
|
||||
{
|
||||
line_art_queue_pixel (queue, x, y, thickness);
|
||||
line_art_queue_pixel (queue, x, y, thickness, 1);
|
||||
continue;
|
||||
}
|
||||
}
|
||||
ny = y;
|
||||
if (mask[nx + ny * width] != 0.0)
|
||||
{
|
||||
line_art_queue_pixel (queue, x, y, thickness);
|
||||
line_art_queue_pixel (queue, x, y, thickness, 1);
|
||||
continue;
|
||||
}
|
||||
if (y < height - 1)
|
||||
|
@ -464,7 +467,7 @@ gimp_pickable_contiguous_region_by_seed (GimpPickable *pickable,
|
|||
ny = y + 1;
|
||||
if (mask[nx + ny * width] != 0.0)
|
||||
{
|
||||
line_art_queue_pixel (queue, x, y, thickness);
|
||||
line_art_queue_pixel (queue, x, y, thickness, 1);
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
@ -477,14 +480,14 @@ gimp_pickable_contiguous_region_by_seed (GimpPickable *pickable,
|
|||
ny = y - 1;
|
||||
if (mask[nx + ny * width] != 0.0)
|
||||
{
|
||||
line_art_queue_pixel (queue, x, y, thickness);
|
||||
line_art_queue_pixel (queue, x, y, thickness, 1);
|
||||
continue;
|
||||
}
|
||||
}
|
||||
ny = y;
|
||||
if (mask[nx + ny * width] != 0.0)
|
||||
{
|
||||
line_art_queue_pixel (queue, x, y, thickness);
|
||||
line_art_queue_pixel (queue, x, y, thickness, 1);
|
||||
continue;
|
||||
}
|
||||
if (y < height - 1)
|
||||
|
@ -492,7 +495,7 @@ gimp_pickable_contiguous_region_by_seed (GimpPickable *pickable,
|
|||
ny = y + 1;
|
||||
if (mask[nx + ny * width] != 0.0)
|
||||
{
|
||||
line_art_queue_pixel (queue, x, y, thickness);
|
||||
line_art_queue_pixel (queue, x, y, thickness, 1);
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
@ -503,7 +506,7 @@ gimp_pickable_contiguous_region_by_seed (GimpPickable *pickable,
|
|||
ny = y - 1;
|
||||
if (mask[nx + ny * width] != 0.0)
|
||||
{
|
||||
line_art_queue_pixel (queue, x, y, thickness);
|
||||
line_art_queue_pixel (queue, x, y, thickness, 1);
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
@ -512,7 +515,7 @@ gimp_pickable_contiguous_region_by_seed (GimpPickable *pickable,
|
|||
ny = y + 1;
|
||||
if (mask[nx + ny * width] != 0.0)
|
||||
{
|
||||
line_art_queue_pixel (queue, x, y, thickness);
|
||||
line_art_queue_pixel (queue, x, y, thickness, 1);
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
@ -526,6 +529,9 @@ gimp_pickable_contiguous_region_by_seed (GimpPickable *pickable,
|
|||
if (mask[c->x + c->y * width] != 1.0)
|
||||
{
|
||||
mask[c->x + c->y * width] = 1.0;
|
||||
if (c->level >= flooding_max)
|
||||
/* Do not overflood under line arts. */
|
||||
continue;
|
||||
if (c->x > 0)
|
||||
{
|
||||
nx = c->x - 1;
|
||||
|
@ -534,21 +540,21 @@ gimp_pickable_contiguous_region_by_seed (GimpPickable *pickable,
|
|||
ny = c->y - 1;
|
||||
if (mask[nx + ny * width] == 0.0 &&
|
||||
distmap[nx + ny * width] > distmap[c->x + c->y * width] &&
|
||||
distmap[nx + ny * width] < c->dist)
|
||||
line_art_queue_pixel (queue, nx, ny, c->dist);
|
||||
distmap[nx + ny * width] < c->radius)
|
||||
line_art_queue_pixel (queue, nx, ny, c->radius, c->level + 1);
|
||||
}
|
||||
ny = c->y;
|
||||
if (mask[nx + ny * width] == 0.0 &&
|
||||
distmap[nx + ny * width] > distmap[c->x + c->y * width] &&
|
||||
distmap[nx + ny * width] < c->dist)
|
||||
line_art_queue_pixel (queue, nx, ny, c->dist);
|
||||
distmap[nx + ny * width] < c->radius)
|
||||
line_art_queue_pixel (queue, nx, ny, c->radius, c->level + 1);
|
||||
if (c->y < height - 1)
|
||||
{
|
||||
ny = c->y - 1;
|
||||
if (mask[nx + ny * width] == 0.0 &&
|
||||
distmap[nx + ny * width] > distmap[c->x + c->y * width] &&
|
||||
distmap[nx + ny * width] < c->dist)
|
||||
line_art_queue_pixel (queue, nx, ny, c->dist);
|
||||
distmap[nx + ny * width] < c->radius)
|
||||
line_art_queue_pixel (queue, nx, ny, c->radius, c->level + 1);
|
||||
}
|
||||
}
|
||||
if (c->x < width - 1)
|
||||
|
@ -559,21 +565,21 @@ gimp_pickable_contiguous_region_by_seed (GimpPickable *pickable,
|
|||
ny = c->y - 1;
|
||||
if (mask[nx + ny * width] == 0.0 &&
|
||||
distmap[nx + ny * width] > distmap[c->x + c->y * width] &&
|
||||
distmap[nx + ny * width] < c->dist)
|
||||
line_art_queue_pixel (queue, nx, ny, c->dist);
|
||||
distmap[nx + ny * width] < c->radius)
|
||||
line_art_queue_pixel (queue, nx, ny, c->radius, c->level + 1);
|
||||
}
|
||||
ny = c->y;
|
||||
if (mask[nx + ny * width] == 0.0 &&
|
||||
distmap[nx + ny * width] > distmap[c->x + c->y * width] &&
|
||||
distmap[nx + ny * width] < c->dist)
|
||||
line_art_queue_pixel (queue, nx, ny, c->dist);
|
||||
distmap[nx + ny * width] < c->radius)
|
||||
line_art_queue_pixel (queue, nx, ny, c->radius, c->level + 1);
|
||||
if (c->y < height - 1)
|
||||
{
|
||||
ny = c->y - 1;
|
||||
if (mask[nx + ny * width] == 0.0 &&
|
||||
distmap[nx + ny * width] > distmap[c->x + c->y * width] &&
|
||||
distmap[nx + ny * width] < c->dist)
|
||||
line_art_queue_pixel (queue, nx, ny, c->dist);
|
||||
distmap[nx + ny * width] < c->radius)
|
||||
line_art_queue_pixel (queue, nx, ny, c->radius, c->level + 1);
|
||||
}
|
||||
}
|
||||
nx = c->x;
|
||||
|
@ -582,16 +588,16 @@ gimp_pickable_contiguous_region_by_seed (GimpPickable *pickable,
|
|||
ny = c->y - 1;
|
||||
if (mask[nx + ny * width] == 0.0 &&
|
||||
distmap[nx + ny * width] > distmap[c->x + c->y * width] &&
|
||||
distmap[nx + ny * width] < c->dist)
|
||||
line_art_queue_pixel (queue, nx, ny, c->dist);
|
||||
distmap[nx + ny * width] < c->radius)
|
||||
line_art_queue_pixel (queue, nx, ny, c->radius, c->level + 1);
|
||||
}
|
||||
if (c->y < height - 1)
|
||||
{
|
||||
ny = c->y + 1;
|
||||
if (mask[nx + ny * width] == 0.0 &&
|
||||
distmap[nx + ny * width] > distmap[c->x + c->y * width] &&
|
||||
distmap[nx + ny * width] < c->dist)
|
||||
line_art_queue_pixel (queue, nx, ny, c->dist);
|
||||
distmap[nx + ny * width] < c->radius)
|
||||
line_art_queue_pixel (queue, nx, ny, c->radius, c->level + 1);
|
||||
}
|
||||
}
|
||||
g_free (c);
|
||||
|
@ -1206,13 +1212,15 @@ static void
|
|||
line_art_queue_pixel (GQueue *queue,
|
||||
gint x,
|
||||
gint y,
|
||||
gfloat dist)
|
||||
gfloat radius,
|
||||
gint level)
|
||||
{
|
||||
BorderPixel *p = g_new (BorderPixel, 1);
|
||||
|
||||
p->x = x;
|
||||
p->y = y;
|
||||
p->dist = dist;
|
||||
p->x = x;
|
||||
p->y = y;
|
||||
p->radius = radius;
|
||||
p->level = level;
|
||||
|
||||
g_queue_push_head (queue, p);
|
||||
}
|
||||
|
|
|
@ -37,14 +37,15 @@ GimpAsync * gimp_pickable_contiguous_region_prepare_line_art_async (GimpPickabl
|
|||
|
||||
GeglBuffer * gimp_pickable_contiguous_region_by_seed (GimpPickable *pickable,
|
||||
GeglBuffer *line_art,
|
||||
gfloat *distmap,
|
||||
gfloat *thickmap,
|
||||
gfloat *line_art_distmap,
|
||||
gfloat *line_art_thickmap,
|
||||
gboolean antialias,
|
||||
gfloat threshold,
|
||||
gboolean select_transparent,
|
||||
GimpSelectCriterion select_criterion,
|
||||
gboolean diagonal_neighbors,
|
||||
gfloat stroke_threshold,
|
||||
gfloat line_art_stroke_threshold,
|
||||
gint line_art_max_grow,
|
||||
gint x,
|
||||
gint y);
|
||||
|
||||
|
|
|
@ -171,7 +171,7 @@ drawable_edit_bucket_fill_invoker (GimpProcedure *procedure,
|
|||
GIMP_PDB_CONTEXT (context)->sample_threshold,
|
||||
GIMP_PDB_CONTEXT (context)->sample_merged,
|
||||
GIMP_PDB_CONTEXT (context)->diagonal_neighbors,
|
||||
0.92, /* TODO */
|
||||
0.92, 3, /* TODO */
|
||||
x, y);
|
||||
}
|
||||
else
|
||||
|
|
|
@ -54,6 +54,7 @@ enum
|
|||
PROP_ANTIALIAS,
|
||||
PROP_THRESHOLD,
|
||||
PROP_LINE_ART_THRESHOLD,
|
||||
PROP_LINE_ART_MAX_GROW,
|
||||
PROP_FILL_CRITERION
|
||||
};
|
||||
|
||||
|
@ -64,6 +65,7 @@ struct _GimpBucketFillOptionsPrivate
|
|||
GtkWidget *threshold_scale;
|
||||
|
||||
GtkWidget *line_art_threshold_scale;
|
||||
GtkWidget *line_art_grow_scale;
|
||||
};
|
||||
|
||||
static void gimp_bucket_fill_options_config_iface_init (GimpConfigInterface *config_iface);
|
||||
|
@ -162,6 +164,13 @@ gimp_bucket_fill_options_class_init (GimpBucketFillOptionsClass *klass)
|
|||
0.0, 1.0, 0.92,
|
||||
GIMP_PARAM_STATIC_STRINGS);
|
||||
|
||||
GIMP_CONFIG_PROP_INT (object_class, PROP_LINE_ART_MAX_GROW,
|
||||
"line-art-max-grow",
|
||||
_("Maximum growing size"),
|
||||
_("Maximum number of pixels grown under the line art"),
|
||||
1, 100, 3,
|
||||
GIMP_PARAM_STATIC_STRINGS);
|
||||
|
||||
GIMP_CONFIG_PROP_ENUM (object_class, PROP_FILL_CRITERION,
|
||||
"fill-criterion",
|
||||
_("Fill by"),
|
||||
|
@ -219,6 +228,9 @@ gimp_bucket_fill_options_set_property (GObject *object,
|
|||
case PROP_LINE_ART_THRESHOLD:
|
||||
options->line_art_threshold = g_value_get_double (value);
|
||||
break;
|
||||
case PROP_LINE_ART_MAX_GROW:
|
||||
options->line_art_max_grow = g_value_get_int (value);
|
||||
break;
|
||||
case PROP_FILL_CRITERION:
|
||||
options->fill_criterion = g_value_get_enum (value);
|
||||
gimp_bucket_fill_options_update_criterion (options);
|
||||
|
@ -264,6 +276,9 @@ gimp_bucket_fill_options_get_property (GObject *object,
|
|||
case PROP_LINE_ART_THRESHOLD:
|
||||
g_value_set_double (value, options->line_art_threshold);
|
||||
break;
|
||||
case PROP_LINE_ART_MAX_GROW:
|
||||
g_value_set_int (value, options->line_art_max_grow);
|
||||
break;
|
||||
case PROP_FILL_CRITERION:
|
||||
g_value_set_enum (value, options->fill_criterion);
|
||||
break;
|
||||
|
@ -305,9 +320,11 @@ gimp_bucket_fill_options_update_criterion (GimpBucketFillOptions *options)
|
|||
gtk_widget_hide (options->priv->threshold_scale);
|
||||
|
||||
gtk_widget_show (options->priv->line_art_threshold_scale);
|
||||
gtk_widget_show (options->priv->line_art_grow_scale);
|
||||
break;
|
||||
default:
|
||||
gtk_widget_hide (options->priv->line_art_threshold_scale);
|
||||
gtk_widget_hide (options->priv->line_art_grow_scale);
|
||||
|
||||
gtk_widget_show (options->priv->antialias_checkbox);
|
||||
gtk_widget_show (options->priv->diagonal_neighbors_checkbox);
|
||||
|
@ -404,6 +421,13 @@ gimp_bucket_fill_options_gui (GimpToolOptions *tool_options)
|
|||
options->priv->threshold_scale = scale;
|
||||
gtk_widget_show (scale);
|
||||
|
||||
/* Line Art: max growing size */
|
||||
scale = gimp_prop_spin_scale_new (config, "line-art-max-grow", NULL,
|
||||
1, 5, 0);
|
||||
gtk_box_pack_start (GTK_BOX (vbox2), scale, FALSE, FALSE, 0);
|
||||
options->priv->line_art_grow_scale = scale;
|
||||
gtk_widget_show (scale);
|
||||
|
||||
/* Line Art: stroke threshold */
|
||||
scale = gimp_prop_spin_scale_new (config, "line-art-threshold", NULL,
|
||||
0.05, 0.1, 2);
|
||||
|
|
|
@ -47,6 +47,7 @@ struct _GimpBucketFillOptions
|
|||
gdouble threshold;
|
||||
|
||||
gdouble line_art_threshold;
|
||||
gint line_art_max_grow;
|
||||
|
||||
GimpSelectCriterion fill_criterion;
|
||||
|
||||
|
|
|
@ -398,6 +398,7 @@ gimp_bucket_fill_tool_preview (GimpBucketFillTool *tool,
|
|||
options->sample_merged,
|
||||
options->diagonal_neighbors,
|
||||
options->line_art_threshold,
|
||||
options->line_art_max_grow,
|
||||
x, y, &tool->priv->fill_mask,
|
||||
&x, &y, NULL, NULL);
|
||||
if (line_art)
|
||||
|
|
|
@ -128,6 +128,6 @@ gimp_fuzzy_select_tool_get_mask (GimpRegionSelectTool *region_select,
|
|||
options->select_transparent,
|
||||
options->select_criterion,
|
||||
options->diagonal_neighbors,
|
||||
0.92, /* TODO */
|
||||
0.92, 3, /* TODO */
|
||||
x, y);
|
||||
}
|
||||
|
|
|
@ -175,7 +175,7 @@ HELP
|
|||
GIMP_PDB_CONTEXT (context)->sample_threshold,
|
||||
GIMP_PDB_CONTEXT (context)->sample_merged,
|
||||
GIMP_PDB_CONTEXT (context)->diagonal_neighbors,
|
||||
0.92, /* TODO */
|
||||
0.92, 3, /* TODO */
|
||||
x, y);
|
||||
}
|
||||
else
|
||||
|
|
Loading…
Reference in New Issue