From e31e8d77903bd363901723b153fe901fa2e13c8f Mon Sep 17 00:00:00 2001 From: Nicolas Dufour Date: Fri, 28 Feb 2014 16:24:40 +0100 Subject: Spray tool: * Partial patch (in sp_spray_dilate) for crashes explained in Bug #1274831. * Some minor style fixes (indentation). * Due to some remaining crashes, the Single path mode is disabled in Inkscape 0.91. (bzr r13077) --- src/ui/tools/spray-tool.cpp | 90 +++++++++++++++++++++++++++++---------------- 1 file changed, 58 insertions(+), 32 deletions(-) (limited to 'src/ui/tools/spray-tool.cpp') diff --git a/src/ui/tools/spray-tool.cpp b/src/ui/tools/spray-tool.cpp index c9f9c8e91..e43b6575e 100644 --- a/src/ui/tools/spray-tool.cpp +++ b/src/ui/tools/spray-tool.cpp @@ -79,6 +79,11 @@ using namespace std; #define DDC_RED_RGBA 0xff0000ff #define DYNA_MIN_WIDTH 1.0e-6 +// Disabled in 0.91 because of Bug #1274831 (crash, spraying an object +// with the mode: spray object in single path) +// Please enable again when working on 1.0 +//#define ENABLE_SPRAY_MODE_SINGLE_PATH + #include "tool-factory.h" namespace Inkscape { @@ -86,15 +91,15 @@ namespace UI { namespace Tools { namespace { - ToolBase* createSprayContext() { - return new SprayTool(); - } + ToolBase* createSprayContext() { + return new SprayTool(); + } - bool sprayContextRegistered = ToolFactory::instance().registerObject("/tools/spray", createSprayContext); + bool sprayContextRegistered = ToolFactory::instance().registerObject("/tools/spray", createSprayContext); } const std::string& SprayTool::getPrefsPath() { - return SprayTool::prefsPath; + return SprayTool::prefsPath; } const std::string SprayTool::prefsPath = "/tools/spray"; @@ -189,22 +194,22 @@ void SprayTool::update_cursor(bool /*with_shift*/) { sel_message = g_strdup_printf("%s", _("Nothing selected")); } - switch (this->mode) { - case SPRAY_MODE_COPY: - this->message_context->setF(Inkscape::NORMAL_MESSAGE, _("%s. Drag, click or click and scroll to spray copies of the initial selection."), sel_message); - break; - case SPRAY_MODE_CLONE: - this->message_context->setF(Inkscape::NORMAL_MESSAGE, _("%s. Drag, click or click and scroll to spray clones of the initial selection."), sel_message); - break; - case SPRAY_MODE_SINGLE_PATH: - this->message_context->setF(Inkscape::NORMAL_MESSAGE, _("%s. Drag, click or click and scroll to spray in a single path of the initial selection."), sel_message); - break; - default: - break; - } - - this->sp_event_context_update_cursor(); - g_free(sel_message); + switch (this->mode) { + case SPRAY_MODE_COPY: + this->message_context->setF(Inkscape::NORMAL_MESSAGE, _("%s. Drag, click or click and scroll to spray copies of the initial selection."), sel_message); + break; + case SPRAY_MODE_CLONE: + this->message_context->setF(Inkscape::NORMAL_MESSAGE, _("%s. Drag, click or click and scroll to spray clones of the initial selection."), sel_message); + break; + case SPRAY_MODE_SINGLE_PATH: + this->message_context->setF(Inkscape::NORMAL_MESSAGE, _("%s. Drag, click or click and scroll to spray in a single path of the initial selection."), sel_message); + break; + default: + break; + } + + this->sp_event_context_update_cursor(); + g_free(sel_message); } void SprayTool::setup() { @@ -420,6 +425,7 @@ static bool sp_spray_recursive(SPDesktop *desktop, did = true; } } +#ifdef ENABLE_SPRAY_MODE_SINGLE_PATH } else if (mode == SPRAY_MODE_SINGLE_PATH) { SPItem *parent_item = NULL; // Initial object @@ -475,6 +481,7 @@ static bool sp_spray_recursive(SPDesktop *desktop, did = true; } } +#endif } else if (mode == SPRAY_MODE_CLONE) { Geom::OptRect a = item->documentVisualBounds(); if (a) { @@ -541,18 +548,35 @@ static bool sp_spray_dilate(SprayTool *tc, Geom::Point /*event_p*/, Geom::Point double move_mean = get_move_mean(tc); double move_standard_deviation = get_move_standard_deviation(tc); - for (GSList *items = g_slist_copy(const_cast(selection->itemList())); - items != NULL; - items = items->next) { + { + GSList *const original_selection = g_slist_copy(const_cast(selection->itemList())); - SPItem *item = SP_ITEM(items->data); + for (GSList *items = original_selection; + items != NULL; + items = items->next) { + sp_object_ref(SP_ITEM(items->data)); + } - if (is_transform_modes(tc->mode)) { - if (sp_spray_recursive(desktop, selection, item, p, vector, tc->mode, radius, move_force, tc->population, tc->scale, tc->scale_variation, reverse, move_mean, move_standard_deviation, tc->ratio, tc->tilt, tc->rotation_variation, tc->distrib)) - did = true; - } else { - if (sp_spray_recursive(desktop, selection, item, p, vector, tc->mode, radius, path_force, tc->population, tc->scale, tc->scale_variation, reverse, path_mean, path_standard_deviation, tc->ratio, tc->tilt, tc->rotation_variation, tc->distrib)) - did = true; + for (GSList *items = original_selection; + items != NULL; + items = items->next) { + SPItem *item = SP_ITEM(items->data); + + if (is_transform_modes(tc->mode)) { + if (sp_spray_recursive(desktop, selection, item, p, vector, tc->mode, radius, move_force, tc->population, tc->scale, tc->scale_variation, reverse, move_mean, move_standard_deviation, tc->ratio, tc->tilt, tc->rotation_variation, tc->distrib)) { + did = true; + } + } else { + if (sp_spray_recursive(desktop, selection, item, p, vector, tc->mode, radius, path_force, tc->population, tc->scale, tc->scale_variation, reverse, path_mean, path_standard_deviation, tc->ratio, tc->tilt, tc->rotation_variation, tc->distrib)) { + did = true; + } + } + } + + for (GSList *items = original_selection; + items != NULL; + items = items->next) { + sp_object_unref(SP_ITEM(items->data)); } } @@ -735,6 +759,7 @@ bool SprayTool::root_handler(GdkEvent* event) { ret = TRUE; } break; +#ifdef ENABLE_SPRAY_MODE_SINGLE_PATH case GDK_KEY_l: case GDK_KEY_L: if (MOD__SHIFT_ONLY(event)) { @@ -742,6 +767,7 @@ bool SprayTool::root_handler(GdkEvent* event) { ret = TRUE; } break; +#endif case GDK_KEY_Up: case GDK_KEY_KP_Up: if (!MOD__CTRL_ONLY(event)) { @@ -854,7 +880,7 @@ bool SprayTool::root_handler(GdkEvent* event) { // if ((SP_EVENT_CONTEXT_CLASS(sp_spray_context_parent_class))->root_handler) { // ret = (SP_EVENT_CONTEXT_CLASS(sp_spray_context_parent_class))->root_handler(event_context, event); // } - ret = ToolBase::root_handler(event); + ret = ToolBase::root_handler(event); } return ret; -- cgit v1.2.3