mirror of https://github.com/GNOME/gimp.git
app/Makefile.am app/path_bezier.[ch] app/path_curves.[ch]
2003-02-12 Sven Neumann <sven@gimp.org> * app/Makefile.am * app/path_bezier.[ch] * app/path_curves.[ch] * app/tools/Makefile.am * app/tools/gimppathtool.[ch] * app/tools/path_tool.[ch]: removed the abandoned path tool prototype.
This commit is contained in:
parent
b0161a5089
commit
4858a3750b
10
ChangeLog
10
ChangeLog
|
@ -1,3 +1,13 @@
|
|||
2003-02-12 Sven Neumann <sven@gimp.org>
|
||||
|
||||
* app/Makefile.am
|
||||
* app/path_bezier.[ch]
|
||||
* app/path_curves.[ch]
|
||||
* app/tools/Makefile.am
|
||||
* app/tools/gimppathtool.[ch]
|
||||
* app/tools/path_tool.[ch]: removed the abandoned path tool
|
||||
prototype.
|
||||
|
||||
2003-02-12 Sven Neumann <sven@gimp.org>
|
||||
|
||||
* app/tools/Makefile.am
|
||||
|
|
|
@ -52,10 +52,6 @@ bye_sources = \
|
|||
path.h \
|
||||
pathP.h \
|
||||
path_transform.h \
|
||||
path_curves.h \
|
||||
path_curves.c \
|
||||
path_bezier.h \
|
||||
path_bezier.c \
|
||||
undo.c \
|
||||
undo.h \
|
||||
undo_types.h
|
||||
|
|
|
@ -1,277 +0,0 @@
|
|||
/* 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 <gtk/gtk.h>
|
||||
|
||||
#include "libgimpmath/gimpmath.h"
|
||||
|
||||
#include "core/core-types.h"
|
||||
#include "tools/tools-types.h"
|
||||
|
||||
#include "path_curves.h"
|
||||
#include "path_bezier.h"
|
||||
|
||||
|
||||
#define HANDLE_HALFWIDTH 3
|
||||
#define HANDLE_WIDTH 6
|
||||
|
||||
/*
|
||||
* This function is to get a set of npoints different coordinates for
|
||||
* the range from start to end (each in the range from 0 to 1 and
|
||||
* start < end.
|
||||
* returns the number of created coords. Make sure that the points-
|
||||
* Array is allocated.
|
||||
*/
|
||||
|
||||
guint
|
||||
path_bezier_get_points (PathSegment *segment,
|
||||
gfloat *points,
|
||||
guint npoints,
|
||||
gdouble start,
|
||||
gdouble end)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
void
|
||||
path_bezier_get_point (PathSegment *segment,
|
||||
gdouble pos,
|
||||
gdouble *x,
|
||||
gdouble *y)
|
||||
{
|
||||
PathBezierData *data = (PathBezierData *) segment->data;
|
||||
|
||||
if (segment->next) {
|
||||
|
||||
*x = (1-pos) * (1-pos) * (1-pos) * segment->x
|
||||
+ 3 * pos * (1-pos) * (1-pos) * (segment->x + data->x1)
|
||||
+ 3 * pos * pos * (1-pos) * (segment->next->x + data->x2)
|
||||
+ pos * pos * pos * (segment->next->x);
|
||||
|
||||
*y = (1-pos) * (1-pos) * (1-pos) * segment->y
|
||||
+ 3 * pos * (1-pos) * (1-pos) * (segment->y + data->y1)
|
||||
+ 3 * pos * pos * (1-pos) * (segment->next->y + data->y2)
|
||||
+ pos * pos * pos * (segment->next->y);
|
||||
}
|
||||
#ifdef PATH_TOOL_DEBUG
|
||||
else fprintf (stderr, "FIXME: path_bezier_get_point called with endpoint-segment!!!\n");
|
||||
#endif
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
void
|
||||
path_bezier_draw_handles (GimpDrawTool *tool,
|
||||
PathSegment *segment)
|
||||
{
|
||||
#if 0
|
||||
PathTool *path_tool = (PathTool *) (tool->private);
|
||||
PathBezierData *data = (PathBezierData *) segment->data;
|
||||
GimpDisplay * gdisp = tool->gdisp;
|
||||
|
||||
gint sx, sy, hx, hy;
|
||||
|
||||
if (segment->next) {
|
||||
if (segment->flags & SEGMENT_ACTIVE) {
|
||||
gdisplay_transform_coords (gdisp,
|
||||
(gint) (segment->x), (gint) (segment->y), &sx, &sy, FALSE);
|
||||
gdisplay_transform_coords (gdisp,
|
||||
(gint) (segment->x + data->x1),
|
||||
(gint) (segment->y + data->y1), &hx, &hy, FALSE);
|
||||
|
||||
gdk_draw_line (path_tool->core->win,
|
||||
path_tool->core->gc, hx, hy, sx, sy);
|
||||
|
||||
gdk_draw_rectangle (path_tool->core->win, path_tool->core->gc, 0,
|
||||
hx - HANDLE_HALFWIDTH, hy - HANDLE_HALFWIDTH,
|
||||
HANDLE_WIDTH, HANDLE_WIDTH);
|
||||
}
|
||||
|
||||
if (segment->next->flags & SEGMENT_ACTIVE) {
|
||||
gdisplay_transform_coords (gdisp,
|
||||
(gint) (segment->next->x), (gint) (segment->next->y), &sx, &sy, FALSE);
|
||||
gdisplay_transform_coords (gdisp,
|
||||
(gint) (segment->next->x + data->x2),
|
||||
(gint) (segment->next->y + data->y2), &hx, &hy, FALSE);
|
||||
|
||||
gdk_draw_line (path_tool->core->win,
|
||||
path_tool->core->gc, hx, hy, sx, sy);
|
||||
|
||||
gdk_draw_rectangle (path_tool->core->win, path_tool->core->gc, 0,
|
||||
hx - HANDLE_HALFWIDTH, hy - HANDLE_HALFWIDTH,
|
||||
HANDLE_WIDTH, HANDLE_WIDTH);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
void
|
||||
path_bezier_draw_segment (GimpDrawTool *tool,
|
||||
PathSegment *segment)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
gdouble
|
||||
path_bezier_on_segment (PathSegment *segment,
|
||||
gint x,
|
||||
gint y,
|
||||
gint halfwidth,
|
||||
gint *distance)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
|
||||
void
|
||||
path_bezier_drag_segment (PathSegment *segment,
|
||||
gdouble pos,
|
||||
gdouble dx,
|
||||
gdouble dy)
|
||||
{
|
||||
PathBezierData *data = (PathBezierData *) segment->data;
|
||||
gdouble feel_good;
|
||||
|
||||
if (pos <= 0.5)
|
||||
feel_good = (pow(2 * pos, 3)) / 2;
|
||||
else
|
||||
feel_good = (1 - pow((1-pos)*2, 3)) / 2 + 0.5;
|
||||
|
||||
data->x1 += (dx / (3*pos*(1-pos)*(1-pos)))*(1-feel_good);
|
||||
data->y1 += (dy / (3*pos*(1-pos)*(1-pos)))*(1-feel_good);
|
||||
data->x2 += (dx / (3*pos*pos*(1-pos)))*feel_good;
|
||||
data->y2 += (dy / (3*pos*pos*(1-pos)))*feel_good;
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
gint
|
||||
path_bezier_on_handles (PathSegment *segment,
|
||||
gdouble x,
|
||||
gdouble y,
|
||||
gdouble halfwidth)
|
||||
{
|
||||
PathBezierData *data = (PathBezierData *) segment->data;
|
||||
|
||||
if (segment->flags & SEGMENT_ACTIVE &&
|
||||
fabs(segment->x + data->x1 - x) <= halfwidth &&
|
||||
fabs(segment->y + data->y1 - y) <= halfwidth)
|
||||
return 1;
|
||||
|
||||
if (segment->next && segment->next->flags & SEGMENT_ACTIVE &&
|
||||
fabs(segment->next->x + data->x2 - x) <= halfwidth &&
|
||||
fabs(segment->next->y + data->y2 - y) <= halfwidth)
|
||||
return 2;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void
|
||||
path_bezier_drag_handles (PathSegment *segment,
|
||||
gdouble dx,
|
||||
gdouble dy,
|
||||
gint handle_id)
|
||||
{
|
||||
PathBezierData *data = (PathBezierData *) segment->data;
|
||||
|
||||
if (handle_id == 1) {
|
||||
data->x1 += dx;
|
||||
data->y1 += dy;
|
||||
} else {
|
||||
data->x2 += dx;
|
||||
data->y2 += dy;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
PathSegment *
|
||||
path_bezier_insert_anchor (PathSegment *segment,
|
||||
gdouble position)
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
|
||||
void
|
||||
path_bezier_update_segment (PathSegment *segment)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
path_bezier_flip_segment (PathSegment *segment)
|
||||
{
|
||||
PathBezierData *data = (PathBezierData *) segment->data;
|
||||
gdouble swap;
|
||||
|
||||
swap = data->x1;
|
||||
data->x1 = data->x2;
|
||||
data->x2 = swap;
|
||||
|
||||
swap = data->y1;
|
||||
data->y1 = data->y2;
|
||||
data->y2 = swap;
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
path_bezier_init_segment (PathSegment *segment)
|
||||
{
|
||||
PathBezierData *data, *neardata;
|
||||
|
||||
data = g_new(PathBezierData, 1);
|
||||
data->x1 = 0;
|
||||
data->y1 = 0;
|
||||
data->x2 = 0;
|
||||
data->y2 = 0;
|
||||
if (segment->prev && segment->prev->type == SEGMENT_BEZIER) {
|
||||
neardata = (PathBezierData *) segment->prev->data;
|
||||
data->x1 = - neardata->x2;
|
||||
data->y1 = - neardata->y2;
|
||||
}
|
||||
if (segment->next && segment->next->type == SEGMENT_BEZIER) {
|
||||
neardata = (PathBezierData *) segment->next->data;
|
||||
data->x2 = - neardata->x1;
|
||||
data->y2 = - neardata->y1;
|
||||
}
|
||||
|
||||
#ifdef PATH_TOOL_DEBUG
|
||||
if (segment->data)
|
||||
fprintf(stderr, "Warning: path_bezier_init_segment called with already initialized segment\n");
|
||||
#endif
|
||||
segment->data = data;
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
path_bezier_cleanup_segment (PathSegment *segment)
|
||||
{
|
||||
g_free(segment->data);
|
||||
segment->data = NULL;
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
|
|
@ -1,105 +0,0 @@
|
|||
/* 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.
|
||||
*/
|
||||
|
||||
/*
|
||||
* This function is to get a set of npoints different coordinates for
|
||||
* the range from start to end (each in the range from 0 to 1 and
|
||||
* start < end.
|
||||
* returns the number of created coords. Make sure that the points-
|
||||
* Array is allocated.
|
||||
*/
|
||||
|
||||
#ifndef __PATH_BEZIER_H__
|
||||
#define __PATH_BEZIER_H__
|
||||
|
||||
|
||||
typedef struct
|
||||
{
|
||||
gdouble x1;
|
||||
gdouble y1;
|
||||
gdouble x2;
|
||||
gdouble y2;
|
||||
} PathBezierData;
|
||||
|
||||
|
||||
guint
|
||||
path_bezier_get_points (PathSegment *segment,
|
||||
gfloat *points,
|
||||
guint npoints,
|
||||
gdouble start,
|
||||
gdouble end);
|
||||
|
||||
void
|
||||
path_bezier_get_point (PathSegment *segment,
|
||||
gdouble position,
|
||||
gdouble *x,
|
||||
gdouble *y);
|
||||
|
||||
void
|
||||
path_bezier_draw_handles (GimpDrawTool *tool,
|
||||
PathSegment *segment);
|
||||
|
||||
void
|
||||
path_bezier_draw_segment (GimpDrawTool *tool,
|
||||
PathSegment *segment);
|
||||
|
||||
gdouble
|
||||
path_bezier_on_segment (PathSegment *segment,
|
||||
gint x,
|
||||
gint y,
|
||||
gint halfwidth,
|
||||
gint *distance);
|
||||
|
||||
void
|
||||
path_bezier_drag_segment (PathSegment *segment,
|
||||
gdouble position,
|
||||
gdouble dx,
|
||||
gdouble dy);
|
||||
|
||||
gint
|
||||
path_bezier_on_handles (PathSegment *segment,
|
||||
gdouble x,
|
||||
gdouble y,
|
||||
gdouble halfwidth);
|
||||
|
||||
void
|
||||
path_bezier_drag_handles (PathSegment *segment,
|
||||
gdouble dx,
|
||||
gdouble dy,
|
||||
gint handle_id);
|
||||
|
||||
PathSegment *
|
||||
path_bezier_insert_anchor (PathSegment *segment,
|
||||
gdouble position);
|
||||
|
||||
void
|
||||
path_bezier_update_segment (PathSegment *segment);
|
||||
|
||||
void
|
||||
path_bezier_flip_segment (PathSegment *segment);
|
||||
|
||||
void
|
||||
path_bezier_init_segment (PathSegment *segment);
|
||||
|
||||
void
|
||||
path_bezier_cleanup_segment (PathSegment *segment);
|
||||
|
||||
#endif /* __PATH_BEZIER_H__ */
|
||||
|
||||
|
|
@ -1,321 +0,0 @@
|
|||
/* 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 <gtk/gtk.h>
|
||||
|
||||
#include "libgimpmath/gimpmath.h"
|
||||
|
||||
#include "core/core-types.h"
|
||||
#include "tools/tools-types.h"
|
||||
|
||||
#include "path_curves.h"
|
||||
#include "path_bezier.h"
|
||||
|
||||
#include "tools/gimpdrawtool.h"
|
||||
|
||||
|
||||
/* only here temporarily */
|
||||
PathSegment * path_split_segment (PathSegment *, gdouble);
|
||||
|
||||
/* Here the different curves register their functions */
|
||||
|
||||
static CurveDescription CurveTypes[] =
|
||||
{
|
||||
/* SEGMENT_LINE */
|
||||
{
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL
|
||||
},
|
||||
|
||||
/* SEGMENT_BEZIER */
|
||||
{
|
||||
NULL, /* path_bezier_get_points, */
|
||||
path_bezier_get_point,
|
||||
NULL, /* path_bezier_draw_handles, */
|
||||
NULL, /* path_bezier_draw_segment, */
|
||||
NULL, /* path_bezier_on_segment, */
|
||||
path_bezier_drag_segment,
|
||||
path_bezier_on_handles,
|
||||
path_bezier_drag_handles,
|
||||
NULL, /* path_bezier_insert_anchor, */
|
||||
NULL, /* path_bezier_update_segment, */
|
||||
path_bezier_flip_segment,
|
||||
path_bezier_init_segment,
|
||||
NULL /* path_bezier_cleanup_segment */
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
/*
|
||||
* these functions implement the dispatching for the different
|
||||
* curve-types. It implements default actions, which happen
|
||||
* to work with straight lines.
|
||||
*/
|
||||
|
||||
|
||||
guint
|
||||
path_curve_get_points (PathSegment *segment,
|
||||
gdouble *points,
|
||||
guint npoints,
|
||||
gdouble start,
|
||||
gdouble end)
|
||||
{
|
||||
gdouble pos;
|
||||
|
||||
gint index=0;
|
||||
|
||||
if (segment && segment->next) {
|
||||
if (CurveTypes[segment->type].get_points)
|
||||
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 (segment, pos, &points[index*2],
|
||||
&points[index*2+1]);
|
||||
index++;
|
||||
}
|
||||
return index;
|
||||
} else
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
#ifdef PATH_TOOL_DEBUG
|
||||
else
|
||||
fprintf (stderr, "path_curve_get_points called without valid curve");
|
||||
#endif
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
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) (segment, position, x, y);
|
||||
else {
|
||||
#if 1
|
||||
*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 with fixed tangents */
|
||||
|
||||
*x = (1-position)*(1-position)*(1-position) * segment->x +
|
||||
3 * position *(1-position)*(1-position) * (segment->x - 60) +
|
||||
3 * position * position *(1-position) * (segment->next->x + 60) +
|
||||
position * position * position * (segment->next->x);
|
||||
*y = (1-position)*(1-position)*(1-position) * segment->y +
|
||||
3 * position *(1-position)*(1-position) * (segment->y + 60) +
|
||||
3 * position * position *(1-position) * (segment->next->y + 60) +
|
||||
position * position * position * (segment->next->y);
|
||||
#endif
|
||||
}
|
||||
}
|
||||
#ifdef PATH_TOOL_DEBUG
|
||||
else
|
||||
fprintf (stderr, "path_curve_get_point called without valid curve");
|
||||
#endif
|
||||
return;
|
||||
}
|
||||
|
||||
void
|
||||
path_curve_draw_handles (GimpDrawTool *tool,
|
||||
PathSegment *segment)
|
||||
{
|
||||
if (segment && CurveTypes[segment->type].draw_handles)
|
||||
(* CurveTypes[segment->type].draw_handles) (tool, segment);
|
||||
|
||||
/* straight lines do not have handles... */
|
||||
return;
|
||||
}
|
||||
|
||||
void
|
||||
path_curve_draw_segment (GimpDrawTool *tool,
|
||||
PathSegment *segment)
|
||||
{
|
||||
gint num_pts;
|
||||
|
||||
if (segment && segment->next) {
|
||||
if (CurveTypes[segment->type].draw_segment) {
|
||||
(* CurveTypes[segment->type].draw_segment) (tool, segment);
|
||||
return;
|
||||
} else {
|
||||
gdouble *coordinates = g_new (gdouble, 200);
|
||||
num_pts = path_curve_get_points (segment, coordinates, 100, 0, 1);
|
||||
gimp_draw_tool_draw_lines (tool, coordinates, num_pts, FALSE, FALSE);
|
||||
g_free (coordinates);
|
||||
}
|
||||
|
||||
#ifdef PATH_TOOL_DEBUG
|
||||
} else {
|
||||
fprintf (stderr, "Fatal Error: path_curve_draw_segment called without valid segment *\n");
|
||||
#endif
|
||||
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
gdouble
|
||||
path_curve_on_segment (PathSegment *segment,
|
||||
gint x,
|
||||
gint y,
|
||||
gint halfwidth,
|
||||
gint *distance)
|
||||
{
|
||||
|
||||
if (segment && CurveTypes[segment->type].on_segment)
|
||||
return (* CurveTypes[segment->type].on_segment) (segment, x, y, halfwidth, distance);
|
||||
else {
|
||||
if (segment && segment->next) {
|
||||
#if 1
|
||||
gint x1, y1, numpts, index;
|
||||
gdouble *coordinates;
|
||||
gint bestindex = -1;
|
||||
|
||||
coordinates = g_new (gdouble, 200);
|
||||
*distance = halfwidth * halfwidth + 1;
|
||||
|
||||
numpts = path_curve_get_points (segment, coordinates, 100, 0, 1);
|
||||
for (index=0; index < numpts; index++) {
|
||||
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;
|
||||
}
|
||||
}
|
||||
g_free (coordinates);
|
||||
if (numpts == 1) {
|
||||
*distance = (gint) sqrt ((gdouble) *distance);
|
||||
return bestindex;
|
||||
}
|
||||
if (bestindex >= 0 && (*distance <= halfwidth * halfwidth)) {
|
||||
*distance = (gint) sqrt ((gdouble) *distance);
|
||||
return bestindex == 0 ? 0 : ((gdouble) bestindex) / (numpts - 1);
|
||||
}
|
||||
|
||||
#else
|
||||
|
||||
/* Special case for lines */
|
||||
gdouble Ax, Ay, Bx, By, r, d;
|
||||
Ax = segment->x;
|
||||
Ay = segment->y;
|
||||
Bx = segment->next->x;
|
||||
By = segment->next->y;
|
||||
|
||||
r = (( x - Ax)*(Bx - Ax) + ( y - Ay)* (By - Ay)) /
|
||||
((Bx - Ax)*(Bx - Ax) + (By - Ay)* (By - Ay)) ;
|
||||
|
||||
if (r >= 0 && r <= 1) {
|
||||
d = (((Ax + (Bx - Ax) * r) - x) * ((Ax + (Bx - Ax) * r) - x) +
|
||||
((Ay + (By - Ay) * r) - y) * ((Ay + (By - Ay) * r) - y));
|
||||
if (d <= halfwidth * halfwidth) {
|
||||
*distance = (gint) (d + 0.5);
|
||||
return r;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
void
|
||||
path_curve_drag_segment (PathSegment *segment,
|
||||
gdouble position,
|
||||
gdouble dx,
|
||||
gdouble dy)
|
||||
{
|
||||
if (segment && CurveTypes[segment->type].drag_segment)
|
||||
(* CurveTypes[segment->type].drag_segment) (segment, position, dx, dy);
|
||||
return;
|
||||
}
|
||||
|
||||
gint
|
||||
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) (segment, x, y, halfwidth);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
void
|
||||
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) (segment, dx, dy, handle_id);
|
||||
}
|
||||
|
||||
PathSegment *
|
||||
path_curve_insert_anchor (PathSegment *segment,
|
||||
gdouble position)
|
||||
{
|
||||
if (segment && CurveTypes[segment->type].insert_anchor)
|
||||
return (* CurveTypes[segment->type].insert_anchor) (segment, position);
|
||||
else {
|
||||
return path_split_segment (segment, position);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
path_curve_flip_segment (PathSegment *segment)
|
||||
{
|
||||
if (segment && CurveTypes[segment->type].flip_segment)
|
||||
(* CurveTypes[segment->type].flip_segment) (segment);
|
||||
return;
|
||||
}
|
||||
|
||||
void
|
||||
path_curve_update_segment (PathSegment *segment)
|
||||
{
|
||||
if (segment && CurveTypes[segment->type].update_segment)
|
||||
(* CurveTypes[segment->type].update_segment) (segment);
|
||||
return;
|
||||
}
|
||||
|
||||
void
|
||||
path_curve_init_segment (PathSegment *segment)
|
||||
{
|
||||
if (segment && CurveTypes[segment->type].init_segment)
|
||||
(* CurveTypes[segment->type].init_segment) (segment);
|
||||
return;
|
||||
}
|
||||
|
||||
void
|
||||
path_curve_cleanup_segment (PathSegment *segment)
|
||||
{
|
||||
if (segment && CurveTypes[segment->type].cleanup_segment)
|
||||
(* CurveTypes[segment->type].cleanup_segment) (segment);
|
||||
return;
|
||||
}
|
||||
|
|
@ -1,271 +0,0 @@
|
|||
/* 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 __PATH_CURVES_H__
|
||||
#define __PATH_CURVES_H__
|
||||
|
||||
#define 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);
|
||||
|
||||
|
||||
/*
|
||||
* This function is to get a set of npoints different coordinates for
|
||||
* the range from start to end (each in the range from 0 to 1 and
|
||||
* start < end).
|
||||
* returns the number of created coords. Make sure that the points-
|
||||
* Array is allocated.
|
||||
*/
|
||||
|
||||
typedef guint (*PathGetPointsFunc) (PathSegment *segment,
|
||||
gdouble *points,
|
||||
guint npoints,
|
||||
gdouble start,
|
||||
gdouble end);
|
||||
|
||||
typedef void (*PathGetPointFunc) (PathSegment *segment,
|
||||
gdouble position,
|
||||
gdouble *x,
|
||||
gdouble *y);
|
||||
|
||||
typedef void (*PathDrawHandlesFunc) (GimpDrawTool *tool,
|
||||
PathSegment *segment);
|
||||
|
||||
typedef void (*PathDrawSegmentFunc) (GimpDrawTool *tool,
|
||||
PathSegment *segment);
|
||||
|
||||
|
||||
typedef gdouble (*PathOnSegmentFunc) (PathSegment *segment,
|
||||
gint x,
|
||||
gint y,
|
||||
gint halfwidth,
|
||||
gint *distance);
|
||||
|
||||
typedef void (*PathDragSegmentFunc) (PathSegment *segment,
|
||||
gdouble position,
|
||||
gdouble dx,
|
||||
gdouble dy);
|
||||
|
||||
typedef gint (*PathOnHandlesFunc) (PathSegment *segment,
|
||||
gdouble x,
|
||||
gdouble y,
|
||||
gdouble halfwidth);
|
||||
|
||||
typedef void (*PathDragHandleFunc) (PathSegment *segment,
|
||||
gdouble dx,
|
||||
gdouble dy,
|
||||
gint handle_id);
|
||||
|
||||
typedef PathSegment * (*PathInsertAnchorFunc) (PathSegment *segment,
|
||||
gdouble position);
|
||||
|
||||
typedef void (*PathUpdateSegmentFunc) (PathSegment *segment);
|
||||
|
||||
typedef void (*PathFlipSegmentFunc) (PathSegment *segment);
|
||||
|
||||
typedef void (*PathInitSegmentFunc) (PathSegment *segment);
|
||||
|
||||
typedef void (*PathCleanupSegmentFunc) (PathSegment *segment);
|
||||
|
||||
typedef struct {
|
||||
PathGetPointsFunc get_points;
|
||||
PathGetPointFunc get_point;
|
||||
PathDrawHandlesFunc draw_handles;
|
||||
PathDrawSegmentFunc draw_segment;
|
||||
PathOnSegmentFunc on_segment;
|
||||
PathDragSegmentFunc drag_segment;
|
||||
PathOnHandlesFunc on_handles;
|
||||
PathDragHandleFunc drag_handle;
|
||||
PathInsertAnchorFunc insert_anchor;
|
||||
PathUpdateSegmentFunc update_segment;
|
||||
PathFlipSegmentFunc flip_segment;
|
||||
PathInitSegmentFunc init_segment;
|
||||
PathCleanupSegmentFunc cleanup_segment;
|
||||
} CurveDescription;
|
||||
|
||||
|
||||
guint
|
||||
path_curve_get_points (PathSegment *segment,
|
||||
gdouble *points,
|
||||
guint npoints,
|
||||
gdouble start,
|
||||
gdouble end);
|
||||
|
||||
void
|
||||
path_curve_get_point (PathSegment *segment,
|
||||
gdouble position,
|
||||
gdouble *x,
|
||||
gdouble *y);
|
||||
|
||||
void
|
||||
path_curve_draw_handles (GimpDrawTool *tool,
|
||||
PathSegment *segment);
|
||||
|
||||
void
|
||||
path_curve_draw_segment (GimpDrawTool *tool,
|
||||
PathSegment *segment);
|
||||
|
||||
|
||||
gdouble
|
||||
path_curve_on_segment (PathSegment *segment,
|
||||
gint x,
|
||||
gint y,
|
||||
gint halfwidth,
|
||||
gint *distance);
|
||||
|
||||
void
|
||||
path_curve_drag_segment (PathSegment *segment,
|
||||
gdouble position,
|
||||
gdouble dx,
|
||||
gdouble dy);
|
||||
|
||||
gint
|
||||
path_curve_on_handle (PathSegment *segment,
|
||||
gdouble x,
|
||||
gdouble y,
|
||||
gdouble halfwidth);
|
||||
|
||||
void
|
||||
path_curve_drag_handle (PathSegment *segment,
|
||||
gdouble dx,
|
||||
gdouble dy,
|
||||
gint handle_id);
|
||||
|
||||
PathSegment *
|
||||
path_curve_insert_anchor (PathSegment *segment,
|
||||
gdouble position);
|
||||
|
||||
void
|
||||
path_curve_update_segment (PathSegment *segment);
|
||||
|
||||
void
|
||||
path_curve_flip_segment (PathSegment *segment);
|
||||
|
||||
void
|
||||
path_curve_init_segment (PathSegment *segment);
|
||||
|
||||
void
|
||||
path_curve_cleanup_segment (PathSegment *segment);
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
/* This is, what Soleil (Olofs little daughter) has to say to this:
|
||||
|
||||
fc fc g hgvfvv drrrrrrtcc jctfcz w sdzs d bx cv^[ ^[c^[f c
|
||||
vffvcccccccccccccggfc fvx^[c^[x^[x^[x^[x^[x^[x^[ v xbvcbvcxv cxxc xxxx^[x
|
||||
xz^[c^[x^[x^[x^[x^[x^[x^[xxxxxxcccccccxxxxxxxxxxxxxxxvä"åp'
|
||||
hj^[[24~^[[4~^[[1~^[[4~^[[1~^[[4~ ^[[D^[[Bk^[[B,,,,,
|
||||
,^[[2~^[[4~^[[6~^[[4~l^[[6~,l' .holg^[[B^[[B n,,klmj ^[[B^[[1~j ^[[P^[[B
|
||||
^[[D^[[4~^[[6~nb ^[[A^[[C ^[[Akj^[[B ^[[A^[[C^[[A
|
||||
|
||||
|
||||
...^[[1~^[[D^[[4~^[[2~^[[C^[[B,^[[A^[[2~^[[C^[[2~^[[A^[[3~^[[A^[[4~ ^[[2~
|
||||
^[[2~pö- ., å^[[Aöpl., k,km ,
|
||||
m,^[[5~^[[6~^[[2~^[[C^[[3~p^[[A^[[Bö^[[2~^[[B^[[6~^[[1~, .^[[D^[[4~^[[2~^[[Db
|
||||
.l, .,.,m ^[[2~pöl. ik
|
||||
^[[20~kl9i^[[20~^[[20~^[[20~^[[21~^[[21~^[[21~^[[21~^[[21~^[[21~^[[20~m +
|
||||
^[[A^[[5~^[[G^[[D ^[[5~^[[1+^[[C
|
||||
|
||||
*/
|
||||
|
||||
#endif /* __PATH_CURVES_H__ */
|
||||
|
|
@ -88,8 +88,6 @@ libapptools_a_SOURCES = \
|
|||
gimppaintbrushtool.h \
|
||||
gimppainttool.c \
|
||||
gimppainttool.h \
|
||||
gimppathtool.c \
|
||||
gimppathtool.h \
|
||||
gimppenciltool.c \
|
||||
gimppenciltool.h \
|
||||
gimpperspectivetool.c \
|
||||
|
@ -134,9 +132,7 @@ libapptools_a_SOURCES = \
|
|||
tool_options.c \
|
||||
tool_options.h \
|
||||
tool_manager.c \
|
||||
tool_manager.h \
|
||||
path_tool.h \
|
||||
path_tool.c
|
||||
tool_manager.h
|
||||
|
||||
AM_CPPFLAGS = \
|
||||
-DG_LOG_DOMAIN=\"Gimp-Tools\" \
|
||||
|
|
|
@ -1,890 +0,0 @@
|
|||
/* 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 <gtk/gtk.h>
|
||||
|
||||
#include "libgimpmath/gimpmath.h"
|
||||
#include "libgimpwidgets/gimpwidgets.h"
|
||||
|
||||
#include "tools-types.h"
|
||||
|
||||
#include "core/gimpimage.h"
|
||||
|
||||
#include "display/gimpdisplay.h"
|
||||
#include "display/gimpdisplayshell.h"
|
||||
|
||||
#include "gimppathtool.h"
|
||||
#include "path_tool.h"
|
||||
|
||||
#include "path_curves.h"
|
||||
|
||||
#include "libgimp/gimpintl.h"
|
||||
|
||||
|
||||
/* 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_finalize (GObject *object);
|
||||
|
||||
static void gimp_path_tool_control (GimpTool *tool,
|
||||
GimpToolAction action,
|
||||
GimpDisplay *gdisp);
|
||||
|
||||
static void gimp_path_tool_button_press (GimpTool *tool,
|
||||
GimpCoords *coords,
|
||||
guint32 time,
|
||||
GdkModifierType state,
|
||||
GimpDisplay *gdisp);
|
||||
static gint gimp_path_tool_button_press_canvas (GimpPathTool *tool,
|
||||
guint32 time,
|
||||
GimpDisplay *gdisp);
|
||||
static gint gimp_path_tool_button_press_anchor (GimpPathTool *tool,
|
||||
guint32 time,
|
||||
GimpDisplay *gdisp);
|
||||
static gint gimp_path_tool_button_press_handle (GimpPathTool *tool,
|
||||
guint32 time,
|
||||
GimpDisplay *gdisp);
|
||||
static gint gimp_path_tool_button_press_curve (GimpPathTool *tool,
|
||||
guint32 time,
|
||||
GimpDisplay *gdisp);
|
||||
|
||||
static void gimp_path_tool_button_release (GimpTool *tool,
|
||||
GimpCoords *coords,
|
||||
guint32 time,
|
||||
GdkModifierType state,
|
||||
GimpDisplay *gdisp);
|
||||
|
||||
static void gimp_path_tool_motion (GimpTool *tool,
|
||||
GimpCoords *coords,
|
||||
guint32 time,
|
||||
GdkModifierType state,
|
||||
GimpDisplay *gdisp);
|
||||
static void gimp_path_tool_motion_anchor (GimpPathTool *path_tool,
|
||||
GimpCoords *coords,
|
||||
GdkModifierType state,
|
||||
GimpDisplay *gdisp);
|
||||
static void gimp_path_tool_motion_handle (GimpPathTool *path_tool,
|
||||
GimpCoords *coords,
|
||||
GdkModifierType state,
|
||||
GimpDisplay *gdisp);
|
||||
static void gimp_path_tool_motion_curve (GimpPathTool *path_tool,
|
||||
GimpCoords *coords,
|
||||
GdkModifierType state,
|
||||
GimpDisplay *gdisp);
|
||||
|
||||
static void gimp_path_tool_cursor_update (GimpTool *tool,
|
||||
GimpCoords *coords,
|
||||
GdkModifierType state,
|
||||
GimpDisplay *gdisp);
|
||||
|
||||
static void gimp_path_tool_draw (GimpDrawTool *draw_tool);
|
||||
|
||||
|
||||
|
||||
static GimpDrawToolClass *parent_class = NULL;
|
||||
|
||||
|
||||
void
|
||||
gimp_path_tool_register (GimpToolRegisterCallback callback,
|
||||
gpointer data)
|
||||
{
|
||||
(* callback) (GIMP_TYPE_PATH_TOOL,
|
||||
G_TYPE_NONE, NULL,
|
||||
FALSE,
|
||||
"gimp-path-tool",
|
||||
_("Path"),
|
||||
_("Path tool prototype"),
|
||||
N_("/Tools/Path"), NULL,
|
||||
NULL, "tools/path.html",
|
||||
GIMP_STOCK_TOOL_PATH,
|
||||
data);
|
||||
}
|
||||
|
||||
GType
|
||||
gimp_path_tool_get_type (void)
|
||||
{
|
||||
static GType tool_type = 0;
|
||||
|
||||
if (! tool_type)
|
||||
{
|
||||
static const GTypeInfo tool_info =
|
||||
{
|
||||
sizeof (GimpPathToolClass),
|
||||
(GBaseInitFunc) NULL,
|
||||
(GBaseFinalizeFunc) NULL,
|
||||
(GClassInitFunc) gimp_path_tool_class_init,
|
||||
NULL, /* class_finalize */
|
||||
NULL, /* class_data */
|
||||
sizeof (GimpPathTool),
|
||||
0, /* n_preallocs */
|
||||
(GInstanceInitFunc) gimp_path_tool_init,
|
||||
};
|
||||
|
||||
tool_type = g_type_register_static (GIMP_TYPE_DRAW_TOOL,
|
||||
"GimpPathTool",
|
||||
&tool_info, 0);
|
||||
}
|
||||
|
||||
return tool_type;
|
||||
}
|
||||
|
||||
static void
|
||||
gimp_path_tool_class_init (GimpPathToolClass *klass)
|
||||
{
|
||||
GObjectClass *object_class;
|
||||
GimpToolClass *tool_class;
|
||||
GimpDrawToolClass *draw_tool_class;
|
||||
|
||||
object_class = G_OBJECT_CLASS (klass);
|
||||
tool_class = GIMP_TOOL_CLASS (klass);
|
||||
draw_tool_class = GIMP_DRAW_TOOL_CLASS (klass);
|
||||
|
||||
parent_class = g_type_class_peek_parent (klass);
|
||||
|
||||
object_class->finalize = gimp_path_tool_finalize;
|
||||
|
||||
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);
|
||||
|
||||
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_finalize (GObject *object)
|
||||
{
|
||||
GimpPathTool *path_tool;
|
||||
|
||||
path_tool = GIMP_PATH_TOOL (object);
|
||||
|
||||
#ifdef PATH_TOOL_DEBUG
|
||||
g_printerr ("gimp_path_tool_free start\n");
|
||||
#endif
|
||||
|
||||
if (path_tool->cur_path)
|
||||
{
|
||||
path_free_path (path_tool->cur_path);
|
||||
path_tool->cur_path = NULL;
|
||||
}
|
||||
|
||||
G_OBJECT_CLASS (parent_class)->finalize (object);
|
||||
}
|
||||
|
||||
static void
|
||||
gimp_path_tool_control (GimpTool *tool,
|
||||
GimpToolAction action,
|
||||
GimpDisplay *gdisp)
|
||||
{
|
||||
GimpPathTool *path_tool;
|
||||
|
||||
#ifdef PATH_TOOL_DEBUG
|
||||
g_printerr ("path_tool_control\n");
|
||||
#endif
|
||||
|
||||
path_tool = GIMP_PATH_TOOL (tool);
|
||||
|
||||
switch (action)
|
||||
{
|
||||
case PAUSE:
|
||||
break;
|
||||
|
||||
case RESUME:
|
||||
break;
|
||||
|
||||
case HALT:
|
||||
gimp_tool_control_halt (tool->control);
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
GIMP_TOOL_CLASS (parent_class)->control (tool, action, gdisp);
|
||||
}
|
||||
|
||||
static void
|
||||
gimp_path_tool_button_press (GimpTool *tool,
|
||||
GimpCoords *coords,
|
||||
guint32 time,
|
||||
GdkModifierType state,
|
||||
GimpDisplay *gdisp)
|
||||
{
|
||||
GimpPathTool *path_tool;
|
||||
GimpDisplayShell *shell;
|
||||
gint grab_pointer = 0;
|
||||
gint halfwidth, halfheight;
|
||||
|
||||
path_tool = GIMP_PATH_TOOL (tool);
|
||||
|
||||
shell = GIMP_DISPLAY_SHELL (gdisp->shell);
|
||||
|
||||
#ifdef PATH_TOOL_DEBUG
|
||||
g_printerr ("path_tool_button_press\n");
|
||||
#endif
|
||||
|
||||
path_tool->click_x = coords->x;
|
||||
path_tool->click_y = coords->y;
|
||||
path_tool->click_modifier = state;
|
||||
|
||||
/* get halfwidth in image coord */
|
||||
halfwidth = UNSCALEX (shell, PATH_TOOL_HALFWIDTH);
|
||||
halfheight = UNSCALEY (shell, PATH_TOOL_HALFWIDTH);
|
||||
|
||||
path_tool->click_halfwidth = halfwidth;
|
||||
path_tool->click_halfheight = halfheight;
|
||||
|
||||
tool->gdisp = gdisp;
|
||||
gimp_tool_control_activate (tool->control);
|
||||
|
||||
if (! path_tool->cur_path->curves)
|
||||
gimp_draw_tool_start (GIMP_DRAW_TOOL (tool), gdisp);
|
||||
|
||||
/* determine point, where clicked,
|
||||
* switch accordingly.
|
||||
*/
|
||||
|
||||
path_tool->click_type =
|
||||
path_tool_cursor_position (path_tool->cur_path,
|
||||
coords->x,
|
||||
coords->y,
|
||||
halfwidth,
|
||||
halfheight,
|
||||
&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, time, gdisp);
|
||||
break;
|
||||
|
||||
case ON_ANCHOR:
|
||||
grab_pointer = gimp_path_tool_button_press_anchor (path_tool, time, gdisp);
|
||||
break;
|
||||
|
||||
case ON_HANDLE:
|
||||
grab_pointer = gimp_path_tool_button_press_handle (path_tool, time, gdisp);
|
||||
break;
|
||||
|
||||
case ON_CURVE:
|
||||
grab_pointer = gimp_path_tool_button_press_curve (path_tool, time, gdisp);
|
||||
break;
|
||||
|
||||
default:
|
||||
g_message ("Huh? Whats happening here? (button_press_*)");
|
||||
}
|
||||
}
|
||||
|
||||
static gint
|
||||
gimp_path_tool_button_press_anchor (GimpPathTool *path_tool,
|
||||
guint32 time,
|
||||
GimpDisplay *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
|
||||
g_printerr ("path_tool_button_press_anchor:\n");
|
||||
#endif
|
||||
|
||||
grab_pointer = 1;
|
||||
|
||||
if (!cur_path) {
|
||||
#ifdef PATH_TOOL_DEBUG
|
||||
g_printerr ("Fatal error: No current Path\n");
|
||||
#endif
|
||||
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 (time - last_click_time < 250) {
|
||||
doubleclick=TRUE;
|
||||
#ifdef PATH_TOOL_DEBUG
|
||||
g_printerr ("Doppelclick!\n");
|
||||
#endif
|
||||
} else
|
||||
doubleclick=FALSE;
|
||||
last_click_time = 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
|
||||
g_printerr ("p_sas: %p\n", p_sas);
|
||||
#endif
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
|
||||
static gint
|
||||
gimp_path_tool_button_press_handle (GimpPathTool *path_tool,
|
||||
guint32 time,
|
||||
GimpDisplay *gdisp)
|
||||
{
|
||||
static guint32 last_click_time=0;
|
||||
gboolean doubleclick=FALSE;
|
||||
|
||||
NPath * cur_path = path_tool->cur_path;
|
||||
gint grab_pointer;
|
||||
|
||||
#ifdef PATH_TOOL_DEBUG
|
||||
g_printerr ("path_tool_button_press_handle:\n");
|
||||
#endif
|
||||
|
||||
grab_pointer = 1;
|
||||
|
||||
if (!cur_path) {
|
||||
#ifdef PATH_TOOL_DEBUG
|
||||
g_printerr ("Fatal error: No current Path\n");
|
||||
#endif
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* gint click_halfwidth;
|
||||
|
||||
* 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 (time - last_click_time < 250) {
|
||||
doubleclick=TRUE;
|
||||
#ifdef PATH_TOOL_DEBUG
|
||||
g_printerr ("Doppelclick!\n");
|
||||
#endif
|
||||
} else
|
||||
doubleclick=FALSE;
|
||||
last_click_time = time;
|
||||
|
||||
return grab_pointer;
|
||||
}
|
||||
|
||||
static gint
|
||||
gimp_path_tool_button_press_canvas (GimpPathTool *path_tool,
|
||||
guint32 time,
|
||||
GimpDisplay *gdisp)
|
||||
{
|
||||
NPath * cur_path = path_tool->cur_path;
|
||||
PathCurve * cur_curve;
|
||||
PathSegment * cur_segment;
|
||||
gint grab_pointer;
|
||||
|
||||
#ifdef PATH_TOOL_DEBUG
|
||||
g_printerr ("path_tool_button_press_canvas:\n");
|
||||
#endif
|
||||
|
||||
grab_pointer = 1;
|
||||
|
||||
if (!cur_path) {
|
||||
#ifdef PATH_TOOL_DEBUG
|
||||
g_printerr ("Fatal error: No current Path\n");
|
||||
#endif
|
||||
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;
|
||||
}
|
||||
|
||||
static gint
|
||||
gimp_path_tool_button_press_curve (GimpPathTool *path_tool,
|
||||
guint32 time,
|
||||
GimpDisplay *gdisp)
|
||||
{
|
||||
NPath * cur_path = path_tool->cur_path;
|
||||
PathSegment * cur_segment;
|
||||
gint grab_pointer;
|
||||
|
||||
#ifdef PATH_TOOL_DEBUG
|
||||
g_printerr ("path_tool_button_press_curve:\n");
|
||||
#endif
|
||||
|
||||
grab_pointer = 1;
|
||||
|
||||
if (!cur_path) {
|
||||
#ifdef PATH_TOOL_DEBUG
|
||||
g_printerr ("Fatal error: No current NPath\n");
|
||||
#endif
|
||||
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,
|
||||
GimpCoords *coords,
|
||||
guint32 time,
|
||||
GdkModifierType state,
|
||||
GimpDisplay *gdisp)
|
||||
{
|
||||
GimpPathTool *path_tool;
|
||||
|
||||
path_tool = GIMP_PATH_TOOL (tool);
|
||||
|
||||
#ifdef PATH_TOOL_DEBUG
|
||||
g_printerr ("path_tool_button_release\n");
|
||||
#endif
|
||||
|
||||
path_tool->state &= ~PATH_TOOL_DRAG;
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
gimp_path_tool_motion (GimpTool *tool,
|
||||
GimpCoords *coords,
|
||||
guint32 time,
|
||||
GdkModifierType state,
|
||||
GimpDisplay *gdisp)
|
||||
{
|
||||
GimpPathTool *path_tool;
|
||||
|
||||
path_tool = GIMP_PATH_TOOL (tool);
|
||||
|
||||
switch (path_tool->click_type)
|
||||
{
|
||||
case ON_ANCHOR:
|
||||
gimp_path_tool_motion_anchor (path_tool, coords, state, gdisp);
|
||||
break;
|
||||
case ON_HANDLE:
|
||||
gimp_path_tool_motion_handle (path_tool, coords, state, gdisp);
|
||||
break;
|
||||
case ON_CURVE:
|
||||
gimp_path_tool_motion_curve (path_tool, coords, state, gdisp);
|
||||
break;
|
||||
default:
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
gimp_path_tool_motion_anchor (GimpPathTool *path_tool,
|
||||
GimpCoords *coords,
|
||||
GdkModifierType state,
|
||||
GimpDisplay *gdisp)
|
||||
{
|
||||
static gdouble dxsum = 0;
|
||||
static gdouble dysum = 0;
|
||||
|
||||
gdouble dx, dy, d;
|
||||
|
||||
/* 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;
|
||||
}
|
||||
|
||||
dx = coords->x - path_tool->click_x - dxsum;
|
||||
dy = coords->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 (state & GDK_MOD1_MASK)
|
||||
{
|
||||
if (state & GDK_CONTROL_MASK)
|
||||
{
|
||||
d = (fabs (dx) + fabs (dy)) / 2;
|
||||
d = (fabs (coords->x - path_tool->click_x) +
|
||||
fabs (coords->y - path_tool->click_y)) / 2;
|
||||
dx = ((coords->x < path_tool->click_x) ? -d : d ) - dxsum;
|
||||
dy = ((coords->y < path_tool->click_y) ? -d : d ) - dysum;
|
||||
}
|
||||
else
|
||||
{
|
||||
dx = - dxsum;
|
||||
}
|
||||
}
|
||||
else if (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;
|
||||
}
|
||||
|
||||
static void
|
||||
gimp_path_tool_motion_handle (GimpPathTool *path_tool,
|
||||
GimpCoords *coords,
|
||||
GdkModifierType state,
|
||||
GimpDisplay *gdisp)
|
||||
{
|
||||
static gdouble dxsum = 0;
|
||||
static gdouble dysum = 0;
|
||||
|
||||
gdouble dx, dy;
|
||||
|
||||
/* 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;
|
||||
}
|
||||
|
||||
dx = coords->x - path_tool->click_x - dxsum;
|
||||
dy = coords->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;
|
||||
}
|
||||
|
||||
static void
|
||||
gimp_path_tool_motion_curve (GimpPathTool *path_tool,
|
||||
GimpCoords *coords,
|
||||
GdkModifierType state,
|
||||
GimpDisplay *gdisp)
|
||||
{
|
||||
static gdouble dxsum = 0;
|
||||
static gdouble dysum = 0;
|
||||
|
||||
gdouble dx, dy;
|
||||
|
||||
if (! (path_tool->state & PATH_TOOL_DRAG))
|
||||
{
|
||||
path_tool->state |= PATH_TOOL_DRAG;
|
||||
dxsum = 0;
|
||||
dysum = 0;
|
||||
}
|
||||
|
||||
dx = coords->x - path_tool->click_x - dxsum;
|
||||
dy = coords->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,
|
||||
GimpCoords *coords,
|
||||
GdkModifierType state,
|
||||
GimpDisplay *gdisp)
|
||||
{
|
||||
GimpCursorModifier cmodifier = GIMP_CURSOR_MODIFIER_NONE;
|
||||
gint cursor_location;
|
||||
|
||||
cursor_location = path_tool_cursor_position (GIMP_PATH_TOOL (tool)->cur_path,
|
||||
coords->x,
|
||||
coords->y,
|
||||
PATH_TOOL_HALFWIDTH,
|
||||
PATH_TOOL_HALFWIDTH,
|
||||
NULL, NULL, NULL, NULL, NULL);
|
||||
|
||||
/* FIXME: add GIMP_PATH_TOOL_CURSOR */
|
||||
|
||||
switch (cursor_location)
|
||||
{
|
||||
case ON_CANVAS:
|
||||
cmodifier = GIMP_CURSOR_MODIFIER_PLUS;
|
||||
break;
|
||||
case ON_ANCHOR:
|
||||
cmodifier = GIMP_CURSOR_MODIFIER_MOVE;
|
||||
break;
|
||||
case ON_HANDLE:
|
||||
cmodifier = GIMP_CURSOR_MODIFIER_MOVE;
|
||||
break;
|
||||
case ON_CURVE:
|
||||
cmodifier = GIMP_CURSOR_MODIFIER_NONE;
|
||||
break;
|
||||
default:
|
||||
g_warning ("gimp_path_tool_cursor_update(): bad cursor_location");
|
||||
break;
|
||||
}
|
||||
|
||||
gimp_tool_control_set_cursor_modifier (tool->control, cmodifier);
|
||||
|
||||
GIMP_TOOL_CLASS (parent_class)->cursor_update (tool, coords, state, gdisp);
|
||||
}
|
||||
|
||||
|
||||
/* This is a CurveTraverseFunc */
|
||||
static void
|
||||
gimp_path_tool_draw_helper (NPath *path,
|
||||
PathCurve *curve,
|
||||
PathSegment *segment,
|
||||
gpointer tool)
|
||||
{
|
||||
GimpPathTool *path_tool;
|
||||
GimpDrawTool *draw_tool;
|
||||
gboolean draw = TRUE;
|
||||
|
||||
path_tool = GIMP_PATH_TOOL (tool);
|
||||
draw_tool = GIMP_DRAW_TOOL (tool);
|
||||
|
||||
if (path_tool->draw & PATH_TOOL_REDRAW_ACTIVE)
|
||||
draw = (segment->flags & SEGMENT_ACTIVE ||
|
||||
(segment->next && segment->next->flags & SEGMENT_ACTIVE));
|
||||
|
||||
if (segment->flags & SEGMENT_ACTIVE)
|
||||
{
|
||||
gimp_draw_tool_draw_handle (draw_tool,
|
||||
GIMP_HANDLE_CIRCLE,
|
||||
segment->x, segment->y,
|
||||
PATH_TOOL_WIDTH,
|
||||
PATH_TOOL_WIDTH,
|
||||
GTK_ANCHOR_CENTER,
|
||||
FALSE);
|
||||
}
|
||||
else
|
||||
{
|
||||
gimp_draw_tool_draw_handle (draw_tool,
|
||||
GIMP_HANDLE_FILLED_CIRCLE,
|
||||
segment->x, segment->y,
|
||||
PATH_TOOL_WIDTH,
|
||||
PATH_TOOL_WIDTH,
|
||||
GTK_ANCHOR_CENTER,
|
||||
FALSE);
|
||||
}
|
||||
|
||||
if (segment->next)
|
||||
path_curve_draw_segment (draw_tool, segment);
|
||||
}
|
||||
|
||||
static void
|
||||
gimp_path_tool_draw (GimpDrawTool *draw_tool)
|
||||
{
|
||||
GimpPathTool *path_tool;
|
||||
|
||||
path_tool = GIMP_PATH_TOOL (draw_tool);
|
||||
|
||||
path_traverse_path (path_tool->click_path, NULL, gimp_path_tool_draw_helper, NULL, draw_tool);
|
||||
}
|
||||
|
|
@ -1,80 +0,0 @@
|
|||
/* 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) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GIMP_TYPE_PATH_TOOL, GimpPathTool))
|
||||
#define GIMP_PATH_TOOL_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), GIMP_TYPE_PATH_TOOL, GimpPathToolClass))
|
||||
#define GIMP_IS_PATH_TOOL(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GIMP_TYPE_PATH_TOOL))
|
||||
#define GIMP_IS_PATH_TOOL_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), GIMP_TYPE_PATH_TOOL))
|
||||
#define GIMP_PATH_TOOL_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), GIMP_TYPE_PATH_TOOL, GimpPathToolClass))
|
||||
|
||||
|
||||
typedef struct _GimpPathToolClass GimpPathToolClass;
|
||||
|
||||
struct _GimpPathTool
|
||||
{
|
||||
GimpDrawTool parent_instance;
|
||||
|
||||
gint click_type; /* where did the user click? */
|
||||
gdouble click_x; /* X-coordinate of the click */
|
||||
gdouble click_y; /* Y-coordinate of the click */
|
||||
gint click_halfwidth;
|
||||
gint click_halfheight;
|
||||
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 (GimpToolRegisterCallback callback,
|
||||
gpointer data);
|
||||
|
||||
GType gimp_path_tool_get_type (void) G_GNUC_CONST;
|
||||
|
||||
|
||||
|
||||
#endif /* __GIMP_PATH_TOOL_H__ */
|
File diff suppressed because it is too large
Load Diff
|
@ -1,144 +0,0 @@
|
|||
/* 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 __PATH_TOOL_H__
|
||||
#define __PATH_TOOL_H__
|
||||
|
||||
/*
|
||||
* Every new curve-type has to have a parameter between 0 and 1, and
|
||||
* should go from a starting to a target point.
|
||||
*/
|
||||
|
||||
/* Some defines... */
|
||||
|
||||
#define PATH_TOOL_WIDTH 8
|
||||
#define PATH_TOOL_HALFWIDTH 4
|
||||
|
||||
/* function prototypes */
|
||||
|
||||
|
||||
/* 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 *,
|
||||
gdouble,
|
||||
gdouble);
|
||||
PathSegment * path_append_segment (NPath *,
|
||||
PathCurve *,
|
||||
SegmentType,
|
||||
gdouble,
|
||||
gdouble);
|
||||
PathSegment * path_prepend_segment (NPath *,
|
||||
PathCurve *,
|
||||
SegmentType,
|
||||
gdouble,
|
||||
gdouble);
|
||||
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 *path_tool,
|
||||
NPath *,
|
||||
PathCurve *,
|
||||
PathSegment *,
|
||||
guint32,
|
||||
guint32);
|
||||
|
||||
gdouble gimp_path_tool_on_curve (GimpPathTool *path_tool,
|
||||
gint,
|
||||
gint,
|
||||
gint,
|
||||
NPath**,
|
||||
PathCurve**,
|
||||
PathSegment**);
|
||||
gboolean gimp_path_tool_on_anchors (GimpPathTool *path_tool,
|
||||
gint,
|
||||
gint,
|
||||
gint,
|
||||
NPath**,
|
||||
PathCurve**,
|
||||
PathSegment**);
|
||||
gint gimp_path_tool_on_handles (GimpPathTool *path_tool,
|
||||
gint,
|
||||
gint,
|
||||
gint,
|
||||
NPath **,
|
||||
PathCurve **,
|
||||
PathSegment **);
|
||||
|
||||
gint path_tool_cursor_position (NPath *path,
|
||||
gdouble x,
|
||||
gdouble y,
|
||||
gint halfwidth,
|
||||
gint halfheight,
|
||||
NPath **pathP,
|
||||
PathCurve **curveP,
|
||||
PathSegment **segmentP,
|
||||
gdouble *positionP,
|
||||
gint *handle_idP);
|
||||
|
||||
|
||||
/* High level image-manipulation functions */
|
||||
|
||||
void path_stroke (GimpPathTool *path_tool,
|
||||
NPath *);
|
||||
void path_to_selection (GimpPathTool *path_tool,
|
||||
NPath *);
|
||||
|
||||
|
||||
#endif /* __PATH_TOOL_H__ */
|
||||
|
|
@ -62,7 +62,6 @@
|
|||
#include "gimpmeasuretool.h"
|
||||
#include "gimpmovetool.h"
|
||||
#include "gimppaintbrushtool.h"
|
||||
#include "gimppathtool.h"
|
||||
#include "gimppenciltool.h"
|
||||
#include "gimpperspectivetool.h"
|
||||
#include "gimpposterizetool.h"
|
||||
|
@ -126,7 +125,6 @@ tools_init (Gimp *gimp)
|
|||
|
||||
/* non-modifying tools */
|
||||
|
||||
gimp_path_tool_register,
|
||||
gimp_vector_tool_register,
|
||||
gimp_measure_tool_register,
|
||||
gimp_magnify_tool_register,
|
||||
|
|
Loading…
Reference in New Issue