summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorJabier Arraiza Cenoz <jabier.arraiza@marker.es>2013-10-02 22:35:52 +0000
committerJabiertxof <jtx@jtx.marker.es>2013-10-02 22:35:52 +0000
commit9240dbde4547c7e7529f31645ea916faae72bafa (patch)
tree82c7e2e222dd3bd92dea9a21ed60c0479f0149b8 /src
parentupdate to trunk (diff)
parentFix segment welding in the node tool hanging when a two-point segment (diff)
downloadinkscape-9240dbde4547c7e7529f31645ea916faae72bafa.tar.gz
inkscape-9240dbde4547c7e7529f31645ea916faae72bafa.zip
update to trunk
(bzr r12588.1.10)
Diffstat (limited to 'src')
-rw-r--r--src/arc-context.cpp2
-rw-r--r--src/color-profile.cpp2
-rw-r--r--src/display/drawing-group.cpp1
-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/display/nr-style.cpp2
-rw-r--r--src/display/sodipodi-ctrl.cpp191
-rw-r--r--src/display/sodipodi-ctrl.h4
-rw-r--r--src/document.cpp10
-rw-r--r--src/dyna-draw-context.cpp15
-rw-r--r--src/extension/dbus/document-interface.cpp4
-rw-r--r--src/extension/effect.cpp2
-rw-r--r--src/extension/init.cpp2
-rw-r--r--src/extension/internal/metafile-print.h4
-rw-r--r--src/inkscape.cpp6
-rw-r--r--src/knot.cpp30
-rw-r--r--src/libavoid/vertices.h2
-rw-r--r--src/libcola/connected_components.cpp8
-rw-r--r--src/libcola/cycle_detector.cpp4
-rw-r--r--src/libcola/gradient_projection.cpp2
-rw-r--r--src/libcola/straightener.cpp18
-rw-r--r--src/libnrtype/FontFactory.cpp17
-rw-r--r--src/libnrtype/FontInstance.cpp8
-rw-r--r--src/libnrtype/Layout-TNG-Compute.cpp1
-rw-r--r--src/libnrtype/Layout-TNG-Output.cpp1
-rw-r--r--src/measure-context.cpp4
-rw-r--r--src/measure-context.h6
-rw-r--r--src/menus-skeleton.h1
-rw-r--r--src/number-opt-number.h2
-rw-r--r--src/object-edit.cpp54
-rw-r--r--src/proj_pt.cpp1
-rw-r--r--src/selection-chemistry.cpp16
-rw-r--r--src/sp-ellipse.cpp640
-rw-r--r--src/sp-ellipse.h113
-rw-r--r--src/sp-filter.cpp4
-rw-r--r--src/sp-flowdiv.cpp32
-rw-r--r--src/sp-flowregion.cpp16
-rw-r--r--src/sp-flowtext.cpp24
-rw-r--r--src/sp-image.cpp3
-rw-r--r--src/sp-item-group.cpp42
-rw-r--r--src/sp-item.cpp24
-rw-r--r--src/sp-object.h4
-rw-r--r--src/sp-radial-gradient.cpp36
-rw-r--r--src/sp-text.cpp21
-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/style.cpp18
-rw-r--r--src/svg/svg-length.cpp8
-rw-r--r--src/svg/svg-length.h1
-rw-r--r--src/text-chemistry.cpp12
-rw-r--r--src/tools-switch.cpp164
-rw-r--r--src/ui/dialog/ocaldialogs.cpp4
-rw-r--r--src/ui/dialog/svg-fonts-dialog.cpp8
-rw-r--r--src/ui/tool/path-manipulator.cpp9
-rw-r--r--src/verbs.cpp5
-rw-r--r--src/verbs.h1
-rw-r--r--src/widgets/arc-toolbar.cpp2
-rw-r--r--src/widgets/stroke-style.cpp2
65 files changed, 858 insertions, 925 deletions
diff --git a/src/arc-context.cpp b/src/arc-context.cpp
index 350df908b..046541b9b 100644
--- a/src/arc-context.cpp
+++ b/src/arc-context.cpp
@@ -409,7 +409,7 @@ void SPArcContext::drag(Geom::Point pt, guint state) {
}
}
- sp_arc_position_set(SP_ARC(this->arc),
+ this->arc->sp_arc_position_set(
r.midpoint()[Geom::X], r.midpoint()[Geom::Y],
r.dimensions()[Geom::X] / 2, r.dimensions()[Geom::Y] / 2);
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-group.cpp b/src/display/drawing-group.cpp
index 6d52b89fc..b5ce18891 100644
--- a/src/display/drawing-group.cpp
+++ b/src/display/drawing-group.cpp
@@ -28,6 +28,7 @@ DrawingGroup::~DrawingGroup()
{
if (_style)
sp_style_unref(_style);
+ delete _child_transform; // delete NULL; is safe
}
/**
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/display/nr-style.cpp b/src/display/nr-style.cpp
index cd7e9575f..317f38635 100644
--- a/src/display/nr-style.cpp
+++ b/src/display/nr-style.cpp
@@ -77,6 +77,8 @@ NRStyle::~NRStyle()
if (dash){
delete [] dash;
}
+ fill.clear();
+ stroke.clear();
}
void NRStyle::set(SPStyle *style)
diff --git a/src/display/sodipodi-ctrl.cpp b/src/display/sodipodi-ctrl.cpp
index 45dc38a37..3636319df 100644
--- a/src/display/sodipodi-ctrl.cpp
+++ b/src/display/sodipodi-ctrl.cpp
@@ -108,81 +108,50 @@ sp_ctrl_set_property(GObject *object, guint prop_id, const GValue *value, GParam
ctrl = SP_CTRL (object);
switch (prop_id) {
- case ARG_SHAPE: {
- ctrl->shape = (SPCtrlShapeType) g_value_get_int(value);
- ctrl->build = FALSE;
- sp_canvas_item_request_update(item);
- }
- break;
-
- case ARG_MODE: {
- ctrl->mode = (SPCtrlModeType) g_value_get_int(value);
- ctrl->build = FALSE;
- sp_canvas_item_request_update(item);
- }
- break;
-
- case ARG_ANCHOR: {
- ctrl->anchor = (SPAnchorType) g_value_get_int(value);
- ctrl->build = FALSE;
- sp_canvas_item_request_update(item);
- }
- break;
-
- case ARG_SIZE: {
- ctrl->span = (gint)((g_value_get_double(value) - 1.0) / 2.0 + 0.5);
- ctrl->defined = (ctrl->span > 0);
- ctrl->build = FALSE;
- sp_canvas_item_request_update(item);
- }
- break;
-
- case ARG_FILLED: {
- ctrl->filled = g_value_get_boolean(value);
- ctrl->build = FALSE;
- sp_canvas_item_request_update(item);
- }
- break;
-
- case ARG_FILL_COLOR: {
- guint32 fill = g_value_get_int(value);
- ctrl->fill_color = fill;
- ctrl->build = FALSE;
- sp_canvas_item_request_update(item);
- }
- break;
-
- case ARG_STROKED: {
- ctrl->stroked = g_value_get_boolean(value);
- ctrl->build = FALSE;
- sp_canvas_item_request_update(item);
- }
- break;
-
- case ARG_STROKE_COLOR: {
- guint32 stroke = g_value_get_int(value);
- ctrl->stroke_color = stroke;
- ctrl->build = FALSE;
- sp_canvas_item_request_update(item);
- }
- break;
-
- case ARG_PIXBUF: {
- pixbuf = (GdkPixbuf*) g_value_get_pointer(value);
- if (gdk_pixbuf_get_has_alpha(pixbuf)) {
- ctrl->pixbuf = pixbuf;
- } else {
- ctrl->pixbuf = gdk_pixbuf_add_alpha(pixbuf, FALSE, 0, 0, 0);
- g_object_unref(pixbuf);
- }
- ctrl->build = FALSE;
- }
- break;
-
- default:
- G_OBJECT_WARN_INVALID_PROPERTY_ID(object, prop_id, pspec);
- break;
+ case ARG_SHAPE:
+ ctrl->shape = (SPCtrlShapeType) g_value_get_int(value);
+ break;
+ case ARG_MODE:
+ ctrl->mode = (SPCtrlModeType) g_value_get_int(value);
+ break;
+ case ARG_ANCHOR:
+ ctrl->anchor = (SPAnchorType) g_value_get_int(value);
+ break;
+ case ARG_SIZE:
+ ctrl->width = (gint)(g_value_get_double(value) / 2.0);
+ ctrl->height = ctrl->width;
+ ctrl->defined = (ctrl->width > 0);
+ break;
+ case ARG_FILLED:
+ ctrl->filled = g_value_get_boolean(value);
+ break;
+ case ARG_FILL_COLOR:
+ ctrl->fill_color = (guint32)g_value_get_int(value);
+ break;
+ case ARG_STROKED:
+ ctrl->stroked = g_value_get_boolean(value);
+ break;
+ case ARG_STROKE_COLOR:
+ ctrl->stroke_color = (guint32)g_value_get_int(value);
+ break;
+ case ARG_PIXBUF:
+ pixbuf = (GdkPixbuf*) g_value_get_pointer(value);
+ // A pixbuf defines it's own size, don't mess about with size.
+ ctrl->width = gdk_pixbuf_get_width(pixbuf) / 2.0;
+ ctrl->height = gdk_pixbuf_get_height(pixbuf) / 2.0;
+ if (gdk_pixbuf_get_has_alpha(pixbuf)) {
+ ctrl->pixbuf = pixbuf;
+ } else {
+ ctrl->pixbuf = gdk_pixbuf_add_alpha(pixbuf, FALSE, 0, 0, 0);
+ g_object_unref(pixbuf);
+ }
+ break;
+ default:
+ G_OBJECT_WARN_INVALID_PROPERTY_ID(object, prop_id, pspec);
+ return; // Do not do an update
}
+ ctrl->build = FALSE;
+ sp_canvas_item_request_update(item);
}
static void
@@ -206,7 +175,7 @@ sp_ctrl_get_property (GObject *object, guint prop_id, GValue *value, GParamSpec
break;
case ARG_SIZE:
- g_value_set_double(value, ctrl->span);
+ g_value_set_double(value, ctrl->width);
break;
case ARG_FILLED:
@@ -241,7 +210,8 @@ sp_ctrl_init (SPCtrl *ctrl)
ctrl->shape = SP_CTRL_SHAPE_SQUARE;
ctrl->mode = SP_CTRL_MODE_COLOR;
ctrl->anchor = SP_ANCHOR_CENTER;
- ctrl->span = 3;
+ ctrl->width = 3;
+ ctrl->height = 3;
ctrl->defined = TRUE;
ctrl->shown = FALSE;
ctrl->build = FALSE;
@@ -250,12 +220,6 @@ sp_ctrl_init (SPCtrl *ctrl)
ctrl->fill_color = 0x000000ff;
ctrl->stroke_color = 0x000000ff;
- // This way we make sure that the first sp_ctrl_update() call finishes properly;
- // in subsequent calls it will not update anything it the control hasn't moved
- // Consider for example the case in which a snap indicator is drawn at (0, 0);
- // If moveto() is called then it will not set _moved to true because we're initially already at (0, 0)
- ctrl->_moved = true; // Is this flag ever going to be set back to false? I can't find where that is supposed to happen
-
new (&ctrl->box) Geom::IntRect(0,0,0,0);
ctrl->cache = NULL;
ctrl->pixbuf = NULL;
@@ -292,16 +256,14 @@ sp_ctrl_update (SPCanvasItem *item, Geom::Affine const &affine, unsigned int fla
sp_canvas_item_reset_bounds (item);
- if (!ctrl->_moved) return;
-
if (ctrl->shown) {
item->canvas->requestRedraw(ctrl->box.left(), ctrl->box.top(), ctrl->box.right() + 1, ctrl->box.bottom() + 1);
}
if (!ctrl->defined) return;
- x = (gint) ((affine[4] > 0) ? (affine[4] + 0.5) : (affine[4] - 0.5)) - ctrl->span;
- y = (gint) ((affine[5] > 0) ? (affine[5] + 0.5) : (affine[5] - 0.5)) - ctrl->span;
+ x = (gint) ((affine[4] > 0) ? (affine[4] + 0.5) : (affine[4] - 0.5)) - ctrl->width;
+ y = (gint) ((affine[5] > 0) ? (affine[5] + 0.5) : (affine[5] - 0.5)) - ctrl->height;
switch (ctrl->anchor) {
case SP_ANCHOR_N:
@@ -312,13 +274,13 @@ sp_ctrl_update (SPCanvasItem *item, Geom::Affine const &affine, unsigned int fla
case SP_ANCHOR_NW:
case SP_ANCHOR_W:
case SP_ANCHOR_SW:
- x += ctrl->span;
+ x += ctrl->width;
break;
case SP_ANCHOR_NE:
case SP_ANCHOR_E:
case SP_ANCHOR_SE:
- x -= (ctrl->span + 1);
+ x -= (ctrl->width + 1);
break;
}
@@ -331,17 +293,17 @@ sp_ctrl_update (SPCanvasItem *item, Geom::Affine const &affine, unsigned int fla
case SP_ANCHOR_NW:
case SP_ANCHOR_N:
case SP_ANCHOR_NE:
- y += ctrl->span;
+ y += ctrl->height;
break;
case SP_ANCHOR_SW:
case SP_ANCHOR_S:
case SP_ANCHOR_SE:
- y -= (ctrl->span + 1);
+ y -= (ctrl->height + 1);
break;
}
- ctrl->box = Geom::IntRect::from_xywh(x, y, 2*ctrl->span, 2*ctrl->span);
+ ctrl->box = Geom::IntRect::from_xywh(x, y, 2*ctrl->width, 2*ctrl->height);
sp_canvas_update_bbox (item, ctrl->box.left(), ctrl->box.top(), ctrl->box.right() + 1, ctrl->box.bottom() + 1);
}
@@ -360,7 +322,7 @@ static void
sp_ctrl_build_cache (SPCtrl *ctrl)
{
guint32 *p, *q;
- gint size, x, y, z, s, a, side, c;
+ gint size, x, y, z, s, a, width, height, c;
guint32 stroke_color, fill_color;
if (ctrl->filled) {
@@ -382,11 +344,11 @@ sp_ctrl_build_cache (SPCtrl *ctrl)
stroke_color = fill_color;
}
-
- side = (ctrl->span * 2 +1);
- c = ctrl->span;
- size = side * side;
- if (side < 2) return;
+ width = (ctrl->width * 2 +1);
+ height = (ctrl->height * 2 +1);
+ c = ctrl->width; // Only used for pre-set square drawing
+ size = width * height;
+ if (width < 2) return;
if (ctrl->cache) delete[] ctrl->cache;
ctrl->cache = new guint32[size];
@@ -395,19 +357,19 @@ sp_ctrl_build_cache (SPCtrl *ctrl)
case SP_CTRL_SHAPE_SQUARE:
p = ctrl->cache;
// top edge
- for (x=0; x < side; x++) {
+ for (x=0; x < width; x++) {
*p++ = stroke_color;
}
// middle
- for (y = 2; y < side; y++) {
+ for (y = 2; y < height; y++) {
*p++ = stroke_color; // stroke at first and last pixel
- for (x=2; x < side; x++) {
+ for (x=2; x < width; x++) {
*p++ = fill_color; // fill in the middle
}
*p++ = stroke_color;
}
// bottom edge
- for (x=0; x < side; x++) {
+ for (x=0; x < width; x++) {
*p++ = stroke_color;
}
ctrl->build = TRUE;
@@ -415,19 +377,19 @@ sp_ctrl_build_cache (SPCtrl *ctrl)
case SP_CTRL_SHAPE_DIAMOND:
p = ctrl->cache;
- for (y = 0; y < side; y++) {
+ for (y = 0; y < height; y++) {
z = abs (c - y);
for (x = 0; x < z; x++) {
*p++ = 0;
}
*p++ = stroke_color; x++;
- for (; x < side - z -1; x++) {
+ for (; x < width - z -1; x++) {
*p++ = fill_color;
}
if (z != c) {
*p++ = stroke_color; x++;
}
- for (; x < side; x++) {
+ for (; x < width; x++) {
*p++ = 0;
}
}
@@ -462,7 +424,7 @@ sp_ctrl_build_cache (SPCtrl *ctrl)
*q-- = stroke_color;
x++;
} while (x <= c+z);
- while (x < side) {
+ while (x < width) {
*p++ = 0;
*q-- = 0;
x++;
@@ -474,7 +436,7 @@ sp_ctrl_build_cache (SPCtrl *ctrl)
case SP_CTRL_SHAPE_CROSS:
p = ctrl->cache;
- for (y = 0; y < side; y++) {
+ for (y = 0; y < height; y++) {
z = abs (c - y);
for (x = 0; x < c-z; x++) {
*p++ = 0;
@@ -486,7 +448,7 @@ sp_ctrl_build_cache (SPCtrl *ctrl)
if (z != 0) {
*p++ = stroke_color; x++;
}
- for (; x < side; x++) {
+ for (; x < width; x++) {
*p++ = 0;
}
}
@@ -499,12 +461,12 @@ sp_ctrl_build_cache (SPCtrl *ctrl)
unsigned int rs;
px = gdk_pixbuf_get_pixels (ctrl->pixbuf);
rs = gdk_pixbuf_get_rowstride (ctrl->pixbuf);
- for (y = 0; y < side; y++){
+ for (y = 0; y < height; y++){
guint32 *d;
unsigned char *s;
s = px + y * rs;
- d = ctrl->cache + side * y;
- for (x = 0; x < side; x++) {
+ d = ctrl->cache + height * y;
+ for (x = 0; x < width; x++) {
if (s[3] < 0x80) {
*d++ = 0;
} else if (s[0] < 0x80) {
@@ -527,9 +489,9 @@ sp_ctrl_build_cache (SPCtrl *ctrl)
guint32 *px;
guchar *data = gdk_pixbuf_get_pixels (ctrl->pixbuf);
p = ctrl->cache;
- for (y = 0; y < side; y++){
+ for (y = 0; y < height; y++){
px = reinterpret_cast<guint32*>(data + y * r);
- for (x = 0; x < side; x++) {
+ for (x = 0; x < width; x++) {
*p++ = *px++;
}
}
@@ -566,8 +528,8 @@ sp_ctrl_render (SPCanvasItem *item, SPCanvasBuf *buf)
sp_ctrl_build_cache (ctrl);
}
- int w, h;
- w = h = (ctrl->span * 2 +1);
+ int w = (ctrl->width * 2 + 1);
+ int h = (ctrl->height * 2 + 1);
// The code below works even when the target is not an image surface
if (ctrl->mode == SP_CTRL_MODE_XOR) {
@@ -627,7 +589,6 @@ sp_ctrl_render (SPCanvasItem *item, SPCanvasBuf *buf)
void SPCtrl::moveto (Geom::Point const p) {
if (p != _point) {
sp_canvas_item_affine_absolute (SP_CANVAS_ITEM (this), Geom::Affine(Geom::Translate (p)));
- _moved = true;
}
_point = p;
}
diff --git a/src/display/sodipodi-ctrl.h b/src/display/sodipodi-ctrl.h
index cd0fcadf1..ecdb896a7 100644
--- a/src/display/sodipodi-ctrl.h
+++ b/src/display/sodipodi-ctrl.h
@@ -37,7 +37,8 @@ struct SPCtrl : public SPCanvasItem {
SPCtrlShapeType shape;
SPCtrlModeType mode;
SPAnchorType anchor;
- gint span;
+ gint width;
+ gint height;
guint defined : 1;
guint shown : 1;
guint build : 1;
@@ -45,7 +46,6 @@ struct SPCtrl : public SPCanvasItem {
guint stroked : 1;
guint32 fill_color;
guint32 stroke_color;
- bool _moved;
Geom::IntRect box; /* NB! x1 & y1 are included */
guint32 *cache;
diff --git a/src/document.cpp b/src/document.cpp
index 800f2f33d..b94b72bda 100644
--- a/src/document.cpp
+++ b/src/document.cpp
@@ -139,8 +139,6 @@ SPDocument::SPDocument() :
}
SPDocument::~SPDocument() {
- collectOrphans();
-
// kill/unhook this first
if ( profileManager ) {
delete profileManager;
@@ -219,6 +217,14 @@ SPDocument::~SPDocument() {
inkscape_unref();
keepalive = FALSE;
}
+
+ if (this->current_persp3d_impl)
+ delete this->current_persp3d_impl;
+ this->current_persp3d_impl = NULL;
+
+ // This is at the end of the destructor, because preceding code adds new orphans to the queue
+ collectOrphans();
+
//delete this->_whiteboard_session_manager;
}
diff --git a/src/dyna-draw-context.cpp b/src/dyna-draw-context.cpp
index 01f71f76a..f8980e218 100644
--- a/src/dyna-draw-context.cpp
+++ b/src/dyna-draw-context.cpp
@@ -954,9 +954,20 @@ void SPDynaDrawContext::set_to_accumulated(bool unionize, bool subtract) {
}
}
- SPItem *item=SP_ITEM(desktop->doc()->getObjectByRepr(this->repr));
- item->doWriteTransform(item->getRepr(), item->transform, NULL, true);
+ // Now we need to write the transform information.
+ // First, find out whether our repr is still linked to a valid object. In this case,
+ // we need to write the transform data only for this element.
+ // Either there was no boolean op or it failed.
+ SPItem *result = SP_ITEM(desktop->doc()->getObjectByRepr(this->repr));
+
+ if (result == NULL) {
+ // The boolean operation succeeded.
+ // Now we fetch the single item, that has been set as selected by the boolean op.
+ // This is its result.
+ result = desktop->getSelection()->singleItem();
+ }
+ result->doWriteTransform(result->getRepr(), result->transform, NULL, true);
} else {
if (this->repr) {
sp_repr_unparent(this->repr);
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/effect.cpp b/src/extension/effect.cpp
index dcccf3d7d..1575c2b10 100644
--- a/src/extension/effect.cpp
+++ b/src/extension/effect.cpp
@@ -89,7 +89,7 @@ Effect::Effect (Inkscape::XML::Node * in_repr, Implementation::Implementation *
} // children of "inkscape-extension"
} // if we have an XML file
- if (INKSCAPE != NULL) {
+ if (INKSCAPE != NULL && inkscape_use_gui()) {
if (_effects_list == NULL)
_effects_list = find_menu(inkscape_get_menus(INKSCAPE), EFFECTS_LIST);
if (_filters_list == NULL)
diff --git a/src/extension/init.cpp b/src/extension/init.cpp
index 2dde9eeb8..0ff4b79c4 100644
--- a/src/extension/init.cpp
+++ b/src/extension/init.cpp
@@ -109,8 +109,6 @@
#include "init.h"
-extern gboolean inkscape_app_use_gui( Inkscape::Application const *app );
-
namespace Inkscape {
namespace Extension {
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/inkscape.cpp b/src/inkscape.cpp
index e1cabd2d5..228841362 100644
--- a/src/inkscape.cpp
+++ b/src/inkscape.cpp
@@ -502,7 +502,7 @@ inkscape_init (SPObject * object)
new (&inkscape->document_set) std::map<SPDocument *, int>();
new (&inkscape->selection_models) std::map<SPDocument *, AppSelectionModel *>();
- inkscape->menus = sp_repr_read_mem (_(menus_skeleton), MENUS_SKELETON_SIZE, NULL);
+ inkscape->menus = NULL;
inkscape->desktops = NULL;
inkscape->dialogs_toggle = TRUE;
inkscape->mapalt = GDK_MOD1_MASK;
@@ -1483,7 +1483,9 @@ profile_path(const char *filename)
}
if (prefdir) {
- prefdir = g_build_filename(prefdir, INKSCAPE_PROFILE_DIR, NULL);
+ const char *prefdir_profile = g_build_filename(prefdir, INKSCAPE_PROFILE_DIR, NULL);
+ g_free((void *)prefdir);
+ prefdir = prefdir_profile;
}
}
#endif
diff --git a/src/knot.cpp b/src/knot.cpp
index 890abd0a1..2b67440dc 100644
--- a/src/knot.cpp
+++ b/src/knot.cpp
@@ -646,34 +646,14 @@ void sp_knot_update_ctrl(SPKnot *knot)
*/
static void sp_knot_set_ctrl_state(SPKnot *knot)
{
+ int state = SP_KNOT_STATE_NORMAL;
if (knot->flags & SP_KNOT_DRAGGING) {
- g_object_set(knot->item,
- "fill_color",
- knot->fill[SP_KNOT_STATE_DRAGGING],
- NULL);
- g_object_set(knot->item,
- "stroke_color",
- knot->stroke[SP_KNOT_STATE_DRAGGING],
- NULL);
+ state = SP_KNOT_STATE_DRAGGING;
} else if (knot->flags & SP_KNOT_MOUSEOVER) {
- g_object_set(knot->item,
- "fill_color",
- knot->fill[SP_KNOT_STATE_MOUSEOVER],
- NULL);
- g_object_set(knot->item,
- "stroke_color",
- knot->stroke[SP_KNOT_STATE_MOUSEOVER],
- NULL);
- } else {
- g_object_set(knot->item,
- "fill_color",
- knot->fill[SP_KNOT_STATE_NORMAL],
- NULL);
- g_object_set(knot->item,
- "stroke_color",
- knot->stroke[SP_KNOT_STATE_NORMAL],
- NULL);
+ state = SP_KNOT_STATE_MOUSEOVER;
}
+ g_object_set(knot->item, "fill_color", knot->fill[state], NULL);
+ g_object_set(knot->item, "stroke_color", knot->stroke[state], NULL);
}
diff --git a/src/libavoid/vertices.h b/src/libavoid/vertices.h
index b07c87f95..619692c23 100644
--- a/src/libavoid/vertices.h
+++ b/src/libavoid/vertices.h
@@ -129,7 +129,7 @@ class VertInfList
unsigned int shapesSize(void) const;
void stats(FILE *fp = stderr)
{
- fprintf(fp, "Conns %d, shapes %d\n", _connVertices,
+ fprintf(fp, "Conns %u, shapes %u\n", _connVertices,
_shapeVertices);
}
private:
diff --git a/src/libcola/connected_components.cpp b/src/libcola/connected_components.cpp
index 1afec55b4..823f7cf6e 100644
--- a/src/libcola/connected_components.cpp
+++ b/src/libcola/connected_components.cpp
@@ -77,7 +77,7 @@ namespace cola {
}
vector<Edge>::const_iterator ei;
SimpleConstraints::const_iterator ci;
- for(ei=es.begin();ei!=es.end();ei++) {
+ for(ei=es.begin();ei!=es.end();++ei) {
vs[ei->first].neighbours.push_back(&vs[ei->second]);
vs[ei->second].neighbours.push_back(&vs[ei->first]);
}
@@ -88,13 +88,13 @@ namespace cola {
dfs(v,remaining,component,cmap);
components.push_back(component);
}
- for(ei=es.begin();ei!=es.end();ei++) {
+ for(ei=es.begin();ei!=es.end();++ei) {
pair<Component*,unsigned> u=cmap[ei->first],
v=cmap[ei->second];
assert(u.first==v.first);
u.first->edges.push_back(make_pair(u.second,v.second));
}
- for(ci=scx.begin();ci!=scx.end();ci++) {
+ for(ci=scx.begin();ci!=scx.end();++ci) {
SimpleConstraint *c=*ci;
pair<Component*,unsigned> u=cmap[c->left],
v=cmap[c->right];
@@ -102,7 +102,7 @@ namespace cola {
u.first->scx.push_back(
new SimpleConstraint(u.second,v.second,c->gap));
}
- for(ci=scy.begin();ci!=scy.end();ci++) {
+ for(ci=scy.begin();ci!=scy.end();++ci) {
SimpleConstraint *c=*ci;
pair<Component*,unsigned> u=cmap[c->left],
v=cmap[c->right];
diff --git a/src/libcola/cycle_detector.cpp b/src/libcola/cycle_detector.cpp
index 89a2ccaae..11e24a0ba 100644
--- a/src/libcola/cycle_detector.cpp
+++ b/src/libcola/cycle_detector.cpp
@@ -53,7 +53,7 @@ void CycleDetector::make_matrix() {
assert(traverse.empty());
// from the edges passed, fill the adjacency matrix
- for (ei = edges->begin(); ei != edges->end(); ei++) {
+ for (ei = edges->begin(); ei != edges->end(); ++ei) {
anEdge = *ei;
// the matrix is indexed by the first vertex of the edge
// the second vertex of the edge is pushed onto another
@@ -241,7 +241,7 @@ bool CycleDetector::find_node(std::vector<Node *> *& list, unsigned k) {
}
pair< bool, vector<unsigned>::iterator > CycleDetector::find_node(std::vector<unsigned>& list, unsigned k) {
- for (vector<unsigned>::iterator ti = traverse.begin(); ti != traverse.end(); ti++) {
+ for (vector<unsigned>::iterator ti = traverse.begin(); ti != traverse.end(); ++ti) {
if (*ti == k) { return pair< bool, vector<unsigned>::iterator >(true, ti); }
}
diff --git a/src/libcola/gradient_projection.cpp b/src/libcola/gradient_projection.cpp
index 47109a4b0..3e41aceac 100644
--- a/src/libcola/gradient_projection.cpp
+++ b/src/libcola/gradient_projection.cpp
@@ -222,7 +222,7 @@ void GradientProjection::destroyVPSC(IncSolver *vpsc) {
delete vpsc;
delete [] cs;
delete [] vs;
- for(vector<Constraint*>::iterator i=lcs.begin();i!=lcs.end();i++) {
+ for(vector<Constraint*>::iterator i=lcs.begin();i!=lcs.end();++i) {
delete *i;
}
lcs.clear();
diff --git a/src/libcola/straightener.cpp b/src/libcola/straightener.cpp
index 650f41aac..fab30d48d 100644
--- a/src/libcola/straightener.cpp
+++ b/src/libcola/straightener.cpp
@@ -90,7 +90,7 @@ namespace straightener {
ds.erase(copyit);
}
}
- for(set<pair<double,unsigned> >::iterator j=pntsOnLineSegment.begin();j!=pntsOnLineSegment.end();j++) {
+ for(set<pair<double,unsigned> >::iterator j=pntsOnLineSegment.begin();j!=pntsOnLineSegment.end();++j) {
path.push_back(j->second);
}
//printf("\n");
@@ -144,11 +144,11 @@ namespace straightener {
e->ypos(conjpos,bs);
}
//cerr << "edge(intersections="<<bs.size()<<":("<<e->startNode<<","<<e->endNode<<"))"<<endl;
- for(vector<double>::iterator it=bs.begin();it!=bs.end();it++) {
+ for(vector<double>::iterator it=bs.begin();it!=bs.end();++it) {
sortedEdges.insert(make_pair(*it,e));
}
}
- for(set<PosEdgePair>::iterator i=sortedEdges.begin();i!=sortedEdges.end();i++) {
+ for(set<PosEdgePair>::iterator i=sortedEdges.begin();i!=sortedEdges.end();++i) {
double pos=i->first;
if(pos < minpos) continue;
if(pos > v->scanpos) break;
@@ -169,7 +169,7 @@ namespace straightener {
if(r!=NULL) {
maxpos=r->scanpos;
}
- for(set<PosEdgePair>::iterator i=sortedEdges.begin();i!=sortedEdges.end();i++) {
+ for(set<PosEdgePair>::iterator i=sortedEdges.begin();i!=sortedEdges.end();++i) {
if(i->first < v->scanpos) continue;
if(i->first > maxpos) break;
double pos=i->first;
@@ -262,7 +262,7 @@ namespace straightener {
// Case A: create constraints between adjacent edges skipping edges joined
// to l,v or r.
Node* lastNode=NULL;
- for(vector<Node*>::iterator i=L.begin();i!=L.end();i++) {
+ for(vector<Node*>::iterator i=L.begin();i!=L.end();++i) {
if((*i)->dummy) {
// node is on an edge
Edge *edge=(*i)->edge;
@@ -284,7 +284,7 @@ namespace straightener {
// their own end, also in the scan line
vector<Node*> skipList;
lastNode=NULL;
- for(vector<Node*>::iterator i=L.begin();i!=L.end();i++) {
+ for(vector<Node*>::iterator i=L.begin();i!=L.end();++i) {
if((*i)->dummy) {
// node is on an edge
if(lastNode!=NULL) {
@@ -292,7 +292,7 @@ namespace straightener {
skipList.push_back(*i);
} else {
for(vector<Node*>::iterator j=skipList.begin();
- j!=skipList.end();j++) {
+ j!=skipList.end();++j) {
//printf(" Rule B: Constraint: v%d +g <= v%d\n",(*j)->id,(*i)->id);
cs.push_back(createConstraint(*j,*i,dim));
}
@@ -309,7 +309,7 @@ namespace straightener {
skipList.clear();
// Case C: reverse of B
lastNode=NULL;
- for(vector<Node*>::reverse_iterator i=L.rbegin();i!=L.rend();i++) {
+ for(vector<Node*>::reverse_iterator i=L.rbegin();i!=L.rend();++i) {
if((*i)->dummy) {
// node is on an edge
if(lastNode!=NULL) {
@@ -317,7 +317,7 @@ namespace straightener {
skipList.push_back(*i);
} else {
for(vector<Node*>::iterator j=skipList.begin();
- j!=skipList.end();j++) {
+ j!=skipList.end();++j) {
//printf(" Rule C: Constraint: v%d +g <= v%d\n",(*i)->id,(*j)->id);
cs.push_back(createConstraint(*i,*j,dim));
}
diff --git a/src/libnrtype/FontFactory.cpp b/src/libnrtype/FontFactory.cpp
index c896cc470..9fc553efd 100644
--- a/src/libnrtype/FontFactory.cpp
+++ b/src/libnrtype/FontFactory.cpp
@@ -25,7 +25,6 @@ typedef INK_UNORDERED_MAP<PangoFontDescription*, font_instance*, font_descr_hash
// need to avoid using the size field
size_t font_descr_hash::operator()( PangoFontDescription *const &x) const {
int h = 0;
- h *= 1128467;
char const *theF = sp_font_description_get_family(x);
h += (theF)?g_str_hash(theF):0;
h *= 1128467;
@@ -295,7 +294,7 @@ font_factory *font_factory::Default(void)
}
font_factory::font_factory(void) :
- nbEnt(0),
+ nbEnt(0), // Note: this "ents" cache only keeps fonts from being unreffed, does not speed up access
maxEnt(32),
ents(static_cast<font_entry*>(g_malloc(maxEnt*sizeof(font_entry)))),
@@ -327,12 +326,6 @@ font_factory::font_factory(void) :
font_factory::~font_factory(void)
{
- if (loadedPtr) {
- FaceMapType* tmp = static_cast<FaceMapType*>(loadedPtr);
- delete tmp;
- loadedPtr = 0;
- }
-
for (int i = 0;i < nbEnt;i++) ents[i].f->Unref();
if ( ents ) g_free(ents);
@@ -344,6 +337,12 @@ font_factory::~font_factory(void)
#endif
//g_object_unref(fontContext);
+ if (loadedPtr) {
+ FaceMapType* tmp = static_cast<FaceMapType*>(loadedPtr);
+ delete tmp;
+ loadedPtr = 0;
+ }
+
// Delete the pango font pointers in the string to instance map
PangoStringToDescrMap::iterator it = fontInstanceMap.begin();
while (it != fontInstanceMap.end()) {
@@ -1126,7 +1125,7 @@ void font_factory::AddInCache(font_instance *who)
return;
}
who->Ref();
- if ( nbEnt == maxEnt ) {
+ if ( nbEnt == maxEnt ) { // cache is filled, unref the oldest-accessed font in it
int bi = 0;
double ba = ents[bi].age;
for (int i = 1;i < nbEnt;i++) {
diff --git a/src/libnrtype/FontInstance.cpp b/src/libnrtype/FontInstance.cpp
index fd0cdd3d4..38a105459 100644
--- a/src/libnrtype/FontInstance.cpp
+++ b/src/libnrtype/FontInstance.cpp
@@ -192,6 +192,7 @@ font_instance::~font_instance(void)
//printf("font instance death\n");
if ( pFont ) {
+ FreeTheFace();
g_object_unref(pFont);
pFont = 0;
}
@@ -232,10 +233,6 @@ void font_instance::Unref(void)
//printf("font %x %s unref'd %i\n",this,tc,refCount);
//free(tc);
if ( refCount <= 0 ) {
- if ( daddy ) {
- daddy->UnrefFace(this);
- }
- daddy=NULL;
delete this;
}
}
@@ -387,6 +384,7 @@ unsigned int font_instance::Attribute(const gchar *key, gchar *str, unsigned int
void font_instance::InitTheFace()
{
+ if (theFace == NULL && pFont != NULL) {
#ifdef USE_PANGO_WIN32
if ( !theFace ) {
LOGFONT *lf=pango_win32_font_logfont(pFont);
@@ -404,6 +402,7 @@ void font_instance::InitTheFace()
FT_Select_Charmap(theFace,ft_encoding_unicode) && FT_Select_Charmap(theFace,ft_encoding_symbol);
}
#endif
+ }
}
void font_instance::FreeTheFace()
@@ -423,6 +422,7 @@ void font_instance::InstallFace(PangoFont* iFace)
return;
}
pFont=iFace;
+ iFace = NULL;
InitTheFace();
diff --git a/src/libnrtype/Layout-TNG-Compute.cpp b/src/libnrtype/Layout-TNG-Compute.cpp
index 7ea089c93..973db0165 100644
--- a/src/libnrtype/Layout-TNG-Compute.cpp
+++ b/src/libnrtype/Layout-TNG-Compute.cpp
@@ -980,6 +980,7 @@ void Layout::Calculator::_buildPangoItemizationForPara(ParagraphInfo *para) con
attribute_font_description->end_index = para_text.bytes();
pango_attr_list_insert(attributes_list, attribute_font_description);
// ownership of attribute is assumed by the list
+ font->Unref();
}
}
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/measure-context.cpp b/src/measure-context.cpp
index 8db703205..7570e36e7 100644
--- a/src/measure-context.cpp
+++ b/src/measure-context.cpp
@@ -48,10 +48,6 @@ using Inkscape::ControlManager;
using Inkscape::CTLINE_SECONDARY;
using Inkscape::Util::unit_table;
-Geom::Point start_point;
-boost::optional<Geom::Point> explicitBase;
-boost::optional<Geom::Point> lastEnd;
-
std::vector<Inkscape::Display::TemporaryItem*> measure_tmp_items;
diff --git a/src/measure-context.h b/src/measure-context.h
index e42265045..7d5a88ab7 100644
--- a/src/measure-context.h
+++ b/src/measure-context.h
@@ -13,6 +13,8 @@
*/
#include "event-context.h"
+#include <2geom/point.h>
+#include <boost/optional.hpp>
#define SP_MEASURE_CONTEXT(obj) (dynamic_cast<SPMeasureContext*>((SPEventContext*)obj))
#define SP_IS_MEASURE_CONTEXT(obj) (dynamic_cast<const SPMeasureContext*>((const SPEventContext*)obj) != NULL)
@@ -31,6 +33,10 @@ public:
private:
SPCanvasItem* grabbed;
+
+ Geom::Point start_point;
+ boost::optional<Geom::Point> explicitBase;
+ boost::optional<Geom::Point> lastEnd;
};
#endif // SEEN_SP_MEASURING_CONTEXT_H
diff --git a/src/menus-skeleton.h b/src/menus-skeleton.h
index 2334a08c1..3fcb77207 100644
--- a/src/menus-skeleton.h
+++ b/src/menus-skeleton.h
@@ -285,6 +285,7 @@ static char const menus_skeleton[] =
" <verb verb-id=\"TutorialsShapes\" />\n"
" <verb verb-id=\"TutorialsAdvanced\" />\n"
" <verb verb-id=\"TutorialsTracing\" />\n"
+" <verb verb-id=\"TutorialsTracingPixelArt\" />\n"
" <verb verb-id=\"TutorialsCalligraphy\" />\n"
" <verb verb-id=\"TutorialsInterpolate\" />\n"
" <verb verb-id=\"TutorialsDesign\" />\n"
diff --git a/src/number-opt-number.h b/src/number-opt-number.h
index 867d0535f..d9ab56102 100644
--- a/src/number-opt-number.h
+++ b/src/number-opt-number.h
@@ -120,6 +120,8 @@ public:
_set = FALSE;
optNumber_set = FALSE;
}
+
+ g_strfreev(values);
}
};
diff --git a/src/object-edit.cpp b/src/object-edit.cpp
index 25bc62a7f..28786bf66 100644
--- a/src/object-edit.cpp
+++ b/src/object-edit.cpp
@@ -785,24 +785,23 @@ sp_genericellipse_side(SPGenericEllipse *ellipse, Geom::Point const &p)
void
ArcKnotHolderEntityStart::knot_set(Geom::Point const &p, Geom::Point const &/*origin*/, guint state)
{
- Inkscape::Preferences *prefs = Inkscape::Preferences::get();
- int snaps = prefs->getInt("/options/rotationsnapsperpi/value", 12);
+ int snaps = Inkscape::Preferences::get()->getInt("/options/rotationsnapsperpi/value", 12);
- SPGenericEllipse *ge = SP_GENERICELLIPSE(item);
SPArc *arc = SP_ARC(item);
- ge->closed = (sp_genericellipse_side(ge, p) == -1) ? TRUE : FALSE;
+ arc->setClosed(sp_genericellipse_side(arc, p) == -1);
- Geom::Point delta = p - Geom::Point(ge->cx.computed, ge->cy.computed);
- Geom::Scale sc(ge->rx.computed, ge->ry.computed);
- ge->start = atan2(delta * sc.inverse());
- if ( ( state & GDK_CONTROL_MASK )
- && snaps )
- {
- ge->start = sp_round(ge->start, M_PI/snaps);
+ Geom::Point delta = p - Geom::Point(arc->cx.computed, arc->cy.computed);
+ Geom::Scale sc(arc->rx.computed, arc->ry.computed);
+
+ arc->start = atan2(delta * sc.inverse());
+
+ if ((state & GDK_CONTROL_MASK) && snaps) {
+ arc->start = sp_round(arc->start, M_PI / snaps);
}
- sp_genericellipse_normalize(ge);
- (static_cast<SPObject *>(arc))->requestDisplayUpdate(SP_OBJECT_MODIFIED_FLAG);
+
+ arc->normalize();
+ arc->requestDisplayUpdate(SP_OBJECT_MODIFIED_FLAG);
}
Geom::Point
@@ -811,7 +810,7 @@ ArcKnotHolderEntityStart::knot_get() const
SPGenericEllipse const *ge = SP_GENERICELLIPSE(item);
SPArc *arc = SP_ARC(item);
- return sp_arc_get_xy(arc, ge->start);
+ return arc->getPointAtAngle(ge->start);
}
void
@@ -828,24 +827,23 @@ ArcKnotHolderEntityStart::knot_click(guint state)
void
ArcKnotHolderEntityEnd::knot_set(Geom::Point const &p, Geom::Point const &/*origin*/, guint state)
{
- Inkscape::Preferences *prefs = Inkscape::Preferences::get();
- int snaps = prefs->getInt("/options/rotationsnapsperpi/value", 12);
+ int snaps = Inkscape::Preferences::get()->getInt("/options/rotationsnapsperpi/value", 12);
- SPGenericEllipse *ge = SP_GENERICELLIPSE(item);
SPArc *arc = SP_ARC(item);
- ge->closed = (sp_genericellipse_side(ge, p) == -1) ? TRUE : FALSE;
+ arc->setClosed(sp_genericellipse_side(arc, p) == -1);
- Geom::Point delta = p - Geom::Point(ge->cx.computed, ge->cy.computed);
- Geom::Scale sc(ge->rx.computed, ge->ry.computed);
- ge->end = atan2(delta * sc.inverse());
- if ( ( state & GDK_CONTROL_MASK )
- && snaps )
- {
- ge->end = sp_round(ge->end, M_PI/snaps);
+ Geom::Point delta = p - Geom::Point(arc->cx.computed, arc->cy.computed);
+ Geom::Scale sc(arc->rx.computed, arc->ry.computed);
+
+ arc->end = atan2(delta * sc.inverse());
+
+ if ((state & GDK_CONTROL_MASK) && snaps) {
+ arc->end = sp_round(arc->end, M_PI/snaps);
}
- sp_genericellipse_normalize(ge);
- (static_cast<SPObject *>(arc))->requestDisplayUpdate(SP_OBJECT_MODIFIED_FLAG);
+
+ arc->normalize();
+ arc->requestDisplayUpdate(SP_OBJECT_MODIFIED_FLAG);
}
Geom::Point
@@ -854,7 +852,7 @@ ArcKnotHolderEntityEnd::knot_get() const
SPGenericEllipse const *ge = SP_GENERICELLIPSE(item);
SPArc *arc = SP_ARC(item);
- return sp_arc_get_xy(arc, ge->end);
+ return arc->getPointAtAngle(ge->end);
}
diff --git a/src/proj_pt.cpp b/src/proj_pt.cpp
index d9d4e06f1..28286948d 100644
--- a/src/proj_pt.cpp
+++ b/src/proj_pt.cpp
@@ -34,6 +34,7 @@ Pt2::Pt2(const gchar *coord_str) {
pt[0] = g_ascii_strtod(coords[0], NULL);
pt[1] = g_ascii_strtod(coords[1], NULL);
pt[2] = g_ascii_strtod(coords[2], NULL);
+ g_strfreev (coords);
}
void
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-ellipse.cpp b/src/sp-ellipse.cpp
index fc78b9777..80e57afc3 100644
--- a/src/sp-ellipse.cpp
+++ b/src/sp-ellipse.cpp
@@ -24,6 +24,8 @@
#include "style.h"
#include "display/curve.h"
#include <glibmm/i18n.h>
+#include <2geom/angle.h>
+#include <2geom/ellipse.h>
#include <2geom/transforms.h>
#include <2geom/pathvector.h>
#include <2geom/svg-path.h>
@@ -32,29 +34,27 @@
#include "preferences.h"
#include "snap-candidate.h"
-/* Common parent class */
-
-#define noELLIPSE_VERBOSE
-
-
#include "sp-factory.h"
namespace {
- SPObject* createEllipse() {
- return new SPEllipse();
- }
+SPObject *create_ellipse()
+{
+ return new SPEllipse();
+}
- SPObject* createCircle() {
- return new SPCircle();
- }
+SPObject *create_circle()
+{
+ return new SPCircle();
+}
- SPObject* createArc() {
- return new SPArc();
- }
+SPObject *create_arc()
+{
+ return new SPArc();
+}
- bool ellipseRegistered = SPFactory::instance().registerObject("svg:ellipse", createEllipse);
- bool circleRegistered = SPFactory::instance().registerObject("svg:circle", createCircle);
- bool arcRegistered = SPFactory::instance().registerObject("arc", createArc);
+bool ellipse_registered = SPFactory::instance().registerObject("svg:ellipse", create_ellipse);
+bool circle_registered = SPFactory::instance().registerObject("svg:circle", create_circle);
+bool arc_registered = SPFactory::instance().registerObject("arc", create_arc);
}
@@ -64,52 +64,34 @@ namespace {
#define SP_2PI (2 * M_PI)
-#if 1
-/* Hmmm... shouldn't this also qualify */
-/* Whether it is faster or not, well, nobody knows */
-#define sp_round(v,m) (((v) < 0.0) ? ((ceil((v) / (m) - 0.5)) * (m)) : ((floor((v) / (m) + 0.5)) * (m)))
-#else
-/* we do not use C99 round(3) function yet */
-static double sp_round(double x, double y)
+SPGenericEllipse::SPGenericEllipse()
+ : SPShape()
+ , start(0)
+ , end(SP_2PI)
+ , _closed(true)
{
- double remain;
-
- g_assert(y > 0.0);
-
- /* return round(x/y) * y; */
-
- remain = fmod(x, y);
-
- if (remain >= 0.5*y)
- return x - remain + y;
- else
- return x - remain;
}
-#endif
-
-static gboolean sp_arc_set_elliptical_path_attribute(SPArc *arc, Inkscape::XML::Node *repr);
-SPGenericEllipse::SPGenericEllipse() : SPShape() {
- this->cx.unset();
- this->cy.unset();
- this->rx.unset();
- this->ry.unset();
+SPGenericEllipse::~SPGenericEllipse()
+{
+}
- this->start = 0.0;
- this->end = SP_2PI;
- this->closed = TRUE;
+bool SPGenericEllipse::closed() {
+ return _closed;
}
-SPGenericEllipse::~SPGenericEllipse() {
+void SPGenericEllipse::setClosed(bool value) {
+ _closed = value;
}
-void SPGenericEllipse::update(SPCtx *ctx, guint flags) {
+void SPGenericEllipse::update(SPCtx *ctx, guint flags)
+{
if (flags & (SP_OBJECT_MODIFIED_FLAG | SP_OBJECT_STYLE_MODIFIED_FLAG | SP_OBJECT_VIEWPORT_MODIFIED_FLAG)) {
Geom::Rect const &viewbox = ((SPItemCtx const *) ctx)->viewport;
double const dx = viewbox.width();
double const dy = viewbox.height();
- double const dr = sqrt(dx*dx + dy*dy)/sqrt(2);
+ double const dr = hypot(dx, dy) / sqrt(2);
double const em = this->style->font_size.computed;
double const ex = em * 0.5; // fixme: get from pango or libnrtype
@@ -124,13 +106,14 @@ void SPGenericEllipse::update(SPCtx *ctx, guint flags) {
SPShape::update(ctx, flags);
}
-void SPGenericEllipse::update_patheffect(bool write) {
+void SPGenericEllipse::update_patheffect(bool write)
+{
this->set_shape();
if (write) {
Inkscape::XML::Node *repr = this->getRepr();
- if ( this->_curve != NULL ) {
+ if (this->_curve != NULL) {
gchar *str = sp_svg_write_path(this->_curve->get_pathvector());
repr->setAttribute("d", str);
g_free(str);
@@ -142,64 +125,49 @@ void SPGenericEllipse::update_patheffect(bool write) {
this->requestDisplayUpdate(SP_OBJECT_MODIFIED_FLAG);
}
-#include <2geom/ellipse.h>
+bool SPGenericEllipse::_isSlice() const
+{
+ Geom::AngleInterval a(this->start, this->end, true);
-/* fixme: Think (Lauris) */
-/* Can't we use arcto in this method? */
-void SPGenericEllipse::set_shape() {
+ return !(Geom::are_near(a.extent(), 0) || Geom::are_near(a.extent(), SP_2PI));
+}
+
+void SPGenericEllipse::set_shape()
+{
if (hasBrokenPathEffect()) {
- g_warning ("The ellipse shape has unknown LPE on it! Convert to path to make it editable preserving the appearance; editing it as ellipse will remove the bad LPE");
+ g_warning("The ellipse shape has unknown LPE on it! Convert to path to make it editable preserving the appearance; editing it as ellipse will remove the bad LPE");
if (this->getRepr()->attribute("d")) {
// unconditionally read the curve from d, if any, to preserve appearance
Geom::PathVector pv = sp_svg_read_pathv(this->getRepr()->attribute("d"));
SPCurve *cold = new SPCurve(pv);
- this->setCurveInsync( cold, TRUE);
+ this->setCurveInsync(cold, TRUE);
cold->unref();
}
return;
}
- if ((this->rx.computed < 1e-18) || (this->ry.computed < 1e-18)) {
- return;
- }
-
- if (fabs(this->end - this->start) < 1e-9) {
- return;
- }
-
- sp_genericellipse_normalize(this);
-
- // figure out if we have a slice, guarding against rounding errors
- double len = fmod(this->end - this->start, SP_2PI);
-
- if (len < 0.0) {
- len += SP_2PI;
+ if (Geom::are_near(this->rx.computed, 0) || Geom::are_near(this->ry.computed, 0)) {
+ return;
}
- bool slice = false;
-
- if (fabs(len) < 1e-8 || fabs(len - SP_2PI) < 1e-8) {
- slice = false;
- this->end = this->start + SP_2PI;
- } else {
- slice = true;
- }
+ this->normalize();
SPCurve *curve = NULL;
// For simplicity, we use a circle with center (0, 0) and radius 1 for our calculations.
- if (slice) {
- Geom::Point startPoint(cos(start), sin(start));
- Geom::Point endPoint(cos(end), sin(end));
- Geom::Point middlePoint = make_angle_bisector_ray(Geom::Ray(Geom::Point(), start), Geom::Ray(Geom::Point(), end)).versor();
+ if (this->_isSlice()) {
+ Geom::Point center(0, 0);
+ Geom::Point start_point = Geom::Point::polar(start);
+ Geom::Point end_point = Geom::Point::polar(end);
+ Geom::Point middle_point = make_angle_bisector_ray(Geom::Ray(center, start), Geom::Ray(center, end)).versor();
Geom::Ellipse ellipse(0, 0, 1, 1, 0);
- Geom::EllipticalArc *arc = ellipse.arc(startPoint, middlePoint, endPoint);
+ Geom::EllipticalArc *arc = ellipse.arc(start_point, middle_point, end_point);
- Geom::Path path(startPoint);
+ Geom::Path path(start_point);
path.append(*arc);
delete arc;
@@ -207,9 +175,9 @@ void SPGenericEllipse::set_shape() {
Geom::PathBuilder pb;
pb.append(path);
- if (this->closed) {
+ if (this->_closed) {
// "pizza slice"
- pb.lineTo(Geom::Point(0, 0));
+ pb.lineTo(center);
pb.closePath();
} else {
// arc only
@@ -234,7 +202,7 @@ void SPGenericEllipse::set_shape() {
/* Reset the shape's curve to the "original_curve"
* This is very important for LPEs to work properly! (the bbox might be recalculated depending on the curve in shape)*/
- this->setCurveInsync( curve, TRUE);
+ this->setCurveInsync(curve, TRUE);
this->setCurveBeforeLPE(curve);
if (hasPathEffect() && sp_lpe_item_path_effects_enabled(this)) {
@@ -242,7 +210,7 @@ void SPGenericEllipse::set_shape() {
bool success = sp_lpe_item_perform_path_effect(this, c_lpe);
if (success) {
- this->setCurveInsync( c_lpe, TRUE);
+ this->setCurveInsync(c_lpe, TRUE);
}
c_lpe->unref();
@@ -251,70 +219,49 @@ void SPGenericEllipse::set_shape() {
curve->unref();
}
-void SPGenericEllipse::snappoints(std::vector<Inkscape::SnapCandidatePoint> &p, Inkscape::SnapPreferences const *snapprefs) {
- sp_genericellipse_normalize(this);
+void SPGenericEllipse::snappoints(std::vector<Inkscape::SnapCandidatePoint> &p, Inkscape::SnapPreferences const *snapprefs)
+{
+ this->normalize();
Geom::Affine const i2dt = this->i2dt_affine();
- // figure out if we have a slice, while guarding against rounding errors
- bool slice = false;
- double len = fmod(this->end - this->start, SP_2PI);
-
- if (len < 0.0) {
- len += SP_2PI;
- }
-
- if (fabs(len) < 1e-8 || fabs(len - SP_2PI) < 1e-8) {
- slice = false;
- this->end = this->start + SP_2PI;
- } else {
- slice = true;
- }
-
- double rx = this->rx.computed;
- double ry = this->ry.computed;
- double cx = this->cx.computed;
- double cy = this->cy.computed;
-
- // Snap to the 4 quadrant points of the this, but only if the arc
+ // Snap to the 4 quadrant points of the ellipse, but only if the arc
// spans far enough to include them
if (snapprefs->isTargetSnappable(Inkscape::SNAPTARGET_ELLIPSE_QUADRANT_POINT)) {
- double angle = 0;
-
- for (angle = 0; angle < SP_2PI; angle += M_PI_2) {
- if (angle >= this->start && angle <= this->end) {
- Geom::Point pt = Geom::Point(cx + cos(angle)*rx, cy + sin(angle)*ry) * i2dt;
+ for (double angle = 0; angle < SP_2PI; angle += M_PI_2) {
+ if (Geom::AngleInterval(this->start, this->end, true).contains(angle)) {
+ Geom::Point pt = this->getPointAtAngle(angle) * i2dt;
p.push_back(Inkscape::SnapCandidatePoint(pt, Inkscape::SNAPSOURCE_ELLIPSE_QUADRANT_POINT, Inkscape::SNAPTARGET_ELLIPSE_QUADRANT_POINT));
}
}
}
- // Add the centre, if we have a closed slice or when explicitly asked for
- bool c1 = snapprefs->isTargetSnappable(Inkscape::SNAPTARGET_NODE_CUSP) && slice && this->closed;
- bool c2 = snapprefs->isTargetSnappable(Inkscape::SNAPTARGET_OBJECT_MIDPOINT);
+ double cx = this->cx.computed;
+ double cy = this->cy.computed;
- if (c1 || c2) {
- Geom::Point pt = Geom::Point(cx, cy) * i2dt;
+ bool slice = this->_isSlice();
- if (c1) {
- p.push_back(Inkscape::SnapCandidatePoint(pt, Inkscape::SNAPSOURCE_NODE_CUSP, Inkscape::SNAPTARGET_NODE_CUSP));
- }
+ // Add the centre, if we have a closed slice or when explicitly asked for
+ if (snapprefs->isTargetSnappable(Inkscape::SNAPTARGET_NODE_CUSP) && slice && this->_closed) {
+ Geom::Point pt = Geom::Point(cx, cy) * i2dt;
+ p.push_back(Inkscape::SnapCandidatePoint(pt, Inkscape::SNAPSOURCE_NODE_CUSP, Inkscape::SNAPTARGET_NODE_CUSP));
+ }
- if (c2) {
- p.push_back(Inkscape::SnapCandidatePoint(pt, Inkscape::SNAPSOURCE_OBJECT_MIDPOINT, Inkscape::SNAPTARGET_OBJECT_MIDPOINT));
- }
+ if (snapprefs->isTargetSnappable(Inkscape::SNAPTARGET_OBJECT_MIDPOINT)) {
+ Geom::Point pt = Geom::Point(cx, cy) * i2dt;
+ p.push_back(Inkscape::SnapCandidatePoint(pt, Inkscape::SNAPSOURCE_OBJECT_MIDPOINT, Inkscape::SNAPTARGET_OBJECT_MIDPOINT));
}
// And if we have a slice, also snap to the endpoints
if (snapprefs->isTargetSnappable(Inkscape::SNAPTARGET_NODE_CUSP) && slice) {
// Add the start point, if it's not coincident with a quadrant point
- if (fmod(this->start, M_PI_2) != 0.0 ) {
- Geom::Point pt = Geom::Point(cx + cos(this->start)*rx, cy + sin(this->start)*ry) * i2dt;
+ if (!Geom::are_near(std::fmod(this->start, M_PI_2), 0)) {
+ Geom::Point pt = this->getPointAtAngle(this->start) * i2dt;
p.push_back(Inkscape::SnapCandidatePoint(pt, Inkscape::SNAPSOURCE_NODE_CUSP, Inkscape::SNAPTARGET_NODE_CUSP));
}
// Add the end point, if it's not coincident with a quadrant point
- if (fmod(this->end, M_PI_2) != 0.0 ) {
- Geom::Point pt = Geom::Point(cx + cos(this->end)*rx, cy + sin(this->end)*ry) * i2dt;
+ if (!Geom::are_near(std::fmod(this->end, M_PI_2), 0)) {
+ Geom::Point pt = this->getPointAtAngle(this->end) * i2dt;
p.push_back(Inkscape::SnapCandidatePoint(pt, Inkscape::SNAPSOURCE_NODE_CUSP, Inkscape::SNAPTARGET_NODE_CUSP));
}
}
@@ -323,13 +270,14 @@ void SPGenericEllipse::snappoints(std::vector<Inkscape::SnapCandidatePoint> &p,
Geom::Affine SPGenericEllipse::set_transform(Geom::Affine const &xform)
{
/* Calculate ellipse start in parent coords. */
- Geom::Point pos( Geom::Point(this->cx.computed, this->cy.computed) * xform );
+ Geom::Point pos(Geom::Point(this->cx.computed, this->cy.computed) * xform);
/* This function takes care of translation and scaling, we return whatever parts we can't
handle. */
Geom::Affine ret(Geom::Affine(xform).withoutTranslation());
gdouble const sw = hypot(ret[0], ret[1]);
gdouble const sh = hypot(ret[2], ret[3]);
+
if (sw > 1e-9) {
ret[0] /= sw;
ret[1] /= sw;
@@ -337,6 +285,7 @@ Geom::Affine SPGenericEllipse::set_transform(Geom::Affine const &xform)
ret[0] = 1.0;
ret[1] = 0.0;
}
+
if (sh > 1e-9) {
ret[2] /= sh;
ret[3] /= sh;
@@ -348,6 +297,7 @@ Geom::Affine SPGenericEllipse::set_transform(Geom::Affine const &xform)
if (this->rx._set) {
this->rx = this->rx.computed * sw;
}
+
if (this->ry._set) {
this->ry = this->ry.computed * sh;
}
@@ -373,26 +323,16 @@ Geom::Affine SPGenericEllipse::set_transform(Geom::Affine const &xform)
return ret;
}
-void
-sp_genericellipse_normalize(SPGenericEllipse *ellipse)
+void SPGenericEllipse::normalize()
{
- ellipse->start = fmod(ellipse->start, SP_2PI);
- ellipse->end = fmod(ellipse->end, SP_2PI);
+ Geom::AngleInterval a(this->start, this->end, true);
- if (ellipse->start < 0.0) {
- ellipse->start += SP_2PI;
- }
-
- double diff = ellipse->start - ellipse->end;
-
- if (diff >= 0.0) {
- ellipse->end += diff - fmod(diff, SP_2PI) + SP_2PI;
- }
-
- /* Now we keep: 0 <= start < end <= 2*PI */
+ this->start = a.initialAngle().radians0();
+ this->end = a.finalAngle().radians0();
}
-Inkscape::XML::Node* SPGenericEllipse::write(Inkscape::XML::Document *xml_doc, Inkscape::XML::Node *repr, guint flags) {
+Inkscape::XML::Node *SPGenericEllipse::write(Inkscape::XML::Document *xml_doc, Inkscape::XML::Node *repr, guint flags)
+{
if (flags & SP_OBJECT_WRITE_EXT) {
if ((flags & SP_OBJECT_WRITE_BUILD) && !repr) {
repr = xml_doc->createElement("svg:path");
@@ -404,7 +344,7 @@ Inkscape::XML::Node* SPGenericEllipse::write(Inkscape::XML::Document *xml_doc, I
sp_repr_set_svg_double(repr, "sodipodi:ry", this->ry.computed);
if (SP_IS_ARC(this)) {
- sp_arc_set_elliptical_path_attribute(SP_ARC(this), this->getRepr());
+ SP_ARC(this)->sp_arc_set_elliptical_path_attribute(this->getRepr());
}
}
@@ -416,23 +356,27 @@ Inkscape::XML::Node* SPGenericEllipse::write(Inkscape::XML::Document *xml_doc, I
}
/* SVG <ellipse> element */
-SPEllipse::SPEllipse() : SPGenericEllipse() {
+SPEllipse::SPEllipse() : SPGenericEllipse()
+{
}
-SPEllipse::~SPEllipse() {
+SPEllipse::~SPEllipse()
+{
}
-void SPEllipse::build(SPDocument *document, Inkscape::XML::Node *repr) {
- SPGenericEllipse::build(document, repr);
+void SPEllipse::build(SPDocument *document, Inkscape::XML::Node *repr)
+{
+ SPGenericEllipse::build(document, repr);
- this->readAttr( "cx" );
- this->readAttr( "cy" );
- this->readAttr( "rx" );
- this->readAttr( "ry" );
+ this->readAttr("cx");
+ this->readAttr("cy");
+ this->readAttr("rx");
+ this->readAttr("ry");
}
-Inkscape::XML::Node* SPEllipse::write(Inkscape::XML::Document *xml_doc, Inkscape::XML::Node *repr, guint flags) {
+Inkscape::XML::Node *SPEllipse::write(Inkscape::XML::Document *xml_doc, Inkscape::XML::Node *repr, guint flags)
+{
if ((flags & SP_OBJECT_WRITE_BUILD) && !repr) {
repr = xml_doc->createElement("svg:ellipse");
}
@@ -448,80 +392,68 @@ Inkscape::XML::Node* SPEllipse::write(Inkscape::XML::Document *xml_doc, Inkscape
}
-void SPEllipse::set(unsigned int key, gchar const* value) {
+void SPEllipse::set(unsigned int key, gchar const *value)
+{
switch (key) {
- case SP_ATTR_CX:
- this->cx.readOrUnset(value);
- this->requestDisplayUpdate(SP_OBJECT_MODIFIED_FLAG);
- break;
-
- case SP_ATTR_CY:
- this->cy.readOrUnset(value);
- this->requestDisplayUpdate(SP_OBJECT_MODIFIED_FLAG);
- break;
-
- case SP_ATTR_RX:
- if (!this->rx.read(value) || (this->rx.value <= 0.0)) {
- this->rx.unset();
- }
-
- this->requestDisplayUpdate(SP_OBJECT_MODIFIED_FLAG);
- break;
-
- case SP_ATTR_RY:
- if (!this->ry.read(value) || (this->ry.value <= 0.0)) {
- this->ry.unset();
- }
-
- this->requestDisplayUpdate(SP_OBJECT_MODIFIED_FLAG);
- break;
-
- default:
- SPGenericEllipse::set(key, value);
- break;
- }
-}
-
-const char* SPEllipse::displayName() {
- return _("Ellipse");
-}
+ case SP_ATTR_CX:
+ this->cx.readOrUnset(value);
+ this->requestDisplayUpdate(SP_OBJECT_MODIFIED_FLAG);
+ break;
+
+ case SP_ATTR_CY:
+ this->cy.readOrUnset(value);
+ this->requestDisplayUpdate(SP_OBJECT_MODIFIED_FLAG);
+ break;
+
+ case SP_ATTR_RX:
+ if (!this->rx.read(value) || (this->rx.value <= 0.0)) {
+ this->rx.unset();
+ }
+ this->requestDisplayUpdate(SP_OBJECT_MODIFIED_FLAG);
+ break;
-void
-sp_ellipse_position_set(SPEllipse *ellipse, gdouble x, gdouble y, gdouble rx, gdouble ry)
-{
- SPGenericEllipse *ge;
-
- g_return_if_fail(ellipse != NULL);
- g_return_if_fail(SP_IS_ELLIPSE(ellipse));
+ case SP_ATTR_RY:
+ if (!this->ry.read(value) || (this->ry.value <= 0.0)) {
+ this->ry.unset();
+ }
- ge = SP_GENERICELLIPSE(ellipse);
+ this->requestDisplayUpdate(SP_OBJECT_MODIFIED_FLAG);
+ break;
- ge->cx.computed = x;
- ge->cy.computed = y;
- ge->rx.computed = rx;
- ge->ry.computed = ry;
+ default:
+ SPGenericEllipse::set(key, value);
+ break;
+ }
+}
- ((SPObject *)ge)->requestDisplayUpdate(SP_OBJECT_MODIFIED_FLAG);
+const char *SPEllipse::displayName()
+{
+ return _("Ellipse");
}
+
/* SVG <circle> element */
-SPCircle::SPCircle() : SPGenericEllipse() {
+SPCircle::SPCircle() : SPGenericEllipse()
+{
}
-SPCircle::~SPCircle() {
+SPCircle::~SPCircle()
+{
}
-void SPCircle::build(SPDocument *document, Inkscape::XML::Node *repr) {
+void SPCircle::build(SPDocument *document, Inkscape::XML::Node *repr)
+{
SPGenericEllipse::build(document, repr);
- this->readAttr( "cx" );
- this->readAttr( "cy" );
- this->readAttr( "r" );
+ this->readAttr("cx");
+ this->readAttr("cy");
+ this->readAttr("r");
}
-Inkscape::XML::Node* SPCircle::write(Inkscape::XML::Document *xml_doc, Inkscape::XML::Node *repr, guint flags) {
+Inkscape::XML::Node *SPCircle::write(Inkscape::XML::Document *xml_doc, Inkscape::XML::Node *repr, guint flags)
+{
if ((flags & SP_OBJECT_WRITE_BUILD) && !repr) {
repr = xml_doc->createElement("svg:circle");
}
@@ -535,55 +467,60 @@ Inkscape::XML::Node* SPCircle::write(Inkscape::XML::Document *xml_doc, Inkscape:
return repr;
}
-void SPCircle::set(unsigned int key, gchar const* value) {
+void SPCircle::set(unsigned int key, gchar const *value)
+{
switch (key) {
- case SP_ATTR_CX:
- this->cx.readOrUnset(value);
- this->requestDisplayUpdate(SP_OBJECT_MODIFIED_FLAG);
- break;
-
- case SP_ATTR_CY:
- this->cy.readOrUnset(value);
- this->requestDisplayUpdate(SP_OBJECT_MODIFIED_FLAG);
- break;
-
- case SP_ATTR_R:
- if (!this->rx.read(value) || this->rx.value <= 0.0) {
- this->rx.unset();
- }
-
- this->ry = this->rx;
- this->requestDisplayUpdate(SP_OBJECT_MODIFIED_FLAG);
- break;
-
- default:
- SPGenericEllipse::set(key, value);
- break;
+ case SP_ATTR_CX:
+ this->cx.readOrUnset(value);
+ this->requestDisplayUpdate(SP_OBJECT_MODIFIED_FLAG);
+ break;
+
+ case SP_ATTR_CY:
+ this->cy.readOrUnset(value);
+ this->requestDisplayUpdate(SP_OBJECT_MODIFIED_FLAG);
+ break;
+
+ case SP_ATTR_R:
+ if (!this->rx.read(value) || this->rx.value <= 0.0) {
+ this->rx.unset();
+ }
+
+ this->ry = this->rx;
+ this->requestDisplayUpdate(SP_OBJECT_MODIFIED_FLAG);
+ break;
+
+ default:
+ SPGenericEllipse::set(key, value);
+ break;
}
}
-const char* SPCircle::displayName() {
- return _("Circle");
+const char *SPCircle::displayName()
+{
+ return _("Circle");
}
/* <path sodipodi:type="arc"> element */
-SPArc::SPArc() : SPGenericEllipse() {
+SPArc::SPArc() : SPGenericEllipse()
+{
}
-SPArc::~SPArc() {
+SPArc::~SPArc()
+{
}
-void SPArc::build(SPDocument *document, Inkscape::XML::Node *repr) {
- SPGenericEllipse::build(document, repr);
+void SPArc::build(SPDocument *document, Inkscape::XML::Node *repr)
+{
+ SPGenericEllipse::build(document, repr);
- this->readAttr( "sodipodi:cx" );
- this->readAttr( "sodipodi:cy" );
- this->readAttr( "sodipodi:rx" );
- this->readAttr( "sodipodi:ry" );
+ this->readAttr("sodipodi:cx");
+ this->readAttr("sodipodi:cy");
+ this->readAttr("sodipodi:rx");
+ this->readAttr("sodipodi:ry");
- this->readAttr( "sodipodi:start" );
- this->readAttr( "sodipodi:end" );
- this->readAttr( "sodipodi:open" );
+ this->readAttr("sodipodi:start");
+ this->readAttr("sodipodi:end");
+ this->readAttr("sodipodi:open");
}
/*
@@ -594,32 +531,33 @@ void SPArc::build(SPDocument *document, Inkscape::XML::Node *repr) {
* See SVG 1.0 Specification W3C Recommendation
* ``F.6 Ellptical arc implementation notes'' for more detail.
*/
-static gboolean
-sp_arc_set_elliptical_path_attribute(SPArc *arc, Inkscape::XML::Node *repr)
+bool SPArc::sp_arc_set_elliptical_path_attribute(Inkscape::XML::Node *repr)
{
- SPGenericEllipse *ge = SP_GENERICELLIPSE(arc);
-
Inkscape::SVG::PathString str;
- Geom::Point p1 = sp_arc_get_xy(arc, ge->start);
- Geom::Point p2 = sp_arc_get_xy(arc, ge->end);
- double rx = ge->rx.computed;
- double ry = ge->ry.computed;
+ Geom::Point p1 = this->getPointAtAngle(this->start);
+ Geom::Point p2 = this->getPointAtAngle(this->end);
+ double rx = this->rx.computed;
+ double ry = this->ry.computed;
str.moveTo(p1);
- double dt = fmod(ge->end - ge->start, SP_2PI);
+ double dt = fmod(this->end - this->start, SP_2PI);
+
if (fabs(dt) < 1e-6) {
- Geom::Point ph = sp_arc_get_xy(arc, (ge->start + ge->end) / 2.0);
+ Geom::Point ph = getPointAtAngle((this->start + this->end) / 2.0);
+
str.arcTo(rx, ry, 0, true, true, ph)
- .arcTo(rx, ry, 0, true, true, p2)
- .closePath();
+ .arcTo(rx, ry, 0, true, true, p2)
+ .closePath();
} else {
bool fa = (fabs(dt) > M_PI);
bool fs = (dt > 0);
+
str.arcTo(rx, ry, 0, fa, fs, p2);
- if (ge->closed) {
- Geom::Point center = Geom::Point(ge->cx.computed, ge->cy.computed);
+
+ if (this->_closed) {
+ Geom::Point center = Geom::Point(this->cx.computed, this->cy.computed);
str.lineTo(center).closePath();
}
}
@@ -628,7 +566,8 @@ sp_arc_set_elliptical_path_attribute(SPArc *arc, Inkscape::XML::Node *repr)
return true;
}
-Inkscape::XML::Node* SPArc::write(Inkscape::XML::Document *xml_doc, Inkscape::XML::Node *repr, guint flags) {
+Inkscape::XML::Node *SPArc::write(Inkscape::XML::Document *xml_doc, Inkscape::XML::Node *repr, guint flags)
+{
if ((flags & SP_OBJECT_WRITE_BUILD) && !repr) {
repr = xml_doc->createElement("svg:path");
}
@@ -642,17 +581,11 @@ Inkscape::XML::Node* SPArc::write(Inkscape::XML::Document *xml_doc, Inkscape::XM
sp_repr_set_svg_double(repr, "sodipodi:ry", this->ry.computed);
// write start and end only if they are non-trivial; otherwise remove
- gdouble len = fmod(this->end - this->start, SP_2PI);
-
- if (len < 0.0) {
- len += SP_2PI;
- }
-
- if (!(fabs(len) < 1e-8 || fabs(len - SP_2PI) < 1e-8)) {
+ if (this->_isSlice()) {
sp_repr_set_svg_double(repr, "sodipodi:start", this->start);
sp_repr_set_svg_double(repr, "sodipodi:end", this->end);
- repr->setAttribute("sodipodi:open", (!this->closed) ? "true" : NULL);
+ repr->setAttribute("sodipodi:open", (!this->_closed) ? "true" : NULL);
} else {
repr->setAttribute("sodipodi:end", NULL);
repr->setAttribute("sodipodi:start", NULL);
@@ -661,73 +594,75 @@ Inkscape::XML::Node* SPArc::write(Inkscape::XML::Document *xml_doc, Inkscape::XM
}
// write d=
- sp_arc_set_elliptical_path_attribute(this, repr);
+ this->sp_arc_set_elliptical_path_attribute(repr);
SPGenericEllipse::write(xml_doc, repr, flags);
return repr;
}
-void SPArc::set(unsigned int key, gchar const* value) {
+void SPArc::set(unsigned int key, gchar const *value)
+{
switch (key) {
- case SP_ATTR_SODIPODI_CX:
- this->cx.readOrUnset(value);
- this->requestDisplayUpdate(SP_OBJECT_MODIFIED_FLAG);
- break;
-
- case SP_ATTR_SODIPODI_CY:
- this->cy.readOrUnset(value);
- this->requestDisplayUpdate(SP_OBJECT_MODIFIED_FLAG);
- break;
-
- case SP_ATTR_SODIPODI_RX:
- if (!this->rx.read(value) || this->rx.computed <= 0.0) {
- this->rx.unset();
- }
+ case SP_ATTR_SODIPODI_CX:
+ this->cx.readOrUnset(value);
+ this->requestDisplayUpdate(SP_OBJECT_MODIFIED_FLAG);
+ break;
+
+ case SP_ATTR_SODIPODI_CY:
+ this->cy.readOrUnset(value);
+ this->requestDisplayUpdate(SP_OBJECT_MODIFIED_FLAG);
+ break;
+
+ case SP_ATTR_SODIPODI_RX:
+ if (!this->rx.read(value) || this->rx.computed <= 0.0) {
+ this->rx.unset();
+ }
- this->requestDisplayUpdate(SP_OBJECT_MODIFIED_FLAG);
- break;
+ this->requestDisplayUpdate(SP_OBJECT_MODIFIED_FLAG);
+ break;
- case SP_ATTR_SODIPODI_RY:
- if (!this->ry.read(value) || this->ry.computed <= 0.0) {
- this->ry.unset();
- }
+ case SP_ATTR_SODIPODI_RY:
+ if (!this->ry.read(value) || this->ry.computed <= 0.0) {
+ this->ry.unset();
+ }
- this->requestDisplayUpdate(SP_OBJECT_MODIFIED_FLAG);
- break;
+ this->requestDisplayUpdate(SP_OBJECT_MODIFIED_FLAG);
+ break;
- case SP_ATTR_SODIPODI_START:
- if (value) {
- sp_svg_number_read_d(value, &this->start);
- } else {
- this->start = 0;
- }
+ case SP_ATTR_SODIPODI_START:
+ if (value) {
+ sp_svg_number_read_d(value, &this->start);
+ } else {
+ this->start = 0;
+ }
- this->requestDisplayUpdate(SP_OBJECT_MODIFIED_FLAG);
- break;
+ this->requestDisplayUpdate(SP_OBJECT_MODIFIED_FLAG);
+ break;
- case SP_ATTR_SODIPODI_END:
- if (value) {
- sp_svg_number_read_d(value, &this->end);
- } else {
- this->end = 2 * M_PI;
- }
+ case SP_ATTR_SODIPODI_END:
+ if (value) {
+ sp_svg_number_read_d(value, &this->end);
+ } else {
+ this->end = 2 * M_PI;
+ }
- this->requestDisplayUpdate(SP_OBJECT_MODIFIED_FLAG);
- break;
+ this->requestDisplayUpdate(SP_OBJECT_MODIFIED_FLAG);
+ break;
- case SP_ATTR_SODIPODI_OPEN:
- this->closed = (!value);
- this->requestDisplayUpdate(SP_OBJECT_MODIFIED_FLAG);
- break;
+ case SP_ATTR_SODIPODI_OPEN:
+ this->_closed = (!value);
+ this->requestDisplayUpdate(SP_OBJECT_MODIFIED_FLAG);
+ break;
- default:
- SPGenericEllipse::set(key, value);
- break;
+ default:
+ SPGenericEllipse::set(key, value);
+ break;
}
}
-void SPArc::modified(guint flags) {
+void SPArc::modified(guint flags)
+{
if (flags & (SP_OBJECT_MODIFIED_FLAG | SP_OBJECT_STYLE_MODIFIED_FLAG | SP_OBJECT_VIEWPORT_MODIFIED_FLAG)) {
this->set_shape();
}
@@ -735,16 +670,10 @@ void SPArc::modified(guint flags) {
SPGenericEllipse::modified(flags);
}
-
-const char* SPArc::displayName() {
- gdouble len = fmod(this->end - this->start, SP_2PI);
-
- if (len < 0.0) {
- len += SP_2PI;
- }
-
- if (!(fabs(len) < 1e-8 || fabs(len - SP_2PI) < 1e-8)) {
- if (this->closed) {
+const char *SPArc::displayName()
+{
+ if (this->_isSlice()) {
+ if (this->_closed) {
return _("Segment");
} else {
return _("Arc");
@@ -754,40 +683,33 @@ const char* SPArc::displayName() {
}
}
-void
-sp_arc_position_set(SPArc *arc, gdouble x, gdouble y, gdouble rx, gdouble ry)
+void SPArc::sp_arc_position_set(gdouble x, gdouble y, gdouble rx, gdouble ry)
{
- g_return_if_fail(arc != NULL);
- g_return_if_fail(SP_IS_ARC(arc));
-
- SPGenericEllipse *ge = SP_GENERICELLIPSE(arc);
+ this->cx.computed = x;
+ this->cy.computed = y;
+ this->rx.computed = rx;
+ this->ry.computed = ry;
- ge->cx.computed = x;
- ge->cy.computed = y;
- ge->rx.computed = rx;
- ge->ry.computed = ry;
Inkscape::Preferences *prefs = Inkscape::Preferences::get();
+
// those pref values are in degrees, while we want radians
- if (prefs->getDouble("/tools/shapes/arc/start", 0.0) != 0)
- ge->start = prefs->getDouble("/tools/shapes/arc/start", 0.0) * M_PI / 180;
- if (prefs->getDouble("/tools/shapes/arc/end", 0.0) != 0)
- ge->end = prefs->getDouble("/tools/shapes/arc/end", 0.0) * M_PI / 180;
- if (!prefs->getBool("/tools/shapes/arc/open"))
- ge->closed = 1;
- else
- ge->closed = 0;
+ if (prefs->getDouble("/tools/shapes/arc/start", 0.0) != 0) {
+ this->start = Geom::Angle::from_degrees(prefs->getDouble("/tools/shapes/arc/start", 0.0)).radians0();
+ }
- ((SPObject *)arc)->requestDisplayUpdate(SP_OBJECT_MODIFIED_FLAG);
-}
+ if (prefs->getDouble("/tools/shapes/arc/end", 0.0) != 0) {
+ this->end = Geom::Angle::from_degrees(prefs->getDouble("/tools/shapes/arc/end", 0.0)).radians0();
+ }
-Geom::Point sp_arc_get_xy(SPArc *arc, gdouble arg)
-{
- SPGenericEllipse *ge = SP_GENERICELLIPSE(arc);
+ this->_closed = !prefs->getBool("/tools/shapes/arc/open");
- return Geom::Point(ge->rx.computed * cos(arg) + ge->cx.computed,
- ge->ry.computed * sin(arg) + ge->cy.computed);
+ this->requestDisplayUpdate(SP_OBJECT_MODIFIED_FLAG);
}
+Geom::Point SPGenericEllipse::getPointAtAngle(double arg) const
+{
+ return Geom::Point::polar(arg) * Geom::Scale(rx.computed, ry.computed) * Geom::Translate(cx.computed, cy.computed);
+}
/*
Local Variables:
diff --git a/src/sp-ellipse.h b/src/sp-ellipse.h
index 083f5847d..eab0b4907 100644
--- a/src/sp-ellipse.h
+++ b/src/sp-ellipse.h
@@ -23,29 +23,47 @@
class SPGenericEllipse : public SPShape {
public:
- SPGenericEllipse();
- virtual ~SPGenericEllipse();
+ SPGenericEllipse();
+ virtual ~SPGenericEllipse();
- SVGLength cx;
- SVGLength cy;
- SVGLength rx;
- SVGLength ry;
+ SVGLength cx;
+ SVGLength cy;
+ SVGLength rx;
+ SVGLength ry;
- unsigned int closed : 1;
- double start, end;
+ /**
+ * If we have a slice, returns whether the shape is closed ("pizza slice") or not (arc only).
+ */
+ bool closed();
+ void setClosed(bool value);
- virtual void update(SPCtx* ctx, unsigned int flags);
- virtual Inkscape::XML::Node* write(Inkscape::XML::Document *xml_doc, Inkscape::XML::Node *repr, guint flags);
+ double start, end;
- virtual void snappoints(std::vector<Inkscape::SnapCandidatePoint> &p, Inkscape::SnapPreferences const *snapprefs);
- virtual void set_shape();
- virtual Geom::Affine set_transform(Geom::Affine const& xform);
+ virtual void update(SPCtx *ctx, unsigned int flags);
+ virtual Inkscape::XML::Node *write(Inkscape::XML::Document *xml_doc, Inkscape::XML::Node *repr, guint flags);
- virtual void update_patheffect(bool write);
+ virtual void snappoints(std::vector<Inkscape::SnapCandidatePoint> &p, Inkscape::SnapPreferences const *snapprefs);
+ virtual void set_shape();
+ virtual Geom::Affine set_transform(Geom::Affine const &xform);
+
+ virtual void update_patheffect(bool write);
+
+ /**
+ * @brief Makes sure that start and end lie between 0 and 2 * PI.
+ */
+ void normalize();
+
+ Geom::Point getPointAtAngle(double arg) const;
+
+protected:
+ /**
+ * @brief Determines whether the shape is a part of an ellipse.
+ */
+ bool _isSlice() const;
+
+ bool _closed;
};
-/* This is technically priate by we need this in object edit (Lauris) */
-void sp_genericellipse_normalize (SPGenericEllipse *ellipse);
/* SVG <ellipse> element */
#define SP_ELLIPSE(obj) (dynamic_cast<SPEllipse*>((SPObject*)obj))
@@ -53,16 +71,15 @@ void sp_genericellipse_normalize (SPGenericEllipse *ellipse);
class SPEllipse : public SPGenericEllipse {
public:
- SPEllipse();
- virtual ~SPEllipse();
+ SPEllipse();
+ virtual ~SPEllipse();
- virtual void build(SPDocument *document, Inkscape::XML::Node *repr);
- virtual Inkscape::XML::Node* write(Inkscape::XML::Document *xml_doc, Inkscape::XML::Node *repr, guint flags);
- virtual void set(unsigned int key, gchar const* value);
- virtual const char* displayName();
+ virtual void build(SPDocument *document, Inkscape::XML::Node *repr);
+ virtual Inkscape::XML::Node *write(Inkscape::XML::Document *xml_doc, Inkscape::XML::Node *repr, guint flags);
+ virtual void set(unsigned int key, gchar const *value);
+ virtual const char *displayName();
};
-void sp_ellipse_position_set (SPEllipse * ellipse, gdouble x, gdouble y, gdouble rx, gdouble ry);
/* SVG <circle> element */
#define SP_CIRCLE(obj) (dynamic_cast<SPCircle*>((SPObject*)obj))
@@ -70,32 +87,48 @@ void sp_ellipse_position_set (SPEllipse * ellipse, gdouble x, gdouble y, gdouble
class SPCircle : public SPGenericEllipse {
public:
- SPCircle();
- virtual ~SPCircle();
+ SPCircle();
+ virtual ~SPCircle();
- virtual void build(SPDocument *document, Inkscape::XML::Node *repr);
- virtual Inkscape::XML::Node* write(Inkscape::XML::Document *xml_doc, Inkscape::XML::Node *repr, guint flags);
- virtual void set(unsigned int key, gchar const* value);
- virtual const char* displayName();
+ virtual void build(SPDocument *document, Inkscape::XML::Node *repr);
+ virtual Inkscape::XML::Node *write(Inkscape::XML::Document *xml_doc, Inkscape::XML::Node *repr, guint flags);
+ virtual void set(unsigned int key, gchar const *value);
+ virtual const char *displayName();
};
+
/* <path sodipodi:type="arc"> element */
#define SP_ARC(obj) (dynamic_cast<SPArc*>((SPObject*)obj))
#define SP_IS_ARC(obj) (dynamic_cast<const SPArc*>((SPObject*)obj) != NULL)
class SPArc : public SPGenericEllipse {
public:
- SPArc();
- virtual ~SPArc();
-
- virtual void build(SPDocument *document, Inkscape::XML::Node *repr);
- virtual Inkscape::XML::Node* write(Inkscape::XML::Document *xml_doc, Inkscape::XML::Node *repr, guint flags);
- virtual void set(unsigned int key, gchar const* value);
- virtual const char* displayName();
- virtual void modified(unsigned int flags);
-};
+ SPArc();
+ virtual ~SPArc();
-void sp_arc_position_set (SPArc * arc, gdouble x, gdouble y, gdouble rx, gdouble ry);
-Geom::Point sp_arc_get_xy (SPArc *ge, gdouble arg);
+ virtual void build(SPDocument *document, Inkscape::XML::Node *repr);
+ virtual Inkscape::XML::Node *write(Inkscape::XML::Document *xml_doc, Inkscape::XML::Node *repr, guint flags);
+ virtual void set(unsigned int key, gchar const *value);
+ virtual const char *displayName();
+ virtual void modified(unsigned int flags);
+
+ void sp_arc_position_set(gdouble x, gdouble y, gdouble rx, gdouble ry);
+
+private:
+ bool sp_arc_set_elliptical_path_attribute(Inkscape::XML::Node *repr);
+
+ friend class SPGenericEllipse;
+};
#endif
+
+/*
+ Local Variables:
+ mode:c++
+ c-file-style:"stroustrup"
+ c-file-offsets:((innamespace . 0)(inline-open . 0)(case-label . +))
+ indent-tabs-mode:nil
+ fill-column:99
+ End:
+*/
+// vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=8:softtabstop=4:fileencoding=utf-8:textwidth=99 :
diff --git a/src/sp-filter.cpp b/src/sp-filter.cpp
index 91389bf7d..1a5c65be9 100644
--- a/src/sp-filter.cpp
+++ b/src/sp-filter.cpp
@@ -114,6 +114,10 @@ void SPFilter::release() {
this->href = NULL;
}
+ for (map<gchar *, int, ltstr>::const_iterator i = this->_image_name->begin() ; i != this->_image_name->end() ; i++) {
+ g_free(i->first);
+ }
+
delete this->_image_name;
SPObject::release();
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 88564c0ac..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();
@@ -326,7 +329,12 @@ Inkscape::DrawingItem* SPFlowtext::show(Inkscape::Drawing &drawing, unsigned int
}
void SPFlowtext::hide(unsigned int key) {
- SPItem::hide(key);
+ for (SPItemView* v = this->display; v != NULL; v = v->next) {
+ if (v->key == key) {
+ Inkscape::DrawingGroup *g = dynamic_cast<Inkscape::DrawingGroup *>(v->arenaitem);
+ this->_clearFlow(g);
+ }
+ }
}
diff --git a/src/sp-image.cpp b/src/sp-image.cpp
index 05dfb5f48..f2fc6a37a 100644
--- a/src/sp-image.cpp
+++ b/src/sp-image.cpp
@@ -682,11 +682,12 @@ Inkscape::Pixbuf *sp_image_repr_read_image(gchar const *href, gchar const *absre
// and if it fails, we also try to use bare href regardless of its g_path_is_absolute
if (g_file_test (fullname, G_FILE_TEST_EXISTS) && !g_file_test (fullname, G_FILE_TEST_IS_DIR)) {
inkpb = Inkscape::Pixbuf::create_from_file(fullname);
- g_free (fullname);
if (inkpb != NULL) {
+ g_free (fullname);
return inkpb;
}
}
+ g_free (fullname);
}
/* try filename as absolute */
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 a99bf85cc..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) );
}
@@ -665,16 +665,20 @@ Inkscape::XML::Node* SPItem::write(Inkscape::XML::Document *xml_doc, Inkscape::X
if (item->clip_ref){
if (item->clip_ref->getObject()) {
- const gchar *value = g_strdup_printf ("url(%s)", item->clip_ref->getURI()->toString());
+ gchar *uri = item->clip_ref->getURI()->toString();
+ const gchar *value = g_strdup_printf ("url(%s)", uri);
repr->setAttribute ("clip-path", value);
g_free ((void *) value);
+ g_free ((void *) uri);
}
}
if (item->mask_ref){
if (item->mask_ref->getObject()) {
- const gchar *value = g_strdup_printf ("url(%s)", item->mask_ref->getURI()->toString());
+ gchar *uri = item->mask_ref->getURI()->toString();
+ const gchar *value = g_strdup_printf ("url(%s)", uri);
repr->setAttribute ("mask", value);
g_free ((void *) value);
+ g_free ((void *) uri);
}
}
@@ -721,7 +725,7 @@ Geom::OptRect SPItem::visualBounds(Geom::Affine const &transform) const
// call the subclass method
// CPPIFY
//bbox = this->bbox(Geom::identity(), SPItem::VISUAL_BBOX);
- bbox = const_cast<SPItem*>(this)->bbox(Geom::identity(), SPItem::VISUAL_BBOX);
+ bbox = const_cast<SPItem*>(this)->bbox(Geom::identity(), SPItem::GEOMETRIC_BBOX); // see LP Bug 1229971
SPFilter *filter = SP_FILTER(style->getFilter());
// default filer area per the SVG spec:
@@ -1061,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-object.h b/src/sp-object.h
index 4e9a6c938..bcaa1dac7 100644
--- a/src/sp-object.h
+++ b/src/sp-object.h
@@ -106,7 +106,9 @@ enum {
class SPDocument;
/// Internal class consisting of two bits.
-struct SPIXmlSpace {
+class SPIXmlSpace {
+public:
+ SPIXmlSpace(): set(0), value(SP_XML_SPACE_DEFAULT) {};
guint set : 1;
guint value : 1;
};
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 72a5996d1..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 ) )
@@ -318,7 +318,12 @@ Inkscape::DrawingItem* SPText::show(Inkscape::Drawing &drawing, unsigned key, un
void SPText::hide(unsigned int key) {
-// SPItem::onHide(key);
+ for (SPItemView* v = this->display; v != NULL; v = v->next) {
+ if (v->key == key) {
+ Inkscape::DrawingGroup *g = dynamic_cast<Inkscape::DrawingGroup *>(v->arenaitem);
+ this->_clearFlow(g);
+ }
+ }
}
const char* SPText::displayName() {
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/style.cpp b/src/style.cpp
index 2807a7d9a..bea56e7b1 100644
--- a/src/style.cpp
+++ b/src/style.cpp
@@ -593,10 +593,18 @@ sp_style_unref(SPStyle *style)
sp_style_filter_clear(style);
g_free(style->stroke_dash.dash);
+
+ for (unsigned i = SP_MARKER_LOC; i < SP_MARKER_LOC_QTY; i++) {
+ if (style->marker[i].value) {
+ g_free(style->marker[i].value);
+ style->marker[i].value = NULL;
+ }
+ }
+
g_free(style);
+ return NULL;
}
-
- return NULL;
+ return style;
}
/**
@@ -4447,6 +4455,7 @@ sp_style_write_ipaint(gchar *b, gint const len, gchar const *const key,
if ( paint->value.href && paint->value.href->getURI() ) {
const gchar* uri = paint->value.href->getURI()->toString();
css << "url(" << uri << ")";
+ g_free((void *)uri);
}
if ( paint->noneSet ) {
@@ -4631,7 +4640,10 @@ sp_style_write_ifilter(gchar *p, gint const len, gchar const *key,
if (val->inherit) {
return g_snprintf(p, len, "%s:inherit;", key);
} else if (val->href && val->href->getURI()) {
- return g_snprintf(p, len, "%s:url(%s);", key, val->href->getURI()->toString());
+ gchar *uri = val->href->getURI()->toString();
+ gint ret = g_snprintf(p, len, "%s:url(%s);", key, uri);
+ g_free(uri);
+ return ret;
}
}
diff --git a/src/svg/svg-length.cpp b/src/svg/svg-length.cpp
index bb6cc5428..8d26a95d2 100644
--- a/src/svg/svg-length.cpp
+++ b/src/svg/svg-length.cpp
@@ -171,6 +171,14 @@ unsigned int sp_svg_number_write_de(gchar *buf, int bufLen, double val, unsigned
}
}
+SVGLength::SVGLength()
+ : _set(false)
+ , unit(NONE)
+ , value(0)
+ , computed(0)
+{
+}
+
/* Length */
bool SVGLength::read(gchar const *str)
diff --git a/src/svg/svg-length.h b/src/svg/svg-length.h
index 3832a4eb5..477b3ef81 100644
--- a/src/svg/svg-length.h
+++ b/src/svg/svg-length.h
@@ -21,6 +21,7 @@
class SVGLength
{
public:
+ SVGLength();
enum Unit {
NONE,
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 fd160e518..a3c0f2daa 100644
--- a/src/tools-switch.cpp
+++ b/src/tools-switch.cpp
@@ -86,6 +86,31 @@ static char const *const tool_names[] = {
"/tools/lpetool",
NULL
};
+static char const *const tool_msg[] = {
+ NULL,
+ 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
tools_prefpath2num(char const *id)
@@ -123,140 +148,11 @@ tools_switch(SPDesktop *dt, int num)
}
dt->set_event_context2(tool_names[num]);
-
- switch (num) {
- case TOOLS_SELECT:
- //dt->set_event_context(SP_TYPE_SELECT_CONTEXT, tool_names[num]);
- /* fixme: This is really ugly hack. We should bind and unbind class methods */
- dt->activate_guides(true);
- inkscape_eventcontext_set(dt->getEventContext());
- break;
- case TOOLS_NODES:
- //dt->set_event_context(INK_TYPE_NODE_TOOL, tool_names[num]);
- dt->activate_guides(true);
- inkscape_eventcontext_set(dt->getEventContext());
- break;
- case TOOLS_TWEAK:
- //dt->set_event_context(SP_TYPE_TWEAK_CONTEXT, tool_names[num]);
- dt->activate_guides(true);
- inkscape_eventcontext_set(dt->getEventContext());
- dt->tipsMessageContext()->set(Inkscape::NORMAL_MESSAGE, _("To tweak a path by pushing, select it and drag over it."));
- break;
- case TOOLS_SPRAY:
- //dt->set_event_context(SP_TYPE_SPRAY_CONTEXT, tool_names[num]);
- dt->activate_guides(true);
- inkscape_eventcontext_set(dt->getEventContext());
- dt->tipsMessageContext()->set(Inkscape::NORMAL_MESSAGE, _("<b>Drag</b>, <b>click</b> or <b>click and scroll</b> to spray the selected objects."));
- break;
- case TOOLS_SHAPES_RECT:
- //dt->set_event_context(SP_TYPE_RECT_CONTEXT, tool_names[num]);
- dt->activate_guides(false);
- inkscape_eventcontext_set(dt->getEventContext());
- dt->tipsMessageContext()->set(Inkscape::NORMAL_MESSAGE, _("<b>Drag</b> to create a rectangle. <b>Drag controls</b> to round corners and resize. <b>Click</b> to select."));
- break;
- case TOOLS_SHAPES_3DBOX:
- //dt->set_event_context(SP_TYPE_BOX3D_CONTEXT, tool_names[num]);
- dt->activate_guides(false);
- inkscape_eventcontext_set(dt->getEventContext());
- dt->tipsMessageContext()->set(Inkscape::NORMAL_MESSAGE, _("<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)."));
- break;
- case TOOLS_SHAPES_ARC:
- //dt->set_event_context(SP_TYPE_ARC_CONTEXT, tool_names[num]);
- dt->activate_guides(false);
- inkscape_eventcontext_set(dt->getEventContext());
- dt->tipsMessageContext()->set(Inkscape::NORMAL_MESSAGE, _("<b>Drag</b> to create an ellipse. <b>Drag controls</b> to make an arc or segment. <b>Click</b> to select."));
- break;
- case TOOLS_SHAPES_STAR:
- //dt->set_event_context(SP_TYPE_STAR_CONTEXT, tool_names[num]);
- dt->activate_guides(false);
- inkscape_eventcontext_set(dt->getEventContext());
- dt->tipsMessageContext()->set(Inkscape::NORMAL_MESSAGE, _("<b>Drag</b> to create a star. <b>Drag controls</b> to edit the star shape. <b>Click</b> to select."));
- break;
- case TOOLS_SHAPES_SPIRAL:
- //dt->set_event_context(SP_TYPE_SPIRAL_CONTEXT, tool_names[num]);
- dt->activate_guides(false);
- inkscape_eventcontext_set(dt->getEventContext());
- dt->tipsMessageContext()->set(Inkscape::NORMAL_MESSAGE, _("<b>Drag</b> to create a spiral. <b>Drag controls</b> to edit the spiral shape. <b>Click</b> to select."));
- break;
- case TOOLS_FREEHAND_PENCIL:
- //dt->set_event_context(SP_TYPE_PENCIL_CONTEXT, tool_names[num]);
- dt->activate_guides(false);
- inkscape_eventcontext_set(dt->getEventContext());
- dt->tipsMessageContext()->set(Inkscape::NORMAL_MESSAGE, _("<b>Drag</b> to create a freehand line. <b>Shift</b> appends to selected path, <b>Alt</b> activates sketch mode."));
- break;
- case TOOLS_FREEHAND_PEN:
- //dt->set_event_context(SP_TYPE_PEN_CONTEXT, tool_names[num]);
- dt->activate_guides(false);
- inkscape_eventcontext_set(dt->getEventContext());
- dt->tipsMessageContext()->set(Inkscape::NORMAL_MESSAGE, _("<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)."));
- break;
- case TOOLS_CALLIGRAPHIC:
- //dt->set_event_context(SP_TYPE_DYNA_DRAW_CONTEXT, tool_names[num]);
- dt->activate_guides(false);
- inkscape_eventcontext_set(dt->getEventContext());
- dt->tipsMessageContext()->set(Inkscape::NORMAL_MESSAGE, _("<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)."));
- break;
- case TOOLS_TEXT:
- //dt->set_event_context(SP_TYPE_TEXT_CONTEXT, tool_names[num]);
- dt->activate_guides(false);
- inkscape_eventcontext_set(dt->getEventContext());
- dt->tipsMessageContext()->set(Inkscape::NORMAL_MESSAGE, _("<b>Click</b> to select or create text, <b>drag</b> to create flowed text; then type."));
- break;
- case TOOLS_GRADIENT:
- //dt->set_event_context(SP_TYPE_GRADIENT_CONTEXT, tool_names[num]);
- dt->activate_guides(false);
- inkscape_eventcontext_set(dt->getEventContext());
- dt->tipsMessageContext()->set(Inkscape::NORMAL_MESSAGE, _("<b>Drag</b> or <b>double click</b> to create a gradient on selected objects, <b>drag handles</b> to adjust gradients."));
- break;
- case TOOLS_MESH:
- //dt->set_event_context(SP_TYPE_MESH_CONTEXT, tool_names[num]);
- dt->activate_guides(false);
- inkscape_eventcontext_set(dt->getEventContext());
- dt->tipsMessageContext()->set(Inkscape::NORMAL_MESSAGE, _("<b>Drag</b> or <b>double click</b> to create a mesh on selected objects, <b>drag handles</b> to adjust meshes."));
- break;
- case TOOLS_ZOOM:
- //dt->set_event_context(SP_TYPE_ZOOM_CONTEXT, tool_names[num]);
- dt->activate_guides(false);
- inkscape_eventcontext_set(dt->getEventContext());
- dt->tipsMessageContext()->set(Inkscape::NORMAL_MESSAGE, _("<b>Click</b> or <b>drag around an area</b> to zoom in, <b>Shift+click</b> to zoom out."));
- break;
- case TOOLS_MEASURE:
- //dt->set_event_context(SP_TYPE_MEASURE_CONTEXT, tool_names[num]);
- dt->activate_guides(false);
- inkscape_eventcontext_set(dt->getEventContext());
- dt->tipsMessageContext()->set(Inkscape::NORMAL_MESSAGE, _("<b>Drag</b> to measure the dimensions of objects."));
- break;
- case TOOLS_DROPPER:
- //dt->set_event_context(SP_TYPE_DROPPER_CONTEXT, tool_names[num]);
- dt->activate_guides(false);
- inkscape_eventcontext_set(dt->getEventContext());
- dt->tipsMessageContext()->set(Inkscape::NORMAL_MESSAGE, _("<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"));
- break;
- case TOOLS_CONNECTOR:
- //dt->set_event_context(SP_TYPE_CONNECTOR_CONTEXT, tool_names[num]);
- dt->activate_guides(false);
- inkscape_eventcontext_set(dt->getEventContext());
- dt->tipsMessageContext()->set(Inkscape::NORMAL_MESSAGE, _("<b>Click and drag</b> between shapes to create a connector."));
- break;
- case TOOLS_PAINTBUCKET:
- //dt->set_event_context(SP_TYPE_FLOOD_CONTEXT, tool_names[num]);
- dt->activate_guides(false);
- inkscape_eventcontext_set(dt->getEventContext());
- dt->tipsMessageContext()->set(Inkscape::NORMAL_MESSAGE, _("<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."));
- break;
- case TOOLS_ERASER:
- //dt->set_event_context(SP_TYPE_ERASER_CONTEXT, tool_names[num]);
- dt->activate_guides(false);
- inkscape_eventcontext_set(dt->getEventContext());
- dt->tipsMessageContext()->set(Inkscape::NORMAL_MESSAGE, _("<b>Drag</b> to erase."));
- break;
- case TOOLS_LPETOOL:
- //dt->set_event_context(SP_TYPE_LPETOOL_CONTEXT, tool_names[num]);
- dt->activate_guides(false);
- inkscape_eventcontext_set(dt->getEventContext());
- dt->tipsMessageContext()->set(Inkscape::NORMAL_MESSAGE, _("Choose a subtool from the toolbar"));
- break;
- }
+ /* fixme: This is really ugly hack. We should bind and unbind class methods */
+ /* 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, 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/dialog/svg-fonts-dialog.cpp b/src/ui/dialog/svg-fonts-dialog.cpp
index ab5f4c0e9..56ecfdecc 100644
--- a/src/ui/dialog/svg-fonts-dialog.cpp
+++ b/src/ui/dialog/svg-fonts-dialog.cpp
@@ -541,7 +541,9 @@ void SvgFontsDialog::set_glyph_description_from_selected_path(){
Geom::PathVector pathv = sp_svg_read_pathv(node->attribute("d"));
//XML Tree being directly used here while it shouldn't be.
- glyph->getRepr()->setAttribute("d", (char*) sp_svg_write_path (flip_coordinate_system(pathv)));
+ gchar *str = sp_svg_write_path (flip_coordinate_system(pathv));
+ glyph->getRepr()->setAttribute("d", str);
+ g_free(str);
DocumentUndo::done(doc, SP_VERB_DIALOG_SVG_FONTS, _("Set glyph curves"));
update_glyphs();
@@ -578,7 +580,9 @@ void SvgFontsDialog::missing_glyph_description_from_selected_path(){
if (SP_IS_MISSING_GLYPH(obj)){
//XML Tree being directly used here while it shouldn't be.
- obj->getRepr()->setAttribute("d", (char*) sp_svg_write_path (flip_coordinate_system(pathv)));
+ gchar *str = sp_svg_write_path (flip_coordinate_system(pathv));
+ obj->getRepr()->setAttribute("d", str);
+ g_free(str);
DocumentUndo::done(doc, SP_VERB_DIALOG_SVG_FONTS, _("Set glyph curves"));
}
}
diff --git a/src/ui/tool/path-manipulator.cpp b/src/ui/tool/path-manipulator.cpp
index 6e14e8e97..b775c0637 100644
--- a/src/ui/tool/path-manipulator.cpp
+++ b/src/ui/tool/path-manipulator.cpp
@@ -459,7 +459,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;
@@ -489,14 +492,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/verbs.cpp b/src/verbs.cpp
index 23a560423..bdef0526a 100644
--- a/src/verbs.cpp
+++ b/src/verbs.cpp
@@ -2119,6 +2119,9 @@ void TutorialVerb::perform(SPAction *action, void *data)
// TRANSLATORS: See "tutorial-basic.svg" comment.
sp_help_open_tutorial(NULL, (gpointer)_("tutorial-tracing.svg"));
break;
+ case SP_VERB_TUTORIAL_TRACING_PIXELART:
+ sp_help_open_tutorial(NULL, (gpointer)_("tutorial-tracing-pixelart.svg"));
+ break;
case SP_VERB_TUTORIAL_CALLIGRAPHY:
// TRANSLATORS: See "tutorial-basic.svg" comment.
sp_help_open_tutorial(NULL, (gpointer)_("tutorial-calligraphy.svg"));
@@ -2883,6 +2886,8 @@ Verb *Verb::_base_verbs[] = {
// TRANSLATORS: "to trace" means "to convert a bitmap to vector graphics" (to vectorize)
new TutorialVerb(SP_VERB_TUTORIAL_TRACING, "TutorialsTracing", N_("Inkscape: T_racing"),
N_("Using bitmap tracing"), NULL/*"tutorial_tracing"*/),
+ new TutorialVerb(SP_VERB_TUTORIAL_TRACING_PIXELART, "TutorialsTracingPixelArt", N_("Inkscape: Tracing Pixel Art"),
+ N_("Using Trace Pixel Art dialog"), NULL),
new TutorialVerb(SP_VERB_TUTORIAL_CALLIGRAPHY, "TutorialsCalligraphy", N_("Inkscape: _Calligraphy"),
N_("Using the Calligraphy pen tool"), NULL),
new TutorialVerb(SP_VERB_TUTORIAL_INTERPOLATE, "TutorialsInterpolate", N_("Inkscape: _Interpolate"),
diff --git a/src/verbs.h b/src/verbs.h
index 40292745a..0f764eb29 100644
--- a/src/verbs.h
+++ b/src/verbs.h
@@ -304,6 +304,7 @@ enum {
SP_VERB_TUTORIAL_SHAPES,
SP_VERB_TUTORIAL_ADVANCED,
SP_VERB_TUTORIAL_TRACING,
+ SP_VERB_TUTORIAL_TRACING_PIXELART,
SP_VERB_TUTORIAL_CALLIGRAPHY,
SP_VERB_TUTORIAL_INTERPOLATE,
SP_VERB_TUTORIAL_DESIGN,
diff --git a/src/widgets/arc-toolbar.cpp b/src/widgets/arc-toolbar.cpp
index 42f696bec..c31c61e32 100644
--- a/src/widgets/arc-toolbar.cpp
+++ b/src/widgets/arc-toolbar.cpp
@@ -123,7 +123,7 @@ sp_arctb_startend_value_changed(GtkAdjustment *adj, GObject *tbl, gchar const *v
ge->end = (gtk_adjustment_get_value(adj) * M_PI)/ 180;
}
- sp_genericellipse_normalize(ge);
+ ge->normalize();
(SP_OBJECT(arc))->updateRepr();
(SP_OBJECT(arc))->requestDisplayUpdate(SP_OBJECT_MODIFIED_FLAG);
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;
}