From e244543e8df2d19c706c349139922189f01b63f8 Mon Sep 17 00:00:00 2001 From: Krzysztof Kosi??ski Date: Thu, 27 Feb 2014 02:01:31 +0100 Subject: Move extended input events stuff from desktop-widget.cpp to sp-canvas.cpp, where it belongs (bzr r13062) --- src/display/sp-canvas.cpp | 7 ++++++- src/widgets/desktop-widget.cpp | 5 ----- 2 files changed, 6 insertions(+), 6 deletions(-) (limited to 'src') diff --git a/src/display/sp-canvas.cpp b/src/display/sp-canvas.cpp index d9640f763..543962376 100644 --- a/src/display/sp-canvas.cpp +++ b/src/display/sp-canvas.cpp @@ -1387,8 +1387,13 @@ void SPCanvasImpl::realize(GtkWidget *widget) gdk_window_set_user_data (window, widget); Inkscape::Preferences *prefs = Inkscape::Preferences::get(); - if ( prefs->getBool("/options/useextinput/value", true) ) + if (prefs->getBool("/options/useextinput/value", true)) { gtk_widget_set_events(widget, attributes.event_mask); +#if !GTK_CHECK_VERSION(3,0,0) + gtk_widget_set_extension_events(widget, GDK_EXTENSION_EVENTS_ALL); + // TODO: Extension event stuff has been deprecated in GTK+ 3 +#endif + } #if !GTK_CHECK_VERSION(3,0,0) // This does nothing in GTK+ 3 diff --git a/src/widgets/desktop-widget.cpp b/src/widgets/desktop-widget.cpp index cf6a908b6..583dbec85 100644 --- a/src/widgets/desktop-widget.cpp +++ b/src/widgets/desktop-widget.cpp @@ -552,11 +552,6 @@ void SPDesktopWidget::init( SPDesktopWidget *dtw ) GtkStyle *style = gtk_style_copy(gtk_widget_get_style(GTK_WIDGET(dtw->canvas))); style->bg[GTK_STATE_NORMAL] = style->white; gtk_widget_set_style (GTK_WIDGET (dtw->canvas), style); - - // TODO: Extension event stuff has been removed from public API in GTK+ 3 - // Need to check that this hasn't broken anything - if ( prefs->getBool("/options/useextinput/value", true) ) - gtk_widget_set_extension_events(GTK_WIDGET (dtw->canvas) , GDK_EXTENSION_EVENTS_ALL); //set extension events for tablets, unless disabled in preferences #endif g_signal_connect (G_OBJECT (dtw->canvas), "event", G_CALLBACK (sp_desktop_widget_event), dtw); -- cgit v1.2.3 From a8d7f4db568ca421bab7f4d2828fe2d3c17e6072 Mon Sep 17 00:00:00 2001 From: Krzysztof Kosi??ski Date: Thu, 27 Feb 2014 04:54:34 +0100 Subject: Partial fix for LP #1001756 (crash when ungrouping a selection containing both a group and its clone). There are still some problems with undo/redo (incomplete undo transaction somewhere). (bzr r13063) --- src/selection-chemistry.cpp | 103 ++++++++++++++++++++++++++++++-------------- src/sp-use.cpp | 17 ++++++++ src/sp-use.h | 1 + 3 files changed, 89 insertions(+), 32 deletions(-) (limited to 'src') diff --git a/src/selection-chemistry.cpp b/src/selection-chemistry.cpp index c3d37af72..ea95cecd8 100644 --- a/src/selection-chemistry.cpp +++ b/src/selection-chemistry.cpp @@ -53,6 +53,7 @@ SPCycleType SP_CYCLING = SP_CYCLE_FOCUS; #include "sp-ellipse.h" #include "sp-star.h" #include "sp-spiral.h" +#include "sp-switch.h" #include "sp-polyline.h" #include "sp-line.h" #include "text-editing.h" @@ -767,57 +768,95 @@ void sp_selection_group(Inkscape::Selection *selection, SPDesktop *desktop) Inkscape::GC::release(group); } +static gint clone_depth_descending(gconstpointer a, gconstpointer b) { + SPUse *use_a = static_cast(const_cast(a)); + SPUse *use_b = static_cast(const_cast(b)); + int depth_a = use_a->cloneDepth(); + int depth_b = use_b->cloneDepth(); + if (depth_a < depth_b) { + return 1; + } else if (depth_a == depth_b) { + return 0; + } else { + return -1; + } +} + void sp_selection_ungroup(Inkscape::Selection *selection, SPDesktop *desktop) { if (selection->isEmpty()) { selection_display_message(desktop, Inkscape::WARNING_MESSAGE, _("Select a group to ungroup.")); + } + + // first check whether there is anything to ungroup + GSList *old_select = const_cast(selection->itemList()); + GSList *new_select = NULL; + GSList *groups = NULL; + for (GSList *item = old_select; item; item = item->next) { + SPItem *obj = static_cast(item->data); + if (SP_IS_GROUP(obj) && !SP_IS_SWITCH(obj)) { + groups = g_slist_prepend(groups, obj); + } + } + + if (groups == NULL) { + selection_display_message(desktop, Inkscape::ERROR_MESSAGE, _("No groups to ungroup in the selection.")); + g_slist_free(groups); return; } - GSList *items = g_slist_copy(const_cast(selection->itemList())); + GSList *items = g_slist_copy(old_select); selection->clear(); - // Get a copy of current selection. - GSList *new_select = NULL; - bool ungrouped = false; - for (GSList *i = items; - i != NULL; - i = i->next) - { - SPItem *group = static_cast(i->data); + // If any of the clones refer to the groups, unlink them and replace them with successors + // in the items list. + GSList *clones_to_unlink = NULL; + for (GSList *item = items; item; item = item->next) { + SPUse *use = dynamic_cast(static_cast(item->data)); - // when ungrouping cloned groups with their originals, some objects that were selected may no more exist due to unlinking - if (!SP_IS_OBJECT(group) || !group->getRepr()) { - continue; + SPItem *original = use; + while (SP_IS_USE(original)) { + original = SP_USE(original)->get_original(); } - // This check reflects the g_return_if_fail in sp_item_group_ungroup and - // may be a redundent. It also allows ungrouping of 'a' tags and we dont - if (strcmp(group->getRepr()->name(), "svg:g") && strcmp(group->getRepr()->name(), "svg:switch") && - strcmp(group->getRepr()->name(), "svg:svg")) { - // keep the non-group item in the new selection - new_select = g_slist_append(new_select, group); - continue; + if (g_slist_find(groups, original) != NULL) { + clones_to_unlink = g_slist_prepend(clones_to_unlink, item->data); } - - GSList *children = NULL; - /* This is not strictly required, but is nicer to rely on group ::destroy (lauris) */ - sp_item_group_ungroup(SP_GROUP(group), &children, false); - ungrouped = true; - // Add ungrouped items to the new selection. - new_select = g_slist_concat(new_select, children); } - if (new_select) { // Set new selection. - selection->addList(new_select); - g_slist_free(new_select); + // Unlink clones beginning from those with highest clone depth. + // This way we can be sure than no additional automatic unlinking happens, + // and the items in the list remain valid + clones_to_unlink = g_slist_sort(clones_to_unlink, clone_depth_descending); + + for (GSList *item = clones_to_unlink; item; item = item->next) { + SPUse *use = static_cast(item->data); + GSList *items_node = g_slist_find(items, item->data); + items_node->data = use->unlink(); } - if (!ungrouped) { - selection_display_message(desktop, Inkscape::ERROR_MESSAGE, _("No groups to ungroup in the selection.")); + g_slist_free(clones_to_unlink); + + // do the actual work + for (GSList *item = items; item; item = item->next) { + SPItem *obj = static_cast(item->data); + + // do not ungroup switches + if (SP_IS_GROUP(obj) && !SP_IS_SWITCH(obj)) { + GSList *children = NULL; + sp_item_group_ungroup(SP_GROUP(obj), &children, false); + // add the items resulting from ungrouping to the selection + new_select = g_slist_concat(new_select, children); + item->data = NULL; // zero out the original pointer, which is no longer valid + } else { + // if not a group, keep in the selection + new_select = g_slist_append(new_select, item->data); + } } + selection->addList(new_select); + g_slist_free(new_select); g_slist_free(items); - + DocumentUndo::done(selection->layers()->getDocument(), SP_VERB_SELECTION_UNGROUP, _("Ungroup")); } diff --git a/src/sp-use.cpp b/src/sp-use.cpp index b2a51b8d9..e394e84c2 100644 --- a/src/sp-use.cpp +++ b/src/sp-use.cpp @@ -299,6 +299,23 @@ SPItem const *SPUse::root() const { return const_cast(this)->root(); } +/** + * Get the number of dereferences or calls to get_original() needed to get an object + * which is not an svg:use. Returns -1 if there is no original object. + */ +int SPUse::cloneDepth() const { + unsigned depth = 1; + SPItem *orig = this->child; + + while (orig && SP_IS_USE(orig)) { + ++depth; + orig = SP_USE(orig)->child; + } + + if (!orig) return -1; + return depth; +} + /** * Returns the effective transform that goes from the ultimate original to given SPUse, both ends * included. diff --git a/src/sp-use.h b/src/sp-use.h index 31a52c1a1..604040d59 100644 --- a/src/sp-use.h +++ b/src/sp-use.h @@ -66,6 +66,7 @@ public: SPItem *root(); SPItem const *root() const; + int cloneDepth() const; SPItem *unlink(); SPItem *get_original(); -- cgit v1.2.3 From 6a9254d69806df5ac3f4c8eb6edc1b0cca57160e Mon Sep 17 00:00:00 2001 From: Krzysztof Kosi??ski Date: Thu, 27 Feb 2014 05:19:36 +0100 Subject: Correct the ungrouping logic so that selected clones of selected groups are only unlinked, with the resulting groups not ungrouped (bzr r13064) --- src/selection-chemistry.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'src') diff --git a/src/selection-chemistry.cpp b/src/selection-chemistry.cpp index ea95cecd8..821d078d1 100644 --- a/src/selection-chemistry.cpp +++ b/src/selection-chemistry.cpp @@ -840,8 +840,8 @@ void sp_selection_ungroup(Inkscape::Selection *selection, SPDesktop *desktop) for (GSList *item = items; item; item = item->next) { SPItem *obj = static_cast(item->data); - // do not ungroup switches - if (SP_IS_GROUP(obj) && !SP_IS_SWITCH(obj)) { + // ungroup only the groups marked earlier + if (g_slist_find(groups, item->data) != NULL) { GSList *children = NULL; sp_item_group_ungroup(SP_GROUP(obj), &children, false); // add the items resulting from ungrouping to the selection -- cgit v1.2.3 From 70d5e94706c772944411e12e13082b531ed2185e Mon Sep 17 00:00:00 2001 From: Tavmjong Bah Date: Thu, 27 Feb 2014 14:25:45 +0100 Subject: Don't overwrite SPItemCtx in SPRoot::update. (Maybe should be made const everywhere?) (bzr r13065) --- src/sp-root.cpp | 15 +++++++++++---- 1 file changed, 11 insertions(+), 4 deletions(-) (limited to 'src') diff --git a/src/sp-root.cpp b/src/sp-root.cpp index bc870b116..4f1444e31 100644 --- a/src/sp-root.cpp +++ b/src/sp-root.cpp @@ -221,7 +221,7 @@ void SPRoot::remove_child(Inkscape::XML::Node *child) void SPRoot::update(SPCtx *ctx, guint flags) { - SPItemCtx *ictx = (SPItemCtx *) ctx; + SPItemCtx const *ictx = (SPItemCtx const *) ctx; if( !this->parent ) { @@ -288,10 +288,17 @@ void SPRoot::update(SPCtx *ctx, guint flags) this->height.computed = this->height.value * ictx->viewport.height(); } + // std::cout << "SPRoot::update: final:" + // << " x: " << x.computed + // << " y: " << y.computed + // << " width: " << width.computed + // << " height: " << height.computed << std::endl; + // Calculate new viewport - ictx->viewport = Geom::Rect::from_xywh( this->x.computed, this->y.computed, - this->width.computed, this->height.computed ); - SPItemCtx rctx = get_rctx( ictx ); + SPItemCtx rctx = *ictx; + rctx.viewport = Geom::Rect::from_xywh( this->x.computed, this->y.computed, + this->width.computed, this->height.computed ); + rctx = get_rctx( &rctx ); /* And invoke parent method */ SPGroup::update((SPCtx *) &rctx, flags); -- cgit v1.2.3 From 0bb64f871043fa33fd7dc00df2aef6d9f0cfc4f4 Mon Sep 17 00:00:00 2001 From: Tomasz Boczkowski Date: Thu, 27 Feb 2014 14:43:12 +0100 Subject: Fix whitespace formatting of dbus documentation (bug 1282045) Fixed bugs: - https://launchpad.net/bugs/1282045 (bzr r13066) --- src/extension/dbus/doc/spec-to-docbook.xsl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src') diff --git a/src/extension/dbus/doc/spec-to-docbook.xsl b/src/extension/dbus/doc/spec-to-docbook.xsl index e200a05e0..a4e792df0 100644 --- a/src/extension/dbus/doc/spec-to-docbook.xsl +++ b/src/extension/dbus/doc/spec-to-docbook.xsl @@ -491,7 +491,7 @@ See also: - + -- cgit v1.2.3 From 532446c4121658b3da2841ec43c7d95e803525ca Mon Sep 17 00:00:00 2001 From: "Johan B. C. Engelen" Date: Thu, 27 Feb 2014 22:11:39 +0100 Subject: remove superfluous line of code (vector has just been constructed, so is empty) (bzr r13067) --- src/display/curve.cpp | 1 - 1 file changed, 1 deletion(-) (limited to 'src') diff --git a/src/display/curve.cpp b/src/display/curve.cpp index ae243853e..50f4c8954 100644 --- a/src/display/curve.cpp +++ b/src/display/curve.cpp @@ -34,7 +34,6 @@ SPCurve::SPCurve() : _refcount(1), _pathv() { - _pathv.clear(); } SPCurve::SPCurve(Geom::PathVector const& pathv) -- cgit v1.2.3 From 83e693c338fb585bed735d8302a700ba7ad39442 Mon Sep 17 00:00:00 2001 From: "Johan B. C. Engelen" Date: Thu, 27 Feb 2014 22:50:53 +0100 Subject: swatches dialog: properly reference count the reference to SPDocument in timer object. Fixes crash reported in comment #6 of bug 1284391! Fixed bugs: - https://launchpad.net/bugs/1284391 (bzr r13068) --- src/ui/dialog/swatches.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'src') diff --git a/src/ui/dialog/swatches.cpp b/src/ui/dialog/swatches.cpp index 3f161ad28..06b52e2e2 100644 --- a/src/ui/dialog/swatches.cpp +++ b/src/ui/dialog/swatches.cpp @@ -746,7 +746,7 @@ class DocTrack { public: DocTrack(SPDocument *doc, sigc::connection &gradientRsrcChanged, sigc::connection &defsChanged, sigc::connection &defsModified) : - doc(doc), + doc(doc->doRef()), updatePending(false), lastGradientUpdate(0.0), gradientRsrcChanged(gradientRsrcChanged), @@ -776,6 +776,7 @@ public: gradientRsrcChanged.disconnect(); defsChanged.disconnect(); defsModified.disconnect(); + doc->doUnref(); } } -- cgit v1.2.3 From b368877bf540ce4b6b06581d1f6955b6ce37e248 Mon Sep 17 00:00:00 2001 From: "Johan B. C. Engelen" Date: Thu, 27 Feb 2014 23:48:55 +0100 Subject: swatches dialog: remove unused code part. cleanup some code (bzr r13069) --- src/ui/dialog/swatches.cpp | 10 +++------- 1 file changed, 3 insertions(+), 7 deletions(-) (limited to 'src') diff --git a/src/ui/dialog/swatches.cpp b/src/ui/dialog/swatches.cpp index 06b52e2e2..807618b4d 100644 --- a/src/ui/dialog/swatches.cpp +++ b/src/ui/dialog/swatches.cpp @@ -777,6 +777,7 @@ public: defsChanged.disconnect(); defsModified.disconnect(); doc->doUnref(); + doc = NULL; } } @@ -859,7 +860,7 @@ bool DocTrack::queueUpdateIfNeeded( SPDocument *doc ) void SwatchesPanel::_trackDocument( SwatchesPanel *panel, SPDocument *document ) { - SPDocument *oldDoc = 0; + SPDocument *oldDoc = NULL; if (docPerPanel.find(panel) != docPerPanel.end()) { oldDoc = docPerPanel[panel]; if (!oldDoc) { @@ -868,7 +869,7 @@ void SwatchesPanel::_trackDocument( SwatchesPanel *panel, SPDocument *document ) } if (oldDoc != document) { if (oldDoc) { - docPerPanel[panel] = 0; + docPerPanel[panel] = NULL; bool found = false; for (std::map::iterator it = docPerPanel.begin(); (it != docPerPanel.end()) && !found; ++it) { found = (it->second == document); @@ -906,11 +907,6 @@ void SwatchesPanel::_trackDocument( SwatchesPanel *panel, SPDocument *document ) } } } - - std::set docs; - for (std::map::iterator it = docPerPanel.begin(); it != docPerPanel.end(); ++it) { - docs.insert(it->second); - } } void SwatchesPanel::_setDocument( SPDocument *document ) -- cgit v1.2.3 From a06efaf2a7e31b8ed38efead9259fd02560c5299 Mon Sep 17 00:00:00 2001 From: "Johan B. C. Engelen" Date: Fri, 28 Feb 2014 00:00:40 +0100 Subject: remove some unnecessary copying/casting (bzr r13070) --- src/ui/tools/spray-tool.cpp | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) (limited to 'src') diff --git a/src/ui/tools/spray-tool.cpp b/src/ui/tools/spray-tool.cpp index 2fc3f1c91..c9f9c8e91 100644 --- a/src/ui/tools/spray-tool.cpp +++ b/src/ui/tools/spray-tool.cpp @@ -114,9 +114,9 @@ inline double NormalDistribution(double mu, double sigma) static void sp_spray_rotate_rel(Geom::Point c, SPDesktop */*desktop*/, SPItem *item, Geom::Rotate const &rotation) { Geom::Translate const s(c); - Geom::Affine affine = Geom::Affine(s).inverse() * Geom::Affine(rotation) * Geom::Affine(s); + Geom::Affine affine = s.inverse() * rotation * s; // Rotate item. - item->set_i2d_affine(item->i2dt_affine() * (Geom::Affine)affine); + item->set_i2d_affine(item->i2dt_affine() * affine); // Use each item's own transform writer, consistent with sp_selection_apply_affine() item->doWriteTransform(item->getRepr(), item->transform); // Restore the center position (it's changed because the bbox center changed) @@ -516,8 +516,8 @@ static bool sp_spray_recursive(SPDesktop *desktop, static bool sp_spray_dilate(SprayTool *tc, Geom::Point /*event_p*/, Geom::Point p, Geom::Point vector, bool reverse) { - Inkscape::Selection *selection = sp_desktop_selection(SP_EVENT_CONTEXT(tc)->desktop); - SPDesktop *desktop = SP_EVENT_CONTEXT(tc)->desktop; + SPDesktop *desktop = tc->desktop; + Inkscape::Selection *selection = sp_desktop_selection(desktop); if (selection->isEmpty()) { return false; -- cgit v1.2.3 From 58301f7eaa81359ecd10506cbbe73d35060d6a9b Mon Sep 17 00:00:00 2001 From: Krzysztof Kosi??ski Date: Fri, 28 Feb 2014 03:46:20 +0100 Subject: Work around a crash in the Undo History dialog caused by incorrect modifications to the XML when ensureUpToDate() is called during SPDesktop initialization. The underlying problem remains to be fixed. (bzr r13071) --- src/desktop.cpp | 18 +++++++++++++++++- 1 file changed, 17 insertions(+), 1 deletion(-) (limited to 'src') diff --git a/src/desktop.cpp b/src/desktop.cpp index 364b5e930..a02baeac8 100644 --- a/src/desktop.cpp +++ b/src/desktop.cpp @@ -52,6 +52,7 @@ #include "display/sp-canvas.h" #include "display/sp-canvas-util.h" #include "document.h" +#include "document-undo.h" #include "event-log.h" #include "helper/action-context.h" #include "interface.h" @@ -167,8 +168,23 @@ SPDesktop::init (SPNamedView *nv, SPCanvas *aCanvas, Inkscape::UI::View::EditWid canvas = aCanvas; SPDocument *document = namedview->document; - /* Kill flicker */ + /* XXX: + * ensureUpToDate() sends a 'modified' signal to the root element. + * This is reportedly required to prevent flickering after the document + * loads. However, many SPObjects write to their repr in response + * to this signal. This is apparently done to support live path effects, + * which rewrite their result paths after each modification of the base object. + * This causes the generation of an incomplete undo transaction, + * which causes problems down the line, including crashes in the + * Undo History dialog. + * + * For now, this is handled by disabling undo tracking during this call. + * A proper fix would involve modifying the way ensureUpToDate() works, + * so that the LPE results are not rewritten. + */ + Inkscape::DocumentUndo::setUndoSensitive(document, false); document->ensureUpToDate(); + Inkscape::DocumentUndo::setUndoSensitive(document, true); /* Setup Dialog Manager */ _dlg_mgr = &Inkscape::UI::Dialog::DialogManager::getInstance(); -- cgit v1.2.3 From f776b7244d69143db71077456836d8745d6f30ed Mon Sep 17 00:00:00 2001 From: Krzysztof Kosi??ski Date: Fri, 28 Feb 2014 04:13:51 +0100 Subject: Copy event with gdk_event_copy instead of assigning to structure by value. Fixes problems on GTK+/Quartz 2.24.19. For more information, see LP #1198597 and https://bugzilla.gnome.org/show_bug.cgi?id=694273#c33 Fixed bugs: - https://launchpad.net/bugs/1198597 (bzr r13072) --- src/display/sp-canvas.cpp | 17 +++++++++-------- 1 file changed, 9 insertions(+), 8 deletions(-) (limited to 'src') diff --git a/src/display/sp-canvas.cpp b/src/display/sp-canvas.cpp index 543962376..c502daf64 100644 --- a/src/display/sp-canvas.cpp +++ b/src/display/sp-canvas.cpp @@ -1529,23 +1529,22 @@ int SPCanvasImpl::emitEvent(SPCanvas *canvas, GdkEvent *event) // Convert to world coordinates -- we have two cases because of different // offsets of the fields in the event structures. - // - GdkEvent ev = *event; + GdkEvent *ev = gdk_event_copy(event); - switch (ev.type) { + switch (ev->type) { case GDK_ENTER_NOTIFY: case GDK_LEAVE_NOTIFY: - ev.crossing.x += canvas->x0; - ev.crossing.y += canvas->y0; + ev->crossing.x += canvas->x0; + ev->crossing.y += canvas->y0; break; case GDK_MOTION_NOTIFY: case GDK_BUTTON_PRESS: case GDK_2BUTTON_PRESS: case GDK_3BUTTON_PRESS: case GDK_BUTTON_RELEASE: - ev.motion.x += canvas->x0; - ev.motion.y += canvas->y0; + ev->motion.x += canvas->x0; + ev->motion.y += canvas->y0; break; default: break; @@ -1598,12 +1597,14 @@ int SPCanvasImpl::emitEvent(SPCanvas *canvas, GdkEvent *event) while (item && !finished) { g_object_ref (item); - g_signal_emit (G_OBJECT (item), item_signals[ITEM_EVENT], 0, &ev, &finished); + g_signal_emit (G_OBJECT (item), item_signals[ITEM_EVENT], 0, ev, &finished); SPCanvasItem *parent = item->parent; g_object_unref (item); item = parent; } + gdk_event_free(ev); + return finished; } -- cgit v1.2.3 From 2b00f3b9bdfa55829ce5521f3de15b83b14b654a Mon Sep 17 00:00:00 2001 From: Tavmjong Bah Date: Fri, 28 Feb 2014 11:09:32 +0100 Subject: Use viewport when calculating filter region when filterUnits set to "userSpaceOnUse", fixes #229246. (bzr r13073) --- src/display/nr-filter.cpp | 23 +++++++++++++++-------- src/sp-filter.cpp | 28 ++++++++++++++++++++++++++++ 2 files changed, 43 insertions(+), 8 deletions(-) (limited to 'src') diff --git a/src/display/nr-filter.cpp b/src/display/nr-filter.cpp index 11984ba76..90b233fbc 100644 --- a/src/display/nr-filter.cpp +++ b/src/display/nr-filter.cpp @@ -222,14 +222,19 @@ void Filter::area_enlarge(Geom::IntRect &bbox, Inkscape::DrawingItem const *item Geom::OptRect Filter::filter_effect_area(Geom::OptRect const &bbox) { Geom::Point minp, maxp; - double len_x = bbox ? bbox->width() : 0; - double len_y = bbox ? bbox->height() : 0; - /* TODO: fetch somehow the object ex and em lengths */ - _region_x.update(12, 6, len_x); - _region_y.update(12, 6, len_y); - _region_width.update(12, 6, len_x); - _region_height.update(12, 6, len_y); + if (_filter_units == SP_FILTER_UNITS_OBJECTBOUNDINGBOX) { + + double len_x = bbox ? bbox->width() : 0; + double len_y = bbox ? bbox->height() : 0; + /* TODO: fetch somehow the object ex and em lengths */ + + // Update for em, ex, and % values + _region_x.update(12, 6, len_x); + _region_y.update(12, 6, len_y); + _region_width.update(12, 6, len_x); + _region_height.update(12, 6, len_y); + if (!bbox) return Geom::OptRect(); if (_region_x.unit == SVGLength::PERCENT) { @@ -254,7 +259,7 @@ Geom::OptRect Filter::filter_effect_area(Geom::OptRect const &bbox) maxp[Y] = minp[Y] + _region_height.computed * len_y; } } else if (_filter_units == SP_FILTER_UNITS_USERSPACEONUSE) { - /* TODO: make sure bbox and fe region are in same coordinate system */ + // Region already set in sp-filter.cpp minp[X] = _region_x.computed; maxp[X] = minp[X] + _region_width.computed; minp[Y] = _region_y.computed; @@ -262,7 +267,9 @@ Geom::OptRect Filter::filter_effect_area(Geom::OptRect const &bbox) } else { g_warning("Error in Inkscape::Filters::Filter::filter_effect_area: unrecognized value of _filter_units"); } + Geom::OptRect area(minp, maxp); + // std::cout << "Filter::filter_effect_area: area: " << *area << std::endl; return area; } diff --git a/src/sp-filter.cpp b/src/sp-filter.cpp index c3e7d217e..0e3d2d5ce 100644 --- a/src/sp-filter.cpp +++ b/src/sp-filter.cpp @@ -28,6 +28,7 @@ using std::pair; #include "sp-filter.h" #include "sp-filter-reference.h" #include "sp-filter-primitive.h" +#include "sp-item.h" #include "uri.h" #include "xml/repr.h" #include @@ -206,6 +207,33 @@ void SPFilter::update(SPCtx *ctx, guint flags) { if (flags & (SP_OBJECT_MODIFIED_FLAG | SP_OBJECT_STYLE_MODIFIED_FLAG | SP_OBJECT_VIEWPORT_MODIFIED_FLAG)) { + SPItemCtx *ictx = (SPItemCtx *) ctx; + + // Do here since we know viewport (Bounding box case handled during rendering) + // Note: This only works for root viewport since this routine is not called after + // setting a new viewport. A true fix requires a strategy like SPItemView or SPMarkerView. + if(this->filterUnits == SP_FILTER_UNITS_USERSPACEONUSE) { + std::cout << " userSpaceOnUse" << std::endl; + if (this->x.unit == SVGLength::PERCENT) { + this->x._set = true; + this->x.computed = this->x.value * ictx->viewport.width(); + } + + if (this->y.unit == SVGLength::PERCENT) { + this->y._set = true; + this->y.computed = this->y.value * ictx->viewport.height(); + } + + if (this->width.unit == SVGLength::PERCENT) { + this->width._set = true; + this->width.computed = this->width.value * ictx->viewport.width(); + } + + if (this->height.unit == SVGLength::PERCENT) { + this->height._set = true; + this->height.computed = this->height.value * ictx->viewport.height(); + } + } /* do something to trigger redisplay, updates? */ } -- cgit v1.2.3 From dd29914fcfe97975ce7145adc24cc556d67b83d2 Mon Sep 17 00:00:00 2001 From: Nicolas Dufour Date: Fri, 28 Feb 2014 14:56:31 +0100 Subject: Fix for Bug #1281859 (color gesture problems, alpha values below 0 and above 1). Fixed bugs: - https://launchpad.net/bugs/1281859 (bzr r13074) --- src/ui/widget/selected-style.cpp | 5 +++++ 1 file changed, 5 insertions(+) (limited to 'src') diff --git a/src/ui/widget/selected-style.cpp b/src/ui/widget/selected-style.cpp index d29554c41..042a6614e 100644 --- a/src/ui/widget/selected-style.cpp +++ b/src/ui/widget/selected-style.cpp @@ -1267,6 +1267,11 @@ RotateableSwatch::color_adjust(float *hsla, double by, guint32 cc, guint modifie } else if (modifier == 3) { // alpha double old = hsla[3]; hsla[3] += by/2; + if (hsla[3] < 0) { + hsla[3] = 0; + } else if (hsla[3] > 1) { + hsla[3] = 1; + } diff = hsla[3] - old; } else { // hue double old = hsla[0]; -- cgit v1.2.3 From fa0d3b889ad80af4b5a0c3f58226978a42e96b37 Mon Sep 17 00:00:00 2001 From: Tavmjong Bah Date: Fri, 28 Feb 2014 15:01:45 +0100 Subject: Properly identify an embedded SVG. (bzr r13075) --- src/sp-root.cpp | 3 +++ src/sp-root.h | 1 + 2 files changed, 4 insertions(+) (limited to 'src') diff --git a/src/sp-root.cpp b/src/sp-root.cpp index 4f1444e31..12570e03e 100644 --- a/src/sp-root.cpp +++ b/src/sp-root.cpp @@ -387,6 +387,9 @@ void SPRoot::print(SPPrintContext *ctx) sp_print_release(ctx); } +const char *SPRoot::displayName() const { + return "SVG"; // Do not translate +} /* Local Variables: diff --git a/src/sp-root.h b/src/sp-root.h index 1c9faed9b..0e5d87133 100644 --- a/src/sp-root.h +++ b/src/sp-root.h @@ -63,6 +63,7 @@ public: virtual Inkscape::DrawingItem* show(Inkscape::Drawing &drawing, unsigned int key, unsigned int flags); virtual void print(SPPrintContext *ctx); + virtual const char* displayName() const; }; #endif /* !SP_ROOT_H_SEEN */ -- cgit v1.2.3 From e32a54537e44cda5d90aa8b26d7fde87bff0ca58 Mon Sep 17 00:00:00 2001 From: Tavmjong Bah Date: Fri, 28 Feb 2014 15:08:12 +0100 Subject: Embedded SVG's cannot be transformed. (bzr r13076) --- src/selection-chemistry.cpp | 7 +++++++ src/seltrans.cpp | 6 ++++++ 2 files changed, 13 insertions(+) (limited to 'src') diff --git a/src/selection-chemistry.cpp b/src/selection-chemistry.cpp index 821d078d1..76be086a2 100644 --- a/src/selection-chemistry.cpp +++ b/src/selection-chemistry.cpp @@ -1497,6 +1497,13 @@ void sp_selection_apply_affine(Inkscape::Selection *selection, Geom::Affine cons for (GSList const *l = selection->itemList(); l != NULL; l = l->next) { SPItem *item = SP_ITEM(l->data); + if( SP_IS_ROOT(item) ) { + // An SVG element cannot have a transform. We could change 'x' and 'y' in response + // to a translation... but leave that for another day. + selection->desktop()->messageStack()->flash(Inkscape::WARNING_MESSAGE, _("Cannot transform an embedded SVG.")); + break; + } + Geom::Point old_center(0,0); if (set_i2d && item->isCenterSet()) old_center = item->getCenter(); diff --git a/src/seltrans.cpp b/src/seltrans.cpp index 78d9958c4..a55bc3c0d 100644 --- a/src/seltrans.cpp +++ b/src/seltrans.cpp @@ -29,11 +29,13 @@ #include "desktop-handles.h" #include "desktop-style.h" #include "knot.h" +#include "message-stack.h" #include "snap.h" #include "selection.h" #include "ui/tools/select-tool.h" #include "sp-item.h" #include "sp-item-transform.h" +#include "sp-root.h" #include "seltrans-handles.h" #include "seltrans.h" #include "selection-chemistry.h" @@ -381,6 +383,10 @@ void Inkscape::SelTrans::transform(Geom::Affine const &rel_affine, Geom::Point c // update the content for (unsigned i = 0; i < _items.size(); i++) { SPItem &item = *_items[i]; + if( SP_IS_ROOT(&item) ) { + _desktop->messageStack()->flash(Inkscape::WARNING_MESSAGE, _("Cannot transform an embedded SVG.")); + break; + } Geom::Affine const &prev_transform = _items_affines[i]; item.set_i2d_affine(prev_transform * affine); } -- cgit v1.2.3 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 ++++++++++++++++++++++++++++--------------- src/widgets/spray-toolbar.cpp | 8 +++- 2 files changed, 64 insertions(+), 34 deletions(-) (limited to 'src') 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; diff --git a/src/widgets/spray-toolbar.cpp b/src/widgets/spray-toolbar.cpp index 2a8c85475..49406d564 100644 --- a/src/widgets/spray-toolbar.cpp +++ b/src/widgets/spray-toolbar.cpp @@ -60,6 +60,10 @@ using Inkscape::DocumentUndo; using Inkscape::UI::ToolboxFactory; using Inkscape::UI::PrefPusher; +// 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 //######################## //## Spray ## @@ -186,14 +190,14 @@ void sp_spray_toolbox_prep(SPDesktop *desktop, GtkActionGroup* mainActions, GObj 1, _("Spray clones of the initial selection"), 2, INKSCAPE_ICON("spray-mode-clone"), -1 ); - +#ifdef ENABLE_SPRAY_MODE_SINGLE_PATH gtk_list_store_append( model, &iter ); gtk_list_store_set( model, &iter, 0, _("Spray single path"), 1, _("Spray objects in a single path"), 2, INKSCAPE_ICON("spray-mode-union"), -1 ); - +#endif EgeSelectOneAction* act = ege_select_one_action_new( "SprayModeAction", _("Mode"), (""), NULL, GTK_TREE_MODEL(model) ); g_object_set( act, "short_label", _("Mode:"), NULL ); gtk_action_group_add_action( mainActions, GTK_ACTION(act) ); -- cgit v1.2.3