app/Makefile.am app/apptypes.h app/path_bezier.[ch] app/path_curves.[ch]

2001-04-07  Simon Budig  <simon@gimp.org>

        * app/Makefile.am
        * app/apptypes.h
        * app/path_bezier.[ch]
        * app/path_curves.[ch]
        * app/pixmaps2.h
        * app/tools/Makefile.am
        * app/tools/gimpdrawtool.[ch]
        * app/tools/path_tool.[ch]
        * app/tools/path_toolP.h
        * app/tools/tools.c

        new files:
        * app/tools/gimppathtool.c
        * app/tools/gimppathtool.h

        Reactivated (at least partially) the old new path tool. It
        will undergo major restructuring. Especially the path data
        will become proper objects. This definitely is work in progress
        and totally unuseable now.
This commit is contained in:
Simon Budig
2001-04-07 14:55:39 +00:00
committed by Simon Budig
parent 1187328dee
commit e2f373cbd2
17 changed files with 1414 additions and 241 deletions

View File

@ -1,3 +1,25 @@
2001-04-07 Simon Budig <simon@gimp.org>
* app/Makefile.am
* app/apptypes.h
* app/path_bezier.[ch]
* app/path_curves.[ch]
* app/pixmaps2.h
* app/tools/Makefile.am
* app/tools/gimpdrawtool.[ch]
* app/tools/path_tool.[ch]
* app/tools/path_toolP.h
* app/tools/tools.c
new files:
* app/tools/gimppathtool.c
* app/tools/gimppathtool.h
Reactivated (at least partially) the old new path tool. It
will undergo major restructuring. Especially the path stuff
will become proper objects. This definitely is work in progress
and totally unuseable now.
2001-04-07 Michael Natterer <mitch@gimp.org> 2001-04-07 Michael Natterer <mitch@gimp.org>
* configure.in * configure.in

View File

@ -240,6 +240,10 @@ gimp_SOURCES = \
paths_dialog.c \ paths_dialog.c \
paths_dialog.h \ paths_dialog.h \
paths_dialogP.h \ paths_dialogP.h \
path_curves.h \
path_curves.c \
path_bezier.h \
path_bezier.c \
pattern_header.h \ pattern_header.h \
pattern_select.c \ pattern_select.c \
pattern_select.h \ pattern_select.h \

View File

@ -79,6 +79,7 @@ typedef struct _GimpToolInfo GimpToolInfo;
typedef struct _GimpTool GimpTool; typedef struct _GimpTool GimpTool;
typedef struct _GimpPaintTool GimpPaintTool; typedef struct _GimpPaintTool GimpPaintTool;
typedef struct _GimpDrawTool GimpDrawTool; typedef struct _GimpDrawTool GimpDrawTool;
typedef struct _GimpPathTool GimpPathTool;
typedef struct _GimpTransformTool GimpTransformTool; typedef struct _GimpTransformTool GimpTransformTool;
typedef struct _GimpBezierSelectPoint GimpBezierSelectPoint; typedef struct _GimpBezierSelectPoint GimpBezierSelectPoint;

View File

