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>
* configure.in

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -20,8 +20,85 @@
#ifndef __PATH_CURVES_H__
#define __PATH_CURVES_H__
#include <gdk/gdk.h>
#include "path_toolP.h"
#undef PATH_TOOL_DEBUG
#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.
*/
typedef guint (*PathGetPointsFunc) (PathTool *path_tool,
PathSegment *segment,
GdkPoint *points,
typedef guint (*PathGetPointsFunc) (PathSegment *segment,
gdouble *points,
guint npoints,
gdouble start,
gdouble end);
typedef void (*PathGetPointFunc) (PathTool *path_tool,
PathSegment *segment,
typedef void (*PathGetPointFunc) (PathSegment *segment,
gdouble position,
gdouble *x,
gdouble *y);
typedef void (*PathDrawHandlesFunc) (Tool *tool,
typedef void (*PathDrawHandlesFunc) (GimpDrawTool *tool,
PathSegment *segment);
typedef void (*PathDrawSegmentFunc) (Tool *tool,
typedef void (*PathDrawSegmentFunc) (GimpDrawTool *tool,
PathSegment *segment);
typedef gdouble (*PathOnSegmentFunc) (Tool *tool,
PathSegment *segment,
typedef gdouble (*PathOnSegmentFunc) (PathSegment *segment,
gint x,
gint y,
gint halfwidth,
gint *distance);
typedef void (*PathDragSegmentFunc) (PathTool *path_tool,
PathSegment *segment,
typedef void (*PathDragSegmentFunc) (PathSegment *segment,
gdouble position,
gdouble dx,
gdouble dy);
typedef gint (*PathOnHandlesFunc) (PathTool *path_tool,
PathSegment *segment,
typedef gint (*PathOnHandlesFunc) (PathSegment *segment,
gdouble x,
gdouble y,
gdouble halfwidth);
typedef void (*PathDragHandleFunc) (PathTool *path_tool,
PathSegment *segment,
typedef void (*PathDragHandleFunc) (PathSegment *segment,
gdouble dx,
gdouble dy,
gint handle_id);
typedef PathSegment * (*PathInsertAnchorFunc) (PathTool *path_tool,
PathSegment *segment,
typedef PathSegment * (*PathInsertAnchorFunc) (PathSegment *segment,
gdouble position);
typedef void (*PathUpdateSegmentFunc) (PathTool *path_tool,
PathSegment *segment);
typedef void (*PathUpdateSegmentFunc) (PathSegment *segment);
typedef void (*PathFlipSegmentFunc) (PathSegment *segment);
@ -108,66 +177,58 @@ typedef struct {
guint
path_curve_get_points (PathTool *path_tool,
PathSegment *segment,
GdkPoint *points,
path_curve_get_points (PathSegment *segment,
gdouble *points,
guint npoints,
gdouble start,
gdouble end);
void
path_curve_get_point (PathTool *path_tool,
PathSegment *segment,
path_curve_get_point (PathSegment *segment,
gdouble position,
gdouble *x,
gdouble *y);
void
path_curve_draw_handles (Tool *tool,
path_curve_draw_handles (GimpDrawTool *tool,
PathSegment *segment);
void
path_curve_draw_segment (Tool *tool,
path_curve_draw_segment (GimpDrawTool *tool,
PathSegment *segment);
gdouble
path_curve_on_segment (Tool *tool,
PathSegment *segment,
path_curve_on_segment (PathSegment *segment,
gint x,
gint y,
gint halfwidth,
gint *distance);
void
path_curve_drag_segment (PathTool *path_tool,
PathSegment *segment,
path_curve_drag_segment (PathSegment *segment,
gdouble position,
gdouble dx,
gdouble dy);
gint
path_curve_on_handle (PathTool *path_tool,
PathSegment *segment,
path_curve_on_handle (PathSegment *segment,
gdouble x,
gdouble y,
gdouble halfwidth);
void
path_curve_drag_handle (PathTool *path_tool,
PathSegment *segment,
path_curve_drag_handle (PathSegment *segment,
gdouble dx,
gdouble dy,
gint handle_id);
PathSegment *
path_curve_insert_anchor (PathTool *path_tool,
PathSegment *segment,
gdouble position);
path_curve_insert_anchor (PathSegment *segment,
gdouble position);
void
path_curve_update_segment (PathTool *path_tool,
PathSegment *segment);
path_curve_update_segment (PathSegment *segment);
void
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 */
/* Image name: path_tool */
/*
#define path_tool_width 22
#define path_tool_height 22
static char *path_tool_bits [] =
@ -1040,7 +1039,6 @@ static char *path_tool_bits [] =
"..a...................",
"......................"
};
*/
/* GIMP icon image format -- S. Kimball, P. Mattis */
/* Image name: by_color_select */

View File

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

View File

@ -22,7 +22,9 @@
#include "apptypes.h"
#include "gdisplay.h"
#include "gimpdrawtool.h"
#include "libgimpmath/gimpmath.h"
enum
@ -225,3 +227,70 @@ gimp_draw_tool_pause (GimpDrawTool *core)
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_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__ */

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

View File

@ -1,5 +1,5 @@
/* 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
@ -20,14 +20,89 @@
#ifndef __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);
void tools_free_path_tool (Tool *);
#define PATH_TOOL_WIDTH 8
#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
#include "draw_core.h"
#ifdef PATH_TOOL_DEBUG
#include <stdio.h>
#endif
#include "apptypes.h"
#define IMAGE_COORDS 1
#define AA_IMAGE_COORDS 2
#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_curve PathCurve;
typedef struct _path Path;
typedef struct _path_tool PathTool;
typedef struct _npath NPath;
struct _path_segment
{
@ -69,22 +67,23 @@ struct _path_curve
{
PathSegment *segments; /* The segments of the curve */
PathSegment *cur_segment; /* the current segment */
Path *parent; /* the parent Path */
NPath *parent; /* the parent Path */
PathCurve *next; /* Next Curve or NULL */
PathCurve *prev; /* Previous Curve or NULL */
};
struct _path
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? */
PathTool *path_tool; /* The parent Path Tool */
/* GimpPathTool *path_tool; */ /* The parent Path Tool */
};
#if 0
struct _path_tool
{
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_halfwidth;
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? */
PathSegment *click_segment;
gdouble click_position; /* The position on the segment */
@ -109,21 +108,23 @@ struct _path_tool
gint state; /* state of tool */
gint draw; /* all or part */
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 */
};
#endif
typedef void
(*PathTraverseFunc) (Path *,
(*PathTraverseFunc) (NPath *,
PathCurve *,
gpointer);
typedef void
(*CurveTraverseFunc) (Path *,
(*CurveTraverseFunc) (NPath *,
PathCurve *,
PathSegment *,
gpointer);
typedef void
(*SegmentTraverseFunc) (Path *,
(*SegmentTraverseFunc) (NPath *,
PathCurve *,
PathSegment *,
gint,

View File

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