summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorJabier Arraiza Cenoz <jabier.arraiza@marker.es>2013-10-02 22:15:00 +0000
committerJabiertxof <jtx@jtx.marker.es>2013-10-02 22:15:00 +0000
commitaa6d389286f6402ef393015b000755bc3124362a (patch)
tree81e17d682f5aade76e44bc8809e751b42dd5f773 /src
parentFixed a bug editing paths in others LPE -envelope- (diff)
parentFix segment welding in the node tool hanging when a two-point segment (diff)
downloadinkscape-aa6d389286f6402ef393015b000755bc3124362a.tar.gz
inkscape-aa6d389286f6402ef393015b000755bc3124362a.zip
update to trunk
(bzr r11950.1.158)
Diffstat (limited to 'src')
-rw-r--r--src/color-profile.cpp2
-rw-r--r--src/display/drawing-item.cpp74
-rw-r--r--src/display/drawing-item.h6
-rw-r--r--src/display/drawing-shape.cpp4
-rw-r--r--src/display/drawing-text.cpp4
-rw-r--r--src/display/guideline.cpp12
-rw-r--r--src/display/nr-filter.cpp8
-rw-r--r--src/extension/dbus/document-interface.cpp4
-rw-r--r--src/extension/internal/metafile-print.h4
-rw-r--r--src/libnrtype/Layout-TNG-Output.cpp1
-rw-r--r--src/selection-chemistry.cpp16
-rw-r--r--src/sp-flowdiv.cpp32
-rw-r--r--src/sp-flowregion.cpp16
-rw-r--r--src/sp-flowtext.cpp17
-rw-r--r--src/sp-item-group.cpp42
-rw-r--r--src/sp-item.cpp14
-rw-r--r--src/sp-radial-gradient.cpp36
-rw-r--r--src/sp-text.cpp14
-rw-r--r--src/sp-tref.cpp14
-rw-r--r--src/sp-tspan.cpp12
-rw-r--r--src/sp-use.cpp29
-rw-r--r--src/splivarot.cpp3
-rw-r--r--src/spray-context.cpp4
-rw-r--r--src/text-chemistry.cpp12
-rw-r--r--src/tools-switch.cpp46
-rw-r--r--src/ui/dialog/ocaldialogs.cpp4
-rw-r--r--src/ui/tool/path-manipulator.cpp9
-rw-r--r--src/widgets/stroke-style.cpp2
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;
}