@ -19,6 +19,10 @@
#include <math.h> #include <math.h>
#include <glib.h>
#include <gdk/gdk.h>
#include "apptypes.h"
#include "path_curves.h"
#include "path_bezier.h" #include "path_bezier.h"
#define HANDLE_HALFWIDTH 3 #define HANDLE_HALFWIDTH 3
@ -33,9 +37,8 @@
*/ */
guint guint
path_bezier_get_points (PathTool *path_tool, path_bezier_get_points (PathSegment *segment,
PathSegment *segment, gfloat *points,
GdkPoint *points,
guint npoints, guint npoints,
gdouble start, gdouble start,
gdouble end) gdouble end)
@ -44,8 +47,7 @@ path_bezier_get_points (PathTool *path_tool,
} }
void void
path_bezier_get_point (PathTool *path_tool, path_bezier_get_point (PathSegment *segment,
PathSegment *segment,
gdouble pos, gdouble pos,
gdouble *x, gdouble *x,
gdouble *y) gdouble *y)
@ -72,9 +74,10 @@ path_bezier_get_point (PathTool *path_tool,
} }
void void
path_bezier_draw_handles (GimpTool *tool, path_bezier_draw_handles (GimpDrawTool *tool,
PathSegment *segment) PathSegment *segment)
{ {
#if 0
PathTool *path_tool = (PathTool *) (tool->private); PathTool *path_tool = (PathTool *) (tool->private);
PathBezierData *data = (PathBezierData *) segment->data; PathBezierData *data = (PathBezierData *) segment->data;
GDisplay * gdisp = tool->gdisp; GDisplay * gdisp = tool->gdisp;
@ -112,10 +115,11 @@ path_bezier_draw_handles (GimpTool *tool,
HANDLE_WIDTH, HANDLE_WIDTH); HANDLE_WIDTH, HANDLE_WIDTH);
} }
} }
#endif
} }
void void
path_bezier_draw_segment (GimpTool *tool, path_bezier_draw_segment (GimpDrawTool *tool,
PathSegment *segment) PathSegment *segment)
{ {
return; return;
@ -123,8 +127,7 @@ path_bezier_draw_segment (GimpTool *tool,
gdouble gdouble
path_bezier_on_segment (GimpTool *tool, path_bezier_on_segment (PathSegment *segment,
PathSegment *segment,
gint x, gint x,
gint y, gint y,
gint halfwidth, gint halfwidth,
@ -134,8 +137,7 @@ path_bezier_on_segment (GimpTool *tool,
} }
void void
path_bezier_drag_segment (PathTool *path_tool, path_bezier_drag_segment (PathSegment *segment,
PathSegment *segment,
gdouble pos, gdouble pos,
gdouble dx, gdouble dx,
gdouble dy) gdouble dy)
@ -157,8 +159,7 @@ path_bezier_drag_segment (PathTool *path_tool,
} }
gint gint
path_bezier_on_handles (PathTool *path_tool, path_bezier_on_handles (PathSegment *segment,
PathSegment *segment,
gdouble x, gdouble x,
gdouble y, gdouble y,
gdouble halfwidth) gdouble halfwidth)
@ -179,8 +180,7 @@ path_bezier_on_handles (PathTool *path_tool,
} }
void void
path_bezier_drag_handles (PathTool *path_tool, path_bezier_drag_handles (PathSegment *segment,
PathSegment *segment,
gdouble dx, gdouble dx,
gdouble dy, gdouble dy,
gint handle_id) gint handle_id)
@ -198,16 +198,14 @@ path_bezier_drag_handles (PathTool *path_tool,
PathSegment * PathSegment *
path_bezier_insert_anchor (PathTool *path_tool, path_bezier_insert_anchor (PathSegment *segment,
PathSegment *segment,
gdouble position) gdouble position)
{ {
return NULL; return NULL;
} }
void void
path_bezier_update_segment (PathTool *path_tool, path_bezier_update_segment (PathSegment *segment)
PathSegment *segment)
{ {
return; return;
} }

View File

@ -29,79 +29,67 @@
#define __PATH_BEZIER_H__ #define __PATH_BEZIER_H__
#include "path_toolP.h"
typedef struct typedef struct
{ {
gdouble x1; gdouble x1;
gdouble y1; gdouble y1;
gdouble x2; gdouble x2;
gdouble y2; gdouble y2;
} PathBezierData; } PathBezierData;
guint guint
path_bezier_get_points (PathTool *path_tool, path_bezier_get_points (PathSegment *segment,
PathSegment *segment, gfloat *points,
GdkPoint *points,
guint npoints, guint npoints,
gdouble start, gdouble start,
gdouble end); gdouble end);
void void
path_bezier_get_point (PathTool *path_tool, path_bezier_get_point (PathSegment *segment,
PathSegment *segment,
gdouble position, gdouble position,
gdouble *x, gdouble *x,
gdouble *y); gdouble *y);
void void
path_bezier_draw_handles (GimpTool *tool, path_bezier_draw_handles (GimpDrawTool *tool,
PathSegment *segment); PathSegment *segment);
void void
path_bezier_draw_segment (GimpTool *tool, path_bezier_draw_segment (GimpDrawTool *tool,
PathSegment *segment); PathSegment *segment);
gdouble gdouble
path_bezier_on_segment (GimpTool *tool, path_bezier_on_segment (PathSegment *segment,
PathSegment *segment,
gint x, gint x,
gint y, gint y,
gint halfwidth, gint halfwidth,
gint *distance); gint *distance);
void void
path_bezier_drag_segment (PathTool *path_tool, path_bezier_drag_segment (PathSegment *segment,
PathSegment *segment,
gdouble position, gdouble position,
gdouble dx, gdouble dx,
gdouble dy); gdouble dy);
gint gint
path_bezier_on_handles (PathTool *path_tool, path_bezier_on_handles (PathSegment *segment,
PathSegment *segment,
gdouble x, gdouble x,
gdouble y, gdouble y,
gdouble halfwidth); gdouble halfwidth);
void void
path_bezier_drag_handles (PathTool *path_tool, path_bezier_drag_handles (PathSegment *segment,
PathSegment *segment,
gdouble dx, gdouble dx,
gdouble dy, gdouble dy,
gint handle_id); gint handle_id);
PathSegment * PathSegment *
path_bezier_insert_anchor (PathTool *path_tool, path_bezier_insert_anchor (PathSegment *segment,
PathSegment *segment,
gdouble position); gdouble position);
void void
path_bezier_update_segment (PathTool *path_tool, path_bezier_update_segment (PathSegment *segment);
PathSegment *segment);
void void
path_bezier_flip_segment (PathSegment *segment); path_bezier_flip_segment (PathSegment *segment);

View File

@ -18,9 +18,14 @@
*/ */
#include <math.h> #include <math.h>
#include <glib.h>
#include <gdk/gdk.h>
#include "apptypes.h"
#include "path_curves.h" #include "path_curves.h"
#include "path_bezier.h" #include "path_bezier.h"
#include "tools/gimpdrawtool.h"
/* only here temporarily */ /* only here temporarily */
PathSegment * path_split_segment (PathSegment *, gdouble); PathSegment * path_split_segment (PathSegment *, gdouble);
@ -37,7 +42,7 @@ static CurveDescription CurveTypes[] =
{ {
NULL, /* path_bezier_get_points, */ NULL, /* path_bezier_get_points, */
path_bezier_get_point, path_bezier_get_point,
path_bezier_draw_handles, NULL, /* path_bezier_draw_handles, */
NULL, /* path_bezier_draw_segment, */ NULL, /* path_bezier_draw_segment, */
NULL, /* path_bezier_on_segment, */ NULL, /* path_bezier_on_segment, */
path_bezier_drag_segment, path_bezier_drag_segment,
@ -60,25 +65,25 @@ static CurveDescription CurveTypes[] =
guint guint
path_curve_get_points (PathTool *path_tool, path_curve_get_points (PathSegment *segment,
PathSegment *segment, gdouble *points,
GdkPoint *points,
guint npoints, guint npoints,
gdouble start, gdouble start,
gdouble end) gdouble end)
{ {
gdouble pos, x, y; gdouble pos, x, y;
gint index=0; gint index=0;
if (segment && segment->next) { if (segment && segment->next) {
if (CurveTypes[segment->type].get_points) if (CurveTypes[segment->type].get_points)
return (* CurveTypes[segment->type].get_points) (path_tool, segment, points, npoints, start, end); return (* CurveTypes[segment->type].get_points) (segment, points, npoints, start, end);
else { else {
if (npoints > 1 && segment && segment->next) { if (npoints > 1 && segment && segment->next) {
for (pos = start; pos <= end; pos += (end - start) / (npoints -1)) { for (pos = start; pos <= end; pos += (end - start) / (npoints -1)) {
path_curve_get_point (path_tool, segment, pos, &x, &y); path_curve_get_point (segment, pos, &points[index*2],
points[index].x = (guint) (x + 0.5); &points[index*2+1]);
points[index].y = (guint) (y + 0.5);
index++; index++;
} }
return index; return index;
@ -95,21 +100,20 @@ path_curve_get_points (PathTool *path_tool,
void void
path_curve_get_point (PathTool *path_tool, path_curve_get_point (PathSegment *segment,
PathSegment *segment,
gdouble position, gdouble position,
gdouble *x, gdouble *x,
gdouble *y) gdouble *y)
{ {
if (segment && segment->next) { if (segment && segment->next) {
if (CurveTypes[segment->type].get_point) if (CurveTypes[segment->type].get_point)
(* CurveTypes[segment->type].get_point) (path_tool, segment, position, x, y); (* CurveTypes[segment->type].get_point) (segment, position, x, y);
else { else {
#if 0 #if 0
*x = segment->x + (segment->next->x - segment->x) * position; *x = segment->x + (segment->next->x - segment->x) * position;
*y = segment->y + (segment->next->y - segment->y) * position; *y = segment->y + (segment->next->y - segment->y) * position;
#else #else
/* Only here for debugging purposes: A bezier curve fith fixed tangents */ /* Only here for debugging purposes: A bezier curve with fixed tangents */
*x = (1-position)*(1-position)*(1-position) * segment->x + *x = (1-position)*(1-position)*(1-position) * segment->x +
3 * position *(1-position)*(1-position) * (segment->x - 60) + 3 * position *(1-position)*(1-position) * (segment->x - 60) +
@ -130,7 +134,7 @@ path_curve_get_point (PathTool *path_tool,
} }
void void
path_curve_draw_handles (Tool *tool, path_curve_draw_handles (GimpDrawTool *tool,
PathSegment *segment) PathSegment *segment)
{ {
if (segment && CurveTypes[segment->type].draw_handles) if (segment && CurveTypes[segment->type].draw_handles)
@ -141,7 +145,7 @@ path_curve_draw_handles (Tool *tool,
} }
void void
path_curve_draw_segment (Tool *tool, path_curve_draw_segment (GimpDrawTool *tool,
PathSegment *segment) PathSegment *segment)
{ {
gint x, y, numpts, index; gint x, y, numpts, index;
@ -151,20 +155,9 @@ path_curve_draw_segment (Tool *tool,
(* CurveTypes[segment->type].draw_segment) (tool, segment); (* CurveTypes[segment->type].draw_segment) (tool, segment);
return; return;
} else { } else {
GdkPoint *coordinates = g_new (GdkPoint, 100); gdouble *coordinates = g_new (gdouble, 200);
numpts = path_curve_get_points (((PathTool *) tool->private), segment, numpts = path_curve_get_points (segment, coordinates, 100, 0, 1);
coordinates, 100, 0, 1); gimp_draw_tool_draw_lines (tool, coordinates, 100, FALSE);
for (index=0; index < numpts; index++) {
gdisplay_transform_coords (tool->gdisp,
coordinates[index].x,
coordinates[index].y,
&x, &y, FALSE);
coordinates[index].x = x;
coordinates[index].y = y;
}
gdk_draw_lines (((PathTool *) tool->private)->core->win,
((PathTool *) tool->private)->core->gc,
coordinates, numpts);
g_free (coordinates); g_free (coordinates);
} }
@ -180,8 +173,7 @@ path_curve_draw_segment (Tool *tool,
gdouble gdouble
path_curve_on_segment (Tool *tool, path_curve_on_segment (PathSegment *segment,
PathSegment *segment,
gint x, gint x,
gint y, gint y,
gint halfwidth, gint halfwidth,
@ -189,21 +181,21 @@ path_curve_on_segment (Tool *tool,
{ {
if (segment && CurveTypes[segment->type].on_segment) if (segment && CurveTypes[segment->type].on_segment)
return (* CurveTypes[segment->type].on_segment) (tool, segment, x, y, halfwidth, distance); return (* CurveTypes[segment->type].on_segment) (segment, x, y, halfwidth, distance);
else { else {
if (segment && segment->next) { if (segment && segment->next) {
#if 1 #if 1
gint x1, y1, numpts, index; gint x1, y1, numpts, index;
GdkPoint *coordinates = g_new (GdkPoint, 100); gdouble *coordinates;
gint bestindex = -1; gint bestindex = -1;
coordinates = g_new (gdouble, 200);
*distance = halfwidth * halfwidth + 1; *distance = halfwidth * halfwidth + 1;
numpts = path_curve_get_points (((PathTool *) tool->private), segment, numpts = path_curve_get_points (segment, coordinates, 100, 0, 1);
coordinates, 100, 0, 1);
for (index=0; index < numpts; index++) { for (index=0; index < numpts; index++) {
x1 = coordinates[index].x; x1 = coordinates[2*index];
y1 = coordinates[index].y; y1 = coordinates[2*index+1];
if (((x - x1) * (x - x1) + (y - y1) * (y - y1)) < *distance) { if (((x - x1) * (x - x1) + (y - y1) * (y - y1)) < *distance) {
*distance = (x - x1) * (x - x1) + (y - y1) * (y - y1); *distance = (x - x1) * (x - x1) + (y - y1) * (y - y1);
bestindex = index; bestindex = index;
@ -247,47 +239,43 @@ path_curve_on_segment (Tool *tool,
} }
void void
path_curve_drag_segment (PathTool *path_tool, path_curve_drag_segment (PathSegment *segment,
PathSegment *segment,
gdouble position, gdouble position,
gdouble dx, gdouble dx,
gdouble dy) gdouble dy)
{ {
if (segment && CurveTypes[segment->type].drag_segment) if (segment && CurveTypes[segment->type].drag_segment)
(* CurveTypes[segment->type].drag_segment) (path_tool, segment, position, dx, dy); (* CurveTypes[segment->type].drag_segment) (segment, position, dx, dy);
return; return;
} }
gint gint
path_curve_on_handle (PathTool *path_tool, path_curve_on_handle (PathSegment *segment,
PathSegment *segment,
gdouble x, gdouble x,
gdouble y, gdouble y,
gdouble halfwidth) gdouble halfwidth)
{ {
if (segment && CurveTypes[segment->type].on_handles) if (segment && CurveTypes[segment->type].on_handles)
return (* CurveTypes[segment->type].on_handles) (path_tool, segment, x, y, halfwidth); return (* CurveTypes[segment->type].on_handles) (segment, x, y, halfwidth);
return FALSE; return FALSE;
} }
void void
path_curve_drag_handle (PathTool *path_tool, path_curve_drag_handle (PathSegment *segment,
PathSegment *segment,
gdouble dx, gdouble dx,
gdouble dy, gdouble dy,
gint handle_id) gint handle_id)
{ {
if (segment && CurveTypes[segment->type].drag_handle) if (segment && CurveTypes[segment->type].drag_handle)
(* CurveTypes[segment->type].drag_handle) (path_tool, segment, dx, dy, handle_id); (* CurveTypes[segment->type].drag_handle) (segment, dx, dy, handle_id);
} }
PathSegment * PathSegment *
path_curve_insert_anchor (PathTool *path_tool, path_curve_insert_anchor (PathSegment *segment,
PathSegment *segment,
gdouble position) gdouble position)
{ {
if (segment && CurveTypes[segment->type].insert_anchor) if (segment && CurveTypes[segment->type].insert_anchor)
return (* CurveTypes[segment->type].insert_anchor) (path_tool, segment, position); return (* CurveTypes[segment->type].insert_anchor) (segment, position);
else { else {
return path_split_segment (segment, position); return path_split_segment (segment, position);
} }
@ -302,11 +290,10 @@ path_curve_flip_segment (PathSegment *segment)
} }
void void
path_curve_update_segment (PathTool *path_tool, path_curve_update_segment (PathSegment *segment)
PathSegment *segment)
{ {
if (segment && CurveTypes[segment->type].update_segment) if (segment && CurveTypes[segment->type].update_segment)
(* CurveTypes[segment->type].update_segment) (path_tool, segment); (* CurveTypes[segment->type].update_segment) (segment);
return; return;
} }

View File

@ -20,8 +20,85 @@
#ifndef __PATH_CURVES_H__ #ifndef __PATH_CURVES_H__
#define __PATH_CURVES_H__ #define __PATH_CURVES_H__
#include <gdk/gdk.h> #undef PATH_TOOL_DEBUG
#include "path_toolP.h" #ifdef PATH_TOOL_DEBUG
#include <stdio.h>
#endif
#define IMAGE_COORDS 1
#define AA_IMAGE_COORDS 2
#define SCREEN_COORDS 3
#define SEGMENT_ACTIVE 1
#define PATH_TOOL_DRAG 1
#define PATH_TOOL_REDRAW_ALL 1
#define PATH_TOOL_REDRAW_ACTIVE 2
#define PATH_TOOL_REDRAW_HANDLES 4
#define SUBDIVIDE 1000
typedef enum { SEGMENT_LINE=0, SEGMENT_BEZIER} SegmentType;
enum { ON_ANCHOR, ON_HANDLE, ON_CURVE, ON_CANVAS };
typedef struct _path_segment PathSegment;
typedef struct _path_curve PathCurve;
typedef struct _npath NPath;
struct _path_segment
{
SegmentType type; /* What type of segment */
gdouble x, y; /* location of starting-point in image space */
gpointer data; /* Additional data, dependant of segment-type */
guint32 flags; /* Various Flags: Is the Segment active? */
PathCurve *parent; /* the parent Curve */
PathSegment *next; /* Next Segment or NULL */
PathSegment *prev; /* Previous Segment or NULL */
};
struct _path_curve
{
PathSegment *segments; /* The segments of the curve */
PathSegment *cur_segment; /* the current segment */
NPath *parent; /* the parent Path */
PathCurve *next; /* Next Curve or NULL */
PathCurve *prev; /* Previous Curve or NULL */
};
struct _npath
{
PathCurve *curves; /* the curves */
PathCurve *cur_curve; /* the current curve */
GString *name; /* the name of the path */
guint32 state; /* is the path locked? */
/* GimpPathTool *path_tool; */ /* The parent Path Tool */
};
typedef void
(*PathTraverseFunc) (NPath *,
PathCurve *,
gpointer);
typedef void
(*CurveTraverseFunc) (NPath *,
PathCurve *,
PathSegment *,
gpointer);
typedef void
(*SegmentTraverseFunc) (NPath *,
PathCurve *,
PathSegment *,
gint,
gint,
gpointer);
/* /*
@ -32,57 +109,49 @@
* Array is allocated. * Array is allocated.
*/ */
typedef guint (*PathGetPointsFunc) (PathTool *path_tool, typedef guint (*PathGetPointsFunc) (PathSegment *segment,
PathSegment *segment, gdouble *points,
GdkPoint *points,
guint npoints, guint npoints,
gdouble start, gdouble start,
gdouble end); gdouble end);
typedef void (*PathGetPointFunc) (PathTool *path_tool, typedef void (*PathGetPointFunc) (PathSegment *segment,
PathSegment *segment,
gdouble position, gdouble position,
gdouble *x, gdouble *x,
gdouble *y); gdouble *y);
typedef void (*PathDrawHandlesFunc) (Tool *tool, typedef void (*PathDrawHandlesFunc) (GimpDrawTool *tool,
PathSegment *segment); PathSegment *segment);
typedef void (*PathDrawSegmentFunc) (Tool *tool, typedef void (*PathDrawSegmentFunc) (GimpDrawTool *tool,
PathSegment *segment); PathSegment *segment);
typedef gdouble (*PathOnSegmentFunc) (Tool *tool, typedef gdouble (*PathOnSegmentFunc) (PathSegment *segment,
PathSegment *segment,
gint x, gint x,
gint y, gint y,
gint halfwidth, gint halfwidth,
gint *distance); gint *distance);
typedef void (*PathDragSegmentFunc) (PathTool *path_tool, typedef void (*PathDragSegmentFunc) (PathSegment *segment,
PathSegment *segment,
gdouble position, gdouble position,
gdouble dx, gdouble dx,
gdouble dy); gdouble dy);
typedef gint (*PathOnHandlesFunc) (PathTool *path_tool, typedef gint (*PathOnHandlesFunc) (PathSegment *segment,
PathSegment *segment,
gdouble x, gdouble x,
gdouble y, gdouble y,
gdouble halfwidth); gdouble halfwidth);
typedef void (*PathDragHandleFunc) (PathTool *path_tool, typedef void (*PathDragHandleFunc) (PathSegment *segment,
PathSegment *segment,
gdouble dx, gdouble dx,
gdouble dy, gdouble dy,
gint handle_id); gint handle_id);
typedef PathSegment * (*PathInsertAnchorFunc) (PathTool *path_tool, typedef PathSegment * (*PathInsertAnchorFunc) (PathSegment *segment,
PathSegment *segment,
gdouble position); gdouble position);
typedef void (*PathUpdateSegmentFunc) (PathTool *path_tool, typedef void (*PathUpdateSegmentFunc) (PathSegment *segment);
PathSegment *segment);
typedef void (*PathFlipSegmentFunc) (PathSegment *segment); typedef void (*PathFlipSegmentFunc) (PathSegment *segment);
@ -108,66 +177,58 @@ typedef struct {
guint guint
path_curve_get_points (PathTool *path_tool, path_curve_get_points (PathSegment *segment,
PathSegment *segment, gdouble *points,
GdkPoint *points,
guint npoints, guint npoints,
gdouble start, gdouble start,
gdouble end); gdouble end);
void void
path_curve_get_point (PathTool *path_tool, path_curve_get_point (PathSegment *segment,
PathSegment *segment,
gdouble position, gdouble position,
gdouble *x, gdouble *x,
gdouble *y); gdouble *y);
void void
path_curve_draw_handles (Tool *tool, path_curve_draw_handles (GimpDrawTool *tool,
PathSegment *segment); PathSegment *segment);
void void
path_curve_draw_segment (Tool *tool, path_curve_draw_segment (GimpDrawTool *tool,
PathSegment *segment); PathSegment *segment);
gdouble gdouble
path_curve_on_segment (Tool *tool, path_curve_on_segment (PathSegment *segment,
PathSegment *segment,
gint x, gint x,
gint y, gint y,
gint halfwidth, gint halfwidth,
gint *distance); gint *distance);
void void
path_curve_drag_segment (PathTool *path_tool, path_curve_drag_segment (PathSegment *segment,
PathSegment *segment,
gdouble position, gdouble position,
gdouble dx, gdouble dx,
gdouble dy); gdouble dy);
gint gint
path_curve_on_handle (PathTool *path_tool, path_curve_on_handle (PathSegment *segment,
PathSegment *segment,
gdouble x, gdouble x,
gdouble y, gdouble y,
gdouble halfwidth); gdouble halfwidth);
void void
path_curve_drag_handle (PathTool *path_tool, path_curve_drag_handle (PathSegment *segment,
PathSegment *segment,
gdouble dx, gdouble dx,
gdouble dy, gdouble dy,
gint handle_id); gint handle_id);
PathSegment * PathSegment *
path_curve_insert_anchor (PathTool *path_tool, path_curve_insert_anchor (PathSegment *segment,
PathSegment *segment, gdouble position);
gdouble position);
void void
path_curve_update_segment (PathTool *path_tool, path_curve_update_segment (PathSegment *segment);
PathSegment *segment);
void void
path_curve_flip_segment (PathSegment *segment); path_curve_flip_segment (PathSegment *segment);

View File

@ -1012,7 +1012,6 @@ static char *xinput_airbrush_bits [] =
/* GIMP icon image format -- S. Kimball, P. Mattis */ /* GIMP icon image format -- S. Kimball, P. Mattis */
/* Image name: path_tool */ /* Image name: path_tool */
/*
#define path_tool_width 22 #define path_tool_width 22
#define path_tool_height 22 #define path_tool_height 22
static char *path_tool_bits [] = static char *path_tool_bits [] =
@ -1040,7 +1039,6 @@ static char *path_tool_bits [] =
"..a...................", "..a...................",
"......................" "......................"
}; };
*/
/* GIMP icon image format -- S. Kimball, P. Mattis */ /* GIMP icon image format -- S. Kimball, P. Mattis */
/* Image name: by_color_select */ /* Image name: by_color_select */

View File

@ -54,6 +54,8 @@ libapptools_la_SOURCES = \
gimppainttool.c \ gimppainttool.c \
gimppainttool.h \ gimppainttool.h \
gimppainttool_kernels.h \ gimppainttool_kernels.h \
gimppathtool.c \
gimppathtool.h \
gimppenciltool.c \ gimppenciltool.c \
gimppenciltool.h \ gimppenciltool.h \
## gimpperspectivetool.c \ ## gimpperspectivetool.c \
@ -90,7 +92,10 @@ libapptools_la_SOURCES = \
gimptoolinfo.h \ gimptoolinfo.h \
tool_manager.c \ tool_manager.c \
tool_manager.h \ tool_manager.h \
tools.c tools.c \
path_tool.h \
path_tool.c \
path_toolP.h
## brightness_contrast.c \ ## brightness_contrast.c \
## brightness_contrast.h \ ## brightness_contrast.h \

View File

@ -22,7 +22,9 @@
#include "apptypes.h" #include "apptypes.h"
#include "gdisplay.h"
#include "gimpdrawtool.h" #include "gimpdrawtool.h"
#include "libgimpmath/gimpmath.h"
enum enum
@ -225,3 +227,70 @@ gimp_draw_tool_pause (GimpDrawTool *core)
core->paused_count++; core->paused_count++;
} }
void
gimp_draw_tool_draw_handle (GimpDrawTool *draw_tool,
gdouble x,
gdouble y,
gint size,
gint type)
{
GimpTool *tool = GIMP_TOOL (draw_tool);
gdouble hx, hy;
gint filled;
gdisplay_transform_coords_f (tool->gdisp, x, y, &hx, &hy, TRUE);
hx = ROUND (hx);
hy = ROUND (hy);
filled = type % 2;
if (type < 2)
gdk_draw_rectangle (tool->gdisp->canvas->window,
draw_tool->gc, filled,
hx - size/2, hy - size/2,
size, size);
else
gdk_draw_arc (tool->gdisp->canvas->window,
draw_tool->gc, filled,
hx - size/2, hy - size/2,
size, size, 0, 360);
}
void
gimp_draw_tool_draw_lines (GimpDrawTool *draw_tool,
gdouble *points,
gint npoints,
gint filled)
{
GimpTool *tool = GIMP_TOOL (draw_tool);
GdkPoint *coords = g_new (GdkPoint, npoints);
gint i;
gdouble sx, sy;
for (i=0; i < npoints ; i++)
{
gdisplay_transform_coords_f (tool->gdisp, points[i*2], points[i*2+1],
&sx, &sy, TRUE);
coords[i].x = ROUND (sx);
coords[i].y = ROUND (sy);
}
if (filled)
gdk_draw_polygon (tool->gdisp->canvas->window,
draw_tool->gc, TRUE,
coords, npoints);
else
gdk_draw_lines (tool->gdisp->canvas->window,
draw_tool->gc,
coords, npoints);
g_free (coords);
}

View File

@ -70,5 +70,16 @@ void gimp_draw_tool_stop (GimpDrawTool *draw_tool);
void gimp_draw_tool_pause (GimpDrawTool *draw_tool); void gimp_draw_tool_pause (GimpDrawTool *draw_tool);
void gimp_draw_tool_resume (GimpDrawTool *draw_tool); void gimp_draw_tool_resume (GimpDrawTool *draw_tool);
void gimp_draw_tool_draw_handle (GimpDrawTool *draw_tool,
gdouble x,
gdouble y,
gint size,
gint type);
void gimp_draw_tool_draw_lines (GimpDrawTool *draw_tool,
gdouble *points,
gint npoints,
gint filled);
#endif /* __GIMP_DRAW_TOOL_H__ */ #endif /* __GIMP_DRAW_TOOL_H__ */

830
app/tools/gimppathtool.c Normal file
View File

@ -0,0 +1,830 @@
/* The GIMP -- an image manipulation program
*
* This file Copyright (C) 1999 Simon Budig
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
#include "config.h"
#include <stdlib.h>
#include <gtk/gtk.h>
#include "libgimpmath/gimpmath.h"
#include "libgimpwidgets/gimpwidgets.h"
#include "apptypes.h"
#include "gdisplay.h"
#include "path_curves.h"
#include "gimpdrawtool.h"
#include "gimppathtool.h"
#include "tool_manager.h"
#include "tool_options.h"
#include "libgimp/gimpintl.h"
#include "path_tool.h"
#include "pixmaps2.h"
/* definitions */
/* local function prototypes */
static void gimp_path_tool_class_init (GimpPathToolClass *klass);
static void gimp_path_tool_init (GimpPathTool *tool);
static void gimp_path_tool_destroy (GtkObject *object);
static void gimp_path_tool_control (GimpTool *tool,
ToolAction action,
GDisplay *gdisp);
static void gimp_path_tool_button_press (GimpTool *tool,
GdkEventButton *bevent,
GDisplay *gdisp);
static void gimp_path_tool_button_release (GimpTool *tool,
GdkEventButton *bevent,
GDisplay *gdisp);
static void gimp_path_tool_motion (GimpTool *tool,
GdkEventMotion *mevent,
GDisplay *gdisp);
static void gimp_path_tool_cursor_update (GimpTool *tool,
GdkEventMotion *mevent,
GDisplay *gdisp);
static void gimp_path_tool_draw (GimpDrawTool *draw_tool);
static GimpDrawToolClass *parent_class = NULL;
/* the move tool options */
static ToolOptions *path_options = NULL;
void
gimp_path_tool_register (void)
{
tool_manager_register_tool (GIMP_TYPE_PATH_TOOL,
FALSE,
"gimp:path_tool",
_("Path Tool"),
_("Path tool prototype"),
N_("/Tools/Path"), NULL,
NULL, "tools/path.html",
(const gchar **) path_tool_bits);
}
GtkType
gimp_path_tool_get_type (void)
{
static GtkType tool_type = 0;
if (! tool_type)
{
GtkTypeInfo tool_info =
{
"GimpPathTool",
sizeof (GimpPathTool),
sizeof (GimpPathToolClass),
(GtkClassInitFunc) gimp_path_tool_class_init,
(GtkObjectInitFunc) gimp_path_tool_init,
/* reserved_1 */ NULL,
/* reserved_2 */ NULL,
(GtkClassInitFunc) NULL,
};
tool_type = gtk_type_unique (GIMP_TYPE_DRAW_TOOL, &tool_info);
}
return tool_type;
}
static void
gimp_path_tool_class_init (GimpPathToolClass *klass)
{
GtkObjectClass *object_class;
GimpToolClass *tool_class;
GimpDrawToolClass *draw_tool_class;
object_class = (GtkObjectClass *) klass;
tool_class = (GimpToolClass *) klass;
draw_tool_class = (GimpDrawToolClass *) klass;
parent_class = gtk_type_class (GIMP_TYPE_DRAW_TOOL);
object_class->destroy = gimp_path_tool_destroy;
tool_class->control = gimp_path_tool_control;
tool_class->button_press = gimp_path_tool_button_press;
tool_class->button_release = gimp_path_tool_button_release;
tool_class->motion = gimp_path_tool_motion;
tool_class->cursor_update = gimp_path_tool_cursor_update;
draw_tool_class->draw = gimp_path_tool_draw;
}
static void
gimp_path_tool_init (GimpPathTool *path_tool)
{
GimpTool *tool;
tool = GIMP_TOOL (path_tool);
/* The tool options */
if (! path_options)
{
path_options = tool_options_new ();
tool_manager_register_tool_options (GIMP_TYPE_PATH_TOOL,
(ToolOptions *) path_options);
}
tool->preserve = TRUE; /* Preserve on drawable change */
path_tool->click_type = ON_CANVAS;
path_tool->click_x = 0;
path_tool->click_y = 0;
path_tool->click_halfwidth = 0;
path_tool->click_modifier = 0;
path_tool->click_path = NULL;
path_tool->click_curve = NULL;
path_tool->click_segment = NULL;
path_tool->click_position = -1;
path_tool->active_count = 0;
path_tool->single_active_segment = NULL;
path_tool->state = 0;
path_tool->draw = PATH_TOOL_REDRAW_ALL;
path_tool->cur_path = g_new0(NPath, 1);
path_tool->scanlines = NULL;
/* Initial Path */
path_tool->cur_path->curves = NULL;
path_tool->cur_path->cur_curve = NULL;
path_tool->cur_path->name = g_string_new("Path 0");
path_tool->cur_path->state = 0;
/* path_tool->cur_path->path_tool = path_tool; */
}
static void
gimp_path_tool_destroy (GtkObject *object)
{
GimpPathTool *path_tool = GIMP_PATH_TOOL (object);
#ifdef PATH_TOOL_DEBUG
fprintf (stderr, "tools_free_path_tool start\n");
#endif PATH_TOOL_DEBUG
path_free_path (path_tool->cur_path);
if (GTK_OBJECT_CLASS (parent_class)->destroy)
GTK_OBJECT_CLASS (parent_class)->destroy (object);
}
static void
gimp_path_tool_control (GimpTool *tool,
ToolAction action,
GDisplay *gdisp)
{
GimpPathTool *path_tool;
#ifdef PATH_TOOL_DEBUG
fprintf (stderr, "path_tool_control\n");
#endif PATH_TOOL_DEBUG
path_tool = GIMP_PATH_TOOL (tool);
switch (action)
{
case PAUSE:
break;
case RESUME:
break;
case HALT:
tool->state = INACTIVE;
break;
default:
break;
}
if (GIMP_TOOL_CLASS (parent_class)->control)
GIMP_TOOL_CLASS (parent_class)->control (tool, action, gdisp);
}
static void
gimp_path_tool_button_press (GimpTool *tool,
GdkEventButton *bevent,
GDisplay *gdisp)
{
GimpPathTool *path_tool = GIMP_PATH_TOOL (tool);
gint grab_pointer=0;
gint x, y, halfwidth, dummy;
#ifdef PATH_TOOL_DEBUG
fprintf (stderr, "path_tool_button_press\n");
#endif PATH_TOOL_DEBUG
/* Transform window-coordinates to canvas-coordinates */
gdisplay_untransform_coords (gdisp, bevent->x, bevent->y, &x, &y, TRUE, 0);
#ifdef PATH_TOOL_DEBUG
fprintf(stderr, "Clickcoordinates %d, %d\n",x,y);
#endif PATH_TOOL_DEBUG
path_tool->click_x = x;
path_tool->click_y = y;
path_tool->click_modifier = bevent->state;
/* get halfwidth in image coord */
gdisplay_untransform_coords (gdisp, bevent->x + PATH_TOOL_HALFWIDTH, 0, &halfwidth, &dummy, TRUE, 0);
halfwidth -= x;
path_tool->click_halfwidth = halfwidth;
if (!path_tool->cur_path->curves)
gimp_draw_tool_start (GIMP_DRAW_TOOL(path_tool), gdisp->canvas->window);
/* determine point, where clicked,
* switch accordingly.
*/
path_tool->click_type =
path_tool_cursor_position (path_tool->cur_path, x, y, halfwidth,
&(path_tool->click_path),
&(path_tool->click_curve),
&(path_tool->click_segment),
&(path_tool->click_position),
&(path_tool->click_handle_id));
switch (path_tool->click_type)
{
case ON_CANVAS:
grab_pointer = gimp_path_tool_button_press_canvas(path_tool, bevent, gdisp);
break;
case ON_ANCHOR:
grab_pointer = gimp_path_tool_button_press_anchor(path_tool, bevent, gdisp);
break;
case ON_HANDLE:
grab_pointer = gimp_path_tool_button_press_handle(path_tool, bevent, gdisp);
break;
case ON_CURVE:
grab_pointer = gimp_path_tool_button_press_curve(path_tool, bevent, gdisp);
break;
default:
g_message("Huh? Whats happening here? (button_press_*)");
}
if (grab_pointer)
gdk_pointer_grab (gdisp->canvas->window, FALSE,
GDK_POINTER_MOTION_HINT_MASK |
GDK_BUTTON1_MOTION_MASK |
GDK_BUTTON_RELEASE_MASK,
NULL, NULL, bevent->time);
tool->state = ACTIVE;
}
gint
gimp_path_tool_button_press_anchor (GimpPathTool *path_tool,
GdkEventButton *bevent,
GDisplay *gdisp)
{
static guint32 last_click_time=0;
gboolean doubleclick=FALSE;
NPath * cur_path = path_tool->cur_path;
PathSegment *p_sas;
gint grab_pointer;
#ifdef PATH_TOOL_DEBUG
fprintf(stderr, "path_tool_button_press_anchor:\n");
#endif PATH_TOOL_DEBUG
grab_pointer = 1;
if (!cur_path) {
#ifdef PATH_TOOL_DEBUG
fprintf (stderr, "Fatal error: No current Path\n");
#endif PATH_TOOL_DEBUG
return 0;
}
/*
* We have to determine, if this was a doubleclick for ourself, because
* disp_callback.c ignores the GDK_[23]BUTTON_EVENT's and adding them to
* the switch statement confuses some tools.
*/
if (bevent->time - last_click_time < 250) {
doubleclick=TRUE;
#ifdef PATH_TOOL_DEBUG
fprintf (stderr, "Doppelclick!\n");
#endif PATH_TOOL_DEBUG
} else
doubleclick=FALSE;
last_click_time = bevent->time;
gimp_draw_tool_pause (GIMP_DRAW_TOOL(path_tool));
/* The user pressed on an anchor:
* normally this activates this anchor
* + SHIFT toggles the activity of an anchor.
* if this anchor is at the end of an open curve and the other
* end is active, close the curve.
*
* Doubleclick (de)activates the whole curve (not Path!).
*/
p_sas = path_tool->single_active_segment;
#ifdef PATH_TOOL_DEBUG
fprintf (stderr, "p_sas: %p\n", p_sas);
#endif PATH_TOOL_DEBUG
if (path_tool->click_modifier & GDK_SHIFT_MASK) {
if (path_tool->active_count == 1 && p_sas && p_sas != path_tool->click_segment &&
(p_sas->next == NULL || p_sas->prev == NULL) &&
(path_tool->click_segment->next == NULL || path_tool->click_segment->prev == NULL)) {
/*
* if this is the end of an open curve and the single active segment was another
* open end, connect those ends.
*/
path_join_curves (path_tool->click_segment, p_sas);
path_set_flags (path_tool, path_tool->click_path, path_tool->click_curve,
NULL, 0, SEGMENT_ACTIVE);
}
if (doubleclick)
/*
* Doubleclick set the whole curve to the same state, depending on the
* state of the clicked anchor.
*/
if (path_tool->click_segment->flags & SEGMENT_ACTIVE)
path_set_flags (path_tool, path_tool->click_path, path_tool->click_curve,
NULL, SEGMENT_ACTIVE, 0);
else
path_set_flags (path_tool, path_tool->click_path, path_tool->click_curve,
NULL, 0, SEGMENT_ACTIVE);
else
/*
* Toggle the state of the clicked anchor.
*/
if (path_tool->click_segment->flags & SEGMENT_ACTIVE)
path_set_flags (path_tool, path_tool->click_path, path_tool->click_curve,
path_tool->click_segment, 0, SEGMENT_ACTIVE);
else
path_set_flags (path_tool, path_tool->click_path, path_tool->click_curve,
path_tool->click_segment, SEGMENT_ACTIVE, 0);
}
/*
* Delete anchors, when CONTROL is pressed
*/
else if (path_tool->click_modifier & GDK_CONTROL_MASK)
{
if (path_tool->click_segment->flags & SEGMENT_ACTIVE)
{
if (path_tool->click_segment->prev)
path_set_flags (path_tool, path_tool->click_path, path_tool->click_curve,
path_tool->click_segment->prev, SEGMENT_ACTIVE, 0);
else if (path_tool->click_segment->next)
path_set_flags (path_tool, path_tool->click_path, path_tool->click_curve,
path_tool->click_segment->next, SEGMENT_ACTIVE, 0);
}
path_delete_segment (path_tool->click_segment);
path_tool->click_segment = NULL;
/* Maybe CTRL-ALT Click should remove the whole curve? Or the active points? */
}
else if (!(path_tool->click_segment->flags & SEGMENT_ACTIVE))
{
path_set_flags (path_tool, cur_path, NULL, NULL, 0, SEGMENT_ACTIVE);
path_set_flags (path_tool, cur_path, path_tool->click_curve, path_tool->click_segment, SEGMENT_ACTIVE, 0);
}
gimp_draw_tool_resume (GIMP_DRAW_TOOL(path_tool));
return grab_pointer;
}
gint
gimp_path_tool_button_press_handle (GimpPathTool *path_tool,
GdkEventButton *bevent,
GDisplay *gdisp)
{
static guint32 last_click_time=0;
gboolean doubleclick=FALSE;
NPath * cur_path = path_tool->cur_path;
gint grab_pointer;
#ifdef PATH_TOOL_DEBUG
fprintf(stderr, "path_tool_button_press_handle:\n");
#endif PATH_TOOL_DEBUG
grab_pointer = 1;
if (!cur_path) {
#ifdef PATH_TOOL_DEBUG
fprintf (stderr, "Fatal error: No current Path\n");
#endif PATH_TOOL_DEBUG
return 0;
}
/*
* We have to determine, if this was a doubleclick for ourself, because
* disp_callback.c ignores the GDK_[23]BUTTON_EVENT's and adding them to
* the switch statement confuses some tools.
*/
if (bevent->time - last_click_time < 250) {
doubleclick=TRUE;
#ifdef PATH_TOOL_DEBUG
fprintf (stderr, "Doppelclick!\n");
#endif PATH_TOOL_DEBUG
} else
doubleclick=FALSE;
last_click_time = bevent->time;
return grab_pointer;
}
gint
gimp_path_tool_button_press_canvas (GimpPathTool *path_tool,
GdkEventButton *bevent,
GDisplay *gdisp)
{
NPath * cur_path = path_tool->cur_path;
PathCurve * cur_curve;
PathSegment * cur_segment;
gint grab_pointer;
#ifdef PATH_TOOL_DEBUG
fprintf(stderr, "path_tool_button_press_canvas:\n");
#endif PATH_TOOL_DEBUG
grab_pointer = 1;
if (!cur_path) {
#ifdef PATH_TOOL_DEBUG
fprintf (stderr, "Fatal error: No current Path\n");
#endif PATH_TOOL_DEBUG
return 0;
}
gimp_draw_tool_pause (GIMP_DRAW_TOOL(path_tool));
if (path_tool->active_count == 1 && path_tool->single_active_segment != NULL
&& (path_tool->single_active_segment->prev == NULL || path_tool->single_active_segment->next == NULL)) {
cur_segment = path_tool->single_active_segment;
cur_curve = cur_segment->parent;
path_set_flags (path_tool, cur_path, NULL, NULL, 0, SEGMENT_ACTIVE);
if (cur_segment->next == NULL)
cur_curve->cur_segment = path_append_segment(cur_path, cur_curve, SEGMENT_BEZIER, path_tool->click_x, path_tool->click_y);
else
cur_curve->cur_segment = path_prepend_segment(cur_path, cur_curve, SEGMENT_BEZIER, path_tool->click_x, path_tool->click_y);
if (cur_curve->cur_segment) {
path_set_flags (path_tool, cur_path, cur_curve, cur_curve->cur_segment, SEGMENT_ACTIVE, 0);
}
} else {
if (path_tool->active_count == 0) {
path_set_flags (path_tool, cur_path, NULL, NULL, 0, SEGMENT_ACTIVE);
cur_path->cur_curve = path_add_curve(cur_path, path_tool->click_x, path_tool->click_y);
path_set_flags (path_tool, cur_path, cur_path->cur_curve, cur_path->cur_curve->segments, SEGMENT_ACTIVE, 0);
} else {
path_set_flags (path_tool, cur_path, NULL, NULL, 0, SEGMENT_ACTIVE);
}
}
gimp_draw_tool_resume (GIMP_DRAW_TOOL(path_tool));
return 0;
}
gint
gimp_path_tool_button_press_curve (GimpPathTool *path_tool,
GdkEventButton *bevent,
GDisplay *gdisp)
{
NPath * cur_path = path_tool->cur_path;
PathSegment * cur_segment;
gint grab_pointer;
#ifdef PATH_TOOL_DEBUG
fprintf(stderr, "path_tool_button_press_curve:\n");
#endif PATH_TOOL_DEBUG
grab_pointer = 1;
if (!cur_path) {
#ifdef PATH_TOOL_DEBUG
fprintf (stderr, "Fatal error: No current NPath\n");
#endif PATH_TOOL_DEBUG
return 0;
}
gimp_draw_tool_pause (GIMP_DRAW_TOOL(path_tool));
if (path_tool->click_modifier & GDK_SHIFT_MASK) {
cur_segment = path_curve_insert_anchor (path_tool->click_segment, path_tool->click_position);
path_set_flags (path_tool, cur_path, NULL, NULL, 0, SEGMENT_ACTIVE);
path_set_flags (path_tool, cur_path, path_tool->click_curve, cur_segment, SEGMENT_ACTIVE, 0);
path_tool->click_type = ON_ANCHOR;
path_tool->click_segment = cur_segment;
} else {
path_set_flags (path_tool, cur_path, NULL, NULL, 0, SEGMENT_ACTIVE);
path_set_flags (path_tool, cur_path, path_tool->click_curve, path_tool->click_segment, SEGMENT_ACTIVE, 0);
path_set_flags (path_tool, cur_path, path_tool->click_curve, path_tool->click_segment->next, SEGMENT_ACTIVE, 0);
}
gimp_draw_tool_resume (GIMP_DRAW_TOOL(path_tool));
return 0;
}
static void
gimp_path_tool_button_release (GimpTool *tool,
GdkEventButton *bevent,
GDisplay *gdisp)
{
GimpPathTool *path_tool = GIMP_PATH_TOOL (tool);
#ifdef PATH_TOOL_DEBUG
fprintf (stderr, "path_tool_button_release\n");
#endif PATH_TOOL_DEBUG
path_tool->state &= ~PATH_TOOL_DRAG;
gdk_pointer_ungrab (bevent->time);
gdk_flush ();
}
static void
gimp_path_tool_motion (GimpTool *tool,
GdkEventMotion *mevent,
GDisplay *gdisp)
{
GimpPathTool *path_tool;
path_tool = GIMP_PATH_TOOL (tool);
if (gtk_events_pending()) return;
switch (path_tool->click_type) {
case ON_ANCHOR:
gimp_path_tool_motion_anchor (path_tool, mevent, gdisp);
break;
case ON_HANDLE:
gimp_path_tool_motion_handle (path_tool, mevent, gdisp);
break;
case ON_CURVE:
gimp_path_tool_motion_curve (path_tool, mevent, gdisp);
break;
default:
return;
}
}
void
gimp_path_tool_motion_anchor (GimpPathTool *path_tool,
GdkEventMotion *mevent,
GDisplay *gdisp)
{
gdouble dx, dy, d;
gint x,y;
static gint dxsum = 0;
static gint dysum = 0;
/*
* Dont do anything, if the user clicked with pressed CONTROL-Key,
* because he deleted an anchor.
*/
if (path_tool->click_modifier & GDK_CONTROL_MASK)
return;
if (!(path_tool->state & PATH_TOOL_DRAG))
{
path_tool->state |= PATH_TOOL_DRAG;
dxsum = 0;
dysum = 0;
}
gdisplay_untransform_coords (gdisp, mevent->x, mevent->y, &x, &y, TRUE, 0);
dx = x - path_tool->click_x - dxsum;
dy = y - path_tool->click_y - dysum;
/* restrict to horizontal/vertical lines, if modifiers are pressed
* I'm not sure, if this is intuitive for the user. Esp. When moving
* an endpoint of an curve I'd expect, that the *line* is
* horiz/vertical - not the delta to the point, where the point was
* originally...
*/
if (mevent->state & GDK_MOD1_MASK)
{
if (mevent->state & GDK_CONTROL_MASK)
{
d = (fabs(dx) + fabs(dy)) / 2;
d = (fabs(x - path_tool->click_x) + fabs(y - path_tool->click_y)) / 2;
dx = ((x < path_tool->click_x) ? -d : d ) - dxsum;
dy = ((y < path_tool->click_y) ? -d : d ) - dysum;
}
else
dx = - dxsum;
}
else if (mevent->state & GDK_CONTROL_MASK)
dy = - dysum;
path_tool->draw |= PATH_TOOL_REDRAW_ACTIVE;
gimp_draw_tool_pause (GIMP_DRAW_TOOL(path_tool));
path_offset_active (path_tool->cur_path, dx, dy);
dxsum += dx;
dysum += dy;
gimp_draw_tool_resume (GIMP_DRAW_TOOL (path_tool));
path_tool->draw &= ~PATH_TOOL_REDRAW_ACTIVE;
}
void
gimp_path_tool_motion_handle (GimpPathTool *path_tool,
GdkEventMotion *mevent,
GDisplay *gdisp)
{
gdouble dx, dy;
gint x,y;
static gint dxsum = 0;
static gint dysum = 0;
/*
* Dont do anything, if the user clicked with pressed CONTROL-Key,
* because he moved the handle to the anchor an anchor.
* XXX: Not yet! :-)
*/
if (path_tool->click_modifier & GDK_CONTROL_MASK)
return;
if (!(path_tool->state & PATH_TOOL_DRAG))
{
path_tool->state |= PATH_TOOL_DRAG;
dxsum = 0;
dysum = 0;
}
gdisplay_untransform_coords (gdisp, mevent->x, mevent->y, &x, &y, TRUE, 0);
dx = x - path_tool->click_x - dxsum;
dy = y - path_tool->click_y - dysum;
path_tool->draw |= PATH_TOOL_REDRAW_ACTIVE;
gimp_draw_tool_pause (GIMP_DRAW_TOOL(path_tool));
path_curve_drag_handle (path_tool->click_segment, dx, dy, path_tool->click_handle_id);
dxsum += dx;
dysum += dy;
gimp_draw_tool_resume (GIMP_DRAW_TOOL(path_tool));
path_tool->draw &= ~PATH_TOOL_REDRAW_ACTIVE;
}
void
gimp_path_tool_motion_curve (GimpPathTool *path_tool,
GdkEventMotion *mevent,
GDisplay *gdisp)
{
gdouble dx, dy;
gint x,y;
static gint dxsum = 0;
static gint dysum = 0;
if (!(path_tool->state & PATH_TOOL_DRAG))
{
path_tool->state |= PATH_TOOL_DRAG;
dxsum = 0;
dysum = 0;
}
gdisplay_untransform_coords (gdisp, mevent->x, mevent->y, &x, &y, TRUE, 0);
dx = x - path_tool->click_x - dxsum;
dy = y - path_tool->click_y - dysum;
path_tool->draw |= PATH_TOOL_REDRAW_ACTIVE;
gimp_draw_tool_pause (GIMP_DRAW_TOOL (path_tool));
path_curve_drag_segment (path_tool->click_segment, path_tool->click_position, dx, dy);
dxsum += dx;
dysum += dy;
gimp_draw_tool_resume (GIMP_DRAW_TOOL (path_tool));
path_tool->draw &= ~PATH_TOOL_REDRAW_ACTIVE;
}
static void
gimp_path_tool_cursor_update (GimpTool *tool,
GdkEventMotion *mevent,
GDisplay *gdisp)
{
GimpPathTool *path_tool = GIMP_PATH_TOOL (tool);
#if 0
gint x, y, halfwidth, dummy, cursor_location;
#ifdef PATH_TOOL_DEBUG
/* fprintf (stderr, "path_tool_cursor_update\n");
*/
#endif PATH_TOOL_DEBUG
path_tool = (PathTool *) tool->private;
gdisplay_untransform_coords (gdisp, mevent->x, mevent->y, &x, &y, TRUE, 0);
/* get halfwidth in image coord */
gdisplay_untransform_coords (gdisp, mevent->x + PATH_TOOL_HALFWIDTH, 0, &halfwidth, &dummy, TRUE, 0);
halfwidth -= x;
cursor_location = path_tool_cursor_position (tool, x, y, halfwidth, NULL, NULL, NULL, NULL, NULL);
switch (cursor_location) {
case ON_CANVAS:
gdisplay_install_tool_cursor (gdisp, GIMP_MOUSE1AP_CURSOR);
break;
case ON_ANCHOR:
gdisplay_install_tool_cursor (gdisp, GDK_FLEUR);
break;
case ON_HANDLE:
gdisplay_install_tool_cursor (gdisp, GDK_CROSSHAIR);
break;
case ON_CURVE:
gdisplay_install_tool_cursor (gdisp, GDK_CROSSHAIR);
break;
default:
gdisplay_install_tool_cursor (gdisp, GDK_QUESTION_ARROW);
break;
}
/* New Syntax */
gdisplay_install_tool_cursor (gdisp,
ctype,
GIMP_MEASURE_TOOL_CURSOR,
cmodifier);
#endif
}
static void
gimp_path_tool_draw (GimpDrawTool *draw_tool)
{
GimpPathTool *path_tool;
GimpTool *tool;
path_tool = GIMP_PATH_TOOL (draw_tool);
tool = GIMP_TOOL (draw_tool);
}

101
app/tools/gimppathtool.h Normal file
View File

@ -0,0 +1,101 @@
/* The GIMP -- an image manipulation program
*
* This file Copyright (C) 1999 Simon Budig
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
#ifndef __GIMP_PATH_TOOL_H__
#define __GIMP_PATH_TOOL_H__
#include "gimpdrawtool.h"
#include "path_curves.h"
#define GIMP_TYPE_PATH_TOOL (gimp_path_tool_get_type ())
#define GIMP_PATH_TOOL(obj) (GTK_CHECK_CAST ((obj), GIMP_TYPE_PATH_TOOL, GimpPathTool))
#define GIMP_IS_PATH_TOOL(obj) (GTK_CHECK_TYPE ((obj), GIMP_TYPE_PATH_TOOL))
#define GIMP_PATH_TOOL_CLASS(klass) (GTK_CHECK_CLASS_CAST ((klass), GIMP_TYPE_PATH_TOOL, GimpPathToolClass))
#define GIMP_IS_PATH_TOOL_CLASS(klass) (GTK_CHECK_CLASS_TYPE ((klass), GIMP_TYPE_PATH_TOOL))
typedef struct _GimpPathToolClass GimpPathToolClass;
struct _GimpPathTool
{
GimpDrawTool parent_instance;
gint click_type; /* where did the user click? */
gint click_x; /* X-coordinate of the click */
gint click_y; /* Y-coordinate of the click */
gint click_halfwidth;
guint click_modifier; /* what modifiers were pressed? */
NPath *click_path; /* On which Path/Curve/Segment */
PathCurve *click_curve; /* was the click? */
PathSegment *click_segment;
gdouble click_position; /* The position on the segment */
gint click_handle_id; /* The handle ID of the segment */
gint active_count; /* How many segments are active? */
/*
* WARNING: single_active_segment may contain non NULL Values
* which point to the nirvana. But they are important!
* The pointer is garantueed to be valid, when active_count==1
*/
PathSegment *single_active_segment; /* The only active segment */
gint state; /* state of tool */
gint draw; /* all or part */
NPath *cur_path; /* the current active path */
GSList **scanlines; /* used in converting a path */
};
struct _GimpPathToolClass
{
GimpDrawToolClass parent_class;
};
void gimp_path_tool_register (void);
GtkType gimp_path_tool_get_type (void);
void gimp_path_tool_button_press (GimpTool *, GdkEventButton *, GDisplay *);
void gimp_path_tool_button_release (GimpTool *, GdkEventButton *, GDisplay *);
void gimp_path_tool_motion (GimpTool *, GdkEventMotion *, GDisplay *);
void gimp_path_tool_cursor_update (GimpTool *, GdkEventMotion *, GDisplay *);
void gimp_path_tool_control (GimpTool *, ToolAction, GDisplay *);
void gimp_path_tool_draw (GimpDrawTool *);
void gimp_path_tool_draw_curve (GimpPathTool *, PathCurve *);
void gimp_path_tool_draw_segment (GimpPathTool *, PathSegment *);
gdouble gimp_path_tool_on_curve (GimpPathTool *, gint, gint, gint,
NPath**, PathCurve**, PathSegment**);
gboolean gimp_path_tool_on_anchors (GimpPathTool *, gint, gint, gint,
NPath**, PathCurve**, PathSegment**);
gint gimp_path_tool_on_handles (GimpPathTool *, gint, gint, gint,
NPath **, PathCurve **, PathSegment **);
gint gimp_path_tool_button_press_canvas (GimpPathTool *, GdkEventButton *, GDisplay *);
gint gimp_path_tool_button_press_anchor (GimpPathTool *, GdkEventButton *, GDisplay *);
gint gimp_path_tool_button_press_handle (GimpPathTool *, GdkEventButton *, GDisplay *);
gint gimp_path_tool_button_press_curve (GimpPathTool *, GdkEventButton *, GDisplay *);
void gimp_path_tool_motion_anchor (GimpPathTool *, GdkEventMotion *, GDisplay *);
void gimp_path_tool_motion_handle (GimpPathTool *, GdkEventMotion *, GDisplay *);
void gimp_path_tool_motion_curve (GimpPathTool *, GdkEventMotion *, GDisplay *);
#endif /* __GIMP_PATH_TOOL_H__ */

View File

@ -27,18 +27,20 @@
* segments between two anchors. * segments between two anchors.
*/ */
/*
#include <math.h> #include <math.h>
/* #include "appenv.h"
*/
#include "draw_core.h"
#include "cursorutil.h"
#include "path_tool.h"
#include "path_toolP.h"
#include "path_curves.h" #include "path_curves.h"
#include "config.h" #include "config.h"
#include "libgimp/gimpintl.h" #include "libgimp/gimpintl.h"
*/
#include <glib.h>
#include <gdk/gdk.h>
#include "apptypes.h"
#include "path_curves.h"
#include "path_tool.h"
/* /*
* Every new curve-type has to have a parameter between 0 and 1, and * Every new curve-type has to have a parameter between 0 and 1, and
@ -61,22 +63,22 @@ void path_segment_get_coordinates (PathSegment *,
gdouble, gdouble,
gint *, gint *,
gint *); gint *);
void path_traverse_path (Path *, void path_traverse_path (NPath *,
PathTraverseFunc, PathTraverseFunc,
CurveTraverseFunc, CurveTraverseFunc,
SegmentTraverseFunc, SegmentTraverseFunc,
gpointer); gpointer);
void path_traverse_curve (Path *, void path_traverse_curve (NPath *,
PathCurve *, PathCurve *,
CurveTraverseFunc, CurveTraverseFunc,
SegmentTraverseFunc, SegmentTraverseFunc,
gpointer); gpointer);
void path_traverse_segment (Path *, void path_traverse_segment (NPath *,
PathCurve *, PathCurve *,
PathSegment *, PathSegment *,
SegmentTraverseFunc, SegmentTraverseFunc,
gpointer); gpointer);
gdouble path_locate_point (Path *, gdouble path_locate_point (NPath *,
PathCurve **, PathCurve **,
PathSegment **, PathSegment **,
gint, gint,
@ -85,17 +87,26 @@ gdouble path_locate_point (Path *,
gint, gint,
gint); gint);
gdouble path_tool_on_curve (NPath *path,
gint x,
gint y,
gint halfwidth,
NPath **ret_pathP,
PathCurve **ret_curveP,
PathSegment **ret_segmentP);
/* Tools to manipulate paths, curves, segments */ /* Tools to manipulate paths, curves, segments */
PathCurve * path_add_curve (Path *, PathCurve * path_add_curve (NPath *,
gint, gint,
gint); gint);
PathSegment * path_append_segment (Path *, PathSegment * path_append_segment (NPath *,
PathCurve *, PathCurve *,
SegmentType, SegmentType,
gint, gint,
gint); gint);
PathSegment * path_prepend_segment (Path *, PathSegment * path_prepend_segment (NPath *,
PathCurve *, PathCurve *,
SegmentType, SegmentType,
gint, gint,
@ -105,14 +116,14 @@ PathSegment * path_split_segment (PathSegment *,
void path_join_curves (PathSegment *, void path_join_curves (PathSegment *,
PathSegment *); PathSegment *);
void path_flip_curve (PathCurve *); void path_flip_curve (PathCurve *);
void path_free_path (Path *); void path_free_path (NPath *);
void path_free_curve (PathCurve *); void path_free_curve (PathCurve *);
void path_free_segment (PathSegment *); void path_free_segment (PathSegment *);
void path_delete_segment (PathSegment *); void path_delete_segment (PathSegment *);
void path_print (Path *); void path_print (NPath *);
void path_offset_active (Path *, gdouble, gdouble); void path_offset_active (NPath *, gdouble, gdouble);
void path_set_flags (PathTool *, void path_set_flags (GimpPathTool *,
Path *, NPath *,
PathCurve *, PathCurve *,
PathSegment *, PathSegment *,
guint32, guint32,
@ -120,13 +131,14 @@ void path_set_flags (PathTool *,
/* High level image-manipulation functions */ /* High level image-manipulation functions */
void path_stroke (PathTool *, void path_stroke (GimpPathTool *,
Path *); NPath *);
void path_to_selection (PathTool *, void path_to_selection (GimpPathTool *,
Path *); NPath *);
/* Functions necessary for the tool */ /* Functions necessary for the tool */
#if 0
void path_tool_button_press (Tool *, GdkEventButton *, gpointer); void path_tool_button_press (Tool *, GdkEventButton *, gpointer);
void path_tool_button_release (Tool *, GdkEventButton *, gpointer); void path_tool_button_release (Tool *, GdkEventButton *, gpointer);
void path_tool_motion (Tool *, GdkEventMotion *, gpointer); void path_tool_motion (Tool *, GdkEventMotion *, gpointer);
@ -137,11 +149,11 @@ void path_tool_draw_curve (Tool *, PathCurve *);
void path_tool_draw_segment (Tool *, PathSegment *); void path_tool_draw_segment (Tool *, PathSegment *);
gdouble path_tool_on_curve (Tool *, gint, gint, gint, gdouble path_tool_on_curve (Tool *, gint, gint, gint,
Path**, PathCurve**, PathSegment**); NPath**, PathCurve**, PathSegment**);
gboolean path_tool_on_anchors (Tool *, gint, gint, gint, gboolean path_tool_on_anchors (Tool *, gint, gint, gint,
Path**, PathCurve**, PathSegment**); NPath**, PathCurve**, PathSegment**);
gint path_tool_on_handles (Tool *, gint, gint, gint, gint path_tool_on_handles (Tool *, gint, gint, gint,
Path **, PathCurve **, PathSegment **); NPath **, PathCurve **, PathSegment **);
gint path_tool_button_press_canvas (Tool *, GdkEventButton *, GDisplay *); gint path_tool_button_press_canvas (Tool *, GdkEventButton *, GDisplay *);
gint path_tool_button_press_anchor (Tool *, GdkEventButton *, GDisplay *); gint path_tool_button_press_anchor (Tool *, GdkEventButton *, GDisplay *);
@ -151,6 +163,7 @@ void path_tool_motion_anchor (Tool *, GdkEventMotion *, GDisplay *);
void path_tool_motion_handle (Tool *, GdkEventMotion *, GDisplay *); void path_tool_motion_handle (Tool *, GdkEventMotion *, GDisplay *);
void path_tool_motion_curve (Tool *, GdkEventMotion *, GDisplay *); void path_tool_motion_curve (Tool *, GdkEventMotion *, GDisplay *);
#endif
/* the path tool options */ /* the path tool options */
static ToolOptions *path_options = NULL; static ToolOptions *path_options = NULL;
@ -181,7 +194,7 @@ static ToolOptions *path_options = NULL;
*/ */
void void
path_traverse_path (Path *path, path_traverse_path (NPath *path,
PathTraverseFunc pathfunc, PathTraverseFunc pathfunc,
CurveTraverseFunc curvefunc, CurveTraverseFunc curvefunc,
SegmentTraverseFunc segmentfunc, SegmentTraverseFunc segmentfunc,
@ -207,7 +220,7 @@ path_traverse_path (Path *path,
void void
path_traverse_curve (Path *path, path_traverse_curve (NPath *path,
PathCurve *curve, PathCurve *curve,
CurveTraverseFunc curvefunc, CurveTraverseFunc curvefunc,
SegmentTraverseFunc segmentfunc, SegmentTraverseFunc segmentfunc,
@ -232,7 +245,7 @@ path_traverse_curve (Path *path,
} }
void void
path_traverse_segment (Path *path, path_traverse_segment (NPath *path,
PathCurve *curve, PathCurve *curve,
PathSegment *segment, PathSegment *segment,
SegmentTraverseFunc function, SegmentTraverseFunc function,
@ -257,7 +270,7 @@ path_traverse_segment (Path *path,
*/ */
PathCurve * PathCurve *
path_add_curve (Path * cur_path, path_add_curve (NPath * cur_path,
gint x, gint x,
gint y) gint y)
{ {
@ -293,7 +306,7 @@ path_add_curve (Path * cur_path,
PathSegment * PathSegment *
path_append_segment (Path * cur_path, path_append_segment (NPath * cur_path,
PathCurve * cur_curve, PathCurve * cur_curve,
SegmentType type, SegmentType type,
gint x, gint x,
@ -347,7 +360,7 @@ path_append_segment (Path * cur_path,
PathSegment * PathSegment *
path_prepend_segment (Path * cur_path, path_prepend_segment (NPath * cur_path,
PathCurve * cur_curve, PathCurve * cur_curve,
SegmentType type, SegmentType type,
gint x, gint x,
@ -409,8 +422,7 @@ path_split_segment (PathSegment *segment,
new_segment = g_new (PathSegment, 1); new_segment = g_new (PathSegment, 1);
new_segment->type = segment->type; new_segment->type = segment->type;
/* XXX: Giving PathTool as NULL Pointer! */ path_curve_get_point (segment, position, &(new_segment->x), &(new_segment->y));
path_curve_get_point (NULL, segment, position, &(new_segment->x), &(new_segment->y));
new_segment->flags = 0; new_segment->flags = 0;
new_segment->parent = segment->parent; new_segment->parent = segment->parent;
new_segment->next = segment->next; new_segment->next = segment->next;
@ -602,7 +614,7 @@ path_flip_curve (PathCurve *curve)
void void
path_free_path (Path * path) path_free_path (NPath * path)
{ {
PathCurve *tmp1, *tmp2; PathCurve *tmp1, *tmp2;
@ -651,7 +663,7 @@ path_free_segment (PathSegment *segment)
* consistent */ * consistent */
path_set_flags (segment->parent->parent->path_tool, segment->parent->parent, path_set_flags (NULL, segment->parent->parent,
segment->parent, segment, 0, SEGMENT_ACTIVE); segment->parent, segment, 0, SEGMENT_ACTIVE);
path_curve_cleanup_segment(segment); path_curve_cleanup_segment(segment);
@ -715,11 +727,11 @@ path_delete_segment (PathSegment *segment)
*/ */
gint gint
path_tool_cursor_position (Tool *tool, path_tool_cursor_position (NPath *path,
gint x, gint x,
gint y, gint y,
gint halfwidth, gint halfwidth,
Path **pathP, NPath **pathP,
PathCurve **curveP, PathCurve **curveP,
PathSegment **segmentP, PathSegment **segmentP,
gdouble *positionP, gdouble *positionP,
@ -728,16 +740,16 @@ path_tool_cursor_position (Tool *tool,
gdouble pos; gdouble pos;
gint handle_id; gint handle_id;
if (path_tool_on_anchors (tool, x, y, halfwidth, pathP, curveP, segmentP)) if (path_tool_on_anchors (path, x, y, halfwidth, pathP, curveP, segmentP))
return ON_ANCHOR; return ON_ANCHOR;
handle_id = path_tool_on_handles (tool, x, y, halfwidth, pathP, curveP, segmentP); handle_id = path_tool_on_handles (path, x, y, halfwidth, pathP, curveP, segmentP);
if (handle_id) { if (handle_id) {
if (handle_idP) (*handle_idP) = handle_id; if (handle_idP) (*handle_idP) = handle_id;
return ON_HANDLE; return ON_HANDLE;
} }
pos = path_tool_on_curve (tool, x, y, halfwidth, pathP, curveP, segmentP); pos = path_tool_on_curve (path, x, y, halfwidth, pathP, curveP, segmentP);
if (pos >= 0 && pos <= 1) { if (pos >= 0 && pos <= 1) {
if (positionP) (*positionP) = pos; if (positionP) (*positionP) = pos;
return ON_CURVE; return ON_CURVE;
@ -748,6 +760,7 @@ path_tool_cursor_position (Tool *tool,
} }
#if 0
/************************************************************** /**************************************************************
* The click-callbacks for the tool * The click-callbacks for the tool
*/ */
@ -837,7 +850,7 @@ path_tool_button_press_anchor (Tool *tool,
gboolean doubleclick=FALSE; gboolean doubleclick=FALSE;
PathTool *path_tool = tool->private; PathTool *path_tool = tool->private;
Path * cur_path = path_tool->cur_path; NPath * cur_path = path_tool->cur_path;
PathSegment *p_sas; PathSegment *p_sas;
gint grab_pointer; gint grab_pointer;
@ -962,7 +975,7 @@ path_tool_button_press_handle (Tool *tool,
gboolean doubleclick=FALSE; gboolean doubleclick=FALSE;
PathTool *path_tool = tool->private; PathTool *path_tool = tool->private;
Path * cur_path = path_tool->cur_path; NPath * cur_path = path_tool->cur_path;
gint grab_pointer; gint grab_pointer;
#ifdef PATH_TOOL_DEBUG #ifdef PATH_TOOL_DEBUG
@ -1002,7 +1015,7 @@ path_tool_button_press_canvas (Tool *tool,
{ {
PathTool *path_tool = tool->private; PathTool *path_tool = tool->private;
Path * cur_path = path_tool->cur_path; NPath * cur_path = path_tool->cur_path;
PathCurve * cur_curve; PathCurve * cur_curve;
PathSegment * cur_segment; PathSegment * cur_segment;
gint grab_pointer; gint grab_pointer;
@ -1058,7 +1071,7 @@ path_tool_button_press_curve (Tool *tool,
{ {
PathTool *path_tool = tool->private; PathTool *path_tool = tool->private;
Path * cur_path = path_tool->cur_path; NPath * cur_path = path_tool->cur_path;
PathSegment * cur_segment; PathSegment * cur_segment;
gint grab_pointer; gint grab_pointer;
@ -1070,7 +1083,7 @@ path_tool_button_press_curve (Tool *tool,
if (!cur_path) { if (!cur_path) {
#ifdef PATH_TOOL_DEBUG #ifdef PATH_TOOL_DEBUG
fprintf (stderr, "Fatal error: No current Path\n"); fprintf (stderr, "Fatal error: No current NPath\n");
#endif PATH_TOOL_DEBUG #endif PATH_TOOL_DEBUG
return 0; return 0;
} }
@ -1421,7 +1434,7 @@ tools_new_path_tool (void)
private->state = 0; private->state = 0;
private->draw = PATH_TOOL_REDRAW_ALL; private->draw = PATH_TOOL_REDRAW_ALL;
private->core = draw_core_new (path_tool_draw); private->core = draw_core_new (path_tool_draw);
private->cur_path = g_new0(Path, 1); private->cur_path = g_new0(NPath, 1);
private->scanlines = NULL; private->scanlines = NULL;
@ -1470,14 +1483,14 @@ tools_free_path_tool (Tool *tool)
} }
#endif
/************************************************************** /**************************************************************
* Set of function to determine, if the click was on a segment * Set of function to determine, if the click was on a segment
*/ */
typedef struct { typedef struct {
Tool *tool; NPath *path;
Path *path;
PathCurve *curve; PathCurve *curve;
PathSegment *segment; PathSegment *segment;
gint testx; gint testx;
@ -1490,7 +1503,7 @@ typedef struct {
/* This is a CurveTraverseFunc */ /* This is a CurveTraverseFunc */
void void
path_tool_on_curve_helper (Path *path, path_tool_on_curve_helper (NPath *path,
PathCurve *curve, PathCurve *curve,
PathSegment *segment, PathSegment *segment,
gpointer ptr) gpointer ptr)
@ -1501,7 +1514,7 @@ path_tool_on_curve_helper (Path *path,
if (segment && segment->next && data && data->distance > 0) if (segment && segment->next && data && data->distance > 0)
{ {
position = path_curve_on_segment (data->tool, segment, data->testx, data->testy, data->halfwidth, &distance); position = path_curve_on_segment (segment, data->testx, data->testy, data->halfwidth, &distance);
if (position >= 0 && distance < data->distance ) if (position >= 0 && distance < data->distance )
{ {
data->path = path; data->path = path;
@ -1515,20 +1528,19 @@ path_tool_on_curve_helper (Path *path,
} }
gdouble gdouble
path_tool_on_curve (Tool *tool, path_tool_on_curve (NPath *path,
gint x, gint x,
gint y, gint y,
gint halfwidth, gint halfwidth,
Path **ret_pathP, NPath **ret_pathP,
PathCurve **ret_curveP, PathCurve **ret_curveP,
PathSegment **ret_segmentP) PathSegment **ret_segmentP)
{ {
Path_on_curve_type *data = g_new (Path_on_curve_type, 1); Path_on_curve_type *data = g_new (Path_on_curve_type, 1);
gdouble position; gdouble position;
data->tool = tool; data->path = path;
data->path = NULL; data->curve = NULL;
data->segment = NULL;
data->segment = NULL; data->segment = NULL;
data->testx = x; data->testx = x;
data->testy = y; data->testy = y;
@ -1537,7 +1549,7 @@ path_tool_on_curve (Tool *tool,
data->position = -1; data->position = -1;
data->found = FALSE; data->found = FALSE;
path_traverse_path (((PathTool *) data->tool->private)->cur_path, NULL, path_tool_on_curve_helper, NULL, data); path_traverse_path (path, NULL, path_tool_on_curve_helper, NULL, data);
if (ret_pathP) *ret_pathP = data->path; if (ret_pathP) *ret_pathP = data->path;
if (ret_curveP) *ret_curveP = data->curve; if (ret_curveP) *ret_curveP = data->curve;
@ -1556,7 +1568,7 @@ path_tool_on_curve (Tool *tool,
*/ */
typedef struct { typedef struct {
Path *path; NPath *path;
PathCurve *curve; PathCurve *curve;
PathSegment *segment; PathSegment *segment;
gint testx; gint testx;
@ -1567,7 +1579,7 @@ typedef struct {
/* This is a CurveTraverseFunc */ /* This is a CurveTraverseFunc */
void void
path_tool_on_anchors_helper (Path *path, path_tool_on_anchors_helper (NPath *path,
PathCurve *curve, PathCurve *curve,
PathSegment *segment, PathSegment *segment,
gpointer ptr) gpointer ptr)
@ -1592,18 +1604,18 @@ path_tool_on_anchors_helper (Path *path,
} }
gboolean gboolean
path_tool_on_anchors (Tool *tool, path_tool_on_anchors (NPath *path,
gint x, gint x,
gint y, gint y,
gint halfwidth, gint halfwidth,
Path **ret_pathP, NPath **ret_pathP,
PathCurve **ret_curveP, PathCurve **ret_curveP,
PathSegment **ret_segmentP) PathSegment **ret_segmentP)
{ {
Path_on_anchors_type *data = g_new (Path_on_anchors_type, 1); Path_on_anchors_type *data = g_new (Path_on_anchors_type, 1);
gboolean ret_found; gboolean ret_found;
data->path = NULL; data->path = path;
data->curve = NULL; data->curve = NULL;
data->segment = NULL; data->segment = NULL;
data->testx = x; data->testx = x;
@ -1611,7 +1623,7 @@ path_tool_on_anchors (Tool *tool,
data->distance = halfwidth * halfwidth + 1; data->distance = halfwidth * halfwidth + 1;
data->found = FALSE; data->found = FALSE;
path_traverse_path (((PathTool *) tool->private)->cur_path, NULL, path_tool_on_anchors_helper, NULL, data); path_traverse_path (path, NULL, path_tool_on_anchors_helper, NULL, data);
if (ret_pathP) *ret_pathP = data->path; if (ret_pathP) *ret_pathP = data->path;
if (ret_curveP) *ret_curveP = data->curve; if (ret_curveP) *ret_curveP = data->curve;
@ -1630,7 +1642,7 @@ path_tool_on_anchors (Tool *tool,
*/ */
typedef struct { typedef struct {
Path *path; NPath *path;
PathCurve *curve; PathCurve *curve;
PathSegment *segment; PathSegment *segment;
gint testx; gint testx;
@ -1642,7 +1654,7 @@ typedef struct {
/* This is a CurveTraverseFunc */ /* This is a CurveTraverseFunc */
void void
path_tool_on_handles_helper (Path *path, path_tool_on_handles_helper (NPath *path,
PathCurve *curve, PathCurve *curve,
PathSegment *segment, PathSegment *segment,
gpointer ptr) gpointer ptr)
@ -1652,8 +1664,8 @@ path_tool_on_handles_helper (Path *path,
if (segment && data && !data->found) if (segment && data && !data->found)
{ {
handle = path_curve_on_handle (NULL, segment, data->testx, data->testy, handle = path_curve_on_handle (segment, data->testx, data->testy,
data->halfwidth); data->halfwidth);
if (handle) if (handle)
{ {
data->path = path; data->path = path;
@ -1666,18 +1678,18 @@ path_tool_on_handles_helper (Path *path,
} }
gint gint
path_tool_on_handles (Tool *tool, path_tool_on_handles (NPath *path,
gint x, gint x,
gint y, gint y,
gint halfwidth, gint halfwidth,
Path **ret_pathP, NPath **ret_pathP,
PathCurve **ret_curveP, PathCurve **ret_curveP,
PathSegment **ret_segmentP) PathSegment **ret_segmentP)
{ {
Path_on_handles_type *data = g_new (Path_on_handles_type, 1); Path_on_handles_type *data = g_new (Path_on_handles_type, 1);
gint handle_ret; gint handle_ret;
data->path = NULL; data->path = path;
data->curve = NULL; data->curve = NULL;
data->segment = NULL; data->segment = NULL;
data->testx = x; data->testx = x;
@ -1686,7 +1698,7 @@ path_tool_on_handles (Tool *tool,
data->handle_id = 0; data->handle_id = 0;
data->found = FALSE; data->found = FALSE;
path_traverse_path (((PathTool *) tool->private)->cur_path, NULL, path_tool_on_handles_helper, NULL, data); path_traverse_path (path, NULL, path_tool_on_handles_helper, NULL, data);
if (ret_pathP) *ret_pathP = data->path; if (ret_pathP) *ret_pathP = data->path;
if (ret_curveP) *ret_curveP = data->curve; if (ret_curveP) *ret_curveP = data->curve;
@ -1711,7 +1723,7 @@ typedef struct {
/* This is a CurveTraverseFunc */ /* This is a CurveTraverseFunc */
void void
path_offset_active_helper (Path *path, path_offset_active_helper (NPath *path,
PathCurve *curve, PathCurve *curve,
PathSegment *segment, PathSegment *segment,
gpointer ptr) gpointer ptr)
@ -1726,7 +1738,7 @@ path_offset_active_helper (Path *path,
} }
void void
path_offset_active (Path *path, path_offset_active (NPath *path,
gdouble dx, gdouble dx,
gdouble dy) gdouble dy)
{ {
@ -1748,12 +1760,12 @@ path_offset_active (Path *path,
typedef struct { typedef struct {
guint32 bits_set; guint32 bits_set;
guint32 bits_clear; guint32 bits_clear;
PathTool *path_tool; GimpPathTool *path_tool;
} Path_set_flags_type; } Path_set_flags_type;
/* This is a CurveTraverseFunc */ /* This is a CurveTraverseFunc */
void void
path_set_flags_helper (Path *path, path_set_flags_helper (NPath *path,
PathCurve *curve, PathCurve *curve,
PathSegment *segment, PathSegment *segment,
gpointer ptr) gpointer ptr)
@ -1768,14 +1780,17 @@ path_set_flags_helper (Path *path,
segment->flags |= tmp->bits_set; segment->flags |= tmp->bits_set;
/* /*
* Some black magic: We try to remember, which is the single active segment. * Some black magic: We try to remember, which is the single active
* We count, how many segments are active (in path_tool->active_count) and * segment. We count, how many segments are active (in
* XOR path_tool->single_active_segment every time we select or deselect * path_tool->active_count) and XOR path_tool->single_active_segment
* an anchor. So if exactly one anchor is active, path_tool->single_active_segment * every time we select or deselect an anchor. So if exactly one anchor
* points to it. * is active, path_tool->single_active_segment points to it.
*/ */
/* If SEGMENT_ACTIVE state has changed change the PathTool data accordingly.*/ #if 0
/* If SEGMENT_ACTIVE state has changed change the PathTool data
* accordingly.
*/
if (((segment->flags ^ oldflags) & SEGMENT_ACTIVE) && tmp && tmp->path_tool) { if (((segment->flags ^ oldflags) & SEGMENT_ACTIVE) && tmp && tmp->path_tool) {
if (segment->flags & SEGMENT_ACTIVE) if (segment->flags & SEGMENT_ACTIVE)
tmp->path_tool->active_count++; tmp->path_tool->active_count++;
@ -1788,12 +1803,13 @@ path_set_flags_helper (Path *path,
tmp_uint ^= GPOINTER_TO_UINT(segment); tmp_uint ^= GPOINTER_TO_UINT(segment);
tmp->path_tool->single_active_segment = GUINT_TO_POINTER(tmp_uint); tmp->path_tool->single_active_segment = GUINT_TO_POINTER(tmp_uint);
} }
#endif
} }
} }
void void
path_set_flags (PathTool *path_tool, path_set_flags (GimpPathTool *path_tool,
Path *path, NPath *path,
PathCurve *curve, PathCurve *curve,
PathSegment *segment, PathSegment *segment,
guint32 bits_set, guint32 bits_set,
@ -1821,11 +1837,12 @@ path_set_flags (PathTool *path_tool,
/* This is a CurveTraverseFunc */ /* This is a CurveTraverseFunc */
void void
path_tool_draw_helper (Path *path, path_tool_draw_helper (NPath *path,
PathCurve *curve, PathCurve *curve,
PathSegment *segment, PathSegment *segment,
gpointer tool_ptr) gpointer tool_ptr)
{ {
#if 0
Tool * tool = (Tool *) tool_ptr; Tool * tool = (Tool *) tool_ptr;
GDisplay * gdisp; GDisplay * gdisp;
PathTool * path_tool; PathTool * path_tool;
@ -1871,13 +1888,15 @@ path_tool_draw_helper (Path *path,
else if (!segment) else if (!segment)
fprintf(stderr, "path_tool_draw_segment: no segment to draw\n"); fprintf(stderr, "path_tool_draw_segment: no segment to draw\n");
#endif PATH_TOOL_DEBUG #endif PATH_TOOL_DEBUG
#endif
} }
void void
path_tool_draw (Tool *tool) path_tool_draw (Tool *tool)
{ {
#if 0
GDisplay * gdisp; GDisplay * gdisp;
Path * cur_path; NPath * cur_path;
PathTool * path_tool; PathTool * path_tool;
#ifdef PATH_TOOL_DEBUG #ifdef PATH_TOOL_DEBUG
@ -1894,6 +1913,7 @@ path_tool_draw (Tool *tool)
/* fprintf (stderr, "path_tool_draw end.\n"); /* fprintf (stderr, "path_tool_draw end.\n");
*/ */
#endif PATH_TOOL_DEBUG #endif PATH_TOOL_DEBUG
#endif
} }

View File

@ -20,14 +20,89 @@
#ifndef __PATH_TOOL_H__ #ifndef __PATH_TOOL_H__
#define __PATH_TOOL_H__ #define __PATH_TOOL_H__
#include "tools.h" /*
* Every new curve-type has to have a parameter between 0 and 1, and
* should go from a starting to a target point.
*/
/* path functions */ /* Some defines... */
Tool * tools_new_path_tool (void); #define PATH_TOOL_WIDTH 8
void tools_free_path_tool (Tool *); #define PATH_TOOL_HALFWIDTH 4
/* function prototypes */
#endif /* __PATH_TOOL_H__ */ /* Small functions to determine coordinates, iterate over path/curve/segment */
void path_segment_get_coordinates (PathSegment *,
gdouble,
gint *,
gint *);
void path_traverse_path (NPath *,
PathTraverseFunc,
CurveTraverseFunc,
SegmentTraverseFunc,
gpointer);
void path_traverse_curve (NPath *,
PathCurve *,
CurveTraverseFunc,
SegmentTraverseFunc,
gpointer);
void path_traverse_segment (NPath *,
PathCurve *,
PathSegment *,
SegmentTraverseFunc,
gpointer);
gdouble path_locate_point (NPath *,
PathCurve **,
PathSegment **,
gint,
gint,
gint,
gint,
gint);
/* Tools to manipulate paths, curves, segments */
PathCurve * path_add_curve (NPath *,
gint,
gint);
PathSegment * path_append_segment (NPath *,
PathCurve *,
SegmentType,
gint,
gint);
PathSegment * path_prepend_segment (NPath *,
PathCurve *,
SegmentType,
gint,
gint);
PathSegment * path_split_segment (PathSegment *,
gdouble);
void path_join_curves (PathSegment *,
PathSegment *);
void path_flip_curve (PathCurve *);
void path_free_path (NPath *);
void path_free_curve (PathCurve *);
void path_free_segment (PathSegment *);
void path_delete_segment (PathSegment *);
void path_print (NPath *);
void path_offset_active (NPath *, gdouble, gdouble);
void path_set_flags (GimpPathTool *,
NPath *,
PathCurve *,
PathSegment *,
guint32,
guint32);
/* High level image-manipulation functions */
void path_stroke (GimpPathTool *,
NPath *);
void path_to_selection (GimpPathTool *,
NPath *);
#endif /* __PATH_TOOL_H__ */

View File

@ -20,12 +20,12 @@
#undef PATH_TOOL_DEBUG #undef PATH_TOOL_DEBUG
#include "draw_core.h"
#ifdef PATH_TOOL_DEBUG #ifdef PATH_TOOL_DEBUG
#include <stdio.h> #include <stdio.h>
#endif #endif
#include "apptypes.h"
#define IMAGE_COORDS 1 #define IMAGE_COORDS 1
#define AA_IMAGE_COORDS 2 #define AA_IMAGE_COORDS 2
#define SCREEN_COORDS 3 #define SCREEN_COORDS 3
@ -46,9 +46,7 @@ enum { ON_ANCHOR, ON_HANDLE, ON_CURVE, ON_CANVAS };
typedef struct _path_segment PathSegment; typedef struct _path_segment PathSegment;
typedef struct _path_curve PathCurve; typedef struct _path_curve PathCurve;
typedef struct _path Path; typedef struct _npath NPath;
typedef struct _path_tool PathTool;
struct _path_segment struct _path_segment
{ {
@ -69,22 +67,23 @@ struct _path_curve
{ {
PathSegment *segments; /* The segments of the curve */ PathSegment *segments; /* The segments of the curve */
PathSegment *cur_segment; /* the current segment */ PathSegment *cur_segment; /* the current segment */
Path *parent; /* the parent Path */ NPath *parent; /* the parent Path */
PathCurve *next; /* Next Curve or NULL */ PathCurve *next; /* Next Curve or NULL */
PathCurve *prev; /* Previous Curve or NULL */ PathCurve *prev; /* Previous Curve or NULL */
}; };
struct _path struct _npath
{ {
PathCurve *curves; /* the curves */ PathCurve *curves; /* the curves */
PathCurve *cur_curve; /* the current curve */ PathCurve *cur_curve; /* the current curve */
GString *name; /* the name of the path */ GString *name; /* the name of the path */
guint32 state; /* is the path locked? */ guint32 state; /* is the path locked? */
PathTool *path_tool; /* The parent Path Tool */ /* GimpPathTool *path_tool; */ /* The parent Path Tool */
}; };
#if 0
struct _path_tool struct _path_tool
{ {
gint click_type; /* where did the user click? */ gint click_type; /* where did the user click? */
@ -92,7 +91,7 @@ struct _path_tool
gint click_y; /* Y-coordinate of the click */ gint click_y; /* Y-coordinate of the click */
gint click_halfwidth; gint click_halfwidth;
guint click_modifier; /* what modifiers were pressed? */ guint click_modifier; /* what modifiers were pressed? */
Path *click_path; /* On which Path/Curve/Segment */ NPath *click_path; /* On which Path/Curve/Segment */
PathCurve *click_curve; /* was the click? */ PathCurve *click_curve; /* was the click? */
PathSegment *click_segment; PathSegment *click_segment;
gdouble click_position; /* The position on the segment */ gdouble click_position; /* The position on the segment */
@ -109,21 +108,23 @@ struct _path_tool
gint state; /* state of tool */ gint state; /* state of tool */
gint draw; /* all or part */ gint draw; /* all or part */
DrawCore *core; /* Core drawing object */ DrawCore *core; /* Core drawing object */
Path *cur_path; /* the current active path */ NPath *cur_path; /* the current active path */
GSList **scanlines; /* used in converting a path */ GSList **scanlines; /* used in converting a path */
}; };
#endif
typedef void typedef void
(*PathTraverseFunc) (Path *, (*PathTraverseFunc) (NPath *,
PathCurve *, PathCurve *,
gpointer); gpointer);
typedef void typedef void
(*CurveTraverseFunc) (Path *, (*CurveTraverseFunc) (NPath *,
PathCurve *, PathCurve *,
PathSegment *, PathSegment *,
gpointer); gpointer);
typedef void typedef void
(*SegmentTraverseFunc) (Path *, (*SegmentTraverseFunc) (NPath *,
PathCurve *, PathCurve *,
PathSegment *, PathSegment *,
gint, gint,

View File

@ -46,6 +46,7 @@
#include "gimpmeasuretool.h" #include "gimpmeasuretool.h"
#include "gimpmovetool.h" #include "gimpmovetool.h"
#include "gimppaintbrushtool.h" #include "gimppaintbrushtool.h"
#include "gimppathtool.h"
#include "gimppenciltool.h" #include "gimppenciltool.h"
#include "gimpperspectivetool.h" #include "gimpperspectivetool.h"
#include "gimprectselecttool.h" #include "gimprectselecttool.h"
@ -88,6 +89,7 @@ register_tools (void)
/* non-modifying tools */ /* non-modifying tools */
gimp_path_tool_register ();
gimp_measure_tool_register (); gimp_measure_tool_register ();
gimp_magnify_tool_register (); gimp_magnify_tool_register ();
gimp_color_picker_tool_register (); gimp_color_picker_tool_register ();