mirror of https://github.com/GNOME/gimp.git
Some updates for the Path-Tool.
Bye, Simon (using Svens account)
This commit is contained in:
parent
7ccdba83bb
commit
2212b94fff
29
ChangeLog
29
ChangeLog
|
@ -1,3 +1,32 @@
|
||||||
|
1999-10-3 Simon Budig <Simon.Budig@unix-ag.org>
|
||||||
|
|
||||||
|
* app/path_tool.h
|
||||||
|
* app/path_tool.c
|
||||||
|
* app/path_toolP.h
|
||||||
|
* app/path_curves.h
|
||||||
|
* app/path_curves.c
|
||||||
|
* app/path_bezier.h
|
||||||
|
* app/path_bezer.c
|
||||||
|
|
||||||
|
Lots of stuff for the bezier-tool which will be also used for the
|
||||||
|
interface for the intelligent scissors. I started to factor out the
|
||||||
|
formulas for the actual curve type, so it is some kind of independant.
|
||||||
|
To try this out simply change the "#if 0" in app/path_curve.c to
|
||||||
|
a "#if 1" to handle straight lines instead of strange beziers with
|
||||||
|
fixed handles :-)
|
||||||
|
The functions in app/path_curves.c implement some kind of
|
||||||
|
default-action, where useful. To implement a new curve-tzpe it
|
||||||
|
should be sufficient to overload the path_curve_get_point()
|
||||||
|
function. Of course, then the speed is not as performant... :-)
|
||||||
|
|
||||||
|
The API for other types is not yet completely fixed, esp. Im not
|
||||||
|
clear about when to give a Tool* or PathTool* as a parameter.
|
||||||
|
But it shows the way, I want to implement this. In the next step
|
||||||
|
I'll fill the stubs in app/path_bezer.c.
|
||||||
|
|
||||||
|
New handling functions: The Tool detects, when you are over an curve
|
||||||
|
and lets you split it there by shift clicking.
|
||||||
|
|
||||||
1999-10-03 Sven Neumann <sven@gimp.org>
|
1999-10-03 Sven Neumann <sven@gimp.org>
|
||||||
|
|
||||||
* app/channel_ops.c: copy resolution and unit information when duplicating
|
* app/channel_ops.c: copy resolution and unit information when duplicating
|
||||||
|
|
|
@ -131,3 +131,7 @@ checkin: populate
|
||||||
|
|
||||||
release:
|
release:
|
||||||
$(MAKE) dist distdir=$(PACKAGE)`date +"%y%m%d"`
|
$(MAKE) dist distdir=$(PACKAGE)`date +"%y%m%d"`
|
||||||
|
path_bezier.c \
|
||||||
|
path_bezier.h \
|
||||||
|
path_curves.c \
|
||||||
|
path_curves.h \
|
||||||
|
|
|
@ -327,6 +327,10 @@ gimp_SOURCES = \
|
||||||
parasitelist.h \
|
parasitelist.h \
|
||||||
parasitelistF.h \
|
parasitelistF.h \
|
||||||
parasitelistP.h \
|
parasitelistP.h \
|
||||||
|
path_bezier.c \
|
||||||
|
path_bezier.h \
|
||||||
|
path_curves.c \
|
||||||
|
path_curves.h \
|
||||||
path_tool.c \
|
path_tool.c \
|
||||||
path_tool.h \
|
path_tool.h \
|
||||||
path_toolP.h \
|
path_toolP.h \
|
||||||
|
|
|
@ -0,0 +1,132 @@
|
||||||
|
/* 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 "path_bezier.h"
|
||||||
|
|
||||||
|
/*
|
||||||
|
* 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 (PathTool *path_tool,
|
||||||
|
PathSegment *segment,
|
||||||
|
GdkPoint *points,
|
||||||
|
guint npoints,
|
||||||
|
gdouble start,
|
||||||
|
gdouble end)
|
||||||
|
{
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
path_bezier_get_point (PathTool *path_tool,
|
||||||
|
PathSegment *segment,
|
||||||
|
gdouble position,
|
||||||
|
gdouble *x,
|
||||||
|
gdouble *y)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
path_bezier_draw_handles (Tool *tool,
|
||||||
|
PathSegment *segment)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
path_bezier_draw_segment (Tool *tool,
|
||||||
|
PathSegment *segment)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
gdouble
|
||||||
|
path_bezier_on_segment (Tool *tool,
|
||||||
|
PathSegment *segment,
|
||||||
|
gint x,
|
||||||
|
gint y,
|
||||||
|
gint halfwidth,
|
||||||
|
gint *distance)
|
||||||
|
{
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
path_bezier_drag_segment (PathTool *path_tool,
|
||||||
|
PathSegment *segment,
|
||||||
|
gdouble position,
|
||||||
|
gint x,
|
||||||
|
gint y)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
gboolean
|
||||||
|
path_bezier_on_handles (PathTool *path_tool,
|
||||||
|
PathSegment *segment,
|
||||||
|
gint x,
|
||||||
|
gint y,
|
||||||
|
gint halfwidth)
|
||||||
|
{
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
path_bezier_drag_handles (PathTool *path_tool,
|
||||||
|
PathSegment *segment,
|
||||||
|
gint x,
|
||||||
|
gint y)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
PathSegment *
|
||||||
|
path_bezier_insert_anchor (PathTool *path_tool,
|
||||||
|
PathSegment *segment,
|
||||||
|
gdouble position)
|
||||||
|
{
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
path_bezier_update_segment (PathTool *path_tool,
|
||||||
|
PathSegment *segment)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void
|
||||||
|
path_bezier_flip_segment (PathTool *path_tool,
|
||||||
|
PathSegment *segment)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,103 @@
|
||||||
|
/* 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__
|
||||||
|
|
||||||
|
#include <gdk/gdk.h>
|
||||||
|
#include <glib.h>
|
||||||
|
|
||||||
|
#include "path_toolP.h"
|
||||||
|
|
||||||
|
guint
|
||||||
|
path_bezier_get_points (PathTool *path_tool,
|
||||||
|
PathSegment *segment,
|
||||||
|
GdkPoint *points,
|
||||||
|
guint npoints,
|
||||||
|
gdouble start,
|
||||||
|
gdouble end);
|
||||||
|
|
||||||
|
void
|
||||||
|
path_bezier_get_point (PathTool *path_tool,
|
||||||
|
PathSegment *segment,
|
||||||
|
gdouble position,
|
||||||
|
gdouble *x,
|
||||||
|
gdouble *y);
|
||||||
|
|
||||||
|
void
|
||||||
|
path_bezier_draw_handles (Tool *tool,
|
||||||
|
PathSegment *segment);
|
||||||
|
|
||||||
|
void
|
||||||
|
path_bezier_draw_segment (Tool *tool,
|
||||||
|
PathSegment *segment);
|
||||||
|
|
||||||
|
|
||||||
|
gdouble
|
||||||
|
path_bezier_on_segment (Tool *tool,
|
||||||
|
PathSegment *segment,
|
||||||
|
gint x,
|
||||||
|
gint y,
|
||||||
|
gint halfwidth,
|
||||||
|
gint *distance);
|
||||||
|
|
||||||
|
void
|
||||||
|
path_bezier_drag_segment (PathTool *path_tool,
|
||||||
|
PathSegment *segment,
|
||||||
|
gdouble position,
|
||||||
|
gint x,
|
||||||
|
gint y);
|
||||||
|
|
||||||
|
gboolean
|
||||||
|
path_bezier_on_handles (PathTool *path_tool,
|
||||||
|
PathSegment *segment,
|
||||||
|
gint x,
|
||||||
|
gint y,
|
||||||
|
gint halfwidth);
|
||||||
|
|
||||||
|
void
|
||||||
|
path_bezier_drag_handles (PathTool *path_tool,
|
||||||
|
PathSegment *segment,
|
||||||
|
gint x,
|
||||||
|
gint y);
|
||||||
|
|
||||||
|
PathSegment *
|
||||||
|
path_bezier_insert_anchor (PathTool *path_tool,
|
||||||
|
PathSegment *segment,
|
||||||
|
gdouble position);
|
||||||
|
|
||||||
|
void
|
||||||
|
path_bezier_update_segment (PathTool *path_tool,
|
||||||
|
PathSegment *segment);
|
||||||
|
|
||||||
|
void
|
||||||
|
path_bezier_flip_segment (PathTool *path_tool,
|
||||||
|
PathSegment *segment);
|
||||||
|
|
||||||
|
#endif /* __PATH_BEZIER_H__ */
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,307 @@
|
||||||
|
/* 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 <math.h>
|
||||||
|
#include "path_curves.h"
|
||||||
|
#include "path_bezier.h"
|
||||||
|
|
||||||
|
#ifdef PATH_TOOL_DEBUG
|
||||||
|
#include <stdio.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* 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
|
||||||
|
},
|
||||||
|
|
||||||
|
/* SEGMENT_BEZIER */
|
||||||
|
{
|
||||||
|
path_bezier_get_points,
|
||||||
|
path_bezier_get_point,
|
||||||
|
path_bezier_draw_handles,
|
||||||
|
path_bezier_draw_segment,
|
||||||
|
path_bezier_on_segment,
|
||||||
|
path_bezier_drag_segment,
|
||||||
|
path_bezier_on_handles,
|
||||||
|
path_bezier_drag_handles,
|
||||||
|
path_bezier_insert_anchor,
|
||||||
|
path_bezier_update_segment,
|
||||||
|
path_bezier_flip_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 (PathTool *path_tool,
|
||||||
|
PathSegment *segment,
|
||||||
|
GdkPoint *points,
|
||||||
|
guint npoints,
|
||||||
|
gdouble start,
|
||||||
|
gdouble end)
|
||||||
|
{
|
||||||
|
gdouble pos, x, y;
|
||||||
|
gint index=0;
|
||||||
|
|
||||||
|
if (segment && CurveTypes[segment->type].get_points)
|
||||||
|
return (* CurveTypes[segment->type].get_points) (path_tool, 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);
|
||||||
|
index++;
|
||||||
|
}
|
||||||
|
return index;
|
||||||
|
} else
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void
|
||||||
|
path_curve_get_point (PathTool *path_tool,
|
||||||
|
PathSegment *segment,
|
||||||
|
gdouble position,
|
||||||
|
gdouble *x,
|
||||||
|
gdouble *y)
|
||||||
|
{
|
||||||
|
if (segment && CurveTypes[segment->type].get_point)
|
||||||
|
(* CurveTypes[segment->type].get_point) (path_tool, segment, position, x, y);
|
||||||
|
else {
|
||||||
|
if (segment && segment->next) {
|
||||||
|
#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 */
|
||||||
|
*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 (Tool *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 (Tool *tool,
|
||||||
|
PathSegment *segment)
|
||||||
|
{
|
||||||
|
gint x, y, numpts, index;
|
||||||
|
|
||||||
|
if (segment && segment->next) {
|
||||||
|
if (CurveTypes[segment->type].draw_segment) {
|
||||||
|
(* 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_ptr,
|
||||||
|
coordinates[index].x,
|
||||||
|
coordinates[index].y,
|
||||||
|
&x, &y, FALSE);
|
||||||
|
coordinates[index].x = x;
|
||||||
|
coordinates[index].y = y;
|
||||||
|
}
|
||||||
|
gdk_draw_lines (((PathTool *) tool->private)->core->win,
|
||||||
|
((PathTool *) tool->private)->core->gc,
|
||||||
|
coordinates, numpts);
|
||||||
|
g_free (coordinates);
|
||||||
|
}
|
||||||
|
|
||||||
|
#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 (Tool *tool,
|
||||||
|
PathSegment *segment,
|
||||||
|
gint x,
|
||||||
|
gint y,
|
||||||
|
gint halfwidth,
|
||||||
|
gint *distance)
|
||||||
|
{
|
||||||
|
|
||||||
|
if (segment && CurveTypes[segment->type].on_segment)
|
||||||
|
return (* CurveTypes[segment->type].on_segment) (tool, segment, x, y, halfwidth, distance);
|
||||||
|
else {
|
||||||
|
if (segment && segment->next) {
|
||||||
|
#if 1
|
||||||
|
gint x1, y1, numpts, index;
|
||||||
|
GdkPoint *coordinates = g_new (GdkPoint, 100);
|
||||||
|
gint bestindex = -1;
|
||||||
|
|
||||||
|
*distance = halfwidth * halfwidth + 1;
|
||||||
|
|
||||||
|
numpts = path_curve_get_points (((PathTool *) tool->private), segment,
|
||||||
|
coordinates, 100, 0, 1);
|
||||||
|
for (index=0; index < numpts; index++) {
|
||||||
|
x1 = coordinates[index].x;
|
||||||
|
y1 = coordinates[index].y;
|
||||||
|
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 (PathTool *path_tool,
|
||||||
|
PathSegment *segment,
|
||||||
|
gdouble position,
|
||||||
|
gint x,
|
||||||
|
gint y
|
||||||
|
)
|
||||||
|
{
|
||||||
|
if (segment && CurveTypes[segment->type].drag_segment)
|
||||||
|
(* CurveTypes[segment->type].drag_segment) (path_tool, segment, position, x, y);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
gboolean
|
||||||
|
path_curve_on_handle (PathTool *path_tool,
|
||||||
|
PathSegment *segment,
|
||||||
|
gint x,
|
||||||
|
gint y,
|
||||||
|
gint halfwidth)
|
||||||
|
{
|
||||||
|
if (segment && CurveTypes[segment->type].on_handles)
|
||||||
|
return (* CurveTypes[segment->type].on_handles) (path_tool, segment, x, y, halfwidth);
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
path_curve_drag_handle (PathTool *path_tool,
|
||||||
|
PathSegment *segment,
|
||||||
|
gint x,
|
||||||
|
gint y
|
||||||
|
)
|
||||||
|
{
|
||||||
|
if (segment && CurveTypes[segment->type].drag_handle)
|
||||||
|
(* CurveTypes[segment->type].drag_handle) (path_tool, segment, x, y);
|
||||||
|
}
|
||||||
|
|
||||||
|
PathSegment *
|
||||||
|
path_curve_insert_anchor (PathTool *path_tool,
|
||||||
|
PathSegment *segment,
|
||||||
|
gdouble position)
|
||||||
|
{
|
||||||
|
if (segment && CurveTypes[segment->type].insert_anchor)
|
||||||
|
return (* CurveTypes[segment->type].insert_anchor) (path_tool, segment, position);
|
||||||
|
else {
|
||||||
|
return path_split_segment (segment, position);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
path_curve_flip_segment (PathTool *path_tool,
|
||||||
|
PathSegment *segment)
|
||||||
|
{
|
||||||
|
if (segment && CurveTypes[segment->type].flip_segment)
|
||||||
|
(* CurveTypes[segment->type].flip_segment) (path_tool, segment);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
path_curve_update_segment (PathTool *path_tool,
|
||||||
|
PathSegment *segment)
|
||||||
|
{
|
||||||
|
if (segment && CurveTypes[segment->type].update_segment)
|
||||||
|
(* CurveTypes[segment->type].update_segment) (path_tool, segment);
|
||||||
|
return;
|
||||||
|
}
|
|
@ -0,0 +1,201 @@
|
||||||
|
/* 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__
|
||||||
|
|
||||||
|
#include <gdk/gdk.h>
|
||||||
|
#include "path_toolP.h"
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
* 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) (PathTool *path_tool,
|
||||||
|
PathSegment *segment,
|
||||||
|
GdkPoint *points,
|
||||||
|
guint npoints,
|
||||||
|
gdouble start,
|
||||||
|
gdouble end);
|
||||||
|
|
||||||
|
typedef void (*PathGetPointFunc) (PathTool *path_tool,
|
||||||
|
PathSegment *segment,
|
||||||
|
gdouble position,
|
||||||
|
gdouble *x,
|
||||||
|
gdouble *y);
|
||||||
|
|
||||||
|
typedef void (*PathDrawHandlesFunc) (Tool *tool,
|
||||||
|
PathSegment *segment);
|
||||||
|
|
||||||
|
typedef void (*PathDrawSegmentFunc) (Tool *tool,
|
||||||
|
PathSegment *segment);
|
||||||
|
|
||||||
|
|
||||||
|
typedef gdouble (*PathOnSegmentFunc) (Tool *tool,
|
||||||
|
PathSegment *segment,
|
||||||
|
gint x,
|
||||||
|
gint y,
|
||||||
|
gint halfwidth,
|
||||||
|
gint *distance);
|
||||||
|
|
||||||
|
typedef void (*PathDragSegmentFunc) (PathTool *path_tool,
|
||||||
|
PathSegment *segment,
|
||||||
|
gdouble position,
|
||||||
|
gint x,
|
||||||
|
gint y
|
||||||
|
);
|
||||||
|
|
||||||
|
typedef gboolean (*PathOnHandlesFunc) (PathTool *path_tool,
|
||||||
|
PathSegment *segment,
|
||||||
|
gint x,
|
||||||
|
gint y,
|
||||||
|
gint halfwidth);
|
||||||
|
|
||||||
|
typedef void (*PathDragHandleFunc) (PathTool *path_tool,
|
||||||
|
PathSegment *segment,
|
||||||
|
gint x,
|
||||||
|
gint y
|
||||||
|
);
|
||||||
|
|
||||||
|
typedef PathSegment * (*PathInsertAnchorFunc) (PathTool *path_tool,
|
||||||
|
PathSegment *segment,
|
||||||
|
gdouble position);
|
||||||
|
|
||||||
|
typedef void (*PathUpdateSegmentFunc) (PathTool *path_tool,
|
||||||
|
PathSegment *segment);
|
||||||
|
|
||||||
|
typedef void (*PathFlipSegmentFunc) (PathTool *path_tool,
|
||||||
|
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;
|
||||||
|
} CurveDescription;
|
||||||
|
|
||||||
|
|
||||||
|
guint
|
||||||
|
path_curve_get_points (PathTool *path_tool,
|
||||||
|
PathSegment *segment,
|
||||||
|
GdkPoint *points,
|
||||||
|
guint npoints,
|
||||||
|
gdouble start,
|
||||||
|
gdouble end);
|
||||||
|
|
||||||
|
void
|
||||||
|
path_curve_get_point (PathTool *path_tool,
|
||||||
|
PathSegment *segment,
|
||||||
|
gdouble position,
|
||||||
|
gdouble *x,
|
||||||
|
gdouble *y);
|
||||||
|
|
||||||
|
void
|
||||||
|
path_curve_draw_handles (Tool *tool,
|
||||||
|
PathSegment *segment);
|
||||||
|
|
||||||
|
void
|
||||||
|
path_curve_draw_segment (Tool *tool,
|
||||||
|
PathSegment *segment);
|
||||||
|
|
||||||
|
|
||||||
|
gdouble
|
||||||
|
path_curve_on_segment (Tool *tool,
|
||||||
|
PathSegment *segment,
|
||||||
|
gint x,
|
||||||
|
gint y,
|
||||||
|
gint halfwidth,
|
||||||
|
gint *distance);
|
||||||
|
|
||||||
|
void
|
||||||
|
path_curve_drag_segment (PathTool *path_tool,
|
||||||
|
PathSegment *segment,
|
||||||
|
gdouble position,
|
||||||
|
gint x,
|
||||||
|
gint y
|
||||||
|
);
|
||||||
|
|
||||||
|
gboolean
|
||||||
|
path_curve_on_handle (PathTool *path_tool,
|
||||||
|
PathSegment *segment,
|
||||||
|
gint x,
|
||||||
|
gint y,
|
||||||
|
gint halfwidth);
|
||||||
|
|
||||||
|
void
|
||||||
|
path_curve_drag_handle (PathTool *path_tool,
|
||||||
|
PathSegment *segment,
|
||||||
|
gint x,
|
||||||
|
gint y);
|
||||||
|
|
||||||
|
PathSegment *
|
||||||
|
path_curve_insert_anchor (PathTool *path_tool,
|
||||||
|
PathSegment *segment,
|
||||||
|
gdouble position);
|
||||||
|
|
||||||
|
void
|
||||||
|
path_curve_update_segment (PathTool *path_tool,
|
||||||
|
PathSegment *segment);
|
||||||
|
|
||||||
|
void
|
||||||
|
path_curve_flip_segment (PathTool *path_tool,
|
||||||
|
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__ */
|
||||||
|
|
363
app/path_tool.c
363
app/path_tool.c
|
@ -29,8 +29,6 @@
|
||||||
* segments between two anchors.
|
* segments between two anchors.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#undef PATH_TOOL_DEBUG
|
|
||||||
|
|
||||||
#include <math.h>
|
#include <math.h>
|
||||||
/* #include "appenv.h"
|
/* #include "appenv.h"
|
||||||
*/
|
*/
|
||||||
|
@ -39,6 +37,7 @@
|
||||||
#include "cursorutil.h"
|
#include "cursorutil.h"
|
||||||
#include "path_tool.h"
|
#include "path_tool.h"
|
||||||
#include "path_toolP.h"
|
#include "path_toolP.h"
|
||||||
|
#include "path_curves.h"
|
||||||
|
|
||||||
#ifdef PATH_TOOL_DEBUG
|
#ifdef PATH_TOOL_DEBUG
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
|
@ -63,51 +62,52 @@
|
||||||
|
|
||||||
/* Small functions to determine coordinates, iterate over path/curve/segment */
|
/* Small functions to determine coordinates, iterate over path/curve/segment */
|
||||||
|
|
||||||
static void path_segment_get_coordinates (PathSegment *, gdouble, gint *, gint *);
|
void path_segment_get_coordinates (PathSegment *, gdouble, gint *, gint *);
|
||||||
static void path_traverse_path (Path *, PathTraverseFunc, CurveTraverseFunc, SegmentTraverseFunc, gpointer);
|
void path_traverse_path (Path *, PathTraverseFunc, CurveTraverseFunc, SegmentTraverseFunc, gpointer);
|
||||||
static void path_traverse_curve (Path *, PathCurve *, CurveTraverseFunc, SegmentTraverseFunc, gpointer);
|
void path_traverse_curve (Path *, PathCurve *, CurveTraverseFunc, SegmentTraverseFunc, gpointer);
|
||||||
static void path_traverse_segment (Path *, PathCurve *, PathSegment *, SegmentTraverseFunc, gpointer);
|
void path_traverse_segment (Path *, PathCurve *, PathSegment *, SegmentTraverseFunc, gpointer);
|
||||||
static gdouble path_locate_point (Path *, PathCurve **, PathSegment **, gint, gint, gint, gint, gint);
|
gdouble path_locate_point (Path *, PathCurve **, PathSegment **, gint, gint, gint, gint, gint);
|
||||||
|
|
||||||
/* Tools to manipulate paths, curves, segments */
|
/* Tools to manipulate paths, curves, segments */
|
||||||
|
|
||||||
static PathCurve * path_add_curve (Path *, gint, gint);
|
PathCurve * path_add_curve (Path *, gint, gint);
|
||||||
static PathSegment * path_append_segment (Path *, PathCurve *, SegmentType, gint, gint);
|
PathSegment * path_append_segment (Path *, PathCurve *, SegmentType, gint, gint);
|
||||||
static PathSegment * path_prepend_segment (Path *, PathCurve *, SegmentType, gint, gint);
|
PathSegment * path_prepend_segment (Path *, PathCurve *, SegmentType, gint, gint);
|
||||||
static PathSegment * path_split_segment (PathSegment *, gdouble);
|
PathSegment * path_split_segment (PathSegment *, gdouble);
|
||||||
static void path_join_curves (PathSegment *, PathSegment *);
|
void path_join_curves (PathSegment *, PathSegment *);
|
||||||
static void path_flip_curve (PathCurve *);
|
void path_flip_curve (PathCurve *);
|
||||||
static void path_free_path (Path *);
|
void path_free_path (Path *);
|
||||||
static void path_free_curve (PathCurve *);
|
void path_free_curve (PathCurve *);
|
||||||
static void path_free_segment (PathSegment *);
|
void path_free_segment (PathSegment *);
|
||||||
static void path_delete_segment (PathSegment *);
|
void path_delete_segment (PathSegment *);
|
||||||
static void path_print (Path *);
|
void path_print (Path *);
|
||||||
static void path_offset_active (Path *, gdouble, gdouble);
|
void path_offset_active (Path *, gdouble, gdouble);
|
||||||
static void path_set_flags (PathTool *, Path *, PathCurve *, PathSegment *, guint32, guint32);
|
void path_set_flags (PathTool *, Path *, PathCurve *, PathSegment *, guint32, guint32);
|
||||||
|
|
||||||
/* High level image-manipulation functions */
|
/* High level image-manipulation functions */
|
||||||
|
|
||||||
static void path_stroke (PathTool *, Path *);
|
void path_stroke (PathTool *, Path *);
|
||||||
static void path_to_selection (PathTool *, Path *);
|
void path_to_selection (PathTool *, Path *);
|
||||||
|
|
||||||
/* Functions necessary for the tool */
|
/* Functions necessary for the tool */
|
||||||
|
|
||||||
static void path_tool_button_press (Tool *, GdkEventButton *, gpointer);
|
void path_tool_button_press (Tool *, GdkEventButton *, gpointer);
|
||||||
static void path_tool_button_release (Tool *, GdkEventButton *, gpointer);
|
void path_tool_button_release (Tool *, GdkEventButton *, gpointer);
|
||||||
static void path_tool_motion (Tool *, GdkEventMotion *, gpointer);
|
void path_tool_motion (Tool *, GdkEventMotion *, gpointer);
|
||||||
static void path_tool_cursor_update (Tool *, GdkEventMotion *, gpointer);
|
void path_tool_cursor_update (Tool *, GdkEventMotion *, gpointer);
|
||||||
static void path_tool_control (Tool *, ToolAction, gpointer);
|
void path_tool_control (Tool *, ToolAction, gpointer);
|
||||||
static void path_tool_draw (Tool *);
|
void path_tool_draw (Tool *);
|
||||||
static void path_tool_draw_curve (Tool *, PathCurve *);
|
void path_tool_draw_curve (Tool *, PathCurve *);
|
||||||
static void path_tool_draw_segment (Tool *, PathSegment *);
|
void path_tool_draw_segment (Tool *, PathSegment *);
|
||||||
static gboolean path_tool_on_anchors (Tool *, gint, gint, gint, Path**, PathCurve**, PathSegment**);
|
gboolean path_tool_on_anchors (Tool *, gint, gint, gint, Path**, PathCurve**, PathSegment**);
|
||||||
static gboolean path_tool_on_handles (Tool *, gint, gint, gint);
|
gdouble path_tool_on_curve (Tool *, gint, gint, gint, Path**, PathCurve**, PathSegment**);
|
||||||
static gboolean path_tool_on_curve (Tool *, gint, gint, gint);
|
gboolean path_tool_on_handles (Tool *, gint, gint, gint);
|
||||||
|
|
||||||
static gint path_tool_button_press_canvas (Tool *, GdkEventButton *, GDisplay *);
|
gint path_tool_button_press_canvas (Tool *, GdkEventButton *, GDisplay *);
|
||||||
static gint path_tool_button_press_anchor (Tool *, GdkEventButton *, GDisplay *);
|
gint path_tool_button_press_anchor (Tool *, GdkEventButton *, GDisplay *);
|
||||||
static void path_tool_motion_anchor (Tool *, GdkEventMotion *, GDisplay *);
|
gint path_tool_button_press_curve (Tool *, GdkEventButton *, GDisplay *);
|
||||||
static void path_tool_motion_curve (Tool *, GdkEventMotion *, GDisplay *);
|
void path_tool_motion_anchor (Tool *, GdkEventMotion *, GDisplay *);
|
||||||
|
void path_tool_motion_curve (Tool *, GdkEventMotion *, GDisplay *);
|
||||||
|
|
||||||
|
|
||||||
/* the path tool options */
|
/* the path tool options */
|
||||||
|
@ -138,7 +138,7 @@ static ToolOptions *path_options = NULL;
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
|
|
||||||
static void
|
void
|
||||||
path_traverse_path (Path *path, PathTraverseFunc pathfunc, CurveTraverseFunc curvefunc, SegmentTraverseFunc segmentfunc, gpointer data)
|
path_traverse_path (Path *path, PathTraverseFunc pathfunc, CurveTraverseFunc curvefunc, SegmentTraverseFunc segmentfunc, gpointer data)
|
||||||
{
|
{
|
||||||
PathCurve *cur_curve;
|
PathCurve *cur_curve;
|
||||||
|
@ -160,7 +160,7 @@ path_traverse_path (Path *path, PathTraverseFunc pathfunc, CurveTraverseFunc cur
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static void
|
void
|
||||||
path_traverse_curve (Path *path, PathCurve *curve, CurveTraverseFunc curvefunc, SegmentTraverseFunc segmentfunc, gpointer data)
|
path_traverse_curve (Path *path, PathCurve *curve, CurveTraverseFunc curvefunc, SegmentTraverseFunc segmentfunc, gpointer data)
|
||||||
{
|
{
|
||||||
PathSegment *cur_segment;
|
PathSegment *cur_segment;
|
||||||
|
@ -181,13 +181,15 @@ path_traverse_curve (Path *path, PathCurve *curve, CurveTraverseFunc curvefunc,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
void
|
||||||
path_traverse_segment (Path *path, PathCurve *curve, PathSegment *segment, SegmentTraverseFunc function, gpointer data)
|
path_traverse_segment (Path *path, PathCurve *curve, PathSegment *segment, SegmentTraverseFunc function, gpointer data)
|
||||||
{
|
{
|
||||||
#ifdef PATH_TOOL_DEBUG
|
#ifdef PATH_TOOL_DEBUG
|
||||||
fprintf(stderr, "path_traverse_segment\n");
|
fprintf(stderr, "path_traverse_segment\n");
|
||||||
#endif PATH_TOOL_DEBUG
|
#endif PATH_TOOL_DEBUG
|
||||||
|
|
||||||
|
#warning here we need path_curve_get_point(s)
|
||||||
|
|
||||||
/* Something like:
|
/* Something like:
|
||||||
* for i = 1 to subsamples {
|
* for i = 1 to subsamples {
|
||||||
* (x,y) = get_coordinates(i / subsamples)
|
* (x,y) = get_coordinates(i / subsamples)
|
||||||
|
@ -200,7 +202,7 @@ path_traverse_segment (Path *path, PathCurve *curve, PathSegment *segment, Segme
|
||||||
* Helper functions for manipulating the data-structures:
|
* Helper functions for manipulating the data-structures:
|
||||||
*/
|
*/
|
||||||
|
|
||||||
static PathCurve *path_add_curve (Path * cur_path, gint x, gint y)
|
PathCurve *path_add_curve (Path * cur_path, gint x, gint y)
|
||||||
{
|
{
|
||||||
PathCurve * tmp = cur_path->curves;
|
PathCurve * tmp = cur_path->curves;
|
||||||
PathCurve * new_curve = NULL;
|
PathCurve * new_curve = NULL;
|
||||||
|
@ -233,7 +235,7 @@ static PathCurve *path_add_curve (Path * cur_path, gint x, gint y)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static PathSegment * path_append_segment (Path * cur_path, PathCurve * cur_curve, SegmentType type, gint x, gint y)
|
PathSegment * path_append_segment (Path * cur_path, PathCurve * cur_curve, SegmentType type, gint x, gint y)
|
||||||
{
|
{
|
||||||
PathSegment * tmp = cur_curve->segments;
|
PathSegment * tmp = cur_curve->segments;
|
||||||
PathSegment * new_segment = NULL;
|
PathSegment * new_segment = NULL;
|
||||||
|
@ -264,6 +266,9 @@ static PathSegment * path_append_segment (Path * cur_path, PathCurve * cur_curv
|
||||||
tmp->next = new_segment;
|
tmp->next = new_segment;
|
||||||
|
|
||||||
cur_curve->cur_segment = new_segment;
|
cur_curve->cur_segment = new_segment;
|
||||||
|
|
||||||
|
#warning we need initialisation of the segment here.
|
||||||
|
|
||||||
}
|
}
|
||||||
#ifdef PATH_TOOL_DEBUG
|
#ifdef PATH_TOOL_DEBUG
|
||||||
else
|
else
|
||||||
|
@ -279,7 +284,7 @@ static PathSegment * path_append_segment (Path * cur_path, PathCurve * cur_curv
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static PathSegment * path_prepend_segment (Path * cur_path, PathCurve * cur_curve, SegmentType type, gint x, gint y)
|
PathSegment * path_prepend_segment (Path * cur_path, PathCurve * cur_curve, SegmentType type, gint x, gint y)
|
||||||
{
|
{
|
||||||
PathSegment * tmp = cur_curve->segments;
|
PathSegment * tmp = cur_curve->segments;
|
||||||
PathSegment * new_segment = NULL;
|
PathSegment * new_segment = NULL;
|
||||||
|
@ -308,6 +313,7 @@ static PathSegment * path_prepend_segment (Path * cur_path, PathCurve * cur_cur
|
||||||
|
|
||||||
cur_curve->segments = new_segment;
|
cur_curve->segments = new_segment;
|
||||||
cur_curve->cur_segment = new_segment;
|
cur_curve->cur_segment = new_segment;
|
||||||
|
#warning we need initialisation of the segment here.
|
||||||
}
|
}
|
||||||
#ifdef PATH_TOOL_DEBUG
|
#ifdef PATH_TOOL_DEBUG
|
||||||
else
|
else
|
||||||
|
@ -322,15 +328,47 @@ static PathSegment * path_prepend_segment (Path * cur_path, PathCurve * cur_cur
|
||||||
return new_segment;
|
return new_segment;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* static PathSegment * path_split_segment (PathSegment *, gdouble);
|
PathSegment * path_split_segment (PathSegment *segment, gdouble position)
|
||||||
*/
|
{
|
||||||
|
PathSegment * new_segment = NULL;
|
||||||
|
|
||||||
|
#ifdef PATH_TOOL_DEBUG
|
||||||
|
fprintf(stderr, "path_split_segment\n");
|
||||||
|
#endif PATH_TOOL_DEBUG
|
||||||
|
if (segment && segment->next) {
|
||||||
|
new_segment = g_new (PathSegment, 1);
|
||||||
|
|
||||||
|
new_segment->type = segment->type;
|
||||||
|
#warning Giving PathTool as NULL Pointer!
|
||||||
|
path_curve_get_point (NULL, segment, position, &(new_segment->x), &(new_segment->y));
|
||||||
|
new_segment->flags = 0;
|
||||||
|
new_segment->parent = segment->parent;
|
||||||
|
new_segment->next = segment->next;
|
||||||
|
new_segment->prev = segment;
|
||||||
|
new_segment->data = NULL;
|
||||||
|
|
||||||
|
#warning we need initialisation of the segment here.
|
||||||
|
|
||||||
|
new_segment->next->prev = new_segment;
|
||||||
|
segment->next = new_segment;
|
||||||
|
|
||||||
|
return new_segment;
|
||||||
|
|
||||||
|
}
|
||||||
|
#ifdef PATH_TOOL_DEBUG
|
||||||
|
else
|
||||||
|
fprintf(stderr, "path_split_segment without valid segment\n");
|
||||||
|
#endif PATH_TOOL_DEBUG
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Join two arbitrary endpoints and free the parent from the second
|
* Join two arbitrary endpoints and free the parent from the second
|
||||||
* segment, if it differs from the first parents.
|
* segment, if it differs from the first parents.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
static void
|
void
|
||||||
path_join_curves (PathSegment *segment1, PathSegment *segment2) {
|
path_join_curves (PathSegment *segment1, PathSegment *segment2) {
|
||||||
PathCurve *curve1, *curve2;
|
PathCurve *curve1, *curve2;
|
||||||
PathSegment *tmp;
|
PathSegment *tmp;
|
||||||
|
@ -352,6 +390,7 @@ path_join_curves (PathSegment *segment1, PathSegment *segment2) {
|
||||||
segment2->prev = segment1;
|
segment2->prev = segment1;
|
||||||
segment1->next = segment2;
|
segment1->next = segment2;
|
||||||
}
|
}
|
||||||
|
#warning Probably some segment-updates needed
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -403,6 +442,7 @@ path_join_curves (PathSegment *segment1, PathSegment *segment2) {
|
||||||
tmp->parent = curve1;
|
tmp->parent = curve1;
|
||||||
tmp = tmp->next;
|
tmp = tmp->next;
|
||||||
}
|
}
|
||||||
|
#warning Probably some segment-updates needed
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -433,10 +473,11 @@ path_join_curves (PathSegment *segment1, PathSegment *segment2) {
|
||||||
tmp = tmp->prev;
|
tmp = tmp->prev;
|
||||||
}
|
}
|
||||||
return;
|
return;
|
||||||
|
#warning Probably some segment-updates needed
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef PATH_TOOL_DEBUG
|
#ifdef PATH_TOOL_DEBUG
|
||||||
fprintf (stderr, "Cant join these curves yet...\n");
|
fprintf (stderr, "Cant join these curves yet...\nThis should not happen.");
|
||||||
return;
|
return;
|
||||||
#endif PATH_TOOL_DEBUG
|
#endif PATH_TOOL_DEBUG
|
||||||
|
|
||||||
|
@ -446,7 +487,7 @@ path_join_curves (PathSegment *segment1, PathSegment *segment2) {
|
||||||
* This function reverses the order of the anchors. This is
|
* This function reverses the order of the anchors. This is
|
||||||
* necessary for some joining operations.
|
* necessary for some joining operations.
|
||||||
*/
|
*/
|
||||||
static void
|
void
|
||||||
path_flip_curve (PathCurve *curve)
|
path_flip_curve (PathCurve *curve)
|
||||||
{
|
{
|
||||||
gpointer *end_data;
|
gpointer *end_data;
|
||||||
|
@ -454,6 +495,8 @@ path_flip_curve (PathCurve *curve)
|
||||||
|
|
||||||
PathSegment *tmp, *tmp2;
|
PathSegment *tmp, *tmp2;
|
||||||
|
|
||||||
|
#warning Please add path_curve_flip_segment here
|
||||||
|
|
||||||
if (!curve && !curve->segments) {
|
if (!curve && !curve->segments) {
|
||||||
#ifdef PATH_TOOL_DEBUG
|
#ifdef PATH_TOOL_DEBUG
|
||||||
fprintf (stderr, "path_flip_curve: No curve o no segments to flip!\n");
|
fprintf (stderr, "path_flip_curve: No curve o no segments to flip!\n");
|
||||||
|
@ -483,11 +526,12 @@ path_flip_curve (PathCurve *curve)
|
||||||
tmp->data = end_data;
|
tmp->data = end_data;
|
||||||
}
|
}
|
||||||
tmp = tmp->next;
|
tmp = tmp->next;
|
||||||
|
#warning Probably some segment-updates needed
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static void
|
void
|
||||||
path_free_path (Path * path)
|
path_free_path (Path * path)
|
||||||
{
|
{
|
||||||
PathCurve *tmp1, *tmp2;
|
PathCurve *tmp1, *tmp2;
|
||||||
|
@ -495,18 +539,18 @@ path_free_path (Path * path)
|
||||||
if (path)
|
if (path)
|
||||||
{
|
{
|
||||||
tmp2 = path->curves;
|
tmp2 = path->curves;
|
||||||
g_string_free(path->name, TRUE);
|
|
||||||
g_free(path);
|
|
||||||
|
|
||||||
while ((tmp1 = tmp2) != NULL)
|
while ((tmp1 = tmp2) != NULL)
|
||||||
{
|
{
|
||||||
tmp2 = tmp1->next;
|
tmp2 = tmp1->next;
|
||||||
path_free_curve (tmp1);
|
path_free_curve (tmp1);
|
||||||
}
|
}
|
||||||
|
g_string_free(path->name, TRUE);
|
||||||
|
g_free(path);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
void
|
||||||
path_free_curve (PathCurve *curve)
|
path_free_curve (PathCurve *curve)
|
||||||
{
|
{
|
||||||
PathSegment *tmp1, *tmp2;
|
PathSegment *tmp1, *tmp2;
|
||||||
|
@ -528,7 +572,7 @@ path_free_curve (PathCurve *curve)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
void
|
||||||
path_free_segment (PathSegment *segment)
|
path_free_segment (PathSegment *segment)
|
||||||
{
|
{
|
||||||
if (segment)
|
if (segment)
|
||||||
|
@ -538,11 +582,12 @@ path_free_segment (PathSegment *segment)
|
||||||
segment->parent, segment, 0, SEGMENT_ACTIVE);
|
segment->parent, segment, 0, SEGMENT_ACTIVE);
|
||||||
if (segment->data)
|
if (segment->data)
|
||||||
g_free(segment->data);
|
g_free(segment->data);
|
||||||
|
#warning Free Segment needs an own hook in the different curve-types!
|
||||||
g_free (segment);
|
g_free (segment);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
void
|
||||||
path_delete_curve (PathCurve *curve)
|
path_delete_curve (PathCurve *curve)
|
||||||
{
|
{
|
||||||
if (curve)
|
if (curve)
|
||||||
|
@ -560,7 +605,7 @@ path_delete_curve (PathCurve *curve)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
void
|
||||||
path_delete_segment (PathSegment *segment)
|
path_delete_segment (PathSegment *segment)
|
||||||
{
|
{
|
||||||
if (segment)
|
if (segment)
|
||||||
|
@ -587,6 +632,7 @@ path_delete_segment (PathSegment *segment)
|
||||||
/*
|
/*
|
||||||
* here we have to update the surrounding segments
|
* here we have to update the surrounding segments
|
||||||
*/
|
*/
|
||||||
|
#warning Please add path_curve_update_segment here
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -595,14 +641,21 @@ path_delete_segment (PathSegment *segment)
|
||||||
* A function to determine, which object is hit by the cursor
|
* A function to determine, which object is hit by the cursor
|
||||||
*/
|
*/
|
||||||
|
|
||||||
static gint
|
gint
|
||||||
path_tool_cursor_position (Tool *tool, gint x, gint y, gint halfwidth, Path **pathP, PathCurve **curveP, PathSegment **segmentP)
|
path_tool_cursor_position (Tool *tool, gint x, gint y, gint halfwidth, Path **pathP, PathCurve **curveP, PathSegment **segmentP, gdouble *positionP)
|
||||||
{
|
{
|
||||||
gint location;
|
gint location;
|
||||||
|
gdouble pos;
|
||||||
|
|
||||||
if (path_tool_on_anchors (tool, x, y, halfwidth, pathP, curveP, segmentP))
|
if (path_tool_on_anchors (tool, x, y, halfwidth, pathP, curveP, segmentP))
|
||||||
return ON_ANCHOR;
|
return ON_ANCHOR;
|
||||||
|
|
||||||
|
pos = path_tool_on_curve (tool, x, y, halfwidth, pathP, curveP, segmentP);
|
||||||
|
if (pos >= 0 && pos <= 1) {
|
||||||
|
if (positionP) (*positionP) = pos;
|
||||||
|
return ON_CURVE;
|
||||||
|
}
|
||||||
|
|
||||||
return ON_CANVAS;
|
return ON_CANVAS;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -611,7 +664,7 @@ path_tool_cursor_position (Tool *tool, gint x, gint y, gint halfwidth, Path **pa
|
||||||
* The click-callbacks for the tool
|
* The click-callbacks for the tool
|
||||||
*/
|
*/
|
||||||
|
|
||||||
static void
|
void
|
||||||
path_tool_button_press (Tool *tool,
|
path_tool_button_press (Tool *tool,
|
||||||
GdkEventButton *bevent,
|
GdkEventButton *bevent,
|
||||||
gpointer gdisp_ptr)
|
gpointer gdisp_ptr)
|
||||||
|
@ -649,12 +702,13 @@ path_tool_button_press (Tool *tool,
|
||||||
* switch accordingly.
|
* switch accordingly.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
path_tool->click_pos = path_tool_cursor_position(tool, x, y, halfwidth,
|
path_tool->click_type = path_tool_cursor_position(tool, x, y, halfwidth,
|
||||||
&(path_tool->click_path),
|
&(path_tool->click_path),
|
||||||
&(path_tool->click_curve),
|
&(path_tool->click_curve),
|
||||||
&(path_tool->click_segment));
|
&(path_tool->click_segment),
|
||||||
|
&(path_tool->click_position));
|
||||||
|
|
||||||
switch (path_tool->click_pos)
|
switch (path_tool->click_type)
|
||||||
{
|
{
|
||||||
case ON_CANVAS:
|
case ON_CANVAS:
|
||||||
grab_pointer = path_tool_button_press_canvas(tool, bevent, gdisp);
|
grab_pointer = path_tool_button_press_canvas(tool, bevent, gdisp);
|
||||||
|
@ -664,6 +718,10 @@ path_tool_button_press (Tool *tool,
|
||||||
grab_pointer = path_tool_button_press_anchor(tool, bevent, gdisp);
|
grab_pointer = path_tool_button_press_anchor(tool, bevent, gdisp);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case ON_CURVE:
|
||||||
|
grab_pointer = path_tool_button_press_curve(tool, bevent, gdisp);
|
||||||
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
g_message("Huh? Whats happening here? (button_press_*)");
|
g_message("Huh? Whats happening here? (button_press_*)");
|
||||||
}
|
}
|
||||||
|
@ -679,7 +737,7 @@ path_tool_button_press (Tool *tool,
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static gint
|
gint
|
||||||
path_tool_button_press_anchor (Tool *tool,
|
path_tool_button_press_anchor (Tool *tool,
|
||||||
GdkEventButton *bevent,
|
GdkEventButton *bevent,
|
||||||
GDisplay *gdisp)
|
GDisplay *gdisp)
|
||||||
|
@ -789,6 +847,7 @@ path_tool_button_press_anchor (Tool *tool,
|
||||||
|
|
||||||
path_delete_segment (path_tool->click_segment);
|
path_delete_segment (path_tool->click_segment);
|
||||||
path_tool->click_segment = NULL;
|
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))
|
else if (!(path_tool->click_segment->flags & SEGMENT_ACTIVE))
|
||||||
{
|
{
|
||||||
|
@ -797,14 +856,12 @@ path_tool_button_press_anchor (Tool *tool,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/* Action goes here */
|
|
||||||
|
|
||||||
draw_core_resume(path_tool->core, tool);
|
draw_core_resume(path_tool->core, tool);
|
||||||
|
|
||||||
return grab_pointer;
|
return grab_pointer;
|
||||||
}
|
}
|
||||||
|
|
||||||
static gint
|
gint
|
||||||
path_tool_button_press_canvas (Tool *tool,
|
path_tool_button_press_canvas (Tool *tool,
|
||||||
GdkEventButton *bevent,
|
GdkEventButton *bevent,
|
||||||
GDisplay *gdisp)
|
GDisplay *gdisp)
|
||||||
|
@ -857,7 +914,48 @@ path_tool_button_press_canvas (Tool *tool,
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
gint
|
||||||
|
path_tool_button_press_curve (Tool *tool,
|
||||||
|
GdkEventButton *bevent,
|
||||||
|
GDisplay *gdisp)
|
||||||
|
{
|
||||||
|
PathTool *path_tool = tool->private;
|
||||||
|
|
||||||
|
Path * 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_curve:\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;
|
||||||
|
}
|
||||||
|
|
||||||
|
draw_core_pause (path_tool->core, tool);
|
||||||
|
|
||||||
|
if (path_tool->click_modifier & GDK_SHIFT_MASK) {
|
||||||
|
cur_segment = path_curve_insert_anchor (path_tool, 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;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
draw_core_resume(path_tool->core, tool);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
path_tool_button_release (Tool *tool,
|
path_tool_button_release (Tool *tool,
|
||||||
GdkEventButton *bevent,
|
GdkEventButton *bevent,
|
||||||
gpointer gdisp_ptr)
|
gpointer gdisp_ptr)
|
||||||
|
@ -883,7 +981,7 @@ path_tool_button_release (Tool *tool,
|
||||||
* The motion-callbacks for the tool
|
* The motion-callbacks for the tool
|
||||||
*/
|
*/
|
||||||
|
|
||||||
static void
|
void
|
||||||
path_tool_motion (Tool *tool,
|
path_tool_motion (Tool *tool,
|
||||||
GdkEventMotion *mevent,
|
GdkEventMotion *mevent,
|
||||||
gpointer gdisp_ptr)
|
gpointer gdisp_ptr)
|
||||||
|
@ -896,7 +994,7 @@ path_tool_motion (Tool *tool,
|
||||||
gdisp = (GDisplay *) gdisp_ptr;
|
gdisp = (GDisplay *) gdisp_ptr;
|
||||||
path_tool = (PathTool *) tool->private;
|
path_tool = (PathTool *) tool->private;
|
||||||
|
|
||||||
switch (path_tool->click_pos) {
|
switch (path_tool->click_type) {
|
||||||
case ON_ANCHOR:
|
case ON_ANCHOR:
|
||||||
path_tool_motion_anchor(tool, mevent, gdisp);
|
path_tool_motion_anchor(tool, mevent, gdisp);
|
||||||
break;
|
break;
|
||||||
|
@ -906,7 +1004,7 @@ path_tool_motion (Tool *tool,
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
void
|
||||||
path_tool_motion_anchor (Tool *tool,
|
path_tool_motion_anchor (Tool *tool,
|
||||||
GdkEventMotion *mevent,
|
GdkEventMotion *mevent,
|
||||||
GDisplay *gdisp)
|
GDisplay *gdisp)
|
||||||
|
@ -977,7 +1075,7 @@ path_tool_motion_anchor (Tool *tool,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static void
|
void
|
||||||
path_tool_cursor_update (Tool *tool,
|
path_tool_cursor_update (Tool *tool,
|
||||||
GdkEventMotion *mevent,
|
GdkEventMotion *mevent,
|
||||||
gpointer gdisp_ptr)
|
gpointer gdisp_ptr)
|
||||||
|
@ -999,13 +1097,16 @@ path_tool_cursor_update (Tool *tool,
|
||||||
gdisplay_untransform_coords (gdisp, mevent->x + PATH_TOOL_HALFWIDTH, 0, &halfwidth, &dummy, TRUE, 0);
|
gdisplay_untransform_coords (gdisp, mevent->x + PATH_TOOL_HALFWIDTH, 0, &halfwidth, &dummy, TRUE, 0);
|
||||||
halfwidth -= x;
|
halfwidth -= x;
|
||||||
|
|
||||||
cursor_location = path_tool_cursor_position(tool, x, y, halfwidth, NULL, NULL, NULL);
|
cursor_location = path_tool_cursor_position(tool, x, y, halfwidth, NULL, NULL, NULL, NULL);
|
||||||
|
|
||||||
switch (cursor_location) {
|
switch (cursor_location) {
|
||||||
case ON_CANVAS:
|
case ON_CANVAS:
|
||||||
gdisplay_install_tool_cursor (gdisp, GIMP_MOUSE1AP_CURSOR);
|
gdisplay_install_tool_cursor (gdisp, GIMP_MOUSE1AP_CURSOR);
|
||||||
break;
|
break;
|
||||||
case ON_ANCHOR:
|
case ON_ANCHOR:
|
||||||
|
gdisplay_install_tool_cursor (gdisp, GDK_FLEUR);
|
||||||
|
break;
|
||||||
|
case ON_CURVE:
|
||||||
gdisplay_install_tool_cursor (gdisp, GDK_TCROSS);
|
gdisplay_install_tool_cursor (gdisp, GDK_TCROSS);
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
|
@ -1018,7 +1119,7 @@ path_tool_cursor_update (Tool *tool,
|
||||||
* Tool-control functions
|
* Tool-control functions
|
||||||
*/
|
*/
|
||||||
|
|
||||||
static void
|
void
|
||||||
path_tool_control (Tool *tool,
|
path_tool_control (Tool *tool,
|
||||||
ToolAction action,
|
ToolAction action,
|
||||||
gpointer gdisp_ptr)
|
gpointer gdisp_ptr)
|
||||||
|
@ -1044,6 +1145,9 @@ path_tool_control (Tool *tool,
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case HALT:
|
case HALT:
|
||||||
|
#ifdef PATH_TOOL_DEBUG
|
||||||
|
fprintf (stderr, "path_tool_control: HALT\n");
|
||||||
|
#endif PATH_TOOL_DEBUG
|
||||||
draw_core_stop (path_tool->core, tool);
|
draw_core_stop (path_tool->core, tool);
|
||||||
tool->state = INACTIVE;
|
tool->state = INACTIVE;
|
||||||
break;
|
break;
|
||||||
|
@ -1051,6 +1155,9 @@ path_tool_control (Tool *tool,
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
#ifdef PATH_TOOL_DEBUG
|
||||||
|
fprintf (stderr, "path_tool_control: end\n");
|
||||||
|
#endif PATH_TOOL_DEBUG
|
||||||
}
|
}
|
||||||
|
|
||||||
Tool *
|
Tool *
|
||||||
|
@ -1069,11 +1176,15 @@ tools_new_path_tool (void)
|
||||||
tool = tools_new_tool (PATH_TOOL);
|
tool = tools_new_tool (PATH_TOOL);
|
||||||
private = g_new (PathTool, 1);
|
private = g_new (PathTool, 1);
|
||||||
|
|
||||||
private->click_pos = ON_CANVAS;
|
private->click_type = ON_CANVAS;
|
||||||
private->click_x = 0;
|
private->click_x = 0;
|
||||||
private->click_y = 0;
|
private->click_y = 0;
|
||||||
private->click_halfwidth = 0;
|
private->click_halfwidth = 0;
|
||||||
private->click_modifier = 0;
|
private->click_modifier = 0;
|
||||||
|
private->click_path = NULL;
|
||||||
|
private->click_curve = NULL;
|
||||||
|
private->click_segment = NULL;
|
||||||
|
private->click_position = -1;
|
||||||
|
|
||||||
private->active_count = 0;
|
private->active_count = 0;
|
||||||
private->single_active_segment = NULL;
|
private->single_active_segment = NULL;
|
||||||
|
@ -1108,6 +1219,9 @@ tools_free_path_tool (Tool *tool)
|
||||||
GDisplay * gdisp;
|
GDisplay * gdisp;
|
||||||
PathTool * path_tool;
|
PathTool * path_tool;
|
||||||
|
|
||||||
|
#ifdef PATH_TOOL_DEBUG
|
||||||
|
fprintf (stderr, "tools_free_path_tool start\n");
|
||||||
|
#endif PATH_TOOL_DEBUG
|
||||||
path_tool = (PathTool *) tool->private;
|
path_tool = (PathTool *) tool->private;
|
||||||
gdisp = (GDisplay *) tool->gdisp_ptr;
|
gdisp = (GDisplay *) tool->gdisp_ptr;
|
||||||
|
|
||||||
|
@ -1121,9 +1235,84 @@ tools_free_path_tool (Tool *tool)
|
||||||
draw_core_free (path_tool->core);
|
draw_core_free (path_tool->core);
|
||||||
|
|
||||||
g_free (path_tool);
|
g_free (path_tool);
|
||||||
|
#ifdef PATH_TOOL_DEBUG
|
||||||
|
fprintf (stderr, "tools_free_path_tool end\n");
|
||||||
|
#endif PATH_TOOL_DEBUG
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**************************************************************
|
||||||
|
* Set of function to determine, if the click was on an segment
|
||||||
|
*/
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
Tool *tool;
|
||||||
|
Path *path;
|
||||||
|
PathCurve *curve;
|
||||||
|
PathSegment *segment;
|
||||||
|
gint testx;
|
||||||
|
gint testy;
|
||||||
|
gint halfwidth;
|
||||||
|
gint distance;
|
||||||
|
gdouble position;
|
||||||
|
gboolean found;
|
||||||
|
} Path_on_curve_type;
|
||||||
|
|
||||||
|
/* This is a CurveTraverseFunc */
|
||||||
|
void
|
||||||
|
path_tool_on_curve_helper (Path *path, PathCurve *curve, PathSegment *segment, gpointer ptr)
|
||||||
|
{
|
||||||
|
gint distance;
|
||||||
|
gdouble position;
|
||||||
|
Path_on_curve_type *data = (Path_on_curve_type *) ptr;
|
||||||
|
|
||||||
|
if (segment && segment->next && data && data->distance > 0)
|
||||||
|
{
|
||||||
|
position = path_curve_on_segment (data->tool, segment, data->testx, data->testy, data->halfwidth, &distance);
|
||||||
|
if (position >= 0 && distance < data->distance )
|
||||||
|
{
|
||||||
|
data->path = path;
|
||||||
|
data->curve = curve;
|
||||||
|
data->segment = segment;
|
||||||
|
data->distance = distance;
|
||||||
|
data->position = position;
|
||||||
|
data->found = TRUE;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
gdouble
|
||||||
|
path_tool_on_curve (Tool *tool, gint x, gint y, gint halfwidth, Path **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->segment = NULL;
|
||||||
|
data->testx = x;
|
||||||
|
data->testy = y;
|
||||||
|
data->halfwidth = halfwidth;
|
||||||
|
data->distance = halfwidth * halfwidth + 1;
|
||||||
|
data->position = -1;
|
||||||
|
data->found = FALSE;
|
||||||
|
|
||||||
|
path_traverse_path (((PathTool *) data->tool->private)->cur_path, NULL, path_tool_on_curve_helper, NULL, data);
|
||||||
|
|
||||||
|
if (ret_pathP) *ret_pathP = data->path;
|
||||||
|
if (ret_curveP) *ret_curveP = data->curve;
|
||||||
|
if (ret_segmentP) *ret_segmentP = data->segment;
|
||||||
|
|
||||||
|
position = data->position;
|
||||||
|
|
||||||
|
g_free(data);
|
||||||
|
|
||||||
|
return position;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
/**************************************************************
|
/**************************************************************
|
||||||
* Set of function to determine, if the click was on an anchor
|
* Set of function to determine, if the click was on an anchor
|
||||||
*/
|
*/
|
||||||
|
@ -1139,7 +1328,7 @@ typedef struct {
|
||||||
} Path_on_anchors_type;
|
} Path_on_anchors_type;
|
||||||
|
|
||||||
/* This is a CurveTraverseFunc */
|
/* This is a CurveTraverseFunc */
|
||||||
static void
|
void
|
||||||
path_tool_on_anchors_helper (Path *path, PathCurve *curve, PathSegment *segment, gpointer ptr)
|
path_tool_on_anchors_helper (Path *path, PathCurve *curve, PathSegment *segment, gpointer ptr)
|
||||||
{
|
{
|
||||||
gint distance;
|
gint distance;
|
||||||
|
@ -1161,7 +1350,7 @@ path_tool_on_anchors_helper (Path *path, PathCurve *curve, PathSegment *segment,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static gboolean
|
gboolean
|
||||||
path_tool_on_anchors (Tool *tool, gint x, gint y, gint halfwidth, Path **ret_pathP, PathCurve **ret_curveP, PathSegment **ret_segmentP)
|
path_tool_on_anchors (Tool *tool, gint x, gint y, gint halfwidth, Path **ret_pathP, PathCurve **ret_curveP, PathSegment **ret_segmentP)
|
||||||
{
|
{
|
||||||
Path_on_anchors_type *data = g_new (Path_on_anchors_type, 1);
|
Path_on_anchors_type *data = g_new (Path_on_anchors_type, 1);
|
||||||
|
@ -1200,7 +1389,7 @@ typedef struct {
|
||||||
} Path_offset_active_type;
|
} Path_offset_active_type;
|
||||||
|
|
||||||
/* This is a CurveTraverseFunc */
|
/* This is a CurveTraverseFunc */
|
||||||
static void
|
void
|
||||||
path_offset_active_helper (Path *path, PathCurve *curve, PathSegment *segment, gpointer ptr)
|
path_offset_active_helper (Path *path, PathCurve *curve, PathSegment *segment, gpointer ptr)
|
||||||
{
|
{
|
||||||
Path_offset_active_type *data = (Path_offset_active_type *) ptr;
|
Path_offset_active_type *data = (Path_offset_active_type *) ptr;
|
||||||
|
@ -1209,9 +1398,10 @@ path_offset_active_helper (Path *path, PathCurve *curve, PathSegment *segment, g
|
||||||
segment->x += data->dx;
|
segment->x += data->dx;
|
||||||
segment->y += data->dy;
|
segment->y += data->dy;
|
||||||
}
|
}
|
||||||
|
#warning Do a segment_update here!
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
void
|
||||||
path_offset_active (Path *path, gdouble dx, gdouble dy)
|
path_offset_active (Path *path, gdouble dx, gdouble dy)
|
||||||
{
|
{
|
||||||
Path_offset_active_type *data = g_new (Path_offset_active_type, 1);
|
Path_offset_active_type *data = g_new (Path_offset_active_type, 1);
|
||||||
|
@ -1226,7 +1416,7 @@ path_offset_active (Path *path, gdouble dx, gdouble dy)
|
||||||
|
|
||||||
|
|
||||||
/**************************************************************
|
/**************************************************************
|
||||||
* Set of function to set the state of all anchors to inactive
|
* Set of function to set the state of all anchors
|
||||||
*/
|
*/
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
|
@ -1236,7 +1426,7 @@ typedef struct {
|
||||||
} Path_set_flags_type;
|
} Path_set_flags_type;
|
||||||
|
|
||||||
/* This is a CurveTraverseFunc */
|
/* This is a CurveTraverseFunc */
|
||||||
static void
|
void
|
||||||
path_set_flags_helper (Path *path, PathCurve *curve, PathSegment *segment, gpointer ptr)
|
path_set_flags_helper (Path *path, PathCurve *curve, PathSegment *segment, gpointer ptr)
|
||||||
{
|
{
|
||||||
Path_set_flags_type *tmp = (Path_set_flags_type *) ptr;
|
Path_set_flags_type *tmp = (Path_set_flags_type *) ptr;
|
||||||
|
@ -1272,7 +1462,7 @@ path_set_flags_helper (Path *path, PathCurve *curve, PathSegment *segment, gpoin
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
void
|
||||||
path_set_flags (PathTool *path_tool, Path *path, PathCurve *curve, PathSegment *segment, guint32 bits_set, guint32 bits_clear)
|
path_set_flags (PathTool *path_tool, Path *path, PathCurve *curve, PathSegment *segment, guint32 bits_set, guint32 bits_clear)
|
||||||
{
|
{
|
||||||
Path_set_flags_type *tmp = g_new (Path_set_flags_type, 1);
|
Path_set_flags_type *tmp = g_new (Path_set_flags_type, 1);
|
||||||
|
@ -1296,7 +1486,7 @@ path_set_flags (PathTool *path_tool, Path *path, PathCurve *curve, PathSegment *
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/* This is a CurveTraverseFunc */
|
/* This is a CurveTraverseFunc */
|
||||||
static void
|
void
|
||||||
path_tool_draw_helper (Path *path, PathCurve *curve, PathSegment * segment, gpointer tool_ptr)
|
path_tool_draw_helper (Path *path, PathCurve *curve, PathSegment * segment, gpointer tool_ptr)
|
||||||
{
|
{
|
||||||
Tool * tool = (Tool *) tool_ptr;
|
Tool * tool = (Tool *) tool_ptr;
|
||||||
|
@ -1335,8 +1525,7 @@ path_tool_draw_helper (Path *path, PathCurve *curve, PathSegment * segment, gpoi
|
||||||
|
|
||||||
if (segment->next)
|
if (segment->next)
|
||||||
{
|
{
|
||||||
gdisplay_transform_coords (gdisp, (gint) segment->next->x, (gint) segment->next->y, &x2, &y2, FALSE);
|
path_curve_draw_segment (tool, segment);
|
||||||
gdk_draw_line (core->win, core->gc, x1, y1, x2, y2);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
#ifdef PATH_TOOL_DEBUG
|
#ifdef PATH_TOOL_DEBUG
|
||||||
|
@ -1345,7 +1534,7 @@ path_tool_draw_helper (Path *path, PathCurve *curve, PathSegment * segment, gpoi
|
||||||
#endif PATH_TOOL_DEBUG
|
#endif PATH_TOOL_DEBUG
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
void
|
||||||
path_tool_draw (Tool *tool)
|
path_tool_draw (Tool *tool)
|
||||||
{
|
{
|
||||||
GDisplay * gdisp;
|
GDisplay * gdisp;
|
||||||
|
@ -1363,4 +1552,10 @@ path_tool_draw (Tool *tool)
|
||||||
|
|
||||||
path_traverse_path (cur_path, NULL, path_tool_draw_helper, NULL, tool);
|
path_traverse_path (cur_path, NULL, path_tool_draw_helper, NULL, tool);
|
||||||
|
|
||||||
|
#ifdef PATH_TOOL_DEBUG
|
||||||
|
fprintf (stderr, "path_tool_draw end.\n");
|
||||||
|
#endif PATH_TOOL_DEBUG
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -1,5 +1,6 @@
|
||||||
/* The GIMP -- an image manipulation program
|
/* The GIMP -- an image manipulation program
|
||||||
* Copyright (C) 1995 Spencer Kimball and Peter Mattis
|
*
|
||||||
|
* This file Copyright (C) 1999 Simon Budig
|
||||||
*
|
*
|
||||||
* This program is free software; you can redistribute it and/or modify
|
* 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
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
@ -15,6 +16,7 @@
|
||||||
* along with this program; if not, write to the Free Software
|
* along with this program; if not, write to the Free Software
|
||||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#ifndef __PATH_TOOL_H__
|
#ifndef __PATH_TOOL_H__
|
||||||
#define __PATH_TOOL_H__
|
#define __PATH_TOOL_H__
|
||||||
|
|
||||||
|
|
|
@ -18,6 +18,9 @@
|
||||||
#ifndef __PATH_TOOLP_H__
|
#ifndef __PATH_TOOLP_H__
|
||||||
#define __PATH_TOOLP_H__
|
#define __PATH_TOOLP_H__
|
||||||
|
|
||||||
|
#undef PATH_TOOL_DEBUG
|
||||||
|
|
||||||
|
#include "draw_core.h"
|
||||||
|
|
||||||
#define IMAGE_COORDS 1
|
#define IMAGE_COORDS 1
|
||||||
#define AA_IMAGE_COORDS 2
|
#define AA_IMAGE_COORDS 2
|
||||||
|
@ -33,12 +36,10 @@
|
||||||
|
|
||||||
#define SUBDIVIDE 1000
|
#define SUBDIVIDE 1000
|
||||||
|
|
||||||
|
typedef enum { SEGMENT_LINE=0, SEGMENT_BEZIER} SegmentType;
|
||||||
|
|
||||||
enum { ON_ANCHOR, ON_HANDLE, ON_CURVE, ON_CANVAS };
|
enum { ON_ANCHOR, ON_HANDLE, ON_CURVE, ON_CANVAS };
|
||||||
|
|
||||||
typedef enum { SEGMENT_LINE, SEGMENT_BEZIER } SegmentType;
|
|
||||||
|
|
||||||
|
|
||||||
typedef struct _path_segment PathSegment;
|
typedef struct _path_segment PathSegment;
|
||||||
typedef struct _path_curve PathCurve;
|
typedef struct _path_curve PathCurve;
|
||||||
typedef struct _path Path;
|
typedef struct _path Path;
|
||||||
|
@ -82,7 +83,7 @@ struct _path
|
||||||
|
|
||||||
struct _path_tool
|
struct _path_tool
|
||||||
{
|
{
|
||||||
gint click_pos; /* where did the user click? */
|
gint click_type; /* where did the user click? */
|
||||||
gint click_x; /* X-coordinate of the click */
|
gint click_x; /* X-coordinate of the click */
|
||||||
gint click_y; /* Y-coordinate of the click */
|
gint click_y; /* Y-coordinate of the click */
|
||||||
gint click_halfwidth;
|
gint click_halfwidth;
|
||||||
|
@ -90,6 +91,7 @@ struct _path_tool
|
||||||
Path *click_path; /* On which Path/Curve/Segment */
|
Path *click_path; /* On which Path/Curve/Segment */
|
||||||
PathCurve *click_curve; /* was the click? */
|
PathCurve *click_curve; /* was the click? */
|
||||||
PathSegment *click_segment;
|
PathSegment *click_segment;
|
||||||
|
gdouble click_position; /* The position on the segment */
|
||||||
|
|
||||||
gint active_count; /* How many segments are active? */
|
gint active_count; /* How many segments are active? */
|
||||||
/*
|
/*
|
||||||
|
@ -110,6 +112,4 @@ typedef void (*PathTraverseFunc) (Path *, PathCurve *, gpointer);
|
||||||
typedef void (*CurveTraverseFunc) (Path *, PathCurve *, PathSegment *, gpointer);
|
typedef void (*CurveTraverseFunc) (Path *, PathCurve *, PathSegment *, gpointer);
|
||||||
typedef void (*SegmentTraverseFunc) (Path *, PathCurve *, PathSegment *, gint, gint, gpointer);
|
typedef void (*SegmentTraverseFunc) (Path *, PathCurve *, PathSegment *, gint, gint, gpointer);
|
||||||
|
|
||||||
/* typedef void (*SegmentTraverseFunc) (PathTool *, GdkPoint *, gint, gpointer);*/
|
|
||||||
|
|
||||||
#endif /* __PATH_TOOLP_H__ */
|
#endif /* __PATH_TOOLP_H__ */
|
||||||
|
|
|
@ -29,8 +29,6 @@
|
||||||
* segments between two anchors.
|
* segments between two anchors.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#undef PATH_TOOL_DEBUG
|
|
||||||
|
|
||||||
#include <math.h>
|
#include <math.h>
|
||||||
/* #include "appenv.h"
|
/* #include "appenv.h"
|
||||||
*/
|
*/
|
||||||
|
@ -39,6 +37,7 @@
|
||||||
#include "cursorutil.h"
|
#include "cursorutil.h"
|
||||||
#include "path_tool.h"
|
#include "path_tool.h"
|
||||||
#include "path_toolP.h"
|
#include "path_toolP.h"
|
||||||
|
#include "path_curves.h"
|
||||||
|
|
||||||
#ifdef PATH_TOOL_DEBUG
|
#ifdef PATH_TOOL_DEBUG
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
|
@ -63,51 +62,52 @@
|
||||||
|
|
||||||
/* Small functions to determine coordinates, iterate over path/curve/segment */
|
/* Small functions to determine coordinates, iterate over path/curve/segment */
|
||||||
|
|
||||||
static void path_segment_get_coordinates (PathSegment *, gdouble, gint *, gint *);
|
void path_segment_get_coordinates (PathSegment *, gdouble, gint *, gint *);
|
||||||
static void path_traverse_path (Path *, PathTraverseFunc, CurveTraverseFunc, SegmentTraverseFunc, gpointer);
|
void path_traverse_path (Path *, PathTraverseFunc, CurveTraverseFunc, SegmentTraverseFunc, gpointer);
|
||||||
static void path_traverse_curve (Path *, PathCurve *, CurveTraverseFunc, SegmentTraverseFunc, gpointer);
|
void path_traverse_curve (Path *, PathCurve *, CurveTraverseFunc, SegmentTraverseFunc, gpointer);
|
||||||
static void path_traverse_segment (Path *, PathCurve *, PathSegment *, SegmentTraverseFunc, gpointer);
|
void path_traverse_segment (Path *, PathCurve *, PathSegment *, SegmentTraverseFunc, gpointer);
|
||||||
static gdouble path_locate_point (Path *, PathCurve **, PathSegment **, gint, gint, gint, gint, gint);
|
gdouble path_locate_point (Path *, PathCurve **, PathSegment **, gint, gint, gint, gint, gint);
|
||||||
|
|
||||||
/* Tools to manipulate paths, curves, segments */
|
/* Tools to manipulate paths, curves, segments */
|
||||||
|
|
||||||
static PathCurve * path_add_curve (Path *, gint, gint);
|
PathCurve * path_add_curve (Path *, gint, gint);
|
||||||
static PathSegment * path_append_segment (Path *, PathCurve *, SegmentType, gint, gint);
|
PathSegment * path_append_segment (Path *, PathCurve *, SegmentType, gint, gint);
|
||||||
static PathSegment * path_prepend_segment (Path *, PathCurve *, SegmentType, gint, gint);
|
PathSegment * path_prepend_segment (Path *, PathCurve *, SegmentType, gint, gint);
|
||||||
static PathSegment * path_split_segment (PathSegment *, gdouble);
|
PathSegment * path_split_segment (PathSegment *, gdouble);
|
||||||
static void path_join_curves (PathSegment *, PathSegment *);
|
void path_join_curves (PathSegment *, PathSegment *);
|
||||||
static void path_flip_curve (PathCurve *);
|
void path_flip_curve (PathCurve *);
|
||||||
static void path_free_path (Path *);
|
void path_free_path (Path *);
|
||||||
static void path_free_curve (PathCurve *);
|
void path_free_curve (PathCurve *);
|
||||||
static void path_free_segment (PathSegment *);
|
void path_free_segment (PathSegment *);
|
||||||
static void path_delete_segment (PathSegment *);
|
void path_delete_segment (PathSegment *);
|
||||||
static void path_print (Path *);
|
void path_print (Path *);
|
||||||
static void path_offset_active (Path *, gdouble, gdouble);
|
void path_offset_active (Path *, gdouble, gdouble);
|
||||||
static void path_set_flags (PathTool *, Path *, PathCurve *, PathSegment *, guint32, guint32);
|
void path_set_flags (PathTool *, Path *, PathCurve *, PathSegment *, guint32, guint32);
|
||||||
|
|
||||||
/* High level image-manipulation functions */
|
/* High level image-manipulation functions */
|
||||||
|
|
||||||
static void path_stroke (PathTool *, Path *);
|
void path_stroke (PathTool *, Path *);
|
||||||
static void path_to_selection (PathTool *, Path *);
|
void path_to_selection (PathTool *, Path *);
|
||||||
|
|
||||||
/* Functions necessary for the tool */
|
/* Functions necessary for the tool */
|
||||||
|
|
||||||
static void path_tool_button_press (Tool *, GdkEventButton *, gpointer);
|
void path_tool_button_press (Tool *, GdkEventButton *, gpointer);
|
||||||
static void path_tool_button_release (Tool *, GdkEventButton *, gpointer);
|
void path_tool_button_release (Tool *, GdkEventButton *, gpointer);
|
||||||
static void path_tool_motion (Tool *, GdkEventMotion *, gpointer);
|
void path_tool_motion (Tool *, GdkEventMotion *, gpointer);
|
||||||
static void path_tool_cursor_update (Tool *, GdkEventMotion *, gpointer);
|
void path_tool_cursor_update (Tool *, GdkEventMotion *, gpointer);
|
||||||
static void path_tool_control (Tool *, ToolAction, gpointer);
|
void path_tool_control (Tool *, ToolAction, gpointer);
|
||||||
static void path_tool_draw (Tool *);
|
void path_tool_draw (Tool *);
|
||||||
static void path_tool_draw_curve (Tool *, PathCurve *);
|
void path_tool_draw_curve (Tool *, PathCurve *);
|
||||||
static void path_tool_draw_segment (Tool *, PathSegment *);
|
void path_tool_draw_segment (Tool *, PathSegment *);
|
||||||
static gboolean path_tool_on_anchors (Tool *, gint, gint, gint, Path**, PathCurve**, PathSegment**);
|
gboolean path_tool_on_anchors (Tool *, gint, gint, gint, Path**, PathCurve**, PathSegment**);
|
||||||
static gboolean path_tool_on_handles (Tool *, gint, gint, gint);
|
gdouble path_tool_on_curve (Tool *, gint, gint, gint, Path**, PathCurve**, PathSegment**);
|
||||||
static gboolean path_tool_on_curve (Tool *, gint, gint, gint);
|
gboolean path_tool_on_handles (Tool *, gint, gint, gint);
|
||||||
|
|
||||||
static gint path_tool_button_press_canvas (Tool *, GdkEventButton *, GDisplay *);
|
gint path_tool_button_press_canvas (Tool *, GdkEventButton *, GDisplay *);
|
||||||
static gint path_tool_button_press_anchor (Tool *, GdkEventButton *, GDisplay *);
|
gint path_tool_button_press_anchor (Tool *, GdkEventButton *, GDisplay *);
|
||||||
static void path_tool_motion_anchor (Tool *, GdkEventMotion *, GDisplay *);
|
gint path_tool_button_press_curve (Tool *, GdkEventButton *, GDisplay *);
|
||||||
static void path_tool_motion_curve (Tool *, GdkEventMotion *, GDisplay *);
|
void path_tool_motion_anchor (Tool *, GdkEventMotion *, GDisplay *);
|
||||||
|
void path_tool_motion_curve (Tool *, GdkEventMotion *, GDisplay *);
|
||||||
|
|
||||||
|
|
||||||
/* the path tool options */
|
/* the path tool options */
|
||||||
|
@ -138,7 +138,7 @@ static ToolOptions *path_options = NULL;
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
|
|
||||||
static void
|
void
|
||||||
path_traverse_path (Path *path, PathTraverseFunc pathfunc, CurveTraverseFunc curvefunc, SegmentTraverseFunc segmentfunc, gpointer data)
|
path_traverse_path (Path *path, PathTraverseFunc pathfunc, CurveTraverseFunc curvefunc, SegmentTraverseFunc segmentfunc, gpointer data)
|
||||||
{
|
{
|
||||||
PathCurve *cur_curve;
|
PathCurve *cur_curve;
|
||||||
|
@ -160,7 +160,7 @@ path_traverse_path (Path *path, PathTraverseFunc pathfunc, CurveTraverseFunc cur
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static void
|
void
|
||||||
path_traverse_curve (Path *path, PathCurve *curve, CurveTraverseFunc curvefunc, SegmentTraverseFunc segmentfunc, gpointer data)
|
path_traverse_curve (Path *path, PathCurve *curve, CurveTraverseFunc curvefunc, SegmentTraverseFunc segmentfunc, gpointer data)
|
||||||
{
|
{
|
||||||
PathSegment *cur_segment;
|
PathSegment *cur_segment;
|
||||||
|
@ -181,13 +181,15 @@ path_traverse_curve (Path *path, PathCurve *curve, CurveTraverseFunc curvefunc,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
void
|
||||||
path_traverse_segment (Path *path, PathCurve *curve, PathSegment *segment, SegmentTraverseFunc function, gpointer data)
|
path_traverse_segment (Path *path, PathCurve *curve, PathSegment *segment, SegmentTraverseFunc function, gpointer data)
|
||||||
{
|
{
|
||||||
#ifdef PATH_TOOL_DEBUG
|
#ifdef PATH_TOOL_DEBUG
|
||||||
fprintf(stderr, "path_traverse_segment\n");
|
fprintf(stderr, "path_traverse_segment\n");
|
||||||
#endif PATH_TOOL_DEBUG
|
#endif PATH_TOOL_DEBUG
|
||||||
|
|
||||||
|
#warning here we need path_curve_get_point(s)
|
||||||
|
|
||||||
/* Something like:
|
/* Something like:
|
||||||
* for i = 1 to subsamples {
|
* for i = 1 to subsamples {
|
||||||
* (x,y) = get_coordinates(i / subsamples)
|
* (x,y) = get_coordinates(i / subsamples)
|
||||||
|
@ -200,7 +202,7 @@ path_traverse_segment (Path *path, PathCurve *curve, PathSegment *segment, Segme
|
||||||
* Helper functions for manipulating the data-structures:
|
* Helper functions for manipulating the data-structures:
|
||||||
*/
|
*/
|
||||||
|
|
||||||
static PathCurve *path_add_curve (Path * cur_path, gint x, gint y)
|
PathCurve *path_add_curve (Path * cur_path, gint x, gint y)
|
||||||
{
|
{
|
||||||
PathCurve * tmp = cur_path->curves;
|
PathCurve * tmp = cur_path->curves;
|
||||||
PathCurve * new_curve = NULL;
|
PathCurve * new_curve = NULL;
|
||||||
|
@ -233,7 +235,7 @@ static PathCurve *path_add_curve (Path * cur_path, gint x, gint y)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static PathSegment * path_append_segment (Path * cur_path, PathCurve * cur_curve, SegmentType type, gint x, gint y)
|
PathSegment * path_append_segment (Path * cur_path, PathCurve * cur_curve, SegmentType type, gint x, gint y)
|
||||||
{
|
{
|
||||||
PathSegment * tmp = cur_curve->segments;
|
PathSegment * tmp = cur_curve->segments;
|
||||||
PathSegment * new_segment = NULL;
|
PathSegment * new_segment = NULL;
|
||||||
|
@ -264,6 +266,9 @@ static PathSegment * path_append_segment (Path * cur_path, PathCurve * cur_curv
|
||||||
tmp->next = new_segment;
|
tmp->next = new_segment;
|
||||||
|
|
||||||
cur_curve->cur_segment = new_segment;
|
cur_curve->cur_segment = new_segment;
|
||||||
|
|
||||||
|
#warning we need initialisation of the segment here.
|
||||||
|
|
||||||
}
|
}
|
||||||
#ifdef PATH_TOOL_DEBUG
|
#ifdef PATH_TOOL_DEBUG
|
||||||
else
|
else
|
||||||
|
@ -279,7 +284,7 @@ static PathSegment * path_append_segment (Path * cur_path, PathCurve * cur_curv
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static PathSegment * path_prepend_segment (Path * cur_path, PathCurve * cur_curve, SegmentType type, gint x, gint y)
|
PathSegment * path_prepend_segment (Path * cur_path, PathCurve * cur_curve, SegmentType type, gint x, gint y)
|
||||||
{
|
{
|
||||||
PathSegment * tmp = cur_curve->segments;
|
PathSegment * tmp = cur_curve->segments;
|
||||||
PathSegment * new_segment = NULL;
|
PathSegment * new_segment = NULL;
|
||||||
|
@ -308,6 +313,7 @@ static PathSegment * path_prepend_segment (Path * cur_path, PathCurve * cur_cur
|
||||||
|
|
||||||
cur_curve->segments = new_segment;
|
cur_curve->segments = new_segment;
|
||||||
cur_curve->cur_segment = new_segment;
|
cur_curve->cur_segment = new_segment;
|
||||||
|
#warning we need initialisation of the segment here.
|
||||||
}
|
}
|
||||||
#ifdef PATH_TOOL_DEBUG
|
#ifdef PATH_TOOL_DEBUG
|
||||||
else
|
else
|
||||||
|
@ -322,15 +328,47 @@ static PathSegment * path_prepend_segment (Path * cur_path, PathCurve * cur_cur
|
||||||
return new_segment;
|
return new_segment;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* static PathSegment * path_split_segment (PathSegment *, gdouble);
|
PathSegment * path_split_segment (PathSegment *segment, gdouble position)
|
||||||
*/
|
{
|
||||||
|
PathSegment * new_segment = NULL;
|
||||||
|
|
||||||
|
#ifdef PATH_TOOL_DEBUG
|
||||||
|
fprintf(stderr, "path_split_segment\n");
|
||||||
|
#endif PATH_TOOL_DEBUG
|
||||||
|
if (segment && segment->next) {
|
||||||
|
new_segment = g_new (PathSegment, 1);
|
||||||
|
|
||||||
|
new_segment->type = segment->type;
|
||||||
|
#warning Giving PathTool as NULL Pointer!
|
||||||
|
path_curve_get_point (NULL, segment, position, &(new_segment->x), &(new_segment->y));
|
||||||
|
new_segment->flags = 0;
|
||||||
|
new_segment->parent = segment->parent;
|
||||||
|
new_segment->next = segment->next;
|
||||||
|
new_segment->prev = segment;
|
||||||
|
new_segment->data = NULL;
|
||||||
|
|
||||||
|
#warning we need initialisation of the segment here.
|
||||||
|
|
||||||
|
new_segment->next->prev = new_segment;
|
||||||
|
segment->next = new_segment;
|
||||||
|
|
||||||
|
return new_segment;
|
||||||
|
|
||||||
|
}
|
||||||
|
#ifdef PATH_TOOL_DEBUG
|
||||||
|
else
|
||||||
|
fprintf(stderr, "path_split_segment without valid segment\n");
|
||||||
|
#endif PATH_TOOL_DEBUG
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Join two arbitrary endpoints and free the parent from the second
|
* Join two arbitrary endpoints and free the parent from the second
|
||||||
* segment, if it differs from the first parents.
|
* segment, if it differs from the first parents.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
static void
|
void
|
||||||
path_join_curves (PathSegment *segment1, PathSegment *segment2) {
|
path_join_curves (PathSegment *segment1, PathSegment *segment2) {
|
||||||
PathCurve *curve1, *curve2;
|
PathCurve *curve1, *curve2;
|
||||||
PathSegment *tmp;
|
PathSegment *tmp;
|
||||||
|
@ -352,6 +390,7 @@ path_join_curves (PathSegment *segment1, PathSegment *segment2) {
|
||||||
segment2->prev = segment1;
|
segment2->prev = segment1;
|
||||||
segment1->next = segment2;
|
segment1->next = segment2;
|
||||||
}
|
}
|
||||||
|
#warning Probably some segment-updates needed
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -403,6 +442,7 @@ path_join_curves (PathSegment *segment1, PathSegment *segment2) {
|
||||||
tmp->parent = curve1;
|
tmp->parent = curve1;
|
||||||
tmp = tmp->next;
|
tmp = tmp->next;
|
||||||
}
|
}
|
||||||
|
#warning Probably some segment-updates needed
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -433,10 +473,11 @@ path_join_curves (PathSegment *segment1, PathSegment *segment2) {
|
||||||
tmp = tmp->prev;
|
tmp = tmp->prev;
|
||||||
}
|
}
|
||||||
return;
|
return;
|
||||||
|
#warning Probably some segment-updates needed
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef PATH_TOOL_DEBUG
|
#ifdef PATH_TOOL_DEBUG
|
||||||
fprintf (stderr, "Cant join these curves yet...\n");
|
fprintf (stderr, "Cant join these curves yet...\nThis should not happen.");
|
||||||
return;
|
return;
|
||||||
#endif PATH_TOOL_DEBUG
|
#endif PATH_TOOL_DEBUG
|
||||||
|
|
||||||
|
@ -446,7 +487,7 @@ path_join_curves (PathSegment *segment1, PathSegment *segment2) {
|
||||||
* This function reverses the order of the anchors. This is
|
* This function reverses the order of the anchors. This is
|
||||||
* necessary for some joining operations.
|
* necessary for some joining operations.
|
||||||
*/
|
*/
|
||||||
static void
|
void
|
||||||
path_flip_curve (PathCurve *curve)
|
path_flip_curve (PathCurve *curve)
|
||||||
{
|
{
|
||||||
gpointer *end_data;
|
gpointer *end_data;
|
||||||
|
@ -454,6 +495,8 @@ path_flip_curve (PathCurve *curve)
|
||||||
|
|
||||||
PathSegment *tmp, *tmp2;
|
PathSegment *tmp, *tmp2;
|
||||||
|
|
||||||
|
#warning Please add path_curve_flip_segment here
|
||||||
|
|
||||||
if (!curve && !curve->segments) {
|
if (!curve && !curve->segments) {
|
||||||
#ifdef PATH_TOOL_DEBUG
|
#ifdef PATH_TOOL_DEBUG
|
||||||
fprintf (stderr, "path_flip_curve: No curve o no segments to flip!\n");
|
fprintf (stderr, "path_flip_curve: No curve o no segments to flip!\n");
|
||||||
|
@ -483,11 +526,12 @@ path_flip_curve (PathCurve *curve)
|
||||||
tmp->data = end_data;
|
tmp->data = end_data;
|
||||||
}
|
}
|
||||||
tmp = tmp->next;
|
tmp = tmp->next;
|
||||||
|
#warning Probably some segment-updates needed
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static void
|
void
|
||||||
path_free_path (Path * path)
|
path_free_path (Path * path)
|
||||||
{
|
{
|
||||||
PathCurve *tmp1, *tmp2;
|
PathCurve *tmp1, *tmp2;
|
||||||
|
@ -495,18 +539,18 @@ path_free_path (Path * path)
|
||||||
if (path)
|
if (path)
|
||||||
{
|
{
|
||||||
tmp2 = path->curves;
|
tmp2 = path->curves;
|
||||||
g_string_free(path->name, TRUE);
|
|
||||||
g_free(path);
|
|
||||||
|
|
||||||
while ((tmp1 = tmp2) != NULL)
|
while ((tmp1 = tmp2) != NULL)
|
||||||
{
|
{
|
||||||
tmp2 = tmp1->next;
|
tmp2 = tmp1->next;
|
||||||
path_free_curve (tmp1);
|
path_free_curve (tmp1);
|
||||||
}
|
}
|
||||||
|
g_string_free(path->name, TRUE);
|
||||||
|
g_free(path);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
void
|
||||||
path_free_curve (PathCurve *curve)
|
path_free_curve (PathCurve *curve)
|
||||||
{
|
{
|
||||||
PathSegment *tmp1, *tmp2;
|
PathSegment *tmp1, *tmp2;
|
||||||
|
@ -528,7 +572,7 @@ path_free_curve (PathCurve *curve)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
void
|
||||||
path_free_segment (PathSegment *segment)
|
path_free_segment (PathSegment *segment)
|
||||||
{
|
{
|
||||||
if (segment)
|
if (segment)
|
||||||
|
@ -538,11 +582,12 @@ path_free_segment (PathSegment *segment)
|
||||||
segment->parent, segment, 0, SEGMENT_ACTIVE);
|
segment->parent, segment, 0, SEGMENT_ACTIVE);
|
||||||
if (segment->data)
|
if (segment->data)
|
||||||
g_free(segment->data);
|
g_free(segment->data);
|
||||||
|
#warning Free Segment needs an own hook in the different curve-types!
|
||||||
g_free (segment);
|
g_free (segment);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
void
|
||||||
path_delete_curve (PathCurve *curve)
|
path_delete_curve (PathCurve *curve)
|
||||||
{
|
{
|
||||||
if (curve)
|
if (curve)
|
||||||
|
@ -560,7 +605,7 @@ path_delete_curve (PathCurve *curve)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
void
|
||||||
path_delete_segment (PathSegment *segment)
|
path_delete_segment (PathSegment *segment)
|
||||||
{
|
{
|
||||||
if (segment)
|
if (segment)
|
||||||
|
@ -587,6 +632,7 @@ path_delete_segment (PathSegment *segment)
|
||||||
/*
|
/*
|
||||||
* here we have to update the surrounding segments
|
* here we have to update the surrounding segments
|
||||||
*/
|
*/
|
||||||
|
#warning Please add path_curve_update_segment here
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -595,14 +641,21 @@ path_delete_segment (PathSegment *segment)
|
||||||
* A function to determine, which object is hit by the cursor
|
* A function to determine, which object is hit by the cursor
|
||||||
*/
|
*/
|
||||||
|
|
||||||
static gint
|
gint
|
||||||
path_tool_cursor_position (Tool *tool, gint x, gint y, gint halfwidth, Path **pathP, PathCurve **curveP, PathSegment **segmentP)
|
path_tool_cursor_position (Tool *tool, gint x, gint y, gint halfwidth, Path **pathP, PathCurve **curveP, PathSegment **segmentP, gdouble *positionP)
|
||||||
{
|
{
|
||||||
gint location;
|
gint location;
|
||||||
|
gdouble pos;
|
||||||
|
|
||||||
if (path_tool_on_anchors (tool, x, y, halfwidth, pathP, curveP, segmentP))
|
if (path_tool_on_anchors (tool, x, y, halfwidth, pathP, curveP, segmentP))
|
||||||
return ON_ANCHOR;
|
return ON_ANCHOR;
|
||||||
|
|
||||||
|
pos = path_tool_on_curve (tool, x, y, halfwidth, pathP, curveP, segmentP);
|
||||||
|
if (pos >= 0 && pos <= 1) {
|
||||||
|
if (positionP) (*positionP) = pos;
|
||||||
|
return ON_CURVE;
|
||||||
|
}
|
||||||
|
|
||||||
return ON_CANVAS;
|
return ON_CANVAS;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -611,7 +664,7 @@ path_tool_cursor_position (Tool *tool, gint x, gint y, gint halfwidth, Path **pa
|
||||||
* The click-callbacks for the tool
|
* The click-callbacks for the tool
|
||||||
*/
|
*/
|
||||||
|
|
||||||
static void
|
void
|
||||||
path_tool_button_press (Tool *tool,
|
path_tool_button_press (Tool *tool,
|
||||||
GdkEventButton *bevent,
|
GdkEventButton *bevent,
|
||||||
gpointer gdisp_ptr)
|
gpointer gdisp_ptr)
|
||||||
|
@ -649,12 +702,13 @@ path_tool_button_press (Tool *tool,
|
||||||
* switch accordingly.
|
* switch accordingly.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
path_tool->click_pos = path_tool_cursor_position(tool, x, y, halfwidth,
|
path_tool->click_type = path_tool_cursor_position(tool, x, y, halfwidth,
|
||||||
&(path_tool->click_path),
|
&(path_tool->click_path),
|
||||||
&(path_tool->click_curve),
|
&(path_tool->click_curve),
|
||||||
&(path_tool->click_segment));
|
&(path_tool->click_segment),
|
||||||
|
&(path_tool->click_position));
|
||||||
|
|
||||||
switch (path_tool->click_pos)
|
switch (path_tool->click_type)
|
||||||
{
|
{
|
||||||
case ON_CANVAS:
|
case ON_CANVAS:
|
||||||
grab_pointer = path_tool_button_press_canvas(tool, bevent, gdisp);
|
grab_pointer = path_tool_button_press_canvas(tool, bevent, gdisp);
|
||||||
|
@ -664,6 +718,10 @@ path_tool_button_press (Tool *tool,
|
||||||
grab_pointer = path_tool_button_press_anchor(tool, bevent, gdisp);
|
grab_pointer = path_tool_button_press_anchor(tool, bevent, gdisp);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case ON_CURVE:
|
||||||
|
grab_pointer = path_tool_button_press_curve(tool, bevent, gdisp);
|
||||||
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
g_message("Huh? Whats happening here? (button_press_*)");
|
g_message("Huh? Whats happening here? (button_press_*)");
|
||||||
}
|
}
|
||||||
|
@ -679,7 +737,7 @@ path_tool_button_press (Tool *tool,
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static gint
|
gint
|
||||||
path_tool_button_press_anchor (Tool *tool,
|
path_tool_button_press_anchor (Tool *tool,
|
||||||
GdkEventButton *bevent,
|
GdkEventButton *bevent,
|
||||||
GDisplay *gdisp)
|
GDisplay *gdisp)
|
||||||
|
@ -789,6 +847,7 @@ path_tool_button_press_anchor (Tool *tool,
|
||||||
|
|
||||||
path_delete_segment (path_tool->click_segment);
|
path_delete_segment (path_tool->click_segment);
|
||||||
path_tool->click_segment = NULL;
|
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))
|
else if (!(path_tool->click_segment->flags & SEGMENT_ACTIVE))
|
||||||
{
|
{
|
||||||
|
@ -797,14 +856,12 @@ path_tool_button_press_anchor (Tool *tool,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/* Action goes here */
|
|
||||||
|
|
||||||
draw_core_resume(path_tool->core, tool);
|
draw_core_resume(path_tool->core, tool);
|
||||||
|
|
||||||
return grab_pointer;
|
return grab_pointer;
|
||||||
}
|
}
|
||||||
|
|
||||||
static gint
|
gint
|
||||||
path_tool_button_press_canvas (Tool *tool,
|
path_tool_button_press_canvas (Tool *tool,
|
||||||
GdkEventButton *bevent,
|
GdkEventButton *bevent,
|
||||||
GDisplay *gdisp)
|
GDisplay *gdisp)
|
||||||
|
@ -857,7 +914,48 @@ path_tool_button_press_canvas (Tool *tool,
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
gint
|
||||||
|
path_tool_button_press_curve (Tool *tool,
|
||||||
|
GdkEventButton *bevent,
|
||||||
|
GDisplay *gdisp)
|
||||||
|
{
|
||||||
|
PathTool *path_tool = tool->private;
|
||||||
|
|
||||||
|
Path * 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_curve:\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;
|
||||||
|
}
|
||||||
|
|
||||||
|
draw_core_pause (path_tool->core, tool);
|
||||||
|
|
||||||
|
if (path_tool->click_modifier & GDK_SHIFT_MASK) {
|
||||||
|
cur_segment = path_curve_insert_anchor (path_tool, 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;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
draw_core_resume(path_tool->core, tool);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
path_tool_button_release (Tool *tool,
|
path_tool_button_release (Tool *tool,
|
||||||
GdkEventButton *bevent,
|
GdkEventButton *bevent,
|
||||||
gpointer gdisp_ptr)
|
gpointer gdisp_ptr)
|
||||||
|
@ -883,7 +981,7 @@ path_tool_button_release (Tool *tool,
|
||||||
* The motion-callbacks for the tool
|
* The motion-callbacks for the tool
|
||||||
*/
|
*/
|
||||||
|
|
||||||
static void
|
void
|
||||||
path_tool_motion (Tool *tool,
|
path_tool_motion (Tool *tool,
|
||||||
GdkEventMotion *mevent,
|
GdkEventMotion *mevent,
|
||||||
gpointer gdisp_ptr)
|
gpointer gdisp_ptr)
|
||||||
|
@ -896,7 +994,7 @@ path_tool_motion (Tool *tool,
|
||||||
gdisp = (GDisplay *) gdisp_ptr;
|
gdisp = (GDisplay *) gdisp_ptr;
|
||||||
path_tool = (PathTool *) tool->private;
|
path_tool = (PathTool *) tool->private;
|
||||||
|
|
||||||
switch (path_tool->click_pos) {
|
switch (path_tool->click_type) {
|
||||||
case ON_ANCHOR:
|
case ON_ANCHOR:
|
||||||
path_tool_motion_anchor(tool, mevent, gdisp);
|
path_tool_motion_anchor(tool, mevent, gdisp);
|
||||||
break;
|
break;
|
||||||
|
@ -906,7 +1004,7 @@ path_tool_motion (Tool *tool,
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
void
|
||||||
path_tool_motion_anchor (Tool *tool,
|
path_tool_motion_anchor (Tool *tool,
|
||||||
GdkEventMotion *mevent,
|
GdkEventMotion *mevent,
|
||||||
GDisplay *gdisp)
|
GDisplay *gdisp)
|
||||||
|
@ -977,7 +1075,7 @@ path_tool_motion_anchor (Tool *tool,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static void
|
void
|
||||||
path_tool_cursor_update (Tool *tool,
|
path_tool_cursor_update (Tool *tool,
|
||||||
GdkEventMotion *mevent,
|
GdkEventMotion *mevent,
|
||||||
gpointer gdisp_ptr)
|
gpointer gdisp_ptr)
|
||||||
|
@ -999,13 +1097,16 @@ path_tool_cursor_update (Tool *tool,
|
||||||
gdisplay_untransform_coords (gdisp, mevent->x + PATH_TOOL_HALFWIDTH, 0, &halfwidth, &dummy, TRUE, 0);
|
gdisplay_untransform_coords (gdisp, mevent->x + PATH_TOOL_HALFWIDTH, 0, &halfwidth, &dummy, TRUE, 0);
|
||||||
halfwidth -= x;
|
halfwidth -= x;
|
||||||
|
|
||||||
cursor_location = path_tool_cursor_position(tool, x, y, halfwidth, NULL, NULL, NULL);
|
cursor_location = path_tool_cursor_position(tool, x, y, halfwidth, NULL, NULL, NULL, NULL);
|
||||||
|
|
||||||
switch (cursor_location) {
|
switch (cursor_location) {
|
||||||
case ON_CANVAS:
|
case ON_CANVAS:
|
||||||
gdisplay_install_tool_cursor (gdisp, GIMP_MOUSE1AP_CURSOR);
|
gdisplay_install_tool_cursor (gdisp, GIMP_MOUSE1AP_CURSOR);
|
||||||
break;
|
break;
|
||||||
case ON_ANCHOR:
|
case ON_ANCHOR:
|
||||||
|
gdisplay_install_tool_cursor (gdisp, GDK_FLEUR);
|
||||||
|
break;
|
||||||
|
case ON_CURVE:
|
||||||
gdisplay_install_tool_cursor (gdisp, GDK_TCROSS);
|
gdisplay_install_tool_cursor (gdisp, GDK_TCROSS);
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
|
@ -1018,7 +1119,7 @@ path_tool_cursor_update (Tool *tool,
|
||||||
* Tool-control functions
|
* Tool-control functions
|
||||||
*/
|
*/
|
||||||
|
|
||||||
static void
|
void
|
||||||
path_tool_control (Tool *tool,
|
path_tool_control (Tool *tool,
|
||||||
ToolAction action,
|
ToolAction action,
|
||||||
gpointer gdisp_ptr)
|
gpointer gdisp_ptr)
|
||||||
|
@ -1044,6 +1145,9 @@ path_tool_control (Tool *tool,
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case HALT:
|
case HALT:
|
||||||
|
#ifdef PATH_TOOL_DEBUG
|
||||||
|
fprintf (stderr, "path_tool_control: HALT\n");
|
||||||
|
#endif PATH_TOOL_DEBUG
|
||||||
draw_core_stop (path_tool->core, tool);
|
draw_core_stop (path_tool->core, tool);
|
||||||
tool->state = INACTIVE;
|
tool->state = INACTIVE;
|
||||||
break;
|
break;
|
||||||
|
@ -1051,6 +1155,9 @@ path_tool_control (Tool *tool,
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
#ifdef PATH_TOOL_DEBUG
|
||||||
|
fprintf (stderr, "path_tool_control: end\n");
|
||||||
|
#endif PATH_TOOL_DEBUG
|
||||||
}
|
}
|
||||||
|
|
||||||
Tool *
|
Tool *
|
||||||
|
@ -1069,11 +1176,15 @@ tools_new_path_tool (void)
|
||||||
tool = tools_new_tool (PATH_TOOL);
|
tool = tools_new_tool (PATH_TOOL);
|
||||||
private = g_new (PathTool, 1);
|
private = g_new (PathTool, 1);
|
||||||
|
|
||||||
private->click_pos = ON_CANVAS;
|
private->click_type = ON_CANVAS;
|
||||||
private->click_x = 0;
|
private->click_x = 0;
|
||||||
private->click_y = 0;
|
private->click_y = 0;
|
||||||
private->click_halfwidth = 0;
|
private->click_halfwidth = 0;
|
||||||
private->click_modifier = 0;
|
private->click_modifier = 0;
|
||||||
|
private->click_path = NULL;
|
||||||
|
private->click_curve = NULL;
|
||||||
|
private->click_segment = NULL;
|
||||||
|
private->click_position = -1;
|
||||||
|
|
||||||
private->active_count = 0;
|
private->active_count = 0;
|
||||||
private->single_active_segment = NULL;
|
private->single_active_segment = NULL;
|
||||||
|
@ -1108,6 +1219,9 @@ tools_free_path_tool (Tool *tool)
|
||||||
GDisplay * gdisp;
|
GDisplay * gdisp;
|
||||||
PathTool * path_tool;
|
PathTool * path_tool;
|
||||||
|
|
||||||
|
#ifdef PATH_TOOL_DEBUG
|
||||||
|
fprintf (stderr, "tools_free_path_tool start\n");
|
||||||
|
#endif PATH_TOOL_DEBUG
|
||||||
path_tool = (PathTool *) tool->private;
|
path_tool = (PathTool *) tool->private;
|
||||||
gdisp = (GDisplay *) tool->gdisp_ptr;
|
gdisp = (GDisplay *) tool->gdisp_ptr;
|
||||||
|
|
||||||
|
@ -1121,9 +1235,84 @@ tools_free_path_tool (Tool *tool)
|
||||||
draw_core_free (path_tool->core);
|
draw_core_free (path_tool->core);
|
||||||
|
|
||||||
g_free (path_tool);
|
g_free (path_tool);
|
||||||
|
#ifdef PATH_TOOL_DEBUG
|
||||||
|
fprintf (stderr, "tools_free_path_tool end\n");
|
||||||
|
#endif PATH_TOOL_DEBUG
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**************************************************************
|
||||||
|
* Set of function to determine, if the click was on an segment
|
||||||
|
*/
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
Tool *tool;
|
||||||
|
Path *path;
|
||||||
|
PathCurve *curve;
|
||||||
|
PathSegment *segment;
|
||||||
|
gint testx;
|
||||||
|
gint testy;
|
||||||
|
gint halfwidth;
|
||||||
|
gint distance;
|
||||||
|
gdouble position;
|
||||||
|
gboolean found;
|
||||||
|
} Path_on_curve_type;
|
||||||
|
|
||||||
|
/* This is a CurveTraverseFunc */
|
||||||
|
void
|
||||||
|
path_tool_on_curve_helper (Path *path, PathCurve *curve, PathSegment *segment, gpointer ptr)
|
||||||
|
{
|
||||||
|
gint distance;
|
||||||
|
gdouble position;
|
||||||
|
Path_on_curve_type *data = (Path_on_curve_type *) ptr;
|
||||||
|
|
||||||
|
if (segment && segment->next && data && data->distance > 0)
|
||||||
|
{
|
||||||
|
position = path_curve_on_segment (data->tool, segment, data->testx, data->testy, data->halfwidth, &distance);
|
||||||
|
if (position >= 0 && distance < data->distance )
|
||||||
|
{
|
||||||
|
data->path = path;
|
||||||
|
data->curve = curve;
|
||||||
|
data->segment = segment;
|
||||||
|
data->distance = distance;
|
||||||
|
data->position = position;
|
||||||
|
data->found = TRUE;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
gdouble
|
||||||
|
path_tool_on_curve (Tool *tool, gint x, gint y, gint halfwidth, Path **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->segment = NULL;
|
||||||
|
data->testx = x;
|
||||||
|
data->testy = y;
|
||||||
|
data->halfwidth = halfwidth;
|
||||||
|
data->distance = halfwidth * halfwidth + 1;
|
||||||
|
data->position = -1;
|
||||||
|
data->found = FALSE;
|
||||||
|
|
||||||
|
path_traverse_path (((PathTool *) data->tool->private)->cur_path, NULL, path_tool_on_curve_helper, NULL, data);
|
||||||
|
|
||||||
|
if (ret_pathP) *ret_pathP = data->path;
|
||||||
|
if (ret_curveP) *ret_curveP = data->curve;
|
||||||
|
if (ret_segmentP) *ret_segmentP = data->segment;
|
||||||
|
|
||||||
|
position = data->position;
|
||||||
|
|
||||||
|
g_free(data);
|
||||||
|
|
||||||
|
return position;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
/**************************************************************
|
/**************************************************************
|
||||||
* Set of function to determine, if the click was on an anchor
|
* Set of function to determine, if the click was on an anchor
|
||||||
*/
|
*/
|
||||||
|
@ -1139,7 +1328,7 @@ typedef struct {
|
||||||
} Path_on_anchors_type;
|
} Path_on_anchors_type;
|
||||||
|
|
||||||
/* This is a CurveTraverseFunc */
|
/* This is a CurveTraverseFunc */
|
||||||
static void
|
void
|
||||||
path_tool_on_anchors_helper (Path *path, PathCurve *curve, PathSegment *segment, gpointer ptr)
|
path_tool_on_anchors_helper (Path *path, PathCurve *curve, PathSegment *segment, gpointer ptr)
|
||||||
{
|
{
|
||||||
gint distance;
|
gint distance;
|
||||||
|
@ -1161,7 +1350,7 @@ path_tool_on_anchors_helper (Path *path, PathCurve *curve, PathSegment *segment,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static gboolean
|
gboolean
|
||||||
path_tool_on_anchors (Tool *tool, gint x, gint y, gint halfwidth, Path **ret_pathP, PathCurve **ret_curveP, PathSegment **ret_segmentP)
|
path_tool_on_anchors (Tool *tool, gint x, gint y, gint halfwidth, Path **ret_pathP, PathCurve **ret_curveP, PathSegment **ret_segmentP)
|
||||||
{
|
{
|
||||||
Path_on_anchors_type *data = g_new (Path_on_anchors_type, 1);
|
Path_on_anchors_type *data = g_new (Path_on_anchors_type, 1);
|
||||||
|
@ -1200,7 +1389,7 @@ typedef struct {
|
||||||
} Path_offset_active_type;
|
} Path_offset_active_type;
|
||||||
|
|
||||||
/* This is a CurveTraverseFunc */
|
/* This is a CurveTraverseFunc */
|
||||||
static void
|
void
|
||||||
path_offset_active_helper (Path *path, PathCurve *curve, PathSegment *segment, gpointer ptr)
|
path_offset_active_helper (Path *path, PathCurve *curve, PathSegment *segment, gpointer ptr)
|
||||||
{
|
{
|
||||||
Path_offset_active_type *data = (Path_offset_active_type *) ptr;
|
Path_offset_active_type *data = (Path_offset_active_type *) ptr;
|
||||||
|
@ -1209,9 +1398,10 @@ path_offset_active_helper (Path *path, PathCurve *curve, PathSegment *segment, g
|
||||||
segment->x += data->dx;
|
segment->x += data->dx;
|
||||||
segment->y += data->dy;
|
segment->y += data->dy;
|
||||||
}
|
}
|
||||||
|
#warning Do a segment_update here!
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
void
|
||||||
path_offset_active (Path *path, gdouble dx, gdouble dy)
|
path_offset_active (Path *path, gdouble dx, gdouble dy)
|
||||||
{
|
{
|
||||||
Path_offset_active_type *data = g_new (Path_offset_active_type, 1);
|
Path_offset_active_type *data = g_new (Path_offset_active_type, 1);
|
||||||
|
@ -1226,7 +1416,7 @@ path_offset_active (Path *path, gdouble dx, gdouble dy)
|
||||||
|
|
||||||
|
|
||||||
/**************************************************************
|
/**************************************************************
|
||||||
* Set of function to set the state of all anchors to inactive
|
* Set of function to set the state of all anchors
|
||||||
*/
|
*/
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
|
@ -1236,7 +1426,7 @@ typedef struct {
|
||||||
} Path_set_flags_type;
|
} Path_set_flags_type;
|
||||||
|
|
||||||
/* This is a CurveTraverseFunc */
|
/* This is a CurveTraverseFunc */
|
||||||
static void
|
void
|
||||||
path_set_flags_helper (Path *path, PathCurve *curve, PathSegment *segment, gpointer ptr)
|
path_set_flags_helper (Path *path, PathCurve *curve, PathSegment *segment, gpointer ptr)
|
||||||
{
|
{
|
||||||
Path_set_flags_type *tmp = (Path_set_flags_type *) ptr;
|
Path_set_flags_type *tmp = (Path_set_flags_type *) ptr;
|
||||||
|
@ -1272,7 +1462,7 @@ path_set_flags_helper (Path *path, PathCurve *curve, PathSegment *segment, gpoin
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
void
|
||||||
path_set_flags (PathTool *path_tool, Path *path, PathCurve *curve, PathSegment *segment, guint32 bits_set, guint32 bits_clear)
|
path_set_flags (PathTool *path_tool, Path *path, PathCurve *curve, PathSegment *segment, guint32 bits_set, guint32 bits_clear)
|
||||||
{
|
{
|
||||||
Path_set_flags_type *tmp = g_new (Path_set_flags_type, 1);
|
Path_set_flags_type *tmp = g_new (Path_set_flags_type, 1);
|
||||||
|
@ -1296,7 +1486,7 @@ path_set_flags (PathTool *path_tool, Path *path, PathCurve *curve, PathSegment *
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/* This is a CurveTraverseFunc */
|
/* This is a CurveTraverseFunc */
|
||||||
static void
|
void
|
||||||
path_tool_draw_helper (Path *path, PathCurve *curve, PathSegment * segment, gpointer tool_ptr)
|
path_tool_draw_helper (Path *path, PathCurve *curve, PathSegment * segment, gpointer tool_ptr)
|
||||||
{
|
{
|
||||||
Tool * tool = (Tool *) tool_ptr;
|
Tool * tool = (Tool *) tool_ptr;
|
||||||
|
@ -1335,8 +1525,7 @@ path_tool_draw_helper (Path *path, PathCurve *curve, PathSegment * segment, gpoi
|
||||||
|
|
||||||
if (segment->next)
|
if (segment->next)
|
||||||
{
|
{
|
||||||
gdisplay_transform_coords (gdisp, (gint) segment->next->x, (gint) segment->next->y, &x2, &y2, FALSE);
|
path_curve_draw_segment (tool, segment);
|
||||||
gdk_draw_line (core->win, core->gc, x1, y1, x2, y2);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
#ifdef PATH_TOOL_DEBUG
|
#ifdef PATH_TOOL_DEBUG
|
||||||
|
@ -1345,7 +1534,7 @@ path_tool_draw_helper (Path *path, PathCurve *curve, PathSegment * segment, gpoi
|
||||||
#endif PATH_TOOL_DEBUG
|
#endif PATH_TOOL_DEBUG
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
void
|
||||||
path_tool_draw (Tool *tool)
|
path_tool_draw (Tool *tool)
|
||||||
{
|
{
|
||||||
GDisplay * gdisp;
|
GDisplay * gdisp;
|
||||||
|
@ -1363,4 +1552,10 @@ path_tool_draw (Tool *tool)
|
||||||
|
|
||||||
path_traverse_path (cur_path, NULL, path_tool_draw_helper, NULL, tool);
|
path_traverse_path (cur_path, NULL, path_tool_draw_helper, NULL, tool);
|
||||||
|
|
||||||
|
#ifdef PATH_TOOL_DEBUG
|
||||||
|
fprintf (stderr, "path_tool_draw end.\n");
|
||||||
|
#endif PATH_TOOL_DEBUG
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -1,5 +1,6 @@
|
||||||
/* The GIMP -- an image manipulation program
|
/* The GIMP -- an image manipulation program
|
||||||
* Copyright (C) 1995 Spencer Kimball and Peter Mattis
|
*
|
||||||
|
* This file Copyright (C) 1999 Simon Budig
|
||||||
*
|
*
|
||||||
* This program is free software; you can redistribute it and/or modify
|
* 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
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
@ -15,6 +16,7 @@
|
||||||
* along with this program; if not, write to the Free Software
|
* along with this program; if not, write to the Free Software
|
||||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#ifndef __PATH_TOOL_H__
|
#ifndef __PATH_TOOL_H__
|
||||||
#define __PATH_TOOL_H__
|
#define __PATH_TOOL_H__
|
||||||
|
|
||||||
|
|
|
@ -18,6 +18,9 @@
|
||||||
#ifndef __PATH_TOOLP_H__
|
#ifndef __PATH_TOOLP_H__
|
||||||
#define __PATH_TOOLP_H__
|
#define __PATH_TOOLP_H__
|
||||||
|
|
||||||
|
#undef PATH_TOOL_DEBUG
|
||||||
|
|
||||||
|
#include "draw_core.h"
|
||||||
|
|
||||||
#define IMAGE_COORDS 1
|
#define IMAGE_COORDS 1
|
||||||
#define AA_IMAGE_COORDS 2
|
#define AA_IMAGE_COORDS 2
|
||||||
|
@ -33,12 +36,10 @@
|
||||||
|
|
||||||
#define SUBDIVIDE 1000
|
#define SUBDIVIDE 1000
|
||||||
|
|
||||||
|
typedef enum { SEGMENT_LINE=0, SEGMENT_BEZIER} SegmentType;
|
||||||
|
|
||||||
enum { ON_ANCHOR, ON_HANDLE, ON_CURVE, ON_CANVAS };
|
enum { ON_ANCHOR, ON_HANDLE, ON_CURVE, ON_CANVAS };
|
||||||
|
|
||||||
typedef enum { SEGMENT_LINE, SEGMENT_BEZIER } SegmentType;
|
|
||||||
|
|
||||||
|
|
||||||
typedef struct _path_segment PathSegment;
|
typedef struct _path_segment PathSegment;
|
||||||
typedef struct _path_curve PathCurve;
|
typedef struct _path_curve PathCurve;
|
||||||
typedef struct _path Path;
|
typedef struct _path Path;
|
||||||
|
@ -82,7 +83,7 @@ struct _path
|
||||||
|
|
||||||
struct _path_tool
|
struct _path_tool
|
||||||
{
|
{
|
||||||
gint click_pos; /* where did the user click? */
|
gint click_type; /* where did the user click? */
|
||||||
gint click_x; /* X-coordinate of the click */
|
gint click_x; /* X-coordinate of the click */
|
||||||
gint click_y; /* Y-coordinate of the click */
|
gint click_y; /* Y-coordinate of the click */
|
||||||
gint click_halfwidth;
|
gint click_halfwidth;
|
||||||
|
@ -90,6 +91,7 @@ struct _path_tool
|
||||||
Path *click_path; /* On which Path/Curve/Segment */
|
Path *click_path; /* On which Path/Curve/Segment */
|
||||||
PathCurve *click_curve; /* was the click? */
|
PathCurve *click_curve; /* was the click? */
|
||||||
PathSegment *click_segment;
|
PathSegment *click_segment;
|
||||||
|
gdouble click_position; /* The position on the segment */
|
||||||
|
|
||||||
gint active_count; /* How many segments are active? */
|
gint active_count; /* How many segments are active? */
|
||||||
/*
|
/*
|
||||||
|
@ -110,6 +112,4 @@ typedef void (*PathTraverseFunc) (Path *, PathCurve *, gpointer);
|
||||||
typedef void (*CurveTraverseFunc) (Path *, PathCurve *, PathSegment *, gpointer);
|
typedef void (*CurveTraverseFunc) (Path *, PathCurve *, PathSegment *, gpointer);
|
||||||
typedef void (*SegmentTraverseFunc) (Path *, PathCurve *, PathSegment *, gint, gint, gpointer);
|
typedef void (*SegmentTraverseFunc) (Path *, PathCurve *, PathSegment *, gint, gint, gpointer);
|
||||||
|
|
||||||
/* typedef void (*SegmentTraverseFunc) (PathTool *, GdkPoint *, gint, gpointer);*/
|
|
||||||
|
|
||||||
#endif /* __PATH_TOOLP_H__ */
|
#endif /* __PATH_TOOLP_H__ */
|
||||||
|
|
Loading…
Reference in New Issue