diff options
| author | Jabier Arraiza Cenoz <jabier.arraiza@marker.es> | 2013-10-02 22:15:00 +0000 |
|---|---|---|
| committer | Jabiertxof <jtx@jtx.marker.es> | 2013-10-02 22:15:00 +0000 |
| commit | aa6d389286f6402ef393015b000755bc3124362a (patch) | |
| tree | 81e17d682f5aade76e44bc8809e751b42dd5f773 /src | |
| parent | Fixed a bug editing paths in others LPE -envelope- (diff) | |
| parent | Fix segment welding in the node tool hanging when a two-point segment (diff) | |
| download | inkscape-aa6d389286f6402ef393015b000755bc3124362a.tar.gz inkscape-aa6d389286f6402ef393015b000755bc3124362a.zip | |
update to trunk
(bzr r11950.1.158)
Diffstat (limited to 'src')
28 files changed, 253 insertions, 188 deletions
diff --git a/src/color-profile.cpp b/src/color-profile.cpp index e8a6a9c98..e6a9ac71c 100644 --- a/src/color-profile.cpp +++ b/src/color-profile.cpp @@ -829,7 +829,7 @@ std::vector<Glib::ustring> ColorProfile::getProfileFiles() for (gchar const *file = g_dir_read_name(dir); file != NULL; file = g_dir_read_name(dir)) { gchar *filepath = g_build_filename(it->c_str(), file, NULL); if ( g_file_test( filepath, G_FILE_TEST_IS_DIR ) ) { - sources.push_back(g_strdup(filepath)); + sources.push_back( filepath ); } else { if ( isIccFile( filepath ) ) { files.push_back( filepath ); diff --git a/src/display/drawing-item.cpp b/src/display/drawing-item.cpp index 1af07cb44..71a7f8906 100644 --- a/src/display/drawing-item.cpp +++ b/src/display/drawing-item.cpp @@ -141,7 +141,14 @@ DrawingItem::appendChild(DrawingItem *item) assert(item->_child_type == CHILD_ORPHAN); item->_child_type = CHILD_NORMAL; _children.push_back(*item); - _markForUpdate(STATE_ALL, false); + + // This ensures that _markForUpdate() called on the child will recurse to this item + item->_state = STATE_ALL; + // Because _markForUpdate recurses through ancestors, we can simply call it + // on the just-added child. This has the additional benefit that we do not + // rely on the appended child being in the default non-updated state. + // We set propagate to true, because the child might have descendants of its own. + item->_markForUpdate(STATE_ALL, true); } void @@ -151,7 +158,9 @@ DrawingItem::prependChild(DrawingItem *item) assert(item->_child_type == CHILD_ORPHAN); item->_child_type = CHILD_NORMAL; _children.push_front(*item); - _markForUpdate(STATE_ALL, false); + // See appendChild for explanation + item->_state = STATE_ALL; + item->_markForUpdate(STATE_ALL, true); } /// Delete all regular children of this item (not mask or clip). @@ -281,17 +290,10 @@ DrawingItem::setZOrder(unsigned z) _markForRendering(); } -void DrawingItem::setItemBounds(Geom::OptRect const &bounds) -{ - if (!bounds) return; - Geom::IntRect copy = bounds->roundOutwards(); - if (_filter) _filter->area_enlarge(copy, this); - this->setFilterBounds(copy); -} - -void DrawingItem::setFilterBounds(Geom::OptRect const &bounds) +void +DrawingItem::setItemBounds(Geom::OptRect const &bounds) { - if (bounds) _filter_bbox = bounds; + _item_bbox = bounds; } /** @@ -359,10 +361,14 @@ DrawingItem::update(Geom::IntRect const &area, UpdateContext const &ctx, unsigne if (to_update & STATE_BBOX) { // compute drawbox - if (_filter && render_filters && _filter_bbox) { - Geom::OptRect enlarged = _filter_bbox; - *enlarged *= ctm(); - _drawbox = enlarged->roundOutwards(); + if (_filter && render_filters) { + Geom::OptRect enlarged = _filter->filter_effect_area(_item_bbox); + if (enlarged) { + *enlarged *= ctm(); + _drawbox = enlarged->roundOutwards(); + } else { + _drawbox = Geom::OptIntRect(); + } } else { _drawbox = _bbox; } @@ -714,8 +720,11 @@ DrawingItem::pick(Geom::Point const &p, double delta, unsigned flags) { // Sometimes there's no BBOX in state, reason unknown (bug 992817) // I made this not an assert to remove the warning - if (!(_state & STATE_BBOX) || !(_state & STATE_PICK)) + if (!(_state & STATE_BBOX) || !(_state & STATE_PICK)) { + g_warning("Invalid state when picking: STATE_BBOX = %d, STATE_PICK = %d", + _state & STATE_BBOX, _state & STATE_PICK); return NULL; + } // ignore invisible and insensitive items unless sticky if (!(flags & PICK_STICKY) && !(_visible && _sensitive)) return NULL; @@ -736,7 +745,10 @@ DrawingItem::pick(Geom::Point const &p, double delta, unsigned flags) } Geom::OptIntRect box = (outline || (flags & PICK_AS_CLIP)) ? _bbox : _drawbox; - if (!box) return NULL; + if (!box) { + g_warning("bbox unset when picking"); + return NULL; + } Geom::Rect expanded = *box; expanded.expandBy(delta); @@ -756,6 +768,9 @@ DrawingItem::pick(Geom::Point const &p, double delta, unsigned flags) void DrawingItem::_markForRendering() { + // TODO: this function does too much work when a large subtree + // is invalidated - fix + bool outline = _drawing.outline(); Geom::OptIntRect dirty = outline ? _bbox : _drawbox; if (!dirty) return; @@ -807,8 +822,8 @@ DrawingItem::_invalidateFilterBackground(Geom::IntRect const &area) * all children should also have the corresponding flags unset before checking * whether they need to be traversed. This way there is one less traversal * of the tree. Without this we would need to unset state bits in all children. - * With _propagate we do this during the update call, when we have to traverse - * the tree anyway. + * With _propagate we do this during the update call, when we have to recurse + * into children anyway. */ void DrawingItem::_markForUpdate(unsigned flags, bool propagate) @@ -818,15 +833,31 @@ DrawingItem::_markForUpdate(unsigned flags, bool propagate) } if (_state & flags) { + unsigned oldstate = _state; _state &= ~flags; - if (_parent) { + if (oldstate != _state && _parent) { + // If we actually reset anything in state, recurse on the parent. _parent->_markForUpdate(flags, false); } else { + // If nothing changed, it means our ancestors are already invalidated + // up to the root. Do not bother recursing, because it won't change anything. + // Also do this if we are the root item, because we have no more ancestors + // to invalidate. _drawing.signal_request_update.emit(this); } } } +/** + * Process information related to the new style. + * + * This function is something of a hack to avoid creating an extra class in the hierarchy + * which would differ from DrawingItem only by having a _style member. + * This is mainly to the benefit of DrawingGlyphs, which use the style of their parent. + * This should probably be refactored some day, possibly by creating the relevant class + * or creating a more complex data model in DrawingText and removing DrawingGlyphs, + * which would cause every item to have a style. + */ void DrawingItem::_setStyleCommon(SPStyle *&_style, SPStyle *style) { @@ -834,7 +865,6 @@ DrawingItem::_setStyleCommon(SPStyle *&_style, SPStyle *style) if (_style) sp_style_unref(_style); _style = style; - // if group has a filter if (style->filter.set && style->getFilter()) { if (!_filter) { int primitives = sp_filter_primitive_count(SP_FILTER(style->getFilter())); diff --git a/src/display/drawing-item.h b/src/display/drawing-item.h index c69b996b4..e03bbd0f7 100644 --- a/src/display/drawing-item.h +++ b/src/display/drawing-item.h @@ -89,7 +89,7 @@ public: Geom::OptIntRect geometricBounds() const { return _bbox; } Geom::OptIntRect visualBounds() const { return _drawbox; } - Geom::OptRect filterBounds() const { return _filter_bbox; } + Geom::OptRect itemBounds() const { return _item_bbox; } Geom::Affine ctm() const { return _ctm; } Geom::Affine transform() const { return _transform ? *_transform : Geom::identity(); } Drawing &drawing() const { return _drawing; } @@ -176,7 +176,9 @@ protected: Geom::Affine _ctm; ///< Total transform from item coords to display coords Geom::OptIntRect _bbox; ///< Bounding box in display (pixel) coords including stroke Geom::OptIntRect _drawbox; ///< Full visual bounding box - enlarged by filters, shrunk by clips and masks - Geom::OptRect _filter_bbox; ///< Used by filters when settings bounds + Geom::OptRect _item_bbox; ///< Geometric bounding box in item's user space. + /// This is used to compute the filter effect region and render in + /// objectBoundingBox units. DrawingItem *_clip; DrawingItem *_mask; diff --git a/src/display/drawing-shape.cpp b/src/display/drawing-shape.cpp index e689d0755..e80f12486 100644 --- a/src/display/drawing-shape.cpp +++ b/src/display/drawing-shape.cpp @@ -179,8 +179,8 @@ DrawingShape::_renderItem(DrawingContext &ct, Geom::IntRect const &area, unsigne // update fill and stroke paints. // this cannot be done during nr_arena_shape_update, because we need a Cairo context // to render svg:pattern - has_fill = _nrstyle.prepareFill(ct, _bbox); - has_stroke = _nrstyle.prepareStroke(ct, _bbox); + has_fill = _nrstyle.prepareFill(ct, _item_bbox); + has_stroke = _nrstyle.prepareStroke(ct, _item_bbox); has_stroke &= (_nrstyle.stroke_width != 0); if (has_fill || has_stroke) { diff --git a/src/display/drawing-text.cpp b/src/display/drawing-text.cpp index fa9ce4ff8..55d54b770 100644 --- a/src/display/drawing-text.cpp +++ b/src/display/drawing-text.cpp @@ -398,8 +398,8 @@ unsigned DrawingText::_renderItem(DrawingContext &ct, Geom::IntRect const &/*are using Geom::X; using Geom::Y; - has_fill = _nrstyle.prepareFill( ct, _bbox); - has_stroke = _nrstyle.prepareStroke(ct, _bbox); + has_fill = _nrstyle.prepareFill( ct, _item_bbox); + has_stroke = _nrstyle.prepareStroke(ct, _item_bbox); if (has_fill || has_stroke) { Geom::Affine rotinv; diff --git a/src/display/guideline.cpp b/src/display/guideline.cpp index f71bc82ef..55c1ee495 100644 --- a/src/display/guideline.cpp +++ b/src/display/guideline.cpp @@ -94,14 +94,20 @@ static void sp_guideline_destroy(SPCanvasItem *object) g_return_if_fail (SP_IS_GUIDELINE (object)); //g_return_if_fail (SP_GUIDELINE(object)->origin != NULL); //g_return_if_fail (SP_IS_CTRLPOINT(SP_GUIDELINE(object)->origin)); - - if (SP_GUIDELINE(object)->origin != NULL && SP_IS_CTRLPOINT(SP_GUIDELINE(object)->origin)) { - sp_canvas_item_destroy(SP_GUIDELINE(object)->origin); + + SPGuideLine *gl = SP_GUIDELINE(object); + + if (gl->origin != NULL && SP_IS_CTRLPOINT(gl->origin)) { + sp_canvas_item_destroy(gl->origin); } else { // FIXME: This branch shouldn't be reached (although it seems to be harmless). //g_error("Why can it be that gl->origin is not a valid SPCtrlPoint?\n"); } + if (gl->label) { + g_free(gl->label); + } + SP_CANVAS_ITEM_CLASS(parent_class)->destroy(object); } diff --git a/src/display/nr-filter.cpp b/src/display/nr-filter.cpp index c0044c5d8..af9c15cd8 100644 --- a/src/display/nr-filter.cpp +++ b/src/display/nr-filter.cpp @@ -114,14 +114,12 @@ int Filter::render(Inkscape::DrawingItem const *item, DrawingContext &graphic, D Geom::Affine trans = item->ctm(); - // Get filter are, the filter_effect_area is already done in visualBounds - Geom::OptRect filter_area = item->filterBounds(); - // Use the geometricBounds as a backup solution + Geom::OptRect filter_area = filter_effect_area(item->itemBounds()); if (!filter_area) return 1; FilterUnits units(_filter_units, _primitive_units); units.set_ctm(trans); - units.set_item_bbox(filter_area); + units.set_item_bbox(item->itemBounds()); units.set_filter_area(*filter_area); std::pair<double,double> resolution @@ -201,7 +199,7 @@ void Filter::area_enlarge(Geom::IntRect &bbox, Inkscape::DrawingItem const *item } Geom::Rect item_bbox; - Geom::OptRect maybe_bbox = item->geometricBounds(); + Geom::OptRect maybe_bbox = item->itemBounds(); if (maybe_bbox.isEmpty()) { // Code below needs a bounding box return; diff --git a/src/extension/dbus/document-interface.cpp b/src/extension/dbus/document-interface.cpp index ccc39fbef..221a3e879 100644 --- a/src/extension/dbus/document-interface.cpp +++ b/src/extension/dbus/document-interface.cpp @@ -268,7 +268,7 @@ dbus_call_verb (DocumentInterface *doc_interface, int verbid, GError **error) if ( action ) { sp_action_perform( action, NULL ); if (doc_interface->updates) - Inkscape::DocumentUndo::done(doc_interface->target.getDocument(), verb->get_code(), g_strdup(verb->get_tip())); + Inkscape::DocumentUndo::done(doc_interface->target.getDocument(), verb->get_code(), verb->get_tip()); return TRUE; } } @@ -357,7 +357,7 @@ document_interface_call_verb (DocumentInterface *doc_interface, gchar *verbid, G if ( action ) { sp_action_perform( action, NULL ); if (doc_interface->updates) { - Inkscape::DocumentUndo::done(doc_interface->target.getDocument(), verb->get_code(), g_strdup(verb->get_tip())); + Inkscape::DocumentUndo::done(doc_interface->target.getDocument(), verb->get_code(), verb->get_tip()); } return TRUE; } diff --git a/src/extension/internal/metafile-print.h b/src/extension/internal/metafile-print.h index cba4d564d..a21f9de58 100644 --- a/src/extension/internal/metafile-print.h +++ b/src/extension/internal/metafile-print.h @@ -26,8 +26,8 @@ #include "splivarot.h" #include "display/canvas-bpath.h" -struct SPGradient; -struct SPObject; +class SPGradient; +class SPObject; namespace Inkscape { class Pixbuf; diff --git a/src/libnrtype/Layout-TNG-Output.cpp b/src/libnrtype/Layout-TNG-Output.cpp index 1989c495a..bdc786749 100644 --- a/src/libnrtype/Layout-TNG-Output.cpp +++ b/src/libnrtype/Layout-TNG-Output.cpp @@ -181,6 +181,7 @@ void Layout::show(DrawingGroup *in_arena, Geom::OptRect const &paintbox) const glyph_index++; } nr_text->setStyle(text_source->style); + nr_text->setItemBounds(paintbox); in_arena->prependChild(nr_text); // Set item bounds without filter enlargement in_arena->setItemBounds(paintbox); diff --git a/src/selection-chemistry.cpp b/src/selection-chemistry.cpp index c22ed777b..2105ca99a 100644 --- a/src/selection-chemistry.cpp +++ b/src/selection-chemistry.cpp @@ -2512,7 +2512,9 @@ void sp_selection_clone(SPDesktop *desktop) Inkscape::XML::Node *clone = xml_doc->createElement("svg:use"); clone->setAttribute("x", "0", false); clone->setAttribute("y", "0", false); - clone->setAttribute("xlink:href", g_strdup_printf("#%s", sel_repr->attribute("id")), false); + gchar *href_str = g_strdup_printf("#%s", sel_repr->attribute("id")); + clone->setAttribute("xlink:href", href_str, false); + g_free(href_str); clone->setAttribute("inkscape:transform-center-x", sel_repr->attribute("inkscape:transform-center-x"), false); clone->setAttribute("inkscape:transform-center-y", sel_repr->attribute("inkscape:transform-center-y"), false); @@ -2993,7 +2995,9 @@ void sp_selection_symbol(SPDocument *doc, SPObject *group) Inkscape::XML::Node *clone = xml_doc->createElement("svg:use"); clone->setAttribute("x", "0", false); clone->setAttribute("y", "0", false); - clone->setAttribute("xlink:href", g_strdup_printf("#%s", id.c_str()), false); + gchar *href_str = g_strdup_printf("#%s", id.c_str()); + clone->setAttribute("xlink:href", href_str, false); + g_free(href_str); clone->setAttribute("inkscape:transform-center-x", group->getAttribute("inkscape:transform-center-x"), false); clone->setAttribute("inkscape:transform-center-y", group->getAttribute("inkscape:transform-center-y"), false); @@ -3153,7 +3157,9 @@ sp_selection_tile(SPDesktop *desktop, bool apply) if (apply) { Inkscape::XML::Node *rect = xml_doc->createElement("svg:rect"); - rect->setAttribute("style", g_strdup_printf("stroke:none;fill:url(#%s)", pat_id)); + gchar *style_str = g_strdup_printf("stroke:none;fill:url(#%s)", pat_id); + rect->setAttribute("style", style_str); + g_free(style_str); Geom::Point min = bbox.min() * parent_transform.inverse(); Geom::Point max = bbox.max() * parent_transform.inverse(); @@ -3719,7 +3725,9 @@ void sp_selection_set_mask(SPDesktop *desktop, bool apply_clip_path, bool apply_ Inkscape::GC::release(group); } - apply_mask_to->setAttribute(attributeName, g_strdup_printf("url(#%s)", mask_id)); + gchar *value_str = g_strdup_printf("url(#%s)", mask_id); + apply_mask_to->setAttribute(attributeName, value_str); + g_free(value_str); } diff --git a/src/sp-flowdiv.cpp b/src/sp-flowdiv.cpp index 867e68441..00ba48b06 100644 --- a/src/sp-flowdiv.cpp +++ b/src/sp-flowdiv.cpp @@ -54,13 +54,11 @@ void SPFlowdiv::update(SPCtx *ctx, unsigned int flags) { SPItemCtx *ictx = reinterpret_cast<SPItemCtx *>(ctx); SPItemCtx cctx = *ictx; - SPItem::update(ctx, flags); - + unsigned childflags = flags; if (flags & SP_OBJECT_MODIFIED_FLAG) { - flags |= SP_OBJECT_PARENT_MODIFIED_FLAG; + childflags |= SP_OBJECT_PARENT_MODIFIED_FLAG; } - - flags &= SP_OBJECT_MODIFIED_CASCADE; + childflags &= SP_OBJECT_MODIFIED_CASCADE; GSList* l = NULL; for (SPObject *child = this->firstChild() ; child ; child = child->getNext() ) { @@ -74,19 +72,21 @@ void SPFlowdiv::update(SPCtx *ctx, unsigned int flags) { SPObject *child = SP_OBJECT(l->data); l = g_slist_remove(l, child); - if (flags || (child->uflags & (SP_OBJECT_MODIFIED_FLAG | SP_OBJECT_CHILD_MODIFIED_FLAG))) { + if (childflags || (child->uflags & (SP_OBJECT_MODIFIED_FLAG | SP_OBJECT_CHILD_MODIFIED_FLAG))) { if (SP_IS_ITEM(child)) { SPItem const &chi = *SP_ITEM(child); cctx.i2doc = chi.transform * ictx->i2doc; cctx.i2vp = chi.transform * ictx->i2vp; - child->updateDisplay((SPCtx *)&cctx, flags); + child->updateDisplay((SPCtx *)&cctx, childflags); } else { - child->updateDisplay(ctx, flags); + child->updateDisplay(ctx, childflags); } } sp_object_unref(child); } + + SPItem::update(ctx, flags); } void SPFlowdiv::modified(unsigned int flags) { @@ -195,13 +195,11 @@ void SPFlowtspan::update(SPCtx *ctx, unsigned int flags) { SPItemCtx *ictx = reinterpret_cast<SPItemCtx *>(ctx); SPItemCtx cctx = *ictx; - SPItem::update(ctx, flags); - + unsigned childflags = flags; if (flags & SP_OBJECT_MODIFIED_FLAG) { - flags |= SP_OBJECT_PARENT_MODIFIED_FLAG; + childflags |= SP_OBJECT_PARENT_MODIFIED_FLAG; } - - flags &= SP_OBJECT_MODIFIED_CASCADE; + childflags &= SP_OBJECT_MODIFIED_CASCADE; GSList* l = NULL; for ( SPObject *child = this->firstChild() ; child ; child = child->getNext() ) { @@ -215,19 +213,21 @@ void SPFlowtspan::update(SPCtx *ctx, unsigned int flags) { SPObject *child = SP_OBJECT(l->data); l = g_slist_remove(l, child); - if (flags || (child->uflags & (SP_OBJECT_MODIFIED_FLAG | SP_OBJECT_CHILD_MODIFIED_FLAG))) { + if (childflags || (child->uflags & (SP_OBJECT_MODIFIED_FLAG | SP_OBJECT_CHILD_MODIFIED_FLAG))) { if (SP_IS_ITEM(child)) { SPItem const &chi = *SP_ITEM(child); cctx.i2doc = chi.transform * ictx->i2doc; cctx.i2vp = chi.transform * ictx->i2vp; - child->updateDisplay((SPCtx *)&cctx, flags); + child->updateDisplay((SPCtx *)&cctx, childflags); } else { - child->updateDisplay(ctx, flags); + child->updateDisplay(ctx, childflags); } } sp_object_unref(child); } + + SPItem::update(ctx, flags); } void SPFlowtspan::modified(unsigned int flags) { diff --git a/src/sp-flowregion.cpp b/src/sp-flowregion.cpp index ed17f1948..13ab7bc64 100644 --- a/src/sp-flowregion.cpp +++ b/src/sp-flowregion.cpp @@ -72,13 +72,11 @@ void SPFlowregion::update(SPCtx *ctx, unsigned int flags) { SPItemCtx *ictx = reinterpret_cast<SPItemCtx *>(ctx); SPItemCtx cctx = *ictx; - SPItem::update(ctx, flags); - + unsigned childflags = flags; if (flags & SP_OBJECT_MODIFIED_FLAG) { - flags |= SP_OBJECT_PARENT_MODIFIED_FLAG; + childflags |= SP_OBJECT_PARENT_MODIFIED_FLAG; } - - flags &= SP_OBJECT_MODIFIED_CASCADE; + childflags &= SP_OBJECT_MODIFIED_CASCADE; GSList *l = NULL; @@ -93,20 +91,22 @@ void SPFlowregion::update(SPCtx *ctx, unsigned int flags) { SPObject *child = SP_OBJECT(l->data); l = g_slist_remove(l, child); - if (flags || (child->uflags & (SP_OBJECT_MODIFIED_FLAG | SP_OBJECT_CHILD_MODIFIED_FLAG))) { + if (childflags || (child->uflags & (SP_OBJECT_MODIFIED_FLAG | SP_OBJECT_CHILD_MODIFIED_FLAG))) { if (SP_IS_ITEM (child)) { SPItem const &chi = *SP_ITEM(child); cctx.i2doc = chi.transform * ictx->i2doc; cctx.i2vp = chi.transform * ictx->i2vp; - child->updateDisplay((SPCtx *)&cctx, flags); + child->updateDisplay((SPCtx *)&cctx, childflags); } else { - child->updateDisplay(ctx, flags); + child->updateDisplay(ctx, childflags); } } sp_object_unref(child); } + SPItem::update(ctx, flags); + this->UpdateComputed(); } diff --git a/src/sp-flowtext.cpp b/src/sp-flowtext.cpp index 266e9dfe0..49360f9d9 100644 --- a/src/sp-flowtext.cpp +++ b/src/sp-flowtext.cpp @@ -72,10 +72,11 @@ void SPFlowtext::update(SPCtx* ctx, unsigned int flags) { SPItemCtx *ictx = (SPItemCtx *) ctx; SPItemCtx cctx = *ictx; - SPItem::update(ctx, flags); - - if (flags & SP_OBJECT_MODIFIED_FLAG) flags |= SP_OBJECT_PARENT_MODIFIED_FLAG; - flags &= SP_OBJECT_MODIFIED_CASCADE; + unsigned childflags = flags; + if (flags & SP_OBJECT_MODIFIED_FLAG) { + childflags |= SP_OBJECT_PARENT_MODIFIED_FLAG; + } + childflags &= SP_OBJECT_MODIFIED_CASCADE; GSList *l = NULL; @@ -90,20 +91,22 @@ void SPFlowtext::update(SPCtx* ctx, unsigned int flags) { SPObject *child = SP_OBJECT(l->data); l = g_slist_remove(l, child); - if (flags || (child->uflags & (SP_OBJECT_MODIFIED_FLAG | SP_OBJECT_CHILD_MODIFIED_FLAG))) { + if (childflags || (child->uflags & (SP_OBJECT_MODIFIED_FLAG | SP_OBJECT_CHILD_MODIFIED_FLAG))) { if (SP_IS_ITEM(child)) { SPItem const &chi = *SP_ITEM(child); cctx.i2doc = chi.transform * ictx->i2doc; cctx.i2vp = chi.transform * ictx->i2vp; - child->updateDisplay((SPCtx *)&cctx, flags); + child->updateDisplay((SPCtx *)&cctx, childflags); } else { - child->updateDisplay(ctx, flags); + child->updateDisplay(ctx, childflags); } } sp_object_unref(child); } + SPItem::update(ctx, flags); + this->rebuildLayout(); Geom::OptRect pbox = this->geometricBounds(); diff --git a/src/sp-item-group.cpp b/src/sp-item-group.cpp index a99a3e988..41e049b86 100644 --- a/src/sp-item-group.cpp +++ b/src/sp-item-group.cpp @@ -161,44 +161,49 @@ void SPGroup::order_changed (Inkscape::XML::Node *child, Inkscape::XML::Node *ol } void SPGroup::update(SPCtx *ctx, unsigned int flags) { - SPLPEItem::update(ctx, flags); - SPItemCtx *ictx, cctx; ictx = (SPItemCtx *) ctx; cctx = *ictx; - if (flags & SP_OBJECT_MODIFIED_FLAG) { - flags |= SP_OBJECT_PARENT_MODIFIED_FLAG; - } + unsigned childflags = flags; - flags &= SP_OBJECT_MODIFIED_CASCADE; - - if (flags & SP_OBJECT_STYLE_MODIFIED_FLAG) { - for (SPItemView *v = this->display; v != NULL; v = v->next) { - Inkscape::DrawingGroup *group = dynamic_cast<Inkscape::DrawingGroup *>(v->arenaitem); - group->setStyle(this->style); - } + if (flags & SP_OBJECT_MODIFIED_FLAG) { + childflags |= SP_OBJECT_PARENT_MODIFIED_FLAG; } + childflags &= SP_OBJECT_MODIFIED_CASCADE; GSList *l = g_slist_reverse(this->childList(true, SPObject::ActionUpdate)); while (l) { SPObject *child = SP_OBJECT (l->data); l = g_slist_remove (l, child); - if (flags || (child->uflags & (SP_OBJECT_MODIFIED_FLAG | SP_OBJECT_CHILD_MODIFIED_FLAG))) { + if (childflags || (child->uflags & (SP_OBJECT_MODIFIED_FLAG | SP_OBJECT_CHILD_MODIFIED_FLAG))) { if (SP_IS_ITEM (child)) { SPItem const &chi = *SP_ITEM(child); cctx.i2doc = chi.transform * ictx->i2doc; cctx.i2vp = chi.transform * ictx->i2vp; - child->updateDisplay((SPCtx *)&cctx, flags); + child->updateDisplay((SPCtx *)&cctx, childflags); } else { - child->updateDisplay(ctx, flags); + child->updateDisplay(ctx, childflags); } } sp_object_unref(child); } + + // For a group, we need to update ourselves *after* updating children. + // this is because the group might contain shapes such as rect or ellipse, + // which recompute their equivalent path (a.k.a curve) in the update callback, + // and this is in turn used when computing bbox. + SPLPEItem::update(ctx, flags); + + if (flags & SP_OBJECT_STYLE_MODIFIED_FLAG) { + for (SPItemView *v = this->display; v != NULL; v = v->next) { + Inkscape::DrawingGroup *group = dynamic_cast<Inkscape::DrawingGroup *>(v->arenaitem); + group->setStyle(this->style); + } + } } void SPGroup::modified(guint flags) { @@ -212,13 +217,6 @@ void SPGroup::modified(guint flags) { flags &= SP_OBJECT_MODIFIED_CASCADE; - if (flags & SP_OBJECT_STYLE_MODIFIED_FLAG) { - for (SPItemView *v = this->display; v != NULL; v = v->next) { - Inkscape::DrawingGroup *group = dynamic_cast<Inkscape::DrawingGroup *>(v->arenaitem); - group->setStyle(this->style); - } - } - GSList *l = g_slist_reverse(this->childList(true)); while (l) { diff --git a/src/sp-item.cpp b/src/sp-item.cpp index c342bfd9b..5bf0afdeb 100644 --- a/src/sp-item.cpp +++ b/src/sp-item.cpp @@ -603,13 +603,13 @@ void SPItem::update(SPCtx *ctx, guint flags) { } } } - /* Update bounding box data used by filters */ + /* Update bounding box in user space, used for filter and objectBoundingBox units */ if (item->style->filter.set && item->display) { - Geom::OptRect item_bbox = item->visualBounds(); + Geom::OptRect item_bbox = item->geometricBounds(); SPItemView *itemview = item->display; do { - if (itemview->arenaitem) // Already enlarged by visualBounds - itemview->arenaitem->setFilterBounds(item_bbox); + if (itemview->arenaitem) + itemview->arenaitem->setItemBounds(item_bbox); } while ( (itemview = itemview->next) ); } @@ -1065,12 +1065,8 @@ Inkscape::DrawingItem *SPItem::invoke_show(Inkscape::Drawing &drawing, unsigned SP_MASK(mask)->sp_mask_set_bbox(mask_key, item_bbox); mask->requestDisplayUpdate(SP_OBJECT_MODIFIED_FLAG); } - if (style->filter.set && display) { - item_bbox = visualBounds(); - } ai->setData(this); - // Already enlarged by visualBounds for filters - ai->setFilterBounds(item_bbox); + ai->setItemBounds(geometricBounds()); } return ai; diff --git a/src/sp-radial-gradient.cpp b/src/sp-radial-gradient.cpp index c8bf5db81..7c481fead 100644 --- a/src/sp-radial-gradient.cpp +++ b/src/sp-radial-gradient.cpp @@ -156,28 +156,36 @@ cairo_pattern_t* SPRadialGradient::pattern_new(cairo_t *ct, Geom::OptRect const // https://bugs.launchpad.net/inkscape/+bug/970355 Geom::Affine gs2user = this->gradientTransform; - Geom::Scale gs2user_scale; if (this->getUnits() == SP_GRADIENT_UNITS_OBJECTBOUNDINGBOX && bbox) { Geom::Affine bbox2user(bbox->width(), 0, 0, bbox->height(), bbox->left(), bbox->top()); gs2user *= bbox2user; - gs2user_scale = Geom::Scale( gs2user[0], gs2user[3] ); } - Geom::Point d = focus - center; - Geom::Point d_user = d * gs2user_scale; - Geom::Point r_user( radius, 0 ); - r_user *= gs2user_scale; - - if (d_user.length() + tolerance > r_user.length()) { + // we need to use vectors with the same direction to represent the transformed + // radius and the focus-center delta, because gs2user might contain non-uniform scaling + Geom::Point d(focus - center); + Geom::Point d_user(d.length(), 0); + Geom::Point r_user(radius, 0); + d_user *= gs2user.withoutTranslation(); + r_user *= gs2user.withoutTranslation(); + + double dx = d_user.x(), dy = d_user.y(); + cairo_user_to_device_distance(ct, &dx, &dy); + + // compute the tolerance distance in user space + // create a vector with the same direction as the transformed d, + // with the length equal to tolerance + double dl = hypot(dx, dy); + double tx = tolerance * dx / dl, ty = tolerance * dy / dl; + cairo_device_to_user_distance(ct, &tx, &ty); + double tolerance_user = hypot(tx, ty); + + if (d_user.length() + tolerance_user > r_user.length()) { scale = r_user.length() / d_user.length(); - double dx = d_user.x(), dy = d_user.y(); - cairo_user_to_device_distance(ct, &dx, &dy); - if (!Geom::are_near(dx, 0, tolerance) || !Geom::are_near(dy, 0, tolerance)) - { - scale *= 1.0 - 2.0 * tolerance / hypot(dx, dy); - } + // nudge the focus slightly inside + scale *= 1.0 - 2.0 * tolerance / dl; } cairo_pattern_t *cp = cairo_pattern_create_radial( diff --git a/src/sp-text.cpp b/src/sp-text.cpp index c515828a4..c431f52da 100644 --- a/src/sp-text.cpp +++ b/src/sp-text.cpp @@ -135,12 +135,9 @@ void SPText::remove_child(Inkscape::XML::Node *rch) { void SPText::update(SPCtx *ctx, guint flags) { - SPItem::update(ctx, flags); - - guint cflags = (flags & SP_OBJECT_MODIFIED_CASCADE); - + unsigned childflags = (flags & SP_OBJECT_MODIFIED_CASCADE); if (flags & SP_OBJECT_MODIFIED_FLAG) { - cflags |= SP_OBJECT_PARENT_MODIFIED_FLAG; + childflags |= SP_OBJECT_PARENT_MODIFIED_FLAG; } // Create temporary list of children @@ -157,14 +154,17 @@ void SPText::update(SPCtx *ctx, guint flags) { SPObject *child = reinterpret_cast<SPObject*>(l->data); // We just built this list, so cast is safe. l = g_slist_remove (l, child); - if (cflags || (child->uflags & (SP_OBJECT_MODIFIED_FLAG | SP_OBJECT_CHILD_MODIFIED_FLAG))) { + if (childflags || (child->uflags & (SP_OBJECT_MODIFIED_FLAG | SP_OBJECT_CHILD_MODIFIED_FLAG))) { /* fixme: Do we need transform? */ - child->updateDisplay(ctx, cflags); + child->updateDisplay(ctx, childflags); } sp_object_unref(child, this); } + // update ourselves after updating children + SPItem::update(ctx, flags); + if (flags & ( SP_OBJECT_STYLE_MODIFIED_FLAG | SP_OBJECT_CHILD_MODIFIED_FLAG | SP_TEXT_LAYOUT_MODIFIED_FLAG ) ) diff --git a/src/sp-tref.cpp b/src/sp-tref.cpp index 4f9947a04..1c0481547 100644 --- a/src/sp-tref.cpp +++ b/src/sp-tref.cpp @@ -148,21 +148,21 @@ void SPTRef::set(unsigned int key, const gchar* value) { void SPTRef::update(SPCtx *ctx, guint flags) { debug("0x%p",this); - SPItem::update(ctx, flags); - + unsigned childflags = flags; if (flags & SP_OBJECT_MODIFIED_FLAG) { - flags |= SP_OBJECT_PARENT_MODIFIED_FLAG; + childflags |= SP_OBJECT_PARENT_MODIFIED_FLAG; } - - flags &= SP_OBJECT_MODIFIED_CASCADE; + childflags &= SP_OBJECT_MODIFIED_CASCADE; SPObject *child = this->stringChild; if (child) { - if ( flags || ( child->uflags & SP_OBJECT_MODIFIED_FLAG )) { - child->updateDisplay(ctx, flags); + if ( childflags || ( child->uflags & SP_OBJECT_MODIFIED_FLAG )) { + child->updateDisplay(ctx, childflags); } } + + SPItem::update(ctx, flags); } void SPTRef::modified(unsigned int flags) { diff --git a/src/sp-tspan.cpp b/src/sp-tspan.cpp index 21c5ee11f..20d404130 100644 --- a/src/sp-tspan.cpp +++ b/src/sp-tspan.cpp @@ -107,19 +107,19 @@ void SPTSpan::set(unsigned int key, const gchar* value) { } void SPTSpan::update(SPCtx *ctx, guint flags) { - SPItem::update(ctx, flags); - + unsigned childflags = flags; if (flags & SP_OBJECT_MODIFIED_FLAG) { - flags |= SP_OBJECT_PARENT_MODIFIED_FLAG; + childflags |= SP_OBJECT_PARENT_MODIFIED_FLAG; } - - flags &= SP_OBJECT_MODIFIED_CASCADE; + childflags &= SP_OBJECT_MODIFIED_CASCADE; for ( SPObject *ochild = this->firstChild() ; ochild ; ochild = ochild->getNext() ) { if ( flags || ( ochild->uflags & SP_OBJECT_MODIFIED_FLAG )) { - ochild->updateDisplay(ctx, flags); + ochild->updateDisplay(ctx, childflags); } } + + SPItem::update(ctx, flags); } void SPTSpan::modified(unsigned int flags) { diff --git a/src/sp-use.cpp b/src/sp-use.cpp index a558c6bf4..ec367d786 100644 --- a/src/sp-use.cpp +++ b/src/sp-use.cpp @@ -476,20 +476,12 @@ void SPUse::update(SPCtx *ctx, unsigned flags) { SPItemCtx *ictx = (SPItemCtx *) ctx; SPItemCtx cctx = *ictx; - SPItem::update(ctx, flags); - + unsigned childflags = flags; if (flags & SP_OBJECT_MODIFIED_FLAG) { - flags |= SP_OBJECT_PARENT_MODIFIED_FLAG; + childflags |= SP_OBJECT_PARENT_MODIFIED_FLAG; } - flags &= SP_OBJECT_MODIFIED_CASCADE; - - if (flags & SP_OBJECT_STYLE_MODIFIED_FLAG) { - for (SPItemView *v = this->display; v != NULL; v = v->next) { - Inkscape::DrawingGroup *g = dynamic_cast<Inkscape::DrawingGroup *>(v->arenaitem); - g->setStyle(this->style); - } - } + childflags &= SP_OBJECT_MODIFIED_CASCADE; /* Set up child viewport */ if (this->x.unit == SVGLength::PERCENT) { @@ -510,21 +502,30 @@ void SPUse::update(SPCtx *ctx, unsigned flags) { cctx.viewport = Geom::Rect::from_xywh(0, 0, this->width.computed, this->height.computed); cctx.i2vp = Geom::identity(); - flags&=~SP_OBJECT_USER_MODIFIED_FLAG_B; + childflags &= ~SP_OBJECT_USER_MODIFIED_FLAG_B; if (this->child) { sp_object_ref(this->child); - if (flags || (this->child->uflags & (SP_OBJECT_MODIFIED_FLAG | SP_OBJECT_CHILD_MODIFIED_FLAG))) { + if (childflags || (this->child->uflags & (SP_OBJECT_MODIFIED_FLAG | SP_OBJECT_CHILD_MODIFIED_FLAG))) { SPItem const &chi = *SP_ITEM(this->child); cctx.i2doc = chi.transform * ictx->i2doc; cctx.i2vp = chi.transform * ictx->i2vp; - this->child->updateDisplay((SPCtx *)&cctx, flags); + this->child->updateDisplay((SPCtx *)&cctx, childflags); } sp_object_unref(this->child); } + SPItem::update(ctx, flags); + + if (flags & SP_OBJECT_STYLE_MODIFIED_FLAG) { + for (SPItemView *v = this->display; v != NULL; v = v->next) { + Inkscape::DrawingGroup *g = dynamic_cast<Inkscape::DrawingGroup *>(v->arenaitem); + g->setStyle(this->style); + } + } + /* As last step set additional transform of arena group */ for (SPItemView *v = this->display; v != NULL; v = v->next) { Inkscape::DrawingGroup *g = dynamic_cast<Inkscape::DrawingGroup *>(v->arenaitem); diff --git a/src/splivarot.cpp b/src/splivarot.cpp index 8a57fa98a..319928d99 100644 --- a/src/splivarot.cpp +++ b/src/splivarot.cpp @@ -2183,6 +2183,7 @@ sp_selected_path_simplify_items(SPDesktop *desktop, gchar *message = g_strdup_printf(_("%s <b>%d</b> of <b>%d</b> paths simplified..."), simplificationType, pathsSimplified, totalPathCount); desktop->messageStack()->flash(Inkscape::IMMEDIATE_MESSAGE, message); + g_free(message); } didSomething |= sp_selected_path_simplify_item(desktop, selection, item, @@ -2192,7 +2193,7 @@ sp_selected_path_simplify_items(SPDesktop *desktop, desktop->clearWaitingCursor(); if (pathsSimplified > 20) { - desktop->messageStack()->flash(Inkscape::NORMAL_MESSAGE, g_strdup_printf(_("<b>%d</b> paths simplified."), pathsSimplified)); + desktop->messageStack()->flashF(Inkscape::NORMAL_MESSAGE, _("<b>%d</b> paths simplified."), pathsSimplified); } return didSomething; diff --git a/src/spray-context.cpp b/src/spray-context.cpp index fd9aff196..6b97dcc17 100644 --- a/src/spray-context.cpp +++ b/src/spray-context.cpp @@ -499,7 +499,9 @@ static bool sp_spray_recursive(SPDesktop *desktop, // Ad the clone to the list of the father's sons parent->appendChild(clone); // Generates the link between father and son attributes - clone->setAttribute("xlink:href", g_strdup_printf("#%s", old_repr->attribute("id")), false); + gchar *href_str = g_strdup_printf("#%s", old_repr->attribute("id")); + clone->setAttribute("xlink:href", href_str, false); + g_free(href_str); SPObject *clone_object = doc->getObjectByRepr(clone); // conversion object->item diff --git a/src/text-chemistry.cpp b/src/text-chemistry.cpp index 8a3fede0f..532d19e02 100644 --- a/src/text-chemistry.cpp +++ b/src/text-chemistry.cpp @@ -152,7 +152,9 @@ text_put_on_path() // create textPath and put it into the text Inkscape::XML::Node *textpath = xml_doc->createElement("svg:textPath"); // reference the shape - textpath->setAttribute("xlink:href", g_strdup_printf("#%s", shape->getRepr()->attribute("id"))); + gchar *href_str = g_strdup_printf("#%s", shape->getRepr()->attribute("id")); + textpath->setAttribute("xlink:href", href_str); + g_free(href_str); if (text_alignment == Inkscape::Text::Layout::RIGHT) { textpath->setAttribute("startOffset", "100%"); } else if (text_alignment == Inkscape::Text::Layout::CENTER) { @@ -234,9 +236,9 @@ text_remove_all_kerns_recursively(SPObject *o) gchar **xa_space = g_strsplit(x, " ", 0); gchar **xa_comma = g_strsplit(x, ",", 0); if (xa_space && *xa_space && *(xa_space + 1)) { - o->getRepr()->setAttribute("x", g_strdup(*xa_space)); + o->getRepr()->setAttribute("x", *xa_space); } else if (xa_comma && *xa_comma && *(xa_comma + 1)) { - o->getRepr()->setAttribute("x", g_strdup(*xa_comma)); + o->getRepr()->setAttribute("x", *xa_comma); } g_strfreev(xa_space); g_strfreev(xa_comma); @@ -331,7 +333,9 @@ text_flow_into_shape() Inkscape::XML::Node *clone = xml_doc->createElement("svg:use"); clone->setAttribute("x", "0"); clone->setAttribute("y", "0"); - clone->setAttribute("xlink:href", g_strdup_printf("#%s", item->getRepr()->attribute("id"))); + gchar *href_str = g_strdup_printf("#%s", item->getRepr()->attribute("id")); + clone->setAttribute("xlink:href", href_str); + g_free(href_str); // add the new clone to the region region_repr->appendChild(clone); diff --git a/src/tools-switch.cpp b/src/tools-switch.cpp index 32fab9f7e..a3c0f2daa 100644 --- a/src/tools-switch.cpp +++ b/src/tools-switch.cpp @@ -88,28 +88,28 @@ static char const *const tool_names[] = { }; static char const *const tool_msg[] = { NULL, - _("<b>Click</b> to Select and Tranform objects, <b>Drag</b> to select many objects."), - _("Modify selected path points (nodes) directly."), - _("To tweak a path by pushing, select it and drag over it."), - _("<b>Drag</b>, <b>click</b> or <b>click and scroll</b> to spray the selected objects."), - _("<b>Drag</b> to create a rectangle. <b>Drag controls</b> to round corners and resize. <b>Click</b> to select."), - _("<b>Drag</b> to create a 3D box. <b>Drag controls</b> to resize in perspective. <b>Click</b> to select (with <b>Ctrl+Alt</b> for single faces)."), - _("<b>Drag</b> to create an ellipse. <b>Drag controls</b> to make an arc or segment. <b>Click</b> to select."), - _("<b>Drag</b> to create a star. <b>Drag controls</b> to edit the star shape. <b>Click</b> to select."), - _("<b>Drag</b> to create a spiral. <b>Drag controls</b> to edit the spiral shape. <b>Click</b> to select."), - _("<b>Drag</b> to create a freehand line. <b>Shift</b> appends to selected path, <b>Alt</b> activates sketch mode."), - _("<b>Click</b> or <b>click and drag</b> to start a path; with <b>Shift</b> to append to selected path. <b>Ctrl+click</b> to create single dots (straight line modes only)."), - _("<b>Drag</b> to draw a calligraphic stroke; with <b>Ctrl</b> to track a guide path. <b>Arrow keys</b> adjust width (left/right) and angle (up/down)."), - _("<b>Click</b> to select or create text, <b>drag</b> to create flowed text; then type."), - _("<b>Drag</b> or <b>double click</b> to create a gradient on selected objects, <b>drag handles</b> to adjust gradients."), - _("<b>Drag</b> or <b>double click</b> to create a mesh on selected objects, <b>drag handles</b> to adjust meshes."), - _("<b>Click</b> or <b>drag around an area</b> to zoom in, <b>Shift+click</b> to zoom out."), - _("<b>Drag</b> to measure the dimensions of objects."), - _("<b>Click</b> to set fill, <b>Shift+click</b> to set stroke; <b>drag</b> to average color in area; with <b>Alt</b> to pick inverse color; <b>Ctrl+C</b> to copy the color under mouse to clipboard"), - _("<b>Click and drag</b> between shapes to create a connector."), - _("<b>Click</b> to paint a bounded area, <b>Shift+click</b> to union the new fill with the current selection, <b>Ctrl+click</b> to change the clicked object's fill and stroke to the current setting."), - _("<b>Drag</b> to erase."), - _("Choose a subtool from the toolbar"), + N_("<b>Click</b> to Select and Tranform objects, <b>Drag</b> to select many objects."), + N_("Modify selected path points (nodes) directly."), + N_("To tweak a path by pushing, select it and drag over it."), + N_("<b>Drag</b>, <b>click</b> or <b>click and scroll</b> to spray the selected objects."), + N_("<b>Drag</b> to create a rectangle. <b>Drag controls</b> to round corners and resize. <b>Click</b> to select."), + N_("<b>Drag</b> to create a 3D box. <b>Drag controls</b> to resize in perspective. <b>Click</b> to select (with <b>Ctrl+Alt</b> for single faces)."), + N_("<b>Drag</b> to create an ellipse. <b>Drag controls</b> to make an arc or segment. <b>Click</b> to select."), + N_("<b>Drag</b> to create a star. <b>Drag controls</b> to edit the star shape. <b>Click</b> to select."), + N_("<b>Drag</b> to create a spiral. <b>Drag controls</b> to edit the spiral shape. <b>Click</b> to select."), + N_("<b>Drag</b> to create a freehand line. <b>Shift</b> appends to selected path, <b>Alt</b> activates sketch mode."), + N_("<b>Click</b> or <b>click and drag</b> to start a path; with <b>Shift</b> to append to selected path. <b>Ctrl+click</b> to create single dots (straight line modes only)."), + N_("<b>Drag</b> to draw a calligraphic stroke; with <b>Ctrl</b> to track a guide path. <b>Arrow keys</b> adjust width (left/right) and angle (up/down)."), + N_("<b>Click</b> to select or create text, <b>drag</b> to create flowed text; then type."), + N_("<b>Drag</b> or <b>double click</b> to create a gradient on selected objects, <b>drag handles</b> to adjust gradients."), + N_("<b>Drag</b> or <b>double click</b> to create a mesh on selected objects, <b>drag handles</b> to adjust meshes."), + N_("<b>Click</b> or <b>drag around an area</b> to zoom in, <b>Shift+click</b> to zoom out."), + N_("<b>Drag</b> to measure the dimensions of objects."), + N_("<b>Click</b> to set fill, <b>Shift+click</b> to set stroke; <b>drag</b> to average color in area; with <b>Alt</b> to pick inverse color; <b>Ctrl+C</b> to copy the color under mouse to clipboard"), + N_("<b>Click and drag</b> between shapes to create a connector."), + N_("<b>Click</b> to paint a bounded area, <b>Shift+click</b> to union the new fill with the current selection, <b>Ctrl+click</b> to change the clicked object's fill and stroke to the current setting."), + N_("<b>Drag</b> to erase."), + N_("Choose a subtool from the toolbar"), }; static int @@ -152,7 +152,7 @@ tools_switch(SPDesktop *dt, int num) /* First 4 tools use guides, first is undefined but we don't care */ dt->activate_guides(num < 5); inkscape_eventcontext_set(dt->getEventContext()); - dt->tipsMessageContext()->set(Inkscape::NORMAL_MESSAGE, tool_msg[num] ); + dt->tipsMessageContext()->set(Inkscape::NORMAL_MESSAGE, gettext( tool_msg[num] ) ); } void tools_switch_by_item(SPDesktop *dt, SPItem *item, Geom::Point const p) diff --git a/src/ui/dialog/ocaldialogs.cpp b/src/ui/dialog/ocaldialogs.cpp index f87288494..ca0edfadd 100644 --- a/src/ui/dialog/ocaldialogs.cpp +++ b/src/ui/dialog/ocaldialogs.cpp @@ -1017,7 +1017,7 @@ void SearchResultList::populate_from_xml(xmlNode * a_node) } else if (!strcmp(reinterpret_cast<const char*>(cur_node->name), "enclosure")) { - xmlChar *xml_url = xmlGetProp(cur_node, reinterpret_cast<xmlChar*>(g_strdup("url"))); + xmlChar *xml_url = xmlGetProp(cur_node, reinterpret_cast<xmlChar const*>("url")); char* url = reinterpret_cast<char*>(xml_url); char* filename = g_path_get_basename(url); @@ -1027,7 +1027,7 @@ void SearchResultList::populate_from_xml(xmlNode * a_node) } else if (!strcmp(reinterpret_cast<const char*>(cur_node->name), "thumbnail")) { - xmlChar *xml_thumbnail_url = xmlGetProp(cur_node, reinterpret_cast<xmlChar*>(g_strdup("url"))); + xmlChar *xml_thumbnail_url = xmlGetProp(cur_node, reinterpret_cast<xmlChar const*>("url")); char* thumbnail_url = reinterpret_cast<char*>(xml_thumbnail_url); char* thumbnail_filename = g_path_get_basename(thumbnail_url); diff --git a/src/ui/tool/path-manipulator.cpp b/src/ui/tool/path-manipulator.cpp index 910f75258..10e50a970 100644 --- a/src/ui/tool/path-manipulator.cpp +++ b/src/ui/tool/path-manipulator.cpp @@ -478,7 +478,10 @@ void PathManipulator::weldSegments() if (j->selected()) ++num_selected; else ++num_unselected; } - if (num_selected < 3) continue; + + // if 2 or fewer nodes are selected, there can't be any middle points to remove. + if (num_selected <= 2) continue; + if (num_unselected == 0 && sp->closed()) { // if all nodes in a closed subpath are selected, the operation doesn't make much sense continue; @@ -508,14 +511,16 @@ void PathManipulator::weldSegments() } if (num_points > 2) { // remove nodes in the middle + // TODO: fit bezier to the former shape sel_beg = sel_beg.next(); while (sel_beg != sel_end.prev()) { NodeList::iterator next = sel_beg.next(); sp->erase(sel_beg); sel_beg = next; } - sel_beg = sel_end; } + sel_beg = sel_end; + // decrease num_selected by the number of points processed num_selected -= num_points; } } diff --git a/src/widgets/stroke-style.cpp b/src/widgets/stroke-style.cpp index 31f4bb2e5..a0b638031 100644 --- a/src/widgets/stroke-style.cpp +++ b/src/widgets/stroke-style.cpp @@ -85,6 +85,8 @@ SPObject* getMarkerObj(gchar const *n, SPDocument *doc) // FIXME: get the document from the object and let the caller pass it in SPObject *marker = doc->getObjectById(b); + + g_free(b); return marker; } |
