mirror of https://github.com/GNOME/gimp.git
app: change most of Iscissors to use a GimpPickable not a GimpImage
This is just cleanup and enables adding a mode that doesn't behave like "sample merged".
This commit is contained in:
parent
fbb6b5d425
commit
152c5a2c44
|
@ -164,14 +164,14 @@ static void gimp_iscissors_tool_push_undo (GimpIscissorsTool *
|
||||||
static void gimp_iscissors_tool_pop_undo (GimpIscissorsTool *iscissors);
|
static void gimp_iscissors_tool_pop_undo (GimpIscissorsTool *iscissors);
|
||||||
static void gimp_iscissors_tool_free_redo (GimpIscissorsTool *iscissors);
|
static void gimp_iscissors_tool_free_redo (GimpIscissorsTool *iscissors);
|
||||||
|
|
||||||
static void gimp_iscissors_tool_halt (GimpIscissorsTool *iscissors,
|
static void gimp_iscissors_tool_halt (GimpIscissorsTool *iscissors,
|
||||||
GimpDisplay *display);
|
GimpDisplay *display);
|
||||||
static void gimp_iscissors_tool_commit (GimpIscissorsTool *iscissors,
|
static void gimp_iscissors_tool_commit (GimpIscissorsTool *iscissors,
|
||||||
GimpDisplay *display);
|
GimpDisplay *display);
|
||||||
|
|
||||||
static void iscissors_convert (GimpIscissorsTool *iscissors,
|
static void iscissors_convert (GimpIscissorsTool *iscissors,
|
||||||
GimpDisplay *display);
|
GimpDisplay *display);
|
||||||
static GeglBuffer * gradient_map_new (GimpImage *image);
|
static GeglBuffer * gradient_map_new (GimpPickable *pickable);
|
||||||
|
|
||||||
static void find_optimal_path (GeglBuffer *gradient_map,
|
static void find_optimal_path (GeglBuffer *gradient_map,
|
||||||
GimpTempBuf *dp_buf,
|
GimpTempBuf *dp_buf,
|
||||||
|
@ -182,7 +182,7 @@ static void find_optimal_path (GeglBuffer *gradient_map,
|
||||||
gint xs,
|
gint xs,
|
||||||
gint ys);
|
gint ys);
|
||||||
static void find_max_gradient (GimpIscissorsTool *iscissors,
|
static void find_max_gradient (GimpIscissorsTool *iscissors,
|
||||||
GimpImage *image,
|
GimpPickable *pickable,
|
||||||
gint *x,
|
gint *x,
|
||||||
gint *y);
|
gint *y);
|
||||||
static void calculate_segment (GimpIscissorsTool *iscissors,
|
static void calculate_segment (GimpIscissorsTool *iscissors,
|
||||||
|
@ -418,7 +418,7 @@ gimp_iscissors_tool_button_press (GimpTool *tool,
|
||||||
iscissors->state = SEED_PLACEMENT;
|
iscissors->state = SEED_PLACEMENT;
|
||||||
|
|
||||||
if (! (state & gimp_get_extend_selection_mask ()))
|
if (! (state & gimp_get_extend_selection_mask ()))
|
||||||
find_max_gradient (iscissors, image,
|
find_max_gradient (iscissors, GIMP_PICKABLE (image),
|
||||||
&iscissors->x, &iscissors->y);
|
&iscissors->x, &iscissors->y);
|
||||||
|
|
||||||
iscissors->x = CLAMP (iscissors->x, 0, gimp_image_get_width (image) - 1);
|
iscissors->x = CLAMP (iscissors->x, 0, gimp_image_get_width (image) - 1);
|
||||||
|
@ -743,7 +743,7 @@ gimp_iscissors_tool_motion (GimpTool *tool,
|
||||||
|
|
||||||
/* Hold the shift key down to disable the auto-edge snap feature */
|
/* Hold the shift key down to disable the auto-edge snap feature */
|
||||||
if (! (state & gimp_get_extend_selection_mask ()))
|
if (! (state & gimp_get_extend_selection_mask ()))
|
||||||
find_max_gradient (iscissors, image,
|
find_max_gradient (iscissors, GIMP_PICKABLE (image),
|
||||||
&iscissors->x, &iscissors->y);
|
&iscissors->x, &iscissors->y);
|
||||||
|
|
||||||
iscissors->x = CLAMP (iscissors->x, 0, gimp_image_get_width (image) - 1);
|
iscissors->x = CLAMP (iscissors->x, 0, gimp_image_get_width (image) - 1);
|
||||||
|
@ -1481,13 +1481,22 @@ static void
|
||||||
calculate_segment (GimpIscissorsTool *iscissors,
|
calculate_segment (GimpIscissorsTool *iscissors,
|
||||||
ISegment *segment)
|
ISegment *segment)
|
||||||
{
|
{
|
||||||
GimpDisplay *display = GIMP_TOOL (iscissors)->display;
|
GimpDisplay *display = GIMP_TOOL (iscissors)->display;
|
||||||
GimpImage *image = gimp_display_get_image (display);
|
GimpPickable *pickable = GIMP_PICKABLE (gimp_display_get_image (display));
|
||||||
gint x, y, dir;
|
gint width;
|
||||||
gint xs, ys, xe, ye;
|
gint height;
|
||||||
gint x1, y1, x2, y2;
|
gint xs, ys, xe, ye;
|
||||||
gint width, height;
|
gint x1, y1, x2, y2;
|
||||||
gint ewidth, eheight;
|
gint ewidth, eheight;
|
||||||
|
|
||||||
|
/* Initialise the gradient map buffer for this pickable if we don't
|
||||||
|
* already have one.
|
||||||
|
*/
|
||||||
|
if (! iscissors->gradient_map)
|
||||||
|
iscissors->gradient_map = gradient_map_new (pickable);
|
||||||
|
|
||||||
|
width = gegl_buffer_get_width (iscissors->gradient_map);
|
||||||
|
height = gegl_buffer_get_height (iscissors->gradient_map);
|
||||||
|
|
||||||
/* Calculate the lowest cost path from one vertex to the next as specified
|
/* Calculate the lowest cost path from one vertex to the next as specified
|
||||||
* by the parameter "segment".
|
* by the parameter "segment".
|
||||||
|
@ -1500,10 +1509,10 @@ calculate_segment (GimpIscissorsTool *iscissors,
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/* Get the bounding box */
|
/* Get the bounding box */
|
||||||
xs = CLAMP (segment->x1, 0, gimp_image_get_width (image) - 1);
|
xs = CLAMP (segment->x1, 0, width - 1);
|
||||||
ys = CLAMP (segment->y1, 0, gimp_image_get_height (image) - 1);
|
ys = CLAMP (segment->y1, 0, height - 1);
|
||||||
xe = CLAMP (segment->x2, 0, gimp_image_get_width (image) - 1);
|
xe = CLAMP (segment->x2, 0, width - 1);
|
||||||
ye = CLAMP (segment->y2, 0, gimp_image_get_height (image) - 1);
|
ye = CLAMP (segment->y2, 0, height - 1);
|
||||||
x1 = MIN (xs, xe);
|
x1 = MIN (xs, xe);
|
||||||
y1 = MIN (ys, ye);
|
y1 = MIN (ys, ye);
|
||||||
x2 = MAX (xs, xe) + 1; /* +1 because if xe = 199 & xs = 0, x2 - x1, width = 200 */
|
x2 = MAX (xs, xe) + 1; /* +1 because if xe = 199 & xs = 0, x2 - x1, width = 200 */
|
||||||
|
@ -1520,12 +1529,12 @@ calculate_segment (GimpIscissorsTool *iscissors,
|
||||||
eheight = (y2 - y1) * EXTEND_BY + FIXED;
|
eheight = (y2 - y1) * EXTEND_BY + FIXED;
|
||||||
|
|
||||||
if (xe >= xs)
|
if (xe >= xs)
|
||||||
x2 += CLAMP (ewidth, 0, gimp_image_get_width (image) - x2);
|
x2 += CLAMP (ewidth, 0, width - x2);
|
||||||
else
|
else
|
||||||
x1 -= CLAMP (ewidth, 0, x1);
|
x1 -= CLAMP (ewidth, 0, x1);
|
||||||
|
|
||||||
if (ye >= ys)
|
if (ye >= ys)
|
||||||
y2 += CLAMP (eheight, 0, gimp_image_get_height (image) - y2);
|
y2 += CLAMP (eheight, 0, height - y2);
|
||||||
else
|
else
|
||||||
y1 -= CLAMP (eheight, 0, y1);
|
y1 -= CLAMP (eheight, 0, y1);
|
||||||
|
|
||||||
|
@ -1536,22 +1545,18 @@ calculate_segment (GimpIscissorsTool *iscissors,
|
||||||
segment->points = NULL;
|
segment->points = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* If the bounding box has width and height... */
|
|
||||||
if ((x2 - x1) && (y2 - y1))
|
if ((x2 - x1) && (y2 - y1))
|
||||||
{
|
{
|
||||||
width = (x2 - x1);
|
/* If the bounding box has width and height... */
|
||||||
height = (y2 - y1);
|
|
||||||
|
|
||||||
/* Initialise the gradient map tile manager for this image if we
|
gint bb_width = (x2 - x1);
|
||||||
* don't already have one. */
|
gint bb_height = (y2 - y1);
|
||||||
if (! iscissors->gradient_map)
|
|
||||||
iscissors->gradient_map = gradient_map_new (image);
|
|
||||||
|
|
||||||
/* allocate the dynamic programming array */
|
/* allocate the dynamic programming array */
|
||||||
if (iscissors->dp_buf)
|
if (iscissors->dp_buf)
|
||||||
gimp_temp_buf_unref (iscissors->dp_buf);
|
gimp_temp_buf_unref (iscissors->dp_buf);
|
||||||
|
|
||||||
iscissors->dp_buf = gimp_temp_buf_new (width, height,
|
iscissors->dp_buf = gimp_temp_buf_new (bb_width, bb_height,
|
||||||
babl_format ("Y u32"));
|
babl_format ("Y u32"));
|
||||||
|
|
||||||
/* find the optimal path of pixels from (x1, y1) to (x2, y2) */
|
/* find the optimal path of pixels from (x1, y1) to (x2, y2) */
|
||||||
|
@ -1562,12 +1567,14 @@ calculate_segment (GimpIscissorsTool *iscissors,
|
||||||
segment->points = plot_pixels (iscissors, iscissors->dp_buf,
|
segment->points = plot_pixels (iscissors, iscissors->dp_buf,
|
||||||
x1, y1, xs, ys, xe, ye);
|
x1, y1, xs, ys, xe, ye);
|
||||||
}
|
}
|
||||||
/* If the bounding box has no width */
|
|
||||||
else if ((x2 - x1) == 0)
|
else if ((x2 - x1) == 0)
|
||||||
{
|
{
|
||||||
|
/* If the bounding box has no width */
|
||||||
|
|
||||||
/* plot a vertical line */
|
/* plot a vertical line */
|
||||||
y = ys;
|
gint y = ys;
|
||||||
dir = (ys > ye) ? -1 : 1;
|
gint dir = (ys > ye) ? -1 : 1;
|
||||||
|
|
||||||
segment->points = g_ptr_array_new ();
|
segment->points = g_ptr_array_new ();
|
||||||
while (y != ye)
|
while (y != ye)
|
||||||
{
|
{
|
||||||
|
@ -1575,12 +1582,14 @@ calculate_segment (GimpIscissorsTool *iscissors,
|
||||||
y += dir;
|
y += dir;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
/* If the bounding box has no height */
|
|
||||||
else if ((y2 - y1) == 0)
|
else if ((y2 - y1) == 0)
|
||||||
{
|
{
|
||||||
|
/* If the bounding box has no height */
|
||||||
|
|
||||||
/* plot a horizontal line */
|
/* plot a horizontal line */
|
||||||
x = xs;
|
gint x = xs;
|
||||||
dir = (xs > xe) ? -1 : 1;
|
gint dir = (xs > xe) ? -1 : 1;
|
||||||
|
|
||||||
segment->points = g_ptr_array_new ();
|
segment->points = g_ptr_array_new ();
|
||||||
while (x != xe)
|
while (x != xe)
|
||||||
{
|
{
|
||||||
|
@ -1853,25 +1862,27 @@ find_optimal_path (GeglBuffer *gradient_map,
|
||||||
}
|
}
|
||||||
|
|
||||||
static GeglBuffer *
|
static GeglBuffer *
|
||||||
gradient_map_new (GimpImage *image)
|
gradient_map_new (GimpPickable *pickable)
|
||||||
{
|
{
|
||||||
GeglBuffer *buffer;
|
GeglBuffer *buffer;
|
||||||
GeglTileHandler *handler;
|
GeglTileHandler *handler;
|
||||||
|
|
||||||
|
buffer = gimp_pickable_get_buffer (pickable);
|
||||||
|
|
||||||
buffer = gegl_buffer_new (GEGL_RECTANGLE (0, 0,
|
buffer = gegl_buffer_new (GEGL_RECTANGLE (0, 0,
|
||||||
gimp_image_get_width (image),
|
gegl_buffer_get_width (buffer),
|
||||||
gimp_image_get_height (image)),
|
gegl_buffer_get_height (buffer)),
|
||||||
babl_format_n (babl_type ("u8"), 2));
|
babl_format_n (babl_type ("u8"), 2));
|
||||||
|
|
||||||
handler = gimp_tile_handler_iscissors_new (image);
|
handler = gimp_tile_handler_iscissors_new (pickable);
|
||||||
|
|
||||||
gimp_tile_handler_validate_assign (GIMP_TILE_HANDLER_VALIDATE (handler),
|
gimp_tile_handler_validate_assign (GIMP_TILE_HANDLER_VALIDATE (handler),
|
||||||
buffer);
|
buffer);
|
||||||
|
|
||||||
gimp_tile_handler_validate_invalidate (GIMP_TILE_HANDLER_VALIDATE (handler),
|
gimp_tile_handler_validate_invalidate (GIMP_TILE_HANDLER_VALIDATE (handler),
|
||||||
0, 0,
|
0, 0,
|
||||||
gimp_image_get_width (image),
|
gegl_buffer_get_width (buffer),
|
||||||
gimp_image_get_height (image));
|
gegl_buffer_get_height (buffer));
|
||||||
|
|
||||||
g_object_unref (handler);
|
g_object_unref (handler);
|
||||||
|
|
||||||
|
@ -1880,32 +1891,37 @@ gradient_map_new (GimpImage *image)
|
||||||
|
|
||||||
static void
|
static void
|
||||||
find_max_gradient (GimpIscissorsTool *iscissors,
|
find_max_gradient (GimpIscissorsTool *iscissors,
|
||||||
GimpImage *image,
|
GimpPickable *pickable,
|
||||||
gint *x,
|
gint *x,
|
||||||
gint *y)
|
gint *y)
|
||||||
{
|
{
|
||||||
GeglBufferIterator *iter;
|
GeglBufferIterator *iter;
|
||||||
GeglRectangle *roi;
|
GeglRectangle *roi;
|
||||||
|
gint width;
|
||||||
|
gint height;
|
||||||
gint radius;
|
gint radius;
|
||||||
gint cx, cy;
|
gint cx, cy;
|
||||||
gint x1, y1, x2, y2;
|
gint x1, y1, x2, y2;
|
||||||
gfloat max_gradient;
|
gfloat max_gradient;
|
||||||
|
|
||||||
/* Initialise the gradient map buffer for this image if we don't
|
/* Initialise the gradient map buffer for this pickable if we don't
|
||||||
* already have one.
|
* already have one.
|
||||||
*/
|
*/
|
||||||
if (! iscissors->gradient_map)
|
if (! iscissors->gradient_map)
|
||||||
iscissors->gradient_map = gradient_map_new (image);
|
iscissors->gradient_map = gradient_map_new (pickable);
|
||||||
|
|
||||||
|
width = gegl_buffer_get_width (iscissors->gradient_map);
|
||||||
|
height = gegl_buffer_get_height (iscissors->gradient_map);
|
||||||
|
|
||||||
radius = GRADIENT_SEARCH >> 1;
|
radius = GRADIENT_SEARCH >> 1;
|
||||||
|
|
||||||
/* calculate the extent of the search */
|
/* calculate the extent of the search */
|
||||||
cx = CLAMP (*x, 0, gimp_image_get_width (image));
|
cx = CLAMP (*x, 0, width);
|
||||||
cy = CLAMP (*y, 0, gimp_image_get_height (image));
|
cy = CLAMP (*y, 0, height);
|
||||||
x1 = CLAMP (cx - radius, 0, gimp_image_get_width (image));
|
x1 = CLAMP (cx - radius, 0, width);
|
||||||
y1 = CLAMP (cy - radius, 0, gimp_image_get_height (image));
|
y1 = CLAMP (cy - radius, 0, height);
|
||||||
x2 = CLAMP (cx + radius, 0, gimp_image_get_width (image));
|
x2 = CLAMP (cx + radius, 0, width);
|
||||||
y2 = CLAMP (cy + radius, 0, gimp_image_get_height (image));
|
y2 = CLAMP (cy + radius, 0, height);
|
||||||
/* calculate the factor to multiply the distance from the cursor by */
|
/* calculate the factor to multiply the distance from the cursor by */
|
||||||
|
|
||||||
max_gradient = 0;
|
max_gradient = 0;
|
||||||
|
|
|
@ -28,7 +28,6 @@
|
||||||
|
|
||||||
#include "gegl/gimp-gegl-loops.h"
|
#include "gegl/gimp-gegl-loops.h"
|
||||||
|
|
||||||
#include "core/gimpimage.h"
|
|
||||||
#include "core/gimppickable.h"
|
#include "core/gimppickable.h"
|
||||||
|
|
||||||
#include "gimptilehandleriscissors.h"
|
#include "gimptilehandleriscissors.h"
|
||||||
|
@ -37,7 +36,7 @@
|
||||||
enum
|
enum
|
||||||
{
|
{
|
||||||
PROP_0,
|
PROP_0,
|
||||||
PROP_IMAGE
|
PROP_PICKABLE
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
@ -78,9 +77,9 @@ gimp_tile_handler_iscissors_class_init (GimpTileHandlerIscissorsClass *klass)
|
||||||
|
|
||||||
validate_class->validate = gimp_tile_handler_iscissors_validate;
|
validate_class->validate = gimp_tile_handler_iscissors_validate;
|
||||||
|
|
||||||
g_object_class_install_property (object_class, PROP_IMAGE,
|
g_object_class_install_property (object_class, PROP_PICKABLE,
|
||||||
g_param_spec_object ("image", NULL, NULL,
|
g_param_spec_object ("pickable", NULL, NULL,
|
||||||
GIMP_TYPE_IMAGE,
|
GIMP_TYPE_PICKABLE,
|
||||||
GIMP_PARAM_READWRITE |
|
GIMP_PARAM_READWRITE |
|
||||||
G_PARAM_CONSTRUCT_ONLY));
|
G_PARAM_CONSTRUCT_ONLY));
|
||||||
}
|
}
|
||||||
|
@ -95,10 +94,10 @@ gimp_tile_handler_iscissors_finalize (GObject *object)
|
||||||
{
|
{
|
||||||
GimpTileHandlerIscissors *iscissors = GIMP_TILE_HANDLER_ISCISSORS (object);
|
GimpTileHandlerIscissors *iscissors = GIMP_TILE_HANDLER_ISCISSORS (object);
|
||||||
|
|
||||||
if (iscissors->image)
|
if (iscissors->pickable)
|
||||||
{
|
{
|
||||||
g_object_unref (iscissors->image);
|
g_object_unref (iscissors->pickable);
|
||||||
iscissors->image = NULL;
|
iscissors->pickable = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
G_OBJECT_CLASS (parent_class)->finalize (object);
|
G_OBJECT_CLASS (parent_class)->finalize (object);
|
||||||
|
@ -114,8 +113,8 @@ gimp_tile_handler_iscissors_set_property (GObject *object,
|
||||||
|
|
||||||
switch (property_id)
|
switch (property_id)
|
||||||
{
|
{
|
||||||
case PROP_IMAGE:
|
case PROP_PICKABLE:
|
||||||
iscissors->image = g_value_dup_object (value);
|
iscissors->pickable = g_value_dup_object (value);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
|
@ -134,8 +133,8 @@ gimp_tile_handler_iscissors_get_property (GObject *object,
|
||||||
|
|
||||||
switch (property_id)
|
switch (property_id)
|
||||||
{
|
{
|
||||||
case PROP_IMAGE:
|
case PROP_PICKABLE:
|
||||||
g_value_set_object (value, iscissors->image);
|
g_value_set_object (value, iscissors->pickable);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
|
@ -197,9 +196,9 @@ gimp_tile_handler_iscissors_validate (GimpTileHandlerValidate *validate,
|
||||||
rect->height);
|
rect->height);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
gimp_pickable_flush (GIMP_PICKABLE (iscissors->image));
|
gimp_pickable_flush (iscissors->pickable);
|
||||||
|
|
||||||
src = gimp_pickable_get_buffer (GIMP_PICKABLE (iscissors->image));
|
src = gimp_pickable_get_buffer (iscissors->pickable);
|
||||||
|
|
||||||
temp0 = gegl_buffer_new (GEGL_RECTANGLE (0, 0,
|
temp0 = gegl_buffer_new (GEGL_RECTANGLE (0, 0,
|
||||||
rect->width,
|
rect->width,
|
||||||
|
@ -321,12 +320,12 @@ gimp_tile_handler_iscissors_validate (GimpTileHandlerValidate *validate,
|
||||||
}
|
}
|
||||||
|
|
||||||
GeglTileHandler *
|
GeglTileHandler *
|
||||||
gimp_tile_handler_iscissors_new (GimpImage *image)
|
gimp_tile_handler_iscissors_new (GimpPickable *pickable)
|
||||||
{
|
{
|
||||||
g_return_val_if_fail (GIMP_IS_IMAGE (image), NULL);
|
g_return_val_if_fail (GIMP_IS_PICKABLE (pickable), NULL);
|
||||||
|
|
||||||
return g_object_new (GIMP_TYPE_TILE_HANDLER_ISCISSORS,
|
return g_object_new (GIMP_TYPE_TILE_HANDLER_ISCISSORS,
|
||||||
"whole-tile", TRUE,
|
"whole-tile", TRUE,
|
||||||
"image", image,
|
"pickable", pickable,
|
||||||
NULL);
|
NULL);
|
||||||
}
|
}
|
||||||
|
|
|
@ -42,7 +42,7 @@ struct _GimpTileHandlerIscissors
|
||||||
{
|
{
|
||||||
GimpTileHandlerValidate parent_instance;
|
GimpTileHandlerValidate parent_instance;
|
||||||
|
|
||||||
GimpImage *image;
|
GimpPickable *pickable;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct _GimpTileHandlerIscissorsClass
|
struct _GimpTileHandlerIscissorsClass
|
||||||
|
@ -53,7 +53,7 @@ struct _GimpTileHandlerIscissorsClass
|
||||||
|
|
||||||
GType gimp_tile_handler_iscissors_get_type (void) G_GNUC_CONST;
|
GType gimp_tile_handler_iscissors_get_type (void) G_GNUC_CONST;
|
||||||
|
|
||||||
GeglTileHandler * gimp_tile_handler_iscissors_new (GimpImage *image);
|
GeglTileHandler * gimp_tile_handler_iscissors_new (GimpPickable *pickable);
|
||||||
|
|
||||||
|
|
||||||
#endif /* __GIMP_TILE_HANDLER_ISCISSORS_H__ */
|
#endif /* __GIMP_TILE_HANDLER_ISCISSORS_H__ */
|
||||||
|
|
Loading…
Reference in New Issue