Commit 7f706974 authored by Simon Budig's avatar Simon Budig Committed by Simon Budig

app/tools/gimpdrawtool.c Added function gimp_draw_tool_draw_strokes to be

2002-02-26  Simon Budig  <simon@gimp.org>

        * app/tools/gimpdrawtool.c
        * app/tools/gimpdrawtool.h: Added function gimp_draw_tool_draw_strokes
        to be able to draw lines from a GimpCoords array.

        * app/vectors/gimpanchor.h: removed "active", since this should
        be a GUI thing.

        * app/vectors/gimpstroke.c
        * app/vectors/gimpstroke.h
        * app/vectors/gimpbezierstroke.c
        * app/vectors/gimpbezierstroke.h: Implemented (and fixed API) for
        interpolation.

        * app/tools/gimpvectortool.c
        * app/tools/gimpvectortool.h: Changed accordingly, we can actually
        draw polylines now.
parent b20880ad
2002-02-26 Simon Budig <simon@gimp.org>
* app/tools/gimpdrawtool.c
* app/tools/gimpdrawtool.h: Added function gimp_draw_tool_draw_strokes
to be able to draw lines from a GimpCoords array.
* app/vectors/gimpanchor.h: removed "active", since this should
be a GUI thing.
* app/vectors/gimpstroke.c
* app/vectors/gimpstroke.h
* app/vectors/gimpbezierstroke.c
* app/vectors/gimpbezierstroke.h: Implemented (and fixed API) for
interpolation.
* app/tools/gimpvectortool.c
* app/tools/gimpvectortool.h: Changed accordingly, we can actually
draw polylines now.
2002-02-26 Michael Natterer <mitch@gimp.org>
* app/undo.[ch]: renamed undo_push_layer_rename() to
......
......@@ -721,6 +721,47 @@ gimp_draw_tool_draw_lines (GimpDrawTool *draw_tool,
g_free (coords);
}
void
gimp_draw_tool_draw_strokes (GimpDrawTool *draw_tool,
GimpCoords *points,
gint npoints,
gint filled)
{
GimpDisplayShell *shell;
GdkPoint *coords;
gint i;
gdouble sx, sy;
shell = GIMP_DISPLAY_SHELL (draw_tool->gdisp->shell);
coords = g_new (GdkPoint, npoints);
for (i = 0; i < npoints ; i++)
{
gdisplay_transform_coords_f (draw_tool->gdisp,
points[i].x, points[i].y,
&sx, &sy,
TRUE);
coords[i].x = ROUND (sx);
coords[i].y = ROUND (sy);
}
if (filled)
{
gdk_draw_polygon (draw_tool->win,
draw_tool->gc, TRUE,
coords, npoints);
}
else
{
gdk_draw_lines (draw_tool->win,
draw_tool->gc,
coords, npoints);
}
g_free (coords);
}
/* private functions */
......
......@@ -174,5 +174,10 @@ void gimp_draw_tool_draw_lines (GimpDrawTool *draw_tool,
gint npoints,
gint filled);
void gimp_draw_tool_draw_strokes (GimpDrawTool *draw_tool,
GimpCoords *points,
gint npoints,
gint filled);
#endif /* __GIMP_DRAW_TOOL_H__ */
......@@ -80,6 +80,7 @@ struct _VectorOptions
/* local function prototypes */
static void gimp_vector_tool_class_init (GimpVectorToolClass *klass);
static void gimp_vector_tool_init (GimpVectorTool *tool);
static void gimp_vector_tool_finalize (GObject *object);
static void gimp_vector_tool_control (GimpTool *tool,
GimpToolAction action,
......@@ -162,14 +163,17 @@ gimp_vector_tool_get_type (void)
static void
gimp_vector_tool_class_init (GimpVectorToolClass *klass)
{
GObjectClass *object_class;
GimpToolClass *tool_class;
GimpDrawToolClass *draw_tool_class;
object_class = G_OBJECT_CLASS (klass);
tool_class = GIMP_TOOL_CLASS (klass);
draw_tool_class = GIMP_DRAW_TOOL_CLASS (klass);
parent_class = g_type_class_peek_parent (klass);
object_class->finalize = gimp_vector_tool_finalize;
tool_class->control = gimp_vector_tool_control;
tool_class->button_press = gimp_vector_tool_button_press;
tool_class->button_release = gimp_vector_tool_button_release;
......@@ -190,9 +194,25 @@ gimp_vector_tool_init (GimpVectorTool *vector_tool)
tool->preserve = TRUE; /* Preserve on drawable change */
vector_tool->vectors = g_object_new (GIMP_TYPE_VECTORS, 0);
vector_tool->vectors = NULL;
vector_tool->active_anchors = NULL;
vector_tool->function = VECTORS_CREATING;
}
static void
gimp_vector_tool_finalize (GObject *object)
{
GimpVectorTool *vector_tool = GIMP_VECTOR_TOOL (object);
if (vector_tool->vectors)
g_object_unref (G_OBJECT (vector_tool->vectors));
G_OBJECT_CLASS (parent_class)->finalize (object);
}
static void
gimp_vector_tool_control (GimpTool *tool,
GimpToolAction action,
......@@ -222,6 +242,7 @@ gimp_vector_tool_control (GimpTool *tool,
GIMP_TOOL_CLASS (parent_class)->control (tool, action, gdisp);
}
static void
gimp_vector_tool_button_press (GimpTool *tool,
GimpCoords *coords,
......@@ -232,8 +253,6 @@ gimp_vector_tool_button_press (GimpTool *tool,
GimpVectorTool *vector_tool;
VectorOptions *options;
GimpDisplayShell *shell;
gint i;
GimpCoords cur_point;
GimpAnchor *anchor = NULL;
GimpStroke *stroke = NULL;
......@@ -249,15 +268,12 @@ gimp_vector_tool_button_press (GimpTool *tool,
gimp_tool_pop_status (tool);
}
vector_tool->function = VCREATING;
if (tool->state == ACTIVE && gdisp == tool->gdisp)
{
/* if the cursor is in one of the handles,
* the new function will be moving or adding a new point or guide
*/
anchor = gimp_vectors_anchor_get (vector_tool->vectors, coords, &stroke);
if (anchor && gimp_draw_tool_on_handle (GIMP_DRAW_TOOL (tool), gdisp,
......@@ -270,14 +286,14 @@ gimp_vector_tool_button_press (GimpTool *tool,
GTK_ANCHOR_CENTER,
FALSE))
{
vector_tool->function = VMOVING;
vector_tool->function = VECTORS_MOVING;
vector_tool->cur_stroke = stroke;
vector_tool->cur_anchor = anchor;
}
}
if (vector_tool->function == VCREATING)
if (vector_tool->function == VECTORS_CREATING)
{
if (tool->state == ACTIVE)
{
......@@ -292,7 +308,31 @@ gimp_vector_tool_button_press (GimpTool *tool,
vector_tool->cur_stroke = stroke;
vector_tool->cur_anchor = anchor;
vector_tool->function = VMOVING;
vector_tool->function = VECTORS_MOVING;
/* set the gdisplay */
tool->gdisp = gdisp;
if (tool->state == ACTIVE)
{
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 (tool->state == ACTIVE)
{
/* 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);
vector_tool->cur_anchor = anchor;
/* set the gdisplay */
tool->gdisp = gdisp;
......@@ -321,7 +361,7 @@ gimp_vector_tool_button_release (GimpTool *tool,
vector_tool = GIMP_VECTOR_TOOL (tool);
vector_tool->function = VFINISHED;
vector_tool->function = VECTORS_ADDING;
}
static void
......@@ -333,7 +373,6 @@ gimp_vector_tool_motion (GimpTool *tool,
{
GimpVectorTool *vector_tool;
VectorOptions *options;
gint tmp;
GimpAnchor *anchor;
vector_tool = GIMP_VECTOR_TOOL (tool);
......@@ -344,7 +383,7 @@ gimp_vector_tool_motion (GimpTool *tool,
switch (vector_tool->function)
{
case VMOVING:
case VECTORS_MOVING:
/* if we are moving the start point and only have two, make it the end point */
anchor = vector_tool->cur_anchor;
......@@ -370,7 +409,6 @@ gimp_vector_tool_cursor_update (GimpTool *tool,
gboolean in_handle = FALSE;
GdkCursorType ctype = GIMP_MOUSE_CURSOR;
GimpCursorModifier cmodifier = GIMP_CURSOR_MODIFIER_NONE;
gint i;
GimpAnchor *anchor;
vector_tool = GIMP_VECTOR_TOOL (tool);
......@@ -403,121 +441,38 @@ gimp_vector_tool_cursor_update (GimpTool *tool,
static void
gimp_vector_tool_draw (GimpDrawTool *draw_tool)
{
GimpVectorTool *vector_tool;
GimpVectorTool *vector_tool;
GimpTool *tool;
gint i;
gint angle1, angle2;
gint draw_arc = 0;
GimpAnchor *cur_anchor = NULL;
GimpStroke *cur_stroke = NULL;
GimpVectors *vectors;
GimpCoords *coords;
gint num_coords;
gboolean closed;
vector_tool = GIMP_VECTOR_TOOL (draw_tool);
tool = GIMP_TOOL (draw_tool);
tool = GIMP_TOOL (draw_tool);
vectors = vector_tool->vectors;
while ((cur_stroke = gimp_vectors_stroke_get_next (vectors, cur_stroke))) {
cur_anchor = NULL;
while ((cur_anchor = gimp_stroke_anchor_get_next (cur_stroke, cur_anchor))) {
gimp_draw_tool_draw_handle (draw_tool,
GIMP_HANDLE_CIRCLE,
cur_anchor->position.x,
cur_anchor->position.y,
TARGET,
TARGET,
GTK_ANCHOR_CENTER,
FALSE);
}
}
for (i = 0; i < vector_tool->num_points; i++)
while ((cur_stroke = gimp_vectors_stroke_get_next (vectors, cur_stroke)))
{
if (i == 0 && vector_tool->num_points == 3)
{
cur_anchor = NULL;
while ((cur_anchor = gimp_stroke_anchor_get_next (cur_stroke, cur_anchor)))
{
gimp_draw_tool_draw_handle (draw_tool,
GIMP_HANDLE_CIRCLE,
vector_tool->x[i],
vector_tool->y[i],
cur_anchor->position.x,
cur_anchor->position.y,
TARGET,
TARGET,
GTK_ANCHOR_CENTER,
FALSE);
}
else
{
gimp_draw_tool_draw_handle (draw_tool,
GIMP_HANDLE_CROSS,
vector_tool->x[i],
vector_tool->y[i],
TARGET * 2,
TARGET * 2,
GTK_ANCHOR_CENTER,
FALSE);
}
}
coords = gimp_stroke_interpolate (cur_stroke, 1.0, &num_coords, &closed);
gimp_draw_tool_draw_strokes (draw_tool, coords, num_coords, FALSE);
if (i > 0)
{
gimp_draw_tool_draw_line (draw_tool,
vector_tool->x[0],
vector_tool->y[0],
vector_tool->x[i],
vector_tool->y[i],
FALSE);
/* only draw the arc if the lines are long enough */
if (gimp_draw_tool_calc_distance (draw_tool, tool->gdisp,
vector_tool->x[0],
vector_tool->y[0],
vector_tool->x[i],
vector_tool->y[i]) > ARC_RADIUS)
{
draw_arc++;
}
}
}
if (vector_tool->num_points > 1 && draw_arc == vector_tool->num_points - 1)
{
angle1 = vector_tool->angle2 * 64.0;
angle2 = (vector_tool->angle1 - vector_tool->angle2) * 64.0;
if (angle2 > 11520)
angle2 -= 23040;
if (angle2 < -11520)
angle2 += 23040;
if (angle2 != 0)
{
gimp_draw_tool_draw_arc_by_anchor (draw_tool,
FALSE,
vector_tool->x[0],
vector_tool->y[0],
ARC_RADIUS,
ARC_RADIUS,
angle1, angle2,
GTK_ANCHOR_CENTER,
FALSE);
if (vector_tool->num_points == 2)
{
gdouble target;
gdouble arc_radius;
target = FUNSCALEX (tool->gdisp, (TARGET >> 1));
arc_radius = FUNSCALEX (tool->gdisp, ARC_RADIUS);
gimp_draw_tool_draw_line
(draw_tool,
vector_tool->x[0],
vector_tool->y[0],
(vector_tool->x[1] >= vector_tool->x[0] ?
vector_tool->x[0] + arc_radius + target :
vector_tool->x[0] - arc_radius - target),
vector_tool->y[0],
FALSE);
}
}
g_free (coords);
}
}
......@@ -565,3 +520,27 @@ vector_tool_options_reset (GimpToolOptions *tool_options)
gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (options->use_info_window_w),
options->use_info_window_d);
}
void
gimp_vectors_tool_set_vectors (GimpVectorTool *vector_tool,
GimpVectors *vectors)
{
g_return_if_fail (GIMP_IS_VECTOR_TOOL (vector_tool));
g_return_if_fail (GIMP_IS_VECTORS (vectors));
gimp_draw_tool_pause (GIMP_DRAW_TOOL (vector_tool));
if (vector_tool->vectors)
g_object_unref (G_OBJECT (vector_tool->vectors));
vector_tool->vectors = vectors;
if (vector_tool->vectors)
g_object_ref (G_OBJECT (vector_tool->vectors));
gimp_draw_tool_resume (GIMP_DRAW_TOOL (vector_tool));
}
......@@ -25,12 +25,12 @@
/* possible vector functions */
typedef enum
{
VCREATING,
VADDING,
VMOVING,
VMOVING_ALL,
VGUIDING,
VFINISHED
VECTORS_CREATING,
VECTORS_ADDING,
VECTORS_MOVING,
VECTORS_MOVING_ALL,
VECTORS_GUIDING,
VECTORS_FINISHED
} VectorFunction;
......@@ -49,19 +49,14 @@ struct _GimpVectorTool
{
GimpDrawTool parent_instance;
VectorFunction function; /* function we're performing */
gint last_x; /* last x coordinate */
gint last_y; /* last y coordinate */
gint point; /* what are we manipulating? */
gint num_points; /* how many points? */
gint x[3]; /* three x coordinates */
gint y[3]; /* three y coordinates */
gdouble angle1; /* first angle */
gdouble angle2; /* second angle */
GimpAnchor *cur_anchor; /* The current Anchor */
GimpStroke *cur_stroke; /* The current Stroke */
GimpVectors *vectors; /* The current Vector data */
VectorFunction function; /* function we're performing */
gint last_x; /* last x coordinate */
gint last_y; /* last y coordinate */
GimpAnchor *cur_anchor; /* The current Anchor */
GimpStroke *cur_stroke; /* The current Stroke */
GimpVectors *vectors; /* The current Vector data */
GList *active_anchors; /* The currently active anchors */
};
struct _GimpVectorToolClass
......@@ -75,5 +70,7 @@ void gimp_vector_tool_register (Gimp *gimp,
GType gimp_vector_tool_get_type (void) G_GNUC_CONST;
void gimp_vectors_tool_set_vectors (GimpVectorTool *vector_tool,
GimpVectors *vectors);
#endif /* __GIMP_VECTOR_TOOL_H__ */
......@@ -28,7 +28,6 @@ struct _GimpAnchor
GimpCoords position;
gint type;
gboolean active;
};
#endif /* __GIMP_ANCHOR_H__ */
......@@ -75,12 +75,17 @@ static void
gimp_bezier_stroke_class_init (GimpBezierStrokeClass *klass)
{
GObjectClass *object_class;
GimpStrokeClass *stroke_class;
object_class = G_OBJECT_CLASS (klass);
stroke_class = GIMP_STROKE_CLASS (klass);
parent_class = g_type_class_peek_parent (klass);
object_class->finalize = gimp_bezier_stroke_finalize;
stroke_class->interpolate = gimp_bezier_stroke_interpolate;
}
static void
......@@ -117,10 +122,114 @@ gimp_bezier_stroke_new (const GimpCoords *start)
g_printerr ("Adding at %f, %f\n", start->x, start->y);
anchor->type = 0; /* FIXME */
anchor->active = FALSE;
stroke->anchors = g_list_append (stroke->anchors, anchor);
return stroke;
}
GimpAnchor *
gimp_bezier_stroke_extend (GimpBezierStroke *bezier_stroke,
GimpCoords *coords,
GimpAnchor *neighbor)
{
GimpAnchor *anchor;
GimpStroke *stroke;
GList *listneighbor;
gint loose_end;
g_return_val_if_fail (GIMP_IS_BEZIER_STROKE (bezier_stroke), NULL);
g_return_val_if_fail ((neighbor != NULL), NULL);
stroke = GIMP_STROKE (bezier_stroke);
listneighbor = g_list_last (stroke->anchors);
loose_end = 0;
if (listneighbor->data != neighbor)
{
listneighbor = g_list_first (stroke->anchors);
if (listneighbor->data != neighbor)
{
listneighbor = NULL;
loose_end = 0;
}
else
{
loose_end = -1;
}
}
else
{
loose_end = 1;
}
if (loose_end)
{
anchor = g_new0 (GimpAnchor, 1);
anchor->position.x = coords->x;
anchor->position.y = coords->y;
anchor->position.pressure = 1;
anchor->position.xtilt = 0.5;
anchor->position.ytilt = 0.5;
anchor->position.wheel = 0.5;
anchor->type = 0; /* FIXME */
g_printerr ("Extending at %f, %f\n", coords->x, coords->y);
}
else
anchor = NULL;
if (loose_end == 1)
stroke->anchors = g_list_append (stroke->anchors, anchor);
if (loose_end == -1)
stroke->anchors = g_list_prepend (stroke->anchors, anchor);
return anchor;
}
GimpCoords *
gimp_bezier_stroke_interpolate (const GimpStroke *stroke,
gdouble precision,
gint *ret_numcoords,
gboolean *ret_closed)
{
gint count, alloccount;
gint chunksize = 100;
GimpCoords *ret_coords;
GimpAnchor *anchor;
GList *anchorlist;
g_return_val_if_fail (GIMP_IS_BEZIER_STROKE (stroke), NULL);
g_return_val_if_fail (ret_numcoords != NULL, NULL);
g_return_val_if_fail (ret_closed != NULL, NULL);
count = 0;
alloccount = 0;
ret_coords = NULL;
for (anchorlist = stroke->anchors; anchorlist;
anchorlist = g_list_next (anchorlist))
{
if (count >= alloccount)
{
ret_coords = g_renew (GimpCoords, ret_coords, alloccount + chunksize);
alloccount += chunksize;
}
anchor = anchorlist->data;
ret_coords[count] = anchor->position;
count++;
}
*ret_numcoords = count;
*ret_closed = FALSE;
return ret_coords;
}
......@@ -53,10 +53,19 @@ struct _GimpBezierStrokeClass
};
GType gimp_bezier_stroke_get_type (void) G_GNUC_CONST;
GType gimp_bezier_stroke_get_type (void) G_GNUC_CONST;
GimpStroke * gimp_bezier_stroke_new (const GimpCoords *start);
GimpStroke * gimp_bezier_stroke_new (const GimpCoords *start);
GimpAnchor * gimp_bezier_stroke_extend (GimpBezierStroke *bezier_stroke,
GimpCoords *coords,
GimpAnchor *neighbor);
GimpCoords * gimp_bezier_stroke_interpolate (const GimpStroke *stroke,
const gdouble precision,
gint *ret_numcoords,
gboolean *ret_closed);
#endif /* __GIMP_BEZIER_STROKE_H__ */
......@@ -336,11 +336,11 @@ gimp_stroke_get_distance (const GimpStroke *stroke,
}
gint
gimp_stroke_interpolate (const GimpStroke *stroke,
const gdouble precision,
const gint max_points,
GimpCoords *ret_coords)
GimpCoords *
gimp_stroke_interpolate (const GimpStroke *stroke,
const gdouble precision,
gint *ret_numcoords,
gboolean *ret_closed)
{
GimpStrokeClass *stroke_class;
......@@ -349,7 +349,8 @@ gimp_stroke_interpolate (const GimpStroke *stroke,
stroke_class = GIMP_STROKE_GET_CLASS (stroke);
if (stroke_class->interpolate)
return stroke_class->interpolate (stroke, precision, max_points, ret_coords);
return stroke_class->interpolate (stroke, precision,
ret_numcoords, ret_closed);
else
g_printerr ("gimp_stroke_interpolate: default implementation\n");
......
......@@ -75,10 +75,10 @@ struct _GimpStrokeClass
gdouble (* get_distance) (const GimpStroke *stroke,
const GimpCoords *coord);
gint (* interpolate) (const GimpStroke *stroke,
GimpCoords * (* interpolate) (const GimpStroke *stroke,
const gdouble precision,
const gint max_points,
GimpCoords *ret_coords);
gint *ret_numcoords,
gboolean *ret_closed);
GimpAnchor * (* temp_anchor_get) (const GimpStroke *stroke);
......@@ -122,7 +122,7 @@ void gimp_stroke_anchor_move_absolute (GimpStroke *stroke,
const gint type);
void gimp_stroke_anchor_delete (GimpStroke *stroke,
GimpAnchor *anchor);
GimpAnchor *anchor);
/* accessing the shape of the curve */
......@@ -130,13 +130,13 @@ void gimp_stroke_anchor_delete (GimpStroke *stroke,
gdouble gimp_stroke_get_length (const GimpStroke *stroke);
gdouble gimp_stroke_get_distance (const GimpStroke *stroke,
const GimpCoords *coord);
const GimpCoords *coord);
/* returns the number of valid coordinates */
gint gimp_stroke_interpolate (const GimpStroke *stroke,
const gdouble precision,
const gint max_points,
GimpCoords *ret_coords);
GimpCoords * gimp_stroke_interpolate (const GimpStroke *stroke,
gdouble precision,
gint *ret_numcoords,
gboolean *ret_closed);
/* Allow a singular temorary anchor (marking the "working point")? */
......@@ -144,7 +144,7 @@ gint gimp_stroke_interpolate (const GimpStroke *stroke,
GimpAnchor * gimp_stroke_temp_anchor_get (const GimpStroke *stroke);
GimpAnchor * gimp_stroke_temp_anchor_set (GimpStroke *stroke,
const GimpCoords *coord);
const GimpCoords *coord);
gboolean gimp_stroke_temp_anchor_fix (GimpStroke *stroke);
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment