1997-11-25 06:05:25 +08:00
|
|
|
/* The GIMP -- an image manipulation program
|
|
|
|
* Copyright (C) 1995 Spencer Kimball and Peter Mattis
|
|
|
|
*
|
|
|
|
* 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
|
1998-04-13 13:44:11 +08:00
|
|
|
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
1997-11-25 06:05:25 +08:00
|
|
|
*/
|
Check for mmap.
* configure.in: Check for mmap.
* app/makefile.msc: Depend on gimpi.lib.
* app/app_procs.c (app_init): Fix gccism: Allocate filenames (an
array with non-constant size) dynamically.
* app/{datafiles,fileops,general,install,module_db,temp_buf}.c:
Include glib.h before standard headers, because of certain obscure
details related to compiling with gcc on Win32.
(If you really want to know: glib.h defines he names of POSIXish
(but non-ANSI) functions as prefixed with underscore, because
that's how they are named in the msvcrt runtime C library we want
to use. However, defining stat as _stat causes some problems if
done after including the mingw32 <sys/stat.h>. So, it's easiest to
include <glib.h> early.)
* app/main.c: Use _stdcall and __argc, __argv with MSC, but
__attribute__((stdcall)) and _argc, _argv with gcc. Don't print
the "Passed serialization test" message on Win32. (It would open
up an otherwise unnecessary console window.)
* app/paint_funcs.c (gaussian_blur_region): Don't use variable sum
until initialized.
* app/{bezier_select,paths_dialog}.c: Include config.h and define
rint() if necessary.
* app/plug_in.c: Use _spawnv, not spawnv, on Win32 and OS/2.
1999-05-29 01:47:17 +08:00
|
|
|
#include "config.h"
|
|
|
|
|
1997-11-25 06:05:25 +08:00
|
|
|
#include <string.h>
|
app/appenv.h New file. Includes <math.h>. Move G_PI, RINT(), ROUND() etc
1999-09-01 Tor Lillqvist <tml@iki.fi>
* app/appenv.h
* libgimp/gimpmath.h: New file. Includes <math.h>. Move G_PI,
RINT(), ROUND() etc from app/appenv.h here, so plug-ins can
use them, too. Remove some commented-out old stuff in appenv.h.
* libgimp/gimp.h: Include gimpmath.h.
* libgimp/gimp.c (gimp_main): Win32: Don't install signal
handlers, we can't do anything useful in the handler ourselves
anyway (it would be nice to print out a backtrace, but that seems
pretty hard to do, even if not impossible). Let Windows inform the
user about the crash. If the plug-in was compiled with MSVC, and
the user also has it, she is offered a chance to start the
debugger automatically anyway.
* app/*several*.c: Include gimpmath.h for G_PI etc. Don't include
<math.h>, as gimpmath.h includes it.
* plug-ins/*/*many*.c: Include config.h. Don't include <math.h>.
Remove all the duplicated definitions of G_PI and rint(). Use
RINT() instead of rint().
* app/app_procs.[ch]: app_exit() takes a gboolean.
* app/batch.c
* app/commands.c
* app/interface.c: Call app_exit() with FALSE or TRUE.
* app/main.c (on_error): Call gimp_fatal_error. (main): Don't
install any signal handler on Win32 here, either.
* app/errors.c (gimp_fatal_error, gimp_terminate): Win32: Format
the message and call MessageBox with it. g_on_error_query doesn't
do anything useful on Win32, and printf'ing a message to stdout or
stderr doesn't do anything, either, in a windowing application.
1999-09-02 04:30:56 +08:00
|
|
|
|
1997-11-25 06:05:25 +08:00
|
|
|
#include "appenv.h"
|
1999-05-14 06:53:40 +08:00
|
|
|
#include "cursorutil.h"
|
1997-11-25 06:05:25 +08:00
|
|
|
#include "draw_core.h"
|
|
|
|
#include "edit_selection.h"
|
|
|
|
#include "errors.h"
|
|
|
|
#include "gdisplay.h"
|
|
|
|
#include "gimage_mask.h"
|
|
|
|
#include "rect_select.h"
|
1998-03-27 14:29:39 +08:00
|
|
|
#include "interface.h"
|
1999-03-06 07:50:24 +08:00
|
|
|
#include "bezier_select.h"
|
|
|
|
#include "bezier_selectP.h"
|
1999-06-07 01:26:51 +08:00
|
|
|
#include "paths_dialogP.h"
|
1999-04-13 01:55:06 +08:00
|
|
|
#include "selection_options.h"
|
1998-06-26 16:03:50 +08:00
|
|
|
|
Lots of ii8n stuff here and some additions to the de.po. Applied
Wed Oct 14 17:46:15 EDT 1998 Adrian Likins <adrian@gimp.org>
* app/*, po/de.po, de/POTFILES.in, libgimp/gimpintl.h:
Lots of ii8n stuff here and some additions to the de.po.
Applied gimp-egger-981005-1 ,gimp-egger-981006-1,
gimp-egger-981007-1, gimp-egger-981008-1,
gimp-egger-981009-1.patch, gimp-egger-981010-1.patch
* plug-in/guillotine/guillotine.c: added the coordinates
of the split images from the original image to the title.
ie foo.jpg (0,0) for the image in the topleft.
* plug-in/script-fu/scripts/neon-logo.scm,
perspective-shadow.scm, predator.scm,rendermap.scm,
ripply-anim.scm, select_to_image.scm,swirltile.scm,
xach-effect.scm: updated scripts to use new script-fu stuff
wooo boy! a big un!
in testing this, it looks like some of the po files are busted.
but the code stuff seems okay.
-adrian
1998-10-15 07:23:52 +08:00
|
|
|
#include "libgimp/gimpintl.h"
|
app/appenv.h New file. Includes <math.h>. Move G_PI, RINT(), ROUND() etc
1999-09-01 Tor Lillqvist <tml@iki.fi>
* app/appenv.h
* libgimp/gimpmath.h: New file. Includes <math.h>. Move G_PI,
RINT(), ROUND() etc from app/appenv.h here, so plug-ins can
use them, too. Remove some commented-out old stuff in appenv.h.
* libgimp/gimp.h: Include gimpmath.h.
* libgimp/gimp.c (gimp_main): Win32: Don't install signal
handlers, we can't do anything useful in the handler ourselves
anyway (it would be nice to print out a backtrace, but that seems
pretty hard to do, even if not impossible). Let Windows inform the
user about the crash. If the plug-in was compiled with MSVC, and
the user also has it, she is offered a chance to start the
debugger automatically anyway.
* app/*several*.c: Include gimpmath.h for G_PI etc. Don't include
<math.h>, as gimpmath.h includes it.
* plug-ins/*/*many*.c: Include config.h. Don't include <math.h>.
Remove all the duplicated definitions of G_PI and rint(). Use
RINT() instead of rint().
* app/app_procs.[ch]: app_exit() takes a gboolean.
* app/batch.c
* app/commands.c
* app/interface.c: Call app_exit() with FALSE or TRUE.
* app/main.c (on_error): Call gimp_fatal_error. (main): Don't
install any signal handler on Win32 here, either.
* app/errors.c (gimp_fatal_error, gimp_terminate): Win32: Format
the message and call MessageBox with it. g_on_error_query doesn't
do anything useful on Win32, and printf'ing a message to stdout or
stderr doesn't do anything, either, in a windowing application.
1999-09-02 04:30:56 +08:00
|
|
|
#include "libgimp/gimpmath.h"
|
Lots of ii8n stuff here and some additions to the de.po. Applied
Wed Oct 14 17:46:15 EDT 1998 Adrian Likins <adrian@gimp.org>
* app/*, po/de.po, de/POTFILES.in, libgimp/gimpintl.h:
Lots of ii8n stuff here and some additions to the de.po.
Applied gimp-egger-981005-1 ,gimp-egger-981006-1,
gimp-egger-981007-1, gimp-egger-981008-1,
gimp-egger-981009-1.patch, gimp-egger-981010-1.patch
* plug-in/guillotine/guillotine.c: added the coordinates
of the split images from the original image to the title.
ie foo.jpg (0,0) for the image in the topleft.
* plug-in/script-fu/scripts/neon-logo.scm,
perspective-shadow.scm, predator.scm,rendermap.scm,
ripply-anim.scm, select_to_image.scm,swirltile.scm,
xach-effect.scm: updated scripts to use new script-fu stuff
wooo boy! a big un!
in testing this, it looks like some of the po files are busted.
but the code stuff seems okay.
-adrian
1998-10-15 07:23:52 +08:00
|
|
|
|
1998-06-26 16:03:50 +08:00
|
|
|
/* Bezier extensions made by Raphael FRANCOIS (fraph@ibm.net)
|
|
|
|
|
|
|
|
BEZIER_EXTENDS VER 1.0
|
|
|
|
|
|
|
|
- work as the cut/copy/paste named functions.
|
|
|
|
- allow to add/remove/replace bezier curves
|
|
|
|
- allow to modify the control/anchor points even if the selection is made
|
|
|
|
- allow to add/remove control/anchor points on a curve
|
|
|
|
- allow to update a previous saved curve
|
|
|
|
|
|
|
|
- cannot operate on open or multiple curves simultaneously
|
|
|
|
*/
|
1997-11-25 06:05:25 +08:00
|
|
|
|
|
|
|
#define BEZIER_DRAW_CURVE 1
|
|
|
|
#define BEZIER_DRAW_CURRENT 2
|
|
|
|
#define BEZIER_DRAW_HANDLES 4
|
|
|
|
#define BEZIER_DRAW_ALL (BEZIER_DRAW_CURVE | BEZIER_DRAW_HANDLES)
|
|
|
|
|
|
|
|
#define BEZIER_WIDTH 8
|
|
|
|
#define BEZIER_HALFWIDTH 4
|
|
|
|
|
|
|
|
|
|
|
|
#define SUPERSAMPLE 3
|
|
|
|
#define SUPERSAMPLE2 9
|
|
|
|
|
|
|
|
#define NO 0
|
|
|
|
#define YES 1
|
|
|
|
|
1999-04-13 01:55:06 +08:00
|
|
|
/* the bezier select structures */
|
1997-11-25 06:05:25 +08:00
|
|
|
|
|
|
|
typedef double BezierMatrix[4][4];
|
|
|
|
|
1999-04-13 01:55:06 +08:00
|
|
|
/* The named paste dialog */
|
1998-06-26 16:03:50 +08:00
|
|
|
typedef struct _PasteNamedDlg PasteNamedDlg;
|
|
|
|
struct _PasteNamedDlg
|
|
|
|
{
|
|
|
|
GtkWidget *shell;
|
|
|
|
GtkWidget *list;
|
|
|
|
GDisplay *gdisp;
|
|
|
|
};
|
|
|
|
|
1999-04-13 01:55:06 +08:00
|
|
|
/* The named buffer structure... */
|
1998-06-26 16:03:50 +08:00
|
|
|
typedef struct _named_buffer BezierNamedBuffer;
|
|
|
|
struct _named_buffer
|
|
|
|
{
|
|
|
|
BezierSelect *sel;
|
|
|
|
char * name;
|
|
|
|
};
|
|
|
|
|
1999-05-14 06:53:40 +08:00
|
|
|
|
1999-04-06 07:33:50 +08:00
|
|
|
typedef struct {
|
1999-05-14 06:53:40 +08:00
|
|
|
CountCurves curve_count; /* Must be the first element */
|
1999-04-06 07:33:50 +08:00
|
|
|
gdouble *stroke_points;
|
|
|
|
gint num_stroke_points; /* num of valid points */
|
|
|
|
gint len_stroke_points; /* allocated length */
|
1999-05-14 06:53:40 +08:00
|
|
|
void *next_curve; /* Next curve in list -- we draw all curves
|
|
|
|
* separately.
|
|
|
|
*/
|
1999-04-06 07:33:50 +08:00
|
|
|
} BezierRenderPnts;
|
|
|
|
|
|
|
|
typedef struct {
|
1999-05-14 06:53:40 +08:00
|
|
|
CountCurves curve_count; /* Must be the first element */
|
1999-04-06 07:33:50 +08:00
|
|
|
gboolean firstpnt;
|
|
|
|
gdouble curdist;
|
|
|
|
gdouble dist;
|
|
|
|
gdouble *gradient;
|
|
|
|
gint *x;
|
|
|
|
gint *y;
|
|
|
|
gdouble lastx;
|
|
|
|
gdouble lasty;
|
|
|
|
gboolean found;
|
|
|
|
} BezierDistance;
|
|
|
|
|
1999-05-14 06:53:40 +08:00
|
|
|
typedef struct {
|
|
|
|
CountCurves curve_count; /* Must be the first element */
|
|
|
|
gint x;
|
|
|
|
gint y;
|
|
|
|
gint halfwidth;
|
|
|
|
gint found;
|
|
|
|
} BezierCheckPnts;
|
1998-06-26 16:03:50 +08:00
|
|
|
|
1999-04-13 01:55:06 +08:00
|
|
|
/* the bezier selection tool options */
|
|
|
|
static SelectionOptions *bezier_options = NULL;
|
1997-11-25 06:05:25 +08:00
|
|
|
|
1999-04-13 01:55:06 +08:00
|
|
|
/* local variables */
|
1997-11-25 06:05:25 +08:00
|
|
|
static BezierMatrix basis =
|
|
|
|
{
|
|
|
|
{ -1, 3, -3, 1 },
|
|
|
|
{ 3, -6, 3, 0 },
|
|
|
|
{ -3, 3, 0, 0 },
|
|
|
|
{ 1, 0, 0, 0 },
|
|
|
|
};
|
|
|
|
|
1998-06-26 16:03:50 +08:00
|
|
|
/*
|
|
|
|
static BezierMatrix basis =
|
|
|
|
{
|
|
|
|
{ -1/6.0, 3/6.0, -3/6.0, 1/6.0 },
|
|
|
|
{ 3/6.0, -6/6.0, 3/6.0, 0 },
|
|
|
|
{ -3/6.0, 0, 3/6.0, 0 },
|
|
|
|
{ 1/6.0, 4/6.0, 1, 0 },
|
|
|
|
};
|
|
|
|
*/
|
|
|
|
|
|
|
|
/* The named buffer list */
|
|
|
|
GSList *bezier_named_buffers = NULL;
|
1997-11-25 06:05:25 +08:00
|
|
|
|
1999-04-13 01:55:06 +08:00
|
|
|
/* Global Static Variable to maintain informations about the "contexte" */
|
1998-06-26 16:03:50 +08:00
|
|
|
static BezierSelect * curSel;
|
|
|
|
static Tool * curTool;
|
|
|
|
static GDisplay * curGdisp;
|
|
|
|
static DrawCore * curCore;
|
1999-03-06 07:50:24 +08:00
|
|
|
static int ModeEdit = EXTEND_NEW;
|
1998-06-26 16:03:50 +08:00
|
|
|
|
1997-11-25 06:05:25 +08:00
|
|
|
|
1999-04-13 01:55:06 +08:00
|
|
|
/* local function prototypes */
|
|
|
|
static void bezier_select_button_press (Tool *, GdkEventButton *, gpointer);
|
|
|
|
static void bezier_select_button_release (Tool *, GdkEventButton *, gpointer);
|
|
|
|
static void bezier_select_motion (Tool *, GdkEventMotion *, gpointer);
|
1999-06-22 06:12:07 +08:00
|
|
|
static void bezier_select_control (Tool *, ToolAction, gpointer);
|
1999-05-14 06:53:40 +08:00
|
|
|
static void bezier_select_cursor_update (Tool *, GdkEventMotion *, gpointer);
|
1999-04-13 01:55:06 +08:00
|
|
|
static void bezier_select_draw (Tool *);
|
|
|
|
|
|
|
|
static void bezier_offset_point (BezierPoint *, int, int);
|
|
|
|
static int bezier_check_point (BezierPoint *, int, int, int);
|
1999-05-27 04:36:33 +08:00
|
|
|
static void bezier_draw_handles (BezierSelect *, gint);
|
1999-04-13 01:55:06 +08:00
|
|
|
static void bezier_draw_current (BezierSelect *);
|
|
|
|
static void bezier_draw_point (BezierSelect *, BezierPoint *, int);
|
|
|
|
static void bezier_draw_line (BezierSelect *, BezierPoint *, BezierPoint *);
|
|
|
|
static void bezier_draw_segment (BezierSelect *, BezierPoint *, int, int, BezierPointsFunc,gpointer);
|
|
|
|
static void bezier_draw_segment_points (BezierSelect *, GdkPoint *, int, gpointer);
|
|
|
|
static void bezier_compose (BezierMatrix, BezierMatrix, BezierMatrix);
|
|
|
|
|
|
|
|
static void bezier_convert (BezierSelect *, GDisplay *, int, int);
|
|
|
|
static void bezier_convert_points (BezierSelect *, GdkPoint *, int, gpointer);
|
|
|
|
static void bezier_convert_line (GSList **, int, int, int, int);
|
|
|
|
static GSList * bezier_insert_in_list (GSList *, int);
|
|
|
|
|
|
|
|
static int test_add_point_on_segment (BezierSelect *, BezierPoint *, int, int, int, int, int);
|
|
|
|
static void bezier_to_sel_internal (BezierSelect *, Tool *, GDisplay *, gint, gint);
|
|
|
|
static void bezier_stack_points (BezierSelect *, GdkPoint *, int, gpointer);
|
|
|
|
static gboolean stroke_interpolatable (int, int, int, int, gdouble);
|
|
|
|
static void bezier_stack_points_aux (GdkPoint *, int, int, gdouble, BezierRenderPnts *);
|
1999-05-14 06:53:40 +08:00
|
|
|
static gint count_points_on_curve(BezierPoint *);
|
1999-04-13 01:55:06 +08:00
|
|
|
|
|
|
|
|
|
|
|
/* functions */
|
|
|
|
|
1999-04-09 06:25:54 +08:00
|
|
|
static void
|
1999-04-13 01:55:06 +08:00
|
|
|
bezier_select_options_reset ()
|
1999-04-09 06:25:54 +08:00
|
|
|
{
|
1999-04-13 01:55:06 +08:00
|
|
|
selection_options_reset (bezier_options);
|
1999-04-09 06:25:54 +08:00
|
|
|
}
|
|
|
|
|
1997-11-25 06:05:25 +08:00
|
|
|
Tool*
|
|
|
|
tools_new_bezier_select ()
|
|
|
|
{
|
|
|
|
Tool * tool;
|
1999-06-26 19:16:47 +08:00
|
|
|
BezierSelect * private;
|
1997-11-25 06:05:25 +08:00
|
|
|
|
|
|
|
/* The tool options */
|
1999-04-13 01:55:06 +08:00
|
|
|
if (! bezier_options)
|
|
|
|
{
|
|
|
|
bezier_options =
|
|
|
|
selection_options_new (BEZIER_SELECT, bezier_select_options_reset);
|
|
|
|
tools_register (BEZIER_SELECT, (ToolOptions *) bezier_options);
|
|
|
|
}
|
1997-11-25 06:05:25 +08:00
|
|
|
|
1999-07-03 01:40:10 +08:00
|
|
|
|
|
|
|
tool = tools_new_tool (BEZIER_SELECT);
|
|
|
|
private = g_new (BezierSelect, 1);
|
1997-11-25 06:05:25 +08:00
|
|
|
|
1999-06-26 19:16:47 +08:00
|
|
|
private->num_points = 0;
|
|
|
|
private->mask = NULL;
|
|
|
|
private->core = draw_core_new (bezier_select_draw);
|
|
|
|
bezier_select_reset (private);
|
1997-11-25 06:05:25 +08:00
|
|
|
|
1999-07-03 01:40:10 +08:00
|
|
|
tool->scroll_lock = TRUE; /* Disallow scrolling */
|
|
|
|
tool->preserve = FALSE; /* Don't preserve on drawable change */
|
1999-06-26 19:16:47 +08:00
|
|
|
|
1999-07-03 01:40:10 +08:00
|
|
|
tool->private = (void *) private;
|
1999-06-26 19:16:47 +08:00
|
|
|
|
1999-07-03 01:40:10 +08:00
|
|
|
tool->button_press_func = bezier_select_button_press;
|
1997-11-25 06:05:25 +08:00
|
|
|
tool->button_release_func = bezier_select_button_release;
|
1999-07-03 01:40:10 +08:00
|
|
|
tool->motion_func = bezier_select_motion;
|
|
|
|
tool->cursor_update_func = bezier_select_cursor_update;
|
|
|
|
tool->control_func = bezier_select_control;
|
1997-11-25 06:05:25 +08:00
|
|
|
|
1999-06-26 19:16:47 +08:00
|
|
|
curCore = private->core;
|
|
|
|
curSel = private;
|
1999-03-06 07:50:24 +08:00
|
|
|
curTool = tool;
|
|
|
|
|
1999-06-26 19:16:47 +08:00
|
|
|
paths_new_bezier_select_tool ();
|
1998-06-26 16:03:50 +08:00
|
|
|
|
1997-11-25 06:05:25 +08:00
|
|
|
return tool;
|
|
|
|
}
|
|
|
|
|
|
|
|
void
|
|
|
|
tools_free_bezier_select (Tool *tool)
|
|
|
|
{
|
|
|
|
BezierSelect * bezier_sel;
|
|
|
|
|
|
|
|
bezier_sel = tool->private;
|
|
|
|
|
|
|
|
if (tool->state == ACTIVE)
|
|
|
|
draw_core_stop (bezier_sel->core, tool);
|
|
|
|
draw_core_free (bezier_sel->core);
|
|
|
|
|
|
|
|
bezier_select_reset (bezier_sel);
|
|
|
|
|
|
|
|
g_free (bezier_sel);
|
|
|
|
}
|
|
|
|
|
|
|
|
int
|
|
|
|
bezier_select_load (void *gdisp_ptr,
|
|
|
|
BezierPoint *pts,
|
|
|
|
int num_pts,
|
|
|
|
int closed)
|
|
|
|
{
|
|
|
|
GDisplay * gdisp;
|
|
|
|
Tool * tool;
|
|
|
|
BezierSelect * bezier_sel;
|
|
|
|
|
|
|
|
gdisp = (GDisplay *) gdisp_ptr;
|
|
|
|
|
|
|
|
/* select the bezier tool */
|
1999-10-30 18:39:48 +08:00
|
|
|
gimp_context_set_tool (gimp_context_get_user (), BEZIER_SELECT);
|
1997-11-25 06:05:25 +08:00
|
|
|
tool = active_tool;
|
|
|
|
tool->state = ACTIVE;
|
|
|
|
tool->gdisp_ptr = gdisp_ptr;
|
|
|
|
bezier_sel = (BezierSelect *) tool->private;
|
|
|
|
|
|
|
|
bezier_sel->points = pts;
|
|
|
|
bezier_sel->last_point = pts->prev;
|
|
|
|
bezier_sel->num_points = num_pts;
|
|
|
|
bezier_sel->closed = closed;
|
|
|
|
bezier_sel->state = BEZIER_EDIT;
|
|
|
|
bezier_sel->draw = BEZIER_DRAW_ALL;
|
|
|
|
|
|
|
|
bezier_convert (bezier_sel, tool->gdisp_ptr, SUBDIVIDE, NO);
|
|
|
|
|
|
|
|
draw_core_start (bezier_sel->core, gdisp->canvas->window, tool);
|
|
|
|
|
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
|
1999-05-14 06:53:40 +08:00
|
|
|
static BezierPoint *
|
|
|
|
valid_curve_segment(BezierPoint *points)
|
|
|
|
{
|
|
|
|
/* Valid curve segment is made up of four points */
|
|
|
|
if(points &&
|
|
|
|
points->next &&
|
|
|
|
points->next->next &&
|
|
|
|
points->next->next->next )
|
|
|
|
return(points);
|
|
|
|
|
|
|
|
return (NULL);
|
|
|
|
}
|
|
|
|
|
|
|
|
static BezierPoint *
|
|
|
|
next_anchor(BezierPoint *points,BezierPoint **next_curve)
|
|
|
|
{
|
|
|
|
int loop;
|
|
|
|
|
|
|
|
*next_curve = NULL;
|
|
|
|
|
|
|
|
if(!points)
|
|
|
|
return (NULL);
|
|
|
|
|
|
|
|
for(loop = 0; loop < 3; loop++)
|
|
|
|
{
|
|
|
|
points = points->next;
|
|
|
|
if (!points)
|
|
|
|
return (NULL);
|
|
|
|
if(points->next_curve)
|
|
|
|
{
|
|
|
|
*next_curve = points->next_curve;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return valid_curve_segment(points);
|
|
|
|
}
|
|
|
|
|
1999-03-06 07:50:24 +08:00
|
|
|
void
|
1999-04-06 07:33:50 +08:00
|
|
|
bezier_draw_curve (BezierSelect *bezier_sel,
|
|
|
|
BezierPointsFunc func,
|
|
|
|
gint coord,
|
|
|
|
gpointer udata)
|
1999-03-06 07:50:24 +08:00
|
|
|
{
|
|
|
|
BezierPoint * points;
|
|
|
|
BezierPoint * start_pt;
|
1999-05-14 06:53:40 +08:00
|
|
|
BezierPoint * next_curve;
|
|
|
|
CountCurves * cnt = (CountCurves *)udata;
|
|
|
|
gint point_counts = 0;
|
1999-03-06 07:50:24 +08:00
|
|
|
|
1999-05-14 06:53:40 +08:00
|
|
|
/* printSel(bezier_sel); */
|
|
|
|
|
|
|
|
if(cnt)
|
|
|
|
cnt->count = 0;
|
1999-03-06 07:50:24 +08:00
|
|
|
points = bezier_sel->points;
|
1999-05-14 06:53:40 +08:00
|
|
|
start_pt = bezier_sel->points;
|
1999-03-06 07:50:24 +08:00
|
|
|
|
1999-05-14 06:53:40 +08:00
|
|
|
if(bezier_sel->num_points >= 4)
|
1999-03-06 07:50:24 +08:00
|
|
|
{
|
|
|
|
do {
|
1999-05-14 06:53:40 +08:00
|
|
|
point_counts = count_points_on_curve(points);
|
|
|
|
if(point_counts >= 4)
|
|
|
|
{
|
|
|
|
do {
|
|
|
|
bezier_draw_segment (bezier_sel, points,
|
|
|
|
SUBDIVIDE, coord,
|
|
|
|
func,
|
|
|
|
udata);
|
|
|
|
|
|
|
|
points = next_anchor(points,&next_curve);
|
new ui for the "Layer Offset" dialog.
1999-07-22 Michael Natterer <mitschel@cs.tu-berlin.de>
* app/channel_ops.[ch]: new ui for the "Layer Offset" dialog.
* app/channels_dialog.c
* app/layers_dialog.c: major code cleanup: Folded some callbacks
into common ones, "widget" instead of "w", indentation, ...
* app/commands.c
* app/interface.[ch]
* app/global_edit.c: the query boxes must be shown by the caller
now. There's no need to split up the string for the message box
manually as the Gtk 1.2 label widget handles newlines corectly.
Added the "edge_lock" toggle to the "Shrink Selection" dialog.
Nicer spacings for the query and message boxes.
* app/ink.c: tried to grab the pointer in the blob preview but
failed. Left the code there as a reminder (commented out).
* app/menus.c: reordered <Image>/Select.
I was bored and grep-ed the sources for ancient or deprecated stuff:
* app/about_dialog.[ch]
* app/actionarea.[ch]
* app/app_procs.c
* app/brush_edit.c
* app/brush_select.c
* app/color_select.c
* app/convert.c
* app/devices.c
* app/gdisplay.c
* app/gdisplay_ops.c
* app/histogram_tool.[ch]
* app/info_window.c
* app/install.c
* app/ops_buttons.c
* app/palette.c
* app/palette_select.c
* app/paths_dialog.c
* app/pattern_select.c
* app/resize.c
* app/scale_toolc.c
* app/text_tool.c:
s/container_border_width/container_set_border_width/g,
s/sprintf/g_snprintf/g, replaced some constant string lengths with
strlen(x).
* app/bezier_select.c
* app/blend.c
* app/boundary.c
* app/errors.[ch]
* app/free_select.c
* app/gimpbrushlist.c
* app/gimprc.c
* app/iscissors.c
* app/main.c
* app/patterns.[ch]
* app/text_tool.c: namespace fanaticism: prefixed all gimp error
functions with "gimp_" and formated the messages more uniformly.
* app/gradient.c
* app/gradient_select.c: same stuff as above for the ui
code. There are still some sub-dialogs which need cleanup.
Did some cleanup in most of these files: prototypes, removed tons
of #include's, i18n fixes, s/w/widget/ as above, indentation, ...
1999-07-23 00:21:10 +08:00
|
|
|
/* g_print ("next_anchor = %p\n",points); */
|
1999-05-14 06:53:40 +08:00
|
|
|
} while (points != start_pt && points);
|
|
|
|
if(cnt)
|
|
|
|
cnt->count++;
|
|
|
|
start_pt = next_curve;
|
|
|
|
points = next_curve;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
break; /* must be last curve since only this one is allowed < 4
|
|
|
|
* points.
|
|
|
|
*/
|
|
|
|
} while(next_curve);
|
1999-03-06 07:50:24 +08:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
void
|
1997-11-25 06:05:25 +08:00
|
|
|
bezier_select_reset (BezierSelect *bezier_sel)
|
|
|
|
{
|
|
|
|
BezierPoint * points;
|
|
|
|
BezierPoint * start_pt;
|
|
|
|
BezierPoint * temp_pt;
|
1999-05-14 06:53:40 +08:00
|
|
|
BezierPoint * next_curve;
|
1997-11-25 06:05:25 +08:00
|
|
|
|
|
|
|
if (bezier_sel->num_points > 0)
|
|
|
|
{
|
|
|
|
points = bezier_sel->points;
|
1999-05-14 06:53:40 +08:00
|
|
|
start_pt = bezier_sel->points;
|
1997-11-25 06:05:25 +08:00
|
|
|
|
|
|
|
do {
|
1999-05-14 06:53:40 +08:00
|
|
|
do {
|
|
|
|
temp_pt = points;
|
|
|
|
next_curve = points->next_curve;
|
|
|
|
points = points->next;
|
|
|
|
if(points != start_pt && next_curve)
|
|
|
|
{
|
|
|
|
g_warning("Curve points out of sync");
|
|
|
|
}
|
|
|
|
g_free (temp_pt);
|
|
|
|
} while (points != start_pt && points);
|
|
|
|
points = next_curve;
|
|
|
|
start_pt = next_curve;
|
|
|
|
} while (next_curve);
|
1997-11-25 06:05:25 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
if (bezier_sel->mask)
|
|
|
|
channel_delete (bezier_sel->mask);
|
|
|
|
|
|
|
|
bezier_sel->state = BEZIER_START; /* we are starting the curve */
|
|
|
|
bezier_sel->draw = BEZIER_DRAW_ALL; /* draw everything by default */
|
|
|
|
bezier_sel->closed = 0; /* the curve is initally open */
|
|
|
|
bezier_sel->points = NULL; /* initially there are no points */
|
|
|
|
bezier_sel->cur_anchor = NULL;
|
|
|
|
bezier_sel->cur_control = NULL;
|
|
|
|
bezier_sel->last_point = NULL;
|
|
|
|
bezier_sel->num_points = 0; /* intially there are no points */
|
|
|
|
bezier_sel->mask = NULL; /* empty mask */
|
|
|
|
bezier_sel->scanlines = NULL;
|
|
|
|
}
|
|
|
|
|
1999-05-14 06:53:40 +08:00
|
|
|
/* Find the curve that points to this curve. This makes to_check point
|
|
|
|
* the start of a curve.
|
|
|
|
*/
|
|
|
|
static BezierPoint *
|
|
|
|
check_for_next_curve(BezierSelect *bezier_sel,
|
|
|
|
BezierPoint *to_check)
|
|
|
|
{
|
|
|
|
BezierPoint *points = bezier_sel->points;
|
|
|
|
gint num_points = bezier_sel->num_points;
|
|
|
|
|
|
|
|
while (points && num_points)
|
|
|
|
{
|
|
|
|
if(points->next_curve == to_check)
|
|
|
|
return (points);
|
|
|
|
|
|
|
|
if(points->next_curve)
|
|
|
|
points = points->next_curve;
|
|
|
|
else
|
|
|
|
points = points->next;
|
|
|
|
num_points--;
|
|
|
|
}
|
|
|
|
return (NULL);
|
|
|
|
}
|
|
|
|
|
|
|
|
static gint
|
|
|
|
count_points_on_curve(BezierPoint *points)
|
|
|
|
{
|
|
|
|
BezierPoint *start = points;
|
|
|
|
gint count = 0;
|
|
|
|
|
|
|
|
while(points && points->next != start)
|
|
|
|
{
|
|
|
|
points = points->next;
|
|
|
|
count++;
|
|
|
|
}
|
|
|
|
|
|
|
|
return (count);
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Find the start of the last open curve, if curve already closed
|
|
|
|
* this is an error..
|
|
|
|
*/
|
|
|
|
|
|
|
|
static BezierPoint *
|
|
|
|
find_start_open_curve(BezierSelect *bsel)
|
|
|
|
{
|
|
|
|
BezierPoint *start_pnt = NULL;
|
|
|
|
BezierPoint *this_pnt = bsel->last_point;
|
|
|
|
|
|
|
|
/* Could be one of the first points */
|
|
|
|
if(!bsel->last_point)
|
|
|
|
{
|
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
|
|
|
|
if(bsel->closed)
|
|
|
|
{
|
|
|
|
g_message(_("Bezier path already closed."));
|
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Step backwards until the prev point is null.
|
|
|
|
* in this case this is the start of the open curve.
|
|
|
|
* The start_pnt stuff is to stop us going around forever.
|
|
|
|
* If we even have a closed curve then we are in seroius
|
|
|
|
* trouble.
|
|
|
|
*/
|
|
|
|
|
|
|
|
while(this_pnt->prev && start_pnt != this_pnt)
|
|
|
|
{
|
|
|
|
if(!start_pnt)
|
|
|
|
start_pnt = this_pnt;
|
|
|
|
this_pnt = this_pnt->prev;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Must be an anchor to be the start */
|
|
|
|
if(start_pnt == this_pnt || this_pnt->type != BEZIER_ANCHOR)
|
|
|
|
{
|
|
|
|
g_message(_("Corrupt curve"));
|
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
|
new ui for the "Layer Offset" dialog.
1999-07-22 Michael Natterer <mitschel@cs.tu-berlin.de>
* app/channel_ops.[ch]: new ui for the "Layer Offset" dialog.
* app/channels_dialog.c
* app/layers_dialog.c: major code cleanup: Folded some callbacks
into common ones, "widget" instead of "w", indentation, ...
* app/commands.c
* app/interface.[ch]
* app/global_edit.c: the query boxes must be shown by the caller
now. There's no need to split up the string for the message box
manually as the Gtk 1.2 label widget handles newlines corectly.
Added the "edge_lock" toggle to the "Shrink Selection" dialog.
Nicer spacings for the query and message boxes.
* app/ink.c: tried to grab the pointer in the blob preview but
failed. Left the code there as a reminder (commented out).
* app/menus.c: reordered <Image>/Select.
I was bored and grep-ed the sources for ancient or deprecated stuff:
* app/about_dialog.[ch]
* app/actionarea.[ch]
* app/app_procs.c
* app/brush_edit.c
* app/brush_select.c
* app/color_select.c
* app/convert.c
* app/devices.c
* app/gdisplay.c
* app/gdisplay_ops.c
* app/histogram_tool.[ch]
* app/info_window.c
* app/install.c
* app/ops_buttons.c
* app/palette.c
* app/palette_select.c
* app/paths_dialog.c
* app/pattern_select.c
* app/resize.c
* app/scale_toolc.c
* app/text_tool.c:
s/container_border_width/container_set_border_width/g,
s/sprintf/g_snprintf/g, replaced some constant string lengths with
strlen(x).
* app/bezier_select.c
* app/blend.c
* app/boundary.c
* app/errors.[ch]
* app/free_select.c
* app/gimpbrushlist.c
* app/gimprc.c
* app/iscissors.c
* app/main.c
* app/patterns.[ch]
* app/text_tool.c: namespace fanaticism: prefixed all gimp error
functions with "gimp_" and formated the messages more uniformly.
* app/gradient.c
* app/gradient_select.c: same stuff as above for the ui
code. There are still some sub-dialogs which need cleanup.
Did some cleanup in most of these files: prototypes, removed tons
of #include's, i18n fixes, s/w/widget/ as above, indentation, ...
1999-07-23 00:21:10 +08:00
|
|
|
/* g_print ("Returned start pnt of curve %p is %p\n",bsel->last_point,this_pnt); */
|
1999-05-14 06:53:40 +08:00
|
|
|
return (this_pnt);
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Delete a whole curve. Watch out for special cases.
|
|
|
|
* start_pnt must always be the start point if the curve to delete.
|
|
|
|
*/
|
|
|
|
|
|
|
|
static void
|
|
|
|
delete_whole_curve(BezierSelect *bezier_sel,
|
|
|
|
BezierPoint *start_pnt)
|
|
|
|
{
|
|
|
|
BezierPoint *tmppnt;
|
|
|
|
BezierPoint *next_curve = NULL; /* Next curve this one
|
|
|
|
* points at (if any)
|
|
|
|
*/
|
|
|
|
BezierPoint *prev_curve; /* Does a curve point to this one? */
|
|
|
|
gint cnt_pnts = 0; /* Count how many pnts deleted */
|
|
|
|
gint reset_last = FALSE;
|
|
|
|
|
|
|
|
/* shift and del means delete whole curve */
|
|
|
|
/* Three cases, this is first curve, middle curve
|
|
|
|
* or end curve.
|
|
|
|
*/
|
|
|
|
|
|
|
|
/* Does this curve have another chained on the end?
|
|
|
|
* or is this curve pointed to another one?
|
|
|
|
*/
|
|
|
|
|
new ui for the "Layer Offset" dialog.
1999-07-22 Michael Natterer <mitschel@cs.tu-berlin.de>
* app/channel_ops.[ch]: new ui for the "Layer Offset" dialog.
* app/channels_dialog.c
* app/layers_dialog.c: major code cleanup: Folded some callbacks
into common ones, "widget" instead of "w", indentation, ...
* app/commands.c
* app/interface.[ch]
* app/global_edit.c: the query boxes must be shown by the caller
now. There's no need to split up the string for the message box
manually as the Gtk 1.2 label widget handles newlines corectly.
Added the "edge_lock" toggle to the "Shrink Selection" dialog.
Nicer spacings for the query and message boxes.
* app/ink.c: tried to grab the pointer in the blob preview but
failed. Left the code there as a reminder (commented out).
* app/menus.c: reordered <Image>/Select.
I was bored and grep-ed the sources for ancient or deprecated stuff:
* app/about_dialog.[ch]
* app/actionarea.[ch]
* app/app_procs.c
* app/brush_edit.c
* app/brush_select.c
* app/color_select.c
* app/convert.c
* app/devices.c
* app/gdisplay.c
* app/gdisplay_ops.c
* app/histogram_tool.[ch]
* app/info_window.c
* app/install.c
* app/ops_buttons.c
* app/palette.c
* app/palette_select.c
* app/paths_dialog.c
* app/pattern_select.c
* app/resize.c
* app/scale_toolc.c
* app/text_tool.c:
s/container_border_width/container_set_border_width/g,
s/sprintf/g_snprintf/g, replaced some constant string lengths with
strlen(x).
* app/bezier_select.c
* app/blend.c
* app/boundary.c
* app/errors.[ch]
* app/free_select.c
* app/gimpbrushlist.c
* app/gimprc.c
* app/iscissors.c
* app/main.c
* app/patterns.[ch]
* app/text_tool.c: namespace fanaticism: prefixed all gimp error
functions with "gimp_" and formated the messages more uniformly.
* app/gradient.c
* app/gradient_select.c: same stuff as above for the ui
code. There are still some sub-dialogs which need cleanup.
Did some cleanup in most of these files: prototypes, removed tons
of #include's, i18n fixes, s/w/widget/ as above, indentation, ...
1999-07-23 00:21:10 +08:00
|
|
|
/* g_print ("delete_whole_curve::\n"); */
|
1999-05-14 06:53:40 +08:00
|
|
|
|
|
|
|
tmppnt = start_pnt;
|
|
|
|
do {
|
|
|
|
if(tmppnt->next_curve)
|
|
|
|
{
|
|
|
|
next_curve = tmppnt->next_curve;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
tmppnt = tmppnt->next;
|
|
|
|
} while (tmppnt != start_pnt && tmppnt);
|
|
|
|
|
|
|
|
prev_curve = check_for_next_curve(bezier_sel,start_pnt);
|
|
|
|
|
|
|
|
/* First curve ?*/
|
|
|
|
if(bezier_sel->points == start_pnt)
|
|
|
|
bezier_sel->points = next_curve;
|
|
|
|
else
|
|
|
|
{
|
|
|
|
/* better have a previous curve else how did we get here? */
|
|
|
|
prev_curve->next_curve = next_curve;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* start_pnt points to the curve we should free .. ignoring the next_curve */
|
|
|
|
|
|
|
|
tmppnt = start_pnt;
|
|
|
|
do {
|
|
|
|
BezierPoint *fpnt;
|
|
|
|
fpnt = tmppnt;
|
|
|
|
tmppnt = tmppnt->next;
|
|
|
|
if(fpnt == bezier_sel->last_point)
|
|
|
|
reset_last = TRUE;
|
|
|
|
g_free (fpnt);
|
|
|
|
cnt_pnts++;
|
|
|
|
} while (tmppnt != start_pnt && tmppnt);
|
|
|
|
|
|
|
|
bezier_sel->num_points -= cnt_pnts;
|
|
|
|
|
|
|
|
/* if deleted curve was unclosed then must have been the last curve
|
|
|
|
* and thus this curve becomes closed.
|
|
|
|
*/
|
|
|
|
if(!tmppnt && bezier_sel->num_points > 0)
|
|
|
|
{
|
|
|
|
bezier_sel->closed = 1;
|
|
|
|
bezier_sel->state = BEZIER_EDIT;
|
|
|
|
}
|
|
|
|
|
|
|
|
if(bezier_sel->num_points <= 0)
|
|
|
|
{
|
|
|
|
bezier_select_reset(bezier_sel);
|
|
|
|
}
|
|
|
|
|
|
|
|
bezier_sel->cur_anchor = NULL;
|
|
|
|
bezier_sel->cur_control = NULL;
|
|
|
|
|
|
|
|
/* The last point could have been on this curve as well... */
|
|
|
|
if(reset_last)
|
|
|
|
{
|
|
|
|
BezierPoint *points = bezier_sel->points;
|
|
|
|
BezierPoint *l_pnt = NULL;
|
|
|
|
gint num_points = bezier_sel->num_points;
|
|
|
|
|
|
|
|
while (points && num_points)
|
|
|
|
{
|
|
|
|
l_pnt = points;
|
|
|
|
if(points->next_curve)
|
|
|
|
points = points->next_curve;
|
|
|
|
else
|
|
|
|
points = points->next;
|
|
|
|
num_points--;
|
|
|
|
}
|
|
|
|
bezier_sel->last_point = l_pnt;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
1999-03-06 07:50:24 +08:00
|
|
|
static gint
|
1999-05-14 06:53:40 +08:00
|
|
|
bezier_edit_point_on_curve(int x,
|
|
|
|
int y,
|
|
|
|
int halfwidth,
|
|
|
|
GDisplay *gdisp,
|
|
|
|
BezierSelect *bezier_sel,
|
|
|
|
Tool *tool,
|
|
|
|
GdkEventButton *bevent)
|
1999-03-06 07:50:24 +08:00
|
|
|
{
|
|
|
|
gint grab_pointer = 0;
|
1999-05-14 06:53:40 +08:00
|
|
|
BezierPoint *next_curve;
|
1999-03-06 07:50:24 +08:00
|
|
|
BezierPoint *points = bezier_sel->points;
|
|
|
|
BezierPoint *start_pt = bezier_sel->points;
|
1999-05-14 06:53:40 +08:00
|
|
|
gint point_counts = 0;
|
1999-03-06 07:50:24 +08:00
|
|
|
|
|
|
|
/* find if the button press occurred on a point */
|
|
|
|
do {
|
1999-05-14 06:53:40 +08:00
|
|
|
point_counts = count_points_on_curve(points);
|
|
|
|
do {
|
|
|
|
if (bezier_check_point (points, x, y, halfwidth))
|
|
|
|
{
|
1999-03-06 07:50:24 +08:00
|
|
|
BezierPoint *finded=points;
|
|
|
|
BezierPoint *start_op;
|
|
|
|
BezierPoint *end_op;
|
|
|
|
|
|
|
|
if (ModeEdit== EXTEND_REMOVE)
|
|
|
|
{
|
1999-05-27 04:36:33 +08:00
|
|
|
|
|
|
|
if(bevent->state & GDK_SHIFT_MASK)
|
|
|
|
{
|
|
|
|
delete_whole_curve(bezier_sel,start_pt);
|
|
|
|
}
|
|
|
|
else if (point_counts <= 7)
|
1999-03-06 07:50:24 +08:00
|
|
|
{
|
|
|
|
/* If we've got less then 7 points ie: 2 anchors points 4 controls
|
|
|
|
Then the curve is minimal closed curve.
|
|
|
|
I've decided to not operate on this kind of curve because it
|
|
|
|
implies opening the curve and change some drawing states
|
|
|
|
Removing 1 point of curve that contains 2 point is something
|
|
|
|
similare to reconstruct the curve !!!
|
|
|
|
*/
|
1999-05-14 06:53:40 +08:00
|
|
|
return(0);
|
1999-03-06 07:50:24 +08:00
|
|
|
}
|
1999-05-14 06:53:40 +08:00
|
|
|
else if(!finded->prev || !finded->prev->prev)
|
1999-03-06 07:50:24 +08:00
|
|
|
{
|
|
|
|
/* This is the first point on the curve */
|
new ui for the "Layer Offset" dialog.
1999-07-22 Michael Natterer <mitschel@cs.tu-berlin.de>
* app/channel_ops.[ch]: new ui for the "Layer Offset" dialog.
* app/channels_dialog.c
* app/layers_dialog.c: major code cleanup: Folded some callbacks
into common ones, "widget" instead of "w", indentation, ...
* app/commands.c
* app/interface.[ch]
* app/global_edit.c: the query boxes must be shown by the caller
now. There's no need to split up the string for the message box
manually as the Gtk 1.2 label widget handles newlines corectly.
Added the "edge_lock" toggle to the "Shrink Selection" dialog.
Nicer spacings for the query and message boxes.
* app/ink.c: tried to grab the pointer in the blob preview but
failed. Left the code there as a reminder (commented out).
* app/menus.c: reordered <Image>/Select.
I was bored and grep-ed the sources for ancient or deprecated stuff:
* app/about_dialog.[ch]
* app/actionarea.[ch]
* app/app_procs.c
* app/brush_edit.c
* app/brush_select.c
* app/color_select.c
* app/convert.c
* app/devices.c
* app/gdisplay.c
* app/gdisplay_ops.c
* app/histogram_tool.[ch]
* app/info_window.c
* app/install.c
* app/ops_buttons.c
* app/palette.c
* app/palette_select.c
* app/paths_dialog.c
* app/pattern_select.c
* app/resize.c
* app/scale_toolc.c
* app/text_tool.c:
s/container_border_width/container_set_border_width/g,
s/sprintf/g_snprintf/g, replaced some constant string lengths with
strlen(x).
* app/bezier_select.c
* app/blend.c
* app/boundary.c
* app/errors.[ch]
* app/free_select.c
* app/gimpbrushlist.c
* app/gimprc.c
* app/iscissors.c
* app/main.c
* app/patterns.[ch]
* app/text_tool.c: namespace fanaticism: prefixed all gimp error
functions with "gimp_" and formated the messages more uniformly.
* app/gradient.c
* app/gradient_select.c: same stuff as above for the ui
code. There are still some sub-dialogs which need cleanup.
Did some cleanup in most of these files: prototypes, removed tons
of #include's, i18n fixes, s/w/widget/ as above, indentation, ...
1999-07-23 00:21:10 +08:00
|
|
|
/* FIXME g_print ("Del first point\n"); */
|
1999-03-06 07:50:24 +08:00
|
|
|
}
|
|
|
|
else if(!bezier_sel->closed &&
|
|
|
|
(finded == bezier_sel->last_point ||
|
|
|
|
finded == bezier_sel->last_point->prev ||
|
|
|
|
finded == bezier_sel->last_point->prev->prev))
|
|
|
|
{
|
|
|
|
/* This is the last point on the curve */
|
new ui for the "Layer Offset" dialog.
1999-07-22 Michael Natterer <mitschel@cs.tu-berlin.de>
* app/channel_ops.[ch]: new ui for the "Layer Offset" dialog.
* app/channels_dialog.c
* app/layers_dialog.c: major code cleanup: Folded some callbacks
into common ones, "widget" instead of "w", indentation, ...
* app/commands.c
* app/interface.[ch]
* app/global_edit.c: the query boxes must be shown by the caller
now. There's no need to split up the string for the message box
manually as the Gtk 1.2 label widget handles newlines corectly.
Added the "edge_lock" toggle to the "Shrink Selection" dialog.
Nicer spacings for the query and message boxes.
* app/ink.c: tried to grab the pointer in the blob preview but
failed. Left the code there as a reminder (commented out).
* app/menus.c: reordered <Image>/Select.
I was bored and grep-ed the sources for ancient or deprecated stuff:
* app/about_dialog.[ch]
* app/actionarea.[ch]
* app/app_procs.c
* app/brush_edit.c
* app/brush_select.c
* app/color_select.c
* app/convert.c
* app/devices.c
* app/gdisplay.c
* app/gdisplay_ops.c
* app/histogram_tool.[ch]
* app/info_window.c
* app/install.c
* app/ops_buttons.c
* app/palette.c
* app/palette_select.c
* app/paths_dialog.c
* app/pattern_select.c
* app/resize.c
* app/scale_toolc.c
* app/text_tool.c:
s/container_border_width/container_set_border_width/g,
s/sprintf/g_snprintf/g, replaced some constant string lengths with
strlen(x).
* app/bezier_select.c
* app/blend.c
* app/boundary.c
* app/errors.[ch]
* app/free_select.c
* app/gimpbrushlist.c
* app/gimprc.c
* app/iscissors.c
* app/main.c
* app/patterns.[ch]
* app/text_tool.c: namespace fanaticism: prefixed all gimp error
functions with "gimp_" and formated the messages more uniformly.
* app/gradient.c
* app/gradient_select.c: same stuff as above for the ui
code. There are still some sub-dialogs which need cleanup.
Did some cleanup in most of these files: prototypes, removed tons
of #include's, i18n fixes, s/w/widget/ as above, indentation, ...
1999-07-23 00:21:10 +08:00
|
|
|
/* FIXME g_print ("Del last point\n"); */
|
1999-03-06 07:50:24 +08:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
if ( finded->type == BEZIER_CONTROL )
|
|
|
|
{
|
|
|
|
if (finded->next->type == BEZIER_CONTROL)
|
|
|
|
finded = finded->prev;
|
|
|
|
else
|
|
|
|
finded = finded->next;
|
|
|
|
}
|
|
|
|
|
|
|
|
start_op = finded->prev->prev;
|
|
|
|
end_op = finded->next->next;
|
1999-05-14 06:53:40 +08:00
|
|
|
|
|
|
|
/* we can use next_curve here since we are going to
|
|
|
|
* drop out the bottom anyways.
|
|
|
|
*/
|
|
|
|
next_curve =
|
|
|
|
check_for_next_curve(bezier_sel,finded);
|
|
|
|
|
|
|
|
if(next_curve)
|
|
|
|
{
|
|
|
|
/* Deleteing first point of next curve*/
|
|
|
|
next_curve->next_curve = finded->prev->prev->prev;
|
|
|
|
}
|
|
|
|
else /* Can't be both first and a next curve!*/
|
|
|
|
{
|
|
|
|
if (bezier_sel->points == finded)
|
|
|
|
{
|
new ui for the "Layer Offset" dialog.
1999-07-22 Michael Natterer <mitschel@cs.tu-berlin.de>
* app/channel_ops.[ch]: new ui for the "Layer Offset" dialog.
* app/channels_dialog.c
* app/layers_dialog.c: major code cleanup: Folded some callbacks
into common ones, "widget" instead of "w", indentation, ...
* app/commands.c
* app/interface.[ch]
* app/global_edit.c: the query boxes must be shown by the caller
now. There's no need to split up the string for the message box
manually as the Gtk 1.2 label widget handles newlines corectly.
Added the "edge_lock" toggle to the "Shrink Selection" dialog.
Nicer spacings for the query and message boxes.
* app/ink.c: tried to grab the pointer in the blob preview but
failed. Left the code there as a reminder (commented out).
* app/menus.c: reordered <Image>/Select.
I was bored and grep-ed the sources for ancient or deprecated stuff:
* app/about_dialog.[ch]
* app/actionarea.[ch]
* app/app_procs.c
* app/brush_edit.c
* app/brush_select.c
* app/color_select.c
* app/convert.c
* app/devices.c
* app/gdisplay.c
* app/gdisplay_ops.c
* app/histogram_tool.[ch]
* app/info_window.c
* app/install.c
* app/ops_buttons.c
* app/palette.c
* app/palette_select.c
* app/paths_dialog.c
* app/pattern_select.c
* app/resize.c
* app/scale_toolc.c
* app/text_tool.c:
s/container_border_width/container_set_border_width/g,
s/sprintf/g_snprintf/g, replaced some constant string lengths with
strlen(x).
* app/bezier_select.c
* app/blend.c
* app/boundary.c
* app/errors.[ch]
* app/free_select.c
* app/gimpbrushlist.c
* app/gimprc.c
* app/iscissors.c
* app/main.c
* app/patterns.[ch]
* app/text_tool.c: namespace fanaticism: prefixed all gimp error
functions with "gimp_" and formated the messages more uniformly.
* app/gradient.c
* app/gradient_select.c: same stuff as above for the ui
code. There are still some sub-dialogs which need cleanup.
Did some cleanup in most of these files: prototypes, removed tons
of #include's, i18n fixes, s/w/widget/ as above, indentation, ...
1999-07-23 00:21:10 +08:00
|
|
|
/* g_print ("Deleting first point %p\n",finded); */
|
1999-05-14 06:53:40 +08:00
|
|
|
bezier_sel->points = finded->prev->prev->prev;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Make sure the chain of curves is preserved */
|
|
|
|
if(finded->prev->next_curve)
|
|
|
|
{
|
new ui for the "Layer Offset" dialog.
1999-07-22 Michael Natterer <mitschel@cs.tu-berlin.de>
* app/channel_ops.[ch]: new ui for the "Layer Offset" dialog.
* app/channels_dialog.c
* app/layers_dialog.c: major code cleanup: Folded some callbacks
into common ones, "widget" instead of "w", indentation, ...
* app/commands.c
* app/interface.[ch]
* app/global_edit.c: the query boxes must be shown by the caller
now. There's no need to split up the string for the message box
manually as the Gtk 1.2 label widget handles newlines corectly.
Added the "edge_lock" toggle to the "Shrink Selection" dialog.
Nicer spacings for the query and message boxes.
* app/ink.c: tried to grab the pointer in the blob preview but
failed. Left the code there as a reminder (commented out).
* app/menus.c: reordered <Image>/Select.
I was bored and grep-ed the sources for ancient or deprecated stuff:
* app/about_dialog.[ch]
* app/actionarea.[ch]
* app/app_procs.c
* app/brush_edit.c
* app/brush_select.c
* app/color_select.c
* app/convert.c
* app/devices.c
* app/gdisplay.c
* app/gdisplay_ops.c
* app/histogram_tool.[ch]
* app/info_window.c
* app/install.c
* app/ops_buttons.c
* app/palette.c
* app/palette_select.c
* app/paths_dialog.c
* app/pattern_select.c
* app/resize.c
* app/scale_toolc.c
* app/text_tool.c:
s/container_border_width/container_set_border_width/g,
s/sprintf/g_snprintf/g, replaced some constant string lengths with
strlen(x).
* app/bezier_select.c
* app/blend.c
* app/boundary.c
* app/errors.[ch]
* app/free_select.c
* app/gimpbrushlist.c
* app/gimprc.c
* app/iscissors.c
* app/main.c
* app/patterns.[ch]
* app/text_tool.c: namespace fanaticism: prefixed all gimp error
functions with "gimp_" and formated the messages more uniformly.
* app/gradient.c
* app/gradient_select.c: same stuff as above for the ui
code. There are still some sub-dialogs which need cleanup.
Did some cleanup in most of these files: prototypes, removed tons
of #include's, i18n fixes, s/w/widget/ as above, indentation, ...
1999-07-23 00:21:10 +08:00
|
|
|
/* g_print ("Moving curve on next_curve %p\n",finded->prev->next_curve); */
|
1999-05-14 06:53:40 +08:00
|
|
|
/* last point on closed multi-path */
|
|
|
|
finded->prev->prev->prev->prev->next_curve = finded->prev->next_curve;
|
|
|
|
}
|
1999-03-06 07:50:24 +08:00
|
|
|
|
1999-05-14 06:53:40 +08:00
|
|
|
if(bezier_sel->last_point == finded->prev)
|
1999-03-06 07:50:24 +08:00
|
|
|
{
|
new ui for the "Layer Offset" dialog.
1999-07-22 Michael Natterer <mitschel@cs.tu-berlin.de>
* app/channel_ops.[ch]: new ui for the "Layer Offset" dialog.
* app/channels_dialog.c
* app/layers_dialog.c: major code cleanup: Folded some callbacks
into common ones, "widget" instead of "w", indentation, ...
* app/commands.c
* app/interface.[ch]
* app/global_edit.c: the query boxes must be shown by the caller
now. There's no need to split up the string for the message box
manually as the Gtk 1.2 label widget handles newlines corectly.
Added the "edge_lock" toggle to the "Shrink Selection" dialog.
Nicer spacings for the query and message boxes.
* app/ink.c: tried to grab the pointer in the blob preview but
failed. Left the code there as a reminder (commented out).
* app/menus.c: reordered <Image>/Select.
I was bored and grep-ed the sources for ancient or deprecated stuff:
* app/about_dialog.[ch]
* app/actionarea.[ch]
* app/app_procs.c
* app/brush_edit.c
* app/brush_select.c
* app/color_select.c
* app/convert.c
* app/devices.c
* app/gdisplay.c
* app/gdisplay_ops.c
* app/histogram_tool.[ch]
* app/info_window.c
* app/install.c
* app/ops_buttons.c
* app/palette.c
* app/palette_select.c
* app/paths_dialog.c
* app/pattern_select.c
* app/resize.c
* app/scale_toolc.c
* app/text_tool.c:
s/container_border_width/container_set_border_width/g,
s/sprintf/g_snprintf/g, replaced some constant string lengths with
strlen(x).
* app/bezier_select.c
* app/blend.c
* app/boundary.c
* app/errors.[ch]
* app/free_select.c
* app/gimpbrushlist.c
* app/gimprc.c
* app/iscissors.c
* app/main.c
* app/patterns.[ch]
* app/text_tool.c: namespace fanaticism: prefixed all gimp error
functions with "gimp_" and formated the messages more uniformly.
* app/gradient.c
* app/gradient_select.c: same stuff as above for the ui
code. There are still some sub-dialogs which need cleanup.
Did some cleanup in most of these files: prototypes, removed tons
of #include's, i18n fixes, s/w/widget/ as above, indentation, ...
1999-07-23 00:21:10 +08:00
|
|
|
/* g_print ("Deleting last point %p\n",finded->prev); */
|
1999-05-14 06:53:40 +08:00
|
|
|
bezier_sel->last_point = bezier_sel->last_point->prev->prev->prev;
|
1999-03-06 07:50:24 +08:00
|
|
|
}
|
1999-05-14 06:53:40 +08:00
|
|
|
|
|
|
|
start_op->next = end_op;
|
|
|
|
end_op->prev = start_op;
|
|
|
|
|
|
|
|
/* if ( (bezier_sel->last_point == finded) || */
|
|
|
|
/* (bezier_sel->last_point == finded->next) || */
|
|
|
|
/* (bezier_sel->last_point == finded->prev)) */
|
|
|
|
/* { */
|
|
|
|
/* bezier_sel->last_point = start_op->prev->prev; */
|
|
|
|
/* bezier_sel->points = start_op->prev; */
|
|
|
|
/* } */
|
1999-03-06 07:50:24 +08:00
|
|
|
|
|
|
|
bezier_sel->num_points -= 3;
|
|
|
|
|
|
|
|
g_free( finded->prev );
|
|
|
|
g_free( finded->next );
|
|
|
|
g_free( finded );
|
|
|
|
/* Clear current anchor and control */
|
|
|
|
bezier_sel->cur_anchor = NULL;
|
|
|
|
bezier_sel->cur_control = NULL;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
/* set the current anchor and control points */
|
|
|
|
switch (points->type)
|
|
|
|
{
|
|
|
|
case BEZIER_ANCHOR:
|
|
|
|
bezier_sel->cur_anchor = points;
|
|
|
|
bezier_sel->cur_control = bezier_sel->cur_anchor->next;
|
|
|
|
break;
|
|
|
|
case BEZIER_CONTROL:
|
|
|
|
bezier_sel->cur_control = points;
|
1999-06-06 21:24:26 +08:00
|
|
|
if (bezier_sel->cur_control->next &&
|
|
|
|
bezier_sel->cur_control->next->type == BEZIER_ANCHOR)
|
1999-03-06 07:50:24 +08:00
|
|
|
bezier_sel->cur_anchor = bezier_sel->cur_control->next;
|
|
|
|
else
|
|
|
|
bezier_sel->cur_anchor = bezier_sel->cur_control->prev;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
1999-05-14 06:53:40 +08:00
|
|
|
return(1);
|
1999-03-06 07:50:24 +08:00
|
|
|
}
|
|
|
|
|
1999-05-14 06:53:40 +08:00
|
|
|
next_curve = points->next_curve;
|
|
|
|
points = points->next;
|
|
|
|
} while (points != start_pt && points);
|
|
|
|
start_pt = next_curve;
|
|
|
|
points = next_curve;
|
|
|
|
} while (next_curve);
|
|
|
|
|
1999-03-06 07:50:24 +08:00
|
|
|
return grab_pointer;
|
|
|
|
}
|
|
|
|
|
|
|
|
static gint
|
|
|
|
bezier_add_point_on_segment(int x,
|
|
|
|
int y,
|
|
|
|
int halfwidth,
|
|
|
|
GDisplay *gdisp,
|
|
|
|
BezierSelect *bezier_sel,
|
|
|
|
Tool *tool)
|
|
|
|
{
|
|
|
|
BezierPoint *points = bezier_sel->points;
|
|
|
|
BezierPoint *start_pt = bezier_sel->points;
|
1999-05-14 06:53:40 +08:00
|
|
|
BezierPoint *next_curve;
|
1999-03-06 07:50:24 +08:00
|
|
|
|
|
|
|
do {
|
1999-05-14 06:53:40 +08:00
|
|
|
do {
|
|
|
|
if (test_add_point_on_segment (bezier_sel,
|
|
|
|
points,
|
|
|
|
SUBDIVIDE,
|
|
|
|
IMAGE_COORDS,
|
|
|
|
x, y,
|
|
|
|
halfwidth))
|
|
|
|
{
|
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
|
|
|
|
points = points->next;
|
|
|
|
|
|
|
|
if(!points)
|
|
|
|
return 0;
|
|
|
|
|
|
|
|
points = points->next;
|
|
|
|
|
|
|
|
if(!points)
|
|
|
|
return 0;
|
|
|
|
|
|
|
|
next_curve = points->next_curve;
|
|
|
|
points = points->next;
|
|
|
|
} while (points != start_pt && points);
|
|
|
|
start_pt = next_curve;
|
|
|
|
points = next_curve;
|
|
|
|
} while (next_curve);
|
|
|
|
return 0;
|
|
|
|
}
|
1999-03-06 07:50:24 +08:00
|
|
|
|
|
|
|
|
1999-05-14 06:53:40 +08:00
|
|
|
static void
|
|
|
|
bezier_start_new_segment(BezierSelect *bezier_sel,gint x,gint y)
|
|
|
|
{
|
|
|
|
/* Must be closed to do this! */
|
|
|
|
if(!bezier_sel->closed)
|
|
|
|
return;
|
|
|
|
bezier_sel->closed = 0; /* End is no longer closed !*/
|
|
|
|
bezier_sel->state = BEZIER_ADD;
|
|
|
|
bezier_add_point (bezier_sel, BEZIER_MOVE, (gdouble)x, (gdouble)y);
|
|
|
|
bezier_add_point (bezier_sel, BEZIER_CONTROL, (gdouble)x, (gdouble)y);
|
1999-03-06 07:50:24 +08:00
|
|
|
}
|
|
|
|
|
1997-11-25 06:05:25 +08:00
|
|
|
static void
|
|
|
|
bezier_select_button_press (Tool *tool,
|
|
|
|
GdkEventButton *bevent,
|
|
|
|
gpointer gdisp_ptr)
|
|
|
|
{
|
|
|
|
GDisplay *gdisp;
|
|
|
|
BezierSelect *bezier_sel;
|
|
|
|
BezierPoint *points;
|
|
|
|
BezierPoint *start_pt;
|
1999-05-14 06:53:40 +08:00
|
|
|
BezierPoint *curve_start;
|
1997-11-25 06:05:25 +08:00
|
|
|
int grab_pointer;
|
|
|
|
int op, replace;
|
|
|
|
int x, y;
|
|
|
|
int halfwidth, dummy;
|
|
|
|
|
|
|
|
gdisp = (GDisplay *) gdisp_ptr;
|
1999-06-26 19:16:47 +08:00
|
|
|
|
|
|
|
tool->drawable = gimage_active_drawable (gdisp->gimage);
|
|
|
|
|
1997-11-25 06:05:25 +08:00
|
|
|
bezier_sel = tool->private;
|
|
|
|
grab_pointer = 0;
|
|
|
|
|
1998-06-26 16:03:50 +08:00
|
|
|
if (bezier_options->extend)
|
|
|
|
{
|
|
|
|
tool->gdisp_ptr = gdisp_ptr;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
/* If the tool was being used in another image...reset it */
|
|
|
|
if (tool->state == ACTIVE && gdisp_ptr != tool->gdisp_ptr) {
|
|
|
|
draw_core_stop(bezier_sel->core, tool);
|
|
|
|
bezier_select_reset (bezier_sel);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
1997-11-25 06:05:25 +08:00
|
|
|
gdisplay_untransform_coords (gdisp, bevent->x, bevent->y, &x, &y, TRUE, 0);
|
|
|
|
|
|
|
|
/* get halfwidth in image coord */
|
|
|
|
gdisplay_untransform_coords (gdisp, bevent->x + BEZIER_HALFWIDTH, 0, &halfwidth, &dummy, TRUE, 0);
|
|
|
|
halfwidth -= x;
|
|
|
|
|
1998-06-26 16:03:50 +08:00
|
|
|
curTool = active_tool;
|
|
|
|
curSel = curTool->private;
|
|
|
|
curGdisp = (GDisplay *) gdisp_ptr;
|
1999-03-06 07:50:24 +08:00
|
|
|
active_tool->gdisp_ptr = gdisp_ptr;
|
1998-06-26 16:03:50 +08:00
|
|
|
curCore = bezier_sel->core;
|
|
|
|
|
1997-11-25 06:05:25 +08:00
|
|
|
switch (bezier_sel->state)
|
|
|
|
{
|
|
|
|
case BEZIER_START:
|
1999-05-14 06:53:40 +08:00
|
|
|
if(ModeEdit != EXTEND_NEW)
|
|
|
|
break;
|
1997-11-25 06:05:25 +08:00
|
|
|
grab_pointer = 1;
|
|
|
|
tool->state = ACTIVE;
|
|
|
|
tool->gdisp_ptr = gdisp_ptr;
|
|
|
|
|
1999-05-14 06:53:40 +08:00
|
|
|
/* if (bevent->state & GDK_MOD1_MASK) */
|
|
|
|
/* { */
|
|
|
|
/* init_edit_selection (tool, gdisp_ptr, bevent, MaskTranslate); */
|
|
|
|
/* break; */
|
|
|
|
/* } */
|
|
|
|
/* else if (!(bevent->state & GDK_SHIFT_MASK) && !(bevent->state & GDK_CONTROL_MASK)) */
|
|
|
|
/* if (! (layer_is_floating_sel (gimage_get_active_layer (gdisp->gimage))) && */
|
|
|
|
/* gdisplay_mask_value (gdisp, bevent->x, bevent->y) > HALF_WAY) */
|
|
|
|
/* { */
|
|
|
|
/* init_edit_selection (tool, gdisp_ptr, bevent, MaskToLayerTranslate); */
|
|
|
|
/* break; */
|
|
|
|
/* } */
|
1997-11-25 06:05:25 +08:00
|
|
|
|
|
|
|
bezier_sel->state = BEZIER_ADD;
|
|
|
|
bezier_sel->draw = BEZIER_DRAW_CURRENT | BEZIER_DRAW_HANDLES;
|
|
|
|
|
1999-05-14 06:53:40 +08:00
|
|
|
bezier_add_point (bezier_sel, BEZIER_ANCHOR, (gdouble)x, (gdouble)y);
|
|
|
|
bezier_add_point (bezier_sel, BEZIER_CONTROL, (gdouble)x, (gdouble)y);
|
1997-11-25 06:05:25 +08:00
|
|
|
|
|
|
|
draw_core_start (bezier_sel->core, gdisp->canvas->window, tool);
|
|
|
|
break;
|
|
|
|
case BEZIER_ADD:
|
1999-03-06 07:50:24 +08:00
|
|
|
|
1997-11-25 06:05:25 +08:00
|
|
|
grab_pointer = 1;
|
|
|
|
|
1999-03-06 07:50:24 +08:00
|
|
|
if(ModeEdit == EXTEND_EDIT)
|
|
|
|
{
|
|
|
|
/* erase the handles */
|
1999-05-14 06:53:40 +08:00
|
|
|
bezier_sel->draw = BEZIER_DRAW_ALL;
|
1999-03-06 07:50:24 +08:00
|
|
|
draw_core_pause (bezier_sel->core, tool);
|
|
|
|
/* unset the current anchor and control */
|
|
|
|
bezier_sel->cur_anchor = NULL;
|
|
|
|
bezier_sel->cur_control = NULL;
|
|
|
|
|
1999-05-14 06:53:40 +08:00
|
|
|
grab_pointer = bezier_edit_point_on_curve(x,y,halfwidth,gdisp,bezier_sel,tool,bevent);
|
1999-03-06 07:50:24 +08:00
|
|
|
|
1999-05-14 06:53:40 +08:00
|
|
|
bezier_sel->draw = BEZIER_DRAW_ALL;
|
1999-03-06 07:50:24 +08:00
|
|
|
draw_core_resume (bezier_sel->core, tool);
|
|
|
|
|
|
|
|
if (grab_pointer)
|
|
|
|
gdk_pointer_grab (gdisp->canvas->window, FALSE,
|
|
|
|
GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON1_MOTION_MASK | GDK_BUTTON_RELEASE_MASK,
|
|
|
|
NULL, NULL, bevent->time);
|
1999-10-19 04:55:25 +08:00
|
|
|
else
|
|
|
|
{
|
|
|
|
paths_dialog_set_default_op();
|
|
|
|
/* recursive call */
|
|
|
|
bezier_select_button_press(tool,bevent,gdisp_ptr);
|
|
|
|
}
|
1999-03-06 07:50:24 +08:00
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
if(ModeEdit == EXTEND_REMOVE)
|
|
|
|
{
|
1999-05-27 04:36:33 +08:00
|
|
|
/* if(bezier_sel->num_points < 6) */
|
|
|
|
/* return; */
|
1999-03-06 07:50:24 +08:00
|
|
|
|
|
|
|
/* erase the handles */
|
1999-05-14 06:53:40 +08:00
|
|
|
bezier_sel->draw = BEZIER_DRAW_ALL;
|
1999-03-06 07:50:24 +08:00
|
|
|
draw_core_pause (bezier_sel->core, tool);
|
|
|
|
/* unset the current anchor and control */
|
|
|
|
bezier_sel->cur_anchor = NULL;
|
|
|
|
bezier_sel->cur_control = NULL;
|
|
|
|
|
1999-10-19 04:55:25 +08:00
|
|
|
grab_pointer = bezier_edit_point_on_curve(x,y,halfwidth,gdisp,bezier_sel,tool,bevent);
|
1999-03-06 07:50:24 +08:00
|
|
|
|
1999-05-14 06:53:40 +08:00
|
|
|
bezier_sel->draw = BEZIER_DRAW_ALL;
|
1999-03-06 07:50:24 +08:00
|
|
|
draw_core_resume (bezier_sel->core, tool);
|
1999-10-19 04:55:25 +08:00
|
|
|
|
|
|
|
if(!grab_pointer)
|
|
|
|
{
|
|
|
|
paths_dialog_set_default_op();
|
|
|
|
/* recursive call */
|
|
|
|
bezier_select_button_press(tool,bevent,gdisp_ptr);
|
|
|
|
}
|
1999-03-06 07:50:24 +08:00
|
|
|
return;
|
1997-11-25 06:05:25 +08:00
|
|
|
}
|
|
|
|
|
1999-03-06 07:50:24 +08:00
|
|
|
if(ModeEdit == EXTEND_ADD)
|
1997-11-25 06:05:25 +08:00
|
|
|
{
|
1999-03-06 07:50:24 +08:00
|
|
|
if(bezier_sel->num_points < 5)
|
|
|
|
return;
|
|
|
|
bezier_sel->draw = BEZIER_DRAW_ALL;
|
|
|
|
draw_core_pause (bezier_sel->core, tool);
|
|
|
|
|
|
|
|
grab_pointer = bezier_add_point_on_segment(x,y,halfwidth,gdisp,bezier_sel,tool);
|
|
|
|
|
|
|
|
bezier_sel->draw = BEZIER_DRAW_ALL;
|
|
|
|
draw_core_resume (bezier_sel->core, tool);
|
1999-10-19 04:55:25 +08:00
|
|
|
if (grab_pointer)
|
|
|
|
gdk_pointer_grab (gdisp->canvas->window, FALSE,
|
|
|
|
GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON1_MOTION_MASK | GDK_BUTTON_RELEASE_MASK,
|
|
|
|
NULL, NULL, bevent->time);
|
|
|
|
else
|
|
|
|
{
|
|
|
|
paths_dialog_set_default_op();
|
|
|
|
/* recursive call */
|
|
|
|
bezier_select_button_press(tool,bevent,gdisp_ptr);
|
|
|
|
}
|
|
|
|
return;
|
1997-11-25 06:05:25 +08:00
|
|
|
}
|
|
|
|
|
1999-03-06 07:50:24 +08:00
|
|
|
if(bezier_sel->cur_anchor)
|
1997-11-25 06:05:25 +08:00
|
|
|
{
|
1999-03-06 07:50:24 +08:00
|
|
|
if (bezier_check_point (bezier_sel->cur_anchor, x, y, halfwidth))
|
|
|
|
{
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (bezier_sel->cur_anchor->next &&
|
|
|
|
bezier_check_point (bezier_sel->cur_anchor->next, x, y, halfwidth))
|
|
|
|
{
|
|
|
|
bezier_sel->cur_control = bezier_sel->cur_anchor->next;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (bezier_sel->cur_anchor->prev &&
|
|
|
|
bezier_check_point (bezier_sel->cur_anchor->prev, x, y, halfwidth))
|
|
|
|
{
|
|
|
|
bezier_sel->cur_control = bezier_sel->cur_anchor->prev;
|
|
|
|
break;
|
|
|
|
}
|
1997-11-25 06:05:25 +08:00
|
|
|
}
|
|
|
|
|
1999-05-14 06:53:40 +08:00
|
|
|
curve_start = find_start_open_curve(bezier_sel);
|
|
|
|
|
|
|
|
if (curve_start && bezier_check_point (curve_start, x, y, halfwidth))
|
1997-11-25 06:05:25 +08:00
|
|
|
{
|
|
|
|
bezier_sel->draw = BEZIER_DRAW_ALL;
|
|
|
|
draw_core_pause (bezier_sel->core, tool);
|
|
|
|
|
1999-05-14 06:53:40 +08:00
|
|
|
bezier_add_point (bezier_sel, BEZIER_CONTROL, (gdouble)x, (gdouble)y);
|
|
|
|
bezier_sel->last_point->next = curve_start;
|
|
|
|
curve_start->prev = bezier_sel->last_point;
|
|
|
|
bezier_sel->cur_anchor = curve_start;
|
|
|
|
bezier_sel->cur_control = curve_start->next;
|
1997-11-25 06:05:25 +08:00
|
|
|
|
|
|
|
bezier_sel->closed = 1;
|
|
|
|
bezier_sel->state = BEZIER_EDIT;
|
|
|
|
bezier_sel->draw = BEZIER_DRAW_ALL;
|
|
|
|
|
|
|
|
draw_core_resume (bezier_sel->core, tool);
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
1999-05-27 04:36:33 +08:00
|
|
|
if(bezier_sel->cur_anchor)
|
|
|
|
bezier_sel->cur_anchor->pointflags = 1;
|
|
|
|
bezier_sel->draw = BEZIER_DRAW_HANDLES;
|
|
|
|
draw_core_pause (bezier_sel->core, tool);
|
1997-11-25 06:05:25 +08:00
|
|
|
|
1999-05-14 06:53:40 +08:00
|
|
|
bezier_add_point (bezier_sel, BEZIER_CONTROL, (gdouble)x, (gdouble)y);
|
|
|
|
bezier_add_point (bezier_sel, BEZIER_ANCHOR, (gdouble)x, (gdouble)y);
|
|
|
|
bezier_add_point (bezier_sel, BEZIER_CONTROL, (gdouble)x, (gdouble)y);
|
1997-11-25 06:05:25 +08:00
|
|
|
|
|
|
|
bezier_sel->draw = BEZIER_DRAW_CURRENT | BEZIER_DRAW_HANDLES;
|
1999-03-06 07:50:24 +08:00
|
|
|
|
1997-11-25 06:05:25 +08:00
|
|
|
draw_core_resume (bezier_sel->core, tool);
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
case BEZIER_EDIT:
|
|
|
|
if (!bezier_sel->closed)
|
1999-09-23 19:49:16 +08:00
|
|
|
gimp_fatal_error ("bezier_select_button_press(): Tried to edit on open bezier curve in edit selection");
|
1997-11-25 06:05:25 +08:00
|
|
|
|
|
|
|
/* erase the handles */
|
1999-05-14 06:53:40 +08:00
|
|
|
bezier_sel->draw = BEZIER_DRAW_ALL;
|
1997-11-25 06:05:25 +08:00
|
|
|
draw_core_pause (bezier_sel->core, tool);
|
|
|
|
|
|
|
|
/* unset the current anchor and control */
|
|
|
|
bezier_sel->cur_anchor = NULL;
|
|
|
|
bezier_sel->cur_control = NULL;
|
|
|
|
|
|
|
|
points = bezier_sel->points;
|
|
|
|
start_pt = bezier_sel->points;
|
|
|
|
|
1998-06-26 16:03:50 +08:00
|
|
|
if (ModeEdit == EXTEND_ADD)
|
|
|
|
{
|
|
|
|
if (bezier_sel->closed)
|
|
|
|
{
|
1999-03-06 07:50:24 +08:00
|
|
|
grab_pointer = bezier_add_point_on_segment(x,y,halfwidth,gdisp,bezier_sel,tool);
|
1998-06-26 16:03:50 +08:00
|
|
|
}
|
|
|
|
}
|
1999-03-06 07:50:24 +08:00
|
|
|
else
|
1999-02-09 02:16:28 +08:00
|
|
|
{
|
1999-05-14 06:53:40 +08:00
|
|
|
grab_pointer = bezier_edit_point_on_curve(x,y,halfwidth,gdisp,bezier_sel,tool,bevent);
|
1999-02-09 02:16:28 +08:00
|
|
|
}
|
|
|
|
|
1997-11-25 06:05:25 +08:00
|
|
|
if (!grab_pointer && channel_value (bezier_sel->mask, x, y))
|
|
|
|
{
|
|
|
|
replace = 0;
|
|
|
|
if ((bevent->state & GDK_SHIFT_MASK) && !(bevent->state & GDK_CONTROL_MASK))
|
|
|
|
op = ADD;
|
|
|
|
else if ((bevent->state & GDK_CONTROL_MASK) && !(bevent->state & GDK_SHIFT_MASK))
|
|
|
|
op = SUB;
|
|
|
|
else if ((bevent->state & GDK_CONTROL_MASK) && (bevent->state & GDK_SHIFT_MASK))
|
|
|
|
op = INTERSECT;
|
|
|
|
else
|
|
|
|
{
|
|
|
|
op = ADD;
|
|
|
|
replace = 1;
|
|
|
|
}
|
1999-03-06 07:50:24 +08:00
|
|
|
bezier_to_sel_internal(bezier_sel,tool,gdisp,op,replace);
|
1999-05-14 06:53:40 +08:00
|
|
|
draw_core_resume (bezier_sel->core, tool);
|
1997-11-25 06:05:25 +08:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
/* draw the handles */
|
1999-05-14 06:53:40 +08:00
|
|
|
if(!grab_pointer)
|
1999-10-19 04:55:25 +08:00
|
|
|
{
|
|
|
|
paths_dialog_set_default_op();
|
|
|
|
bezier_start_new_segment(bezier_sel,x,y);
|
|
|
|
}
|
1999-05-14 06:53:40 +08:00
|
|
|
bezier_sel->draw = BEZIER_DRAW_ALL;
|
1997-11-25 06:05:25 +08:00
|
|
|
draw_core_resume (bezier_sel->core, tool);
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (grab_pointer)
|
|
|
|
gdk_pointer_grab (gdisp->canvas->window, FALSE,
|
|
|
|
GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON1_MOTION_MASK | GDK_BUTTON_RELEASE_MASK,
|
|
|
|
NULL, NULL, bevent->time);
|
1999-03-06 07:50:24 +08:00
|
|
|
|
|
|
|
/* Don't bother doing this if we don't have any points */
|
|
|
|
if(bezier_sel->num_points > 0)
|
|
|
|
paths_first_button_press(bezier_sel,gdisp);
|
1997-11-25 06:05:25 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
|
|
|
bezier_select_button_release (Tool *tool,
|
|
|
|
GdkEventButton *bevent,
|
|
|
|
gpointer gdisp_ptr)
|
|
|
|
{
|
|
|
|
GDisplay * gdisp;
|
|
|
|
BezierSelect *bezier_sel;
|
|
|
|
|
|
|
|
gdisp = tool->gdisp_ptr;
|
|
|
|
bezier_sel = tool->private;
|
|
|
|
bezier_sel->state &= ~(BEZIER_DRAG);
|
|
|
|
|
|
|
|
gdk_pointer_ungrab (bevent->time);
|
|
|
|
gdk_flush ();
|
|
|
|
|
|
|
|
if (bezier_sel->closed)
|
|
|
|
bezier_convert (bezier_sel, tool->gdisp_ptr, SUBDIVIDE, NO);
|
1999-03-06 07:50:24 +08:00
|
|
|
|
|
|
|
/* Here ?*/
|
|
|
|
paths_newpoint_current(bezier_sel,gdisp);
|
1997-11-25 06:05:25 +08:00
|
|
|
}
|
|
|
|
|
1999-05-27 04:36:33 +08:00
|
|
|
static void
|
|
|
|
bez_copy_points(BezierSelect *tobez,
|
|
|
|
BezierSelect *frombez)
|
|
|
|
{
|
|
|
|
BezierPoint *pts;
|
|
|
|
gint i;
|
|
|
|
BezierPoint *bpnt = NULL;
|
|
|
|
int need_move = 0;
|
|
|
|
|
|
|
|
pts = (BezierPoint *) frombez->points;
|
|
|
|
|
|
|
|
for (i=0; i< frombez->num_points; i++)
|
|
|
|
{
|
|
|
|
if(need_move)
|
|
|
|
{
|
|
|
|
bezier_add_point( tobez, BEZIER_MOVE, pts->x, pts->y);
|
|
|
|
need_move = 0;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
bezier_add_point( tobez, pts->type, pts->x, pts->y);
|
|
|
|
|
|
|
|
if(pts == frombez->cur_anchor)
|
|
|
|
tobez->cur_anchor = tobez->last_point;
|
|
|
|
else if(pts == frombez->cur_control)
|
|
|
|
tobez->cur_control = tobez->last_point;
|
|
|
|
|
|
|
|
if(bpnt == NULL)
|
|
|
|
bpnt = tobez->last_point;
|
|
|
|
|
|
|
|
if(pts->next_curve)
|
|
|
|
{
|
new ui for the "Layer Offset" dialog.
1999-07-22 Michael Natterer <mitschel@cs.tu-berlin.de>
* app/channel_ops.[ch]: new ui for the "Layer Offset" dialog.
* app/channels_dialog.c
* app/layers_dialog.c: major code cleanup: Folded some callbacks
into common ones, "widget" instead of "w", indentation, ...
* app/commands.c
* app/interface.[ch]
* app/global_edit.c: the query boxes must be shown by the caller
now. There's no need to split up the string for the message box
manually as the Gtk 1.2 label widget handles newlines corectly.
Added the "edge_lock" toggle to the "Shrink Selection" dialog.
Nicer spacings for the query and message boxes.
* app/ink.c: tried to grab the pointer in the blob preview but
failed. Left the code there as a reminder (commented out).
* app/menus.c: reordered <Image>/Select.
I was bored and grep-ed the sources for ancient or deprecated stuff:
* app/about_dialog.[ch]
* app/actionarea.[ch]
* app/app_procs.c
* app/brush_edit.c
* app/brush_select.c
* app/color_select.c
* app/convert.c
* app/devices.c
* app/gdisplay.c
* app/gdisplay_ops.c
* app/histogram_tool.[ch]
* app/info_window.c
* app/install.c
* app/ops_buttons.c
* app/palette.c
* app/palette_select.c
* app/paths_dialog.c
* app/pattern_select.c
* app/resize.c
* app/scale_toolc.c
* app/text_tool.c:
s/container_border_width/container_set_border_width/g,
s/sprintf/g_snprintf/g, replaced some constant string lengths with
strlen(x).
* app/bezier_select.c
* app/blend.c
* app/boundary.c
* app/errors.[ch]
* app/free_select.c
* app/gimpbrushlist.c
* app/gimprc.c
* app/iscissors.c
* app/main.c
* app/patterns.[ch]
* app/text_tool.c: namespace fanaticism: prefixed all gimp error
functions with "gimp_" and formated the messages more uniformly.
* app/gradient.c
* app/gradient_select.c: same stuff as above for the ui
code. There are still some sub-dialogs which need cleanup.
Did some cleanup in most of these files: prototypes, removed tons
of #include's, i18n fixes, s/w/widget/ as above, indentation, ...
1999-07-23 00:21:10 +08:00
|
|
|
/* g_print ("bezier_paste_bezierselect_to_current:: Close last curve off \n"); */
|
1999-05-27 04:36:33 +08:00
|
|
|
tobez->last_point->next = bpnt;
|
|
|
|
bpnt->prev = tobez->last_point;
|
|
|
|
bpnt = NULL;
|
|
|
|
need_move = 1;
|
|
|
|
pts = pts->next_curve;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
pts = pts->next;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if ( frombez->closed )
|
|
|
|
{
|
|
|
|
tobez->last_point->next = bpnt;
|
|
|
|
bpnt->prev = tobez->last_point;
|
|
|
|
tobez->closed = 1;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
1997-11-25 06:05:25 +08:00
|
|
|
static void
|
|
|
|
bezier_select_motion (Tool *tool,
|
|
|
|
GdkEventMotion *mevent,
|
|
|
|
gpointer gdisp_ptr)
|
|
|
|
{
|
|
|
|
static int lastx, lasty;
|
|
|
|
|
|
|
|
GDisplay * gdisp;
|
|
|
|
BezierSelect * bezier_sel;
|
|
|
|
BezierPoint * anchor;
|
|
|
|
BezierPoint * opposite_control;
|
|
|
|
int offsetx;
|
|
|
|
int offsety;
|
|
|
|
int x, y;
|
|
|
|
|
|
|
|
if (tool->state != ACTIVE)
|
|
|
|
return;
|
|
|
|
|
|
|
|
gdisp = gdisp_ptr;
|
|
|
|
bezier_sel = tool->private;
|
|
|
|
|
|
|
|
if (!bezier_sel->cur_anchor || !bezier_sel->cur_control)
|
|
|
|
return;
|
|
|
|
|
1998-06-26 16:03:50 +08:00
|
|
|
if (mevent->state & GDK_MOD1_MASK)
|
|
|
|
{
|
|
|
|
bezier_sel->draw = BEZIER_DRAW_ALL;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
bezier_sel->draw = BEZIER_DRAW_CURRENT | BEZIER_DRAW_HANDLES;
|
|
|
|
}
|
|
|
|
|
1999-05-27 04:36:33 +08:00
|
|
|
|
|
|
|
draw_core_pause (bezier_sel->core, tool);
|
1997-11-25 06:05:25 +08:00
|
|
|
|
|
|
|
gdisplay_untransform_coords (gdisp, mevent->x, mevent->y, &x, &y, TRUE, 0);
|
|
|
|
|
|
|
|
/* If this is the first point then change the state and "remember" the point.
|
|
|
|
*/
|
|
|
|
if (!(bezier_sel->state & BEZIER_DRAG))
|
|
|
|
{
|
|
|
|
bezier_sel->state |= BEZIER_DRAG;
|
|
|
|
lastx = x;
|
|
|
|
lasty = y;
|
|
|
|
}
|
|
|
|
|
1998-06-26 16:03:50 +08:00
|
|
|
/* The Alt key is down... Move all the points of the bezier curve */
|
|
|
|
|
|
|
|
if (mevent->state & GDK_MOD1_MASK)
|
|
|
|
{
|
|
|
|
BezierPoint *tmp = bezier_sel->points;
|
1999-05-14 06:53:40 +08:00
|
|
|
gint num_points = bezier_sel->num_points;
|
1998-06-26 16:03:50 +08:00
|
|
|
offsetx = x - lastx;
|
|
|
|
offsety = y - lasty;
|
|
|
|
|
1999-05-14 06:53:40 +08:00
|
|
|
if(mevent->state & GDK_SHIFT_MASK)
|
|
|
|
{
|
|
|
|
/* Only move this curve */
|
|
|
|
BezierPoint *start_pt = bezier_sel->cur_anchor;
|
|
|
|
|
new ui for the "Layer Offset" dialog.
1999-07-22 Michael Natterer <mitschel@cs.tu-berlin.de>
* app/channel_ops.[ch]: new ui for the "Layer Offset" dialog.
* app/channels_dialog.c
* app/layers_dialog.c: major code cleanup: Folded some callbacks
into common ones, "widget" instead of "w", indentation, ...
* app/commands.c
* app/interface.[ch]
* app/global_edit.c: the query boxes must be shown by the caller
now. There's no need to split up the string for the message box
manually as the Gtk 1.2 label widget handles newlines corectly.
Added the "edge_lock" toggle to the "Shrink Selection" dialog.
Nicer spacings for the query and message boxes.
* app/ink.c: tried to grab the pointer in the blob preview but
failed. Left the code there as a reminder (commented out).
* app/menus.c: reordered <Image>/Select.
I was bored and grep-ed the sources for ancient or deprecated stuff:
* app/about_dialog.[ch]
* app/actionarea.[ch]
* app/app_procs.c
* app/brush_edit.c
* app/brush_select.c
* app/color_select.c
* app/convert.c
* app/devices.c
* app/gdisplay.c
* app/gdisplay_ops.c
* app/histogram_tool.[ch]
* app/info_window.c
* app/install.c
* app/ops_buttons.c
* app/palette.c
* app/palette_select.c
* app/paths_dialog.c
* app/pattern_select.c
* app/resize.c
* app/scale_toolc.c
* app/text_tool.c:
s/container_border_width/container_set_border_width/g,
s/sprintf/g_snprintf/g, replaced some constant string lengths with
strlen(x).
* app/bezier_select.c
* app/blend.c
* app/boundary.c
* app/errors.[ch]
* app/free_select.c
* app/gimpbrushlist.c
* app/gimprc.c
* app/iscissors.c
* app/main.c
* app/patterns.[ch]
* app/text_tool.c: namespace fanaticism: prefixed all gimp error
functions with "gimp_" and formated the messages more uniformly.
* app/gradient.c
* app/gradient_select.c: same stuff as above for the ui
code. There are still some sub-dialogs which need cleanup.
Did some cleanup in most of these files: prototypes, removed tons
of #include's, i18n fixes, s/w/widget/ as above, indentation, ...
1999-07-23 00:21:10 +08:00
|
|
|
/* g_print ("moving only one curve\n"); */
|
1998-06-26 16:03:50 +08:00
|
|
|
|
1999-05-14 06:53:40 +08:00
|
|
|
tmp = start_pt;
|
|
|
|
|
|
|
|
do {
|
|
|
|
bezier_offset_point (tmp, offsetx, offsety);
|
|
|
|
tmp = tmp->next;
|
|
|
|
} while (tmp != start_pt && tmp);
|
|
|
|
/* Check if need to go backwards because curve is open */
|
|
|
|
if(!tmp && bezier_sel->cur_anchor->prev)
|
|
|
|
{
|
|
|
|
BezierPoint *start_pt = bezier_sel->cur_anchor->prev;
|
|
|
|
tmp = start_pt;
|
|
|
|
|
|
|
|
do {
|
|
|
|
bezier_offset_point (tmp, offsetx, offsety);
|
|
|
|
tmp = tmp->prev;
|
|
|
|
} while (tmp != start_pt && tmp);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
while (tmp && num_points)
|
|
|
|
{
|
|
|
|
bezier_offset_point (tmp, offsetx, offsety);
|
|
|
|
if(tmp->next_curve)
|
|
|
|
tmp = tmp->next_curve;
|
|
|
|
else
|
|
|
|
tmp = tmp->next;
|
|
|
|
num_points--;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else
|
1997-11-25 06:05:25 +08:00
|
|
|
if (mevent->state & GDK_CONTROL_MASK)
|
|
|
|
{
|
|
|
|
/* the control key is down ... move the current anchor point */
|
|
|
|
/* we must also move the neighboring control points appropriately */
|
|
|
|
|
|
|
|
offsetx = x - lastx;
|
|
|
|
offsety = y - lasty;
|
|
|
|
|
|
|
|
bezier_offset_point (bezier_sel->cur_anchor, offsetx, offsety);
|
|
|
|
bezier_offset_point (bezier_sel->cur_anchor->next, offsetx, offsety);
|
|
|
|
bezier_offset_point (bezier_sel->cur_anchor->prev, offsetx, offsety);
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
/* the control key is not down ... we move the current control point */
|
|
|
|
|
|
|
|
offsetx = x - bezier_sel->cur_control->x;
|
|
|
|
offsety = y - bezier_sel->cur_control->y;
|
|
|
|
|
|
|
|
bezier_offset_point (bezier_sel->cur_control, offsetx, offsety);
|
|
|
|
|
|
|
|
/* if the shift key is not down then we align the opposite control */
|
|
|
|
/* point...ie the opposite control point acts like a mirror of the */
|
|
|
|
/* current control point */
|
|
|
|
|
|
|
|
if (!(mevent->state & GDK_SHIFT_MASK))
|
|
|
|
{
|
|
|
|
anchor = NULL;
|
|
|
|
opposite_control = NULL;
|
|
|
|
|
|
|
|
if (bezier_sel->cur_control->next)
|
|
|
|
{
|
|
|
|
if (bezier_sel->cur_control->next->type == BEZIER_ANCHOR)
|
|
|
|
{
|
|
|
|
anchor = bezier_sel->cur_control->next;
|
|
|
|
opposite_control = anchor->next;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
if (bezier_sel->cur_control->prev)
|
|
|
|
{
|
|
|
|
if (bezier_sel->cur_control->prev->type == BEZIER_ANCHOR)
|
|
|
|
{
|
|
|
|
anchor = bezier_sel->cur_control->prev;
|
|
|
|
opposite_control = anchor->prev;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if (!anchor)
|
1999-09-23 19:49:16 +08:00
|
|
|
gimp_fatal_error ("bezier_select_motion(): Encountered orphaned bezier control point");
|
1997-11-25 06:05:25 +08:00
|
|
|
|
|
|
|
if (opposite_control)
|
|
|
|
{
|
|
|
|
offsetx = bezier_sel->cur_control->x - anchor->x;
|
|
|
|
offsety = bezier_sel->cur_control->y - anchor->y;
|
|
|
|
|
|
|
|
opposite_control->x = anchor->x - offsetx;
|
|
|
|
opposite_control->y = anchor->y - offsety;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
1998-06-26 16:03:50 +08:00
|
|
|
/* As we're moving all the control points of the curve,
|
|
|
|
we have to redraw all !!!
|
|
|
|
*/
|
|
|
|
|
|
|
|
if ( mevent->state & GDK_MOD1_MASK)
|
|
|
|
bezier_sel->draw = BEZIER_DRAW_ALL;
|
|
|
|
else
|
|
|
|
bezier_sel->draw = BEZIER_DRAW_CURRENT | BEZIER_DRAW_HANDLES;
|
|
|
|
|
1997-11-25 06:05:25 +08:00
|
|
|
draw_core_resume (bezier_sel->core, tool);
|
|
|
|
|
|
|
|
lastx = x;
|
|
|
|
lasty = y;
|
|
|
|
}
|
|
|
|
|
1999-05-14 06:53:40 +08:00
|
|
|
/* returns 0 if not on control point, else BEZIER_ANCHOR or BEZIER_CONTROL */
|
|
|
|
static gint
|
|
|
|
bezier_on_control_point(GDisplay *gdisp,
|
|
|
|
BezierSelect *bezier_sel,
|
|
|
|
gint x,
|
|
|
|
gint y,
|
|
|
|
gint halfwidth)
|
|
|
|
{
|
|
|
|
BezierPoint * points;
|
|
|
|
gint num_points;
|
|
|
|
|
|
|
|
/* transform the points from image space to screen space */
|
|
|
|
points = bezier_sel->points;
|
|
|
|
num_points = bezier_sel->num_points;
|
|
|
|
|
|
|
|
while (points && num_points)
|
|
|
|
{
|
|
|
|
if(bezier_check_point(points,x,y,halfwidth))
|
|
|
|
return points->type;
|
|
|
|
|
|
|
|
if(points->next_curve)
|
|
|
|
points = points->next_curve;
|
|
|
|
else
|
|
|
|
points = points->next;
|
|
|
|
num_points--;
|
|
|
|
}
|
|
|
|
|
|
|
|
return FALSE;
|
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
|
|
|
bezier_check_points (BezierSelect *bezier_sel,
|
|
|
|
GdkPoint *points,
|
|
|
|
int npoints,
|
|
|
|
gpointer udata)
|
|
|
|
{
|
|
|
|
gint loop;
|
|
|
|
int l, r, t, b;
|
|
|
|
BezierCheckPnts *chkpnts = udata;
|
|
|
|
gint halfwidth = chkpnts->halfwidth;
|
|
|
|
|
|
|
|
/* Quick exit if already found */
|
|
|
|
|
|
|
|
if(chkpnts->found)
|
|
|
|
return;
|
|
|
|
|
|
|
|
for(loop = 0 ; loop < npoints; loop++)
|
|
|
|
{
|
|
|
|
l = points[loop].x - halfwidth;
|
|
|
|
r = points[loop].x + halfwidth;
|
|
|
|
t = points[loop].y - halfwidth;
|
|
|
|
b = points[loop].y + halfwidth;
|
|
|
|
|
new ui for the "Layer Offset" dialog.
1999-07-22 Michael Natterer <mitschel@cs.tu-berlin.de>
* app/channel_ops.[ch]: new ui for the "Layer Offset" dialog.
* app/channels_dialog.c
* app/layers_dialog.c: major code cleanup: Folded some callbacks
into common ones, "widget" instead of "w", indentation, ...
* app/commands.c
* app/interface.[ch]
* app/global_edit.c: the query boxes must be shown by the caller
now. There's no need to split up the string for the message box
manually as the Gtk 1.2 label widget handles newlines corectly.
Added the "edge_lock" toggle to the "Shrink Selection" dialog.
Nicer spacings for the query and message boxes.
* app/ink.c: tried to grab the pointer in the blob preview but
failed. Left the code there as a reminder (commented out).
* app/menus.c: reordered <Image>/Select.
I was bored and grep-ed the sources for ancient or deprecated stuff:
* app/about_dialog.[ch]
* app/actionarea.[ch]
* app/app_procs.c
* app/brush_edit.c
* app/brush_select.c
* app/color_select.c
* app/convert.c
* app/devices.c
* app/gdisplay.c
* app/gdisplay_ops.c
* app/histogram_tool.[ch]
* app/info_window.c
* app/install.c
* app/ops_buttons.c
* app/palette.c
* app/palette_select.c
* app/paths_dialog.c
* app/pattern_select.c
* app/resize.c
* app/scale_toolc.c
* app/text_tool.c:
s/container_border_width/container_set_border_width/g,
s/sprintf/g_snprintf/g, replaced some constant string lengths with
strlen(x).
* app/bezier_select.c
* app/blend.c
* app/boundary.c
* app/errors.[ch]
* app/free_select.c
* app/gimpbrushlist.c
* app/gimprc.c
* app/iscissors.c
* app/main.c
* app/patterns.[ch]
* app/text_tool.c: namespace fanaticism: prefixed all gimp error
functions with "gimp_" and formated the messages more uniformly.
* app/gradient.c
* app/gradient_select.c: same stuff as above for the ui
code. There are still some sub-dialogs which need cleanup.
Did some cleanup in most of these files: prototypes, removed tons
of #include's, i18n fixes, s/w/widget/ as above, indentation, ...
1999-07-23 00:21:10 +08:00
|
|
|
/* g_print ("x,y = [%d,%d] halfwidth %d l,r,t,d [%d,%d,%d,%d]\n", */
|
1999-05-14 06:53:40 +08:00
|
|
|
/* points[loop].x, */
|
|
|
|
/* points[loop].y, */
|
|
|
|
/* halfwidth, */
|
|
|
|
/* l,r,t,b); */
|
|
|
|
|
|
|
|
if ((chkpnts->x >= l) &&
|
|
|
|
(chkpnts->x <= r) &&
|
|
|
|
(chkpnts->y >= t) &&
|
|
|
|
(chkpnts->y <= b))
|
|
|
|
{
|
|
|
|
chkpnts->found = TRUE;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
static gboolean
|
|
|
|
points_in_box(BezierPoint *points,
|
|
|
|
gint x,
|
|
|
|
gint y)
|
|
|
|
{
|
|
|
|
/* below code adapted from Wm. Randolph Franklin <wrf@ecse.rpi.edu>
|
|
|
|
*/
|
|
|
|
int i, j, c = 0;
|
|
|
|
double yp[4],xp[4];
|
|
|
|
|
|
|
|
for (i = 0; i < 4; i++)
|
|
|
|
{
|
|
|
|
xp[i] = points->x;
|
|
|
|
yp[i] = points->y;
|
|
|
|
points = points->next;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Check if straight line ..below don't work if it is! */
|
|
|
|
if((xp[0] == xp[1] && yp[0] == yp[1]) ||
|
|
|
|
(xp[2] == xp[3] && yp[0] == yp[1]))
|
|
|
|
return TRUE;
|
|
|
|
|
|
|
|
for (i = 0, j = 3; i < 4; j = i++) {
|
|
|
|
if ((((yp[i]<=y) && (y<yp[j])) ||
|
|
|
|
((yp[j]<=y) && (y<yp[i]))) &&
|
|
|
|
(x < (xp[j] - xp[i]) * (y - yp[i]) / (yp[j] - yp[i]) + xp[i]))
|
|
|
|
c = !c;
|
|
|
|
}
|
|
|
|
|
|
|
|
return c;
|
|
|
|
}
|
|
|
|
|
|
|
|
static int
|
|
|
|
bezier_point_on_curve(GDisplay *gdisp,
|
|
|
|
BezierSelect *bezier_sel,
|
|
|
|
gint x,
|
|
|
|
gint y,
|
|
|
|
gint halfwidth)
|
|
|
|
{
|
|
|
|
BezierCheckPnts chkpnts;
|
|
|
|
BezierPoint * points;
|
|
|
|
BezierPoint * start_pt;
|
|
|
|
BezierPoint * next_curve;
|
|
|
|
CountCurves * cnt = (CountCurves *)&chkpnts;
|
|
|
|
gint point_counts = 0;
|
|
|
|
|
|
|
|
chkpnts.x = x;
|
|
|
|
chkpnts.y = y;
|
|
|
|
chkpnts.halfwidth = halfwidth;
|
|
|
|
chkpnts.found = FALSE;
|
|
|
|
|
|
|
|
if(cnt)
|
|
|
|
cnt->count = 0;
|
|
|
|
points = bezier_sel->points;
|
|
|
|
start_pt = bezier_sel->points;
|
|
|
|
|
|
|
|
if(bezier_sel->num_points >= 4)
|
|
|
|
{
|
|
|
|
do {
|
|
|
|
point_counts = count_points_on_curve(points);
|
|
|
|
if(point_counts >= 4)
|
|
|
|
{
|
|
|
|
do {
|
|
|
|
if(points_in_box(points,x,y))
|
|
|
|
{
|
|
|
|
bezier_draw_segment (bezier_sel, points,
|
|
|
|
SUBDIVIDE, IMAGE_COORDS,
|
|
|
|
bezier_check_points,
|
|
|
|
&chkpnts);
|
|
|
|
}
|
|
|
|
points = next_anchor(points,&next_curve);
|
new ui for the "Layer Offset" dialog.
1999-07-22 Michael Natterer <mitschel@cs.tu-berlin.de>
* app/channel_ops.[ch]: new ui for the "Layer Offset" dialog.
* app/channels_dialog.c
* app/layers_dialog.c: major code cleanup: Folded some callbacks
into common ones, "widget" instead of "w", indentation, ...
* app/commands.c
* app/interface.[ch]
* app/global_edit.c: the query boxes must be shown by the caller
now. There's no need to split up the string for the message box
manually as the Gtk 1.2 label widget handles newlines corectly.
Added the "edge_lock" toggle to the "Shrink Selection" dialog.
Nicer spacings for the query and message boxes.
* app/ink.c: tried to grab the pointer in the blob preview but
failed. Left the code there as a reminder (commented out).
* app/menus.c: reordered <Image>/Select.
I was bored and grep-ed the sources for ancient or deprecated stuff:
* app/about_dialog.[ch]
* app/actionarea.[ch]
* app/app_procs.c
* app/brush_edit.c
* app/brush_select.c
* app/color_select.c
* app/convert.c
* app/devices.c
* app/gdisplay.c
* app/gdisplay_ops.c
* app/histogram_tool.[ch]
* app/info_window.c
* app/install.c
* app/ops_buttons.c
* app/palette.c
* app/palette_select.c
* app/paths_dialog.c
* app/pattern_select.c
* app/resize.c
* app/scale_toolc.c
* app/text_tool.c:
s/container_border_width/container_set_border_width/g,
s/sprintf/g_snprintf/g, replaced some constant string lengths with
strlen(x).
* app/bezier_select.c
* app/blend.c
* app/boundary.c
* app/errors.[ch]
* app/free_select.c
* app/gimpbrushlist.c
* app/gimprc.c
* app/iscissors.c
* app/main.c
* app/patterns.[ch]
* app/text_tool.c: namespace fanaticism: prefixed all gimp error
functions with "gimp_" and formated the messages more uniformly.
* app/gradient.c
* app/gradient_select.c: same stuff as above for the ui
code. There are still some sub-dialogs which need cleanup.
Did some cleanup in most of these files: prototypes, removed tons
of #include's, i18n fixes, s/w/widget/ as above, indentation, ...
1999-07-23 00:21:10 +08:00
|
|
|
/* g_print ("next_anchor = %p\n",points); */
|
1999-05-14 06:53:40 +08:00
|
|
|
} while (points != start_pt && points);
|
|
|
|
if(cnt)
|
|
|
|
cnt->count++;
|
|
|
|
start_pt = next_curve;
|
|
|
|
points = next_curve;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
break; /* must be last curve since only this one is allowed < 4
|
|
|
|
* points.
|
|
|
|
*/
|
|
|
|
} while(next_curve);
|
|
|
|
}
|
|
|
|
|
|
|
|
return (chkpnts.found);
|
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
|
|
|
bezier_select_cursor_update (Tool *tool,
|
|
|
|
GdkEventMotion *mevent,
|
|
|
|
gpointer gdisp_ptr)
|
|
|
|
{
|
|
|
|
GDisplay *gdisp;
|
|
|
|
BezierSelect * bezier_sel;
|
|
|
|
gboolean on_curve;
|
|
|
|
gboolean on_control_pnt;
|
|
|
|
gboolean in_selection_area;
|
|
|
|
gint halfwidth,dummy;
|
|
|
|
gint x,y;
|
|
|
|
|
|
|
|
gdisp = (GDisplay *)gdisp_ptr;
|
|
|
|
|
|
|
|
bezier_sel = tool->private;
|
|
|
|
|
|
|
|
if(gdisp != tool->gdisp_ptr || bezier_sel->core->draw_state == INVISIBLE)
|
|
|
|
{
|
|
|
|
gdisplay_install_tool_cursor (gdisp, GIMP_MOUSE1_CURSOR);
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
gdisplay_untransform_coords (gdisp, mevent->x, mevent->y, &x, &y, TRUE, 0);
|
|
|
|
|
|
|
|
/* get halfwidth in image coord */
|
|
|
|
gdisplay_untransform_coords (gdisp, mevent->x + BEZIER_HALFWIDTH, 0, &halfwidth, &dummy, TRUE, 0);
|
|
|
|
halfwidth -= x;
|
|
|
|
|
|
|
|
on_control_pnt = bezier_on_control_point(gdisp,bezier_sel,x,y,halfwidth);
|
|
|
|
|
|
|
|
on_curve = bezier_point_on_curve(gdisp,bezier_sel,x,y,halfwidth);
|
|
|
|
|
|
|
|
if(bezier_sel->mask && bezier_sel->closed &&
|
|
|
|
channel_value(bezier_sel->mask, x, y) &&
|
|
|
|
!on_control_pnt &&
|
|
|
|
(!on_curve || ModeEdit != EXTEND_ADD))
|
|
|
|
{
|
|
|
|
in_selection_area = TRUE;
|
|
|
|
if ((mevent->state & GDK_SHIFT_MASK) && !(mevent->state & GDK_CONTROL_MASK))
|
|
|
|
gdisplay_install_tool_cursor (gdisp,GIMP_MOUSE1SELP_CURSOR );
|
|
|
|
else if ((mevent->state & GDK_CONTROL_MASK) && !(mevent->state & GDK_SHIFT_MASK))
|
|
|
|
gdisplay_install_tool_cursor (gdisp,GIMP_MOUSE1SELM_CURSOR );
|
|
|
|
else if ((mevent->state & GDK_CONTROL_MASK) && (mevent->state & GDK_SHIFT_MASK))
|
|
|
|
gdisplay_install_tool_cursor (gdisp, GIMP_BIGCIRC_CURSOR);
|
|
|
|
else
|
|
|
|
gdisplay_install_tool_cursor (gdisp, GIMP_MOUSE1SEL_CURSOR);
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
if(mevent->state & GDK_MOD1_MASK)
|
|
|
|
{
|
|
|
|
/* Moving curve */
|
|
|
|
if(mevent->state & GDK_SHIFT_MASK)
|
|
|
|
{
|
|
|
|
/* moving on 1 curve */
|
|
|
|
gdisplay_install_tool_cursor (gdisp, GIMP_MOUSE1MM_CURSOR);
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
gdisplay_install_tool_cursor (gdisp, GIMP_MOUSE1MM_CURSOR);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
switch(ModeEdit)
|
|
|
|
{
|
|
|
|
case EXTEND_NEW:
|
|
|
|
if(on_control_pnt && bezier_sel->closed)
|
|
|
|
{
|
|
|
|
gdisplay_install_tool_cursor (gdisp, GIMP_MOUSE1CP_CURSOR);
|
new ui for the "Layer Offset" dialog.
1999-07-22 Michael Natterer <mitschel@cs.tu-berlin.de>
* app/channel_ops.[ch]: new ui for the "Layer Offset" dialog.
* app/channels_dialog.c
* app/layers_dialog.c: major code cleanup: Folded some callbacks
into common ones, "widget" instead of "w", indentation, ...
* app/commands.c
* app/interface.[ch]
* app/global_edit.c: the query boxes must be shown by the caller
now. There's no need to split up the string for the message box
manually as the Gtk 1.2 label widget handles newlines corectly.
Added the "edge_lock" toggle to the "Shrink Selection" dialog.
Nicer spacings for the query and message boxes.
* app/ink.c: tried to grab the pointer in the blob preview but
failed. Left the code there as a reminder (commented out).
* app/menus.c: reordered <Image>/Select.
I was bored and grep-ed the sources for ancient or deprecated stuff:
* app/about_dialog.[ch]
* app/actionarea.[ch]
* app/app_procs.c
* app/brush_edit.c
* app/brush_select.c
* app/color_select.c
* app/convert.c
* app/devices.c
* app/gdisplay.c
* app/gdisplay_ops.c
* app/histogram_tool.[ch]
* app/info_window.c
* app/install.c
* app/ops_buttons.c
* app/palette.c
* app/palette_select.c
* app/paths_dialog.c
* app/pattern_select.c
* app/resize.c
* app/scale_toolc.c
* app/text_tool.c:
s/container_border_width/container_set_border_width/g,
s/sprintf/g_snprintf/g, replaced some constant string lengths with
strlen(x).
* app/bezier_select.c
* app/blend.c
* app/boundary.c
* app/errors.[ch]
* app/free_select.c
* app/gimpbrushlist.c
* app/gimprc.c
* app/iscissors.c
* app/main.c
* app/patterns.[ch]
* app/text_tool.c: namespace fanaticism: prefixed all gimp error
functions with "gimp_" and formated the messages more uniformly.
* app/gradient.c
* app/gradient_select.c: same stuff as above for the ui
code. There are still some sub-dialogs which need cleanup.
Did some cleanup in most of these files: prototypes, removed tons
of #include's, i18n fixes, s/w/widget/ as above, indentation, ...
1999-07-23 00:21:10 +08:00
|
|
|
/* g_print ("add to curve cursor\n"); */
|
1999-05-14 06:53:40 +08:00
|
|
|
}
|
|
|
|
else if(on_curve)
|
|
|
|
{
|
|
|
|
gdisplay_install_tool_cursor (gdisp, GIMP_MOUSE1AP_CURSOR);
|
new ui for the "Layer Offset" dialog.
1999-07-22 Michael Natterer <mitschel@cs.tu-berlin.de>
* app/channel_ops.[ch]: new ui for the "Layer Offset" dialog.
* app/channels_dialog.c
* app/layers_dialog.c: major code cleanup: Folded some callbacks
into common ones, "widget" instead of "w", indentation, ...
* app/commands.c
* app/interface.[ch]
* app/global_edit.c: the query boxes must be shown by the caller
now. There's no need to split up the string for the message box
manually as the Gtk 1.2 label widget handles newlines corectly.
Added the "edge_lock" toggle to the "Shrink Selection" dialog.
Nicer spacings for the query and message boxes.
* app/ink.c: tried to grab the pointer in the blob preview but
failed. Left the code there as a reminder (commented out).
* app/menus.c: reordered <Image>/Select.
I was bored and grep-ed the sources for ancient or deprecated stuff:
* app/about_dialog.[ch]
* app/actionarea.[ch]
* app/app_procs.c
* app/brush_edit.c
* app/brush_select.c
* app/color_select.c
* app/convert.c
* app/devices.c
* app/gdisplay.c
* app/gdisplay_ops.c
* app/histogram_tool.[ch]
* app/info_window.c
* app/install.c
* app/ops_buttons.c
* app/palette.c
* app/palette_select.c
* app/paths_dialog.c
* app/pattern_select.c
* app/resize.c
* app/scale_toolc.c
* app/text_tool.c:
s/container_border_width/container_set_border_width/g,
s/sprintf/g_snprintf/g, replaced some constant string lengths with
strlen(x).
* app/bezier_select.c
* app/blend.c
* app/boundary.c
* app/errors.[ch]
* app/free_select.c
* app/gimpbrushlist.c
* app/gimprc.c
* app/iscissors.c
* app/main.c
* app/patterns.[ch]
* app/text_tool.c: namespace fanaticism: prefixed all gimp error
functions with "gimp_" and formated the messages more uniformly.
* app/gradient.c
* app/gradient_select.c: same stuff as above for the ui
code. There are still some sub-dialogs which need cleanup.
Did some cleanup in most of these files: prototypes, removed tons
of #include's, i18n fixes, s/w/widget/ as above, indentation, ...
1999-07-23 00:21:10 +08:00
|
|
|
/* g_print ("edit control point cursor\n"); */
|
1999-05-14 06:53:40 +08:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
gdisplay_install_tool_cursor (gdisp, GIMP_MOUSE1AP_CURSOR);
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
case EXTEND_ADD:
|
|
|
|
if(on_curve)
|
|
|
|
{
|
|
|
|
gdisplay_install_tool_cursor (gdisp, GIMP_MOUSE1P_CURSOR);
|
new ui for the "Layer Offset" dialog.
1999-07-22 Michael Natterer <mitschel@cs.tu-berlin.de>
* app/channel_ops.[ch]: new ui for the "Layer Offset" dialog.
* app/channels_dialog.c
* app/layers_dialog.c: major code cleanup: Folded some callbacks
into common ones, "widget" instead of "w", indentation, ...
* app/commands.c
* app/interface.[ch]
* app/global_edit.c: the query boxes must be shown by the caller
now. There's no need to split up the string for the message box
manually as the Gtk 1.2 label widget handles newlines corectly.
Added the "edge_lock" toggle to the "Shrink Selection" dialog.
Nicer spacings for the query and message boxes.
* app/ink.c: tried to grab the pointer in the blob preview but
failed. Left the code there as a reminder (commented out).
* app/menus.c: reordered <Image>/Select.
I was bored and grep-ed the sources for ancient or deprecated stuff:
* app/about_dialog.[ch]
* app/actionarea.[ch]
* app/app_procs.c
* app/brush_edit.c
* app/brush_select.c
* app/color_select.c
* app/convert.c
* app/devices.c
* app/gdisplay.c
* app/gdisplay_ops.c
* app/histogram_tool.[ch]
* app/info_window.c
* app/install.c
* app/ops_buttons.c
* app/palette.c
* app/palette_select.c
* app/paths_dialog.c
* app/pattern_select.c
* app/resize.c
* app/scale_toolc.c
* app/text_tool.c:
s/container_border_width/container_set_border_width/g,
s/sprintf/g_snprintf/g, replaced some constant string lengths with
strlen(x).
* app/bezier_select.c
* app/blend.c
* app/boundary.c
* app/errors.[ch]
* app/free_select.c
* app/gimpbrushlist.c
* app/gimprc.c
* app/iscissors.c
* app/main.c
* app/patterns.[ch]
* app/text_tool.c: namespace fanaticism: prefixed all gimp error
functions with "gimp_" and formated the messages more uniformly.
* app/gradient.c
* app/gradient_select.c: same stuff as above for the ui
code. There are still some sub-dialogs which need cleanup.
Did some cleanup in most of these files: prototypes, removed tons
of #include's, i18n fixes, s/w/widget/ as above, indentation, ...
1999-07-23 00:21:10 +08:00
|
|
|
/* g_print ("add to curve cursor\n"); */
|
1999-05-14 06:53:40 +08:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
gdisplay_install_tool_cursor (gdisp, GIMP_MOUSE1_CURSOR);
|
new ui for the "Layer Offset" dialog.
1999-07-22 Michael Natterer <mitschel@cs.tu-berlin.de>
* app/channel_ops.[ch]: new ui for the "Layer Offset" dialog.
* app/channels_dialog.c
* app/layers_dialog.c: major code cleanup: Folded some callbacks
into common ones, "widget" instead of "w", indentation, ...
* app/commands.c
* app/interface.[ch]
* app/global_edit.c: the query boxes must be shown by the caller
now. There's no need to split up the string for the message box
manually as the Gtk 1.2 label widget handles newlines corectly.
Added the "edge_lock" toggle to the "Shrink Selection" dialog.
Nicer spacings for the query and message boxes.
* app/ink.c: tried to grab the pointer in the blob preview but
failed. Left the code there as a reminder (commented out).
* app/menus.c: reordered <Image>/Select.
I was bored and grep-ed the sources for ancient or deprecated stuff:
* app/about_dialog.[ch]
* app/actionarea.[ch]
* app/app_procs.c
* app/brush_edit.c
* app/brush_select.c
* app/color_select.c
* app/convert.c
* app/devices.c
* app/gdisplay.c
* app/gdisplay_ops.c
* app/histogram_tool.[ch]
* app/info_window.c
* app/install.c
* app/ops_buttons.c
* app/palette.c
* app/palette_select.c
* app/paths_dialog.c
* app/pattern_select.c
* app/resize.c
* app/scale_toolc.c
* app/text_tool.c:
s/container_border_width/container_set_border_width/g,
s/sprintf/g_snprintf/g, replaced some constant string lengths with
strlen(x).
* app/bezier_select.c
* app/blend.c
* app/boundary.c
* app/errors.[ch]
* app/free_select.c
* app/gimpbrushlist.c
* app/gimprc.c
* app/iscissors.c
* app/main.c
* app/patterns.[ch]
* app/text_tool.c: namespace fanaticism: prefixed all gimp error
functions with "gimp_" and formated the messages more uniformly.
* app/gradient.c
* app/gradient_select.c: same stuff as above for the ui
code. There are still some sub-dialogs which need cleanup.
Did some cleanup in most of these files: prototypes, removed tons
of #include's, i18n fixes, s/w/widget/ as above, indentation, ...
1999-07-23 00:21:10 +08:00
|
|
|
/* g_print ("default no action cursor\n"); */
|
1999-05-14 06:53:40 +08:00
|
|
|
}
|
|
|
|
break;
|
|
|
|
case EXTEND_EDIT:
|
|
|
|
if(on_control_pnt)
|
|
|
|
{
|
|
|
|
gdisplay_install_tool_cursor (gdisp, GIMP_MOUSE1CP_CURSOR);
|
new ui for the "Layer Offset" dialog.
1999-07-22 Michael Natterer <mitschel@cs.tu-berlin.de>
* app/channel_ops.[ch]: new ui for the "Layer Offset" dialog.
* app/channels_dialog.c
* app/layers_dialog.c: major code cleanup: Folded some callbacks
into common ones, "widget" instead of "w", indentation, ...
* app/commands.c
* app/interface.[ch]
* app/global_edit.c: the query boxes must be shown by the caller
now. There's no need to split up the string for the message box
manually as the Gtk 1.2 label widget handles newlines corectly.
Added the "edge_lock" toggle to the "Shrink Selection" dialog.
Nicer spacings for the query and message boxes.
* app/ink.c: tried to grab the pointer in the blob preview but
failed. Left the code there as a reminder (commented out).
* app/menus.c: reordered <Image>/Select.
I was bored and grep-ed the sources for ancient or deprecated stuff:
* app/about_dialog.[ch]
* app/actionarea.[ch]
* app/app_procs.c
* app/brush_edit.c
* app/brush_select.c
* app/color_select.c
* app/convert.c
* app/devices.c
* app/gdisplay.c
* app/gdisplay_ops.c
* app/histogram_tool.[ch]
* app/info_window.c
* app/install.c
* app/ops_buttons.c
* app/palette.c
* app/palette_select.c
* app/paths_dialog.c
* app/pattern_select.c
* app/resize.c
* app/scale_toolc.c
* app/text_tool.c:
s/container_border_width/container_set_border_width/g,
s/sprintf/g_snprintf/g, replaced some constant string lengths with
strlen(x).
* app/bezier_select.c
* app/blend.c
* app/boundary.c
* app/errors.[ch]
* app/free_select.c
* app/gimpbrushlist.c
* app/gimprc.c
* app/iscissors.c
* app/main.c
* app/patterns.[ch]
* app/text_tool.c: namespace fanaticism: prefixed all gimp error
functions with "gimp_" and formated the messages more uniformly.
* app/gradient.c
* app/gradient_select.c: same stuff as above for the ui
code. There are still some sub-dialogs which need cleanup.
Did some cleanup in most of these files: prototypes, removed tons
of #include's, i18n fixes, s/w/widget/ as above, indentation, ...
1999-07-23 00:21:10 +08:00
|
|
|
/* g_print ("edit control point cursor\n"); */
|
1999-05-14 06:53:40 +08:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
gdisplay_install_tool_cursor (gdisp, GIMP_MOUSE1_CURSOR);
|
new ui for the "Layer Offset" dialog.
1999-07-22 Michael Natterer <mitschel@cs.tu-berlin.de>
* app/channel_ops.[ch]: new ui for the "Layer Offset" dialog.
* app/channels_dialog.c
* app/layers_dialog.c: major code cleanup: Folded some callbacks
into common ones, "widget" instead of "w", indentation, ...
* app/commands.c
* app/interface.[ch]
* app/global_edit.c: the query boxes must be shown by the caller
now. There's no need to split up the string for the message box
manually as the Gtk 1.2 label widget handles newlines corectly.
Added the "edge_lock" toggle to the "Shrink Selection" dialog.
Nicer spacings for the query and message boxes.
* app/ink.c: tried to grab the pointer in the blob preview but
failed. Left the code there as a reminder (commented out).
* app/menus.c: reordered <Image>/Select.
I was bored and grep-ed the sources for ancient or deprecated stuff:
* app/about_dialog.[ch]
* app/actionarea.[ch]
* app/app_procs.c
* app/brush_edit.c
* app/brush_select.c
* app/color_select.c
* app/convert.c
* app/devices.c
* app/gdisplay.c
* app/gdisplay_ops.c
* app/histogram_tool.[ch]
* app/info_window.c
* app/install.c
* app/ops_buttons.c
* app/palette.c
* app/palette_select.c
* app/paths_dialog.c
* app/pattern_select.c
* app/resize.c
* app/scale_toolc.c
* app/text_tool.c:
s/container_border_width/container_set_border_width/g,
s/sprintf/g_snprintf/g, replaced some constant string lengths with
strlen(x).
* app/bezier_select.c
* app/blend.c
* app/boundary.c
* app/errors.[ch]
* app/free_select.c
* app/gimpbrushlist.c
* app/gimprc.c
* app/iscissors.c
* app/main.c
* app/patterns.[ch]
* app/text_tool.c: namespace fanaticism: prefixed all gimp error
functions with "gimp_" and formated the messages more uniformly.
* app/gradient.c
* app/gradient_select.c: same stuff as above for the ui
code. There are still some sub-dialogs which need cleanup.
Did some cleanup in most of these files: prototypes, removed tons
of #include's, i18n fixes, s/w/widget/ as above, indentation, ...
1999-07-23 00:21:10 +08:00
|
|
|
/* g_print ("default no action cursor\n"); */
|
1999-05-14 06:53:40 +08:00
|
|
|
}
|
|
|
|
break;
|
|
|
|
case EXTEND_REMOVE:
|
|
|
|
if(on_control_pnt && mevent->state & GDK_SHIFT_MASK)
|
|
|
|
{
|
|
|
|
gdisplay_install_tool_cursor (gdisp, GIMP_MOUSE1M_CURSOR);
|
new ui for the "Layer Offset" dialog.
1999-07-22 Michael Natterer <mitschel@cs.tu-berlin.de>
* app/channel_ops.[ch]: new ui for the "Layer Offset" dialog.
* app/channels_dialog.c
* app/layers_dialog.c: major code cleanup: Folded some callbacks
into common ones, "widget" instead of "w", indentation, ...
* app/commands.c
* app/interface.[ch]
* app/global_edit.c: the query boxes must be shown by the caller
now. There's no need to split up the string for the message box
manually as the Gtk 1.2 label widget handles newlines corectly.
Added the "edge_lock" toggle to the "Shrink Selection" dialog.
Nicer spacings for the query and message boxes.
* app/ink.c: tried to grab the pointer in the blob preview but
failed. Left the code there as a reminder (commented out).
* app/menus.c: reordered <Image>/Select.
I was bored and grep-ed the sources for ancient or deprecated stuff:
* app/about_dialog.[ch]
* app/actionarea.[ch]
* app/app_procs.c
* app/brush_edit.c
* app/brush_select.c
* app/color_select.c
* app/convert.c
* app/devices.c
* app/gdisplay.c
* app/gdisplay_ops.c
* app/histogram_tool.[ch]
* app/info_window.c
* app/install.c
* app/ops_buttons.c
* app/palette.c
* app/palette_select.c
* app/paths_dialog.c
* app/pattern_select.c
* app/resize.c
* app/scale_toolc.c
* app/text_tool.c:
s/container_border_width/container_set_border_width/g,
s/sprintf/g_snprintf/g, replaced some constant string lengths with
strlen(x).
* app/bezier_select.c
* app/blend.c
* app/boundary.c
* app/errors.[ch]
* app/free_select.c
* app/gimpbrushlist.c
* app/gimprc.c
* app/iscissors.c
* app/main.c
* app/patterns.[ch]
* app/text_tool.c: namespace fanaticism: prefixed all gimp error
functions with "gimp_" and formated the messages more uniformly.
* app/gradient.c
* app/gradient_select.c: same stuff as above for the ui
code. There are still some sub-dialogs which need cleanup.
Did some cleanup in most of these files: prototypes, removed tons
of #include's, i18n fixes, s/w/widget/ as above, indentation, ...
1999-07-23 00:21:10 +08:00
|
|
|
g_print ("delete whole curve cursor\n");
|
1999-05-14 06:53:40 +08:00
|
|
|
}
|
|
|
|
else if(on_control_pnt)
|
|
|
|
{
|
|
|
|
gdisplay_install_tool_cursor (gdisp, GIMP_MOUSE1M_CURSOR);
|
new ui for the "Layer Offset" dialog.
1999-07-22 Michael Natterer <mitschel@cs.tu-berlin.de>
* app/channel_ops.[ch]: new ui for the "Layer Offset" dialog.
* app/channels_dialog.c
* app/layers_dialog.c: major code cleanup: Folded some callbacks
into common ones, "widget" instead of "w", indentation, ...
* app/commands.c
* app/interface.[ch]
* app/global_edit.c: the query boxes must be shown by the caller
now. There's no need to split up the string for the message box
manually as the Gtk 1.2 label widget handles newlines corectly.
Added the "edge_lock" toggle to the "Shrink Selection" dialog.
Nicer spacings for the query and message boxes.
* app/ink.c: tried to grab the pointer in the blob preview but
failed. Left the code there as a reminder (commented out).
* app/menus.c: reordered <Image>/Select.
I was bored and grep-ed the sources for ancient or deprecated stuff:
* app/about_dialog.[ch]
* app/actionarea.[ch]
* app/app_procs.c
* app/brush_edit.c
* app/brush_select.c
* app/color_select.c
* app/convert.c
* app/devices.c
* app/gdisplay.c
* app/gdisplay_ops.c
* app/histogram_tool.[ch]
* app/info_window.c
* app/install.c
* app/ops_buttons.c
* app/palette.c
* app/palette_select.c
* app/paths_dialog.c
* app/pattern_select.c
* app/resize.c
* app/scale_toolc.c
* app/text_tool.c:
s/container_border_width/container_set_border_width/g,
s/sprintf/g_snprintf/g, replaced some constant string lengths with
strlen(x).
* app/bezier_select.c
* app/blend.c
* app/boundary.c
* app/errors.[ch]
* app/free_select.c
* app/gimpbrushlist.c
* app/gimprc.c
* app/iscissors.c
* app/main.c
* app/patterns.[ch]
* app/text_tool.c: namespace fanaticism: prefixed all gimp error
functions with "gimp_" and formated the messages more uniformly.
* app/gradient.c
* app/gradient_select.c: same stuff as above for the ui
code. There are still some sub-dialogs which need cleanup.
Did some cleanup in most of these files: prototypes, removed tons
of #include's, i18n fixes, s/w/widget/ as above, indentation, ...
1999-07-23 00:21:10 +08:00
|
|
|
/* g_print ("remove point cursor\n"); */
|
1999-05-14 06:53:40 +08:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
gdisplay_install_tool_cursor (gdisp, GIMP_MOUSE1_CURSOR);
|
new ui for the "Layer Offset" dialog.
1999-07-22 Michael Natterer <mitschel@cs.tu-berlin.de>
* app/channel_ops.[ch]: new ui for the "Layer Offset" dialog.
* app/channels_dialog.c
* app/layers_dialog.c: major code cleanup: Folded some callbacks
into common ones, "widget" instead of "w", indentation, ...
* app/commands.c
* app/interface.[ch]
* app/global_edit.c: the query boxes must be shown by the caller
now. There's no need to split up the string for the message box
manually as the Gtk 1.2 label widget handles newlines corectly.
Added the "edge_lock" toggle to the "Shrink Selection" dialog.
Nicer spacings for the query and message boxes.
* app/ink.c: tried to grab the pointer in the blob preview but
failed. Left the code there as a reminder (commented out).
* app/menus.c: reordered <Image>/Select.
I was bored and grep-ed the sources for ancient or deprecated stuff:
* app/about_dialog.[ch]
* app/actionarea.[ch]
* app/app_procs.c
* app/brush_edit.c
* app/brush_select.c
* app/color_select.c
* app/convert.c
* app/devices.c
* app/gdisplay.c
* app/gdisplay_ops.c
* app/histogram_tool.[ch]
* app/info_window.c
* app/install.c
* app/ops_buttons.c
* app/palette.c
* app/palette_select.c
* app/paths_dialog.c
* app/pattern_select.c
* app/resize.c
* app/scale_toolc.c
* app/text_tool.c:
s/container_border_width/container_set_border_width/g,
s/sprintf/g_snprintf/g, replaced some constant string lengths with
strlen(x).
* app/bezier_select.c
* app/blend.c
* app/boundary.c
* app/errors.[ch]
* app/free_select.c
* app/gimpbrushlist.c
* app/gimprc.c
* app/iscissors.c
* app/main.c
* app/patterns.[ch]
* app/text_tool.c: namespace fanaticism: prefixed all gimp error
functions with "gimp_" and formated the messages more uniformly.
* app/gradient.c
* app/gradient_select.c: same stuff as above for the ui
code. There are still some sub-dialogs which need cleanup.
Did some cleanup in most of these files: prototypes, removed tons
of #include's, i18n fixes, s/w/widget/ as above, indentation, ...
1999-07-23 00:21:10 +08:00
|
|
|
/* g_print ("default no action cursor\n"); */
|
1999-05-14 06:53:40 +08:00
|
|
|
}
|
|
|
|
break;
|
|
|
|
default:
|
new ui for the "Layer Offset" dialog.
1999-07-22 Michael Natterer <mitschel@cs.tu-berlin.de>
* app/channel_ops.[ch]: new ui for the "Layer Offset" dialog.
* app/channels_dialog.c
* app/layers_dialog.c: major code cleanup: Folded some callbacks
into common ones, "widget" instead of "w", indentation, ...
* app/commands.c
* app/interface.[ch]
* app/global_edit.c: the query boxes must be shown by the caller
now. There's no need to split up the string for the message box
manually as the Gtk 1.2 label widget handles newlines corectly.
Added the "edge_lock" toggle to the "Shrink Selection" dialog.
Nicer spacings for the query and message boxes.
* app/ink.c: tried to grab the pointer in the blob preview but
failed. Left the code there as a reminder (commented out).
* app/menus.c: reordered <Image>/Select.
I was bored and grep-ed the sources for ancient or deprecated stuff:
* app/about_dialog.[ch]
* app/actionarea.[ch]
* app/app_procs.c
* app/brush_edit.c
* app/brush_select.c
* app/color_select.c
* app/convert.c
* app/devices.c
* app/gdisplay.c
* app/gdisplay_ops.c
* app/histogram_tool.[ch]
* app/info_window.c
* app/install.c
* app/ops_buttons.c
* app/palette.c
* app/palette_select.c
* app/paths_dialog.c
* app/pattern_select.c
* app/resize.c
* app/scale_toolc.c
* app/text_tool.c:
s/container_border_width/container_set_border_width/g,
s/sprintf/g_snprintf/g, replaced some constant string lengths with
strlen(x).
* app/bezier_select.c
* app/blend.c
* app/boundary.c
* app/errors.[ch]
* app/free_select.c
* app/gimpbrushlist.c
* app/gimprc.c
* app/iscissors.c
* app/main.c
* app/patterns.[ch]
* app/text_tool.c: namespace fanaticism: prefixed all gimp error
functions with "gimp_" and formated the messages more uniformly.
* app/gradient.c
* app/gradient_select.c: same stuff as above for the ui
code. There are still some sub-dialogs which need cleanup.
Did some cleanup in most of these files: prototypes, removed tons
of #include's, i18n fixes, s/w/widget/ as above, indentation, ...
1999-07-23 00:21:10 +08:00
|
|
|
g_print ("In default\n");
|
1999-05-14 06:53:40 +08:00
|
|
|
gdisplay_install_tool_cursor (gdisp, GIMP_MOUSE1_CURSOR);
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
1997-11-25 06:05:25 +08:00
|
|
|
static void
|
1999-06-22 06:12:07 +08:00
|
|
|
bezier_select_control (Tool *tool,
|
|
|
|
ToolAction action,
|
|
|
|
gpointer gdisp_ptr)
|
1997-11-25 06:05:25 +08:00
|
|
|
{
|
|
|
|
BezierSelect * bezier_sel;
|
|
|
|
|
|
|
|
bezier_sel = tool->private;
|
|
|
|
|
|
|
|
switch (action)
|
|
|
|
{
|
|
|
|
case PAUSE :
|
|
|
|
draw_core_pause (bezier_sel->core, tool);
|
|
|
|
break;
|
1999-06-22 06:12:07 +08:00
|
|
|
|
1997-11-25 06:05:25 +08:00
|
|
|
case RESUME :
|
|
|
|
draw_core_resume (bezier_sel->core, tool);
|
|
|
|
break;
|
1999-06-22 06:12:07 +08:00
|
|
|
|
1997-11-25 06:05:25 +08:00
|
|
|
case HALT :
|
|
|
|
draw_core_stop (bezier_sel->core, tool);
|
|
|
|
bezier_select_reset (bezier_sel);
|
|
|
|
break;
|
1999-06-22 06:12:07 +08:00
|
|
|
|
1999-03-06 07:50:24 +08:00
|
|
|
default:
|
|
|
|
break;
|
1997-11-25 06:05:25 +08:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
1999-05-27 04:36:33 +08:00
|
|
|
void
|
|
|
|
bezier_draw(GDisplay * gdisp,BezierSelect * bezier_sel)
|
1997-11-25 06:05:25 +08:00
|
|
|
{
|
|
|
|
BezierPoint * points;
|
|
|
|
int num_points;
|
|
|
|
int draw_curve;
|
|
|
|
int draw_handles;
|
|
|
|
int draw_current;
|
|
|
|
|
|
|
|
|
|
|
|
if (!bezier_sel->draw)
|
|
|
|
return;
|
|
|
|
|
|
|
|
draw_curve = bezier_sel->draw & BEZIER_DRAW_CURVE;
|
|
|
|
draw_current = bezier_sel->draw & BEZIER_DRAW_CURRENT;
|
|
|
|
draw_handles = bezier_sel->draw & BEZIER_DRAW_HANDLES;
|
|
|
|
|
|
|
|
/* reset to the default drawing state of drawing the curve and handles */
|
|
|
|
bezier_sel->draw = BEZIER_DRAW_ALL;
|
|
|
|
|
|
|
|
/* transform the points from image space to screen space */
|
|
|
|
points = bezier_sel->points;
|
|
|
|
num_points = bezier_sel->num_points;
|
|
|
|
|
|
|
|
while (points && num_points)
|
|
|
|
{
|
|
|
|
gdisplay_transform_coords (gdisp, points->x, points->y,
|
|
|
|
&points->sx, &points->sy, 0);
|
1999-05-14 06:53:40 +08:00
|
|
|
if(points->next_curve)
|
|
|
|
points = points->next_curve;
|
|
|
|
else
|
|
|
|
points = points->next;
|
1997-11-25 06:05:25 +08:00
|
|
|
num_points--;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (draw_curve)
|
1999-05-27 04:36:33 +08:00
|
|
|
{
|
|
|
|
bezier_draw_curve (bezier_sel,bezier_draw_segment_points,SCREEN_COORDS,NULL);
|
|
|
|
bezier_draw_handles (bezier_sel,1);
|
|
|
|
}
|
|
|
|
else if (draw_current)
|
|
|
|
{
|
|
|
|
bezier_draw_current (bezier_sel);
|
|
|
|
bezier_draw_handles (bezier_sel,0);
|
|
|
|
}
|
|
|
|
else if (draw_handles)
|
|
|
|
bezier_draw_handles (bezier_sel,0);
|
1999-03-06 07:50:24 +08:00
|
|
|
|
1997-11-25 06:05:25 +08:00
|
|
|
}
|
|
|
|
|
1999-05-27 04:36:33 +08:00
|
|
|
static void
|
|
|
|
bezier_select_draw (Tool *tool)
|
|
|
|
{
|
|
|
|
GDisplay * gdisp;
|
|
|
|
BezierSelect * bezier_sel;
|
|
|
|
|
|
|
|
gdisp = tool->gdisp_ptr;
|
|
|
|
bezier_sel = tool->private;
|
|
|
|
|
|
|
|
bezier_draw(gdisp,bezier_sel);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
1999-03-06 07:50:24 +08:00
|
|
|
void
|
1997-11-25 06:05:25 +08:00
|
|
|
bezier_add_point (BezierSelect *bezier_sel,
|
|
|
|
int type,
|
1999-05-14 06:53:40 +08:00
|
|
|
gdouble x,
|
|
|
|
gdouble y)
|
1997-11-25 06:05:25 +08:00
|
|
|
{
|
|
|
|
BezierPoint *newpt;
|
|
|
|
|
1999-05-14 06:53:40 +08:00
|
|
|
newpt = g_new0 (BezierPoint,1);
|
1997-11-25 06:05:25 +08:00
|
|
|
|
|
|
|
newpt->type = type;
|
|
|
|
newpt->x = x;
|
|
|
|
newpt->y = y;
|
|
|
|
newpt->next = NULL;
|
|
|
|
newpt->prev = NULL;
|
1999-05-14 06:53:40 +08:00
|
|
|
newpt->next_curve = NULL;
|
1997-11-25 06:05:25 +08:00
|
|
|
|
1999-05-14 06:53:40 +08:00
|
|
|
if(type == BEZIER_MOVE &&
|
|
|
|
bezier_sel->last_point)
|
1997-11-25 06:05:25 +08:00
|
|
|
{
|
new ui for the "Layer Offset" dialog.
1999-07-22 Michael Natterer <mitschel@cs.tu-berlin.de>
* app/channel_ops.[ch]: new ui for the "Layer Offset" dialog.
* app/channels_dialog.c
* app/layers_dialog.c: major code cleanup: Folded some callbacks
into common ones, "widget" instead of "w", indentation, ...
* app/commands.c
* app/interface.[ch]
* app/global_edit.c: the query boxes must be shown by the caller
now. There's no need to split up the string for the message box
manually as the Gtk 1.2 label widget handles newlines corectly.
Added the "edge_lock" toggle to the "Shrink Selection" dialog.
Nicer spacings for the query and message boxes.
* app/ink.c: tried to grab the pointer in the blob preview but
failed. Left the code there as a reminder (commented out).
* app/menus.c: reordered <Image>/Select.
I was bored and grep-ed the sources for ancient or deprecated stuff:
* app/about_dialog.[ch]
* app/actionarea.[ch]
* app/app_procs.c
* app/brush_edit.c
* app/brush_select.c
* app/color_select.c
* app/convert.c
* app/devices.c
* app/gdisplay.c
* app/gdisplay_ops.c
* app/histogram_tool.[ch]
* app/info_window.c
* app/install.c
* app/ops_buttons.c
* app/palette.c
* app/palette_select.c
* app/paths_dialog.c
* app/pattern_select.c
* app/resize.c
* app/scale_toolc.c
* app/text_tool.c:
s/container_border_width/container_set_border_width/g,
s/sprintf/g_snprintf/g, replaced some constant string lengths with
strlen(x).
* app/bezier_select.c
* app/blend.c
* app/boundary.c
* app/errors.[ch]
* app/free_select.c
* app/gimpbrushlist.c
* app/gimprc.c
* app/iscissors.c
* app/main.c
* app/patterns.[ch]
* app/text_tool.c: namespace fanaticism: prefixed all gimp error
functions with "gimp_" and formated the messages more uniformly.
* app/gradient.c
* app/gradient_select.c: same stuff as above for the ui
code. There are still some sub-dialogs which need cleanup.
Did some cleanup in most of these files: prototypes, removed tons
of #include's, i18n fixes, s/w/widget/ as above, indentation, ...
1999-07-23 00:21:10 +08:00
|
|
|
/* g_print ("Adding move point\n"); */
|
1999-05-14 06:53:40 +08:00
|
|
|
newpt->type = BEZIER_ANCHOR;
|
|
|
|
bezier_sel->last_point->next_curve = newpt;
|
1997-11-25 06:05:25 +08:00
|
|
|
bezier_sel->last_point = newpt;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
1999-05-14 06:53:40 +08:00
|
|
|
if(type == BEZIER_MOVE)
|
|
|
|
{
|
|
|
|
newpt->type = BEZIER_ANCHOR;
|
new ui for the "Layer Offset" dialog.
1999-07-22 Michael Natterer <mitschel@cs.tu-berlin.de>
* app/channel_ops.[ch]: new ui for the "Layer Offset" dialog.
* app/channels_dialog.c
* app/layers_dialog.c: major code cleanup: Folded some callbacks
into common ones, "widget" instead of "w", indentation, ...
* app/commands.c
* app/interface.[ch]
* app/global_edit.c: the query boxes must be shown by the caller
now. There's no need to split up the string for the message box
manually as the Gtk 1.2 label widget handles newlines corectly.
Added the "edge_lock" toggle to the "Shrink Selection" dialog.
Nicer spacings for the query and message boxes.
* app/ink.c: tried to grab the pointer in the blob preview but
failed. Left the code there as a reminder (commented out).
* app/menus.c: reordered <Image>/Select.
I was bored and grep-ed the sources for ancient or deprecated stuff:
* app/about_dialog.[ch]
* app/actionarea.[ch]
* app/app_procs.c
* app/brush_edit.c
* app/brush_select.c
* app/color_select.c
* app/convert.c
* app/devices.c
* app/gdisplay.c
* app/gdisplay_ops.c
* app/histogram_tool.[ch]
* app/info_window.c
* app/install.c
* app/ops_buttons.c
* app/palette.c
* app/palette_select.c
* app/paths_dialog.c
* app/pattern_select.c
* app/resize.c
* app/scale_toolc.c
* app/text_tool.c:
s/container_border_width/container_set_border_width/g,
s/sprintf/g_snprintf/g, replaced some constant string lengths with
strlen(x).
* app/bezier_select.c
* app/blend.c
* app/boundary.c
* app/errors.[ch]
* app/free_select.c
* app/gimpbrushlist.c
* app/gimprc.c
* app/iscissors.c
* app/main.c
* app/patterns.[ch]
* app/text_tool.c: namespace fanaticism: prefixed all gimp error
functions with "gimp_" and formated the messages more uniformly.
* app/gradient.c
* app/gradient_select.c: same stuff as above for the ui
code. There are still some sub-dialogs which need cleanup.
Did some cleanup in most of these files: prototypes, removed tons
of #include's, i18n fixes, s/w/widget/ as above, indentation, ...
1999-07-23 00:21:10 +08:00
|
|
|
/* g_print ("Adding MOVE point to null curve\n"); */
|
1999-05-14 06:53:40 +08:00
|
|
|
}
|
1997-11-25 06:05:25 +08:00
|
|
|
|
1999-05-14 06:53:40 +08:00
|
|
|
if (bezier_sel->last_point)
|
|
|
|
{
|
|
|
|
bezier_sel->last_point->next = newpt;
|
|
|
|
newpt->prev = bezier_sel->last_point;
|
|
|
|
bezier_sel->last_point = newpt;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
bezier_sel->points = newpt;
|
|
|
|
bezier_sel->last_point = newpt;
|
|
|
|
}
|
|
|
|
|
|
|
|
switch (type)
|
|
|
|
{
|
|
|
|
case BEZIER_ANCHOR:
|
|
|
|
bezier_sel->cur_anchor = newpt;
|
|
|
|
break;
|
|
|
|
case BEZIER_CONTROL:
|
|
|
|
bezier_sel->cur_control = newpt;
|
|
|
|
break;
|
|
|
|
}
|
1997-11-25 06:05:25 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
bezier_sel->num_points += 1;
|
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
|
|
|
bezier_offset_point (BezierPoint *pt,
|
|
|
|
int x,
|
|
|
|
int y)
|
|
|
|
{
|
|
|
|
if (pt)
|
|
|
|
{
|
|
|
|
pt->x += x;
|
|
|
|
pt->y += y;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
static int
|
|
|
|
bezier_check_point (BezierPoint *pt,
|
|
|
|
int x,
|
|
|
|
int y,
|
|
|
|
int halfwidth)
|
|
|
|
{
|
|
|
|
int l, r, t, b;
|
|
|
|
|
|
|
|
if (pt)
|
|
|
|
{
|
|
|
|
l = pt->x - halfwidth;
|
|
|
|
r = pt->x + halfwidth;
|
|
|
|
t = pt->y - halfwidth;
|
|
|
|
b = pt->y + halfwidth;
|
|
|
|
|
|
|
|
return ((x >= l) && (x <= r) && (y >= t) && (y <= b));
|
|
|
|
}
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
static void
|
1999-05-27 04:36:33 +08:00
|
|
|
bezier_draw_handles (BezierSelect *bezier_sel,gint doAll)
|
1997-11-25 06:05:25 +08:00
|
|
|
{
|
|
|
|
BezierPoint * points;
|
|
|
|
int num_points;
|
|
|
|
|
new ui for the "Layer Offset" dialog.
1999-07-22 Michael Natterer <mitschel@cs.tu-berlin.de>
* app/channel_ops.[ch]: new ui for the "Layer Offset" dialog.
* app/channels_dialog.c
* app/layers_dialog.c: major code cleanup: Folded some callbacks
into common ones, "widget" instead of "w", indentation, ...
* app/commands.c
* app/interface.[ch]
* app/global_edit.c: the query boxes must be shown by the caller
now. There's no need to split up the string for the message box
manually as the Gtk 1.2 label widget handles newlines corectly.
Added the "edge_lock" toggle to the "Shrink Selection" dialog.
Nicer spacings for the query and message boxes.
* app/ink.c: tried to grab the pointer in the blob preview but
failed. Left the code there as a reminder (commented out).
* app/menus.c: reordered <Image>/Select.
I was bored and grep-ed the sources for ancient or deprecated stuff:
* app/about_dialog.[ch]
* app/actionarea.[ch]
* app/app_procs.c
* app/brush_edit.c
* app/brush_select.c
* app/color_select.c
* app/convert.c
* app/devices.c
* app/gdisplay.c
* app/gdisplay_ops.c
* app/histogram_tool.[ch]
* app/info_window.c
* app/install.c
* app/ops_buttons.c
* app/palette.c
* app/palette_select.c
* app/paths_dialog.c
* app/pattern_select.c
* app/resize.c
* app/scale_toolc.c
* app/text_tool.c:
s/container_border_width/container_set_border_width/g,
s/sprintf/g_snprintf/g, replaced some constant string lengths with
strlen(x).
* app/bezier_select.c
* app/blend.c
* app/boundary.c
* app/errors.[ch]
* app/free_select.c
* app/gimpbrushlist.c
* app/gimprc.c
* app/iscissors.c
* app/main.c
* app/patterns.[ch]
* app/text_tool.c: namespace fanaticism: prefixed all gimp error
functions with "gimp_" and formated the messages more uniformly.
* app/gradient.c
* app/gradient_select.c: same stuff as above for the ui
code. There are still some sub-dialogs which need cleanup.
Did some cleanup in most of these files: prototypes, removed tons
of #include's, i18n fixes, s/w/widget/ as above, indentation, ...
1999-07-23 00:21:10 +08:00
|
|
|
/* g_print ("bezier_draw_handles cur_anchor = %p\n",bezier_sel->cur_anchor); */
|
1999-05-14 06:53:40 +08:00
|
|
|
|
1997-11-25 06:05:25 +08:00
|
|
|
points = bezier_sel->points;
|
|
|
|
num_points = bezier_sel->num_points;
|
1999-05-14 06:53:40 +08:00
|
|
|
|
1997-11-25 06:05:25 +08:00
|
|
|
if (num_points <= 0)
|
|
|
|
return;
|
|
|
|
|
1999-05-14 06:53:40 +08:00
|
|
|
while (num_points && num_points > 0)
|
|
|
|
{
|
|
|
|
if (points == bezier_sel->cur_anchor)
|
|
|
|
{
|
new ui for the "Layer Offset" dialog.
1999-07-22 Michael Natterer <mitschel@cs.tu-berlin.de>
* app/channel_ops.[ch]: new ui for the "Layer Offset" dialog.
* app/channels_dialog.c
* app/layers_dialog.c: major code cleanup: Folded some callbacks
into common ones, "widget" instead of "w", indentation, ...
* app/commands.c
* app/interface.[ch]
* app/global_edit.c: the query boxes must be shown by the caller
now. There's no need to split up the string for the message box
manually as the Gtk 1.2 label widget handles newlines corectly.
Added the "edge_lock" toggle to the "Shrink Selection" dialog.
Nicer spacings for the query and message boxes.
* app/ink.c: tried to grab the pointer in the blob preview but
failed. Left the code there as a reminder (commented out).
* app/menus.c: reordered <Image>/Select.
I was bored and grep-ed the sources for ancient or deprecated stuff:
* app/about_dialog.[ch]
* app/actionarea.[ch]
* app/app_procs.c
* app/brush_edit.c
* app/brush_select.c
* app/color_select.c
* app/convert.c
* app/devices.c
* app/gdisplay.c
* app/gdisplay_ops.c
* app/histogram_tool.[ch]
* app/info_window.c
* app/install.c
* app/ops_buttons.c
* app/palette.c
* app/palette_select.c
* app/paths_dialog.c
* app/pattern_select.c
* app/resize.c
* app/scale_toolc.c
* app/text_tool.c:
s/container_border_width/container_set_border_width/g,
s/sprintf/g_snprintf/g, replaced some constant string lengths with
strlen(x).
* app/bezier_select.c
* app/blend.c
* app/boundary.c
* app/errors.[ch]
* app/free_select.c
* app/gimpbrushlist.c
* app/gimprc.c
* app/iscissors.c
* app/main.c
* app/patterns.[ch]
* app/text_tool.c: namespace fanaticism: prefixed all gimp error
functions with "gimp_" and formated the messages more uniformly.
* app/gradient.c
* app/gradient_select.c: same stuff as above for the ui
code. There are still some sub-dialogs which need cleanup.
Did some cleanup in most of these files: prototypes, removed tons
of #include's, i18n fixes, s/w/widget/ as above, indentation, ...
1999-07-23 00:21:10 +08:00
|
|
|
/* g_print ("bezier_draw_handles:: found cur_anchor %p\n",points); */
|
1999-05-14 06:53:40 +08:00
|
|
|
bezier_draw_point (bezier_sel, points, 0);
|
|
|
|
bezier_draw_point (bezier_sel, points->next, 0);
|
|
|
|
bezier_draw_point (bezier_sel, points->prev, 0);
|
|
|
|
bezier_draw_line (bezier_sel, points, points->next);
|
|
|
|
bezier_draw_line (bezier_sel, points, points->prev);
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
new ui for the "Layer Offset" dialog.
1999-07-22 Michael Natterer <mitschel@cs.tu-berlin.de>
* app/channel_ops.[ch]: new ui for the "Layer Offset" dialog.
* app/channels_dialog.c
* app/layers_dialog.c: major code cleanup: Folded some callbacks
into common ones, "widget" instead of "w", indentation, ...
* app/commands.c
* app/interface.[ch]
* app/global_edit.c: the query boxes must be shown by the caller
now. There's no need to split up the string for the message box
manually as the Gtk 1.2 label widget handles newlines corectly.
Added the "edge_lock" toggle to the "Shrink Selection" dialog.
Nicer spacings for the query and message boxes.
* app/ink.c: tried to grab the pointer in the blob preview but
failed. Left the code there as a reminder (commented out).
* app/menus.c: reordered <Image>/Select.
I was bored and grep-ed the sources for ancient or deprecated stuff:
* app/about_dialog.[ch]
* app/actionarea.[ch]
* app/app_procs.c
* app/brush_edit.c
* app/brush_select.c
* app/color_select.c
* app/convert.c
* app/devices.c
* app/gdisplay.c
* app/gdisplay_ops.c
* app/histogram_tool.[ch]
* app/info_window.c
* app/install.c
* app/ops_buttons.c
* app/palette.c
* app/palette_select.c
* app/paths_dialog.c
* app/pattern_select.c
* app/resize.c
* app/scale_toolc.c
* app/text_tool.c:
s/container_border_width/container_set_border_width/g,
s/sprintf/g_snprintf/g, replaced some constant string lengths with
strlen(x).
* app/bezier_select.c
* app/blend.c
* app/boundary.c
* app/errors.[ch]
* app/free_select.c
* app/gimpbrushlist.c
* app/gimprc.c
* app/iscissors.c
* app/main.c
* app/patterns.[ch]
* app/text_tool.c: namespace fanaticism: prefixed all gimp error
functions with "gimp_" and formated the messages more uniformly.
* app/gradient.c
* app/gradient_select.c: same stuff as above for the ui
code. There are still some sub-dialogs which need cleanup.
Did some cleanup in most of these files: prototypes, removed tons
of #include's, i18n fixes, s/w/widget/ as above, indentation, ...
1999-07-23 00:21:10 +08:00
|
|
|
/* g_print ("bezier_draw_handles:: not found cur_anchor %p\n",points); */
|
1999-05-27 04:36:33 +08:00
|
|
|
if(doAll || points->pointflags == 1)
|
|
|
|
{
|
|
|
|
bezier_draw_point (bezier_sel, points, 1);
|
|
|
|
points->pointflags = 0;
|
|
|
|
}
|
1999-05-14 06:53:40 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
if(points)
|
1997-11-25 06:05:25 +08:00
|
|
|
{
|
1999-05-14 06:53:40 +08:00
|
|
|
if(points->next_curve)
|
|
|
|
points = points->next_curve;
|
|
|
|
else
|
|
|
|
points = points->next;
|
1997-11-25 06:05:25 +08:00
|
|
|
}
|
1999-05-14 06:53:40 +08:00
|
|
|
|
|
|
|
if(points)
|
|
|
|
{
|
|
|
|
if(points->next_curve)
|
|
|
|
points = points->next_curve;
|
|
|
|
else
|
|
|
|
points = points->next;
|
|
|
|
}
|
|
|
|
|
|
|
|
if(points)
|
1997-11-25 06:05:25 +08:00
|
|
|
{
|
1999-05-14 06:53:40 +08:00
|
|
|
if(points->next_curve)
|
|
|
|
points = points->next_curve;
|
|
|
|
else
|
|
|
|
points = points->next;
|
1997-11-25 06:05:25 +08:00
|
|
|
}
|
|
|
|
|
1999-05-14 06:53:40 +08:00
|
|
|
num_points -= 3;
|
|
|
|
}
|
1997-11-25 06:05:25 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
|
|
|
bezier_draw_current (BezierSelect *bezier_sel)
|
|
|
|
{
|
|
|
|
BezierPoint * points;
|
|
|
|
|
|
|
|
points = bezier_sel->cur_anchor;
|
|
|
|
|
|
|
|
if (points) points = points->prev;
|
|
|
|
if (points) points = points->prev;
|
|
|
|
if (points) points = points->prev;
|
|
|
|
|
|
|
|
if (points)
|
|
|
|
bezier_draw_segment (bezier_sel, points,
|
|
|
|
SUBDIVIDE, SCREEN_COORDS,
|
1999-04-06 07:33:50 +08:00
|
|
|
bezier_draw_segment_points,
|
|
|
|
NULL);
|
1997-11-25 06:05:25 +08:00
|
|
|
|
|
|
|
if (points != bezier_sel->cur_anchor)
|
|
|
|
{
|
|
|
|
points = bezier_sel->cur_anchor;
|
|
|
|
|
|
|
|
if (points) points = points->next;
|
|
|
|
if (points) points = points->next;
|
|
|
|
if (points) points = points->next;
|
|
|
|
|
|
|
|
if (points)
|
|
|
|
bezier_draw_segment (bezier_sel, bezier_sel->cur_anchor,
|
|
|
|
SUBDIVIDE, SCREEN_COORDS,
|
1999-04-06 07:33:50 +08:00
|
|
|
bezier_draw_segment_points,
|
|
|
|
NULL);
|
1997-11-25 06:05:25 +08:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
|
|
|
bezier_draw_point (BezierSelect *bezier_sel,
|
|
|
|
BezierPoint *pt,
|
|
|
|
int fill)
|
|
|
|
{
|
|
|
|
if (pt)
|
|
|
|
{
|
|
|
|
switch (pt->type)
|
|
|
|
{
|
|
|
|
case BEZIER_ANCHOR:
|
|
|
|
if (fill)
|
|
|
|
{
|
|
|
|
gdk_draw_arc (bezier_sel->core->win, bezier_sel->core->gc, 1,
|
|
|
|
pt->sx - BEZIER_HALFWIDTH, pt->sy - BEZIER_HALFWIDTH,
|
|
|
|
BEZIER_WIDTH, BEZIER_WIDTH, 0, 23040);
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
gdk_draw_arc (bezier_sel->core->win, bezier_sel->core->gc, 0,
|
|
|
|
pt->sx - BEZIER_HALFWIDTH, pt->sy - BEZIER_HALFWIDTH,
|
|
|
|
BEZIER_WIDTH, BEZIER_WIDTH, 0, 23040);
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
case BEZIER_CONTROL:
|
|
|
|
if (fill)
|
|
|
|
{
|
|
|
|
gdk_draw_rectangle (bezier_sel->core->win, bezier_sel->core->gc, 1,
|
|
|
|
pt->sx - BEZIER_HALFWIDTH, pt->sy - BEZIER_HALFWIDTH,
|
|
|
|
BEZIER_WIDTH, BEZIER_WIDTH);
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
gdk_draw_rectangle (bezier_sel->core->win, bezier_sel->core->gc, 0,
|
|
|
|
pt->sx - BEZIER_HALFWIDTH, pt->sy - BEZIER_HALFWIDTH,
|
|
|
|
BEZIER_WIDTH, BEZIER_WIDTH);
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
|
|
|
bezier_draw_line (BezierSelect *bezier_sel,
|
|
|
|
BezierPoint *pt1,
|
|
|
|
BezierPoint *pt2)
|
|
|
|
{
|
|
|
|
if (pt1 && pt2)
|
|
|
|
{
|
|
|
|
gdk_draw_line (bezier_sel->core->win,
|
|
|
|
bezier_sel->core->gc,
|
|
|
|
pt1->sx, pt1->sy, pt2->sx, pt2->sy);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
|
|
|
bezier_draw_segment (BezierSelect *bezier_sel,
|
|
|
|
BezierPoint *points,
|
|
|
|
int subdivisions,
|
|
|
|
int space,
|
1999-04-06 07:33:50 +08:00
|
|
|
BezierPointsFunc points_func,
|
|
|
|
gpointer udata)
|
1997-11-25 06:05:25 +08:00
|
|
|
{
|
|
|
|
static GdkPoint gdk_points[256];
|
|
|
|
static int npoints = 256;
|
|
|
|
|
|
|
|
BezierMatrix geometry;
|
|
|
|
BezierMatrix tmp1, tmp2;
|
|
|
|
BezierMatrix deltas;
|
|
|
|
double x, dx, dx2, dx3;
|
|
|
|
double y, dy, dy2, dy3;
|
|
|
|
double d, d2, d3;
|
1999-05-14 06:53:40 +08:00
|
|
|
int lastx, lasty;
|
|
|
|
int newx, newy;
|
1997-11-25 06:05:25 +08:00
|
|
|
int index;
|
|
|
|
int i;
|
|
|
|
|
|
|
|
/* construct the geometry matrix from the segment */
|
|
|
|
/* assumes that a valid segment containing 4 points is passed in */
|
|
|
|
|
|
|
|
for (i = 0; i < 4; i++)
|
|
|
|
{
|
|
|
|
if (!points)
|
1999-09-23 19:49:16 +08:00
|
|
|
gimp_fatal_error ("bezier_draw_segment(): Bad bezier segment");
|
1997-11-25 06:05:25 +08:00
|
|
|
|
|
|
|
switch (space)
|
|
|
|
{
|
|
|
|
case IMAGE_COORDS:
|
|
|
|
geometry[i][0] = points->x;
|
|
|
|
geometry[i][1] = points->y;
|
|
|
|
break;
|
|
|
|
case AA_IMAGE_COORDS:
|
1999-05-14 06:53:40 +08:00
|
|
|
geometry[i][0] = (points->x * SUPERSAMPLE);
|
|
|
|
geometry[i][1] = (points->y * SUPERSAMPLE);
|
1997-11-25 06:05:25 +08:00
|
|
|
break;
|
|
|
|
case SCREEN_COORDS:
|
|
|
|
geometry[i][0] = points->sx;
|
|
|
|
geometry[i][1] = points->sy;
|
|
|
|
break;
|
|
|
|
default:
|
1999-09-23 19:49:16 +08:00
|
|
|
gimp_fatal_error ("bezier_draw_segment(): Unknown coordinate space: %d", space);
|
1997-11-25 06:05:25 +08:00
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
|
|
|
geometry[i][2] = 0;
|
|
|
|
geometry[i][3] = 0;
|
|
|
|
|
|
|
|
points = points->next;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* subdivide the curve n times */
|
|
|
|
/* n can be adjusted to give a finer or coarser curve */
|
|
|
|
|
|
|
|
d = 1.0 / subdivisions;
|
|
|
|
d2 = d * d;
|
|
|
|
d3 = d * d * d;
|
|
|
|
|
|
|
|
/* construct a temporary matrix for determining the forward diffencing deltas */
|
|
|
|
|
|
|
|
tmp2[0][0] = 0; tmp2[0][1] = 0; tmp2[0][2] = 0; tmp2[0][3] = 1;
|
|
|
|
tmp2[1][0] = d3; tmp2[1][1] = d2; tmp2[1][2] = d; tmp2[1][3] = 0;
|
|
|
|
tmp2[2][0] = 6*d3; tmp2[2][1] = 2*d2; tmp2[2][2] = 0; tmp2[2][3] = 0;
|
|
|
|
tmp2[3][0] = 6*d3; tmp2[3][1] = 0; tmp2[3][2] = 0; tmp2[3][3] = 0;
|
|
|
|
|
|
|
|
/* compose the basis and geometry matrices */
|
|
|
|
bezier_compose (basis, geometry, tmp1);
|
|
|
|
|
|
|
|
/* compose the above results to get the deltas matrix */
|
|
|
|
bezier_compose (tmp2, tmp1, deltas);
|
|
|
|
|
|
|
|
/* extract the x deltas */
|
|
|
|
x = deltas[0][0];
|
|
|
|
dx = deltas[1][0];
|
|
|
|
dx2 = deltas[2][0];
|
|
|
|
dx3 = deltas[3][0];
|
|
|
|
|
|
|
|
/* extract the y deltas */
|
|
|
|
y = deltas[0][1];
|
|
|
|
dy = deltas[1][1];
|
|
|
|
dy2 = deltas[2][1];
|
|
|
|
dy3 = deltas[3][1];
|
|
|
|
|
|
|
|
lastx = x;
|
|
|
|
lasty = y;
|
|
|
|
|
1999-05-14 06:53:40 +08:00
|
|
|
gdk_points[0].x = (lastx);
|
|
|
|
gdk_points[0].y = (lasty);
|
1997-11-25 06:05:25 +08:00
|
|
|
index = 1;
|
|
|
|
|
|
|
|
/* loop over the curve */
|
|
|
|
for (i = 0; i < subdivisions; i++)
|
|
|
|
{
|
|
|
|
/* increment the x values */
|
|
|
|
x += dx;
|
|
|
|
dx += dx2;
|
|
|
|
dx2 += dx3;
|
|
|
|
|
|
|
|
/* increment the y values */
|
|
|
|
y += dy;
|
|
|
|
dy += dy2;
|
|
|
|
dy2 += dy3;
|
|
|
|
|
|
|
|
newx = ROUND (x);
|
|
|
|
newy = ROUND (y);
|
|
|
|
|
|
|
|
/* if this point is different than the last one...then draw it */
|
|
|
|
if ((lastx != newx) || (lasty != newy))
|
|
|
|
{
|
|
|
|
/* add the point to the point buffer */
|
1999-05-14 06:53:40 +08:00
|
|
|
gdk_points[index].x = (newx);
|
|
|
|
gdk_points[index].y = (newy);
|
1997-11-25 06:05:25 +08:00
|
|
|
index++;
|
|
|
|
|
|
|
|
/* if the point buffer is full put it to the screen and zero it out */
|
|
|
|
if (index >= npoints)
|
|
|
|
{
|
1999-04-06 07:33:50 +08:00
|
|
|
(* points_func) (bezier_sel, gdk_points, index, udata);
|
1997-11-25 06:05:25 +08:00
|
|
|
index = 0;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
lastx = newx;
|
|
|
|
lasty = newy;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* if there are points in the buffer, then put them on the screen */
|
|
|
|
if (index)
|
1999-04-06 07:33:50 +08:00
|
|
|
(* points_func) (bezier_sel, gdk_points, index, udata);
|
1997-11-25 06:05:25 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
|
|
|
bezier_draw_segment_points (BezierSelect *bezier_sel,
|
|
|
|
GdkPoint *points,
|
1999-04-06 07:33:50 +08:00
|
|
|
int npoints,
|
|
|
|
gpointer udata)
|
1997-11-25 06:05:25 +08:00
|
|
|
{
|
|
|
|
gdk_draw_points (bezier_sel->core->win,
|
|
|
|
bezier_sel->core->gc, points, npoints);
|
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
|
|
|
bezier_compose (BezierMatrix a,
|
|
|
|
BezierMatrix b,
|
|
|
|
BezierMatrix ab)
|
|
|
|
{
|
|
|
|
int i, j;
|
|
|
|
|
|
|
|
for (i = 0; i < 4; i++)
|
|
|
|
{
|
|
|
|
for (j = 0; j < 4; j++)
|
|
|
|
{
|
|
|
|
ab[i][j] = (a[i][0] * b[0][j] +
|
|
|
|
a[i][1] * b[1][j] +
|
|
|
|
a[i][2] * b[2][j] +
|
|
|
|
a[i][3] * b[3][j]);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
static int start_convert;
|
|
|
|
static int width, height;
|
|
|
|
static int lastx;
|
|
|
|
static int lasty;
|
|
|
|
|
|
|
|
static void
|
|
|
|
bezier_convert (BezierSelect *bezier_sel,
|
|
|
|
GDisplay *gdisp,
|
|
|
|
int subdivisions,
|
|
|
|
int antialias)
|
|
|
|
{
|
|
|
|
PixelRegion maskPR;
|
|
|
|
BezierPoint * points;
|
|
|
|
BezierPoint * start_pt;
|
1999-05-14 06:53:40 +08:00
|
|
|
BezierPoint * next_curve;
|
1998-01-29 16:03:27 +08:00
|
|
|
GSList * list;
|
1997-11-25 06:05:25 +08:00
|
|
|
unsigned char *buf, *b;
|
|
|
|
int draw_type;
|
|
|
|
int * vals, val;
|
|
|
|
int start, end;
|
|
|
|
int x, x2, w;
|
|
|
|
int i, j;
|
|
|
|
|
|
|
|
if (!bezier_sel->closed)
|
1999-09-23 19:49:16 +08:00
|
|
|
gimp_fatal_error ("bezier_convert(): tried to convert an open bezier curve");
|
1997-11-25 06:05:25 +08:00
|
|
|
|
|
|
|
/* destroy previous mask */
|
|
|
|
if (bezier_sel->mask)
|
|
|
|
{
|
|
|
|
channel_delete (bezier_sel->mask);
|
|
|
|
bezier_sel->mask = NULL;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* get the new mask's maximum extents */
|
|
|
|
if (antialias)
|
|
|
|
{
|
|
|
|
buf = (unsigned char *) g_malloc (width);
|
|
|
|
width = gdisp->gimage->width * SUPERSAMPLE;
|
|
|
|
height = gdisp->gimage->height * SUPERSAMPLE;
|
|
|
|
draw_type = AA_IMAGE_COORDS;
|
|
|
|
/* allocate value array */
|
|
|
|
vals = (int *) g_malloc (sizeof (int) * width);
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
buf = NULL;
|
|
|
|
width = gdisp->gimage->width;
|
|
|
|
height = gdisp->gimage->height;
|
|
|
|
draw_type = IMAGE_COORDS;
|
|
|
|
vals = NULL;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* create a new mask */
|
1998-06-29 08:24:44 +08:00
|
|
|
bezier_sel->mask = channel_ref (channel_new_mask (gdisp->gimage,
|
1998-02-14 08:44:47 +08:00
|
|
|
gdisp->gimage->width,
|
|
|
|
gdisp->gimage->height));
|
1997-11-25 06:05:25 +08:00
|
|
|
|
|
|
|
/* allocate room for the scanlines */
|
1998-01-29 16:03:27 +08:00
|
|
|
bezier_sel->scanlines = g_malloc (sizeof (GSList *) * height);
|
1997-11-25 06:05:25 +08:00
|
|
|
|
|
|
|
/* zero out the scanlines */
|
|
|
|
for (i = 0; i < height; i++)
|
|
|
|
bezier_sel->scanlines[i] = NULL;
|
|
|
|
|
|
|
|
/* scan convert the curve */
|
|
|
|
points = bezier_sel->points;
|
|
|
|
start_pt = bezier_sel->points;
|
|
|
|
|
|
|
|
do {
|
1999-05-14 06:53:40 +08:00
|
|
|
start_convert = 1;
|
|
|
|
do {
|
|
|
|
bezier_draw_segment (bezier_sel, points,
|
|
|
|
subdivisions, draw_type,
|
|
|
|
bezier_convert_points,
|
|
|
|
NULL);
|
|
|
|
|
|
|
|
/* advance to the next segment */
|
|
|
|
points = next_anchor(points,&next_curve);
|
|
|
|
} while (points != start_pt && points);
|
|
|
|
start_pt = next_curve;
|
|
|
|
points = next_curve;
|
|
|
|
} while (next_curve);
|
1997-11-25 06:05:25 +08:00
|
|
|
|
1998-01-22 15:02:57 +08:00
|
|
|
pixel_region_init (&maskPR, drawable_data (GIMP_DRAWABLE(bezier_sel->mask)),
|
|
|
|
0, 0,
|
|
|
|
drawable_width (GIMP_DRAWABLE(bezier_sel->mask)),
|
|
|
|
drawable_height (GIMP_DRAWABLE(bezier_sel->mask)), TRUE);
|
1997-11-25 06:05:25 +08:00
|
|
|
for (i = 0; i < height; i++)
|
|
|
|
{
|
|
|
|
list = bezier_sel->scanlines[i];
|
|
|
|
|
|
|
|
/* zero the vals array */
|
|
|
|
if (antialias && !(i % SUPERSAMPLE))
|
|
|
|
memset (vals, 0, width * sizeof (int));
|
|
|
|
|
|
|
|
while (list)
|
|
|
|
{
|
1999-05-14 06:53:40 +08:00
|
|
|
x = (long) list->data;
|
|
|
|
list = list->next;
|
1998-06-26 16:03:50 +08:00
|
|
|
/*
|
1997-11-25 06:05:25 +08:00
|
|
|
if (!list)
|
1999-09-23 19:49:16 +08:00
|
|
|
g_message ("cannot properly scanline convert bezier curve: %d", i);
|
1997-11-25 06:05:25 +08:00
|
|
|
else
|
1998-06-26 16:03:50 +08:00
|
|
|
*/
|
1997-11-25 06:05:25 +08:00
|
|
|
{
|
|
|
|
/* bounds checking */
|
|
|
|
x = BOUNDS (x, 0, width);
|
|
|
|
x2 = BOUNDS ((long) list->data, 0, width);
|
|
|
|
|
|
|
|
w = x2 - x;
|
|
|
|
|
|
|
|
if (!antialias)
|
|
|
|
channel_add_segment (bezier_sel->mask, x, i, w, 255);
|
|
|
|
else
|
|
|
|
for (j = 0; j < w; j++)
|
|
|
|
vals[j + x] += 255;
|
|
|
|
|
1998-01-29 16:03:27 +08:00
|
|
|
list = g_slist_next (list);
|
1997-11-25 06:05:25 +08:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if (antialias && !((i+1) % SUPERSAMPLE))
|
|
|
|
{
|
|
|
|
b = buf;
|
|
|
|
start = 0;
|
|
|
|
end = width;
|
|
|
|
for (j = start; j < end; j += SUPERSAMPLE)
|
|
|
|
{
|
|
|
|
val = 0;
|
|
|
|
for (x = 0; x < SUPERSAMPLE; x++)
|
|
|
|
val += vals[j + x];
|
|
|
|
|
|
|
|
*b++ = (unsigned char) (val / SUPERSAMPLE2);
|
|
|
|
}
|
|
|
|
|
1998-01-22 15:02:57 +08:00
|
|
|
pixel_region_set_row (&maskPR, 0, (i / SUPERSAMPLE),
|
|
|
|
drawable_width (GIMP_DRAWABLE(bezier_sel->mask)), buf);
|
1997-11-25 06:05:25 +08:00
|
|
|
}
|
|
|
|
|
1998-01-29 16:03:27 +08:00
|
|
|
g_slist_free (bezier_sel->scanlines[i]);
|
1997-11-25 06:05:25 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
if (antialias)
|
|
|
|
{
|
|
|
|
g_free (vals);
|
|
|
|
g_free (buf);
|
|
|
|
}
|
|
|
|
|
|
|
|
g_free (bezier_sel->scanlines);
|
|
|
|
bezier_sel->scanlines = NULL;
|
|
|
|
|
1998-01-22 15:02:57 +08:00
|
|
|
channel_invalidate_bounds (bezier_sel->mask);
|
1997-11-25 06:05:25 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
|
|
|
bezier_convert_points (BezierSelect *bezier_sel,
|
|
|
|
GdkPoint *points,
|
1999-04-06 07:33:50 +08:00
|
|
|
int npoints,
|
|
|
|
gpointer udata)
|
1997-11-25 06:05:25 +08:00
|
|
|
{
|
|
|
|
int i;
|
|
|
|
|
|
|
|
if (start_convert)
|
|
|
|
start_convert = 0;
|
|
|
|
else
|
|
|
|
bezier_convert_line (bezier_sel->scanlines, lastx, lasty, points[0].x, points[0].y);
|
|
|
|
|
|
|
|
for (i = 0; i < (npoints - 1); i++)
|
|
|
|
{
|
|
|
|
bezier_convert_line (bezier_sel->scanlines,
|
|
|
|
points[i].x, points[i].y,
|
|
|
|
points[i+1].x, points[i+1].y);
|
|
|
|
}
|
|
|
|
|
|
|
|
lastx = points[npoints-1].x;
|
|
|
|
lasty = points[npoints-1].y;
|
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
1998-01-29 16:03:27 +08:00
|
|
|
bezier_convert_line (GSList ** scanlines,
|
1997-11-25 06:05:25 +08:00
|
|
|
int x1,
|
|
|
|
int y1,
|
|
|
|
int x2,
|
|
|
|
int y2)
|
|
|
|
{
|
1999-05-14 06:53:40 +08:00
|
|
|
int dx, dy;
|
|
|
|
int error, inc;
|
1997-11-25 06:05:25 +08:00
|
|
|
int tmp;
|
1999-05-14 06:53:40 +08:00
|
|
|
int slope;
|
1997-11-25 06:05:25 +08:00
|
|
|
|
|
|
|
if (y1 == y2)
|
|
|
|
return;
|
|
|
|
|
|
|
|
if (y1 > y2)
|
|
|
|
{
|
|
|
|
tmp = y2; y2 = y1; y1 = tmp;
|
|
|
|
tmp = x2; x2 = x1; x1 = tmp;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (y1 < 0)
|
|
|
|
{
|
|
|
|
if (y2 < 0)
|
|
|
|
return;
|
|
|
|
|
|
|
|
if (x2 == x1)
|
|
|
|
{
|
|
|
|
y1 = 0;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
1999-05-14 06:53:40 +08:00
|
|
|
slope = (double) (y2 - y1) / (double) (x2 - x1);
|
1997-11-25 06:05:25 +08:00
|
|
|
x1 = x2 + (0 - y2) / slope;
|
|
|
|
y1 = 0;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if (y2 >= height)
|
|
|
|
{
|
|
|
|
if (y1 >= height)
|
|
|
|
return;
|
|
|
|
|
|
|
|
if (x2 == x1)
|
|
|
|
{
|
|
|
|
y2 = height;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
1999-05-14 06:53:40 +08:00
|
|
|
slope = (double) (y2 - y1) / (double) (x2 - x1);
|
1997-11-25 06:05:25 +08:00
|
|
|
x2 = x1 + (height - y1) / slope;
|
|
|
|
y2 = height;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if (y1 == y2)
|
|
|
|
return;
|
|
|
|
|
|
|
|
dx = x2 - x1;
|
|
|
|
dy = y2 - y1;
|
|
|
|
|
|
|
|
scanlines = &scanlines[y1];
|
|
|
|
|
|
|
|
if (((dx < 0) ? -dx : dx) > ((dy < 0) ? -dy : dy))
|
|
|
|
{
|
|
|
|
if (dx < 0)
|
|
|
|
{
|
|
|
|
inc = -1;
|
|
|
|
dx = -dx;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
inc = 1;
|
|
|
|
}
|
|
|
|
|
|
|
|
error = -dx /2;
|
|
|
|
while (x1 != x2)
|
|
|
|
{
|
|
|
|
error += dy;
|
|
|
|
if (error > 0)
|
|
|
|
{
|
|
|
|
error -= dx;
|
1999-05-14 06:53:40 +08:00
|
|
|
*scanlines = bezier_insert_in_list (*scanlines, x1);
|
1997-11-25 06:05:25 +08:00
|
|
|
scanlines++;
|
|
|
|
}
|
|
|
|
|
|
|
|
x1 += inc;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
error = -dy /2;
|
|
|
|
if (dx < 0)
|
|
|
|
{
|
|
|
|
dx = -dx;
|
|
|
|
inc = -1;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
inc = 1;
|
|
|
|
}
|
|
|
|
|
|
|
|
while (y1++ < y2)
|
|
|
|
{
|
1999-05-14 06:53:40 +08:00
|
|
|
*scanlines = bezier_insert_in_list (*scanlines, x1);
|
1997-11-25 06:05:25 +08:00
|
|
|
scanlines++;
|
|
|
|
|
|
|
|
error += dx;
|
|
|
|
if (error > 0)
|
|
|
|
{
|
|
|
|
error -= dy;
|
|
|
|
x1 += inc;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
1998-01-29 16:03:27 +08:00
|
|
|
static GSList *
|
|
|
|
bezier_insert_in_list (GSList * list,
|
1997-11-25 06:05:25 +08:00
|
|
|
int x)
|
|
|
|
{
|
1998-01-29 16:03:27 +08:00
|
|
|
GSList * orig = list;
|
|
|
|
GSList * rest;
|
1997-11-25 06:05:25 +08:00
|
|
|
|
|
|
|
if (!list)
|
1998-01-29 16:03:27 +08:00
|
|
|
return g_slist_prepend (list, (void *) ((long) x));
|
1997-11-25 06:05:25 +08:00
|
|
|
|
|
|
|
while (list)
|
|
|
|
{
|
1998-01-29 16:03:27 +08:00
|
|
|
rest = g_slist_next (list);
|
1997-11-25 06:05:25 +08:00
|
|
|
if (x < (long) list->data)
|
|
|
|
{
|
1998-01-29 16:03:27 +08:00
|
|
|
rest = g_slist_prepend (rest, list->data);
|
1997-11-25 06:05:25 +08:00
|
|
|
list->next = rest;
|
|
|
|
list->data = (void *) ((long) x);
|
|
|
|
return orig;
|
|
|
|
}
|
|
|
|
else if (!rest)
|
|
|
|
{
|
1998-01-29 16:03:27 +08:00
|
|
|
g_slist_append (list, (void *) ((long) x));
|
1997-11-25 06:05:25 +08:00
|
|
|
return orig;
|
|
|
|
}
|
1998-01-29 16:03:27 +08:00
|
|
|
list = g_slist_next (list);
|
1997-11-25 06:05:25 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
return orig;
|
|
|
|
}
|
1998-06-26 16:03:50 +08:00
|
|
|
|
1999-04-14 05:50:28 +08:00
|
|
|
gboolean
|
|
|
|
bezier_tool_selected()
|
|
|
|
{
|
1999-06-20 04:20:59 +08:00
|
|
|
return(active_tool &&
|
|
|
|
active_tool->type == BEZIER_SELECT &&
|
1999-04-14 05:50:28 +08:00
|
|
|
active_tool->state == ACTIVE);
|
|
|
|
}
|
|
|
|
|
1999-03-06 07:50:24 +08:00
|
|
|
void
|
|
|
|
bezier_paste_bezierselect_to_current(GDisplay *gdisp,BezierSelect *bsel)
|
1998-06-26 16:03:50 +08:00
|
|
|
{
|
|
|
|
BezierPoint *pts;
|
1999-03-06 07:50:24 +08:00
|
|
|
gint i;
|
|
|
|
Tool * tool;
|
1999-05-14 06:53:40 +08:00
|
|
|
BezierPoint *bpnt = NULL;
|
|
|
|
int need_move = 0;
|
|
|
|
|
new ui for the "Layer Offset" dialog.
1999-07-22 Michael Natterer <mitschel@cs.tu-berlin.de>
* app/channel_ops.[ch]: new ui for the "Layer Offset" dialog.
* app/channels_dialog.c
* app/layers_dialog.c: major code cleanup: Folded some callbacks
into common ones, "widget" instead of "w", indentation, ...
* app/commands.c
* app/interface.[ch]
* app/global_edit.c: the query boxes must be shown by the caller
now. There's no need to split up the string for the message box
manually as the Gtk 1.2 label widget handles newlines corectly.
Added the "edge_lock" toggle to the "Shrink Selection" dialog.
Nicer spacings for the query and message boxes.
* app/ink.c: tried to grab the pointer in the blob preview but
failed. Left the code there as a reminder (commented out).
* app/menus.c: reordered <Image>/Select.
I was bored and grep-ed the sources for ancient or deprecated stuff:
* app/about_dialog.[ch]
* app/actionarea.[ch]
* app/app_procs.c
* app/brush_edit.c
* app/brush_select.c
* app/color_select.c
* app/convert.c
* app/devices.c
* app/gdisplay.c
* app/gdisplay_ops.c
* app/histogram_tool.[ch]
* app/info_window.c
* app/install.c
* app/ops_buttons.c
* app/palette.c
* app/palette_select.c
* app/paths_dialog.c
* app/pattern_select.c
* app/resize.c
* app/scale_toolc.c
* app/text_tool.c:
s/container_border_width/container_set_border_width/g,
s/sprintf/g_snprintf/g, replaced some constant string lengths with
strlen(x).
* app/bezier_select.c
* app/blend.c
* app/boundary.c
* app/errors.[ch]
* app/free_select.c
* app/gimpbrushlist.c
* app/gimprc.c
* app/iscissors.c
* app/main.c
* app/patterns.[ch]
* app/text_tool.c: namespace fanaticism: prefixed all gimp error
functions with "gimp_" and formated the messages more uniformly.
* app/gradient.c
* app/gradient_select.c: same stuff as above for the ui
code. There are still some sub-dialogs which need cleanup.
Did some cleanup in most of these files: prototypes, removed tons
of #include's, i18n fixes, s/w/widget/ as above, indentation, ...
1999-07-23 00:21:10 +08:00
|
|
|
/* g_print ("bezier_paste_bezierselect_to_current::\n"); */
|
1999-05-14 06:53:40 +08:00
|
|
|
/* printSel(bsel); */
|
1998-06-26 16:03:50 +08:00
|
|
|
|
1999-03-06 07:50:24 +08:00
|
|
|
/* If the tool was being used before clear it */
|
1999-06-20 04:20:59 +08:00
|
|
|
if (active_tool &&
|
|
|
|
active_tool->type == BEZIER_SELECT &&
|
1999-03-06 07:50:24 +08:00
|
|
|
active_tool->state == ACTIVE)
|
|
|
|
{
|
|
|
|
BezierSelect *bezier_sel = (BezierSelect*)active_tool->private;
|
|
|
|
if(bezier_sel)
|
1998-06-26 16:03:50 +08:00
|
|
|
{
|
1999-03-06 07:50:24 +08:00
|
|
|
draw_core_stop ( curSel->core, active_tool );
|
|
|
|
bezier_select_reset (bezier_sel);
|
1998-06-26 16:03:50 +08:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
1999-10-27 02:27:27 +08:00
|
|
|
gimp_context_set_tool (gimp_context_get_user (), BEZIER_SELECT);
|
1999-03-06 07:50:24 +08:00
|
|
|
active_tool->paused_count = 0;
|
1999-06-22 06:12:07 +08:00
|
|
|
active_tool->gdisp_ptr = gdisp;
|
1999-03-06 07:50:24 +08:00
|
|
|
active_tool->drawable = gimage_active_drawable (gdisp->gimage);
|
1998-06-26 16:03:50 +08:00
|
|
|
|
1999-03-06 07:50:24 +08:00
|
|
|
tool = active_tool;
|
1998-06-26 16:03:50 +08:00
|
|
|
|
1999-03-06 07:50:24 +08:00
|
|
|
bezier_select_reset( curSel );
|
1998-06-26 16:03:50 +08:00
|
|
|
|
1999-03-06 07:50:24 +08:00
|
|
|
draw_core_start (curSel->core, gdisp->canvas->window, tool);
|
1998-06-26 16:03:50 +08:00
|
|
|
|
1999-03-06 07:50:24 +08:00
|
|
|
tool->state = ACTIVE;
|
1998-06-26 16:03:50 +08:00
|
|
|
|
1999-03-06 07:50:24 +08:00
|
|
|
pts = (BezierPoint *) bsel->points;
|
1998-06-26 16:03:50 +08:00
|
|
|
|
1999-03-06 07:50:24 +08:00
|
|
|
for (i=0; i< bsel->num_points; i++)
|
1998-06-26 16:03:50 +08:00
|
|
|
{
|
1999-05-14 06:53:40 +08:00
|
|
|
if(need_move)
|
|
|
|
{
|
|
|
|
bezier_add_point( curSel, BEZIER_MOVE, pts->x, pts->y);
|
|
|
|
need_move = 0;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
bezier_add_point( curSel, pts->type, pts->x, pts->y);
|
|
|
|
|
|
|
|
if(bpnt == NULL)
|
|
|
|
bpnt = curSel->last_point;
|
|
|
|
|
|
|
|
if(pts->next_curve)
|
|
|
|
{
|
new ui for the "Layer Offset" dialog.
1999-07-22 Michael Natterer <mitschel@cs.tu-berlin.de>
* app/channel_ops.[ch]: new ui for the "Layer Offset" dialog.
* app/channels_dialog.c
* app/layers_dialog.c: major code cleanup: Folded some callbacks
into common ones, "widget" instead of "w", indentation, ...
* app/commands.c
* app/interface.[ch]
* app/global_edit.c: the query boxes must be shown by the caller
now. There's no need to split up the string for the message box
manually as the Gtk 1.2 label widget handles newlines corectly.
Added the "edge_lock" toggle to the "Shrink Selection" dialog.
Nicer spacings for the query and message boxes.
* app/ink.c: tried to grab the pointer in the blob preview but
failed. Left the code there as a reminder (commented out).
* app/menus.c: reordered <Image>/Select.
I was bored and grep-ed the sources for ancient or deprecated stuff:
* app/about_dialog.[ch]
* app/actionarea.[ch]
* app/app_procs.c
* app/brush_edit.c
* app/brush_select.c
* app/color_select.c
* app/convert.c
* app/devices.c
* app/gdisplay.c
* app/gdisplay_ops.c
* app/histogram_tool.[ch]
* app/info_window.c
* app/install.c
* app/ops_buttons.c
* app/palette.c
* app/palette_select.c
* app/paths_dialog.c
* app/pattern_select.c
* app/resize.c
* app/scale_toolc.c
* app/text_tool.c:
s/container_border_width/container_set_border_width/g,
s/sprintf/g_snprintf/g, replaced some constant string lengths with
strlen(x).
* app/bezier_select.c
* app/blend.c
* app/boundary.c
* app/errors.[ch]
* app/free_select.c
* app/gimpbrushlist.c
* app/gimprc.c
* app/iscissors.c
* app/main.c
* app/patterns.[ch]
* app/text_tool.c: namespace fanaticism: prefixed all gimp error
functions with "gimp_" and formated the messages more uniformly.
* app/gradient.c
* app/gradient_select.c: same stuff as above for the ui
code. There are still some sub-dialogs which need cleanup.
Did some cleanup in most of these files: prototypes, removed tons
of #include's, i18n fixes, s/w/widget/ as above, indentation, ...
1999-07-23 00:21:10 +08:00
|
|
|
/* g_print ("bezier_paste_bezierselect_to_current:: Close last curve off \n"); */
|
1999-05-14 06:53:40 +08:00
|
|
|
curSel->last_point->next = bpnt;
|
|
|
|
bpnt->prev = curSel->last_point;
|
|
|
|
curSel->cur_anchor = NULL;
|
|
|
|
curSel->cur_control = NULL;
|
|
|
|
bpnt = NULL;
|
|
|
|
need_move = 1;
|
|
|
|
pts = pts->next_curve;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
pts = pts->next;
|
|
|
|
}
|
1999-03-06 07:50:24 +08:00
|
|
|
}
|
1998-06-26 16:03:50 +08:00
|
|
|
|
1999-03-06 07:50:24 +08:00
|
|
|
if ( bsel->closed )
|
1998-06-26 16:03:50 +08:00
|
|
|
{
|
1999-05-14 06:53:40 +08:00
|
|
|
curSel->last_point->next = bpnt;
|
|
|
|
bpnt->prev = curSel->last_point;
|
1999-03-06 07:50:24 +08:00
|
|
|
curSel->cur_anchor = curSel->points;
|
1999-05-14 06:53:40 +08:00
|
|
|
curSel->cur_control = curSel->points->next;
|
1999-03-06 07:50:24 +08:00
|
|
|
curSel->closed = 1;
|
|
|
|
if (curTool->gdisp_ptr)
|
|
|
|
bezier_convert(curSel, curTool->gdisp_ptr, SUBDIVIDE, NO);
|
|
|
|
}
|
1998-06-26 16:03:50 +08:00
|
|
|
|
new ui for the "Layer Offset" dialog.
1999-07-22 Michael Natterer <mitschel@cs.tu-berlin.de>
* app/channel_ops.[ch]: new ui for the "Layer Offset" dialog.
* app/channels_dialog.c
* app/layers_dialog.c: major code cleanup: Folded some callbacks
into common ones, "widget" instead of "w", indentation, ...
* app/commands.c
* app/interface.[ch]
* app/global_edit.c: the query boxes must be shown by the caller
now. There's no need to split up the string for the message box
manually as the Gtk 1.2 label widget handles newlines corectly.
Added the "edge_lock" toggle to the "Shrink Selection" dialog.
Nicer spacings for the query and message boxes.
* app/ink.c: tried to grab the pointer in the blob preview but
failed. Left the code there as a reminder (commented out).
* app/menus.c: reordered <Image>/Select.
I was bored and grep-ed the sources for ancient or deprecated stuff:
* app/about_dialog.[ch]
* app/actionarea.[ch]
* app/app_procs.c
* app/brush_edit.c
* app/brush_select.c
* app/color_select.c
* app/convert.c
* app/devices.c
* app/gdisplay.c
* app/gdisplay_ops.c
* app/histogram_tool.[ch]
* app/info_window.c
* app/install.c
* app/ops_buttons.c
* app/palette.c
* app/palette_select.c
* app/paths_dialog.c
* app/pattern_select.c
* app/resize.c
* app/scale_toolc.c
* app/text_tool.c:
s/container_border_width/container_set_border_width/g,
s/sprintf/g_snprintf/g, replaced some constant string lengths with
strlen(x).
* app/bezier_select.c
* app/blend.c
* app/boundary.c
* app/errors.[ch]
* app/free_select.c
* app/gimpbrushlist.c
* app/gimprc.c
* app/iscissors.c
* app/main.c
* app/patterns.[ch]
* app/text_tool.c: namespace fanaticism: prefixed all gimp error
functions with "gimp_" and formated the messages more uniformly.
* app/gradient.c
* app/gradient_select.c: same stuff as above for the ui
code. There are still some sub-dialogs which need cleanup.
Did some cleanup in most of these files: prototypes, removed tons
of #include's, i18n fixes, s/w/widget/ as above, indentation, ...
1999-07-23 00:21:10 +08:00
|
|
|
/* g_print ("After pasting...\n"); */
|
1999-05-14 06:53:40 +08:00
|
|
|
/* printSel(curSel); */
|
|
|
|
|
1999-03-06 07:50:24 +08:00
|
|
|
if(bsel->num_points == 0)
|
|
|
|
{
|
|
|
|
curSel->state = BEZIER_START;
|
|
|
|
curSel->draw = 0;
|
|
|
|
draw_core_stop( curSel->core, curTool);
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
curSel->state = bsel->state;
|
|
|
|
curSel->draw = BEZIER_DRAW_ALL;
|
|
|
|
draw_core_resume( curSel->core, curTool);
|
|
|
|
}
|
1998-06-26 16:03:50 +08:00
|
|
|
}
|
|
|
|
|
1999-03-06 07:50:24 +08:00
|
|
|
static void
|
|
|
|
bezier_to_sel_internal(BezierSelect *bezier_sel,
|
|
|
|
Tool *tool,
|
|
|
|
GDisplay *gdisp,
|
|
|
|
gint op,
|
|
|
|
gint replace)
|
1998-06-26 16:03:50 +08:00
|
|
|
{
|
1999-03-06 07:50:24 +08:00
|
|
|
/* If we're antialiased, then recompute the
|
|
|
|
* mask...
|
|
|
|
*/
|
|
|
|
if (bezier_options->antialias)
|
|
|
|
bezier_convert (bezier_sel, tool->gdisp_ptr, SUBDIVIDE, YES);
|
1998-06-26 16:03:50 +08:00
|
|
|
|
1999-05-14 06:53:40 +08:00
|
|
|
/* if (!bezier_options->extend) */
|
|
|
|
/* { */
|
|
|
|
/* tool->state = INACTIVE; */
|
|
|
|
/* bezier_sel->draw = BEZIER_DRAW_CURVE; */
|
|
|
|
/* draw_core_resume (bezier_sel->core, tool); */
|
1998-06-26 16:03:50 +08:00
|
|
|
|
1999-05-14 06:53:40 +08:00
|
|
|
/* bezier_sel->draw = 0; */
|
|
|
|
/* draw_core_stop (bezier_sel->core, tool); */
|
|
|
|
/* } */
|
1998-06-26 16:03:50 +08:00
|
|
|
|
1999-03-06 07:50:24 +08:00
|
|
|
if (replace)
|
|
|
|
gimage_mask_clear (gdisp->gimage);
|
|
|
|
else
|
|
|
|
gimage_mask_undo (gdisp->gimage);
|
1998-06-26 16:03:50 +08:00
|
|
|
|
1999-03-06 07:50:24 +08:00
|
|
|
if (bezier_options->feather)
|
|
|
|
channel_feather (bezier_sel->mask,
|
|
|
|
gimage_get_mask (gdisp->gimage),
|
1999-05-14 06:53:40 +08:00
|
|
|
bezier_options->feather_radius,
|
|
|
|
bezier_options->feather_radius,
|
1999-05-07 07:10:29 +08:00
|
|
|
op, 0, 0);
|
1999-03-06 07:50:24 +08:00
|
|
|
else
|
|
|
|
channel_combine_mask (gimage_get_mask (gdisp->gimage),
|
|
|
|
bezier_sel->mask, op, 0, 0);
|
1998-06-26 16:03:50 +08:00
|
|
|
|
1999-03-06 07:50:24 +08:00
|
|
|
/* show selection on all views */
|
|
|
|
gdisplays_flush ();
|
1998-06-26 16:03:50 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
static int
|
1999-03-06 07:50:24 +08:00
|
|
|
test_add_point_on_segment (BezierSelect *bezier_sel,
|
1998-06-26 16:03:50 +08:00
|
|
|
BezierPoint *pt,
|
|
|
|
int subdivisions,
|
|
|
|
int space,
|
|
|
|
int xpos,
|
|
|
|
int ypos,
|
|
|
|
int halfwidth)
|
|
|
|
|
|
|
|
{
|
|
|
|
BezierPoint *points;
|
|
|
|
BezierMatrix geometry;
|
|
|
|
BezierMatrix tmp1, tmp2;
|
|
|
|
BezierMatrix deltas;
|
|
|
|
double x, dx, dx2, dx3;
|
|
|
|
double y, dy, dy2, dy3;
|
|
|
|
double d, d2, d3;
|
|
|
|
int lastx, lasty;
|
|
|
|
int newx, newy;
|
|
|
|
int i;
|
|
|
|
double ratio;
|
|
|
|
|
|
|
|
/* construct the geometry matrix from the segment */
|
|
|
|
/* assumes that a valid segment containing 4 points is passed in */
|
1999-03-06 07:50:24 +08:00
|
|
|
/* ALT ignore invalid segments since we might be working on an open curve */
|
1998-06-26 16:03:50 +08:00
|
|
|
|
|
|
|
points = pt;
|
|
|
|
|
|
|
|
ratio = -1.0;
|
|
|
|
|
|
|
|
for (i = 0; i < 4; i++)
|
|
|
|
{
|
|
|
|
if (!points)
|
1999-03-06 07:50:24 +08:00
|
|
|
return 0;
|
1998-06-26 16:03:50 +08:00
|
|
|
|
|
|
|
switch (space)
|
|
|
|
{
|
|
|
|
case IMAGE_COORDS:
|
|
|
|
geometry[i][0] = points->x;
|
|
|
|
geometry[i][1] = points->y;
|
|
|
|
break;
|
|
|
|
case AA_IMAGE_COORDS:
|
1999-08-05 07:22:29 +08:00
|
|
|
geometry[i][0] = RINT(points->x * SUPERSAMPLE);
|
|
|
|
geometry[i][1] = RINT(points->y * SUPERSAMPLE);
|
1998-06-26 16:03:50 +08:00
|
|
|
break;
|
|
|
|
case SCREEN_COORDS:
|
|
|
|
geometry[i][0] = points->sx;
|
|
|
|
geometry[i][1] = points->sy;
|
|
|
|
break;
|
|
|
|
default:
|
1999-09-23 19:49:16 +08:00
|
|
|
gimp_fatal_error ("test_add_point_on_segment(): Unknown coordinate space: %d", space);
|
1998-06-26 16:03:50 +08:00
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
|
|
|
geometry[i][2] = 0;
|
|
|
|
geometry[i][3] = 0;
|
|
|
|
|
|
|
|
points = points->next;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* subdivide the curve n times */
|
|
|
|
/* n can be adjusted to give a finer or coarser curve */
|
|
|
|
|
|
|
|
d = 1.0 / subdivisions;
|
|
|
|
d2 = d * d;
|
|
|
|
d3 = d * d * d;
|
|
|
|
|
|
|
|
/* construct a temporary matrix for determining the forward diffencing deltas */
|
|
|
|
|
|
|
|
tmp2[0][0] = 0; tmp2[0][1] = 0; tmp2[0][2] = 0; tmp2[0][3] = 1;
|
|
|
|
tmp2[1][0] = d3; tmp2[1][1] = d2; tmp2[1][2] = d; tmp2[1][3] = 0;
|
|
|
|
tmp2[2][0] = 6*d3; tmp2[2][1] = 2*d2; tmp2[2][2] = 0; tmp2[2][3] = 0;
|
|
|
|
tmp2[3][0] = 6*d3; tmp2[3][1] = 0; tmp2[3][2] = 0; tmp2[3][3] = 0;
|
|
|
|
|
|
|
|
/* compose the basis and geometry matrices */
|
|
|
|
bezier_compose (basis, geometry, tmp1);
|
|
|
|
|
|
|
|
/* compose the above results to get the deltas matrix */
|
|
|
|
bezier_compose (tmp2, tmp1, deltas);
|
|
|
|
|
|
|
|
/* extract the x deltas */
|
|
|
|
x = deltas[0][0];
|
|
|
|
dx = deltas[1][0];
|
|
|
|
dx2 = deltas[2][0];
|
|
|
|
dx3 = deltas[3][0];
|
|
|
|
|
|
|
|
/* extract the y deltas */
|
|
|
|
y = deltas[0][1];
|
|
|
|
dy = deltas[1][1];
|
|
|
|
dy2 = deltas[2][1];
|
|
|
|
dy3 = deltas[3][1];
|
|
|
|
|
|
|
|
lastx = x;
|
|
|
|
lasty = y;
|
|
|
|
|
|
|
|
/* loop over the curve */
|
|
|
|
for (i = 0; i < subdivisions; i++)
|
|
|
|
{
|
|
|
|
/* increment the x values */
|
|
|
|
x += dx;
|
|
|
|
dx += dx2;
|
|
|
|
dx2 += dx3;
|
|
|
|
|
|
|
|
/* increment the y values */
|
|
|
|
y += dy;
|
|
|
|
dy += dy2;
|
|
|
|
dy2 += dy3;
|
|
|
|
|
|
|
|
newx = ROUND (x);
|
|
|
|
newy = ROUND (y);
|
|
|
|
|
|
|
|
/* if this point is different than the last one...then test it */
|
|
|
|
if ((lastx != newx) || (lasty != newy))
|
|
|
|
{
|
|
|
|
int l, r, b, t;
|
|
|
|
|
|
|
|
l = newx - halfwidth;
|
|
|
|
r = newx + halfwidth;
|
|
|
|
t = newy - halfwidth;
|
|
|
|
b = newy + halfwidth;
|
|
|
|
|
|
|
|
if ((xpos >= l) && (xpos <= r) && (ypos >= t) && (ypos <= b))
|
|
|
|
{
|
|
|
|
/* so we found one point in the square hit */
|
|
|
|
|
|
|
|
ratio = (double)i/(double)subdivisions;
|
|
|
|
|
|
|
|
/* We found the exact point on the curve, so take it ...*/
|
|
|
|
|
|
|
|
if ((xpos==newx) && (ypos==newy)) break;
|
|
|
|
|
|
|
|
/* to Implement :
|
|
|
|
|
|
|
|
keep each time the nearest point of the curve from where we've clicked
|
|
|
|
in the case where we haven't click exactely on the curve.
|
|
|
|
*/
|
|
|
|
|
|
|
|
}
|
|
|
|
}
|
|
|
|
lastx = newx;
|
|
|
|
lasty = newy;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* we found a point on the curve */
|
|
|
|
|
|
|
|
if (ratio >= 0.0)
|
|
|
|
{
|
|
|
|
BezierPoint *pts, *pt1, *pt2, *pt3;
|
|
|
|
BezierPoint *P00, *P01, *P02, *P03;
|
|
|
|
BezierPoint P10, P11, P12;
|
|
|
|
BezierPoint P20, P21;
|
|
|
|
BezierPoint P30;
|
|
|
|
|
|
|
|
pts = pt;
|
|
|
|
|
|
|
|
P00 = pts;
|
|
|
|
pts = pts->next;
|
|
|
|
P01 = pts;
|
|
|
|
pts = pts->next;
|
|
|
|
P02 = pts;
|
|
|
|
pts = pts->next;
|
|
|
|
P03 = pts;
|
|
|
|
|
|
|
|
/* De Casteljau algorithme
|
|
|
|
[Advanced Animation & Randering Technics / Alan & Mark WATT]
|
|
|
|
[ADDISON WESLEY ref 54412]
|
|
|
|
Iteratif way of drawing a Bezier curve by geometrical approch
|
|
|
|
|
|
|
|
P0x represent the four controls points ( anchor / control /control /anchor )
|
|
|
|
P30 represent the new anchor point to add on the curve
|
|
|
|
P2x represent the new control points of P30
|
|
|
|
P1x represent the new values of the control points P01 and P02
|
|
|
|
|
|
|
|
so if we moves ratio from 0 to 1 we draw the all curve between P00 and P03
|
|
|
|
*/
|
|
|
|
|
|
|
|
P10.x = (int)((1-ratio)*P00->x + ratio * P01->x);
|
|
|
|
P10.y = (int)((1-ratio)*P00->y + ratio * P01->y);
|
|
|
|
|
|
|
|
P11.x = (1-ratio)*P01->x + ratio * P02->x;
|
|
|
|
P11.y = (1-ratio)*P01->y + ratio * P02->y;
|
|
|
|
|
|
|
|
P12.x = (1-ratio)*P02->x + ratio * P03->x;
|
|
|
|
P12.y = (1-ratio)*P02->y + ratio * P03->y;
|
|
|
|
|
|
|
|
P20.x = (1-ratio)*P10.x + ratio * P11.x;
|
|
|
|
P20.y = (1-ratio)*P10.y + ratio * P11.y;
|
|
|
|
|
|
|
|
P21.x = (1-ratio)*P11.x + ratio * P12.x;
|
|
|
|
P21.y = (1-ratio)*P11.y + ratio * P12.y;
|
|
|
|
|
|
|
|
P30.x = (1-ratio)*P20.x + ratio * P21.x;
|
|
|
|
P30.y = (1-ratio)*P20.y + ratio * P21.y;
|
|
|
|
|
|
|
|
P01->x = P10.x;
|
|
|
|
P01->y = P10.y;
|
|
|
|
|
|
|
|
P02->x = P12.x;
|
|
|
|
P02->y = P12.y;
|
|
|
|
|
|
|
|
/* All the computes are done, let's insert the new point on the curve */
|
|
|
|
|
1999-05-14 06:53:40 +08:00
|
|
|
pt1 = g_new0(BezierPoint,1);
|
|
|
|
pt2 = g_new0(BezierPoint,1);
|
|
|
|
pt3 = g_new0(BezierPoint,1);
|
1998-06-26 16:03:50 +08:00
|
|
|
|
|
|
|
pt1->type = BEZIER_CONTROL;
|
|
|
|
pt2->type = BEZIER_ANCHOR;
|
|
|
|
pt3->type = BEZIER_CONTROL;
|
|
|
|
|
|
|
|
pt1->x = P20.x; pt1->y = P20.y;
|
|
|
|
pt2->x = P30.x; pt2->y = P30.y;
|
|
|
|
pt3->x = P21.x; pt3->y = P21.y;
|
|
|
|
|
1999-05-14 06:53:40 +08:00
|
|
|
pt3->next_curve = P01->next_curve;
|
1998-06-26 16:03:50 +08:00
|
|
|
P01->next = pt1;
|
|
|
|
|
|
|
|
pt1->prev = P01;
|
|
|
|
pt1->next = pt2;
|
|
|
|
|
|
|
|
pt2->prev = pt1;
|
|
|
|
pt2->next = pt3;
|
|
|
|
|
|
|
|
pt3->prev = pt2;
|
|
|
|
pt3->next = P02;
|
|
|
|
|
|
|
|
P02->prev = pt3;
|
|
|
|
|
|
|
|
bezier_sel->num_points += 3;
|
|
|
|
|
1999-03-06 07:50:24 +08:00
|
|
|
bezier_sel->cur_anchor = pt2;
|
|
|
|
bezier_sel->cur_control = pt1;
|
|
|
|
|
1998-06-26 16:03:50 +08:00
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
1999-03-06 07:50:24 +08:00
|
|
|
void bezier_select_mode(gint mode)
|
|
|
|
{
|
|
|
|
ModeEdit = mode;
|
|
|
|
}
|
|
|
|
|
1999-03-13 06:04:30 +08:00
|
|
|
/* The curve has to be closed to do a selection. */
|
|
|
|
|
|
|
|
void
|
|
|
|
bezier_to_selection(BezierSelect *bezier_sel,
|
|
|
|
GDisplay *gdisp)
|
|
|
|
{
|
|
|
|
/* Call the internal function */
|
|
|
|
if(!bezier_sel->closed)
|
|
|
|
{
|
1999-09-23 19:49:16 +08:00
|
|
|
g_message(_("Curve not closed!"));
|
1999-03-13 06:04:30 +08:00
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* force the passed selection to be the current selection..*/
|
|
|
|
/* This loads it into curSel for this image */
|
|
|
|
bezier_paste_bezierselect_to_current(gdisp,bezier_sel);
|
|
|
|
bezier_to_sel_internal(curSel,curTool,gdisp,ADD,1);
|
|
|
|
}
|
|
|
|
|
1998-06-26 16:03:50 +08:00
|
|
|
void printSel( BezierSelect *sel)
|
|
|
|
{
|
|
|
|
BezierPoint *pt;
|
1999-05-14 06:53:40 +08:00
|
|
|
BezierPoint *start_pt;
|
1998-06-26 16:03:50 +08:00
|
|
|
int i;
|
|
|
|
|
|
|
|
pt = sel->points;
|
1999-05-14 06:53:40 +08:00
|
|
|
start_pt = pt;
|
1998-06-26 16:03:50 +08:00
|
|
|
|
new ui for the "Layer Offset" dialog.
1999-07-22 Michael Natterer <mitschel@cs.tu-berlin.de>
* app/channel_ops.[ch]: new ui for the "Layer Offset" dialog.
* app/channels_dialog.c
* app/layers_dialog.c: major code cleanup: Folded some callbacks
into common ones, "widget" instead of "w", indentation, ...
* app/commands.c
* app/interface.[ch]
* app/global_edit.c: the query boxes must be shown by the caller
now. There's no need to split up the string for the message box
manually as the Gtk 1.2 label widget handles newlines corectly.
Added the "edge_lock" toggle to the "Shrink Selection" dialog.
Nicer spacings for the query and message boxes.
* app/ink.c: tried to grab the pointer in the blob preview but
failed. Left the code there as a reminder (commented out).
* app/menus.c: reordered <Image>/Select.
I was bored and grep-ed the sources for ancient or deprecated stuff:
* app/about_dialog.[ch]
* app/actionarea.[ch]
* app/app_procs.c
* app/brush_edit.c
* app/brush_select.c
* app/color_select.c
* app/convert.c
* app/devices.c
* app/gdisplay.c
* app/gdisplay_ops.c
* app/histogram_tool.[ch]
* app/info_window.c
* app/install.c
* app/ops_buttons.c
* app/palette.c
* app/palette_select.c
* app/paths_dialog.c
* app/pattern_select.c
* app/resize.c
* app/scale_toolc.c
* app/text_tool.c:
s/container_border_width/container_set_border_width/g,
s/sprintf/g_snprintf/g, replaced some constant string lengths with
strlen(x).
* app/bezier_select.c
* app/blend.c
* app/boundary.c
* app/errors.[ch]
* app/free_select.c
* app/gimpbrushlist.c
* app/gimprc.c
* app/iscissors.c
* app/main.c
* app/patterns.[ch]
* app/text_tool.c: namespace fanaticism: prefixed all gimp error
functions with "gimp_" and formated the messages more uniformly.
* app/gradient.c
* app/gradient_select.c: same stuff as above for the ui
code. There are still some sub-dialogs which need cleanup.
Did some cleanup in most of these files: prototypes, removed tons
of #include's, i18n fixes, s/w/widget/ as above, indentation, ...
1999-07-23 00:21:10 +08:00
|
|
|
g_print ("\n");
|
1998-06-26 16:03:50 +08:00
|
|
|
|
|
|
|
for(i=0; i<sel->num_points; i++)
|
|
|
|
{
|
new ui for the "Layer Offset" dialog.
1999-07-22 Michael Natterer <mitschel@cs.tu-berlin.de>
* app/channel_ops.[ch]: new ui for the "Layer Offset" dialog.
* app/channels_dialog.c
* app/layers_dialog.c: major code cleanup: Folded some callbacks
into common ones, "widget" instead of "w", indentation, ...
* app/commands.c
* app/interface.[ch]
* app/global_edit.c: the query boxes must be shown by the caller
now. There's no need to split up the string for the message box
manually as the Gtk 1.2 label widget handles newlines corectly.
Added the "edge_lock" toggle to the "Shrink Selection" dialog.
Nicer spacings for the query and message boxes.
* app/ink.c: tried to grab the pointer in the blob preview but
failed. Left the code there as a reminder (commented out).
* app/menus.c: reordered <Image>/Select.
I was bored and grep-ed the sources for ancient or deprecated stuff:
* app/about_dialog.[ch]
* app/actionarea.[ch]
* app/app_procs.c
* app/brush_edit.c
* app/brush_select.c
* app/color_select.c
* app/convert.c
* app/devices.c
* app/gdisplay.c
* app/gdisplay_ops.c
* app/histogram_tool.[ch]
* app/info_window.c
* app/install.c
* app/ops_buttons.c
* app/palette.c
* app/palette_select.c
* app/paths_dialog.c
* app/pattern_select.c
* app/resize.c
* app/scale_toolc.c
* app/text_tool.c:
s/container_border_width/container_set_border_width/g,
s/sprintf/g_snprintf/g, replaced some constant string lengths with
strlen(x).
* app/bezier_select.c
* app/blend.c
* app/boundary.c
* app/errors.[ch]
* app/free_select.c
* app/gimpbrushlist.c
* app/gimprc.c
* app/iscissors.c
* app/main.c
* app/patterns.[ch]
* app/text_tool.c: namespace fanaticism: prefixed all gimp error
functions with "gimp_" and formated the messages more uniformly.
* app/gradient.c
* app/gradient_select.c: same stuff as above for the ui
code. There are still some sub-dialogs which need cleanup.
Did some cleanup in most of these files: prototypes, removed tons
of #include's, i18n fixes, s/w/widget/ as above, indentation, ...
1999-07-23 00:21:10 +08:00
|
|
|
g_print ("%d(%p) x,y=%f,%f type=%d next=%p prev=%p next_curve=%p\n", i,pt, pt->x, pt->y,pt->type,pt->next,pt->prev,pt->next_curve);
|
1999-05-14 06:53:40 +08:00
|
|
|
if(pt->next != start_pt && pt->next_curve)
|
new ui for the "Layer Offset" dialog.
1999-07-22 Michael Natterer <mitschel@cs.tu-berlin.de>
* app/channel_ops.[ch]: new ui for the "Layer Offset" dialog.
* app/channels_dialog.c
* app/layers_dialog.c: major code cleanup: Folded some callbacks
into common ones, "widget" instead of "w", indentation, ...
* app/commands.c
* app/interface.[ch]
* app/global_edit.c: the query boxes must be shown by the caller
now. There's no need to split up the string for the message box
manually as the Gtk 1.2 label widget handles newlines corectly.
Added the "edge_lock" toggle to the "Shrink Selection" dialog.
Nicer spacings for the query and message boxes.
* app/ink.c: tried to grab the pointer in the blob preview but
failed. Left the code there as a reminder (commented out).
* app/menus.c: reordered <Image>/Select.
I was bored and grep-ed the sources for ancient or deprecated stuff:
* app/about_dialog.[ch]
* app/actionarea.[ch]
* app/app_procs.c
* app/brush_edit.c
* app/brush_select.c
* app/color_select.c
* app/convert.c
* app/devices.c
* app/gdisplay.c
* app/gdisplay_ops.c
* app/histogram_tool.[ch]
* app/info_window.c
* app/install.c
* app/ops_buttons.c
* app/palette.c
* app/palette_select.c
* app/paths_dialog.c
* app/pattern_select.c
* app/resize.c
* app/scale_toolc.c
* app/text_tool.c:
s/container_border_width/container_set_border_width/g,
s/sprintf/g_snprintf/g, replaced some constant string lengths with
strlen(x).
* app/bezier_select.c
* app/blend.c
* app/boundary.c
* app/errors.[ch]
* app/free_select.c
* app/gimpbrushlist.c
* app/gimprc.c
* app/iscissors.c
* app/main.c
* app/patterns.[ch]
* app/text_tool.c: namespace fanaticism: prefixed all gimp error
functions with "gimp_" and formated the messages more uniformly.
* app/gradient.c
* app/gradient_select.c: same stuff as above for the ui
code. There are still some sub-dialogs which need cleanup.
Did some cleanup in most of these files: prototypes, removed tons
of #include's, i18n fixes, s/w/widget/ as above, indentation, ...
1999-07-23 00:21:10 +08:00
|
|
|
g_print ("Curve out a sync!!\n");
|
1999-05-14 06:53:40 +08:00
|
|
|
if(pt->next_curve)
|
|
|
|
{
|
|
|
|
pt = pt->next_curve;
|
|
|
|
start_pt = pt;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
pt = pt->next;
|
1998-06-26 16:03:50 +08:00
|
|
|
}
|
|
|
|
|
new ui for the "Layer Offset" dialog.
1999-07-22 Michael Natterer <mitschel@cs.tu-berlin.de>
* app/channel_ops.[ch]: new ui for the "Layer Offset" dialog.
* app/channels_dialog.c
* app/layers_dialog.c: major code cleanup: Folded some callbacks
into common ones, "widget" instead of "w", indentation, ...
* app/commands.c
* app/interface.[ch]
* app/global_edit.c: the query boxes must be shown by the caller
now. There's no need to split up the string for the message box
manually as the Gtk 1.2 label widget handles newlines corectly.
Added the "edge_lock" toggle to the "Shrink Selection" dialog.
Nicer spacings for the query and message boxes.
* app/ink.c: tried to grab the pointer in the blob preview but
failed. Left the code there as a reminder (commented out).
* app/menus.c: reordered <Image>/Select.
I was bored and grep-ed the sources for ancient or deprecated stuff:
* app/about_dialog.[ch]
* app/actionarea.[ch]
* app/app_procs.c
* app/brush_edit.c
* app/brush_select.c
* app/color_select.c
* app/convert.c
* app/devices.c
* app/gdisplay.c
* app/gdisplay_ops.c
* app/histogram_tool.[ch]
* app/info_window.c
* app/install.c
* app/ops_buttons.c
* app/palette.c
* app/palette_select.c
* app/paths_dialog.c
* app/pattern_select.c
* app/resize.c
* app/scale_toolc.c
* app/text_tool.c:
s/container_border_width/container_set_border_width/g,
s/sprintf/g_snprintf/g, replaced some constant string lengths with
strlen(x).
* app/bezier_select.c
* app/blend.c
* app/boundary.c
* app/errors.[ch]
* app/free_select.c
* app/gimpbrushlist.c
* app/gimprc.c
* app/iscissors.c
* app/main.c
* app/patterns.[ch]
* app/text_tool.c: namespace fanaticism: prefixed all gimp error
functions with "gimp_" and formated the messages more uniformly.
* app/gradient.c
* app/gradient_select.c: same stuff as above for the ui
code. There are still some sub-dialogs which need cleanup.
Did some cleanup in most of these files: prototypes, removed tons
of #include's, i18n fixes, s/w/widget/ as above, indentation, ...
1999-07-23 00:21:10 +08:00
|
|
|
g_print ("core : %p\n", sel->core);
|
|
|
|
g_print ("closed : %d\n", sel->closed);
|
|
|
|
g_print ("draw : %d\n", sel->draw);
|
|
|
|
g_print ("state: %d\n", sel->state);
|
1998-06-26 16:03:50 +08:00
|
|
|
}
|
|
|
|
|
1999-03-13 06:04:30 +08:00
|
|
|
/* check whether vectors (offx, offy), (l_offx, l_offy) have the same angle. */
|
|
|
|
static gboolean
|
|
|
|
stroke_interpolatable (int offx, int offy, int l_offx, int l_offy, gdouble error)
|
|
|
|
{
|
|
|
|
if ((offx == l_offx) & (offy == l_offy))
|
|
|
|
return TRUE;
|
|
|
|
else if ((offx == 0) | (l_offx == 0))
|
|
|
|
if (offx == l_offx)
|
|
|
|
return ((0 <= offy) & (0 <= offy)) | ((offy < 0) & (l_offy < 0));
|
|
|
|
else
|
|
|
|
return FALSE;
|
|
|
|
else if ((offy == 0) | (l_offy == 0))
|
|
|
|
if (offy == l_offy)
|
|
|
|
return ((0 < offx) & (0 < l_offx)) | ((offx < 0) & (l_offx < 0));
|
|
|
|
else
|
|
|
|
return FALSE;
|
|
|
|
/* At this point, we can assert: offx, offy, l_offx, l_offy != 0 */
|
|
|
|
else if (((0 < offx) & (0 < l_offx)) | ((offx < 0) & (l_offx < 0)))
|
|
|
|
{
|
|
|
|
gdouble grad1, grad2;
|
|
|
|
|
|
|
|
if (ABS (offy) < ABS (offx))
|
|
|
|
{
|
|
|
|
grad1 = (gdouble) offy / (gdouble) offx;
|
|
|
|
grad2 = (gdouble) l_offy / (gdouble) l_offx;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
grad1 = (gdouble) offx / (gdouble) offy;
|
|
|
|
grad2 = (gdouble) l_offx / (gdouble) l_offy;
|
|
|
|
}
|
|
|
|
/* printf ("error: %f / %f\n", ABS (grad1 - grad2), error); */
|
|
|
|
return (ABS (grad1 - grad2) <= error);
|
|
|
|
}
|
|
|
|
else
|
|
|
|
return FALSE;
|
|
|
|
}
|
1999-02-09 02:16:28 +08:00
|
|
|
|
|
|
|
static void
|
1999-03-13 06:04:30 +08:00
|
|
|
bezier_stack_points_aux (GdkPoint *points,
|
|
|
|
int start,
|
|
|
|
int end,
|
1999-04-06 07:33:50 +08:00
|
|
|
gdouble error,
|
|
|
|
BezierRenderPnts *rpnts)
|
1999-02-09 02:16:28 +08:00
|
|
|
{
|
1999-03-13 06:04:30 +08:00
|
|
|
const gint expand_size = 32;
|
|
|
|
gint med;
|
|
|
|
gint offx, offy, l_offx, l_offy;
|
1999-02-09 02:16:28 +08:00
|
|
|
|
1999-04-06 07:33:50 +08:00
|
|
|
if (rpnts->stroke_points == NULL)
|
1999-03-13 06:04:30 +08:00
|
|
|
return;
|
|
|
|
|
|
|
|
/* BASE CASE: stack the end point */
|
|
|
|
if (end - start <= 1)
|
1999-02-09 02:16:28 +08:00
|
|
|
{
|
1999-04-06 07:33:50 +08:00
|
|
|
if ((rpnts->stroke_points[rpnts->num_stroke_points * 2 - 2] == points[end].x)
|
|
|
|
&& (rpnts->stroke_points[rpnts->num_stroke_points * 2 - 1] == points[end].y))
|
1999-03-13 06:04:30 +08:00
|
|
|
return;
|
|
|
|
|
1999-04-06 07:33:50 +08:00
|
|
|
rpnts->num_stroke_points++;
|
|
|
|
if (rpnts->len_stroke_points <= rpnts->num_stroke_points)
|
1999-03-13 06:04:30 +08:00
|
|
|
{
|
1999-04-06 07:33:50 +08:00
|
|
|
rpnts->len_stroke_points += expand_size;
|
|
|
|
rpnts->stroke_points = g_renew (double, rpnts->stroke_points, 2 * rpnts->len_stroke_points);
|
|
|
|
if (rpnts->stroke_points == NULL)
|
1999-03-13 06:04:30 +08:00
|
|
|
{
|
1999-04-06 07:33:50 +08:00
|
|
|
rpnts->len_stroke_points = rpnts->num_stroke_points = 0;
|
1999-03-13 06:04:30 +08:00
|
|
|
return;
|
|
|
|
}
|
|
|
|
}
|
1999-04-06 07:33:50 +08:00
|
|
|
rpnts->stroke_points[rpnts->num_stroke_points * 2 - 2] = points[end].x;
|
|
|
|
rpnts->stroke_points[rpnts->num_stroke_points * 2 - 1] = points[end].y;
|
1999-03-13 06:04:30 +08:00
|
|
|
return;
|
1999-02-09 02:16:28 +08:00
|
|
|
}
|
1999-03-13 06:04:30 +08:00
|
|
|
|
|
|
|
if (end - start <= 32)
|
1999-02-09 02:16:28 +08:00
|
|
|
{
|
1999-03-13 06:04:30 +08:00
|
|
|
gint i;
|
|
|
|
|
|
|
|
for (i = start+ 1; i <= end; i++)
|
1999-04-06 07:33:50 +08:00
|
|
|
bezier_stack_points_aux (points, i, i, 0,rpnts);
|
1999-03-13 06:04:30 +08:00
|
|
|
return;
|
1999-02-09 02:16:28 +08:00
|
|
|
}
|
1999-03-13 06:04:30 +08:00
|
|
|
/* Otherwise, check whether to divide the segment recursively */
|
|
|
|
offx = points[end].x - points[start].x;
|
|
|
|
offy = points[end].y - points[start].y;
|
|
|
|
med = (end + start) / 2;
|
|
|
|
|
|
|
|
l_offx = points[med].x - points[start].x;
|
|
|
|
l_offy = points[med].y - points[start].y;
|
1999-02-09 02:16:28 +08:00
|
|
|
|
1999-03-13 06:04:30 +08:00
|
|
|
if (! stroke_interpolatable (offx, offy, l_offx, l_offy, error))
|
1999-02-09 02:16:28 +08:00
|
|
|
{
|
1999-04-06 07:33:50 +08:00
|
|
|
bezier_stack_points_aux (points, start, med, error, rpnts);
|
|
|
|
bezier_stack_points_aux (points, med, end, error, rpnts);
|
1999-03-13 06:04:30 +08:00
|
|
|
return;
|
1999-02-09 02:16:28 +08:00
|
|
|
}
|
|
|
|
|
1999-03-13 06:04:30 +08:00
|
|
|
l_offx = points[end].x - points[med].x;
|
|
|
|
l_offy = points[end].y - points[med].y;
|
1999-03-06 07:50:24 +08:00
|
|
|
|
1999-03-13 06:04:30 +08:00
|
|
|
if (! stroke_interpolatable (offx, offy, l_offx, l_offy, error))
|
1999-03-06 07:50:24 +08:00
|
|
|
{
|
1999-04-06 07:33:50 +08:00
|
|
|
bezier_stack_points_aux (points, start, med, error, rpnts);
|
|
|
|
bezier_stack_points_aux (points, med, end, error, rpnts);
|
1999-03-06 07:50:24 +08:00
|
|
|
return;
|
|
|
|
}
|
1999-03-13 06:04:30 +08:00
|
|
|
/* Now, the curve can be represented by a points pair: (start, end).
|
|
|
|
So, add the last point to stroke_points. */
|
1999-04-06 07:33:50 +08:00
|
|
|
bezier_stack_points_aux (points, end, end, 0, rpnts);
|
1999-03-06 07:50:24 +08:00
|
|
|
}
|
|
|
|
|
1999-03-13 06:04:30 +08:00
|
|
|
static void
|
|
|
|
bezier_stack_points (BezierSelect *bezier_sel,
|
|
|
|
GdkPoint *points,
|
1999-04-06 07:33:50 +08:00
|
|
|
int npoints,
|
|
|
|
gpointer udata)
|
1999-03-13 06:04:30 +08:00
|
|
|
{
|
|
|
|
gint i;
|
|
|
|
gint expand_size = 32;
|
|
|
|
gint minx, maxx, miny, maxy;
|
|
|
|
gdouble error;
|
1999-04-06 07:33:50 +08:00
|
|
|
BezierRenderPnts *rpnts = udata;
|
1999-03-13 06:04:30 +08:00
|
|
|
|
|
|
|
if (npoints < 2) /* Does this happen? */
|
|
|
|
return;
|
|
|
|
|
1999-04-06 07:33:50 +08:00
|
|
|
if (rpnts->stroke_points == NULL) /* initialize it here */
|
1999-03-13 06:04:30 +08:00
|
|
|
{
|
1999-04-06 07:33:50 +08:00
|
|
|
rpnts->num_stroke_points = 0;
|
|
|
|
rpnts->len_stroke_points = expand_size;
|
|
|
|
rpnts->stroke_points = g_new (double, 2 * rpnts->len_stroke_points);
|
1999-03-13 06:04:30 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
maxx = minx = points[0].x;
|
|
|
|
maxy = miny = points[0].y;
|
|
|
|
for (i = 1; i < npoints; i++)
|
|
|
|
{
|
|
|
|
if (points[i].x < minx)
|
|
|
|
minx = points[i].x;
|
|
|
|
else if (maxx < points[i].x)
|
|
|
|
maxx = points[i].x;
|
|
|
|
if (points[i].y < miny)
|
|
|
|
miny = points[i].x;
|
|
|
|
else if (maxy < points[i].y)
|
|
|
|
maxy = points[i].y;
|
|
|
|
}
|
|
|
|
/* allow one pixel fluctuation */
|
|
|
|
error = 2.0 / MAX(maxx - minx, maxy - miny);
|
1999-07-20 06:42:49 +08:00
|
|
|
error = 0.0; /* ALT */
|
1999-03-13 06:04:30 +08:00
|
|
|
|
|
|
|
/* add the start point */
|
1999-04-06 07:33:50 +08:00
|
|
|
bezier_stack_points_aux (points, 0, 0, 0, rpnts);
|
1999-03-06 07:50:24 +08:00
|
|
|
|
1999-03-13 06:04:30 +08:00
|
|
|
/* divide segments recursively */
|
1999-04-06 07:33:50 +08:00
|
|
|
bezier_stack_points_aux (points, 0, npoints - 1, error, rpnts);
|
1999-03-13 06:04:30 +08:00
|
|
|
|
|
|
|
/* printf ("npoints: %d\n", npoints); */
|
|
|
|
}
|
1999-03-06 07:50:24 +08:00
|
|
|
|
1999-04-06 07:33:50 +08:00
|
|
|
static gint
|
|
|
|
bezier_gen_points(BezierSelect *bezier_sel,
|
|
|
|
int open_path,
|
|
|
|
BezierRenderPnts *rpnts)
|
1999-02-09 02:16:28 +08:00
|
|
|
{
|
|
|
|
BezierPoint * points;
|
1999-05-14 06:53:40 +08:00
|
|
|
BezierPoint * start_pt;
|
|
|
|
BezierPoint * next_curve;
|
|
|
|
BezierRenderPnts *next_rpnts = rpnts;
|
1999-07-20 06:42:49 +08:00
|
|
|
gint point_counts = 0;
|
1999-02-09 02:16:28 +08:00
|
|
|
|
|
|
|
/* stack points */
|
|
|
|
points = bezier_sel->points;
|
1999-05-14 06:53:40 +08:00
|
|
|
start_pt = bezier_sel->points;
|
1999-04-06 07:33:50 +08:00
|
|
|
|
1999-05-14 06:53:40 +08:00
|
|
|
if(bezier_sel->num_points >= 4)
|
1999-02-09 02:16:28 +08:00
|
|
|
{
|
1999-05-14 06:53:40 +08:00
|
|
|
do {
|
1999-07-20 06:42:49 +08:00
|
|
|
point_counts = count_points_on_curve(points);
|
|
|
|
if(point_counts < 4)
|
|
|
|
return(TRUE);
|
1999-05-14 06:53:40 +08:00
|
|
|
do {
|
1999-02-09 02:16:28 +08:00
|
|
|
bezier_draw_segment (bezier_sel, points,
|
1999-07-23 07:11:46 +08:00
|
|
|
SUBDIVIDE, AA_IMAGE_COORDS,
|
1999-04-06 07:33:50 +08:00
|
|
|
bezier_stack_points,
|
1999-05-14 06:53:40 +08:00
|
|
|
(gpointer)next_rpnts);
|
|
|
|
|
|
|
|
points = next_anchor(points,&next_curve);
|
|
|
|
} while (points != start_pt && points);
|
|
|
|
start_pt = next_curve;
|
|
|
|
points = next_curve;
|
|
|
|
if(next_curve)
|
|
|
|
{
|
|
|
|
next_rpnts->next_curve = g_new0(BezierRenderPnts,1);
|
|
|
|
next_rpnts = next_rpnts->next_curve;
|
|
|
|
}
|
|
|
|
} while (next_curve);
|
1999-02-09 02:16:28 +08:00
|
|
|
}
|
1999-05-14 06:53:40 +08:00
|
|
|
|
|
|
|
return (TRUE);
|
1999-04-06 07:33:50 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
void
|
|
|
|
bezier_stroke (BezierSelect *bezier_sel,
|
|
|
|
GDisplay *gdisp,
|
|
|
|
int subdivisions,
|
|
|
|
int open_path)
|
|
|
|
{
|
|
|
|
Argument *return_vals;
|
|
|
|
int nreturn_vals;
|
|
|
|
int redraw;
|
1999-05-14 06:53:40 +08:00
|
|
|
BezierRenderPnts *next_rpnts;
|
1999-04-06 07:33:50 +08:00
|
|
|
BezierRenderPnts *rpnts = g_new0(BezierRenderPnts,1);
|
|
|
|
|
|
|
|
redraw = bezier_gen_points(bezier_sel,open_path,rpnts);
|
1999-05-14 06:53:40 +08:00
|
|
|
do
|
|
|
|
{
|
1999-04-06 07:33:50 +08:00
|
|
|
if (rpnts->stroke_points)
|
1999-03-13 06:04:30 +08:00
|
|
|
{
|
1999-03-19 11:19:18 +08:00
|
|
|
GimpDrawable *drawable;
|
|
|
|
int offset_x, offset_y;
|
1999-07-23 07:11:46 +08:00
|
|
|
gdouble *ptr;
|
1999-03-19 11:19:18 +08:00
|
|
|
|
|
|
|
drawable = gimage_active_drawable (gdisp->gimage);
|
|
|
|
gimp_drawable_offsets (drawable, &offset_x, &offset_y);
|
|
|
|
|
1999-07-23 07:11:46 +08:00
|
|
|
ptr = rpnts->stroke_points;
|
|
|
|
while (ptr < rpnts->stroke_points + (rpnts->num_stroke_points * 2))
|
|
|
|
{
|
|
|
|
*ptr /= SUPERSAMPLE;
|
|
|
|
*ptr++ -= offset_x;
|
|
|
|
*ptr /= SUPERSAMPLE;
|
|
|
|
*ptr++ -= offset_y;
|
|
|
|
}
|
1999-03-19 11:19:18 +08:00
|
|
|
|
1999-07-20 06:42:49 +08:00
|
|
|
/* Stroke with the correct tool */
|
1999-10-19 04:55:25 +08:00
|
|
|
return_vals = procedural_db_run_proc (tool_active_PDB_string(),
|
1999-03-13 06:04:30 +08:00
|
|
|
&nreturn_vals,
|
1999-03-19 11:19:18 +08:00
|
|
|
PDB_DRAWABLE, drawable_ID (drawable),
|
1999-04-06 07:33:50 +08:00
|
|
|
PDB_INT32, (gint32) rpnts->num_stroke_points * 2,
|
|
|
|
PDB_FLOATARRAY, rpnts->stroke_points,
|
1999-03-13 06:04:30 +08:00
|
|
|
PDB_END);
|
|
|
|
|
1999-04-21 07:03:31 +08:00
|
|
|
if (return_vals && return_vals[0].value.pdb_int == PDB_SUCCESS)
|
1999-03-13 06:04:30 +08:00
|
|
|
{
|
|
|
|
if (redraw)
|
|
|
|
{
|
|
|
|
/* FIXME: how to update the image? */
|
|
|
|
}
|
|
|
|
gdisplays_flush ();
|
|
|
|
}
|
|
|
|
else
|
|
|
|
g_message (_("Paintbrush operation failed."));
|
1999-02-09 02:16:28 +08:00
|
|
|
|
1999-03-13 06:04:30 +08:00
|
|
|
procedural_db_destroy_args (return_vals, nreturn_vals);
|
1999-02-09 02:16:28 +08:00
|
|
|
|
1999-04-06 07:33:50 +08:00
|
|
|
g_free (rpnts->stroke_points);
|
1999-03-13 06:04:30 +08:00
|
|
|
}
|
1999-05-14 06:53:40 +08:00
|
|
|
next_rpnts = rpnts->next_curve;
|
|
|
|
rpnts->stroke_points = NULL;
|
|
|
|
rpnts->len_stroke_points = rpnts->num_stroke_points = 0;
|
|
|
|
g_free(rpnts);
|
|
|
|
rpnts = next_rpnts;
|
|
|
|
} while (rpnts);
|
1999-03-13 06:04:30 +08:00
|
|
|
/* printf ("num_stroke_points: %d\ndone.\n", num_stroke_points); */
|
|
|
|
|
1999-05-14 06:53:40 +08:00
|
|
|
/* rpnts->stroke_points = NULL; */
|
|
|
|
/* rpnts->len_stroke_points = rpnts->num_stroke_points = 0; */
|
1999-04-06 07:33:50 +08:00
|
|
|
|
1999-05-14 06:53:40 +08:00
|
|
|
/* g_free(rpnts); */
|
1999-04-06 07:33:50 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
|
|
|
bezier_draw_segment_for_distance (BezierSelect *bezier_sel,
|
|
|
|
BezierPoint *points,
|
|
|
|
int subdivisions,
|
|
|
|
BezierDistance *bdist)
|
|
|
|
{
|
|
|
|
BezierMatrix geometry;
|
|
|
|
BezierMatrix tmp1, tmp2;
|
|
|
|
BezierMatrix deltas;
|
|
|
|
double x, dx, dx2, dx3;
|
|
|
|
double y, dy, dy2, dy3;
|
|
|
|
double d, d2, d3;
|
|
|
|
int index;
|
|
|
|
int i;
|
|
|
|
|
|
|
|
/* construct the geometry matrix from the segment */
|
|
|
|
/* assumes that a valid segment containing 4 points is passed in */
|
|
|
|
|
|
|
|
if(bdist->found)
|
|
|
|
return;
|
|
|
|
|
|
|
|
for (i = 0; i < 4; i++)
|
|
|
|
{
|
|
|
|
if (!points)
|
1999-09-23 19:49:16 +08:00
|
|
|
gimp_fatal_error ("bezier_draw_segment_for_distance(): Bad bezier segment");
|
1999-04-06 07:33:50 +08:00
|
|
|
|
|
|
|
geometry[i][0] = points->x;
|
|
|
|
geometry[i][1] = points->y;
|
|
|
|
geometry[i][2] = 0;
|
|
|
|
geometry[i][3] = 0;
|
|
|
|
|
|
|
|
points = points->next;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* subdivide the curve n times */
|
|
|
|
/* n can be adjusted to give a finer or coarser curve */
|
|
|
|
|
|
|
|
d = 1.0 / subdivisions;
|
|
|
|
d2 = d * d;
|
|
|
|
d3 = d * d * d;
|
|
|
|
|
|
|
|
/* construct a temporary matrix for determining the forward diffencing deltas */
|
|
|
|
|
|
|
|
tmp2[0][0] = 0; tmp2[0][1] = 0; tmp2[0][2] = 0; tmp2[0][3] = 1;
|
|
|
|
tmp2[1][0] = d3; tmp2[1][1] = d2; tmp2[1][2] = d; tmp2[1][3] = 0;
|
|
|
|
tmp2[2][0] = 6*d3; tmp2[2][1] = 2*d2; tmp2[2][2] = 0; tmp2[2][3] = 0;
|
|
|
|
tmp2[3][0] = 6*d3; tmp2[3][1] = 0; tmp2[3][2] = 0; tmp2[3][3] = 0;
|
|
|
|
|
|
|
|
/* compose the basis and geometry matrices */
|
|
|
|
bezier_compose (basis, geometry, tmp1);
|
|
|
|
|
|
|
|
/* compose the above results to get the deltas matrix */
|
|
|
|
bezier_compose (tmp2, tmp1, deltas);
|
|
|
|
|
|
|
|
/* extract the x deltas */
|
|
|
|
x = deltas[0][0];
|
|
|
|
dx = deltas[1][0];
|
|
|
|
dx2 = deltas[2][0];
|
|
|
|
dx3 = deltas[3][0];
|
|
|
|
|
|
|
|
/* extract the y deltas */
|
|
|
|
y = deltas[0][1];
|
|
|
|
dy = deltas[1][1];
|
|
|
|
dy2 = deltas[2][1];
|
|
|
|
dy3 = deltas[3][1];
|
|
|
|
|
|
|
|
index = 1;
|
|
|
|
|
|
|
|
/* loop over the curve */
|
|
|
|
for (i = 0; i < subdivisions; i++)
|
|
|
|
{
|
|
|
|
/* increment the x values */
|
|
|
|
x += dx;
|
|
|
|
dx += dx2;
|
|
|
|
dx2 += dx3;
|
|
|
|
|
|
|
|
/* increment the y values */
|
|
|
|
y += dy;
|
|
|
|
dy += dy2;
|
|
|
|
dy2 += dy3;
|
|
|
|
|
new ui for the "Layer Offset" dialog.
1999-07-22 Michael Natterer <mitschel@cs.tu-berlin.de>
* app/channel_ops.[ch]: new ui for the "Layer Offset" dialog.
* app/channels_dialog.c
* app/layers_dialog.c: major code cleanup: Folded some callbacks
into common ones, "widget" instead of "w", indentation, ...
* app/commands.c
* app/interface.[ch]
* app/global_edit.c: the query boxes must be shown by the caller
now. There's no need to split up the string for the message box
manually as the Gtk 1.2 label widget handles newlines corectly.
Added the "edge_lock" toggle to the "Shrink Selection" dialog.
Nicer spacings for the query and message boxes.
* app/ink.c: tried to grab the pointer in the blob preview but
failed. Left the code there as a reminder (commented out).
* app/menus.c: reordered <Image>/Select.
I was bored and grep-ed the sources for ancient or deprecated stuff:
* app/about_dialog.[ch]
* app/actionarea.[ch]
* app/app_procs.c
* app/brush_edit.c
* app/brush_select.c
* app/color_select.c
* app/convert.c
* app/devices.c
* app/gdisplay.c
* app/gdisplay_ops.c
* app/histogram_tool.[ch]
* app/info_window.c
* app/install.c
* app/ops_buttons.c
* app/palette.c
* app/palette_select.c
* app/paths_dialog.c
* app/pattern_select.c
* app/resize.c
* app/scale_toolc.c
* app/text_tool.c:
s/container_border_width/container_set_border_width/g,
s/sprintf/g_snprintf/g, replaced some constant string lengths with
strlen(x).
* app/bezier_select.c
* app/blend.c
* app/boundary.c
* app/errors.[ch]
* app/free_select.c
* app/gimpbrushlist.c
* app/gimprc.c
* app/iscissors.c
* app/main.c
* app/patterns.[ch]
* app/text_tool.c: namespace fanaticism: prefixed all gimp error
functions with "gimp_" and formated the messages more uniformly.
* app/gradient.c
* app/gradient_select.c: same stuff as above for the ui
code. There are still some sub-dialogs which need cleanup.
Did some cleanup in most of these files: prototypes, removed tons
of #include's, i18n fixes, s/w/widget/ as above, indentation, ...
1999-07-23 00:21:10 +08:00
|
|
|
/* g_print ("x = %g, y = %g\n",x,y); */
|
1999-04-06 07:33:50 +08:00
|
|
|
|
|
|
|
/* if this point is different than the last one...then draw it */
|
|
|
|
/* Note :
|
|
|
|
* It assumes the udata is the place we want the
|
|
|
|
* floating version of the coords to be stuffed.
|
|
|
|
* These are needed when we calculate the gradient of the
|
|
|
|
* curve.
|
|
|
|
*/
|
|
|
|
|
|
|
|
if(!bdist->firstpnt)
|
|
|
|
{
|
|
|
|
gdouble rx = x;
|
|
|
|
gdouble ry = y;
|
|
|
|
gdouble dx = bdist->lastx - rx;
|
|
|
|
gdouble dy = bdist->lasty - ry;
|
|
|
|
|
|
|
|
bdist->curdist += sqrt((dx*dx)+(dy*dy));
|
|
|
|
if(bdist->curdist >= bdist->dist)
|
|
|
|
{
|
1999-08-05 07:22:29 +08:00
|
|
|
*(bdist->x) = ROUND((rx + dx/2));
|
|
|
|
*(bdist->y) = ROUND((ry + dy/2));
|
1999-04-06 07:33:50 +08:00
|
|
|
if(dx == 0.0)
|
|
|
|
*(bdist->gradient) = G_MAXDOUBLE;
|
|
|
|
else
|
|
|
|
*(bdist->gradient) = dy/dx;
|
|
|
|
|
new ui for the "Layer Offset" dialog.
1999-07-22 Michael Natterer <mitschel@cs.tu-berlin.de>
* app/channel_ops.[ch]: new ui for the "Layer Offset" dialog.
* app/channels_dialog.c
* app/layers_dialog.c: major code cleanup: Folded some callbacks
into common ones, "widget" instead of "w", indentation, ...
* app/commands.c
* app/interface.[ch]
* app/global_edit.c: the query boxes must be shown by the caller
now. There's no need to split up the string for the message box
manually as the Gtk 1.2 label widget handles newlines corectly.
Added the "edge_lock" toggle to the "Shrink Selection" dialog.
Nicer spacings for the query and message boxes.
* app/ink.c: tried to grab the pointer in the blob preview but
failed. Left the code there as a reminder (commented out).
* app/menus.c: reordered <Image>/Select.
I was bored and grep-ed the sources for ancient or deprecated stuff:
* app/about_dialog.[ch]
* app/actionarea.[ch]
* app/app_procs.c
* app/brush_edit.c
* app/brush_select.c
* app/color_select.c
* app/convert.c
* app/devices.c
* app/gdisplay.c
* app/gdisplay_ops.c
* app/histogram_tool.[ch]
* app/info_window.c
* app/install.c
* app/ops_buttons.c
* app/palette.c
* app/palette_select.c
* app/paths_dialog.c
* app/pattern_select.c
* app/resize.c
* app/scale_toolc.c
* app/text_tool.c:
s/container_border_width/container_set_border_width/g,
s/sprintf/g_snprintf/g, replaced some constant string lengths with
strlen(x).
* app/bezier_select.c
* app/blend.c
* app/boundary.c
* app/errors.[ch]
* app/free_select.c
* app/gimpbrushlist.c
* app/gimprc.c
* app/iscissors.c
* app/main.c
* app/patterns.[ch]
* app/text_tool.c: namespace fanaticism: prefixed all gimp error
functions with "gimp_" and formated the messages more uniformly.
* app/gradient.c
* app/gradient_select.c: same stuff as above for the ui
code. There are still some sub-dialogs which need cleanup.
Did some cleanup in most of these files: prototypes, removed tons
of #include's, i18n fixes, s/w/widget/ as above, indentation, ...
1999-07-23 00:21:10 +08:00
|
|
|
/* g_print ("found x = %d, y = %d\n",*(bdist->x),*(bdist->y)); */
|
1999-04-06 07:33:50 +08:00
|
|
|
bdist->found = TRUE;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
bdist->lastx = rx;
|
|
|
|
bdist->lasty = ry;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
bdist->firstpnt = FALSE;
|
|
|
|
bdist->lastx = x;
|
|
|
|
bdist->lasty = y;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
|
|
|
bezier_draw_curve_for_distance (BezierSelect *bezier_sel,
|
|
|
|
BezierDistance *udata)
|
|
|
|
{
|
|
|
|
BezierPoint * points;
|
|
|
|
BezierPoint * start_pt;
|
1999-05-14 06:53:40 +08:00
|
|
|
BezierPoint * next_curve;
|
1999-04-06 07:33:50 +08:00
|
|
|
|
|
|
|
points = bezier_sel->points;
|
1999-05-14 06:53:40 +08:00
|
|
|
start_pt = bezier_sel->points;
|
1999-04-06 07:33:50 +08:00
|
|
|
|
1999-05-14 06:53:40 +08:00
|
|
|
if(bezier_sel->num_points >= 4)
|
1999-04-06 07:33:50 +08:00
|
|
|
{
|
|
|
|
do {
|
1999-05-14 06:53:40 +08:00
|
|
|
do {
|
1999-04-06 07:33:50 +08:00
|
|
|
bezier_draw_segment_for_distance (bezier_sel, points,
|
|
|
|
SUBDIVIDE,
|
|
|
|
udata);
|
1999-05-14 06:53:40 +08:00
|
|
|
points = next_anchor(points,&next_curve);
|
|
|
|
} while (points != start_pt && points);
|
|
|
|
start_pt = next_curve;
|
|
|
|
points = next_curve;
|
|
|
|
} while (next_curve);
|
1999-04-06 07:33:50 +08:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
gint
|
|
|
|
bezier_distance_along(BezierSelect *bezier_sel,
|
|
|
|
int open_path,
|
|
|
|
gdouble dist,
|
|
|
|
gint *x,
|
|
|
|
gint *y,
|
|
|
|
gdouble *gradient)
|
|
|
|
{
|
|
|
|
/* Render the curve as points then walk along it... */
|
|
|
|
BezierDistance *bdist = g_new0(BezierDistance,1);
|
|
|
|
gint ret;
|
|
|
|
|
|
|
|
bdist->firstpnt = TRUE;
|
|
|
|
bdist->curdist = 0.0;
|
|
|
|
bdist->lastx = 0.0;
|
|
|
|
bdist->lasty = 0.0;
|
|
|
|
bdist->dist = dist;
|
|
|
|
bdist->x = x;
|
|
|
|
bdist->y = y;
|
|
|
|
bdist->gradient = gradient;
|
|
|
|
bdist->found = FALSE;
|
|
|
|
|
|
|
|
bezier_draw_curve_for_distance (bezier_sel,bdist);
|
|
|
|
ret = bdist->found;
|
|
|
|
|
|
|
|
g_free(bdist);
|
|
|
|
return (ret);
|
1999-02-09 02:16:28 +08:00
|
|
|
}
|