diff --git a/ChangeLog b/ChangeLog index 5c8e67be33..e9d13942f7 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,18 @@ +2004-08-22 Sven Neumann + + * app/tools/Makefile.am + * app/tools/tools-utils.[ch]: added gimp_tool_motion_constrain(), + + * app/paint/gimppaintcore.[ch]: removed gimp_paint_core_constrain(). + + * app/tools/gimppainttool.c: changed accordingly. + + * app/tools/gimpblendtool.[ch]: use gimp_tool_motion_constrain() + instead of duplicating that functionality. + + * app/tools/gimpmeasuretool.c: use gimp_tool_motion_constrain() + instead of implementing completely different constraints. + 2004-08-22 Simon Budig * app/vectors/gimpbezierstroke.c: Implemented the ellipse basic diff --git a/app/paint/gimppaintcore.c b/app/paint/gimppaintcore.c index 0d86a80590..c9fdddd90a 100644 --- a/app/paint/gimppaintcore.c +++ b/app/paint/gimppaintcore.c @@ -452,67 +452,6 @@ gimp_paint_core_cleanup (GimpPaintCore *core) } } -/** - * gimp_paint_core_constrain_helper: - * @dx: the (fixed) delta-x - * @dy: a suggested delta-y - * - * Returns an adjusted dy' near dy such that the slope (dx,dy') is a - * multiple of 15 degrees. - **/ -static gdouble -gimp_paint_core_constrain_helper (gdouble dx, - gdouble dy) -{ - static gdouble slope[4] = { 0, 0.26795, 0.57735, 1 }; - static gdouble divider[3] = { 0.13165, 0.41421, 0.76732 }; - gint i; - - if (dy < 0) - return - gimp_paint_core_constrain_helper (dx,-dy); - dx = fabs (dx); - for (i = 0; i < 3; i ++) - if (dy < dx * divider[i]) - break; - dy = dx * slope[i]; - return dy; -} - -/** - * gimp_paint_core_constrain: - * @core: the #GimpPaintCore. - * - * Restricts the (core->last_coords, core->cur_coords) vector to 15 - * degree steps, possibly changing core->cur_coords. - **/ -void -gimp_paint_core_constrain (GimpPaintCore *core) -{ - gdouble dx, dy; - - g_return_if_fail (GIMP_IS_PAINT_CORE (core)); - - dx = core->cur_coords.x - core->last_coords.x; - dy = core->cur_coords.y - core->last_coords.y; - - /* This algorithm changes only one of dx and dy, and does not try - * to constrain the resulting dx and dy to integers. This gives - * at least two benefits: - * 1. gimp_paint_core_constrain is idempotent, even if followed by - * a rounding operation. - * 2. For any two lines with the same starting-point and ideal - * 15-degree direction, the points plotted by - * gimp_paint_core_interpolate for the shorter line will always - * be a superset of those plotted for the longer line. - */ - if (fabs (dx) > fabs (dy)) - core->cur_coords.y = (core->last_coords.y + - gimp_paint_core_constrain_helper (dx,dy)); - else - core->cur_coords.x = (core->last_coords.x + - gimp_paint_core_constrain_helper (dy,dx)); -} - void gimp_paint_core_interpolate (GimpPaintCore *core, GimpDrawable *drawable, diff --git a/app/paint/gimppaintcore.h b/app/paint/gimppaintcore.h index 93f6d9794d..1dfbebda72 100644 --- a/app/paint/gimppaintcore.h +++ b/app/paint/gimppaintcore.h @@ -117,8 +117,6 @@ void gimp_paint_core_cancel (GimpPaintCore *core, GimpDrawable *drawable); void gimp_paint_core_cleanup (GimpPaintCore *core); -void gimp_paint_core_constrain (GimpPaintCore *core); - void gimp_paint_core_interpolate (GimpPaintCore *core, GimpDrawable *drawable, GimpPaintOptions *paint_options, diff --git a/app/tools/Makefile.am b/app/tools/Makefile.am index 9cfceaa5e4..577bdfd9c9 100644 --- a/app/tools/Makefile.am +++ b/app/tools/Makefile.am @@ -7,6 +7,8 @@ libapptools_a_sources = \ tools-types.h \ gimp-tools.c \ gimp-tools.h \ + tools-utils.c \ + tools-utils.h \ tool_manager.c \ tool_manager.h \ \ diff --git a/app/tools/gimpblendtool.c b/app/tools/gimpblendtool.c index f5ed4657c2..b1dc24589d 100644 --- a/app/tools/gimpblendtool.c +++ b/app/tools/gimpblendtool.c @@ -42,6 +42,7 @@ #include "gimpblendoptions.h" #include "gimpblendtool.h" #include "gimptoolcontrol.h" +#include "tools-utils.h" #include "gimp-intl.h" @@ -297,33 +298,8 @@ gimp_blend_tool_motion (GimpTool *tool, /* Restrict to multiples of 15 degrees if ctrl is pressed */ if (state & GDK_CONTROL_MASK) { - gint tangens2[6] = { 34, 106, 196, 334, 618, 1944 }; - gint cosinus[7] = { 256, 247, 222, 181, 128, 66, 0 }; - gint dx, dy, i, radius, frac; - - dx = blend_tool->endx - blend_tool->startx; - dy = blend_tool->endy - blend_tool->starty; - - if (dy) - { - radius = sqrt (SQR (dx) + SQR (dy)); - frac = abs ((dx << 8) / dy); - - for (i = 0; i < 6; i++) - { - if (frac < tangens2[i]) - break; - } - - dx = dx > 0 ? - (cosinus[6-i] * radius) >> 8 : - ((cosinus[6-i] * radius) >> 8); - - dy = dy > 0 ? - (cosinus[i] * radius) >> 8 : - ((cosinus[i] * radius) >> 8); - } - - blend_tool->endx = blend_tool->startx + dx; - blend_tool->endy = blend_tool->starty + dy; + gimp_tool_motion_constrain (blend_tool->startx, blend_tool->starty, + &blend_tool->endx, &blend_tool->endy); } gimp_tool_pop_status (tool); diff --git a/app/tools/gimpblendtool.h b/app/tools/gimpblendtool.h index bc9b2b4391..a0f532d764 100644 --- a/app/tools/gimpblendtool.h +++ b/app/tools/gimpblendtool.h @@ -38,10 +38,10 @@ struct _GimpBlendTool { GimpDrawTool parent_instance; - gint startx; /* starting x coord */ - gint starty; /* starting y coord */ - gint endx; /* ending x coord */ - gint endy; /* ending y coord */ + gdouble startx; /* starting x coord */ + gdouble starty; /* starting y coord */ + gdouble endx; /* ending x coord */ + gdouble endy; /* ending y coord */ }; struct _GimpBlendToolClass diff --git a/app/tools/gimpbrushtool.c b/app/tools/gimpbrushtool.c index 78db7e4e31..76188aeec6 100644 --- a/app/tools/gimpbrushtool.c +++ b/app/tools/gimpbrushtool.c @@ -53,6 +53,7 @@ #include "gimpcolorpickertool.h" #include "gimppainttool.h" #include "gimptoolcontrol.h" +#include "tools-utils.h" #include "gimp-intl.h" @@ -358,7 +359,8 @@ gimp_paint_tool_round_line (GimpPaintCore *core, /* Restrict to multiples of 15 degrees if ctrl is pressed */ if (state & GDK_CONTROL_MASK) - gimp_paint_core_constrain (core); + gimp_tool_motion_constrain (core->last_coords.x, core->last_coords.y, + &core->cur_coords.x, &core->cur_coords.y); } static void diff --git a/app/tools/gimpmeasuretool.c b/app/tools/gimpmeasuretool.c index 54ded911c8..54d53dfd9d 100644 --- a/app/tools/gimpmeasuretool.c +++ b/app/tools/gimpmeasuretool.c @@ -47,6 +47,7 @@ #include "gimpmeasureoptions.h" #include "gimpmeasuretool.h" #include "gimptoolcontrol.h" +#include "tools-utils.h" #include "gimp-intl.h" @@ -450,29 +451,15 @@ gimp_measure_tool_motion (GimpTool *tool, mtool->x[i] = ROUND (coords->x); mtool->y[i] = ROUND (coords->y); - /* restrict to horizontal/vertical movements if modifiers are pressed */ - if (state & GDK_MOD1_MASK) + if (state & GDK_CONTROL_MASK) { - if (state & GDK_CONTROL_MASK) - { - dx = mtool->x[i] - mtool->x[0]; - dy = mtool->y[i] - mtool->y[0]; + gdouble x = mtool->x[i]; + gdouble y = mtool->y[i]; - mtool->x[i] = mtool->x[0] + (dx > 0 ? - MAX (abs (dx), abs (dy)) : - - MAX (abs (dx), abs (dy))); - mtool->y[i] = mtool->y[0] + (dy > 0 ? - MAX (abs (dx), abs (dy)) : - - MAX (abs (dx), abs (dy))); - } - else - { - mtool->x[i] = mtool->x[0]; - } - } - else if (state & GDK_CONTROL_MASK) - { - mtool->y[i] = mtool->y[0]; + gimp_tool_motion_constrain (mtool->x[0], mtool->y[0], &x, &y); + + mtool->x[i] = ROUND (x); + mtool->y[i] = ROUND (y); } break; diff --git a/app/tools/gimppainttool.c b/app/tools/gimppainttool.c index 78db7e4e31..76188aeec6 100644 --- a/app/tools/gimppainttool.c +++ b/app/tools/gimppainttool.c @@ -53,6 +53,7 @@ #include "gimpcolorpickertool.h" #include "gimppainttool.h" #include "gimptoolcontrol.h" +#include "tools-utils.h" #include "gimp-intl.h" @@ -358,7 +359,8 @@ gimp_paint_tool_round_line (GimpPaintCore *core, /* Restrict to multiples of 15 degrees if ctrl is pressed */ if (state & GDK_CONTROL_MASK) - gimp_paint_core_constrain (core); + gimp_tool_motion_constrain (core->last_coords.x, core->last_coords.y, + &core->cur_coords.x, &core->cur_coords.y); } static void diff --git a/app/tools/tools-utils.c b/app/tools/tools-utils.c new file mode 100644 index 0000000000..a8c67808a0 --- /dev/null +++ b/app/tools/tools-utils.c @@ -0,0 +1,93 @@ +/* The GIMP -- an image manipulation program + * Copyright (C) 1995 Spencer Kimball and Peter Mattis + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + */ + +#include "config.h" + +#include + +#include "libgimpmath/gimpmath.h" + +#include "tool-utils.h" + + +/** + * gimp_tool_motion_constrain_helper: + * @dx: the (fixed) delta-x + * @dy: a suggested delta-y + * + * Returns an adjusted dy' near dy such that the slope (dx,dy') + * is a multiple of 15 degrees. + **/ +static gdouble +gimp_tool_motion_constrain_helper (gdouble dx, + gdouble dy) +{ + static const gdouble slope[4] = { 0, 0.26795, 0.57735, 1 }; + static const gdouble divider[3] = { 0.13165, 0.41421, 0.76732 }; + gint i; + + if (dy < 0) + return - gimp_tool_motion_constrain_helper (dx, -dy); + + dx = fabs (dx); + + for (i = 0; i < 3; i ++) + if (dy < dx * divider[i]) + break; + + dy = dx * slope[i]; + + return dy; +} + +/** + * gimp_tool_motion_constrain: + * @start_x: + * @start_y: + * @end_x: + * @end_y: + * + * Restricts the motion vector to 15 degree steps by changing the end + * point (if necessary). + **/ +void +gimp_tool_motion_constrain (gdouble start_x, + gdouble start_y, + gdouble *end_x, + gdouble *end_y) +{ + gdouble dx = *end_x - start_x; + gdouble dy = *end_y - start_y; + + /* This algorithm changes only one of dx and dy, and does not try + * to constrain the resulting dx and dy to integers. This gives + * at least two benefits: + * 1. gimp_tool_motion_constrain is idempotent, even if followed by + * a rounding operation. + * 2. For any two lines with the same starting-point and ideal + * 15-degree direction, the points plotted by + * gimp_paint_core_interpolate for the shorter line will always + * be a superset of those plotted for the longer line. + */ + + if (fabs (dx) > fabs (dy)) + *end_y = (start_y + gimp_tool_motion_constrain_helper (dx, dy)); + else + *end_x = (start_x + gimp_tool_motion_constrain_helper (dy, dx)); +} + diff --git a/app/tools/tools-utils.h b/app/tools/tools-utils.h new file mode 100644 index 0000000000..2279522284 --- /dev/null +++ b/app/tools/tools-utils.h @@ -0,0 +1,29 @@ +/* The GIMP -- an image manipulation program + * Copyright (C) 1995 Spencer Kimball and Peter Mattis + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + */ + +#ifndef __TOOLS_UTILS_H__ +#define __TOOLS_UTILS_H__ + + +void gimp_tool_motion_constrain (gdouble start_x, + gdouble start_y, + gdouble *end_x, + gdouble *end_y); + + +#endif /* __TOOLS_UTILS_H__ */ diff --git a/app/vectors/gimpvectors-import.c b/app/vectors/gimpvectors-import.c index cf025e4dbf..299a7750a2 100644 --- a/app/vectors/gimpvectors-import.c +++ b/app/vectors/gimpvectors-import.c @@ -7,11 +7,12 @@ * Some code here is based on code from librsvg that was originally * written by Raph Levien for Gill. * - * This SVG path importer implements a subset of SVG that is sufficient - * to parse path elements and to apply all defined transformations as - * described by the SVG specification: http://www.w3.org/TR/SVG/. - * It must handle the SVG files exported by GIMP but it is also supposed - * to be able to extract paths from foreign SVG documents. + * This SVG path importer implements a subset of SVG that is + * sufficient to parse path elements and basic shapes and to apply + * transformations as described by the SVG specification: + * http://www.w3.org/TR/SVG/. It must handle the SVG files exported + * by GIMP but it is also supposed to be able to extract paths and + * shapes from foreign SVG documents. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by