mirror of https://github.com/GNOME/gimp.git
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:
parent
8f9ec0650f
commit
06da10bc08
|
@ -373,30 +373,15 @@ boundary_transform (const BoundSeg *segs,
|
|||
|
||||
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;
|
||||
gdouble x1, y1, x2, y2;
|
||||
|
||||
gimp_matrix3_transform_point (matrix, segs[i].x1, segs[i].y1, &x1, &y1);
|
||||
gimp_matrix3_transform_point (matrix, segs[i].x2, segs[i].y2, &x2, &y2);
|
||||
gimp_matrix3_transform_point (matrix, segs[i].x1, segs[i].y1, &x1, &y1);
|
||||
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),
|
||||
segs[i].open);
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Keep the sorting sentinel */
|
||||
boundary_add_seg (boundary,
|
||||
-1, -1,
|
||||
-1, -1,
|
||||
segs[i].open);
|
||||
}
|
||||
boundary_add_seg (boundary,
|
||||
RINT (x1), RINT (y1),
|
||||
RINT (x2), RINT (y2),
|
||||
segs[i].open);
|
||||
}
|
||||
|
||||
*num_segs = boundary->num_segs;
|
||||
|
|
|
@ -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];
|
||||
}
|
||||
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);
|
||||
/* If it is vertical */
|
||||
if (segs[i].x1 == segs[i].x2)
|
||||
{
|
||||
segs[i].x1 -= 1;
|
||||
segs[i].x2 -= 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
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);
|
||||
|
||||
|
@ -289,21 +268,15 @@ gimp_canvas_boundary_get_extents (GimpCanvasItem *item,
|
|||
|
||||
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;
|
||||
gint x4 = x3 + 3;
|
||||
gint y4 = y3 + 3;
|
||||
gint x3 = segs[i].x1 - 1;
|
||||
gint y3 = segs[i].y1 - 1;
|
||||
gint x4 = x3 + 3;
|
||||
gint y4 = y3 + 3;
|
||||
|
||||
x1 = MIN (x1, x3);
|
||||
y1 = MIN (y1, y3);
|
||||
x2 = MAX (x2, x4);
|
||||
y2 = MAX (y2, y4);
|
||||
}
|
||||
x1 = MIN (x1, x3);
|
||||
y1 = MIN (y1, y3);
|
||||
x2 = MAX (x2, x4);
|
||||
y2 = MAX (y2, y4);
|
||||
}
|
||||
|
||||
g_free (segs);
|
||||
|
|
|
@ -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++)
|
||||
{
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -997,9 +997,7 @@ gimp_brush_core_create_bound_segs (GimpBrushCore *core,
|
|||
|
||||
if (mask)
|
||||
{
|
||||
PixelRegion PR = { 0, };
|
||||
BoundSeg *boundary;
|
||||
gint num_groups;
|
||||
PixelRegion PR = { 0, };
|
||||
|
||||
pixel_region_init_temp_buf (&PR, mask,
|
||||
0, 0, mask->width, mask->height);
|
||||
|
@ -1010,19 +1008,10 @@ 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,
|
||||
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_segs = boundary_find (&PR, BOUNDARY_WITHIN_BOUNDS,
|
||||
0, 0, PR.w, PR.h,
|
||||
0,
|
||||
&core->n_brush_bound_segs);
|
||||
|
||||
core->brush_bound_width = mask->width;
|
||||
core->brush_bound_height = mask->height;
|
||||
|
|
|
@ -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)
|
||||
{
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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,23 +965,17 @@ 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);
|
||||
segs_in[i].x1 = RINT (tx);
|
||||
segs_in[i].y1 = RINT (ty);
|
||||
gimp_matrix3_transform_point (&matrix,
|
||||
segs_in[i].x1, segs_in[i].y1,
|
||||
&tx, &ty);
|
||||
segs_in[i].x1 = RINT (tx);
|
||||
segs_in[i].y1 = RINT (ty);
|
||||
|
||||
gimp_matrix3_transform_point (&matrix,
|
||||
segs_in[i].x2, segs_in[i].y2,
|
||||
&tx, &ty);
|
||||
segs_in[i].x2 = RINT (tx);
|
||||
segs_in[i].y2 = RINT (ty);
|
||||
}
|
||||
gimp_matrix3_transform_point (&matrix,
|
||||
segs_in[i].x2, segs_in[i].y2,
|
||||
&tx, &ty);
|
||||
segs_in[i].x2 = RINT (tx);
|
||||
segs_in[i].y2 = RINT (ty);
|
||||
}
|
||||
|
||||
gimp_draw_tool_add_boundary (draw_tool,
|
||||
|
@ -1000,23 +990,17 @@ 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);
|
||||
segs_out[i].x1 = RINT (tx);
|
||||
segs_out[i].y1 = RINT (ty);
|
||||
gimp_matrix3_transform_point (&matrix,
|
||||
segs_out[i].x1, segs_out[i].y1,
|
||||
&tx, &ty);
|
||||
segs_out[i].x1 = RINT (tx);
|
||||
segs_out[i].y1 = RINT (ty);
|
||||
|
||||
gimp_matrix3_transform_point (&matrix,
|
||||
segs_out[i].x2, segs_out[i].y2,
|
||||
&tx, &ty);
|
||||
segs_out[i].x2 = RINT (tx);
|
||||
segs_out[i].y2 = RINT (ty);
|
||||
}
|
||||
gimp_matrix3_transform_point (&matrix,
|
||||
segs_out[i].x2, segs_out[i].y2,
|
||||
&tx, &ty);
|
||||
segs_out[i].x2 = RINT (tx);
|
||||
segs_out[i].y2 = RINT (ty);
|
||||
}
|
||||
|
||||
gimp_draw_tool_add_boundary (draw_tool,
|
||||
|
|
Loading…
Reference in New Issue