gimp/app/tools/gimpiscissorstool.c

2178 lines
68 KiB
C
Raw Normal View History

/* GIMP - The GNU Image Manipulation Program
1997-11-25 06:05:25 +08:00
* Copyright (C) 1995 Spencer Kimball and Peter Mattis
*
* This program is free software: you can redistribute it and/or modify
1997-11-25 06:05:25 +08:00
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 3 of the License, or
1997-11-25 06:05:25 +08:00
* (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, see <http://www.gnu.org/licenses/>.
1997-11-25 06:05:25 +08:00
*/
/* This tool is based on a paper from SIGGRAPH '95:
* "Intelligent Scissors for Image Composition", Eric N. Mortensen and
* William A. Barrett, Brigham Young University.
*
* thanks to Professor D. Forsyth for prompting us to implement this tool. */
app/tools/gimptoolcontrol.[ch] resurrected the motion hints and cursor * app/tools/gimptoolcontrol.[ch] * libgimptool/gimptool.c: resurrected the motion hints and cursor changing code. app/tools/gimpairbrushtool.c app/tools/gimpbezierselecttool.c app/tools/gimpblendtool.c app/tools/gimpbucketfilltool.c app/tools/gimpbycolorselecttool.c app/tools/gimpclonetool.c app/tools/gimpcolorbalancetool.c app/tools/gimpcolorpickertool.c app/tools/gimpconvolvetool.c app/tools/gimpcroptool.c app/tools/gimpcurvestool.c app/tools/gimpdodgeburntool.c app/tools/gimpeditselectiontool.c app/tools/gimpellipseselecttool.c app/tools/gimperasertool.c app/tools/gimpfliptool.c app/tools/gimpfuzzyselecttool.c app/tools/gimphistogramtool.c app/tools/gimphuesaturationtool.c app/tools/gimpimagemaptool.c app/tools/gimpinktool.c app/tools/gimpiscissorstool.c app/tools/gimplevelstool.c app/tools/gimpmagnifytool.c app/tools/gimpmeasuretool.c app/tools/gimpmovetool.c app/tools/gimppaintbrushtool.c app/tools/gimppainttool.c app/tools/gimppathtool.c app/tools/gimppenciltool.c app/tools/gimpperspectivetool.c app/tools/gimprectselecttool.c app/tools/gimprotatetool.c app/tools/gimpscaletool.c app/tools/gimpselectiontool.c app/tools/gimpsheartool.c app/tools/gimpsmudgetool.c app/tools/gimptexttool.c app/tools/gimptransformtool.c app/tools/gimpvectortool.c: set the motion mode; fix a few parameters * app/tools/gimpinktool.c (gimp_ink_tool_button_press): uncommented some code I had temporarily commented out and didn't uncomment before committing * libgimptool/gimptoolcontrol.h * app/tools/gimptoolcontrol-displayshell.[ch]: merged with gimptoolcontrol.[ch]. The distinction was fairly arbitrary. * plug-ins/tools/gimptoolcontrol.c: added some stubs * app/tools/Makefile.am * app/tools/tool_manager.c * app/display/gimpdisplayshell-callbacks.c: changed accordingly * libgimp/gimpimage_pdb.c: applied a patch from Pippen to correct documentation on the undo operations
2002-04-21 15:31:12 +08:00
/* Personal note: Dr. Barrett, one of the authors of the paper written above
* is not only one of the most brilliant people I have ever met, he is an
* incredible professor who genuinely cares about his students and wants them
* to learn as much as they can about the topic.
*
* I didn't even notice I was taking a class from the person who wrote the
* paper until halfway through the semester.
* -- Rockwalrus
*/
/* The history of this implementation is lonog and varied. It was
2013-01-27 23:52:38 +08:00
* originally done by Spencer and Peter, and worked fine in the 0.54
* (motif only) release of GIMP. Later revisions (0.99.something
* until about 1.1.4) completely changed the algorithm used, until it
* bore little resemblance to the one described in the paper above.
* The 0.54 version of the algorithm was then forwards ported to 1.1.4
app/Makefile.am app/channel_pvt.h app/drawable_pvt.h app/gdisplayF.h 2000-12-29 Michael Natterer <mitch@gimp.org> * app/Makefile.am * app/channel_pvt.h * app/drawable_pvt.h * app/gdisplayF.h * app/gimpdrawableP.h * app/gimpimageP.h * app/layer_pvt.h * app/toolsF.h: removed these files. * app/apptypes.h * tools/pdbgen/enums.pl: added tons of opaque typedefs and enums. * tools/pdbgen/pdb/brush_select.pdb * tools/pdbgen/pdb/brushes.pdb * tools/pdbgen/pdb/channel.pdb * tools/pdbgen/pdb/color.pdb * tools/pdbgen/pdb/convert.pdb * tools/pdbgen/pdb/display.pdb * tools/pdbgen/pdb/drawable.pdb * tools/pdbgen/pdb/fileops.pdb * tools/pdbgen/pdb/gradient_select.pdb * tools/pdbgen/pdb/gradients.pdb * tools/pdbgen/pdb/help.pdb * tools/pdbgen/pdb/image.pdb * tools/pdbgen/pdb/layer.pdb * tools/pdbgen/pdb/pattern_select.pdb * tools/pdbgen/pdb/patterns.pdb * tools/pdbgen/pdb/selection.pdb * tools/pdbgen/pdb/tools.pdb * app/*: chainsaw #include cleanup: - Never (never!!) include stuff in header files except where we need access to structures' contents (like derived objects). - Added prototypes and proper formating in many files. - The #include order in *all* *.c files is as follows: #include "config.h" #include <system stuff> #include <gtk/gtk.h> #include "apptypes.h" #include "gimp stuff" #include "libgimp stuff" #include "libgimp/gimpintl.h" By following this scheme we can easily see a file's dependencies from it's #include's and can grep for the inclusion to find out where a file is used. * tools/pdbgen/app.pl: changed to follow the include scheme above. * libgimp/Makefile.am * libgimp/gimpuitypes.h: new file, included from libgimp/gimpui.h and from app/apptypes.h. * libgimp/gimpcolorbutton.[ch] * libgimp/gimpdialog.[ch] * libgimp/gimphelpui.[ch] * libgimp/gimpparasite.[ch] * libgimp/gimppatheditor.[ch] * libgimp/gimpprotocol.c * libgimp/gimpquerybox.[ch] * libgimp/gimpsizeentry.[ch] * libgimp/gimptypes.h * libgimp/gimpui.h * libgimp/gimpunit.h * libgimp/gimpunitmenu.[ch] * libgimp/gimpwidgets.[ch]: changed accordingly. * plug-ins/FractalExplorer/Dialogs.c * plug-ins/gdyntext/message_window.c * plug-ins/imagemap/imap_default_dialog.c * plug-ins/imagemap/imap_file.c: these files used to include "libgimp/gimpui.h" without including "libgimp/gimp.h". This is no longer possible because the libgimpui headers don't inlcude "libgimp/gimpunit.h" any more.
2000-12-29 23:22:01 +08:00
* by Austin Donnelly.
*/
1997-11-25 06:05:25 +08:00
/* Livewire boundary implementation done by Laramie Leavitt */
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 "config.h"
1997-11-25 06:05:25 +08:00
#include <stdlib.h>
#include <gegl.h>
#include <gtk/gtk.h>
#include <gdk/gdkkeysyms.h>
#include "libgimpmath/gimpmath.h"
2001-08-06 00:08:19 +08:00
#include "libgimpwidgets/gimpwidgets.h"
#include "tools-types.h"
#include "gegl/gimp-gegl-utils.h"
#include "core/gimpchannel.h"
Treat changes to the selection like changes to any other drawable: 2003-10-06 Michael Natterer <mitch@gimp.org> Treat changes to the selection like changes to any other drawable: * app/core/gimpchannel.c * app/core/gimpchannel-combine.c: call gimp_drawable_update() after changing the channel. * app/core/gimpimage.[ch]: added struct GimpImageFlushAccumulator with one member "gboolean mask_changed". Connect to "update" of the selection and set accum.mask_changed to TRUE in the callback. Added default implementation for GimpImage::flush() and emit "mask_changed" there. Unrelated: * app/core/gimpimage.h: removed GimpGuide struct... * app/core/gimpimage-guides.h: ...and added it here. * app/core/gimpimage-undo-push.c (undo_pop_mask) (undo_pop_channel_mod): don't distinguish between selection and non-selection channels and just call gimp_drawable_update(). * app/core/gimpundo.h * app/core/gimpimage-undo.c: removed "gboolean mask_changed" from the GimpUndoAccumulator struct since we don't have to care about that signal explicitly any more. * app/display/gimpdisplay-foreach.[ch]: removed gimp_displays_flush(). * tools/pdbgen/pdb/display.pdb (displays_flush_invoker): call gimp_image_flush() on all images so the flush accumulator is honored. This generalization enables the removal of more special purpose code which was needed to treat the selection different: * app/core/gimpimage-mask-select.[ch]: removed... * app/core/gimpchannel-select.[ch]: ...and added under a new name because it's not selection specific any more. * app/core/gimpimage-mask.[ch]: removed... * app/core/gimpselection.[ch]: ...added the two remaining functions here. Removed all calls to gimp_image_mask_changed(). * app/core/Makefile.am * app/core/gimp-edit.c * app/core/gimpdrawable-transform.c * app/core/gimpimage-scale.c * app/core/gimpimage-snap.c * app/display/gimpdisplayshell.c * app/gui/channels-commands.c * app/gui/layers-commands.c * app/gui/select-commands.c * app/gui/vectors-commands.c * app/tools/gimpbycolorselecttool.c * app/tools/gimpeditselectiontool.c * app/tools/gimpellipseselecttool.c * app/tools/gimpfreeselecttool.c * app/tools/gimpfuzzyselecttool.c * app/tools/gimpiscissorstool.c * app/tools/gimprectselecttool.c * app/tools/gimptransformtool.c * app/widgets/gimpchanneltreeview.c * app/widgets/gimpselectioneditor.c * app/widgets/gimpvectorstreeview.c * app/xcf/xcf-save.c * tools/pdbgen/pdb/paths.pdb * tools/pdbgen/pdb/selection.pdb * tools/pdbgen/pdb/selection_tools.pdb: changed accordingly. * app/core/gimpdrawable-bucket-fill.c * app/core/gimpimage-colormap.c * app/core/gimplayer-floating-sel.c * app/core/gimplayer.c * app/gui/image-menu.c * app/paint/gimppaintcore.c * app/tools/gimpcroptool.c * app/tools/gimpinkoptions.c * app/tools/gimpvectortool.c: removed useless and/or obsolete #includes. * app/pdb/display_cmds.c * app/pdb/paths_cmds.c * app/pdb/selection_cmds.c * app/pdb/selection_tools_cmds.c: regenerated.
2003-10-06 20:17:11 +08:00
#include "core/gimpchannel-select.h"
#include "core/gimpimage.h"
#include "core/gimppickable.h"
#include "core/gimpscanconvert.h"
#include "core/gimptempbuf.h"
#include "core/gimptoolinfo.h"
1997-11-25 06:05:25 +08:00
#include "widgets/gimphelp-ids.h"
#include "widgets/gimpwidgets-utils.h"
#include "display/gimpcanvasitem.h"
#include "display/gimpdisplay.h"
#include "gimpiscissorsoptions.h"
#include "gimpiscissorstool.h"
#include "gimptilehandleriscissors.h"
#include "gimptoolcontrol.h"
Makefile.am configure.in added the new library below. 2001-01-24 Michael Natterer <mitch@gimp.org> * Makefile.am * configure.in * gimptool.in: added the new library below. * libgimpwidgets/Makefile.am * libgimpwidgets/gimpchainbutton.[ch] * libgimpwidgets/gimpcolorarea.[ch] * libgimpwidgets/gimpcolorbutton.[ch] * libgimpwidgets/gimpdialog.[ch] * libgimpwidgets/gimpfileselection.[ch] * libgimpwidgets/gimphelpui.[ch] * libgimpwidgets/gimppatheditor.[ch] * libgimpwidgets/gimppixmap.[ch] * libgimpwidgets/gimpquerybox.[ch] * libgimpwidgets/gimpsizeentry.[ch] * libgimpwidgets/gimpunitmenu.[ch] * libgimpwidgets/gimpwidgets.[ch] * libgimpwidgets/gimpwidgets.def * libgimpwidgets/gimpwidgetstypes.h: new shared library. Currently there are some ugly dependencies into libgimp. These will be removed and go to a "libgimpglue" library which will be a library for functions which share a common interface between plug-ins and the app but have different implementations. Include "libgimp/gimpunit.h" from "libgimpwidgets/gimpwidgetstypes.h" to simulate this upcoming separation. * libgimp/Makefile.am * libgimp/gimpchainbutton.[ch] * libgimp/gimpcolorarea.[ch] * libgimp/gimpcolorbutton.[ch] * libgimp/gimpdialog.[ch] * libgimp/gimpfileselection.[ch] * libgimp/gimphelpui.[ch] * libgimp/gimppatheditor.[ch] * libgimp/gimppixmap.[ch] * libgimp/gimpquerybox.[ch] * libgimp/gimpsizeentry.[ch] * libgimp/gimpunitmenu.[ch] * libgimp/gimpwidgets.[ch]: removed from here. * libgimp/gimpui.h * libgimp/gimpuitypes.h * libgimp/makefile.mingw.in * libgimp/makefile.msc: changed accordingly. * app/[all ui files] * app/pdb/palette_cmds.c * app/pdb/tools_cmds.c * tools/pdbgen/pdb/palette.pdb * tools/pdbgen/pdb/tools.pdb: #include "libgimpwidgets/gimpwidgets.h" and removed useless includes. * app/apptypes.h: #include "libgimpwidgets/gimpwidgetstypes.h" * app/Makefile.am * plug-ins/[all makefiles which link against libgimpui]: link against libgimpwidgets.la * po-libgimp/POTFILES.in: changed file locations.
2001-01-25 06:36:18 +08:00
#include "gimp-intl.h"
app/Makefile.am app/channel_pvt.h app/drawable_pvt.h app/gdisplayF.h 2000-12-29 Michael Natterer <mitch@gimp.org> * app/Makefile.am * app/channel_pvt.h * app/drawable_pvt.h * app/gdisplayF.h * app/gimpdrawableP.h * app/gimpimageP.h * app/layer_pvt.h * app/toolsF.h: removed these files. * app/apptypes.h * tools/pdbgen/enums.pl: added tons of opaque typedefs and enums. * tools/pdbgen/pdb/brush_select.pdb * tools/pdbgen/pdb/brushes.pdb * tools/pdbgen/pdb/channel.pdb * tools/pdbgen/pdb/color.pdb * tools/pdbgen/pdb/convert.pdb * tools/pdbgen/pdb/display.pdb * tools/pdbgen/pdb/drawable.pdb * tools/pdbgen/pdb/fileops.pdb * tools/pdbgen/pdb/gradient_select.pdb * tools/pdbgen/pdb/gradients.pdb * tools/pdbgen/pdb/help.pdb * tools/pdbgen/pdb/image.pdb * tools/pdbgen/pdb/layer.pdb * tools/pdbgen/pdb/pattern_select.pdb * tools/pdbgen/pdb/patterns.pdb * tools/pdbgen/pdb/selection.pdb * tools/pdbgen/pdb/tools.pdb * app/*: chainsaw #include cleanup: - Never (never!!) include stuff in header files except where we need access to structures' contents (like derived objects). - Added prototypes and proper formating in many files. - The #include order in *all* *.c files is as follows: #include "config.h" #include <system stuff> #include <gtk/gtk.h> #include "apptypes.h" #include "gimp stuff" #include "libgimp stuff" #include "libgimp/gimpintl.h" By following this scheme we can easily see a file's dependencies from it's #include's and can grep for the inclusion to find out where a file is used. * tools/pdbgen/app.pl: changed to follow the include scheme above. * libgimp/Makefile.am * libgimp/gimpuitypes.h: new file, included from libgimp/gimpui.h and from app/apptypes.h. * libgimp/gimpcolorbutton.[ch] * libgimp/gimpdialog.[ch] * libgimp/gimphelpui.[ch] * libgimp/gimpparasite.[ch] * libgimp/gimppatheditor.[ch] * libgimp/gimpprotocol.c * libgimp/gimpquerybox.[ch] * libgimp/gimpsizeentry.[ch] * libgimp/gimptypes.h * libgimp/gimpui.h * libgimp/gimpunit.h * libgimp/gimpunitmenu.[ch] * libgimp/gimpwidgets.[ch]: changed accordingly. * plug-ins/FractalExplorer/Dialogs.c * plug-ins/gdyntext/message_window.c * plug-ins/imagemap/imap_default_dialog.c * plug-ins/imagemap/imap_file.c: these files used to include "libgimp/gimpui.h" without including "libgimp/gimp.h". This is no longer possible because the libgimpui headers don't inlcude "libgimp/gimpunit.h" any more.
2000-12-29 23:22:01 +08:00
1997-11-25 06:05:25 +08:00
/* defines */
#define GRADIENT_SEARCH 32 /* how far to look when snapping to an edge */
#define EXTEND_BY 0.2 /* proportion to expand cost map by */
#define FIXED 5 /* additional fixed size to expand cost map */
1997-11-25 06:05:25 +08:00
#define COST_WIDTH 2 /* number of bytes for each pixel in cost map */
/* weight to give between gradient (_G) and direction (_D) */
#define OMEGA_D 0.2
#define OMEGA_G 0.8
1997-11-25 06:05:25 +08:00
/* sentinel to mark seed point in ?cost? map */
#define SEED_POINT 9
1997-11-25 06:05:25 +08:00
/* Functional defines */
#define PIXEL_COST(x) ((x) >> 8)
#define PIXEL_DIR(x) ((x) & 0x000000ff)
1997-11-25 06:05:25 +08:00
struct _ISegment
{
gint x1, y1;
gint x2, y2;
GPtrArray *points;
};
struct _ICurve
{
GQueue *segments;
gboolean first_point;
gboolean closed;
};
/* local function prototypes */
static void gimp_iscissors_tool_finalize (GObject *object);
static void gimp_iscissors_tool_control (GimpTool *tool,
GimpToolAction action,
GimpDisplay *display);
static void gimp_iscissors_tool_button_press (GimpTool *tool,
const GimpCoords *coords,
guint32 time,
GdkModifierType state,
GimpButtonPressType press_type,
GimpDisplay *display);
static void gimp_iscissors_tool_button_release (GimpTool *tool,
const GimpCoords *coords,
guint32 time,
GdkModifierType state,
GimpButtonReleaseType release_type,
GimpDisplay *display);
static void gimp_iscissors_tool_motion (GimpTool *tool,
const GimpCoords *coords,
guint32 time,
GdkModifierType state,
GimpDisplay *display);
static void gimp_iscissors_tool_oper_update (GimpTool *tool,
const GimpCoords *coords,
GdkModifierType state,
gboolean proximity,
GimpDisplay *display);
static void gimp_iscissors_tool_cursor_update (GimpTool *tool,
const GimpCoords *coords,
GdkModifierType state,
GimpDisplay *display);
static gboolean gimp_iscissors_tool_key_press (GimpTool *tool,
GdkEventKey *kevent,
GimpDisplay *display);
static const gchar * gimp_iscissors_tool_can_undo (GimpTool *tool,
GimpDisplay *display);
static const gchar * gimp_iscissors_tool_can_redo (GimpTool *tool,
GimpDisplay *display);
static gboolean gimp_iscissors_tool_undo (GimpTool *tool,
GimpDisplay *display);
static gboolean gimp_iscissors_tool_redo (GimpTool *tool,
GimpDisplay *display);
static void gimp_iscissors_tool_draw (GimpDrawTool *draw_tool);
static void gimp_iscissors_tool_push_undo (GimpIscissorsTool *iscissors);
static void gimp_iscissors_tool_pop_undo (GimpIscissorsTool *iscissors);
static void gimp_iscissors_tool_free_redo (GimpIscissorsTool *iscissors);
static void gimp_iscissors_tool_halt (GimpIscissorsTool *iscissors,
GimpDisplay *display);
static void gimp_iscissors_tool_commit (GimpIscissorsTool *iscissors,
GimpDisplay *display);
static void iscissors_convert (GimpIscissorsTool *iscissors,
GimpDisplay *display);
static GeglBuffer * gradient_map_new (GimpPickable *pickable);
static void find_optimal_path (GeglBuffer *gradient_map,
2012-04-09 02:25:49 +08:00
GimpTempBuf *dp_buf,
gint x1,
gint y1,
gint x2,
gint y2,
gint xs,
gint ys);
static void find_max_gradient (GimpIscissorsTool *iscissors,
GimpPickable *pickable,
gint *x,
gint *y);
static void calculate_segment (GimpIscissorsTool *iscissors,
ISegment *segment);
static GimpCanvasItem * iscissors_draw_segment (GimpDrawTool *draw_tool,
ISegment *segment);
static gint mouse_over_vertex (GimpIscissorsTool *iscissors,
gdouble x,
gdouble y);
static gboolean clicked_on_vertex (GimpIscissorsTool *iscissors,
gdouble x,
gdouble y);
static GList * mouse_over_segment (GimpIscissorsTool *iscissors,
gdouble x,
gdouble y);
static gboolean clicked_on_segment (GimpIscissorsTool *iscissors,
gdouble x,
gdouble y);
static GPtrArray * plot_pixels (GimpTempBuf *dp_buf,
gint x1,
gint y1,
gint xs,
gint ys,
gint xe,
gint ye);
static ISegment * isegment_new (gint x1,
gint y1,
gint x2,
gint y2);
static ISegment * isegment_copy (ISegment *segment);
static void isegment_free (ISegment *segment);
static ICurve * icurve_new (void);
static ICurve * icurve_copy (ICurve *curve);
static void icurve_clear (ICurve *curve);
static void icurve_free (ICurve *curve);
static ISegment * icurve_append_segment (ICurve *curve,
gint x1,
gint y1,
gint x2,
gint y2);
static ISegment * icurve_insert_segment (ICurve *curve,
GList *sibling,
gint x1,
gint y1,
gint x2,
gint y2);
static void icurve_delete_segment (ICurve *curve,
ISegment *segment);
static void icurve_close (ICurve *curve);
static GimpScanConvert *
icurve_create_scan_convert (ICurve *curve);
1997-11-25 06:05:25 +08:00
/* static variables */
/* where to move on a given link direction */
static const gint move[8][2] =
{
build display/ before tools/. 2001-11-08 Michael Natterer <mitch@gimp.org> * app/Makefile.am: build display/ before tools/. * app/devices.c: devices_check_change(): added all events which have a GdkDevice pointer. * app/gimpprogress.c: include "display-types.h" instead of "core-types.h". * app/core/Makefile.am * app/core/gimpdrawable-bucket-fill.[ch]: new files: the bucket_fill stuff taken from tools/gimpbucketfilltool.[ch]. * app/core/core-types.h: added "BucketFillMode". * app/core/gimpimage-mask-select.[ch]: cleanup. * app/core/gimpmarshal.list: added more marshallers for GimpTool's new signal signatures. * app/core/gimpmarshal.[ch]: regenerated. * app/display/Makefile.am * app/display/gimpdisplayshell-dnd.[ch] * app/display/gimpdisplayshell-layer-select.[ch]: new files: the canvas drop callbacks from gimpdisplayshell-callbacks.[ch] and the stuff formerly knows as gui/layer-select.[ch]. * app/display/gimpdisplay.h: don't include "gui/gui-types.h". * app/display/gximage.c: include "display-types.h". * app/display/gimpdisplay-foreach.c * app/display/gimpdisplayshell.[ch]: call gdsplay_delete(), don't destroy the shell widget. * app/gui/Makefile.am * app/gui/layer-select.[ch]: removed. * app/gui/gradients-commands.c: fixed "Save as POV" fprintf()s. * app/gui/preferences-dialog.c: removed the layer_select stuff because it is useless with the new preview system. * app/gui/tool-options-dialog.c: send the correct data to the close_callback. * app/gui/tools-commands.c: changed to follow the new gimp_tool_initialize() semantics (see below). Tool & canvas event handling chainsawing: * app/tools/tools-types.h: new struct GimpCoords which contains x, y, pressure, tilt etc. * app/display/gimpdisplayshell-callbacks.[ch]: added utility functions which transparently retreive the current event's GimpCoords or take it from the device directly if the event has none. Pass GimpCoords _in_image_coordinates_ to all tool functions. Most important: don't pass GdkEvents and display coordinates to tools any more. * app/tools/gimptool.[ch]: changed virtual functions to take GimpCoords, time and state separately instead of GdkEvents. * app/tools/gimpbezierselecttool.c * app/tools/gimpblendtool.c * app/tools/gimpbucketfilltool.[ch] * app/tools/gimpbycolorselecttool.c * app/tools/gimpclonetool.c * app/tools/gimpcolorpickertool.c * app/tools/gimpconvolvetool.c * app/tools/gimpcroptool.[ch] * app/tools/gimpcurvestool.c * app/tools/gimpdodgeburntool.c * app/tools/gimpdrawtool.c * app/tools/gimpeditselectiontool.[ch] * app/tools/gimperasertool.c * app/tools/gimpfliptool.c * app/tools/gimpfreeselecttool.[ch] * app/tools/gimpfuzzyselecttool.c * app/tools/gimpinktool.c * app/tools/gimpiscissorstool.c * app/tools/gimpmagnifytool.c * app/tools/gimpmeasuretool.c * app/tools/gimpmovetool.c * app/tools/gimppainttool.c * app/tools/gimppathtool.[ch] * app/tools/gimprectselecttool.c * app/tools/gimprotatetool.c * app/tools/gimpselectiontool.[ch] * app/tools/gimpsmudgetool.c * app/tools/gimptexttool.c * app/tools/gimptransformtool.[ch] * app/tools/path_tool.[ch] * app/tools/selection_options.c: tons and tons of changes: - changed to use the new virtual function parameters. - removed zillions of gdisplay_untransform_coords(). - get the active drawable's offsets manually in many cases. (questionable, but IMHO ok because it's obvious and not simply a "TRUE" passed to some function) - reordered some functions to be consistent across tools. - some tools had to be changed to work on image coords, not display ones (esp. crop). - fixed strange rotate tool behaviour which should be backported to stable. - some stuff i came across. - indentation and other paranoia. - rounding of coordinated may be broken in some tools. - new bugs guaranteed. * app/tools/tool_manager.[ch]: new semantic of tool_manager_initialize_active() (looked at the places where it was used from and put common code together). Should be a bit better now :) * app/tools/gimpblendtool.c * app/tools/transform_options.c: use the new GTK+ feature that a widget (toggle button) can be a frame's title for this tools' tool options. * app/widgets/widgets-types.h: stuff. * themes/Default/gtkrc: s/GtkDialog/GimpDialog/. * tools/pdbgen/Makefile.am: don't scan tools/gimpbucketfilltool.h any more. * tools/pdbgen/enums.pl: regenerated. * tools/pdbgen/pdb/tools.pdb: changed bucket_fill wrapper. * app/pdb/tools_cmds.c: regenerated.
2001-11-09 03:14:51 +08:00
{ 1, 0 },
{ 0, 1 },
{ -1, 1 },
{ 1, 1 },
{ -1, 0 },
{ 0, -1 },
{ 1, -1 },
{ -1, -1 },
};
/* IE:
* '---+---+---`
* | 7 | 5 | 6 |
* +---+---+---+
* | 4 | | 0 |
* +---+---+---+
* | 2 | 1 | 3 |
* `---+---+---'
*/
1997-11-25 06:05:25 +08:00
static gfloat distance_weights[GRADIENT_SEARCH * GRADIENT_SEARCH];
static gint diagonal_weight[256];
static gint direction_value[256][4];
G_DEFINE_TYPE (GimpIscissorsTool, gimp_iscissors_tool,
GIMP_TYPE_SELECTION_TOOL)
#define parent_class gimp_iscissors_tool_parent_class
void
2002-03-29 11:50:29 +08:00
gimp_iscissors_tool_register (GimpToolRegisterCallback callback,
app/tools/gimpairbrushtool.[ch] app/tools/gimpbezierselecttool.[ch] 2002-05-03 Sven Neumann <sven@gimp.org> * app/tools/gimpairbrushtool.[ch] * app/tools/gimpbezierselecttool.[ch] * app/tools/gimpblendtool.[ch] * app/tools/gimpbrightnesscontrasttool.[ch] * app/tools/gimpbucketfilltool[.ch] * app/tools/gimpbycolorselecttool[.ch] * app/tools/gimpclonetool[.ch] * app/tools/gimpcolorbalancetool[.ch] * app/tools/gimpcolorpickertool[.ch] * app/tools/gimpconvolvetool[.ch] * app/tools/gimpcroptool[.ch] * app/tools/gimpcurvestool[.ch] * app/tools/gimpdodgeburntool[.ch] * app/tools/gimpeditselectiontool.c * app/tools/gimpellipseselecttool[.ch] * app/tools/gimperasertool[.ch] * app/tools/gimpfliptool[.ch] * app/tools/gimpfreeselecttool[.ch] * app/tools/gimpfuzzyselecttool[.ch] * app/tools/gimphistogramtool[.ch] * app/tools/gimphuesaturationtool[.ch] * app/tools/gimpinktool[.ch] * app/tools/gimpiscissorstool[.ch] * app/tools/gimplevelstool[.ch] * app/tools/gimpmagnifytool[.ch] * app/tools/gimpmeasuretool[.ch] * app/tools/gimpmovetool[.ch] * app/tools/gimppaintbrushtool[.ch] * app/tools/gimppainttool.c * app/tools/gimppathtool[.ch] * app/tools/gimppenciltool[.ch] * app/tools/gimpperspectivetool[.ch] * app/tools/gimpposterizetool[.ch] * app/tools/gimprectselecttool[.ch] * app/tools/gimprotatetool[.ch] * app/tools/gimpscaletool[.ch] * app/tools/gimpselectiontool.c * app/tools/gimpsheartool[.ch] * app/tools/gimpsmudgetool[.ch] * app/tools/gimptexttool[.ch] * app/tools/gimpthresholdtool[.ch] * app/tools/gimptool.c * app/tools/gimptoolcontrol.h * app/tools/gimptoolmodule[.ch] * app/tools/gimptransformtool.c * app/tools/gimpvectortool[.ch] * app/tools/path_tool.c * app/tools/tool_manager[.ch] * app/tools/tools.c * libgimptool/gimptool.c * libgimptool/gimptoolcontrol.h * libgimptool/gimptoolmodule.h: removed tons of warnings. Do we need to add -Werror to the CFLAGS to avoid such a mess in the future ?! Also had to enforce the GIMP coding style in lots of places :-( * libgimp/gimppixelrgn.c: got sick and tired of debugging plug-ins, so I've added checks for most parameters passed to the GimpPixelRgn functions. This will slow down plug-in execution a little bit but should help to find bugs early.
2002-05-03 19:31:08 +08:00
gpointer data)
{
2002-03-29 11:50:29 +08:00
(* callback) (GIMP_TYPE_ISCISSORS_TOOL,
GIMP_TYPE_ISCISSORS_OPTIONS,
gimp_iscissors_options_gui,
0,
./mitch --sanitize-identifier-namespace 2002-03-20 Michael Natterer <mitch@gimp.org> ./mitch --sanitize-identifier-namespace * app/core/gimpcontext.c * app/display/gimpdisplayshell-callbacks.c * app/display/gimpdisplayshell-dnd.c * app/gui/dialogs-commands.c * app/gui/dialogs-constructors.c * app/gui/dialogs.c * app/gui/edit-commands.c * app/gui/gui.c * app/gui/menus.c * app/gui/vectors-commands.c * app/gui/view-commands.c * app/tools/gimpairbrushtool.c * app/tools/gimpbezierselecttool.c * app/tools/gimpblendtool.c * app/tools/gimpbrightnesscontrasttool.c * app/tools/gimpbucketfilltool.c * app/tools/gimpbycolorselecttool.c * app/tools/gimpclonetool.c * app/tools/gimpcolorbalancetool.c * app/tools/gimpcolorpickertool.c * app/tools/gimpconvolvetool.c * app/tools/gimpcroptool.c * app/tools/gimpcurvestool.c * app/tools/gimpdodgeburntool.c * app/tools/gimpellipseselecttool.c * app/tools/gimperasertool.c * app/tools/gimpfliptool.c * app/tools/gimpfreeselecttool.c * app/tools/gimpfuzzyselecttool.c * app/tools/gimphistogramtool.c * app/tools/gimphuesaturationtool.c * app/tools/gimpinktool.c * app/tools/gimpiscissorstool.c * app/tools/gimplevelstool.c * app/tools/gimpmagnifytool.c * app/tools/gimpmeasuretool.c * app/tools/gimpmovetool.c * app/tools/gimppaintbrushtool.c * app/tools/gimppathtool.c * app/tools/gimppenciltool.c * app/tools/gimpperspectivetool.c * app/tools/gimpposterizetool.c * app/tools/gimprectselecttool.c * app/tools/gimprotatetool.c * app/tools/gimpscaletool.c * app/tools/gimpsheartool.c * app/tools/gimpsmudgetool.c * app/tools/gimptexttool.c * app/tools/gimpthresholdtool.c * app/tools/gimpvectortool.c * app/widgets/gimpdnd.c * app/widgets/gimptoolbox-indicator-area.c * app/widgets/gimptoolbox.c: s/gimp:/gimp-/g and s/_/-/g for all identifier strings (e.g. gimp:eraser_tool -> gimp-eraser-tool, gimp:layer-list -> gimp-layer-list, ...) * plug-ins/tools/common/gimpbrushselecttool.c: s/gimp:brush_select_tool/gimp-brush-select-tool-module/ Don't quite remember why I introduced the "gimp:" prefix in the first place, but we can always add it back if we need it (for whatever reason) You may want to edit your ~/.gimp-1.3/sessionrc and devicerc or all session settings will be lost due to parse errors.
2002-03-21 20:17:17 +08:00
"gimp-iscissors-tool",
_("Scissors"),
2006-09-19 02:00:22 +08:00
_("Scissors Select Tool: Select shapes using intelligent edge-fitting"),
Action code review and pre-release consistency cleanup: 2004-10-18 Michael Natterer <mitch@gimp.org> Action code review and pre-release consistency cleanup: * app/actions/*-actions.c: added some missing and resolved conflicting mnemonics, added missing help IDs. Cleaned up the *_actions_update() functions. * app/actions/channels-actions.c * app/actions/layers-actions.c * app/actions/vectors-actions.c (*_actions_update): simplified the code that figures the prev and next channel,layer,vectors. * app/actions/qmask-actions.c: use the same accelerator for "qmask-active" and "qmask-toggle". Fixed action sensitivity. * app/actions/channels-commands.c * app/actions/dockable-commands.c * app/actions/documents-commands.c * app/actions/gradients-commands.c * app/actions/layers-commands.c * app/actions/palettes-commands.c * app/actions/image-commands.c * app/actions/select-commands.c * app/actions/vectors-commands.c: folded tons of private utility functions into their only callers (they used to be public and called from outside before the switch to action based menus). Renamed functions and variables saying "query" or "qbox" to "dialog". Moved static functions to the end of the files. Misc minor cleanups. * app/actions/drawable-actions.c * app/actions/drawable-commands.c: made the "drawable-visible" and "drawable-linked" actions affect the layer if the active drawable is a layer mask. * app/actions/select-commands.c: added action to stroke with the last values used in an attempt to address bug #135746 but #if 0'ed it because the approach is too ugly. * app/tools/gimpiscissorstool.c: changed mnemonic from I to S. * menus/image-menu-xml.in: added more stuff to the (commented out) "context" menu.
2004-10-18 19:29:58 +08:00
N_("Intelligent _Scissors"),
"I",
NULL, GIMP_HELP_TOOL_ISCISSORS,
GIMP_ICON_TOOL_ISCISSORS,
app/tools/gimpairbrushtool.[ch] app/tools/gimpbezierselecttool.[ch] 2002-05-03 Sven Neumann <sven@gimp.org> * app/tools/gimpairbrushtool.[ch] * app/tools/gimpbezierselecttool.[ch] * app/tools/gimpblendtool.[ch] * app/tools/gimpbrightnesscontrasttool.[ch] * app/tools/gimpbucketfilltool[.ch] * app/tools/gimpbycolorselecttool[.ch] * app/tools/gimpclonetool[.ch] * app/tools/gimpcolorbalancetool[.ch] * app/tools/gimpcolorpickertool[.ch] * app/tools/gimpconvolvetool[.ch] * app/tools/gimpcroptool[.ch] * app/tools/gimpcurvestool[.ch] * app/tools/gimpdodgeburntool[.ch] * app/tools/gimpeditselectiontool.c * app/tools/gimpellipseselecttool[.ch] * app/tools/gimperasertool[.ch] * app/tools/gimpfliptool[.ch] * app/tools/gimpfreeselecttool[.ch] * app/tools/gimpfuzzyselecttool[.ch] * app/tools/gimphistogramtool[.ch] * app/tools/gimphuesaturationtool[.ch] * app/tools/gimpinktool[.ch] * app/tools/gimpiscissorstool[.ch] * app/tools/gimplevelstool[.ch] * app/tools/gimpmagnifytool[.ch] * app/tools/gimpmeasuretool[.ch] * app/tools/gimpmovetool[.ch] * app/tools/gimppaintbrushtool[.ch] * app/tools/gimppainttool.c * app/tools/gimppathtool[.ch] * app/tools/gimppenciltool[.ch] * app/tools/gimpperspectivetool[.ch] * app/tools/gimpposterizetool[.ch] * app/tools/gimprectselecttool[.ch] * app/tools/gimprotatetool[.ch] * app/tools/gimpscaletool[.ch] * app/tools/gimpselectiontool.c * app/tools/gimpsheartool[.ch] * app/tools/gimpsmudgetool[.ch] * app/tools/gimptexttool[.ch] * app/tools/gimpthresholdtool[.ch] * app/tools/gimptool.c * app/tools/gimptoolcontrol.h * app/tools/gimptoolmodule[.ch] * app/tools/gimptransformtool.c * app/tools/gimpvectortool[.ch] * app/tools/path_tool.c * app/tools/tool_manager[.ch] * app/tools/tools.c * libgimptool/gimptool.c * libgimptool/gimptoolcontrol.h * libgimptool/gimptoolmodule.h: removed tons of warnings. Do we need to add -Werror to the CFLAGS to avoid such a mess in the future ?! Also had to enforce the GIMP coding style in lots of places :-( * libgimp/gimppixelrgn.c: got sick and tired of debugging plug-ins, so I've added checks for most parameters passed to the GimpPixelRgn functions. This will slow down plug-in execution a little bit but should help to find bugs early.
2002-05-03 19:31:08 +08:00
data);
}
static void
gimp_iscissors_tool_class_init (GimpIscissorsToolClass *klass)
{
GObjectClass *object_class = G_OBJECT_CLASS (klass);
GimpToolClass *tool_class = GIMP_TOOL_CLASS (klass);
GimpDrawToolClass *draw_tool_class = GIMP_DRAW_TOOL_CLASS (klass);
gint i, j;
gint radius;
an evil temp_hack which lets GimpContext managing the active display 2001-08-14 Michael Natterer <mitch@gimp.org> * app/gdisplay.h: an evil temp_hack which lets GimpContext managing the active display withoug including "gdisplay.h". Will go away as soon ad context properties are registered dynamically. * app/module_db.c: cleaned up the object code in preparation of moving it to core/. * app/path.c: connect to GimpImage's * app/core/gimpobject.[ch]: derive it from GObject, not from GtkObject any more (yeah :-) * app/core/*.c: #include <glib-object.h> instead of <gtk/gtk.h>, removed some remaining GtkObject-isms. (left in a few #include <gtk/gtk.h> where bigger changes are needed to get rid of the UI dependency). * app/core/core-types.h: #include <gdk-pixbuf/gdk-pixbuf.h> here temporarily. * app/core/gimp.c (gimp_create_display): unref the image after creating it's first display. * app/core/gimpbrush.[ch]: disabled the parts of the code which depend on GimpPaintTool. * app/core/gimpbrushgenerated.c * app/core/gimpbrushpipe.c: changed accordingly. * app/core/gimpcontext.[ch]: evil hack (see above) to manage the active display without including "gdisplay.h" * app/core/gimpimage-mask.[ch]: pass a context to gimage_mask_stroke() and get the current tool's PDB string from there. * app/core/gimpedit.c: changed accordingly. * app/core/gimpimage.c: use gimp_image_update() instead of gdisplays_update_full(). * app/gui/color-area.c * app/gui/colormap-dialog.c * app/gui/dialogs-constructors.c * app/gui/edit-commands.c * app/gui/image-commands.c * app/gui/toolbox.c: changed accordingly (don't use Gtk methods on GObjects). * app/gui/menus.c: fix some const warnings by explicit casting. * app/tools/*.[ch]: ported all tools to GObject, some minor cleanup while i was on it. * app/widgets/gimpdialogfactory.[ch]: ported to GObject. * app/widgets/gimplayerlistview.h: added FOO_GET_CLASS() macro. * tools/pdbgen/app.pl: added a "widgets_eek" hack like "tools_eek" which inserts #include "widgets/widgets-types.h" before ordinary includes. * tools/pdbgen/pdb/brush_select.pdb * tools/pdbgen/pdb/edit.pdb * app/pdb/brush_select_cmds.c * app/pdb/edit_cmds.c: changed according to the stuff above.
2001-08-14 22:53:55 +08:00
object_class->finalize = gimp_iscissors_tool_finalize;
tool_class->control = gimp_iscissors_tool_control;
tool_class->button_press = gimp_iscissors_tool_button_press;
tool_class->button_release = gimp_iscissors_tool_button_release;
tool_class->motion = gimp_iscissors_tool_motion;
tool_class->key_press = gimp_iscissors_tool_key_press;
tool_class->oper_update = gimp_iscissors_tool_oper_update;
build display/ before tools/. 2001-11-08 Michael Natterer <mitch@gimp.org> * app/Makefile.am: build display/ before tools/. * app/devices.c: devices_check_change(): added all events which have a GdkDevice pointer. * app/gimpprogress.c: include "display-types.h" instead of "core-types.h". * app/core/Makefile.am * app/core/gimpdrawable-bucket-fill.[ch]: new files: the bucket_fill stuff taken from tools/gimpbucketfilltool.[ch]. * app/core/core-types.h: added "BucketFillMode". * app/core/gimpimage-mask-select.[ch]: cleanup. * app/core/gimpmarshal.list: added more marshallers for GimpTool's new signal signatures. * app/core/gimpmarshal.[ch]: regenerated. * app/display/Makefile.am * app/display/gimpdisplayshell-dnd.[ch] * app/display/gimpdisplayshell-layer-select.[ch]: new files: the canvas drop callbacks from gimpdisplayshell-callbacks.[ch] and the stuff formerly knows as gui/layer-select.[ch]. * app/display/gimpdisplay.h: don't include "gui/gui-types.h". * app/display/gximage.c: include "display-types.h". * app/display/gimpdisplay-foreach.c * app/display/gimpdisplayshell.[ch]: call gdsplay_delete(), don't destroy the shell widget. * app/gui/Makefile.am * app/gui/layer-select.[ch]: removed. * app/gui/gradients-commands.c: fixed "Save as POV" fprintf()s. * app/gui/preferences-dialog.c: removed the layer_select stuff because it is useless with the new preview system. * app/gui/tool-options-dialog.c: send the correct data to the close_callback. * app/gui/tools-commands.c: changed to follow the new gimp_tool_initialize() semantics (see below). Tool & canvas event handling chainsawing: * app/tools/tools-types.h: new struct GimpCoords which contains x, y, pressure, tilt etc. * app/display/gimpdisplayshell-callbacks.[ch]: added utility functions which transparently retreive the current event's GimpCoords or take it from the device directly if the event has none. Pass GimpCoords _in_image_coordinates_ to all tool functions. Most important: don't pass GdkEvents and display coordinates to tools any more. * app/tools/gimptool.[ch]: changed virtual functions to take GimpCoords, time and state separately instead of GdkEvents. * app/tools/gimpbezierselecttool.c * app/tools/gimpblendtool.c * app/tools/gimpbucketfilltool.[ch] * app/tools/gimpbycolorselecttool.c * app/tools/gimpclonetool.c * app/tools/gimpcolorpickertool.c * app/tools/gimpconvolvetool.c * app/tools/gimpcroptool.[ch] * app/tools/gimpcurvestool.c * app/tools/gimpdodgeburntool.c * app/tools/gimpdrawtool.c * app/tools/gimpeditselectiontool.[ch] * app/tools/gimperasertool.c * app/tools/gimpfliptool.c * app/tools/gimpfreeselecttool.[ch] * app/tools/gimpfuzzyselecttool.c * app/tools/gimpinktool.c * app/tools/gimpiscissorstool.c * app/tools/gimpmagnifytool.c * app/tools/gimpmeasuretool.c * app/tools/gimpmovetool.c * app/tools/gimppainttool.c * app/tools/gimppathtool.[ch] * app/tools/gimprectselecttool.c * app/tools/gimprotatetool.c * app/tools/gimpselectiontool.[ch] * app/tools/gimpsmudgetool.c * app/tools/gimptexttool.c * app/tools/gimptransformtool.[ch] * app/tools/path_tool.[ch] * app/tools/selection_options.c: tons and tons of changes: - changed to use the new virtual function parameters. - removed zillions of gdisplay_untransform_coords(). - get the active drawable's offsets manually in many cases. (questionable, but IMHO ok because it's obvious and not simply a "TRUE" passed to some function) - reordered some functions to be consistent across tools. - some tools had to be changed to work on image coords, not display ones (esp. crop). - fixed strange rotate tool behaviour which should be backported to stable. - some stuff i came across. - indentation and other paranoia. - rounding of coordinated may be broken in some tools. - new bugs guaranteed. * app/tools/tool_manager.[ch]: new semantic of tool_manager_initialize_active() (looked at the places where it was used from and put common code together). Should be a bit better now :) * app/tools/gimpblendtool.c * app/tools/transform_options.c: use the new GTK+ feature that a widget (toggle button) can be a frame's title for this tools' tool options. * app/widgets/widgets-types.h: stuff. * themes/Default/gtkrc: s/GtkDialog/GimpDialog/. * tools/pdbgen/Makefile.am: don't scan tools/gimpbucketfilltool.h any more. * tools/pdbgen/enums.pl: regenerated. * tools/pdbgen/pdb/tools.pdb: changed bucket_fill wrapper. * app/pdb/tools_cmds.c: regenerated.
2001-11-09 03:14:51 +08:00
tool_class->cursor_update = gimp_iscissors_tool_cursor_update;
tool_class->can_undo = gimp_iscissors_tool_can_undo;
tool_class->can_redo = gimp_iscissors_tool_can_redo;
tool_class->undo = gimp_iscissors_tool_undo;
tool_class->redo = gimp_iscissors_tool_redo;
draw_tool_class->draw = gimp_iscissors_tool_draw;
for (i = 0; i < 256; i++)
{
/* The diagonal weight array */
diagonal_weight[i] = (int) (i * G_SQRT2);
/* The direction value array */
direction_value[i][0] = (127 - abs (127 - i)) * 2;
direction_value[i][1] = abs (127 - i) * 2;
direction_value[i][2] = abs (191 - i) * 2;
direction_value[i][3] = abs (63 - i) * 2;
}
/* set the 256th index of the direction_values to the hightest cost */
direction_value[255][0] = 255;
direction_value[255][1] = 255;
direction_value[255][2] = 255;
direction_value[255][3] = 255;
/* compute the distance weights */
radius = GRADIENT_SEARCH >> 1;
for (i = 0; i < GRADIENT_SEARCH; i++)
for (j = 0; j < GRADIENT_SEARCH; j++)
distance_weights[i * GRADIENT_SEARCH + j] =
1.0 / (1 + sqrt (SQR (i - radius) + SQR (j - radius)));
}
static void
gimp_iscissors_tool_init (GimpIscissorsTool *iscissors)
{
GimpTool *tool = GIMP_TOOL (iscissors);
app/core/core-types.h moved GimpToolInfo back into the core. * app/core/core-types.h * libgimptool/gimptooltypes.h: moved GimpToolInfo back into the core. * libgimptool/gimptoolcontrol.h * app/tools/gimptoolcontrol.c: got rid of gimp_tool_control_new * libgimptool/gimptool.c (gimp_tool_init): create the GimpToolControl here instead of in the descendant classes * app/tools/gimpairbrushtool.c * app/tools/gimpbezierselecttool.c * app/tools/gimpblendtool.c * app/tools/gimpbucketfilltool.c * app/tools/gimpbycolorselecttool.c * app/tools/gimpclonetool.c * app/tools/gimpcolorbalancetool.c * app/tools/gimpcolorpickertool.c * app/tools/gimpconvolvetool.c * app/tools/gimpcroptool.c * app/tools/gimpcurvestool.c * app/tools/gimpdodgeburntool.c * app/tools/gimpeditselectiontool.c * app/tools/gimpellipseselecttool.c * app/tools/gimperasertool.c * app/tools/gimpfliptool.c * app/tools/gimpfreeselecttool.c * app/tools/gimpfuzzyselecttool.c * app/tools/gimphistogramtool.c * app/tools/gimphuesaturationtool.c * app/tools/gimpinktool.c * app/tools/gimpiscissorstool.c * app/tools/gimplevelstool.c * app/tools/gimpmagnifytool.c * app/tools/gimpmeasuretool.c * app/tools/gimpmovetool.c * app/tools/gimppaintbrushtool.c * app/tools/gimppathtool.c * app/tools/gimppenciltool.c * app/tools/gimpperspectivetool.c * app/tools/gimprectselecttool.c * app/tools/gimprotatetool.c * app/tools/gimpscaletool.c * app/tools/gimpsheartool.c * app/tools/gimpsmudgetool.c * app/tools/gimptexttool.c * app/tools/gimpvectortool.c * plug-ins/tools/tool-safe-mode.c: changed accordingly * libgimpproxy/gimpproxytypes.h: autogenerated
2002-05-03 05:03:27 +08:00
gimp_tool_control_set_scroll_lock (tool->control, TRUE);
gimp_tool_control_set_snap_to (tool->control, FALSE);
gimp_tool_control_set_preserve (tool->control, FALSE);
gimp_tool_control_set_dirty_mask (tool->control,
GIMP_DIRTY_IMAGE_SIZE |
GIMP_DIRTY_ACTIVE_DRAWABLE);
gimp_tool_control_set_tool_cursor (tool->control,
GIMP_TOOL_CURSOR_ISCISSORS);
build display/ before tools/. 2001-11-08 Michael Natterer <mitch@gimp.org> * app/Makefile.am: build display/ before tools/. * app/devices.c: devices_check_change(): added all events which have a GdkDevice pointer. * app/gimpprogress.c: include "display-types.h" instead of "core-types.h". * app/core/Makefile.am * app/core/gimpdrawable-bucket-fill.[ch]: new files: the bucket_fill stuff taken from tools/gimpbucketfilltool.[ch]. * app/core/core-types.h: added "BucketFillMode". * app/core/gimpimage-mask-select.[ch]: cleanup. * app/core/gimpmarshal.list: added more marshallers for GimpTool's new signal signatures. * app/core/gimpmarshal.[ch]: regenerated. * app/display/Makefile.am * app/display/gimpdisplayshell-dnd.[ch] * app/display/gimpdisplayshell-layer-select.[ch]: new files: the canvas drop callbacks from gimpdisplayshell-callbacks.[ch] and the stuff formerly knows as gui/layer-select.[ch]. * app/display/gimpdisplay.h: don't include "gui/gui-types.h". * app/display/gximage.c: include "display-types.h". * app/display/gimpdisplay-foreach.c * app/display/gimpdisplayshell.[ch]: call gdsplay_delete(), don't destroy the shell widget. * app/gui/Makefile.am * app/gui/layer-select.[ch]: removed. * app/gui/gradients-commands.c: fixed "Save as POV" fprintf()s. * app/gui/preferences-dialog.c: removed the layer_select stuff because it is useless with the new preview system. * app/gui/tool-options-dialog.c: send the correct data to the close_callback. * app/gui/tools-commands.c: changed to follow the new gimp_tool_initialize() semantics (see below). Tool & canvas event handling chainsawing: * app/tools/tools-types.h: new struct GimpCoords which contains x, y, pressure, tilt etc. * app/display/gimpdisplayshell-callbacks.[ch]: added utility functions which transparently retreive the current event's GimpCoords or take it from the device directly if the event has none. Pass GimpCoords _in_image_coordinates_ to all tool functions. Most important: don't pass GdkEvents and display coordinates to tools any more. * app/tools/gimptool.[ch]: changed virtual functions to take GimpCoords, time and state separately instead of GdkEvents. * app/tools/gimpbezierselecttool.c * app/tools/gimpblendtool.c * app/tools/gimpbucketfilltool.[ch] * app/tools/gimpbycolorselecttool.c * app/tools/gimpclonetool.c * app/tools/gimpcolorpickertool.c * app/tools/gimpconvolvetool.c * app/tools/gimpcroptool.[ch] * app/tools/gimpcurvestool.c * app/tools/gimpdodgeburntool.c * app/tools/gimpdrawtool.c * app/tools/gimpeditselectiontool.[ch] * app/tools/gimperasertool.c * app/tools/gimpfliptool.c * app/tools/gimpfreeselecttool.[ch] * app/tools/gimpfuzzyselecttool.c * app/tools/gimpinktool.c * app/tools/gimpiscissorstool.c * app/tools/gimpmagnifytool.c * app/tools/gimpmeasuretool.c * app/tools/gimpmovetool.c * app/tools/gimppainttool.c * app/tools/gimppathtool.[ch] * app/tools/gimprectselecttool.c * app/tools/gimprotatetool.c * app/tools/gimpselectiontool.[ch] * app/tools/gimpsmudgetool.c * app/tools/gimptexttool.c * app/tools/gimptransformtool.[ch] * app/tools/path_tool.[ch] * app/tools/selection_options.c: tons and tons of changes: - changed to use the new virtual function parameters. - removed zillions of gdisplay_untransform_coords(). - get the active drawable's offsets manually in many cases. (questionable, but IMHO ok because it's obvious and not simply a "TRUE" passed to some function) - reordered some functions to be consistent across tools. - some tools had to be changed to work on image coords, not display ones (esp. crop). - fixed strange rotate tool behaviour which should be backported to stable. - some stuff i came across. - indentation and other paranoia. - rounding of coordinated may be broken in some tools. - new bugs guaranteed. * app/tools/tool_manager.[ch]: new semantic of tool_manager_initialize_active() (looked at the places where it was used from and put common code together). Should be a bit better now :) * app/tools/gimpblendtool.c * app/tools/transform_options.c: use the new GTK+ feature that a widget (toggle button) can be a frame's title for this tools' tool options. * app/widgets/widgets-types.h: stuff. * themes/Default/gtkrc: s/GtkDialog/GimpDialog/. * tools/pdbgen/Makefile.am: don't scan tools/gimpbucketfilltool.h any more. * tools/pdbgen/enums.pl: regenerated. * tools/pdbgen/pdb/tools.pdb: changed bucket_fill wrapper. * app/pdb/tools_cmds.c: regenerated.
2001-11-09 03:14:51 +08:00
iscissors->op = ISCISSORS_OP_NONE;
iscissors->curve = icurve_new ();
iscissors->state = NO_ACTION;
}
static void
an evil temp_hack which lets GimpContext managing the active display 2001-08-14 Michael Natterer <mitch@gimp.org> * app/gdisplay.h: an evil temp_hack which lets GimpContext managing the active display withoug including "gdisplay.h". Will go away as soon ad context properties are registered dynamically. * app/module_db.c: cleaned up the object code in preparation of moving it to core/. * app/path.c: connect to GimpImage's * app/core/gimpobject.[ch]: derive it from GObject, not from GtkObject any more (yeah :-) * app/core/*.c: #include <glib-object.h> instead of <gtk/gtk.h>, removed some remaining GtkObject-isms. (left in a few #include <gtk/gtk.h> where bigger changes are needed to get rid of the UI dependency). * app/core/core-types.h: #include <gdk-pixbuf/gdk-pixbuf.h> here temporarily. * app/core/gimp.c (gimp_create_display): unref the image after creating it's first display. * app/core/gimpbrush.[ch]: disabled the parts of the code which depend on GimpPaintTool. * app/core/gimpbrushgenerated.c * app/core/gimpbrushpipe.c: changed accordingly. * app/core/gimpcontext.[ch]: evil hack (see above) to manage the active display without including "gdisplay.h" * app/core/gimpimage-mask.[ch]: pass a context to gimage_mask_stroke() and get the current tool's PDB string from there. * app/core/gimpedit.c: changed accordingly. * app/core/gimpimage.c: use gimp_image_update() instead of gdisplays_update_full(). * app/gui/color-area.c * app/gui/colormap-dialog.c * app/gui/dialogs-constructors.c * app/gui/edit-commands.c * app/gui/image-commands.c * app/gui/toolbox.c: changed accordingly (don't use Gtk methods on GObjects). * app/gui/menus.c: fix some const warnings by explicit casting. * app/tools/*.[ch]: ported all tools to GObject, some minor cleanup while i was on it. * app/widgets/gimpdialogfactory.[ch]: ported to GObject. * app/widgets/gimplayerlistview.h: added FOO_GET_CLASS() macro. * tools/pdbgen/app.pl: added a "widgets_eek" hack like "tools_eek" which inserts #include "widgets/widgets-types.h" before ordinary includes. * tools/pdbgen/pdb/brush_select.pdb * tools/pdbgen/pdb/edit.pdb * app/pdb/brush_select_cmds.c * app/pdb/edit_cmds.c: changed according to the stuff above.
2001-08-14 22:53:55 +08:00
gimp_iscissors_tool_finalize (GObject *object)
{
GimpIscissorsTool *iscissors = GIMP_ISCISSORS_TOOL (object);
icurve_free (iscissors->curve);
iscissors->curve = NULL;
an evil temp_hack which lets GimpContext managing the active display 2001-08-14 Michael Natterer <mitch@gimp.org> * app/gdisplay.h: an evil temp_hack which lets GimpContext managing the active display withoug including "gdisplay.h". Will go away as soon ad context properties are registered dynamically. * app/module_db.c: cleaned up the object code in preparation of moving it to core/. * app/path.c: connect to GimpImage's * app/core/gimpobject.[ch]: derive it from GObject, not from GtkObject any more (yeah :-) * app/core/*.c: #include <glib-object.h> instead of <gtk/gtk.h>, removed some remaining GtkObject-isms. (left in a few #include <gtk/gtk.h> where bigger changes are needed to get rid of the UI dependency). * app/core/core-types.h: #include <gdk-pixbuf/gdk-pixbuf.h> here temporarily. * app/core/gimp.c (gimp_create_display): unref the image after creating it's first display. * app/core/gimpbrush.[ch]: disabled the parts of the code which depend on GimpPaintTool. * app/core/gimpbrushgenerated.c * app/core/gimpbrushpipe.c: changed accordingly. * app/core/gimpcontext.[ch]: evil hack (see above) to manage the active display without including "gdisplay.h" * app/core/gimpimage-mask.[ch]: pass a context to gimage_mask_stroke() and get the current tool's PDB string from there. * app/core/gimpedit.c: changed accordingly. * app/core/gimpimage.c: use gimp_image_update() instead of gdisplays_update_full(). * app/gui/color-area.c * app/gui/colormap-dialog.c * app/gui/dialogs-constructors.c * app/gui/edit-commands.c * app/gui/image-commands.c * app/gui/toolbox.c: changed accordingly (don't use Gtk methods on GObjects). * app/gui/menus.c: fix some const warnings by explicit casting. * app/tools/*.[ch]: ported all tools to GObject, some minor cleanup while i was on it. * app/widgets/gimpdialogfactory.[ch]: ported to GObject. * app/widgets/gimplayerlistview.h: added FOO_GET_CLASS() macro. * tools/pdbgen/app.pl: added a "widgets_eek" hack like "tools_eek" which inserts #include "widgets/widgets-types.h" before ordinary includes. * tools/pdbgen/pdb/brush_select.pdb * tools/pdbgen/pdb/edit.pdb * app/pdb/brush_select_cmds.c * app/pdb/edit_cmds.c: changed according to the stuff above.
2001-08-14 22:53:55 +08:00
G_OBJECT_CLASS (parent_class)->finalize (object);
}
static void
gimp_iscissors_tool_control (GimpTool *tool,
GimpToolAction action,
GimpDisplay *display)
1997-11-25 06:05:25 +08:00
{
GimpIscissorsTool *iscissors = GIMP_ISCISSORS_TOOL (tool);
1997-11-25 06:05:25 +08:00
switch (action)
{
case GIMP_TOOL_ACTION_PAUSE:
case GIMP_TOOL_ACTION_RESUME:
break;
1997-11-25 06:05:25 +08:00
case GIMP_TOOL_ACTION_HALT:
gimp_iscissors_tool_halt (iscissors, display);
break;
case GIMP_TOOL_ACTION_COMMIT:
gimp_iscissors_tool_commit (iscissors, display);
break;
}
GIMP_TOOL_CLASS (parent_class)->control (tool, action, display);
1997-11-25 06:05:25 +08:00
}
static void
gimp_iscissors_tool_button_press (GimpTool *tool,
const GimpCoords *coords,
guint32 time,
GdkModifierType state,
GimpButtonPressType press_type,
GimpDisplay *display)
1997-11-25 06:05:25 +08:00
{
GimpIscissorsTool *iscissors = GIMP_ISCISSORS_TOOL (tool);
GimpIscissorsOptions *options = GIMP_ISCISSORS_TOOL_GET_OPTIONS (tool);
GimpImage *image = gimp_display_get_image (display);
ISegment *segment;
iscissors->x = RINT (coords->x);
iscissors->y = RINT (coords->y);
1997-11-25 06:05:25 +08:00
/* If the tool was being used in another image...reset it */
if (display != tool->display)
gimp_tool_control (tool, GIMP_TOOL_ACTION_HALT, display);
1997-11-25 06:05:25 +08:00
gimp_tool_control_activate (tool->control);
tool->display = display;
gimp_draw_tool_pause (GIMP_DRAW_TOOL (tool));
1997-11-25 06:05:25 +08:00
switch (iscissors->state)
{
case NO_ACTION:
iscissors->state = SEED_PLACEMENT;
build display/ before tools/. 2001-11-08 Michael Natterer <mitch@gimp.org> * app/Makefile.am: build display/ before tools/. * app/devices.c: devices_check_change(): added all events which have a GdkDevice pointer. * app/gimpprogress.c: include "display-types.h" instead of "core-types.h". * app/core/Makefile.am * app/core/gimpdrawable-bucket-fill.[ch]: new files: the bucket_fill stuff taken from tools/gimpbucketfilltool.[ch]. * app/core/core-types.h: added "BucketFillMode". * app/core/gimpimage-mask-select.[ch]: cleanup. * app/core/gimpmarshal.list: added more marshallers for GimpTool's new signal signatures. * app/core/gimpmarshal.[ch]: regenerated. * app/display/Makefile.am * app/display/gimpdisplayshell-dnd.[ch] * app/display/gimpdisplayshell-layer-select.[ch]: new files: the canvas drop callbacks from gimpdisplayshell-callbacks.[ch] and the stuff formerly knows as gui/layer-select.[ch]. * app/display/gimpdisplay.h: don't include "gui/gui-types.h". * app/display/gximage.c: include "display-types.h". * app/display/gimpdisplay-foreach.c * app/display/gimpdisplayshell.[ch]: call gdsplay_delete(), don't destroy the shell widget. * app/gui/Makefile.am * app/gui/layer-select.[ch]: removed. * app/gui/gradients-commands.c: fixed "Save as POV" fprintf()s. * app/gui/preferences-dialog.c: removed the layer_select stuff because it is useless with the new preview system. * app/gui/tool-options-dialog.c: send the correct data to the close_callback. * app/gui/tools-commands.c: changed to follow the new gimp_tool_initialize() semantics (see below). Tool & canvas event handling chainsawing: * app/tools/tools-types.h: new struct GimpCoords which contains x, y, pressure, tilt etc. * app/display/gimpdisplayshell-callbacks.[ch]: added utility functions which transparently retreive the current event's GimpCoords or take it from the device directly if the event has none. Pass GimpCoords _in_image_coordinates_ to all tool functions. Most important: don't pass GdkEvents and display coordinates to tools any more. * app/tools/gimptool.[ch]: changed virtual functions to take GimpCoords, time and state separately instead of GdkEvents. * app/tools/gimpbezierselecttool.c * app/tools/gimpblendtool.c * app/tools/gimpbucketfilltool.[ch] * app/tools/gimpbycolorselecttool.c * app/tools/gimpclonetool.c * app/tools/gimpcolorpickertool.c * app/tools/gimpconvolvetool.c * app/tools/gimpcroptool.[ch] * app/tools/gimpcurvestool.c * app/tools/gimpdodgeburntool.c * app/tools/gimpdrawtool.c * app/tools/gimpeditselectiontool.[ch] * app/tools/gimperasertool.c * app/tools/gimpfliptool.c * app/tools/gimpfreeselecttool.[ch] * app/tools/gimpfuzzyselecttool.c * app/tools/gimpinktool.c * app/tools/gimpiscissorstool.c * app/tools/gimpmagnifytool.c * app/tools/gimpmeasuretool.c * app/tools/gimpmovetool.c * app/tools/gimppainttool.c * app/tools/gimppathtool.[ch] * app/tools/gimprectselecttool.c * app/tools/gimprotatetool.c * app/tools/gimpselectiontool.[ch] * app/tools/gimpsmudgetool.c * app/tools/gimptexttool.c * app/tools/gimptransformtool.[ch] * app/tools/path_tool.[ch] * app/tools/selection_options.c: tons and tons of changes: - changed to use the new virtual function parameters. - removed zillions of gdisplay_untransform_coords(). - get the active drawable's offsets manually in many cases. (questionable, but IMHO ok because it's obvious and not simply a "TRUE" passed to some function) - reordered some functions to be consistent across tools. - some tools had to be changed to work on image coords, not display ones (esp. crop). - fixed strange rotate tool behaviour which should be backported to stable. - some stuff i came across. - indentation and other paranoia. - rounding of coordinated may be broken in some tools. - new bugs guaranteed. * app/tools/tool_manager.[ch]: new semantic of tool_manager_initialize_active() (looked at the places where it was used from and put common code together). Should be a bit better now :) * app/tools/gimpblendtool.c * app/tools/transform_options.c: use the new GTK+ feature that a widget (toggle button) can be a frame's title for this tools' tool options. * app/widgets/widgets-types.h: stuff. * themes/Default/gtkrc: s/GtkDialog/GimpDialog/. * tools/pdbgen/Makefile.am: don't scan tools/gimpbucketfilltool.h any more. * tools/pdbgen/enums.pl: regenerated. * tools/pdbgen/pdb/tools.pdb: changed bucket_fill wrapper. * app/pdb/tools_cmds.c: regenerated.
2001-11-09 03:14:51 +08:00
if (! (state & gimp_get_extend_selection_mask ()))
find_max_gradient (iscissors, GIMP_PICKABLE (image),
&iscissors->x, &iscissors->y);
iscissors->x = CLAMP (iscissors->x, 0, gimp_image_get_width (image) - 1);
iscissors->y = CLAMP (iscissors->y, 0, gimp_image_get_height (image) - 1);
gimp_iscissors_tool_push_undo (iscissors);
segment = icurve_append_segment (iscissors->curve,
iscissors->x,
iscissors->y,
iscissors->x,
iscissors->y);
/* Initialize the draw tool only on starting the tool */
gimp_draw_tool_start (GIMP_DRAW_TOOL (tool), display);
1997-11-25 06:05:25 +08:00
break;
default:
2005-08-22 04:28:05 +08:00
/* Check if the mouse click occurred on a vertex or the curve itself */
if (clicked_on_vertex (iscissors, coords->x, coords->y))
{
iscissors->state = SEED_ADJUSTMENT;
/* recalculate both segments */
if (iscissors->segment1)
{
iscissors->segment1->x1 = iscissors->x;
iscissors->segment1->y1 = iscissors->y;
if (options->interactive)
calculate_segment (iscissors, iscissors->segment1);
}
if (iscissors->segment2)
{
iscissors->segment2->x2 = iscissors->x;
iscissors->segment2->y2 = iscissors->y;
if (options->interactive)
calculate_segment (iscissors, iscissors->segment2);
}
}
/* If the iscissors is closed, check if the click was inside */
else if (iscissors->curve->closed && iscissors->mask &&
gimp_pickable_get_opacity_at (GIMP_PICKABLE (iscissors->mask),
iscissors->x,
iscissors->y))
{
gimp_tool_control (tool, GIMP_TOOL_ACTION_COMMIT, display);
gimp_tool_control (tool, GIMP_TOOL_ACTION_HALT, display);
}
else if (! iscissors->curve->closed)
{
/* if we're not closed, we're adding a new point */
ISegment *last = g_queue_peek_tail (iscissors->curve->segments);
iscissors->state = SEED_PLACEMENT;
gimp_iscissors_tool_push_undo (iscissors);
if (last->x1 == last->x2 &&
last->y1 == last->y2)
{
last->x2 = iscissors->x;
last->y2 = iscissors->y;
if (options->interactive)
calculate_segment (iscissors, last);
}
else
{
segment = icurve_append_segment (iscissors->curve,
last->x2,
last->y2,
iscissors->x,
iscissors->y);
if (options->interactive)
calculate_segment (iscissors, segment);
}
}
1997-11-25 06:05:25 +08:00
break;
}
gimp_draw_tool_resume (GIMP_DRAW_TOOL (tool));
1997-11-25 06:05:25 +08:00
}
static void
iscissors_convert (GimpIscissorsTool *iscissors,
GimpDisplay *display)
{
GimpSelectionOptions *options = GIMP_SELECTION_TOOL_GET_OPTIONS (iscissors);
GimpImage *image = gimp_display_get_image (display);
GimpScanConvert *sc;
sc = icurve_create_scan_convert (iscissors->curve);
if (iscissors->mask)
g_object_unref (iscissors->mask);
iscissors->mask = gimp_channel_new_mask (image,
gimp_image_get_width (image),
gimp_image_get_height (image));
gimp_scan_convert_render (sc,
gimp_drawable_get_buffer (GIMP_DRAWABLE (iscissors->mask)),
0, 0, options->antialias);
gimp_scan_convert_free (sc);
}
1997-11-25 06:05:25 +08:00
static void
gimp_iscissors_tool_button_release (GimpTool *tool,
const GimpCoords *coords,
guint32 time,
GdkModifierType state,
GimpButtonReleaseType release_type,
GimpDisplay *display)
1997-11-25 06:05:25 +08:00
{
GimpIscissorsTool *iscissors = GIMP_ISCISSORS_TOOL (tool);
GimpIscissorsOptions *options = GIMP_ISCISSORS_TOOL_GET_OPTIONS (tool);
1997-11-25 06:05:25 +08:00
gimp_tool_control_halt (tool->control);
/* Make sure X didn't skip the button release event -- as it's known
build display/ before tools/. 2001-11-08 Michael Natterer <mitch@gimp.org> * app/Makefile.am: build display/ before tools/. * app/devices.c: devices_check_change(): added all events which have a GdkDevice pointer. * app/gimpprogress.c: include "display-types.h" instead of "core-types.h". * app/core/Makefile.am * app/core/gimpdrawable-bucket-fill.[ch]: new files: the bucket_fill stuff taken from tools/gimpbucketfilltool.[ch]. * app/core/core-types.h: added "BucketFillMode". * app/core/gimpimage-mask-select.[ch]: cleanup. * app/core/gimpmarshal.list: added more marshallers for GimpTool's new signal signatures. * app/core/gimpmarshal.[ch]: regenerated. * app/display/Makefile.am * app/display/gimpdisplayshell-dnd.[ch] * app/display/gimpdisplayshell-layer-select.[ch]: new files: the canvas drop callbacks from gimpdisplayshell-callbacks.[ch] and the stuff formerly knows as gui/layer-select.[ch]. * app/display/gimpdisplay.h: don't include "gui/gui-types.h". * app/display/gximage.c: include "display-types.h". * app/display/gimpdisplay-foreach.c * app/display/gimpdisplayshell.[ch]: call gdsplay_delete(), don't destroy the shell widget. * app/gui/Makefile.am * app/gui/layer-select.[ch]: removed. * app/gui/gradients-commands.c: fixed "Save as POV" fprintf()s. * app/gui/preferences-dialog.c: removed the layer_select stuff because it is useless with the new preview system. * app/gui/tool-options-dialog.c: send the correct data to the close_callback. * app/gui/tools-commands.c: changed to follow the new gimp_tool_initialize() semantics (see below). Tool & canvas event handling chainsawing: * app/tools/tools-types.h: new struct GimpCoords which contains x, y, pressure, tilt etc. * app/display/gimpdisplayshell-callbacks.[ch]: added utility functions which transparently retreive the current event's GimpCoords or take it from the device directly if the event has none. Pass GimpCoords _in_image_coordinates_ to all tool functions. Most important: don't pass GdkEvents and display coordinates to tools any more. * app/tools/gimptool.[ch]: changed virtual functions to take GimpCoords, time and state separately instead of GdkEvents. * app/tools/gimpbezierselecttool.c * app/tools/gimpblendtool.c * app/tools/gimpbucketfilltool.[ch] * app/tools/gimpbycolorselecttool.c * app/tools/gimpclonetool.c * app/tools/gimpcolorpickertool.c * app/tools/gimpconvolvetool.c * app/tools/gimpcroptool.[ch] * app/tools/gimpcurvestool.c * app/tools/gimpdodgeburntool.c * app/tools/gimpdrawtool.c * app/tools/gimpeditselectiontool.[ch] * app/tools/gimperasertool.c * app/tools/gimpfliptool.c * app/tools/gimpfreeselecttool.[ch] * app/tools/gimpfuzzyselecttool.c * app/tools/gimpinktool.c * app/tools/gimpiscissorstool.c * app/tools/gimpmagnifytool.c * app/tools/gimpmeasuretool.c * app/tools/gimpmovetool.c * app/tools/gimppainttool.c * app/tools/gimppathtool.[ch] * app/tools/gimprectselecttool.c * app/tools/gimprotatetool.c * app/tools/gimpselectiontool.[ch] * app/tools/gimpsmudgetool.c * app/tools/gimptexttool.c * app/tools/gimptransformtool.[ch] * app/tools/path_tool.[ch] * app/tools/selection_options.c: tons and tons of changes: - changed to use the new virtual function parameters. - removed zillions of gdisplay_untransform_coords(). - get the active drawable's offsets manually in many cases. (questionable, but IMHO ok because it's obvious and not simply a "TRUE" passed to some function) - reordered some functions to be consistent across tools. - some tools had to be changed to work on image coords, not display ones (esp. crop). - fixed strange rotate tool behaviour which should be backported to stable. - some stuff i came across. - indentation and other paranoia. - rounding of coordinated may be broken in some tools. - new bugs guaranteed. * app/tools/tool_manager.[ch]: new semantic of tool_manager_initialize_active() (looked at the places where it was used from and put common code together). Should be a bit better now :) * app/tools/gimpblendtool.c * app/tools/transform_options.c: use the new GTK+ feature that a widget (toggle button) can be a frame's title for this tools' tool options. * app/widgets/widgets-types.h: stuff. * themes/Default/gtkrc: s/GtkDialog/GimpDialog/. * tools/pdbgen/Makefile.am: don't scan tools/gimpbucketfilltool.h any more. * tools/pdbgen/enums.pl: regenerated. * tools/pdbgen/pdb/tools.pdb: changed bucket_fill wrapper. * app/pdb/tools_cmds.c: regenerated.
2001-11-09 03:14:51 +08:00
* to do
*/
if (iscissors->state == WAITING)
return;
gimp_draw_tool_pause (GIMP_DRAW_TOOL (tool));
1997-11-25 06:05:25 +08:00
if (release_type != GIMP_BUTTON_RELEASE_CANCEL)
1997-11-25 06:05:25 +08:00
{
/* Progress to the next stage of intelligent selection */
switch (iscissors->state)
{
case SEED_PLACEMENT:
/* Add a new segment */
if (! iscissors->curve->first_point)
{
/* Determine if we're connecting to the first point */
ISegment *segment = g_queue_peek_head (iscissors->curve->segments);
if (gimp_draw_tool_on_handle (GIMP_DRAW_TOOL (tool), display,
iscissors->x, iscissors->y,
GIMP_HANDLE_CIRCLE,
segment->x1, segment->y1,
GIMP_TOOL_HANDLE_SIZE_CIRCLE,
GIMP_TOOL_HANDLE_SIZE_CIRCLE,
GIMP_HANDLE_ANCHOR_CENTER))
{
iscissors->x = segment->x1;
iscissors->y = segment->y1;
icurve_close (iscissors->curve);
if (! options->interactive)
{
segment = g_queue_peek_tail (iscissors->curve->segments);
calculate_segment (iscissors, segment);
}
gimp_iscissors_tool_free_redo (iscissors);
}
else
{
segment = g_queue_peek_tail (iscissors->curve->segments);
if (segment->x1 != segment->x2 ||
segment->y1 != segment->y2)
{
if (! options->interactive)
calculate_segment (iscissors, segment);
gimp_iscissors_tool_free_redo (iscissors);
}
else
{
gimp_iscissors_tool_pop_undo (iscissors);
}
}
}
else /* this was our first point */
{
iscissors->curve->first_point = FALSE;
gimp_iscissors_tool_free_redo (iscissors);
}
break;
case SEED_ADJUSTMENT:
if (state & gimp_get_modify_selection_mask ())
{
if (iscissors->segment1 && iscissors->segment2)
{
icurve_delete_segment (iscissors->curve,
iscissors->segment2);
calculate_segment (iscissors, iscissors->segment1);
}
}
else
{
/* recalculate both segments */
if (iscissors->segment1)
{
if (! options->interactive)
calculate_segment (iscissors, iscissors->segment1);
}
if (iscissors->segment2)
{
if (! options->interactive)
calculate_segment (iscissors, iscissors->segment2);
}
}
gimp_iscissors_tool_free_redo (iscissors);
break;
default:
break;
}
}
else
{
switch (iscissors->state)
{
case SEED_PLACEMENT:
case SEED_ADJUSTMENT:
gimp_iscissors_tool_pop_undo (iscissors);
break;
default:
break;
}
1997-11-25 06:05:25 +08:00
}
if (iscissors->curve->first_point)
iscissors->state = NO_ACTION;
else
iscissors->state = WAITING;
gimp_draw_tool_resume (GIMP_DRAW_TOOL (tool));
/* convert the curves into a region */
if (iscissors->curve->closed)
iscissors_convert (iscissors, display);
1997-11-25 06:05:25 +08:00
}
static void
gimp_iscissors_tool_motion (GimpTool *tool,
const GimpCoords *coords,
guint32 time,
GdkModifierType state,
GimpDisplay *display)
1997-11-25 06:05:25 +08:00
{
GimpIscissorsTool *iscissors = GIMP_ISCISSORS_TOOL (tool);
GimpIscissorsOptions *options = GIMP_ISCISSORS_TOOL_GET_OPTIONS (tool);
GimpImage *image = gimp_display_get_image (display);
ISegment *segment;
if (iscissors->state == NO_ACTION)
return;
gimp_draw_tool_pause (GIMP_DRAW_TOOL (tool));
iscissors->x = RINT (coords->x);
iscissors->y = RINT (coords->y);
/* Hold the shift key down to disable the auto-edge snap feature */
if (! (state & gimp_get_extend_selection_mask ()))
find_max_gradient (iscissors, GIMP_PICKABLE (image),
&iscissors->x, &iscissors->y);
iscissors->x = CLAMP (iscissors->x, 0, gimp_image_get_width (image) - 1);
iscissors->y = CLAMP (iscissors->y, 0, gimp_image_get_height (image) - 1);
1997-11-25 06:05:25 +08:00
switch (iscissors->state)
{
case SEED_PLACEMENT:
segment = g_queue_peek_tail (iscissors->curve->segments);
segment->x2 = iscissors->x;
segment->y2 = iscissors->y;
if (iscissors->curve->first_point)
{
segment->x1 = segment->x2;
segment->y1 = segment->y2;
}
else
{
if (options->interactive)
calculate_segment (iscissors, segment);
}
break;
case SEED_ADJUSTMENT:
if (iscissors->segment1)
{
iscissors->segment1->x1 = iscissors->x;
iscissors->segment1->y1 = iscissors->y;
if (options->interactive)
calculate_segment (iscissors, iscissors->segment1);
}
if (iscissors->segment2)
{
iscissors->segment2->x2 = iscissors->x;
iscissors->segment2->y2 = iscissors->y;
if (options->interactive)
calculate_segment (iscissors, iscissors->segment2);
}
1997-11-25 06:05:25 +08:00
break;
default:
1997-11-25 06:05:25 +08:00
break;
}
gimp_draw_tool_resume (GIMP_DRAW_TOOL (tool));
1997-11-25 06:05:25 +08:00
}
static void
gimp_iscissors_tool_draw (GimpDrawTool *draw_tool)
1997-11-25 06:05:25 +08:00
{
GimpIscissorsTool *iscissors = GIMP_ISCISSORS_TOOL (draw_tool);
GimpIscissorsOptions *options = GIMP_ISCISSORS_TOOL_GET_OPTIONS (draw_tool);
GimpCanvasItem *item;
GList *list;
1997-11-25 06:05:25 +08:00
/* First, render all segments and lines */
if (! iscissors->curve->first_point)
1997-11-25 06:05:25 +08:00
{
for (list = g_queue_peek_head_link (iscissors->curve->segments);
list;
list = g_list_next (list))
{
ISegment *segment = list->data;
1997-11-25 06:05:25 +08:00
/* plot the segment */
item = iscissors_draw_segment (draw_tool, segment);
/* if this segment is currently being added or adjusted */
if ((iscissors->state == SEED_PLACEMENT &&
! list->next)
||
(iscissors->state == SEED_ADJUSTMENT &&
(segment == iscissors->segment1 ||
segment == iscissors->segment2)))
{
if (! options->interactive)
item = gimp_draw_tool_add_line (draw_tool,
segment->x1, segment->y1,
segment->x2, segment->y2);
if (item)
gimp_canvas_item_set_highlight (item, TRUE);
}
}
}
1997-11-25 06:05:25 +08:00
/* Then, render the handles on top of the segments */
for (list = g_queue_peek_head_link (iscissors->curve->segments);
list;
list = g_list_next (list))
{
ISegment *segment = list->data;
if (! iscissors->curve->first_point)
{
gboolean adjustment = (iscissors->state == SEED_ADJUSTMENT &&
segment == iscissors->segment1);
item = gimp_draw_tool_add_handle (draw_tool,
adjustment ?
GIMP_HANDLE_CROSS :
GIMP_HANDLE_FILLED_CIRCLE,
segment->x1,
segment->y1,
GIMP_TOOL_HANDLE_SIZE_CIRCLE,
GIMP_TOOL_HANDLE_SIZE_CIRCLE,
GIMP_HANDLE_ANCHOR_CENTER);
if (adjustment)
gimp_canvas_item_set_highlight (item, TRUE);
}
/* Draw the last point if the curve is not closed */
if (! list->next && ! iscissors->curve->closed)
{
gboolean placement = (iscissors->state == SEED_PLACEMENT);
item = gimp_draw_tool_add_handle (draw_tool,
placement ?
GIMP_HANDLE_CROSS :
GIMP_HANDLE_FILLED_CIRCLE,
segment->x2,
segment->y2,
GIMP_TOOL_HANDLE_SIZE_CIRCLE,
GIMP_TOOL_HANDLE_SIZE_CIRCLE,
GIMP_HANDLE_ANCHOR_CENTER);
if (placement)
gimp_canvas_item_set_highlight (item, TRUE);
}
}
}
1997-11-25 06:05:25 +08:00
static GimpCanvasItem *
iscissors_draw_segment (GimpDrawTool *draw_tool,
ISegment *segment)
{
GimpCanvasItem *item;
GimpVector2 *points;
gpointer *point;
gint i, len;
if (! segment->points)
return NULL;
len = segment->points->len;
points = g_new (GimpVector2, len);
for (i = 0, point = segment->points->pdata; i < len; i++, point++)
{
guint32 coords = GPOINTER_TO_INT (*point);
points[i].x = (coords & 0x0000ffff);
points[i].y = (coords >> 16);
1997-11-25 06:05:25 +08:00
}
item = gimp_draw_tool_add_lines (draw_tool, points, len, NULL, FALSE);
g_free (points);
return item;
1997-11-25 06:05:25 +08:00
}
static void
gimp_iscissors_tool_oper_update (GimpTool *tool,
const GimpCoords *coords,
GdkModifierType state,
gboolean proximity,
GimpDisplay *display)
{
GimpIscissorsTool *iscissors = GIMP_ISCISSORS_TOOL (tool);
GIMP_TOOL_CLASS (parent_class)->oper_update (tool, coords, state, proximity,
display);
/* parent sets a message in the status bar, but it will be replaced here */
if (mouse_over_vertex (iscissors, coords->x, coords->y) > 1)
{
GdkModifierType snap_mask = gimp_get_extend_selection_mask ();
GdkModifierType remove_mask = gimp_get_modify_selection_mask ();
if (state & remove_mask)
{
gimp_tool_replace_status (tool, display,
_("Click to remove this point"));
iscissors->op = ISCISSORS_OP_REMOVE_POINT;
}
else
{
gchar *status =
gimp_suggest_modifiers (_("Click-Drag to move this point"),
(snap_mask | remove_mask) & ~state,
_("%s: disable auto-snap"),
_("%s: remove this point"),
NULL);
gimp_tool_replace_status (tool, display, "%s", status);
g_free (status);
iscissors->op = ISCISSORS_OP_MOVE_POINT;
}
}
else if (mouse_over_segment (iscissors, coords->x, coords->y))
{
ISegment *segment = g_queue_peek_head (iscissors->curve->segments);
if (gimp_draw_tool_on_handle (GIMP_DRAW_TOOL (tool), display,
RINT (coords->x), RINT (coords->y),
GIMP_HANDLE_CIRCLE,
segment->x1, segment->y1,
GIMP_TOOL_HANDLE_SIZE_CIRCLE,
GIMP_TOOL_HANDLE_SIZE_CIRCLE,
GIMP_HANDLE_ANCHOR_CENTER))
{
gimp_tool_replace_status (tool, display,
_("Click to close the curve"));
iscissors->op = ISCISSORS_OP_CONNECT;
}
else
{
gimp_tool_replace_status (tool, display,
_("Click to add a point on this segment"));
iscissors->op = ISCISSORS_OP_ADD_POINT;
}
}
else if (iscissors->curve->closed && iscissors->mask)
{
if (gimp_pickable_get_opacity_at (GIMP_PICKABLE (iscissors->mask),
RINT (coords->x),
RINT (coords->y)))
{
if (proximity)
{
gimp_tool_replace_status (tool, display,
_("Click or press Enter to convert to"
" a selection"));
}
iscissors->op = ISCISSORS_OP_SELECT;
}
else
{
if (proximity)
{
gimp_tool_replace_status (tool, display,
_("Press Enter to convert to a"
" selection"));
}
iscissors->op = ISCISSORS_OP_IMPOSSIBLE;
}
}
else
{
switch (iscissors->state)
{
case WAITING:
if (proximity)
{
GdkModifierType snap_mask = gimp_get_extend_selection_mask ();
gchar *status;
status = gimp_suggest_modifiers (_("Click or Click-Drag to add a"
" point"),
snap_mask & ~state,
_("%s: disable auto-snap"),
NULL, NULL);
bumped minimum required version of GLib to 2.18.0. 2008-11-04 Sven Neumann <sven@sven> * configure.in: bumped minimum required version of GLib to 2.18.0. * INSTALL: document the updated dependency. * app/core/gimp.[ch]: introduced gimp_message_literal(), a variant of gimp_message() that takes a literal string. * app/errors.[ch]: removed format arguments from gimp_fatal_error() and gimp_terminate() and let them take a literal string instead. * app/tools/gimptool.[ch]: introduced gimp_tool_message_literal(), a variant of gimp_tool_message() that takes a literal string. * app/actions/documents-commands.c * app/actions/drawable-commands.c * app/actions/edit-commands.c * app/actions/error-console-commands.c * app/actions/file-commands.c * app/actions/gradients-commands.c * app/actions/image-commands.c * app/actions/layers-commands.c * app/actions/palettes-commands.c * app/actions/plug-in-commands.c * app/actions/select-commands.c * app/actions/vectors-commands.c * app/config/gimprc.c * app/core/gimp-modules.c * app/core/gimp-parasites.c * app/core/gimp-templates.c * app/core/gimp-units.c * app/core/gimpchannel.c * app/core/gimpcontainer-filter.c * app/core/gimpdrawable-bucket-fill.c * app/core/gimpimage-convert.c * app/core/gimpimage-merge.c * app/core/gimpimage.c * app/core/gimpimagefile.c * app/core/gimplayer-floating-sel.c * app/core/gimplayer.c * app/core/gimpselection.c * app/dialogs/convert-dialog.c * app/dialogs/dialogs.c * app/dialogs/palette-import-dialog.c * app/dialogs/preferences-dialog.c * app/dialogs/quit-dialog.c * app/dialogs/stroke-dialog.c * app/display/gimpdisplayshell-dnd.c * app/file/file-open.c * app/file/file-procedure.c * app/file/file-save.c * app/file/file-utils.c * app/gegl/gimpcurvesconfig.c * app/gegl/gimplevelsconfig.c * app/gui/gui-message.c * app/gui/gui.c * app/gui/session.c * app/paint/gimpbrushcore.c * app/paint/gimpclone.c * app/paint/gimpheal.c * app/paint/gimpperspectiveclone.c * app/paint/gimpsourcecore.c * app/pdb/gimppdb-utils.c * app/pdb/gimpprocedure.c * app/plug-in/gimpplugin-message.c * app/plug-in/gimpplugin.c * app/plug-in/gimppluginmanager-restore.c * app/plug-in/gimppluginprocedure.c * app/text/gimptextlayer.c * app/tools/gimp-tools.c * app/tools/gimpaligntool.c * app/tools/gimpblendtool.c * app/tools/gimpbrightnesscontrasttool.c * app/tools/gimpbucketfilltool.c * app/tools/gimpcolorbalancetool.c * app/tools/gimpcolorpickertool.c * app/tools/gimpcurvestool.c * app/tools/gimpdesaturatetool.c * app/tools/gimpeditselectiontool.c * app/tools/gimpforegroundselecttool.c * app/tools/gimpfreeselecttool.c * app/tools/gimpgegltool.c * app/tools/gimphuesaturationtool.c * app/tools/gimpimagemaptool-settings.c * app/tools/gimpiscissorstool.c * app/tools/gimplevelstool.c * app/tools/gimpmeasuretool.c * app/tools/gimppainttool.c * app/tools/gimpposterizetool.c * app/tools/gimpselectiontool.c * app/tools/gimpsourcetool.c * app/tools/gimpthresholdtool.c * app/tools/gimptransformtool.c * app/tools/gimpvectortool.c * app/widgets/gimpactionview.c * app/widgets/gimpcontrollerlist.c * app/widgets/gimpcontrollers.c * app/widgets/gimpdataeditor.c * app/widgets/gimpdevices.c * app/widgets/gimpdnd-xds.c * app/widgets/gimperrordialog.c * app/widgets/gimphelp.c * app/widgets/gimpitemtreeview.c * app/widgets/gimppdbdialog.c * app/widgets/gimpsettingsbox.c * app/widgets/gimpvectorstreeview.c * app/widgets/gimpwidgets-utils.c * app/xcf/xcf-load.c * tools/pdbgen/pdb/convert.pdb * tools/pdbgen/pdb/edit.pdb * tools/pdbgen/pdb/floating_sel.pdb * tools/pdbgen/pdb/image.pdb: use the _literal variants for g_set_error(), gimp_message() and gimp_tool_message(). * app/pdb/convert-cmds.c * app/pdb/edit-cmds.c * app/pdb/floating-sel-cmds.c * app/pdb/image-cmds.c: regenerated. svn path=/trunk/; revision=27548
2008-11-04 20:33:09 +08:00
gimp_tool_replace_status (tool, display, "%s", status);
g_free (status);
}
iscissors->op = ISCISSORS_OP_ADD_POINT;
break;
default:
/* if NO_ACTION, keep parent's status bar message (selection tool) */
iscissors->op = ISCISSORS_OP_NONE;
break;
}
}
}
static void
gimp_iscissors_tool_cursor_update (GimpTool *tool,
const GimpCoords *coords,
GdkModifierType state,
GimpDisplay *display)
{
GimpIscissorsTool *iscissors = GIMP_ISCISSORS_TOOL (tool);
GimpCursorModifier modifier = GIMP_CURSOR_MODIFIER_NONE;
switch (iscissors->op)
{
case ISCISSORS_OP_SELECT:
{
GimpSelectionOptions *options;
options = GIMP_SELECTION_TOOL_GET_OPTIONS (tool);
/* Do not overwrite the modifiers for add, subtract, intersect */
if (options->operation == GIMP_CHANNEL_OP_REPLACE)
{
modifier = GIMP_CURSOR_MODIFIER_SELECT;
}
}
break;
case ISCISSORS_OP_MOVE_POINT:
modifier = GIMP_CURSOR_MODIFIER_MOVE;
break;
case ISCISSORS_OP_ADD_POINT:
modifier = GIMP_CURSOR_MODIFIER_PLUS;
break;
case ISCISSORS_OP_REMOVE_POINT:
modifier = GIMP_CURSOR_MODIFIER_MINUS;
break;
case ISCISSORS_OP_CONNECT:
modifier = GIMP_CURSOR_MODIFIER_JOIN;
break;
case ISCISSORS_OP_IMPOSSIBLE:
modifier = GIMP_CURSOR_MODIFIER_BAD;
break;
default:
break;
}
added fields for both the tool's toggled and untoggled GdkCursorType, 2002-02-04 Michael Natterer <mitch@gimp.org> * app/tools/gimptool.[ch]: added fields for both the tool's toggled and untoggled GdkCursorType, GimpToolCursorType and GimpCursorModifier. Added a default implementation of gimp_tool_cursor_update() which uses the new fields. Added gimp_tool_set_cursor() as simple wrapper around the resp. GimpDisplayShell functions so tools don't need to know them. Tool implementations can either set the new fields in their cursor_update() function and chain up or call the new wrapper. * app/tools/gimpbezierselecttool.c * app/tools/gimpblendtool.c * app/tools/gimpbucketfilltool.c * app/tools/gimpbycolorselecttool.c * app/tools/gimpclonetool.c * app/tools/gimpcolorpickertool.c * app/tools/gimpconvolvetool.c * app/tools/gimpcroptool.c * app/tools/gimpdodgeburntool.c * app/tools/gimperasertool.c * app/tools/gimpfliptool.c * app/tools/gimpinktool.c * app/tools/gimpiscissorstool.c * app/tools/gimpmagnifytool.c * app/tools/gimpmeasuretool.c * app/tools/gimpmovetool.c * app/tools/gimppainttool.[ch] * app/tools/gimppathtool.c * app/tools/gimpselectiontool.c * app/tools/gimpsmudgetool.c * app/tools/gimptexttool.c * app/tools/gimptransformtool.c: changed accordingly: - set default values in the tools' instance_init functions. - changed the cursor_update() stuff. - removed inclusion of subclasses in gimppainttool.c - the cursor_update() functions are better than before but still evil. - i probably broke some of them...
2002-02-05 01:43:01 +08:00
if (modifier != GIMP_CURSOR_MODIFIER_NONE)
{
gimp_tool_set_cursor (tool, display,
GIMP_CURSOR_MOUSE,
GIMP_TOOL_CURSOR_ISCISSORS,
modifier);
}
else
{
GIMP_TOOL_CLASS (parent_class)->cursor_update (tool, coords,
state, display);
}
}
static gboolean
gimp_iscissors_tool_key_press (GimpTool *tool,
GdkEventKey *kevent,
GimpDisplay *display)
{
GimpIscissorsTool *iscissors = GIMP_ISCISSORS_TOOL (tool);
if (display != tool->display)
return FALSE;
switch (kevent->keyval)
{
case GDK_KEY_BackSpace:
if (! iscissors->curve->closed &&
g_queue_peek_tail (iscissors->curve->segments))
{
gimp_draw_tool_pause (GIMP_DRAW_TOOL (tool));
gimp_iscissors_tool_push_undo (iscissors);
icurve_delete_segment (iscissors->curve,
g_queue_peek_tail (iscissors->curve->segments));
gimp_iscissors_tool_free_redo (iscissors);
gimp_draw_tool_resume (GIMP_DRAW_TOOL (tool));
return TRUE;
}
return FALSE;
case GDK_KEY_Return:
case GDK_KEY_KP_Enter:
case GDK_KEY_ISO_Enter:
if (iscissors->curve->closed && iscissors->mask)
{
gimp_tool_control (tool, GIMP_TOOL_ACTION_COMMIT, display);
gimp_tool_control (tool, GIMP_TOOL_ACTION_HALT, display);
return TRUE;
}
return FALSE;
case GDK_KEY_Escape:
gimp_tool_control (tool, GIMP_TOOL_ACTION_HALT, display);
return TRUE;
default:
return FALSE;
}
}
static const gchar *
gimp_iscissors_tool_can_undo (GimpTool *tool,
GimpDisplay *display)
{
GimpIscissorsTool *iscissors = GIMP_ISCISSORS_TOOL (tool);
if (display != tool->display || ! iscissors->undo_stack)
return NULL;
return _("Modify Scissors Curve");
}
static const gchar *
gimp_iscissors_tool_can_redo (GimpTool *tool,
GimpDisplay *display)
{
GimpIscissorsTool *iscissors = GIMP_ISCISSORS_TOOL (tool);
if (display != tool->display || ! iscissors->redo_stack)
return NULL;
return _("Modify Scissors Curve");
}
static gboolean
gimp_iscissors_tool_undo (GimpTool *tool,
GimpDisplay *display)
{
GimpIscissorsTool *iscissors = GIMP_ISCISSORS_TOOL (tool);
if (! gimp_iscissors_tool_can_undo (tool, display))
return FALSE;
gimp_draw_tool_pause (GIMP_DRAW_TOOL (tool));
iscissors->redo_stack = g_list_prepend (iscissors->redo_stack,
iscissors->curve);
iscissors->curve = iscissors->undo_stack->data;
iscissors->undo_stack = g_list_remove (iscissors->undo_stack,
iscissors->curve);
if (! iscissors->undo_stack)
{
iscissors->state = NO_ACTION;
gimp_draw_tool_stop (GIMP_DRAW_TOOL (tool));
}
gimp_draw_tool_resume (GIMP_DRAW_TOOL (tool));
return TRUE;
}
static gboolean
gimp_iscissors_tool_redo (GimpTool *tool,
GimpDisplay *display)
{
GimpIscissorsTool *iscissors = GIMP_ISCISSORS_TOOL (tool);
if (! gimp_iscissors_tool_can_redo (tool, display))
return FALSE;
gimp_draw_tool_pause (GIMP_DRAW_TOOL (tool));
if (! iscissors->undo_stack)
{
iscissors->state = WAITING;
gimp_draw_tool_start (GIMP_DRAW_TOOL (tool), display);
}
iscissors->undo_stack = g_list_prepend (iscissors->undo_stack,
iscissors->curve);
iscissors->curve = iscissors->redo_stack->data;
iscissors->redo_stack = g_list_remove (iscissors->redo_stack,
iscissors->curve);
gimp_draw_tool_resume (GIMP_DRAW_TOOL (tool));
return TRUE;
}
static void
gimp_iscissors_tool_push_undo (GimpIscissorsTool *iscissors)
{
iscissors->undo_stack = g_list_prepend (iscissors->undo_stack,
icurve_copy (iscissors->curve));
}
static void
gimp_iscissors_tool_pop_undo (GimpIscissorsTool *iscissors)
{
icurve_free (iscissors->curve);
iscissors->curve = iscissors->undo_stack->data;
iscissors->undo_stack = g_list_remove (iscissors->undo_stack,
iscissors->curve);
if (! iscissors->undo_stack)
{
iscissors->state = NO_ACTION;
gimp_draw_tool_stop (GIMP_DRAW_TOOL (iscissors));
}
}
static void
gimp_iscissors_tool_free_redo (GimpIscissorsTool *iscissors)
{
g_list_free_full (iscissors->redo_stack,
(GDestroyNotify) icurve_free);
iscissors->redo_stack = NULL;
/* update the undo actions / menu items */
gimp_image_flush (gimp_display_get_image (GIMP_TOOL (iscissors)->display));
}
static void
gimp_iscissors_tool_halt (GimpIscissorsTool *iscissors,
GimpDisplay *display)
{
icurve_clear (iscissors->curve);
iscissors->segment1 = NULL;
iscissors->segment2 = NULL;
iscissors->state = NO_ACTION;
if (iscissors->undo_stack)
{
g_list_free_full (iscissors->undo_stack, (GDestroyNotify) icurve_free);
iscissors->undo_stack = NULL;
}
if (iscissors->redo_stack)
{
g_list_free_full (iscissors->redo_stack, (GDestroyNotify) icurve_free);
iscissors->redo_stack = NULL;
}
if (iscissors->gradient_map)
{
g_object_unref (iscissors->gradient_map);
iscissors->gradient_map = NULL;
}
if (iscissors->mask)
{
g_object_unref (iscissors->mask);
iscissors->mask = NULL;
}
}
static void
gimp_iscissors_tool_commit (GimpIscissorsTool *iscissors,
GimpDisplay *display)
{
GimpTool *tool = GIMP_TOOL (iscissors);
GimpSelectionOptions *options = GIMP_SELECTION_TOOL_GET_OPTIONS (tool);
GimpImage *image = gimp_display_get_image (display);
if (! iscissors->curve->closed)
{
ISegment *first = g_queue_peek_head (iscissors->curve->segments);
ISegment *last = g_queue_peek_tail (iscissors->curve->segments);
if (first && last && first != last)
{
ISegment *segment;
segment = icurve_append_segment (iscissors->curve,
last->x2,
last->y2,
first->x1,
first->y1);
icurve_close (iscissors->curve);
calculate_segment (iscissors, segment);
iscissors_convert (iscissors, display);
}
}
if (iscissors->curve->closed && iscissors->mask)
{
gimp_channel_select_channel (gimp_image_get_mask (image),
tool->tool_info->blurb,
iscissors->mask,
0, 0,
options->operation,
options->feather,
options->feather_radius,
options->feather_radius);
gimp_image_flush (image);
}
}
/* XXX need some scan-conversion routines from somewhere. maybe. ? */
static gint
mouse_over_vertex (GimpIscissorsTool *iscissors,
gdouble x,
gdouble y)
1997-11-25 06:05:25 +08:00
{
GList *list;
gint segments_found = 0;
1997-11-25 06:05:25 +08:00
/* traverse through the list, returning non-zero if the current cursor
* position is on an existing curve vertex. Set the segment1 and segment2
* variables to the two segments containing the vertex in question
*/
1997-11-25 06:05:25 +08:00
iscissors->segment1 = iscissors->segment2 = NULL;
for (list = g_queue_peek_head_link (iscissors->curve->segments);
list;
list = g_list_next (list))
1997-11-25 06:05:25 +08:00
{
ISegment *segment = list->data;
if (gimp_draw_tool_on_handle (GIMP_DRAW_TOOL (iscissors),
GIMP_TOOL (iscissors)->display,
x, y,
GIMP_HANDLE_CIRCLE,
segment->x1, segment->y1,
GIMP_TOOL_HANDLE_SIZE_CIRCLE,
GIMP_TOOL_HANDLE_SIZE_CIRCLE,
GIMP_HANDLE_ANCHOR_CENTER))
{
iscissors->segment1 = segment;
if (segments_found++)
return segments_found;
}
else if (gimp_draw_tool_on_handle (GIMP_DRAW_TOOL (iscissors),
GIMP_TOOL (iscissors)->display,
x, y,
GIMP_HANDLE_CIRCLE,
segment->x2, segment->y2,
GIMP_TOOL_HANDLE_SIZE_CIRCLE,
GIMP_TOOL_HANDLE_SIZE_CIRCLE,
GIMP_HANDLE_ANCHOR_CENTER))
{
iscissors->segment2 = segment;
if (segments_found++)
return segments_found;
}
1997-11-25 06:05:25 +08:00
}
return segments_found;
}
static gboolean
clicked_on_vertex (GimpIscissorsTool *iscissors,
gdouble x,
gdouble y)
{
gint segments_found = mouse_over_vertex (iscissors, x, y);
if (segments_found > 1)
{
gimp_iscissors_tool_push_undo (iscissors);
return TRUE;
}
/* if only one segment was found, the segments are unconnected, and
* the user only wants to move either the first or last point
* disallow this for now.
*/
if (segments_found == 1)
return FALSE;
return clicked_on_segment (iscissors, x, y);
1997-11-25 06:05:25 +08:00
}
static GList *
mouse_over_segment (GimpIscissorsTool *iscissors,
gdouble x,
gdouble y)
1997-11-25 06:05:25 +08:00
{
GList *list;
1997-11-25 06:05:25 +08:00
/* traverse through the list, returning the curve segment's list element
* if the current cursor position is on a curve...
*/
for (list = g_queue_peek_head_link (iscissors->curve->segments);
list;
list = g_list_next (list))
1997-11-25 06:05:25 +08:00
{
ISegment *segment = list->data;
gpointer *pt;
gint len;
1997-11-25 06:05:25 +08:00
if (! segment->points)
continue;
pt = segment->points->pdata;
len = segment->points->len;
while (len--)
{
guint32 coords = GPOINTER_TO_INT (*pt);
gint tx, ty;
pt++;
tx = coords & 0x0000ffff;
ty = coords >> 16;
/* Is the specified point close enough to the segment? */
if (gimp_draw_tool_calc_distance_square (GIMP_DRAW_TOOL (iscissors),
GIMP_TOOL (iscissors)->display,
tx, ty,
x, y) < SQR (GIMP_TOOL_HANDLE_SIZE_CIRCLE / 2))
{
return list;
}
}
}
1997-11-25 06:05:25 +08:00
return NULL;
}
static gboolean
clicked_on_segment (GimpIscissorsTool *iscissors,
gdouble x,
gdouble y)
{
GList *list = mouse_over_segment (iscissors, x, y);
/* traverse through the list, getting back the curve segment's list
* element if the current cursor position is on a segment...
* If this occurs, replace the segment with two new segments,
* separated by a new vertex.
*/
if (list)
{
ISegment *segment = list->data;
ISegment *new_segment;
gimp_iscissors_tool_push_undo (iscissors);
new_segment = icurve_insert_segment (iscissors->curve,
list,
iscissors->x,
iscissors->y,
segment->x2,
segment->y2);
iscissors->segment1 = new_segment;
iscissors->segment2 = segment;
return TRUE;
1997-11-25 06:05:25 +08:00
}
return FALSE;
1997-11-25 06:05:25 +08:00
}
1997-11-25 06:05:25 +08:00
static void
calculate_segment (GimpIscissorsTool *iscissors,
ISegment *segment)
1997-11-25 06:05:25 +08:00
{
GimpDisplay *display = GIMP_TOOL (iscissors)->display;
GimpPickable *pickable = GIMP_PICKABLE (gimp_display_get_image (display));
gint width;
gint height;
gint xs, ys, xe, ye;
gint x1, y1, x2, y2;
gint ewidth, eheight;
/* Initialise the gradient map buffer for this pickable if we don't
* already have one.
*/
if (! iscissors->gradient_map)
iscissors->gradient_map = gradient_map_new (pickable);
width = gegl_buffer_get_width (iscissors->gradient_map);
height = gegl_buffer_get_height (iscissors->gradient_map);
/* Calculate the lowest cost path from one vertex to the next as specified
* by the parameter "segment".
* Here are the steps:
* 1) Calculate the appropriate working area for this operation
* 2) Allocate a temp buf for the dynamic programming array
* 3) Run the dynamic programming algorithm to find the optimal path
* 4) Translate the optimal path into pixels in the isegment data
* structure.
*/
1997-11-25 06:05:25 +08:00
/* Get the bounding box */
xs = CLAMP (segment->x1, 0, width - 1);
ys = CLAMP (segment->y1, 0, height - 1);
xe = CLAMP (segment->x2, 0, width - 1);
ye = CLAMP (segment->y2, 0, height - 1);
x1 = MIN (xs, xe);
y1 = MIN (ys, ye);
x2 = MAX (xs, xe) + 1; /* +1 because if xe = 199 & xs = 0, x2 - x1, width = 200 */
y2 = MAX (ys, ye) + 1;
/* expand the boundaries past the ending points by
* some percentage of width and height. This serves the following purpose:
* It gives the algorithm more area to search so better solutions
* are found. This is particularly helpful in finding "bumps" which
* fall outside the bounding box represented by the start and end
* coordinates of the "segment".
*/
ewidth = (x2 - x1) * EXTEND_BY + FIXED;
eheight = (y2 - y1) * EXTEND_BY + FIXED;
1997-11-25 06:05:25 +08:00
if (xe >= xs)
x2 += CLAMP (ewidth, 0, width - x2);
else
x1 -= CLAMP (ewidth, 0, x1);
app/actions/channels-commands.c app/actions/colormap-actions.c 2007-12-25 Michael Natterer <mitch@gimp.org> * app/actions/channels-commands.c * app/actions/colormap-actions.c * app/actions/colormap-commands.c * app/actions/image-commands.c * app/core/gimp-edit.c * app/core/gimpdrawable-preview.c * app/core/gimpimage-colorhash.c * app/core/gimpimage-colormap.c * app/core/gimpimage-convert.c * app/core/gimpimage-crop.c * app/core/gimpimage-duplicate.c * app/core/gimpimage-flip.c * app/core/gimpimage-guides.c * app/core/gimpimage-merge.c * app/core/gimpimage-preview.c * app/core/gimpimage-quick-mask.c * app/core/gimpimage-resize.c * app/core/gimpimage-rotate.c * app/core/gimpimage-sample-points.c * app/core/gimpimage-scale.c * app/core/gimpimage-snap.c * app/core/gimpimage.c * app/core/gimpimagefile.c * app/core/gimpimageundo.c * app/core/gimpitem-preview.c * app/core/gimpitem.c * app/core/gimplayer.c * app/core/gimppalette-import.c * app/core/gimpprojection-construct.c * app/core/gimpprojection.c * app/core/gimpselection.c * app/core/gimpundo.c * app/dialogs/layer-options-dialog.c * app/dialogs/print-size-dialog.c * app/display/gimpdisplay.c * app/display/gimpdisplayshell-draw.c * app/display/gimpdisplayshell-scale.c * app/display/gimpdisplayshell-scroll.c * app/display/gimpdisplayshell-title.c * app/display/gimpdisplayshell-transform.c * app/display/gimpdisplayshell.c * app/display/gimpstatusbar.c * app/file/file-open.c * app/paint/gimppaintoptions.c * app/tools/gimpaligntool.c * app/tools/gimpcolortool.c * app/tools/gimpeditselectiontool.c * app/tools/gimpiscissorstool.c * app/tools/gimpmeasuretool.c * app/tools/gimpmovetool.c * app/tools/gimpperspectiveclonetool.c * app/tools/gimprectangleselecttool.c * app/tools/gimprectangletool.c * app/tools/gimprotatetool.c * app/vectors/gimpvectors-export.c * app/vectors/gimpvectors-import.c * app/vectors/gimpvectors.c * app/widgets/gimpimagepropview.c * app/widgets/gimpnavigationview.c * app/widgets/gimpselectioneditor.c * app/widgets/gimpviewrendererdrawable.c * app/widgets/gimpviewrendererimage.c * app/xcf/xcf-load.c * app/xcf/xcf-save.c * tools/pdbgen/pdb/guides.pdb * tools/pdbgen/pdb/image.pdb: use accessors for many image properties. * app/pdb/guides_cmds.c * app/pdb/image_cmds.c: regenerated. svn path=/trunk/; revision=24432
2007-12-26 00:21:40 +08:00
if (ye >= ys)
y2 += CLAMP (eheight, 0, height - y2);
else
y1 -= CLAMP (eheight, 0, y1);
/* blow away any previous points list we might have */
if (segment->points)
{
g_ptr_array_free (segment->points, TRUE);
segment->points = NULL;
}
if ((x2 - x1) && (y2 - y1))
1997-11-25 06:05:25 +08:00
{
/* If the bounding box has width and height... */
GimpTempBuf *dp_buf; /* dynamic programming buffer */
gint dp_width = (x2 - x1);
gint dp_height = (y2 - y1);
dp_buf = gimp_temp_buf_new (dp_width, dp_height,
babl_format ("Y u32"));
/* find the optimal path of pixels from (x1, y1) to (x2, y2) */
find_optimal_path (iscissors->gradient_map, dp_buf,
x1, y1, x2, y2, xs, ys);
/* get a list of the pixels in the optimal path */
segment->points = plot_pixels (dp_buf, x1, y1, xs, ys, xe, ye);
gimp_temp_buf_unref (dp_buf);
}
else if ((x2 - x1) == 0)
{
/* If the bounding box has no width */
/* plot a vertical line */
gint y = ys;
gint dir = (ys > ye) ? -1 : 1;
segment->points = g_ptr_array_new ();
while (y != ye)
{
g_ptr_array_add (segment->points, GINT_TO_POINTER ((y << 16) + xs));
y += dir;
}
}
else if ((y2 - y1) == 0)
{
/* If the bounding box has no height */
/* plot a horizontal line */
gint x = xs;
gint dir = (xs > xe) ? -1 : 1;
segment->points = g_ptr_array_new ();
while (x != xe)
{
g_ptr_array_add (segment->points, GINT_TO_POINTER ((ys << 16) + x));
x += dir;
}
1997-11-25 06:05:25 +08:00
}
}
/* badly need to get a replacement - this is _way_ too expensive */
static gboolean
gradient_map_value (GeglBuffer *map,
gint x,
gint y,
guint8 *grad,
guint8 *dir)
{
const GeglRectangle *extents;
extents = gegl_buffer_get_extent (map);
if (x >= extents->x &&
y >= extents->y &&
x < extents->width &&
y < extents->height)
{
guint8 sample[2];
gegl_buffer_sample (map, x, y, NULL, sample, NULL,
GEGL_SAMPLER_NEAREST, GEGL_ABYSS_NONE);
*grad = sample[0];
*dir = sample[1];
return TRUE;
}
1997-11-25 06:05:25 +08:00
return FALSE;
1997-11-25 06:05:25 +08:00
}
static gint
calculate_link (GeglBuffer *gradient_map,
gint x,
gint y,
guint32 pixel,
gint link)
1997-11-25 06:05:25 +08:00
{
gint value = 0;
guint8 grad1, dir1, grad2, dir2;
if (! gradient_map_value (gradient_map, x, y, &grad1, &dir1))
{
grad1 = 0;
dir1 = 255;
}
/* Convert the gradient into a cost: large gradients are good, and
* so have low cost. */
grad1 = 255 - grad1;
/* calculate the contribution of the gradient magnitude */
if (link > 1)
build display/ before tools/. 2001-11-08 Michael Natterer <mitch@gimp.org> * app/Makefile.am: build display/ before tools/. * app/devices.c: devices_check_change(): added all events which have a GdkDevice pointer. * app/gimpprogress.c: include "display-types.h" instead of "core-types.h". * app/core/Makefile.am * app/core/gimpdrawable-bucket-fill.[ch]: new files: the bucket_fill stuff taken from tools/gimpbucketfilltool.[ch]. * app/core/core-types.h: added "BucketFillMode". * app/core/gimpimage-mask-select.[ch]: cleanup. * app/core/gimpmarshal.list: added more marshallers for GimpTool's new signal signatures. * app/core/gimpmarshal.[ch]: regenerated. * app/display/Makefile.am * app/display/gimpdisplayshell-dnd.[ch] * app/display/gimpdisplayshell-layer-select.[ch]: new files: the canvas drop callbacks from gimpdisplayshell-callbacks.[ch] and the stuff formerly knows as gui/layer-select.[ch]. * app/display/gimpdisplay.h: don't include "gui/gui-types.h". * app/display/gximage.c: include "display-types.h". * app/display/gimpdisplay-foreach.c * app/display/gimpdisplayshell.[ch]: call gdsplay_delete(), don't destroy the shell widget. * app/gui/Makefile.am * app/gui/layer-select.[ch]: removed. * app/gui/gradients-commands.c: fixed "Save as POV" fprintf()s. * app/gui/preferences-dialog.c: removed the layer_select stuff because it is useless with the new preview system. * app/gui/tool-options-dialog.c: send the correct data to the close_callback. * app/gui/tools-commands.c: changed to follow the new gimp_tool_initialize() semantics (see below). Tool & canvas event handling chainsawing: * app/tools/tools-types.h: new struct GimpCoords which contains x, y, pressure, tilt etc. * app/display/gimpdisplayshell-callbacks.[ch]: added utility functions which transparently retreive the current event's GimpCoords or take it from the device directly if the event has none. Pass GimpCoords _in_image_coordinates_ to all tool functions. Most important: don't pass GdkEvents and display coordinates to tools any more. * app/tools/gimptool.[ch]: changed virtual functions to take GimpCoords, time and state separately instead of GdkEvents. * app/tools/gimpbezierselecttool.c * app/tools/gimpblendtool.c * app/tools/gimpbucketfilltool.[ch] * app/tools/gimpbycolorselecttool.c * app/tools/gimpclonetool.c * app/tools/gimpcolorpickertool.c * app/tools/gimpconvolvetool.c * app/tools/gimpcroptool.[ch] * app/tools/gimpcurvestool.c * app/tools/gimpdodgeburntool.c * app/tools/gimpdrawtool.c * app/tools/gimpeditselectiontool.[ch] * app/tools/gimperasertool.c * app/tools/gimpfliptool.c * app/tools/gimpfreeselecttool.[ch] * app/tools/gimpfuzzyselecttool.c * app/tools/gimpinktool.c * app/tools/gimpiscissorstool.c * app/tools/gimpmagnifytool.c * app/tools/gimpmeasuretool.c * app/tools/gimpmovetool.c * app/tools/gimppainttool.c * app/tools/gimppathtool.[ch] * app/tools/gimprectselecttool.c * app/tools/gimprotatetool.c * app/tools/gimpselectiontool.[ch] * app/tools/gimpsmudgetool.c * app/tools/gimptexttool.c * app/tools/gimptransformtool.[ch] * app/tools/path_tool.[ch] * app/tools/selection_options.c: tons and tons of changes: - changed to use the new virtual function parameters. - removed zillions of gdisplay_untransform_coords(). - get the active drawable's offsets manually in many cases. (questionable, but IMHO ok because it's obvious and not simply a "TRUE" passed to some function) - reordered some functions to be consistent across tools. - some tools had to be changed to work on image coords, not display ones (esp. crop). - fixed strange rotate tool behaviour which should be backported to stable. - some stuff i came across. - indentation and other paranoia. - rounding of coordinated may be broken in some tools. - new bugs guaranteed. * app/tools/tool_manager.[ch]: new semantic of tool_manager_initialize_active() (looked at the places where it was used from and put common code together). Should be a bit better now :) * app/tools/gimpblendtool.c * app/tools/transform_options.c: use the new GTK+ feature that a widget (toggle button) can be a frame's title for this tools' tool options. * app/widgets/widgets-types.h: stuff. * themes/Default/gtkrc: s/GtkDialog/GimpDialog/. * tools/pdbgen/Makefile.am: don't scan tools/gimpbucketfilltool.h any more. * tools/pdbgen/enums.pl: regenerated. * tools/pdbgen/pdb/tools.pdb: changed bucket_fill wrapper. * app/pdb/tools_cmds.c: regenerated.
2001-11-09 03:14:51 +08:00
value += diagonal_weight[grad1] * OMEGA_G;
1997-11-25 06:05:25 +08:00
else
value += grad1 * OMEGA_G;
/* calculate the contribution of the gradient direction */
x += (gint8)(pixel & 0xff);
y += (gint8)((pixel & 0xff00) >> 8);
if (! gradient_map_value (gradient_map, x, y, &grad2, &dir2))
{
grad2 = 0;
dir2 = 255;
}
value +=
(direction_value[dir1][link] + direction_value[dir2][link]) * OMEGA_D;
return value;
}
1997-11-25 06:05:25 +08:00
static GPtrArray *
plot_pixels (GimpTempBuf *dp_buf,
gint x1,
gint y1,
gint xs,
gint ys,
gint xe,
gint ye)
{
gint x, y;
guint32 coords;
gint link;
gint width = gimp_temp_buf_get_width (dp_buf);
guint *data;
GPtrArray *list;
1997-11-25 06:05:25 +08:00
/* Start the data pointer at the correct location */
data = (guint *) gimp_temp_buf_get_data (dp_buf) + (ye - y1) * width + (xe - x1);
1997-11-25 06:05:25 +08:00
x = xe;
y = ye;
1997-11-25 06:05:25 +08:00
list = g_ptr_array_new ();
1997-11-25 06:05:25 +08:00
while (TRUE)
{
coords = (y << 16) + x;
g_ptr_array_add (list, GINT_TO_POINTER (coords));
1997-11-25 06:05:25 +08:00
link = PIXEL_DIR (*data);
if (link == SEED_POINT)
return list;
1997-11-25 06:05:25 +08:00
build display/ before tools/. 2001-11-08 Michael Natterer <mitch@gimp.org> * app/Makefile.am: build display/ before tools/. * app/devices.c: devices_check_change(): added all events which have a GdkDevice pointer. * app/gimpprogress.c: include "display-types.h" instead of "core-types.h". * app/core/Makefile.am * app/core/gimpdrawable-bucket-fill.[ch]: new files: the bucket_fill stuff taken from tools/gimpbucketfilltool.[ch]. * app/core/core-types.h: added "BucketFillMode". * app/core/gimpimage-mask-select.[ch]: cleanup. * app/core/gimpmarshal.list: added more marshallers for GimpTool's new signal signatures. * app/core/gimpmarshal.[ch]: regenerated. * app/display/Makefile.am * app/display/gimpdisplayshell-dnd.[ch] * app/display/gimpdisplayshell-layer-select.[ch]: new files: the canvas drop callbacks from gimpdisplayshell-callbacks.[ch] and the stuff formerly knows as gui/layer-select.[ch]. * app/display/gimpdisplay.h: don't include "gui/gui-types.h". * app/display/gximage.c: include "display-types.h". * app/display/gimpdisplay-foreach.c * app/display/gimpdisplayshell.[ch]: call gdsplay_delete(), don't destroy the shell widget. * app/gui/Makefile.am * app/gui/layer-select.[ch]: removed. * app/gui/gradients-commands.c: fixed "Save as POV" fprintf()s. * app/gui/preferences-dialog.c: removed the layer_select stuff because it is useless with the new preview system. * app/gui/tool-options-dialog.c: send the correct data to the close_callback. * app/gui/tools-commands.c: changed to follow the new gimp_tool_initialize() semantics (see below). Tool & canvas event handling chainsawing: * app/tools/tools-types.h: new struct GimpCoords which contains x, y, pressure, tilt etc. * app/display/gimpdisplayshell-callbacks.[ch]: added utility functions which transparently retreive the current event's GimpCoords or take it from the device directly if the event has none. Pass GimpCoords _in_image_coordinates_ to all tool functions. Most important: don't pass GdkEvents and display coordinates to tools any more. * app/tools/gimptool.[ch]: changed virtual functions to take GimpCoords, time and state separately instead of GdkEvents. * app/tools/gimpbezierselecttool.c * app/tools/gimpblendtool.c * app/tools/gimpbucketfilltool.[ch] * app/tools/gimpbycolorselecttool.c * app/tools/gimpclonetool.c * app/tools/gimpcolorpickertool.c * app/tools/gimpconvolvetool.c * app/tools/gimpcroptool.[ch] * app/tools/gimpcurvestool.c * app/tools/gimpdodgeburntool.c * app/tools/gimpdrawtool.c * app/tools/gimpeditselectiontool.[ch] * app/tools/gimperasertool.c * app/tools/gimpfliptool.c * app/tools/gimpfreeselecttool.[ch] * app/tools/gimpfuzzyselecttool.c * app/tools/gimpinktool.c * app/tools/gimpiscissorstool.c * app/tools/gimpmagnifytool.c * app/tools/gimpmeasuretool.c * app/tools/gimpmovetool.c * app/tools/gimppainttool.c * app/tools/gimppathtool.[ch] * app/tools/gimprectselecttool.c * app/tools/gimprotatetool.c * app/tools/gimpselectiontool.[ch] * app/tools/gimpsmudgetool.c * app/tools/gimptexttool.c * app/tools/gimptransformtool.[ch] * app/tools/path_tool.[ch] * app/tools/selection_options.c: tons and tons of changes: - changed to use the new virtual function parameters. - removed zillions of gdisplay_untransform_coords(). - get the active drawable's offsets manually in many cases. (questionable, but IMHO ok because it's obvious and not simply a "TRUE" passed to some function) - reordered some functions to be consistent across tools. - some tools had to be changed to work on image coords, not display ones (esp. crop). - fixed strange rotate tool behaviour which should be backported to stable. - some stuff i came across. - indentation and other paranoia. - rounding of coordinated may be broken in some tools. - new bugs guaranteed. * app/tools/tool_manager.[ch]: new semantic of tool_manager_initialize_active() (looked at the places where it was used from and put common code together). Should be a bit better now :) * app/tools/gimpblendtool.c * app/tools/transform_options.c: use the new GTK+ feature that a widget (toggle button) can be a frame's title for this tools' tool options. * app/widgets/widgets-types.h: stuff. * themes/Default/gtkrc: s/GtkDialog/GimpDialog/. * tools/pdbgen/Makefile.am: don't scan tools/gimpbucketfilltool.h any more. * tools/pdbgen/enums.pl: regenerated. * tools/pdbgen/pdb/tools.pdb: changed bucket_fill wrapper. * app/pdb/tools_cmds.c: regenerated.
2001-11-09 03:14:51 +08:00
x += move[link][0];
y += move[link][1];
data += move[link][1] * width + move[link][0];
}
1997-11-25 06:05:25 +08:00
/* won't get here */
return NULL;
}
1997-11-25 06:05:25 +08:00
#define PACK(x, y) ((((y) & 0xff) << 8) | ((x) & 0xff))
#define OFFSET(pixel) ((gint8)((pixel) & 0xff) + \
((gint8)(((pixel) & 0xff00) >> 8)) * \
gimp_temp_buf_get_width (dp_buf))
1997-11-25 06:05:25 +08:00
static void
find_optimal_path (GeglBuffer *gradient_map,
2012-04-09 02:25:49 +08:00
GimpTempBuf *dp_buf,
gint x1,
gint y1,
gint x2,
gint y2,
gint xs,
gint ys)
{
gint i, j, k;
gint x, y;
gint link;
gint linkdir;
gint dirx, diry;
gint min_cost;
gint new_cost;
gint offset;
build display/ before tools/. 2001-11-08 Michael Natterer <mitch@gimp.org> * app/Makefile.am: build display/ before tools/. * app/devices.c: devices_check_change(): added all events which have a GdkDevice pointer. * app/gimpprogress.c: include "display-types.h" instead of "core-types.h". * app/core/Makefile.am * app/core/gimpdrawable-bucket-fill.[ch]: new files: the bucket_fill stuff taken from tools/gimpbucketfilltool.[ch]. * app/core/core-types.h: added "BucketFillMode". * app/core/gimpimage-mask-select.[ch]: cleanup. * app/core/gimpmarshal.list: added more marshallers for GimpTool's new signal signatures. * app/core/gimpmarshal.[ch]: regenerated. * app/display/Makefile.am * app/display/gimpdisplayshell-dnd.[ch] * app/display/gimpdisplayshell-layer-select.[ch]: new files: the canvas drop callbacks from gimpdisplayshell-callbacks.[ch] and the stuff formerly knows as gui/layer-select.[ch]. * app/display/gimpdisplay.h: don't include "gui/gui-types.h". * app/display/gximage.c: include "display-types.h". * app/display/gimpdisplay-foreach.c * app/display/gimpdisplayshell.[ch]: call gdsplay_delete(), don't destroy the shell widget. * app/gui/Makefile.am * app/gui/layer-select.[ch]: removed. * app/gui/gradients-commands.c: fixed "Save as POV" fprintf()s. * app/gui/preferences-dialog.c: removed the layer_select stuff because it is useless with the new preview system. * app/gui/tool-options-dialog.c: send the correct data to the close_callback. * app/gui/tools-commands.c: changed to follow the new gimp_tool_initialize() semantics (see below). Tool & canvas event handling chainsawing: * app/tools/tools-types.h: new struct GimpCoords which contains x, y, pressure, tilt etc. * app/display/gimpdisplayshell-callbacks.[ch]: added utility functions which transparently retreive the current event's GimpCoords or take it from the device directly if the event has none. Pass GimpCoords _in_image_coordinates_ to all tool functions. Most important: don't pass GdkEvents and display coordinates to tools any more. * app/tools/gimptool.[ch]: changed virtual functions to take GimpCoords, time and state separately instead of GdkEvents. * app/tools/gimpbezierselecttool.c * app/tools/gimpblendtool.c * app/tools/gimpbucketfilltool.[ch] * app/tools/gimpbycolorselecttool.c * app/tools/gimpclonetool.c * app/tools/gimpcolorpickertool.c * app/tools/gimpconvolvetool.c * app/tools/gimpcroptool.[ch] * app/tools/gimpcurvestool.c * app/tools/gimpdodgeburntool.c * app/tools/gimpdrawtool.c * app/tools/gimpeditselectiontool.[ch] * app/tools/gimperasertool.c * app/tools/gimpfliptool.c * app/tools/gimpfreeselecttool.[ch] * app/tools/gimpfuzzyselecttool.c * app/tools/gimpinktool.c * app/tools/gimpiscissorstool.c * app/tools/gimpmagnifytool.c * app/tools/gimpmeasuretool.c * app/tools/gimpmovetool.c * app/tools/gimppainttool.c * app/tools/gimppathtool.[ch] * app/tools/gimprectselecttool.c * app/tools/gimprotatetool.c * app/tools/gimpselectiontool.[ch] * app/tools/gimpsmudgetool.c * app/tools/gimptexttool.c * app/tools/gimptransformtool.[ch] * app/tools/path_tool.[ch] * app/tools/selection_options.c: tons and tons of changes: - changed to use the new virtual function parameters. - removed zillions of gdisplay_untransform_coords(). - get the active drawable's offsets manually in many cases. (questionable, but IMHO ok because it's obvious and not simply a "TRUE" passed to some function) - reordered some functions to be consistent across tools. - some tools had to be changed to work on image coords, not display ones (esp. crop). - fixed strange rotate tool behaviour which should be backported to stable. - some stuff i came across. - indentation and other paranoia. - rounding of coordinated may be broken in some tools. - new bugs guaranteed. * app/tools/tool_manager.[ch]: new semantic of tool_manager_initialize_active() (looked at the places where it was used from and put common code together). Should be a bit better now :) * app/tools/gimpblendtool.c * app/tools/transform_options.c: use the new GTK+ feature that a widget (toggle button) can be a frame's title for this tools' tool options. * app/widgets/widgets-types.h: stuff. * themes/Default/gtkrc: s/GtkDialog/GimpDialog/. * tools/pdbgen/Makefile.am: don't scan tools/gimpbucketfilltool.h any more. * tools/pdbgen/enums.pl: regenerated. * tools/pdbgen/pdb/tools.pdb: changed bucket_fill wrapper. * app/pdb/tools_cmds.c: regenerated.
2001-11-09 03:14:51 +08:00
gint cum_cost[8];
gint link_cost[8];
gint pixel_cost[8];
guint32 pixel[8];
guint32 *data;
guint32 *d;
gint dp_buf_width = gimp_temp_buf_get_width (dp_buf);
gint dp_buf_height = gimp_temp_buf_get_height (dp_buf);
/* initialize the dynamic programming buffer */
data = (guint32 *) gimp_temp_buf_data_clear (dp_buf);
/* what directions are we filling the array in according to? */
dirx = (xs - x1 == 0) ? 1 : -1;
diry = (ys - y1 == 0) ? 1 : -1;
linkdir = (dirx * diry);
y = ys;
for (i = 0; i < dp_buf_height; i++)
1997-11-25 06:05:25 +08:00
{
x = xs;
1997-11-25 06:05:25 +08:00
d = data + (y-y1) * dp_buf_width + (x-x1);
1997-11-25 06:05:25 +08:00
for (j = 0; j < dp_buf_width; j++)
{
min_cost = G_MAXINT;
2013-01-27 23:52:38 +08:00
/* pixel[] array encodes how to get to a neighbour, if possible.
* 0 means no connection (eg edge).
* Rest packed as bottom two bytes: y offset then x offset.
* Initially, we assume we can't get anywhere.
*/
for (k = 0; k < 8; k++)
pixel[k] = 0;
/* Find the valid neighboring pixels */
/* the previous pixel */
if (j)
pixel[((dirx == 1) ? 4 : 0)] = PACK (-dirx, 0);
/* the previous row of pixels */
if (i)
{
pixel[((diry == 1) ? 5 : 1)] = PACK (0, -diry);
link = (linkdir == 1) ? 3 : 2;
if (j)
pixel[((diry == 1) ? (link + 4) : link)] = PACK (-dirx, -diry);
link = (linkdir == 1) ? 2 : 3;
if (j != dp_buf_width - 1)
pixel[((diry == 1) ? (link + 4) : link)] = PACK (dirx, -diry);
}
/* find the minimum cost of going through each neighbor to reach the
* seed point...
*/
link = -1;
for (k = 0; k < 8; k ++)
if (pixel[k])
{
link_cost[k] = calculate_link (gradient_map,
build display/ before tools/. 2001-11-08 Michael Natterer <mitch@gimp.org> * app/Makefile.am: build display/ before tools/. * app/devices.c: devices_check_change(): added all events which have a GdkDevice pointer. * app/gimpprogress.c: include "display-types.h" instead of "core-types.h". * app/core/Makefile.am * app/core/gimpdrawable-bucket-fill.[ch]: new files: the bucket_fill stuff taken from tools/gimpbucketfilltool.[ch]. * app/core/core-types.h: added "BucketFillMode". * app/core/gimpimage-mask-select.[ch]: cleanup. * app/core/gimpmarshal.list: added more marshallers for GimpTool's new signal signatures. * app/core/gimpmarshal.[ch]: regenerated. * app/display/Makefile.am * app/display/gimpdisplayshell-dnd.[ch] * app/display/gimpdisplayshell-layer-select.[ch]: new files: the canvas drop callbacks from gimpdisplayshell-callbacks.[ch] and the stuff formerly knows as gui/layer-select.[ch]. * app/display/gimpdisplay.h: don't include "gui/gui-types.h". * app/display/gximage.c: include "display-types.h". * app/display/gimpdisplay-foreach.c * app/display/gimpdisplayshell.[ch]: call gdsplay_delete(), don't destroy the shell widget. * app/gui/Makefile.am * app/gui/layer-select.[ch]: removed. * app/gui/gradients-commands.c: fixed "Save as POV" fprintf()s. * app/gui/preferences-dialog.c: removed the layer_select stuff because it is useless with the new preview system. * app/gui/tool-options-dialog.c: send the correct data to the close_callback. * app/gui/tools-commands.c: changed to follow the new gimp_tool_initialize() semantics (see below). Tool & canvas event handling chainsawing: * app/tools/tools-types.h: new struct GimpCoords which contains x, y, pressure, tilt etc. * app/display/gimpdisplayshell-callbacks.[ch]: added utility functions which transparently retreive the current event's GimpCoords or take it from the device directly if the event has none. Pass GimpCoords _in_image_coordinates_ to all tool functions. Most important: don't pass GdkEvents and display coordinates to tools any more. * app/tools/gimptool.[ch]: changed virtual functions to take GimpCoords, time and state separately instead of GdkEvents. * app/tools/gimpbezierselecttool.c * app/tools/gimpblendtool.c * app/tools/gimpbucketfilltool.[ch] * app/tools/gimpbycolorselecttool.c * app/tools/gimpclonetool.c * app/tools/gimpcolorpickertool.c * app/tools/gimpconvolvetool.c * app/tools/gimpcroptool.[ch] * app/tools/gimpcurvestool.c * app/tools/gimpdodgeburntool.c * app/tools/gimpdrawtool.c * app/tools/gimpeditselectiontool.[ch] * app/tools/gimperasertool.c * app/tools/gimpfliptool.c * app/tools/gimpfreeselecttool.[ch] * app/tools/gimpfuzzyselecttool.c * app/tools/gimpinktool.c * app/tools/gimpiscissorstool.c * app/tools/gimpmagnifytool.c * app/tools/gimpmeasuretool.c * app/tools/gimpmovetool.c * app/tools/gimppainttool.c * app/tools/gimppathtool.[ch] * app/tools/gimprectselecttool.c * app/tools/gimprotatetool.c * app/tools/gimpselectiontool.[ch] * app/tools/gimpsmudgetool.c * app/tools/gimptexttool.c * app/tools/gimptransformtool.[ch] * app/tools/path_tool.[ch] * app/tools/selection_options.c: tons and tons of changes: - changed to use the new virtual function parameters. - removed zillions of gdisplay_untransform_coords(). - get the active drawable's offsets manually in many cases. (questionable, but IMHO ok because it's obvious and not simply a "TRUE" passed to some function) - reordered some functions to be consistent across tools. - some tools had to be changed to work on image coords, not display ones (esp. crop). - fixed strange rotate tool behaviour which should be backported to stable. - some stuff i came across. - indentation and other paranoia. - rounding of coordinated may be broken in some tools. - new bugs guaranteed. * app/tools/tool_manager.[ch]: new semantic of tool_manager_initialize_active() (looked at the places where it was used from and put common code together). Should be a bit better now :) * app/tools/gimpblendtool.c * app/tools/transform_options.c: use the new GTK+ feature that a widget (toggle button) can be a frame's title for this tools' tool options. * app/widgets/widgets-types.h: stuff. * themes/Default/gtkrc: s/GtkDialog/GimpDialog/. * tools/pdbgen/Makefile.am: don't scan tools/gimpbucketfilltool.h any more. * tools/pdbgen/enums.pl: regenerated. * tools/pdbgen/pdb/tools.pdb: changed bucket_fill wrapper. * app/pdb/tools_cmds.c: regenerated.
2001-11-09 03:14:51 +08:00
xs + j*dirx, ys + i*diry,
pixel [k],
((k > 3) ? k - 4 : k));
offset = OFFSET (pixel [k]);
pixel_cost[k] = PIXEL_COST (d[offset]);
cum_cost[k] = pixel_cost[k] + link_cost[k];
if (cum_cost[k] < min_cost)
{
min_cost = cum_cost[k];
link = k;
}
}
/* If anything can be done... */
if (link >= 0)
{
/* set the cumulative cost of this pixel and the new direction
*/
*d = (cum_cost[link] << 8) + link;
/* possibly change the links from the other pixels to this pixel...
* these changes occur if a neighboring pixel will receive a lower
* cumulative cost by going through this pixel.
*/
for (k = 0; k < 8; k ++)
if (pixel[k] && k != link)
{
/* if the cumulative cost at the neighbor is greater than
* the cost through the link to the current pixel, change the
* neighbor's link to point to the current pixel.
*/
new_cost = link_cost[k] + cum_cost[link];
if (pixel_cost[k] > new_cost)
{
/* reverse the link direction /--------------------\ */
offset = OFFSET (pixel[k]);
d[offset] = (new_cost << 8) + ((k > 3) ? k - 4 : k + 4);
}
}
}
/* Set the seed point */
else if (!i && !j)
{
*d = SEED_POINT;
}
/* increment the data pointer and the x counter */
d += dirx;
x += dirx;
}
1997-11-25 06:05:25 +08:00
/* increment the y counter */
y += diry;
1997-11-25 06:05:25 +08:00
}
}
static GeglBuffer *
gradient_map_new (GimpPickable *pickable)
{
GeglBuffer *buffer;
GeglTileHandler *handler;
1997-11-25 06:05:25 +08:00
buffer = gimp_pickable_get_buffer (pickable);
buffer = gegl_buffer_new (GEGL_RECTANGLE (0, 0,
gegl_buffer_get_width (buffer),
gegl_buffer_get_height (buffer)),
babl_format_n (babl_type ("u8"), 2));
1997-11-25 06:05:25 +08:00
handler = gimp_tile_handler_iscissors_new (pickable);
1997-11-25 06:05:25 +08:00
gimp_tile_handler_validate_assign (GIMP_TILE_HANDLER_VALIDATE (handler),
buffer);
gimp_tile_handler_validate_invalidate (GIMP_TILE_HANDLER_VALIDATE (handler),
0, 0,
gegl_buffer_get_width (buffer),
gegl_buffer_get_height (buffer));
g_object_unref (handler);
return buffer;
1997-11-25 06:05:25 +08:00
}
static void
find_max_gradient (GimpIscissorsTool *iscissors,
GimpPickable *pickable,
gint *x,
gint *y)
1997-11-25 06:05:25 +08:00
{
GeglBufferIterator *iter;
GeglRectangle *roi;
gint width;
gint height;
gint radius;
gint cx, cy;
gint x1, y1, x2, y2;
gfloat max_gradient;
/* Initialise the gradient map buffer for this pickable if we don't
* already have one.
*/
if (! iscissors->gradient_map)
iscissors->gradient_map = gradient_map_new (pickable);
width = gegl_buffer_get_width (iscissors->gradient_map);
height = gegl_buffer_get_height (iscissors->gradient_map);
radius = GRADIENT_SEARCH >> 1;
/* calculate the extent of the search */
cx = CLAMP (*x, 0, width);
cy = CLAMP (*y, 0, height);
x1 = CLAMP (cx - radius, 0, width);
y1 = CLAMP (cy - radius, 0, height);
x2 = CLAMP (cx + radius, 0, width);
y2 = CLAMP (cy + radius, 0, height);
/* calculate the factor to multiply the distance from the cursor by */
max_gradient = 0;
*x = cx;
*y = cy;
iter = gegl_buffer_iterator_new (iscissors->gradient_map,
GEGL_RECTANGLE (x1, y1, x2 - x1, y2 - y1),
0, NULL,
GEGL_ACCESS_READ, GEGL_ABYSS_NONE);
roi = &iter->roi[0];
while (gegl_buffer_iterator_next (iter))
1997-11-25 06:05:25 +08:00
{
guint8 *data = iter->data[0];
gint endx = roi->x + roi->width;
gint endy = roi->y + roi->height;
gint i, j;
for (i = roi->y; i < endy; i++)
{
const guint8 *gradient = data + 2 * roi->width * (i - roi->y);
for (j = roi->x; j < endx; j++)
{
gfloat g = *gradient;
gradient += COST_WIDTH;
g *= distance_weights [(i - y1) * GRADIENT_SEARCH + (j - x1)];
if (g > max_gradient)
{
max_gradient = g;
*x = j;
*y = i;
}
}
}
1997-11-25 06:05:25 +08:00
}
}
static ISegment *
isegment_new (gint x1,
gint y1,
gint x2,
gint y2)
{
ISegment *segment = g_slice_new0 (ISegment);
segment->x1 = x1;
segment->y1 = y1;
segment->x2 = x2;
segment->y2 = y2;
return segment;
}
static ISegment *
isegment_copy (ISegment *segment)
{
ISegment *copy = isegment_new (segment->x1,
segment->y1,
segment->x2,
segment->y2);
if (segment->points)
{
gint i;
copy->points = g_ptr_array_sized_new (segment->points->len);
for (i = 0; i < segment->points->len; i++)
{
gpointer value = g_ptr_array_index (segment->points, i);
g_ptr_array_add (copy->points, value);
}
}
return copy;
}
static void
isegment_free (ISegment *segment)
{
if (segment->points)
g_ptr_array_free (segment->points, TRUE);
g_slice_free (ISegment, segment);
}
static ICurve *
icurve_new (void)
{
ICurve *curve = g_slice_new0 (ICurve);
curve->segments = g_queue_new ();
curve->first_point = TRUE;
return curve;
}
static ICurve *
icurve_copy (ICurve *curve)
{
ICurve *copy = icurve_new ();
GList *link;
for (link = g_queue_peek_head_link (curve->segments);
link;
link = g_list_next (link))
{
g_queue_push_tail (copy->segments, isegment_copy (link->data));
}
copy->first_point = curve->first_point;
copy->closed = curve->closed;
return copy;
}
static void
icurve_clear (ICurve *curve)
{
while (! g_queue_is_empty (curve->segments))
isegment_free (g_queue_pop_head (curve->segments));
curve->first_point = TRUE;
curve->closed = FALSE;
}
static void
icurve_free (ICurve *curve)
{
g_queue_free_full (curve->segments, (GDestroyNotify) isegment_free);
g_slice_free (ICurve, curve);
}
static ISegment *
icurve_append_segment (ICurve *curve,
gint x1,
gint y1,
gint x2,
gint y2)
{
ISegment *segment = isegment_new (x1, y1, x2, y2);
g_queue_push_tail (curve->segments, segment);
return segment;
}
static ISegment *
icurve_insert_segment (ICurve *curve,
GList *sibling,
gint x1,
gint y1,
gint x2,
gint y2)
{
ISegment *segment = sibling->data;
ISegment *new_segment;
new_segment = isegment_new (x1, y1, x2, y2);
segment->x2 = x1;
segment->y2 = y1;
g_queue_insert_after (curve->segments, sibling, new_segment);
return new_segment;
}
static void
icurve_delete_segment (ICurve *curve,
ISegment *segment)
{
GList *link = g_queue_find (curve->segments, segment);
ISegment *next_segment = NULL;
if (link->next)
next_segment = link->next->data;
else if (curve->closed)
next_segment = g_queue_peek_head (curve->segments);
if (next_segment)
{
next_segment->x1 = segment->x1;
next_segment->y1 = segment->y1;
}
g_queue_remove (curve->segments, segment);
isegment_free (segment);
}
static void
icurve_close (ICurve *curve)
{
ISegment *first = g_queue_peek_head (curve->segments);
ISegment *last = g_queue_peek_tail (curve->segments);
last->x2 = first->x1;
last->y2 = first->y1;
curve->closed = TRUE;
}
static GimpScanConvert *
icurve_create_scan_convert (ICurve *curve)
{
GimpScanConvert *sc;
GList *list;
GimpVector2 *points;
guint n_total_points = 0;
sc = gimp_scan_convert_new ();
for (list = g_queue_peek_tail_link (curve->segments);
list;
list = g_list_previous (list))
{
ISegment *segment = list->data;
n_total_points += segment->points->len;
}
points = g_new (GimpVector2, n_total_points);
n_total_points = 0;
/* go over the segments in reverse order, adding the points we have */
for (list = g_queue_peek_tail_link (curve->segments);
list;
list = g_list_previous (list))
{
ISegment *segment = list->data;
guint n_points;
gint i;
n_points = segment->points->len;
for (i = 0; i < n_points; i++)
{
guint32 packed = GPOINTER_TO_INT (g_ptr_array_index (segment->points,
i));
points[n_total_points + i].x = packed & 0x0000ffff;
points[n_total_points + i].y = packed >> 16;
}
n_total_points += n_points;
}
gimp_scan_convert_add_polyline (sc, n_total_points, points, TRUE);
g_free (points);
return sc;
}