rewrote gimp_bezier_stroke_extend for the case when the neighbor is not

2003-06-26  Simon Budig  <simon@gimp.org>

        * app/vectors/gimpbezierstroke.c: rewrote gimp_bezier_stroke_extend
        for the case when the neighbor is not really an end point of the
        stroke, but close enough to the end to still be acceptable.

        * app/tools/gimpvectortool.c: Make the tool behave sanely
        and more symetrically (both ends of a stroke behave basically the
        same now), gimp_draw_on_handle () now prefers the anchor passed
        into it via the *ret_anchor parameter over other preferred anchors.
This commit is contained in:
Simon Budig 2003-06-26 09:54:56 +00:00 committed by Simon Budig
parent 4e4b91eda1
commit 1a80262e7e
3 changed files with 156 additions and 99 deletions

View File

@ -1,3 +1,14 @@
2003-06-26 Simon Budig <simon@gimp.org>
* app/vectors/gimpbezierstroke.c: rewrote gimp_bezier_stroke_extend
for the case when the neighbor is not really an end point of the
stroke, but close enough to the end to still be acceptable.
* app/tools/gimpvectortool.c: Make the tool behave sanely
and more symetrically (both ends of a stroke behave basically the
same now), gimp_draw_on_handle () now prefers the anchor passed
into it via the *ret_anchor parameter over other preferred anchors.
2003-06-25 Sven Neumann <sven@gimp.org>
* app/text/gimptext-parasite.c (gimp_text_from_gdyntext_parasite):

View File

