summaryrefslogtreecommitdiffstats
path: root/src/sp-offset.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/sp-offset.cpp')
-rw-r--r--src/sp-offset.cpp79
1 files changed, 50 insertions, 29 deletions
diff --git a/src/sp-offset.cpp b/src/sp-offset.cpp
index 019942892..460421492 100644
--- a/src/sp-offset.cpp
+++ b/src/sp-offset.cpp
@@ -36,7 +36,7 @@
#include "sp-use-reference.h"
#include "uri.h"
-#include <2geom/matrix.h>
+#include <2geom/affine.h>
#include <2geom/pathvector.h>
#include "xml/repr.h"
@@ -90,7 +90,7 @@ static void refresh_offset_source(SPOffset* offset);
static void sp_offset_start_listening(SPOffset *offset,SPObject* to);
static void sp_offset_quit_listening(SPOffset *offset);
static void sp_offset_href_changed(SPObject *old_ref, SPObject *ref, SPOffset *offset);
-static void sp_offset_move_compensate(Geom::Matrix const *mp, SPItem *original, SPOffset *self);
+static void sp_offset_move_compensate(Geom::Affine const *mp, SPItem *original, SPOffset *self);
static void sp_offset_delete_self(SPObject *deleted, SPOffset *self);
static void sp_offset_source_modified (SPObject *iSource, guint flags, SPItem *item);
@@ -183,7 +183,7 @@ sp_offset_init(SPOffset *offset)
new (&offset->_changed_connection) sigc::connection();
new (&offset->_transformed_connection) sigc::connection();
// set up the uri reference
- offset->sourceRef = new SPUseReference(SP_OBJECT(offset));
+ offset->sourceRef = new SPUseReference(offset);
offset->_changed_connection = offset->sourceRef->changedSignal().connect(sigc::bind(sigc::ptr_fun(sp_offset_href_changed), offset));
}
@@ -457,12 +457,13 @@ sp_offset_set_shape(SPShape *shape)
// it's also useless to compute the offset with a 0 radius
//XML Tree being used directly here while it shouldn't be.
- const char *res_d = SP_OBJECT(shape)->getRepr()->attribute("inkscape:original");
+ const char *res_d = shape->getRepr()->attribute("inkscape:original");
if ( res_d ) {
Geom::PathVector pv = sp_svg_read_pathv(res_d);
SPCurve *c = new SPCurve(pv);
g_assert(c != NULL);
((SPShape *) offset)->setCurveInsync (c, TRUE);
+ ((SPShape *) offset)->setCurveBeforeLPE(c);
c->unref();
}
return;
@@ -712,6 +713,7 @@ sp_offset_set_shape(SPShape *shape)
SPCurve *c = new SPCurve(pv);
g_assert(c != NULL);
((SPShape *) offset)->setCurveInsync (c, TRUE);
+ ((SPShape *) offset)->setCurveBeforeLPE(c);
c->unref();
free (res_d);
@@ -987,15 +989,16 @@ sp_offset_top_point (SPOffset * offset, Geom::Point *px)
// the listening functions
static void sp_offset_start_listening(SPOffset *offset,SPObject* to)
{
- if ( to == NULL )
+ if ( to == NULL ) {
return;
+ }
offset->sourceObject = to;
- offset->sourceRepr = SP_OBJECT_REPR(to);
+ offset->sourceRepr = to->getRepr();
- offset->_delete_connection = SP_OBJECT(to)->connectDelete(sigc::bind(sigc::ptr_fun(&sp_offset_delete_self), offset));
+ offset->_delete_connection = to->connectDelete(sigc::bind(sigc::ptr_fun(&sp_offset_delete_self), offset));
offset->_transformed_connection = SP_ITEM(to)->connectTransformed(sigc::bind(sigc::ptr_fun(&sp_offset_move_compensate), offset));
- offset->_modified_connection = SP_OBJECT(to)->connectModified(sigc::bind<2>(sigc::ptr_fun(&sp_offset_source_modified), offset));
+ offset->_modified_connection = to->connectModified(sigc::bind<2>(sigc::ptr_fun(&sp_offset_source_modified), offset));
}
static void sp_offset_quit_listening(SPOffset *offset)
@@ -1019,41 +1022,48 @@ sp_offset_href_changed(SPObject */*old_ref*/, SPObject */*ref*/, SPOffset *offse
SPItem *refobj = offset->sourceRef->getObject();
if (refobj) sp_offset_start_listening(offset,refobj);
offset->sourceDirty=true;
- SP_OBJECT(offset)->requestDisplayUpdate(SP_OBJECT_MODIFIED_FLAG);
+ offset->requestDisplayUpdate(SP_OBJECT_MODIFIED_FLAG);
}
}
static void
-sp_offset_move_compensate(Geom::Matrix const *mp, SPItem */*original*/, SPOffset *self)
+sp_offset_move_compensate(Geom::Affine const *mp, SPItem */*original*/, SPOffset *self)
{
Inkscape::Preferences *prefs = Inkscape::Preferences::get();
guint mode = prefs->getInt("/options/clonecompensation/value", SP_CLONE_COMPENSATION_PARALLEL);
- if (mode == SP_CLONE_COMPENSATION_NONE) return;
- Geom::Matrix m(*mp);
- if (!(m.isTranslation())) return;
+ SPItem *item = SP_ITEM(self);
+
+ Geom::Affine m(*mp);
+ if (!(m.isTranslation()) || mode == SP_CLONE_COMPENSATION_NONE) {
+ self->sourceDirty=true;
+ item->requestDisplayUpdate(SP_OBJECT_MODIFIED_FLAG);
+ return;
+ }
// calculate the compensation matrix and the advertized movement matrix
- SPItem *item = SP_ITEM(self);
+ item->readAttr("transform");
- Geom::Matrix compensate;
- Geom::Matrix advertized_move;
+ Geom::Affine t = self->transform;
+ Geom::Affine offset_move = t.inverse() * m * t;
- if (mode == SP_CLONE_COMPENSATION_UNMOVED) {
- compensate = Geom::identity();
- advertized_move.setIdentity();
- } else if (mode == SP_CLONE_COMPENSATION_PARALLEL) {
- compensate = m;
+ Geom::Affine advertized_move;
+ if (mode == SP_CLONE_COMPENSATION_PARALLEL) {
+ offset_move = offset_move.inverse() * m;
advertized_move = m;
+ } else if (mode == SP_CLONE_COMPENSATION_UNMOVED) {
+ offset_move = offset_move.inverse();
+ advertized_move.setIdentity();
} else {
g_assert_not_reached();
}
- item->transform *= compensate;
+ self->sourceDirty=true;
// commit the compensation
- item->doWriteTransform(SP_OBJECT_REPR(item), item->transform, &advertized_move);
- SP_OBJECT(item)->requestDisplayUpdate(SP_OBJECT_MODIFIED_FLAG);
+ item->transform *= offset_move;
+ item->doWriteTransform(item->getRepr(), item->transform, &advertized_move);
+ item->requestDisplayUpdate(SP_OBJECT_MODIFIED_FLAG);
}
static void
@@ -1069,17 +1079,18 @@ sp_offset_delete_self(SPObject */*deleted*/, SPOffset *offset)
offset->sourceHref = NULL;
offset->sourceRef->detach();
} else if (mode == SP_CLONE_ORPHANS_DELETE) {
- SP_OBJECT(offset)->deleteObject();
+ offset->deleteObject();
}
}
static void
-sp_offset_source_modified (SPObject */*iSource*/, guint /*flags*/, SPItem *item)
+sp_offset_source_modified (SPObject */*iSource*/, guint flags, SPItem *item)
{
SPOffset *offset = SP_OFFSET(item);
offset->sourceDirty=true;
- refresh_offset_source(offset);
- ((SPShape *) offset)->setShape ();
+ if (flags & (SP_OBJECT_MODIFIED_FLAG | SP_OBJECT_CHILD_MODIFIED_FLAG)) {
+ offset->requestDisplayUpdate(SP_OBJECT_MODIFIED_FLAG);
+ }
}
static void
@@ -1110,6 +1121,15 @@ refresh_offset_source(SPOffset* offset)
orig->LoadPathVector(curve->get_pathvector());
curve->unref();
+ if (!item->transform.isIdentity()) {
+ gchar const *t_attr = item->getRepr()->attribute("transform");
+ if (t_attr) {
+ Geom::Affine t;
+ if (sp_svg_transform_read(t_attr, &t)) {
+ orig->Transform(t);
+ }
+ }
+ }
// Finish up.
{
@@ -1148,8 +1168,9 @@ refresh_offset_source(SPOffset* offset)
delete res;
delete orig;
+ // TODO fix:
//XML Tree being used diectly here while it shouldn't be.
- SP_OBJECT (offset)->getRepr()->setAttribute("inkscape:original", res_d);
+ offset->getRepr()->setAttribute("inkscape:original", res_d);
free (res_d);
}