app: change boundary drawing by tools to work like the selection

- GimpCanvasBoundary takes unsorted BoundSeg arrays now and uses
  gimp_display_shell_transform_boundary() and gimp_cairo_add_boundary().
- Nobody calls boundary_sort() any longer for the purpose of displaying
  a boundary.
- gimp_display_shell_transform_boundary() got offset parameters
  so it can transform things that are not in the image's coordinate
  system.
This commit is contained in:
Michael Natterer 2010-09-26 22:41:04 +02:00
parent 8f9ec0650f
commit 06da10bc08
9 changed files with 96 additions and 176 deletions

View file

@ -372,12 +372,6 @@ boundary_transform (const BoundSeg *segs,
gint i;
for (i = 0; i < *num_segs; i++)
{
/* dont transform sorting sentinels */
if (!(segs[i].x1 == -1 &&
segs[i].y1 == -1 &&
segs[i].x2 == -1 &&
segs[i].y2 == -1))
{
gdouble x1, y1, x2, y2;
@ -385,19 +379,10 @@ boundary_transform (const BoundSeg *segs,
gimp_matrix3_transform_point (matrix, segs[i].x2, segs[i].y2, &x2, &y2);
boundary_add_seg (boundary,
(gint) ceil(x1), (gint) ceil(y1),
(gint) ceil(x2), (gint) ceil(y2),
RINT (x1), RINT (y1),
RINT (x2), RINT (y2),
segs[i].open);
}
else
{
/* Keep the sorting sentinel */
boundary_add_seg (boundary,
-1, -1,
-1, -1,
segs[i].open);
}
}
*num_segs = boundary->num_segs;

View file

@ -32,6 +32,8 @@
#include "core/gimpparamspecs.h"
#include "widgets/gimpcairo.h"
#include "gimpcanvasboundary.h"
#include "gimpdisplayshell.h"
#include "gimpdisplayshell-transform.h"
@ -121,6 +123,8 @@ gimp_canvas_boundary_class_init (GimpCanvasBoundaryClass *klass)
static void
gimp_canvas_boundary_init (GimpCanvasBoundary *boundary)
{
gimp_canvas_item_set_line_cap (GIMP_CANVAS_ITEM (boundary),
CAIRO_LINE_CAP_SQUARE);
}
static void
@ -191,36 +195,35 @@ gimp_canvas_boundary_get_property (GObject *object,
static void
gimp_canvas_boundary_transform (GimpCanvasItem *item,
GimpDisplayShell *shell,
BoundSeg *segs)
GdkSegment *segs)
{
GimpCanvasBoundaryPrivate *private = GET_PRIVATE (item);
gint i;
gimp_display_shell_transform_segments (shell,
private->segs, segs, private->n_segs,
private->offset_x, private->offset_y);
for (i = 0; i < private->n_segs; i++)
{
if (private->segs[i].x1 == -1 &&
private->segs[i].y1 == -1 &&
private->segs[i].x2 == -1 &&
private->segs[i].y2 == -1)
/* If this segment is a closing segment && the segments lie inside
* the region, OR if this is an opening segment and the segments
* lie outside the region...
* we need to transform it by one display pixel
*/
if (! private->segs[i].open)
{
segs[i] = private->segs[i];
/* If it is vertical */
if (segs[i].x1 == segs[i].x2)
{
segs[i].x1 -= 1;
segs[i].x2 -= 1;
}
else
{
gimp_display_shell_transform_xy (shell,
private->segs[i].x1 +
private->offset_x,
private->segs[i].y1 +
private->offset_y,
&segs[i].x1,
&segs[i].y1);
gimp_display_shell_transform_xy (shell,
private->segs[i].x2 +
private->offset_x,
private->segs[i].y2 +
private->offset_y,
&segs[i].x2,
&segs[i].y2);
segs[i].y1 -= 1;
segs[i].y2 -= 1;
}
}
}
}
@ -231,38 +234,14 @@ gimp_canvas_boundary_draw (GimpCanvasItem *item,
cairo_t *cr)
{
GimpCanvasBoundaryPrivate *private = GET_PRIVATE (item);
BoundSeg *segs;
gint i;
GdkSegment *segs;
segs = g_new0 (BoundSeg, private->n_segs);
segs = g_new0 (GdkSegment, private->n_segs);
gimp_canvas_boundary_transform (item, shell, segs);
cairo_move_to (cr, segs[0].x1 + 0.5, segs[0].y1 + 0.5);
gimp_cairo_add_segments (cr, segs, private->n_segs);
for (i = 1; i < private->n_segs; i++)
{
if (segs[i].x1 == -1 &&
segs[i].y1 == -1 &&
segs[i].x2 == -1 &&
segs[i].y2 == -1)
{
cairo_close_path (cr);
_gimp_canvas_item_stroke (item, shell, cr);
i++;
if (i == private->n_segs)
break;
cairo_move_to (cr, segs[i].x1 + 0.5, segs[i].y1 + 0.5);
}
else
{
cairo_line_to (cr, segs[i].x1 + 0.5, segs[i].y1 + 0.5);
}
}
cairo_close_path (cr);
_gimp_canvas_item_stroke (item, shell, cr);
g_free (segs);
@ -274,11 +253,11 @@ gimp_canvas_boundary_get_extents (GimpCanvasItem *item,
{
GimpCanvasBoundaryPrivate *private = GET_PRIVATE (item);
GdkRectangle rectangle;
BoundSeg *segs;
GdkSegment *segs;
gint x1, y1, x2, y2;
gint i;
segs = g_new0 (BoundSeg, private->n_segs);
segs = g_new0 (GdkSegment, private->n_segs);
gimp_canvas_boundary_transform (item, shell, segs);
@ -288,11 +267,6 @@ gimp_canvas_boundary_get_extents (GimpCanvasItem *item,
y2 = y1 + 3;
for (i = 1; i < private->n_segs; i++)
{
if (segs[i].x1 != -1 ||
segs[i].y1 != -1 ||
segs[i].x2 != -1 ||
segs[i].y2 != -1)
{
gint x3 = segs[i].x1 - 1;
gint y3 = segs[i].y1 - 1;
@ -304,7 +278,6 @@ gimp_canvas_boundary_get_extents (GimpCanvasItem *item,
x2 = MAX (x2, x4);
y2 = MAX (y2, y4);
}
}
g_free (segs);

View file

@ -409,7 +409,8 @@ selection_transform_segs (Selection *selection,
gint i;
gimp_display_shell_transform_segments (selection->shell,
src_segs, dest_segs, n_segs);
src_segs, dest_segs, n_segs,
0.0, 0.0);
for (i = 0; i < n_segs; i++)
{

View file

@ -307,7 +307,9 @@ void
gimp_display_shell_transform_segments (const GimpDisplayShell *shell,
const BoundSeg *src_segs,
GdkSegment *dest_segs,
gint n_segs)
gint n_segs,
gdouble offset_x,
gdouble offset_y)
{
gint i;
@ -315,23 +317,18 @@ gimp_display_shell_transform_segments (const GimpDisplayShell *shell,
for (i = 0; i < n_segs ; i++)
{
gint64 x1, x2;
gint64 y1, y2;
gdouble x1, x2;
gdouble y1, y2;
x1 = src_segs[i].x1;
x2 = src_segs[i].x2;
y1 = src_segs[i].y1;
y2 = src_segs[i].y2;
x1 = src_segs[i].x1 + offset_x;
x2 = src_segs[i].x2 + offset_x;
y1 = src_segs[i].y1 + offset_y;
y2 = src_segs[i].y2 + offset_y;
x1 = (x1 * shell->x_src_dec) / shell->x_dest_inc;
x2 = (x2 * shell->x_src_dec) / shell->x_dest_inc;
y1 = (y1 * shell->y_src_dec) / shell->y_dest_inc;
y2 = (y2 * shell->y_src_dec) / shell->y_dest_inc;
dest_segs[i].x1 = CLAMP (x1 - shell->offset_x, G_MININT, G_MAXINT);
dest_segs[i].x2 = CLAMP (x2 - shell->offset_x, G_MININT, G_MAXINT);
dest_segs[i].y1 = CLAMP (y1 - shell->offset_y, G_MININT, G_MAXINT);
dest_segs[i].y2 = CLAMP (y2 - shell->offset_y, G_MININT, G_MAXINT);
dest_segs[i].x1 = SCALEX (shell, x1) - shell->offset_x;
dest_segs[i].x2 = SCALEX (shell, x2) - shell->offset_x;
dest_segs[i].y1 = SCALEY (shell, y1) - shell->offset_y;
dest_segs[i].y2 = SCALEY (shell, y2) - shell->offset_y;
}
}

View file

@ -60,7 +60,9 @@ void gimp_display_shell_transform_coords (const GimpDisplayShell *shell,
void gimp_display_shell_transform_segments (const GimpDisplayShell *shell,
const BoundSeg *src_segs,
GdkSegment *dest_segs,
gint n_segs);
gint n_segs,
gdouble offset_x,
gdouble offset_y);
void gimp_display_shell_untransform_viewport (const GimpDisplayShell *shell,
gint *x,

View file

@ -998,8 +998,6 @@ gimp_brush_core_create_bound_segs (GimpBrushCore *core,
if (mask)
{
PixelRegion PR = { 0, };
BoundSeg *boundary;
gint num_groups;
pixel_region_init_temp_buf (&PR, mask,
0, 0, mask->width, mask->height);
@ -1010,20 +1008,11 @@ gimp_brush_core_create_bound_segs (GimpBrushCore *core,
if (mask->width > 32 && mask->height > 32)
smooth_region (&PR);
boundary = boundary_find (&PR, BOUNDARY_WITHIN_BOUNDS,
core->brush_bound_segs = boundary_find (&PR, BOUNDARY_WITHIN_BOUNDS,
0, 0, PR.w, PR.h,
0,
&core->n_brush_bound_segs);
core->brush_bound_segs = boundary_sort (boundary,
core->n_brush_bound_segs,
&num_groups);
core->n_brush_bound_segs += num_groups;
g_free (boundary);
core->brush_bound_width = mask->width;
core->brush_bound_height = mask->height;

View file

@ -194,7 +194,6 @@ gimp_edit_selection_tool_start (GimpTool *parent_tool,
gint off_x, off_y;
const BoundSeg *segs_in;
const BoundSeg *segs_out;
gint num_groups;
const gchar *undo_desc;
edit_select = g_object_new (GIMP_TYPE_EDIT_SELECTION_TOOL,
@ -281,13 +280,11 @@ gimp_edit_selection_tool_start (GimpTool *parent_tool,
&edit_select->num_segs_in, &edit_select->num_segs_out,
0, 0, 0, 0);
edit_select->segs_in = boundary_sort (segs_in, edit_select->num_segs_in,
&num_groups);
edit_select->num_segs_in += num_groups;
edit_select->segs_in = g_memdup (segs_in,
edit_select->num_segs_in * sizeof (BoundSeg));
edit_select->segs_out = boundary_sort (segs_out, edit_select->num_segs_out,
&num_groups);
edit_select->num_segs_out += num_groups;
edit_select->segs_out = g_memdup (segs_out,
edit_select->num_segs_out * sizeof (BoundSeg));
if (edit_select->edit_mode == GIMP_TRANSLATE_MODE_VECTORS)
{

View file

@ -342,9 +342,7 @@ gimp_region_select_tool_calculate (GimpRegionSelectTool *region_sel,
{
GimpDisplayShell *shell = gimp_display_get_shell (display);
BoundSeg *segs;
BoundSeg *sorted;
PixelRegion maskPR;
gint n_groups;
gimp_display_shell_set_override_cursor (shell, GDK_WATCH);
@ -380,13 +378,7 @@ gimp_region_select_tool_calculate (GimpRegionSelectTool *region_sel,
BOUNDARY_HALF_WAY,
n_segs);
sorted = boundary_sort (segs, *n_segs, &n_groups);
*n_segs += n_groups;
g_free (segs);
gimp_display_shell_unset_override_cursor (shell);
return sorted;
return segs;
}

View file

@ -949,7 +949,6 @@ gimp_transform_tool_draw (GimpDrawTool *draw_tool)
BoundSeg *segs_out;
gint num_segs_in;
gint num_segs_out;
gint num_groups;
gint i;
gimp_channel_boundary (gimp_image_get_mask (image),
@ -957,11 +956,8 @@ gimp_transform_tool_draw (GimpDrawTool *draw_tool)
&num_segs_in, &num_segs_out,
0, 0, 0, 0);
segs_in = boundary_sort (orig_in, num_segs_in, &num_groups);
num_segs_in += num_groups;
segs_out = boundary_sort (orig_out, num_segs_out, &num_groups);
num_segs_out += num_groups;
segs_in = g_memdup (orig_in, num_segs_in * sizeof (BoundSeg));
segs_out = g_memdup (orig_out, num_segs_out * sizeof (BoundSeg));
if (segs_in)
{
@ -969,11 +965,6 @@ gimp_transform_tool_draw (GimpDrawTool *draw_tool)
{
gdouble tx, ty;
if (segs_in[i].x1 != -1 &&
segs_in[i].y1 != -1 &&
segs_in[i].x2 != -1 &&
segs_in[i].y2 != -1)
{
gimp_matrix3_transform_point (&matrix,
segs_in[i].x1, segs_in[i].y1,
&tx, &ty);
@ -986,7 +977,6 @@ gimp_transform_tool_draw (GimpDrawTool *draw_tool)
segs_in[i].x2 = RINT (tx);
segs_in[i].y2 = RINT (ty);
}
}
gimp_draw_tool_add_boundary (draw_tool,
segs_in, num_segs_in,
@ -1000,11 +990,6 @@ gimp_transform_tool_draw (GimpDrawTool *draw_tool)
{
gdouble tx, ty;
if (segs_out[i].x1 != -1 &&
segs_out[i].y1 != -1 &&
segs_out[i].x2 != -1 &&
segs_out[i].y2 != -1)
{
gimp_matrix3_transform_point (&matrix,
segs_out[i].x1, segs_out[i].y1,
&tx, &ty);
@ -1017,7 +1002,6 @@ gimp_transform_tool_draw (GimpDrawTool *draw_tool)
segs_out[i].x2 = RINT (tx);
segs_out[i].y2 = RINT (ty);
}
}
gimp_draw_tool_add_boundary (draw_tool,
segs_out, num_segs_out,