@ -259,12 +259,79 @@ gimp_vector_tool_button_press (GimpTool *tool,
gdisp->gimage != GIMP_ITEM (vector_tool->vectors)->gimage)
gimp_vector_tool_clear_vectors (vector_tool);
if (vector_tool->vectors &&
gimp_tool_control_is_active (tool->control) && gdisp == tool->gdisp)
if (gimp_tool_control_is_active (tool->control))
{
/* reset everything */
gimp_draw_tool_stop (GIMP_DRAW_TOOL (vector_tool));
}
tool->gdisp = gdisp;
if (! vector_tool->vectors || vector_tool->function == VECTORS_CREATING)
{
if (! vector_tool->vectors)
{
GimpVectors *vectors;
vectors = gimp_vectors_new (gdisp->gimage, _("Unnamed"));
gimp_image_add_vectors (gdisp->gimage, vectors, -1);
vector_tool->vectors = g_object_ref (vectors);
g_signal_connect_object (vectors, "removed",
G_CALLBACK (gimp_vector_tool_clear_vectors),
vector_tool,
G_CONNECT_SWAPPED);
g_signal_connect_object (vectors, "freeze",
G_CALLBACK (gimp_vector_tool_vectors_freeze),
vector_tool,
0);
g_signal_connect_object (vectors, "thaw",
G_CALLBACK (gimp_vector_tool_vectors_thaw),
vector_tool,
0);
}
stroke = gimp_bezier_stroke_new ();
anchor = gimp_bezier_stroke_extend (GIMP_BEZIER_STROKE (stroke), coords,
NULL, EXTEND_EDITABLE);
gimp_vectors_stroke_add (vector_tool->vectors, stroke);
vector_tool->function = VECTORS_MOVING;
/* We want to drag out the control point later */
state |= GDK_CONTROL_MASK;
vector_tool->restriction = GIMP_ANCHOR_FEATURE_SYMMETRIC;
/* start drawing the vector tool */
gimp_draw_tool_start (GIMP_DRAW_TOOL (tool), gdisp);
}
else if (!gimp_vector_tool_on_handle (tool, coords, GIMP_ANCHOR_CONTROL,
gdisp, NULL, NULL))
{
gimp_draw_tool_pause (GIMP_DRAW_TOOL (vector_tool));
/* not on an anchor, we go into ADDING mode */
vector_tool->function = VECTORS_ADDING;
anchor = gimp_bezier_stroke_extend (GIMP_BEZIER_STROKE (vector_tool->cur_stroke),
coords, vector_tool->cur_anchor,
EXTEND_EDITABLE);
if (anchor)
vector_tool->cur_anchor = anchor;
state |= GDK_CONTROL_MASK;
vector_tool->restriction = GIMP_ANCHOR_FEATURE_SYMMETRIC;
gimp_draw_tool_resume (GIMP_DRAW_TOOL (vector_tool));
}
if (state & GDK_CONTROL_MASK && !(state & GDK_SHIFT_MASK))
preferred = GIMP_ANCHOR_CONTROL;
anchor = vector_tool->cur_anchor;
if (gimp_vector_tool_on_handle (tool, coords,
preferred, gdisp, &anchor, &stroke))
{
@ -308,92 +375,7 @@ gimp_vector_tool_button_press (GimpTool *tool,
gimp_draw_tool_resume (GIMP_DRAW_TOOL (vector_tool));
}
else if (vector_tool->vectors) /* not on an anchor */
{
vector_tool->function = VECTORS_ADDING;
}
}
if (! vector_tool->vectors || vector_tool->function == VECTORS_CREATING)
{
if (gimp_tool_control_is_active (tool->control))
{
/* reset everything */
gimp_draw_tool_stop (GIMP_DRAW_TOOL (vector_tool));
}
if (! vector_tool->vectors)
{
GimpVectors *vectors;
vectors = gimp_vectors_new (gdisp->gimage, _("Unnamed"));
gimp_image_add_vectors (gdisp->gimage, vectors, -1);
vector_tool->vectors = g_object_ref (vectors);
g_signal_connect_object (vectors, "removed",
G_CALLBACK (gimp_vector_tool_clear_vectors),
vector_tool,
G_CONNECT_SWAPPED);
g_signal_connect_object (vectors, "freeze",
G_CALLBACK (gimp_vector_tool_vectors_freeze),
vector_tool,
0);
g_signal_connect_object (vectors, "thaw",
G_CALLBACK (gimp_vector_tool_vectors_thaw),
vector_tool,
0);
}
stroke = gimp_bezier_stroke_new ();
anchor = gimp_bezier_stroke_extend (GIMP_BEZIER_STROKE (stroke), coords,
NULL, EXTEND_EDITABLE);
anchor = gimp_stroke_anchor_get (stroke, coords);
gimp_vectors_stroke_add (vector_tool->vectors, stroke);
vector_tool->cur_stroke = stroke;
vector_tool->cur_anchor = anchor;
gimp_stroke_anchor_select (stroke, anchor, TRUE);
vector_tool->function = VECTORS_MOVING;
if (gimp_tool_control_is_active (tool->control))
{
/* gimp_tool_pop_status (tool); */
/* gimp_tool_push_status (tool, ""); */
}
/* start drawing the vector tool */
gimp_draw_tool_start (GIMP_DRAW_TOOL (tool), gdisp);
}
if (vector_tool->function == VECTORS_ADDING)
{
if (gimp_tool_control_is_active (tool->control))
{
/* reset everything */
gimp_draw_tool_stop (GIMP_DRAW_TOOL (vector_tool));
}
anchor = gimp_bezier_stroke_extend (GIMP_BEZIER_STROKE (vector_tool->cur_stroke),
coords, vector_tool->cur_anchor,
EXTEND_EDITABLE);
if (anchor)
vector_tool->cur_anchor = anchor;
if (gimp_tool_control_is_active (tool->control))
{
/* gimp_tool_pop_status (tool); */
/* gimp_tool_push_status (tool, ""); */
}
/* start drawing the vector tool */
gimp_draw_tool_start (GIMP_DRAW_TOOL (tool), gdisp);
}
tool->gdisp = gdisp;
gimp_tool_control_activate (tool->control);
}
@ -417,6 +399,8 @@ gimp_vector_tool_button_release (GimpTool *tool,
viewable = GIMP_VIEWABLE (vector_tool->vectors);
gimp_viewable_invalidate_preview (viewable);
}
gimp_tool_control_halt (tool->control);
}
static void
@ -507,7 +491,7 @@ gimp_vector_tool_on_handle (GimpTool *tool,
dx = coords->x - ((GimpAnchor *) anchor_list->data)->position.x;
dy = coords->y - ((GimpAnchor *) anchor_list->data)->position.y;
if (mindist < 0 || mindist >= dx * dx + dy * dy)
if (mindist < 0 || mindist > dx * dx + dy * dy)
{
mindist = dx * dx + dy * dy;
anchor = (GimpAnchor *) anchor_list->data;
@ -515,7 +499,7 @@ gimp_vector_tool_on_handle (GimpTool *tool,
*ret_stroke = stroke;
}
if ((pref_mindist < 0 || pref_mindist >= dx * dx + dy * dy) &&
if ((pref_mindist < 0 || pref_mindist > dx * dx + dy * dy) &&
((GimpAnchor *) anchor_list->data)->type == preferred)
{
pref_mindist = dx * dx + dy * dy;
@ -529,6 +513,27 @@ gimp_vector_tool_on_handle (GimpTool *tool,
g_list_free (anchor_list);
}
/* If the data passed into ret_anchor is a preferred anchor, return
* it.
*/
if (ret_anchor && *ret_anchor
&& gimp_draw_tool_on_handle (GIMP_DRAW_TOOL (tool), gdisp,
coords->x,
coords->y,
GIMP_HANDLE_CIRCLE,
(*ret_anchor)->position.x,
(*ret_anchor)->position.y,
TARGET,
TARGET,
GTK_ANCHOR_CENTER,
FALSE)
&& (*ret_anchor)->type == preferred)
{
if (ret_stroke)
*ret_stroke = pref_stroke;
return TRUE;
}
if (pref_anchor && gimp_draw_tool_on_handle (GIMP_DRAW_TOOL (tool), gdisp,
coords->x,
coords->y,
@ -672,8 +677,8 @@ gimp_vector_tool_draw (GimpDrawTool *draw_tool)
GIMP_HANDLE_SQUARE,
cur_anchor->position.x,
cur_anchor->position.y,
TARGET - 2,
TARGET - 2,
TARGET - 3,
TARGET - 3,
GTK_ANCHOR_CENTER,
FALSE);
}

View File

@ -230,9 +230,6 @@ gimp_bezier_stroke_extend (GimpBezierStroke *bezier_stroke,
stroke->anchors = g_list_append (stroke->anchors, anchor);
g_printerr ("New Stroke at %f, %f, type %d\n",
coords->x, coords->y, anchor->type);
switch (extend_mode)
{
case EXTEND_SIMPLE:
@ -245,7 +242,7 @@ gimp_bezier_stroke_extend (GimpBezierStroke *bezier_stroke,
gimp_stroke_anchor_select (stroke, anchor, TRUE);
neighbor = gimp_bezier_stroke_extend (bezier_stroke,
anchor = gimp_bezier_stroke_extend (bezier_stroke,
coords, anchor,
EXTEND_SIMPLE);
@ -257,9 +254,13 @@ gimp_bezier_stroke_extend (GimpBezierStroke *bezier_stroke,
}
else
{
/* assure that there is a neighbor specified */
g_return_val_if_fail (neighbor != NULL, NULL);
loose_end = 0;
listneighbor = g_list_last (stroke->anchors);
/* Check if the neighbor is at an end of the control points */
if (listneighbor->data == neighbor)
{
loose_end = 1;
@ -273,8 +274,51 @@ gimp_bezier_stroke_extend (GimpBezierStroke *bezier_stroke,
}
else
{
listneighbor = NULL;
/*
* it isnt. if we are on a handle go to the nearest
* anchor and see if we can find an end from it.
* Yes, this is tedious.
*/
listneighbor = g_list_find (stroke->anchors, neighbor);
if (listneighbor && neighbor->type == GIMP_ANCHOR_CONTROL)
{
if (listneighbor->prev &&
((GimpAnchor *) listneighbor->prev->data)->type == GIMP_ANCHOR_ANCHOR)
{
listneighbor = listneighbor->prev;
}
else if (listneighbor->next &&
((GimpAnchor *) listneighbor->next->data)->type == GIMP_ANCHOR_ANCHOR)
{
listneighbor = listneighbor->next;
}
else
{
loose_end = 0;
listneighbor = NULL;
}
}
if (listneighbor)
/* we found a suitable ANCHOR_ANCHOR now, lets
* search for its loose end.
*/
{
if (listneighbor->prev &&
listneighbor->prev->prev == NULL)
{
loose_end = -1;
listneighbor = listneighbor->prev;
}
else if (listneighbor->next &&
listneighbor->next->next == NULL)
{
loose_end = 1;
listneighbor = listneighbor->next;
}
}
}
}
@ -328,9 +372,6 @@ gimp_bezier_stroke_extend (GimpBezierStroke *bezier_stroke,
"%d successive control handles", control_count);
}
g_printerr ("Extending at %f, %f, type %d\n",
coords->x, coords->y, anchor->type);
if (loose_end == 1)
stroke->anchors = g_list_append (stroke->anchors, anchor);