2006-12-10 05:33:38 +08:00
|
|
|
/* GIMP - The GNU Image Manipulation Program
|
1997-11-25 06:05:25 +08:00
|
|
|
* Copyright (C) 1995 Spencer Kimball and Peter Mattis
|
|
|
|
*
|
2009-01-18 06:28:01 +08:00
|
|
|
* 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
|
2009-01-18 06:28:01 +08:00
|
|
|
* 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
|
2009-01-18 06:28:01 +08:00
|
|
|
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
1997-11-25 06:05:25 +08:00
|
|
|
*/
|
2000-12-17 05:37:03 +08:00
|
|
|
|
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"
|
|
|
|
|
2010-11-10 21:20:33 +08:00
|
|
|
#include <string.h>
|
|
|
|
|
2008-10-10 04:24:04 +08:00
|
|
|
#include <gegl.h>
|
2000-12-29 23:22:01 +08:00
|
|
|
#include <gtk/gtk.h>
|
2000-12-17 05:37:03 +08:00
|
|
|
|
2007-03-09 21:00:01 +08:00
|
|
|
#include "libgimpmath/gimpmath.h"
|
|
|
|
|
2002-05-03 20:45:22 +08:00
|
|
|
#include "tools-types.h"
|
2000-12-17 05:37:03 +08:00
|
|
|
|
2003-08-20 01:20:05 +08:00
|
|
|
#include "config/gimpdisplayconfig.h"
|
|
|
|
|
2001-07-07 20:17:23 +08:00
|
|
|
#include "core/gimp.h"
|
2011-04-05 03:14:57 +08:00
|
|
|
#include "core/gimpbezierdesc.h"
|
2003-08-20 02:04:40 +08:00
|
|
|
#include "core/gimpbrush.h"
|
2001-05-09 10:32:03 +08:00
|
|
|
#include "core/gimpimage.h"
|
2001-12-02 05:02:34 +08:00
|
|
|
#include "core/gimptoolinfo.h"
|
2001-05-09 10:32:03 +08:00
|
|
|
|
2004-05-26 04:41:09 +08:00
|
|
|
#include "paint/gimpbrushcore.h"
|
2003-02-05 22:39:40 +08:00
|
|
|
#include "paint/gimppaintoptions.h"
|
2002-02-15 03:31:16 +08:00
|
|
|
|
2011-05-05 05:25:55 +08:00
|
|
|
#include "display/gimpcanvashandle.h"
|
|
|
|
#include "display/gimpcanvaspath.h"
|
2001-09-26 07:23:09 +08:00
|
|
|
#include "display/gimpdisplay.h"
|
2007-10-30 01:17:14 +08:00
|
|
|
#include "display/gimpdisplayshell.h"
|
2001-09-26 07:23:09 +08:00
|
|
|
|
2006-08-16 05:46:22 +08:00
|
|
|
#include "gimpbrushtool.h"
|
2003-04-16 00:05:52 +08:00
|
|
|
#include "gimptoolcontrol.h"
|
2001-03-08 09:07:03 +08:00
|
|
|
|
1999-09-02 02:46:25 +08:00
|
|
|
|
2011-01-13 17:06:07 +08:00
|
|
|
static void gimp_brush_tool_constructed (GObject *object);
|
|
|
|
|
|
|
|
static void gimp_brush_tool_oper_update (GimpTool *tool,
|
|
|
|
const GimpCoords *coords,
|
|
|
|
GdkModifierType state,
|
|
|
|
gboolean proximity,
|
|
|
|
GimpDisplay *display);
|
|
|
|
static void gimp_brush_tool_cursor_update (GimpTool *tool,
|
|
|
|
const GimpCoords *coords,
|
|
|
|
GdkModifierType state,
|
|
|
|
GimpDisplay *display);
|
|
|
|
static void gimp_brush_tool_options_notify (GimpTool *tool,
|
|
|
|
GimpToolOptions *options,
|
|
|
|
const GParamSpec *pspec);
|
|
|
|
|
Bug 795257 - Segmentation fault crash using the clone tool
Commit f5cb1fed85341a9d0a46fb1391b19fa9ea3ccb42, which performed
brush outline generation in GimpPaintTool in synchrony with the
paint thread, wasn't enough, since GimpSourceTool could still call
gimp_brush_tool_create_outline() directly during its
GimpDrawTool::draw() method, leading to the same race condition
when executed concurrently with the paint thread.
Partially revert the above commit, so that outline generation is
handled as before, as far as GimpPaintTool is concenered. Instead,
add GimpPaintTool::{start,end,flush}_paint() virtual functions; the
first two are called when starting/ending painting using the paint
thread, while the third is called during the display-update
timeout, while the main thread and the paint thread are
synchronized. This allows subclasses to perform non-thread-safe
actions while the threads are synchronized.
Override these functions in GimpBrushTool, and cache the brush
boundary in the flush() function. Use the cached boundary in
gimp_brush_tool_create_outline() while painting, to avoid the above
race condition, both when this function is called through
GimpPaintTool, and through GimpSourceTool.
2018-04-14 21:48:10 +08:00
|
|
|
static void gimp_brush_tool_start_paint (GimpPaintTool *paint_tool);
|
|
|
|
static void gimp_brush_tool_end_paint (GimpPaintTool *paint_tool);
|
|
|
|
static void gimp_brush_tool_flush_paint (GimpPaintTool *paint_tool);
|
2014-04-12 21:03:15 +08:00
|
|
|
static GimpCanvasItem *
|
|
|
|
gimp_brush_tool_get_outline (GimpPaintTool *paint_tool,
|
|
|
|
GimpDisplay *display,
|
|
|
|
gdouble x,
|
|
|
|
gdouble y);
|
2011-01-13 17:06:07 +08:00
|
|
|
|
|
|
|
static void gimp_brush_tool_brush_changed (GimpContext *context,
|
|
|
|
GimpBrush *brush,
|
|
|
|
GimpBrushTool *brush_tool);
|
|
|
|
static void gimp_brush_tool_set_brush (GimpBrushCore *brush_core,
|
|
|
|
GimpBrush *brush,
|
|
|
|
GimpBrushTool *brush_tool);
|
2003-08-20 01:20:05 +08:00
|
|
|
|
Bug 795257 - Segmentation fault crash using the clone tool
Commit f5cb1fed85341a9d0a46fb1391b19fa9ea3ccb42, which performed
brush outline generation in GimpPaintTool in synchrony with the
paint thread, wasn't enough, since GimpSourceTool could still call
gimp_brush_tool_create_outline() directly during its
GimpDrawTool::draw() method, leading to the same race condition
when executed concurrently with the paint thread.
Partially revert the above commit, so that outline generation is
handled as before, as far as GimpPaintTool is concenered. Instead,
add GimpPaintTool::{start,end,flush}_paint() virtual functions; the
first two are called when starting/ending painting using the paint
thread, while the third is called during the display-update
timeout, while the main thread and the paint thread are
synchronized. This allows subclasses to perform non-thread-safe
actions while the threads are synchronized.
Override these functions in GimpBrushTool, and cache the brush
boundary in the flush() function. Use the cached boundary in
gimp_brush_tool_create_outline() while painting, to avoid the above
race condition, both when this function is called through
GimpPaintTool, and through GimpSourceTool.
2018-04-14 21:48:10 +08:00
|
|
|
static const GimpBezierDesc *
|
|
|
|
gimp_brush_tool_get_boundary (GimpBrushTool *brush_tool,
|
|
|
|
gint *width,
|
|
|
|
gint *height);
|
|
|
|
|
1997-11-25 06:05:25 +08:00
|
|
|
|
2006-08-16 05:46:22 +08:00
|
|
|
G_DEFINE_TYPE (GimpBrushTool, gimp_brush_tool, GIMP_TYPE_PAINT_TOOL)
|
2001-02-28 03:18:01 +08:00
|
|
|
|
2006-08-16 05:46:22 +08:00
|
|
|
#define parent_class gimp_brush_tool_parent_class
|
2001-02-27 13:21:12 +08:00
|
|
|
|
|
|
|
|
2001-02-28 03:18:01 +08:00
|
|
|
static void
|
2006-08-16 05:46:22 +08:00
|
|
|
gimp_brush_tool_class_init (GimpBrushToolClass *klass)
|
2001-02-27 13:21:12 +08:00
|
|
|
{
|
2014-04-12 21:03:15 +08:00
|
|
|
GObjectClass *object_class = G_OBJECT_CLASS (klass);
|
|
|
|
GimpToolClass *tool_class = GIMP_TOOL_CLASS (klass);
|
|
|
|
GimpPaintToolClass *paint_tool_class = GIMP_PAINT_TOOL_CLASS (klass);
|
2001-02-28 03:18:01 +08:00
|
|
|
|
2014-04-12 21:03:15 +08:00
|
|
|
object_class->constructed = gimp_brush_tool_constructed;
|
2002-02-13 22:50:37 +08:00
|
|
|
|
2014-04-12 21:03:15 +08:00
|
|
|
tool_class->oper_update = gimp_brush_tool_oper_update;
|
|
|
|
tool_class->cursor_update = gimp_brush_tool_cursor_update;
|
|
|
|
tool_class->options_notify = gimp_brush_tool_options_notify;
|
2001-02-28 03:18:01 +08:00
|
|
|
|
Bug 795257 - Segmentation fault crash using the clone tool
Commit f5cb1fed85341a9d0a46fb1391b19fa9ea3ccb42, which performed
brush outline generation in GimpPaintTool in synchrony with the
paint thread, wasn't enough, since GimpSourceTool could still call
gimp_brush_tool_create_outline() directly during its
GimpDrawTool::draw() method, leading to the same race condition
when executed concurrently with the paint thread.
Partially revert the above commit, so that outline generation is
handled as before, as far as GimpPaintTool is concenered. Instead,
add GimpPaintTool::{start,end,flush}_paint() virtual functions; the
first two are called when starting/ending painting using the paint
thread, while the third is called during the display-update
timeout, while the main thread and the paint thread are
synchronized. This allows subclasses to perform non-thread-safe
actions while the threads are synchronized.
Override these functions in GimpBrushTool, and cache the brush
boundary in the flush() function. Use the cached boundary in
gimp_brush_tool_create_outline() while painting, to avoid the above
race condition, both when this function is called through
GimpPaintTool, and through GimpSourceTool.
2018-04-14 21:48:10 +08:00
|
|
|
paint_tool_class->start_paint = gimp_brush_tool_start_paint;
|
|
|
|
paint_tool_class->end_paint = gimp_brush_tool_end_paint;
|
|
|
|
paint_tool_class->flush_paint = gimp_brush_tool_flush_paint;
|
2014-04-12 21:03:15 +08:00
|
|
|
paint_tool_class->get_outline = gimp_brush_tool_get_outline;
|
2001-02-27 13:21:12 +08:00
|
|
|
}
|
1997-11-25 06:05:25 +08:00
|
|
|
|
2001-02-28 03:18:01 +08:00
|
|
|
static void
|
2006-08-16 05:46:22 +08:00
|
|
|
gimp_brush_tool_init (GimpBrushTool *brush_tool)
|
2001-02-28 03:18:01 +08:00
|
|
|
{
|
2006-08-16 05:46:22 +08:00
|
|
|
GimpTool *tool = GIMP_TOOL (brush_tool);
|
2002-02-05 19:35:03 +08:00
|
|
|
|
2014-04-20 02:09:39 +08:00
|
|
|
gimp_tool_control_set_action_size (tool->control,
|
2014-05-04 04:55:05 +08:00
|
|
|
"tools/tools-paintbrush-size-set");
|
2014-04-20 02:09:39 +08:00
|
|
|
gimp_tool_control_set_action_aspect (tool->control,
|
2014-05-04 04:55:05 +08:00
|
|
|
"tools/tools-paintbrush-aspect-ratio-set");
|
2014-04-20 02:09:39 +08:00
|
|
|
gimp_tool_control_set_action_angle (tool->control,
|
2014-05-04 04:55:05 +08:00
|
|
|
"tools/tools-paintbrush-angle-set");
|
2016-03-23 06:51:32 +08:00
|
|
|
gimp_tool_control_set_action_spacing (tool->control,
|
|
|
|
"tools/tools-paintbrush-spacing-set");
|
|
|
|
gimp_tool_control_set_action_hardness (tool->control,
|
|
|
|
"tools/tools-paintbrush-hardness-set");
|
|
|
|
gimp_tool_control_set_action_force (tool->control,
|
|
|
|
"tools/tools-paintbrush-force-set");
|
2005-03-05 03:05:40 +08:00
|
|
|
gimp_tool_control_set_action_object_1 (tool->control,
|
|
|
|
"context/context-brush-select-set");
|
2003-08-31 00:41:35 +08:00
|
|
|
}
|
|
|
|
|
2011-01-13 17:06:07 +08:00
|
|
|
static void
|
|
|
|
gimp_brush_tool_constructed (GObject *object)
|
2003-08-31 00:41:35 +08:00
|
|
|
{
|
2014-04-12 21:03:15 +08:00
|
|
|
GimpTool *tool = GIMP_TOOL (object);
|
|
|
|
GimpPaintTool *paint_tool = GIMP_PAINT_TOOL (object);
|
2003-08-31 00:41:35 +08:00
|
|
|
|
2012-11-13 04:51:22 +08:00
|
|
|
G_OBJECT_CLASS (parent_class)->constructed (object);
|
2003-08-31 00:41:35 +08:00
|
|
|
|
2018-02-12 05:23:10 +08:00
|
|
|
gimp_assert (GIMP_IS_BRUSH_CORE (paint_tool->core));
|
2003-08-31 00:41:35 +08:00
|
|
|
|
2006-09-06 02:25:31 +08:00
|
|
|
g_signal_connect_object (gimp_tool_get_options (tool), "brush-changed",
|
2006-08-16 05:46:22 +08:00
|
|
|
G_CALLBACK (gimp_brush_tool_brush_changed),
|
2014-04-12 21:03:15 +08:00
|
|
|
paint_tool, 0);
|
2009-04-26 01:53:09 +08:00
|
|
|
|
2011-04-04 06:01:30 +08:00
|
|
|
g_signal_connect_object (paint_tool->core, "set-brush",
|
|
|
|
G_CALLBACK (gimp_brush_tool_set_brush),
|
2014-04-12 21:03:15 +08:00
|
|
|
paint_tool, 0);
|
2003-06-05 23:43:49 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
2008-11-01 23:17:36 +08:00
|
|
|
gimp_brush_tool_oper_update (GimpTool *tool,
|
|
|
|
const GimpCoords *coords,
|
|
|
|
GdkModifierType state,
|
|
|
|
gboolean proximity,
|
|
|
|
GimpDisplay *display)
|
1997-11-25 06:05:25 +08:00
|
|
|
{
|
2006-09-06 02:25:31 +08:00
|
|
|
GimpPaintOptions *paint_options = GIMP_PAINT_TOOL_GET_OPTIONS (tool);
|
2011-03-31 01:18:29 +08:00
|
|
|
GimpDrawable *drawable;
|
1997-11-25 06:05:25 +08:00
|
|
|
|
2006-09-13 19:04:49 +08:00
|
|
|
gimp_draw_tool_pause (GIMP_DRAW_TOOL (tool));
|
2000-03-05 08:06:11 +08:00
|
|
|
|
2006-08-16 05:46:22 +08:00
|
|
|
GIMP_TOOL_CLASS (parent_class)->oper_update (tool, coords, state,
|
|
|
|
proximity, display);
|
1999-05-15 08:02:47 +08:00
|
|
|
|
2011-03-31 01:18:29 +08:00
|
|
|
drawable = gimp_image_get_active_drawable (gimp_display_get_image (display));
|
|
|
|
|
|
|
|
if (! gimp_color_tool_is_enabled (GIMP_COLOR_TOOL (tool)) &&
|
|
|
|
drawable && proximity)
|
2002-02-19 01:00:09 +08:00
|
|
|
{
|
2011-04-06 01:05:55 +08:00
|
|
|
GimpContext *context = GIMP_CONTEXT (paint_options);
|
2006-09-13 19:04:49 +08:00
|
|
|
GimpPaintTool *paint_tool = GIMP_PAINT_TOOL (tool);
|
|
|
|
GimpBrushCore *brush_core = GIMP_BRUSH_CORE (paint_tool->core);
|
2006-08-16 05:46:22 +08:00
|
|
|
|
2011-04-06 01:05:55 +08:00
|
|
|
gimp_brush_core_set_brush (brush_core,
|
|
|
|
gimp_context_get_brush (context));
|
2004-06-23 20:19:28 +08:00
|
|
|
|
2011-04-06 01:05:55 +08:00
|
|
|
gimp_brush_core_set_dynamics (brush_core,
|
|
|
|
gimp_context_get_dynamics (context));
|
2010-03-15 08:20:13 +08:00
|
|
|
|
|
|
|
if (GIMP_BRUSH_CORE_GET_CLASS (brush_core)->handles_transforming_brush)
|
|
|
|
{
|
2011-04-06 15:11:25 +08:00
|
|
|
gimp_brush_core_eval_transform_dynamics (brush_core,
|
2010-03-17 03:51:59 +08:00
|
|
|
drawable,
|
2010-03-15 08:20:13 +08:00
|
|
|
paint_options,
|
|
|
|
coords);
|
|
|
|
}
|
2002-02-05 01:43:01 +08:00
|
|
|
}
|
2010-03-20 02:21:42 +08:00
|
|
|
|
2006-09-13 19:04:49 +08:00
|
|
|
gimp_draw_tool_resume (GIMP_DRAW_TOOL (tool));
|
2006-08-16 05:46:22 +08:00
|
|
|
}
|
2001-02-25 03:29:47 +08:00
|
|
|
|
2006-08-16 05:46:22 +08:00
|
|
|
static void
|
2008-11-01 23:17:36 +08:00
|
|
|
gimp_brush_tool_cursor_update (GimpTool *tool,
|
|
|
|
const GimpCoords *coords,
|
|
|
|
GdkModifierType state,
|
|
|
|
GimpDisplay *display)
|
2006-08-16 05:46:22 +08:00
|
|
|
{
|
|
|
|
GimpBrushTool *brush_tool = GIMP_BRUSH_TOOL (tool);
|
2011-03-25 03:20:24 +08:00
|
|
|
GimpBrushCore *brush_core = GIMP_BRUSH_CORE (GIMP_PAINT_TOOL (brush_tool)->core);
|
2006-08-16 05:46:22 +08:00
|
|
|
|
2011-03-25 03:20:24 +08:00
|
|
|
if (! gimp_color_tool_is_enabled (GIMP_COLOR_TOOL (tool)))
|
2006-09-12 22:24:10 +08:00
|
|
|
{
|
2011-03-25 03:20:24 +08:00
|
|
|
if (! brush_core->main_brush || ! brush_core->dynamics)
|
|
|
|
{
|
2011-03-31 01:18:29 +08:00
|
|
|
gimp_tool_set_cursor (tool, display,
|
|
|
|
gimp_tool_control_get_cursor (tool->control),
|
|
|
|
gimp_tool_control_get_tool_cursor (tool->control),
|
|
|
|
GIMP_CURSOR_MODIFIER_BAD);
|
|
|
|
return;
|
2011-03-25 03:20:24 +08:00
|
|
|
}
|
2006-09-12 22:24:10 +08:00
|
|
|
}
|
2011-03-25 03:20:24 +08:00
|
|
|
|
|
|
|
GIMP_TOOL_CLASS (parent_class)->cursor_update (tool, coords, state, display);
|
1997-11-25 06:05:25 +08:00
|
|
|
}
|
|
|
|
|
2010-11-10 21:20:33 +08:00
|
|
|
static void
|
|
|
|
gimp_brush_tool_options_notify (GimpTool *tool,
|
|
|
|
GimpToolOptions *options,
|
|
|
|
const GParamSpec *pspec)
|
|
|
|
{
|
|
|
|
GIMP_TOOL_CLASS (parent_class)->options_notify (tool, options, pspec);
|
|
|
|
|
|
|
|
if (! strcmp (pspec->name, "brush-size") ||
|
|
|
|
! strcmp (pspec->name, "brush-angle") ||
|
|
|
|
! strcmp (pspec->name, "brush-aspect-ratio"))
|
|
|
|
{
|
|
|
|
GimpPaintTool *paint_tool = GIMP_PAINT_TOOL (tool);
|
|
|
|
GimpBrushCore *brush_core = GIMP_BRUSH_CORE (paint_tool->core);
|
|
|
|
|
2011-04-06 01:05:55 +08:00
|
|
|
g_signal_emit_by_name (brush_core, "set-brush",
|
|
|
|
brush_core->main_brush);
|
2010-11-10 21:20:33 +08:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
Bug 795257 - Segmentation fault crash using the clone tool
Commit f5cb1fed85341a9d0a46fb1391b19fa9ea3ccb42, which performed
brush outline generation in GimpPaintTool in synchrony with the
paint thread, wasn't enough, since GimpSourceTool could still call
gimp_brush_tool_create_outline() directly during its
GimpDrawTool::draw() method, leading to the same race condition
when executed concurrently with the paint thread.
Partially revert the above commit, so that outline generation is
handled as before, as far as GimpPaintTool is concenered. Instead,
add GimpPaintTool::{start,end,flush}_paint() virtual functions; the
first two are called when starting/ending painting using the paint
thread, while the third is called during the display-update
timeout, while the main thread and the paint thread are
synchronized. This allows subclasses to perform non-thread-safe
actions while the threads are synchronized.
Override these functions in GimpBrushTool, and cache the brush
boundary in the flush() function. Use the cached boundary in
gimp_brush_tool_create_outline() while painting, to avoid the above
race condition, both when this function is called through
GimpPaintTool, and through GimpSourceTool.
2018-04-14 21:48:10 +08:00
|
|
|
static void
|
|
|
|
gimp_brush_tool_start_paint (GimpPaintTool *paint_tool)
|
|
|
|
{
|
2018-04-15 05:55:44 +08:00
|
|
|
GimpBrushTool *brush_tool = GIMP_BRUSH_TOOL (paint_tool);
|
|
|
|
GimpBrushCore *brush_core = GIMP_BRUSH_CORE (paint_tool->core);
|
|
|
|
const GimpBezierDesc *boundary;
|
|
|
|
|
Bug 795257 - Segmentation fault crash using the clone tool
Commit f5cb1fed85341a9d0a46fb1391b19fa9ea3ccb42, which performed
brush outline generation in GimpPaintTool in synchrony with the
paint thread, wasn't enough, since GimpSourceTool could still call
gimp_brush_tool_create_outline() directly during its
GimpDrawTool::draw() method, leading to the same race condition
when executed concurrently with the paint thread.
Partially revert the above commit, so that outline generation is
handled as before, as far as GimpPaintTool is concenered. Instead,
add GimpPaintTool::{start,end,flush}_paint() virtual functions; the
first two are called when starting/ending painting using the paint
thread, while the third is called during the display-update
timeout, while the main thread and the paint thread are
synchronized. This allows subclasses to perform non-thread-safe
actions while the threads are synchronized.
Override these functions in GimpBrushTool, and cache the brush
boundary in the flush() function. Use the cached boundary in
gimp_brush_tool_create_outline() while painting, to avoid the above
race condition, both when this function is called through
GimpPaintTool, and through GimpSourceTool.
2018-04-14 21:48:10 +08:00
|
|
|
if (GIMP_PAINT_TOOL_CLASS (parent_class)->start_paint)
|
|
|
|
GIMP_PAINT_TOOL_CLASS (parent_class)->start_paint (paint_tool);
|
|
|
|
|
2018-04-15 05:55:44 +08:00
|
|
|
boundary = gimp_brush_tool_get_boundary (brush_tool,
|
|
|
|
&brush_tool->boundary_width,
|
|
|
|
&brush_tool->boundary_height);
|
|
|
|
|
|
|
|
if (boundary)
|
|
|
|
brush_tool->boundary = gimp_bezier_desc_copy (boundary);
|
|
|
|
|
|
|
|
brush_tool->boundary_scale = brush_core->scale;
|
|
|
|
brush_tool->boundary_aspect_ratio = brush_core->aspect_ratio;
|
|
|
|
brush_tool->boundary_angle = brush_core->angle;
|
|
|
|
brush_tool->boundary_reflect = brush_core->reflect;
|
|
|
|
brush_tool->boundary_hardness = brush_core->hardness;
|
Bug 795257 - Segmentation fault crash using the clone tool
Commit f5cb1fed85341a9d0a46fb1391b19fa9ea3ccb42, which performed
brush outline generation in GimpPaintTool in synchrony with the
paint thread, wasn't enough, since GimpSourceTool could still call
gimp_brush_tool_create_outline() directly during its
GimpDrawTool::draw() method, leading to the same race condition
when executed concurrently with the paint thread.
Partially revert the above commit, so that outline generation is
handled as before, as far as GimpPaintTool is concenered. Instead,
add GimpPaintTool::{start,end,flush}_paint() virtual functions; the
first two are called when starting/ending painting using the paint
thread, while the third is called during the display-update
timeout, while the main thread and the paint thread are
synchronized. This allows subclasses to perform non-thread-safe
actions while the threads are synchronized.
Override these functions in GimpBrushTool, and cache the brush
boundary in the flush() function. Use the cached boundary in
gimp_brush_tool_create_outline() while painting, to avoid the above
race condition, both when this function is called through
GimpPaintTool, and through GimpSourceTool.
2018-04-14 21:48:10 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
|
|
|
gimp_brush_tool_end_paint (GimpPaintTool *paint_tool)
|
|
|
|
{
|
|
|
|
GimpBrushTool *brush_tool = GIMP_BRUSH_TOOL (paint_tool);
|
|
|
|
|
|
|
|
g_clear_pointer (&brush_tool->boundary, gimp_bezier_desc_free);
|
|
|
|
|
|
|
|
if (GIMP_PAINT_TOOL_CLASS (parent_class)->end_paint)
|
|
|
|
GIMP_PAINT_TOOL_CLASS (parent_class)->end_paint (paint_tool);
|
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
|
|
|
gimp_brush_tool_flush_paint (GimpPaintTool *paint_tool)
|
|
|
|
{
|
|
|
|
GimpBrushTool *brush_tool = GIMP_BRUSH_TOOL (paint_tool);
|
2018-04-15 05:55:44 +08:00
|
|
|
GimpBrushCore *brush_core = GIMP_BRUSH_CORE (paint_tool->core);
|
Bug 795257 - Segmentation fault crash using the clone tool
Commit f5cb1fed85341a9d0a46fb1391b19fa9ea3ccb42, which performed
brush outline generation in GimpPaintTool in synchrony with the
paint thread, wasn't enough, since GimpSourceTool could still call
gimp_brush_tool_create_outline() directly during its
GimpDrawTool::draw() method, leading to the same race condition
when executed concurrently with the paint thread.
Partially revert the above commit, so that outline generation is
handled as before, as far as GimpPaintTool is concenered. Instead,
add GimpPaintTool::{start,end,flush}_paint() virtual functions; the
first two are called when starting/ending painting using the paint
thread, while the third is called during the display-update
timeout, while the main thread and the paint thread are
synchronized. This allows subclasses to perform non-thread-safe
actions while the threads are synchronized.
Override these functions in GimpBrushTool, and cache the brush
boundary in the flush() function. Use the cached boundary in
gimp_brush_tool_create_outline() while painting, to avoid the above
race condition, both when this function is called through
GimpPaintTool, and through GimpSourceTool.
2018-04-14 21:48:10 +08:00
|
|
|
const GimpBezierDesc *boundary;
|
|
|
|
|
|
|
|
if (GIMP_PAINT_TOOL_CLASS (parent_class)->flush_paint)
|
|
|
|
GIMP_PAINT_TOOL_CLASS (parent_class)->flush_paint (paint_tool);
|
|
|
|
|
2018-04-15 05:55:44 +08:00
|
|
|
if (brush_tool->boundary_scale != brush_core->scale ||
|
|
|
|
brush_tool->boundary_aspect_ratio != brush_core->aspect_ratio ||
|
|
|
|
brush_tool->boundary_angle != brush_core->angle ||
|
|
|
|
brush_tool->boundary_reflect != brush_core->reflect ||
|
|
|
|
brush_tool->boundary_hardness != brush_core->hardness)
|
|
|
|
{
|
|
|
|
g_clear_pointer (&brush_tool->boundary, gimp_bezier_desc_free);
|
Bug 795257 - Segmentation fault crash using the clone tool
Commit f5cb1fed85341a9d0a46fb1391b19fa9ea3ccb42, which performed
brush outline generation in GimpPaintTool in synchrony with the
paint thread, wasn't enough, since GimpSourceTool could still call
gimp_brush_tool_create_outline() directly during its
GimpDrawTool::draw() method, leading to the same race condition
when executed concurrently with the paint thread.
Partially revert the above commit, so that outline generation is
handled as before, as far as GimpPaintTool is concenered. Instead,
add GimpPaintTool::{start,end,flush}_paint() virtual functions; the
first two are called when starting/ending painting using the paint
thread, while the third is called during the display-update
timeout, while the main thread and the paint thread are
synchronized. This allows subclasses to perform non-thread-safe
actions while the threads are synchronized.
Override these functions in GimpBrushTool, and cache the brush
boundary in the flush() function. Use the cached boundary in
gimp_brush_tool_create_outline() while painting, to avoid the above
race condition, both when this function is called through
GimpPaintTool, and through GimpSourceTool.
2018-04-14 21:48:10 +08:00
|
|
|
|
2018-04-15 05:55:44 +08:00
|
|
|
boundary = gimp_brush_tool_get_boundary (brush_tool,
|
|
|
|
&brush_tool->boundary_width,
|
|
|
|
&brush_tool->boundary_height);
|
Bug 795257 - Segmentation fault crash using the clone tool
Commit f5cb1fed85341a9d0a46fb1391b19fa9ea3ccb42, which performed
brush outline generation in GimpPaintTool in synchrony with the
paint thread, wasn't enough, since GimpSourceTool could still call
gimp_brush_tool_create_outline() directly during its
GimpDrawTool::draw() method, leading to the same race condition
when executed concurrently with the paint thread.
Partially revert the above commit, so that outline generation is
handled as before, as far as GimpPaintTool is concenered. Instead,
add GimpPaintTool::{start,end,flush}_paint() virtual functions; the
first two are called when starting/ending painting using the paint
thread, while the third is called during the display-update
timeout, while the main thread and the paint thread are
synchronized. This allows subclasses to perform non-thread-safe
actions while the threads are synchronized.
Override these functions in GimpBrushTool, and cache the brush
boundary in the flush() function. Use the cached boundary in
gimp_brush_tool_create_outline() while painting, to avoid the above
race condition, both when this function is called through
GimpPaintTool, and through GimpSourceTool.
2018-04-14 21:48:10 +08:00
|
|
|
|
2018-04-15 05:55:44 +08:00
|
|
|
if (boundary)
|
|
|
|
brush_tool->boundary = gimp_bezier_desc_copy (boundary);
|
|
|
|
|
|
|
|
brush_tool->boundary_scale = brush_core->scale;
|
|
|
|
brush_tool->boundary_aspect_ratio = brush_core->aspect_ratio;
|
|
|
|
brush_tool->boundary_angle = brush_core->angle;
|
|
|
|
brush_tool->boundary_reflect = brush_core->reflect;
|
|
|
|
brush_tool->boundary_hardness = brush_core->hardness;
|
|
|
|
}
|
Bug 795257 - Segmentation fault crash using the clone tool
Commit f5cb1fed85341a9d0a46fb1391b19fa9ea3ccb42, which performed
brush outline generation in GimpPaintTool in synchrony with the
paint thread, wasn't enough, since GimpSourceTool could still call
gimp_brush_tool_create_outline() directly during its
GimpDrawTool::draw() method, leading to the same race condition
when executed concurrently with the paint thread.
Partially revert the above commit, so that outline generation is
handled as before, as far as GimpPaintTool is concenered. Instead,
add GimpPaintTool::{start,end,flush}_paint() virtual functions; the
first two are called when starting/ending painting using the paint
thread, while the third is called during the display-update
timeout, while the main thread and the paint thread are
synchronized. This allows subclasses to perform non-thread-safe
actions while the threads are synchronized.
Override these functions in GimpBrushTool, and cache the brush
boundary in the flush() function. Use the cached boundary in
gimp_brush_tool_create_outline() while painting, to avoid the above
race condition, both when this function is called through
GimpPaintTool, and through GimpSourceTool.
2018-04-14 21:48:10 +08:00
|
|
|
}
|
|
|
|
|
2014-04-12 21:03:15 +08:00
|
|
|
static GimpCanvasItem *
|
|
|
|
gimp_brush_tool_get_outline (GimpPaintTool *paint_tool,
|
|
|
|
GimpDisplay *display,
|
|
|
|
gdouble x,
|
|
|
|
gdouble y)
|
1997-11-25 06:05:25 +08:00
|
|
|
{
|
2014-04-12 21:03:15 +08:00
|
|
|
GimpBrushTool *brush_tool = GIMP_BRUSH_TOOL (paint_tool);
|
|
|
|
GimpCanvasItem *item;
|
2006-09-13 19:04:49 +08:00
|
|
|
|
2014-04-12 21:03:15 +08:00
|
|
|
item = gimp_brush_tool_create_outline (brush_tool, display, x, y);
|
2006-09-13 19:04:49 +08:00
|
|
|
|
2014-04-12 21:03:15 +08:00
|
|
|
if (! item)
|
2014-04-09 20:30:46 +08:00
|
|
|
{
|
2014-04-12 21:03:15 +08:00
|
|
|
GimpBrushCore *brush_core = GIMP_BRUSH_CORE (paint_tool->core);
|
2014-04-12 07:13:11 +08:00
|
|
|
|
2014-04-12 21:03:15 +08:00
|
|
|
if (brush_core->main_brush && brush_core->dynamics)
|
2014-04-12 07:13:11 +08:00
|
|
|
{
|
2014-04-12 21:03:15 +08:00
|
|
|
/* if an outline was expected, but got scaled away by
|
|
|
|
* transform/dynamics, draw a circle in the "normal" size.
|
|
|
|
*/
|
|
|
|
GimpPaintOptions *options;
|
2011-05-05 05:25:55 +08:00
|
|
|
|
2014-04-12 21:03:15 +08:00
|
|
|
options = GIMP_PAINT_TOOL_GET_OPTIONS (brush_tool);
|
2014-04-12 07:13:11 +08:00
|
|
|
|
2014-11-19 05:41:09 +08:00
|
|
|
gimp_paint_tool_set_draw_fallback (paint_tool,
|
|
|
|
TRUE, options->brush_size);
|
2014-04-12 21:03:15 +08:00
|
|
|
}
|
2011-05-05 05:25:55 +08:00
|
|
|
}
|
2014-04-12 21:03:15 +08:00
|
|
|
|
|
|
|
return item;
|
2007-05-07 18:19:04 +08:00
|
|
|
}
|
2003-07-11 00:01:45 +08:00
|
|
|
|
2011-05-05 05:25:55 +08:00
|
|
|
GimpCanvasItem *
|
|
|
|
gimp_brush_tool_create_outline (GimpBrushTool *brush_tool,
|
|
|
|
GimpDisplay *display,
|
|
|
|
gdouble x,
|
2014-04-09 20:30:46 +08:00
|
|
|
gdouble y)
|
2007-05-07 18:19:04 +08:00
|
|
|
{
|
2011-04-06 04:11:27 +08:00
|
|
|
GimpPaintOptions *options;
|
|
|
|
GimpDisplayShell *shell;
|
|
|
|
const GimpBezierDesc *boundary = NULL;
|
|
|
|
gint width = 0;
|
|
|
|
gint height = 0;
|
2007-05-07 18:19:04 +08:00
|
|
|
|
2011-05-05 05:25:55 +08:00
|
|
|
g_return_val_if_fail (GIMP_IS_BRUSH_TOOL (brush_tool), NULL);
|
|
|
|
g_return_val_if_fail (GIMP_IS_DISPLAY (display), NULL);
|
2007-05-07 18:19:04 +08:00
|
|
|
|
Bug 795257 - Segmentation fault crash using the clone tool
Commit f5cb1fed85341a9d0a46fb1391b19fa9ea3ccb42, which performed
brush outline generation in GimpPaintTool in synchrony with the
paint thread, wasn't enough, since GimpSourceTool could still call
gimp_brush_tool_create_outline() directly during its
GimpDrawTool::draw() method, leading to the same race condition
when executed concurrently with the paint thread.
Partially revert the above commit, so that outline generation is
handled as before, as far as GimpPaintTool is concenered. Instead,
add GimpPaintTool::{start,end,flush}_paint() virtual functions; the
first two are called when starting/ending painting using the paint
thread, while the third is called during the display-update
timeout, while the main thread and the paint thread are
synchronized. This allows subclasses to perform non-thread-safe
actions while the threads are synchronized.
Override these functions in GimpBrushTool, and cache the brush
boundary in the flush() function. Use the cached boundary in
gimp_brush_tool_create_outline() while painting, to avoid the above
race condition, both when this function is called through
GimpPaintTool, and through GimpSourceTool.
2018-04-14 21:48:10 +08:00
|
|
|
if (gimp_paint_tool_is_painting (GIMP_PAINT_TOOL (brush_tool)))
|
|
|
|
{
|
|
|
|
boundary = brush_tool->boundary;
|
|
|
|
width = brush_tool->boundary_width;
|
|
|
|
height = brush_tool->boundary_height;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
boundary = gimp_brush_tool_get_boundary (brush_tool, &width, &height);
|
|
|
|
}
|
2007-05-07 18:19:04 +08:00
|
|
|
|
Bug 795257 - Segmentation fault crash using the clone tool
Commit f5cb1fed85341a9d0a46fb1391b19fa9ea3ccb42, which performed
brush outline generation in GimpPaintTool in synchrony with the
paint thread, wasn't enough, since GimpSourceTool could still call
gimp_brush_tool_create_outline() directly during its
GimpDrawTool::draw() method, leading to the same race condition
when executed concurrently with the paint thread.
Partially revert the above commit, so that outline generation is
handled as before, as far as GimpPaintTool is concenered. Instead,
add GimpPaintTool::{start,end,flush}_paint() virtual functions; the
first two are called when starting/ending painting using the paint
thread, while the third is called during the display-update
timeout, while the main thread and the paint thread are
synchronized. This allows subclasses to perform non-thread-safe
actions while the threads are synchronized.
Override these functions in GimpBrushTool, and cache the brush
boundary in the flush() function. Use the cached boundary in
gimp_brush_tool_create_outline() while painting, to avoid the above
race condition, both when this function is called through
GimpPaintTool, and through GimpSourceTool.
2018-04-14 21:48:10 +08:00
|
|
|
if (! boundary)
|
2011-05-05 05:25:55 +08:00
|
|
|
return NULL;
|
2011-03-25 03:20:24 +08:00
|
|
|
|
Bug 795257 - Segmentation fault crash using the clone tool
Commit f5cb1fed85341a9d0a46fb1391b19fa9ea3ccb42, which performed
brush outline generation in GimpPaintTool in synchrony with the
paint thread, wasn't enough, since GimpSourceTool could still call
gimp_brush_tool_create_outline() directly during its
GimpDrawTool::draw() method, leading to the same race condition
when executed concurrently with the paint thread.
Partially revert the above commit, so that outline generation is
handled as before, as far as GimpPaintTool is concenered. Instead,
add GimpPaintTool::{start,end,flush}_paint() virtual functions; the
first two are called when starting/ending painting using the paint
thread, while the third is called during the display-update
timeout, while the main thread and the paint thread are
synchronized. This allows subclasses to perform non-thread-safe
actions while the threads are synchronized.
Override these functions in GimpBrushTool, and cache the brush
boundary in the flush() function. Use the cached boundary in
gimp_brush_tool_create_outline() while painting, to avoid the above
race condition, both when this function is called through
GimpPaintTool, and through GimpSourceTool.
2018-04-14 21:48:10 +08:00
|
|
|
options = GIMP_PAINT_TOOL_GET_OPTIONS (brush_tool);
|
|
|
|
shell = gimp_display_get_shell (display);
|
2011-04-05 03:14:57 +08:00
|
|
|
|
|
|
|
/* don't draw the boundary if it becomes too small */
|
Bug 795257 - Segmentation fault crash using the clone tool
Commit f5cb1fed85341a9d0a46fb1391b19fa9ea3ccb42, which performed
brush outline generation in GimpPaintTool in synchrony with the
paint thread, wasn't enough, since GimpSourceTool could still call
gimp_brush_tool_create_outline() directly during its
GimpDrawTool::draw() method, leading to the same race condition
when executed concurrently with the paint thread.
Partially revert the above commit, so that outline generation is
handled as before, as far as GimpPaintTool is concenered. Instead,
add GimpPaintTool::{start,end,flush}_paint() virtual functions; the
first two are called when starting/ending painting using the paint
thread, while the third is called during the display-update
timeout, while the main thread and the paint thread are
synchronized. This allows subclasses to perform non-thread-safe
actions while the threads are synchronized.
Override these functions in GimpBrushTool, and cache the brush
boundary in the flush() function. Use the cached boundary in
gimp_brush_tool_create_outline() while painting, to avoid the above
race condition, both when this function is called through
GimpPaintTool, and through GimpSourceTool.
2018-04-14 21:48:10 +08:00
|
|
|
if (SCALEX (shell, width) > 4 &&
|
2011-04-05 03:14:57 +08:00
|
|
|
SCALEY (shell, height) > 4)
|
2007-05-07 18:19:04 +08:00
|
|
|
{
|
2011-04-05 03:14:57 +08:00
|
|
|
x -= width / 2.0;
|
|
|
|
y -= height / 2.0;
|
2003-07-14 22:50:41 +08:00
|
|
|
|
2011-04-05 03:14:57 +08:00
|
|
|
if (gimp_paint_options_get_brush_mode (options) == GIMP_BRUSH_HARD)
|
2007-05-07 18:19:04 +08:00
|
|
|
{
|
2007-10-30 01:17:14 +08:00
|
|
|
#define EPSILON 0.000001
|
2011-04-05 03:14:57 +08:00
|
|
|
/* Add EPSILON before rounding since e.g.
|
|
|
|
* (5.0 - 0.5) may end up at (4.499999999....)
|
|
|
|
* due to floating point fnords
|
|
|
|
*/
|
|
|
|
x = RINT (x + EPSILON);
|
|
|
|
y = RINT (y + EPSILON);
|
2003-07-17 00:19:16 +08:00
|
|
|
#undef EPSILON
|
2007-10-30 01:17:14 +08:00
|
|
|
}
|
2011-04-05 03:14:57 +08:00
|
|
|
|
2011-06-30 15:27:43 +08:00
|
|
|
return gimp_canvas_path_new (shell, boundary, x, y, FALSE,
|
|
|
|
GIMP_PATH_STYLE_OUTLINE);
|
2011-04-05 03:14:57 +08:00
|
|
|
}
|
2011-05-05 05:25:55 +08:00
|
|
|
|
|
|
|
return NULL;
|
2004-06-05 07:08:29 +08:00
|
|
|
}
|
|
|
|
|
2006-05-07 05:10:32 +08:00
|
|
|
static void
|
2006-08-16 05:46:22 +08:00
|
|
|
gimp_brush_tool_brush_changed (GimpContext *context,
|
2006-05-07 05:10:32 +08:00
|
|
|
GimpBrush *brush,
|
2006-08-16 05:46:22 +08:00
|
|
|
GimpBrushTool *brush_tool)
|
2006-05-07 05:10:32 +08:00
|
|
|
{
|
2006-08-16 05:46:22 +08:00
|
|
|
GimpPaintTool *paint_tool = GIMP_PAINT_TOOL (brush_tool);
|
2006-05-07 05:10:32 +08:00
|
|
|
GimpBrushCore *brush_core = GIMP_BRUSH_CORE (paint_tool->core);
|
|
|
|
|
2011-04-06 01:05:55 +08:00
|
|
|
gimp_brush_core_set_brush (brush_core, brush);
|
2010-03-17 03:51:59 +08:00
|
|
|
|
2006-05-07 05:10:32 +08:00
|
|
|
}
|
|
|
|
|
2004-06-23 20:19:28 +08:00
|
|
|
static void
|
2006-08-16 05:46:22 +08:00
|
|
|
gimp_brush_tool_set_brush (GimpBrushCore *brush_core,
|
2004-06-23 20:19:28 +08:00
|
|
|
GimpBrush *brush,
|
2006-08-16 05:46:22 +08:00
|
|
|
GimpBrushTool *brush_tool)
|
2004-06-23 20:19:28 +08:00
|
|
|
{
|
2006-08-16 05:46:22 +08:00
|
|
|
gimp_draw_tool_pause (GIMP_DRAW_TOOL (brush_tool));
|
2010-03-17 03:51:59 +08:00
|
|
|
|
|
|
|
if (GIMP_BRUSH_CORE_GET_CLASS (brush_core)->handles_transforming_brush)
|
|
|
|
{
|
2011-04-06 15:11:25 +08:00
|
|
|
GimpPaintCore *paint_core = GIMP_PAINT_CORE (brush_core);
|
|
|
|
|
|
|
|
gimp_brush_core_eval_transform_dynamics (brush_core,
|
2010-03-17 03:51:59 +08:00
|
|
|
NULL,
|
|
|
|
GIMP_PAINT_TOOL_GET_OPTIONS (brush_tool),
|
|
|
|
&paint_core->cur_coords);
|
|
|
|
}
|
2004-06-23 20:19:28 +08:00
|
|
|
|
2006-08-16 05:46:22 +08:00
|
|
|
gimp_draw_tool_resume (GIMP_DRAW_TOOL (brush_tool));
|
2004-06-23 20:19:28 +08:00
|
|
|
}
|
Bug 795257 - Segmentation fault crash using the clone tool
Commit f5cb1fed85341a9d0a46fb1391b19fa9ea3ccb42, which performed
brush outline generation in GimpPaintTool in synchrony with the
paint thread, wasn't enough, since GimpSourceTool could still call
gimp_brush_tool_create_outline() directly during its
GimpDrawTool::draw() method, leading to the same race condition
when executed concurrently with the paint thread.
Partially revert the above commit, so that outline generation is
handled as before, as far as GimpPaintTool is concenered. Instead,
add GimpPaintTool::{start,end,flush}_paint() virtual functions; the
first two are called when starting/ending painting using the paint
thread, while the third is called during the display-update
timeout, while the main thread and the paint thread are
synchronized. This allows subclasses to perform non-thread-safe
actions while the threads are synchronized.
Override these functions in GimpBrushTool, and cache the brush
boundary in the flush() function. Use the cached boundary in
gimp_brush_tool_create_outline() while painting, to avoid the above
race condition, both when this function is called through
GimpPaintTool, and through GimpSourceTool.
2018-04-14 21:48:10 +08:00
|
|
|
|
|
|
|
static const GimpBezierDesc *
|
|
|
|
gimp_brush_tool_get_boundary (GimpBrushTool *brush_tool,
|
|
|
|
gint *width,
|
|
|
|
gint *height)
|
|
|
|
{
|
|
|
|
GimpPaintTool *paint_tool = GIMP_PAINT_TOOL (brush_tool);
|
|
|
|
GimpBrushCore *brush_core = GIMP_BRUSH_CORE (paint_tool->core);
|
|
|
|
|
|
|
|
if (paint_tool->draw_brush &&
|
|
|
|
brush_core->main_brush &&
|
|
|
|
brush_core->dynamics &&
|
|
|
|
brush_core->scale > 0.0)
|
|
|
|
{
|
|
|
|
return gimp_brush_transform_boundary (brush_core->main_brush,
|
|
|
|
brush_core->scale,
|
|
|
|
brush_core->aspect_ratio,
|
|
|
|
brush_core->angle,
|
|
|
|
brush_core->reflect,
|
|
|
|
brush_core->hardness,
|
|
|
|
width,
|
|
|
|
height);
|
|
|
|
}
|
|
|
|
|
|
|
|
return NULL;
|
|
|
|
}
|