summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/selection-chemistry.cpp19
-rw-r--r--src/sp-offset.cpp45
-rw-r--r--src/splivarot.cpp7
3 files changed, 49 insertions, 22 deletions
diff --git a/src/selection-chemistry.cpp b/src/selection-chemistry.cpp
index 082c447d0..67aba5218 100644
--- a/src/selection-chemistry.cpp
+++ b/src/selection-chemistry.cpp
@@ -1379,7 +1379,7 @@ void sp_selection_apply_affine(Inkscape::Selection *selection, Geom::Affine cons
* Same for textpath if we are also doing ANY transform to its path: do not touch textpath,
* letters cannot be squeezed or rotated anyway, they only refill the changed path.
* Same for linked offset if we are also moving its source: do not move it. */
- if (transform_textpath_with_path || transform_offset_with_source) {
+ if (transform_textpath_with_path) {
// Restore item->transform field from the repr, in case it was changed by seltrans.
item->readAttr( "transform" );
} else if (transform_flowtext_with_frame) {
@@ -1394,7 +1394,7 @@ void sp_selection_apply_affine(Inkscape::Selection *selection, Geom::Affine cons
}
}
}
- } else if (transform_clone_with_original) {
+ } else if (transform_clone_with_original || transform_offset_with_source) {
// We are transforming a clone along with its original. The below matrix juggling is
// necessary to ensure that they transform as a whole, i.e. the clone's induced
// transform and its move compensation are both cancelled out.
@@ -1408,7 +1408,7 @@ void sp_selection_apply_affine(Inkscape::Selection *selection, Geom::Affine cons
Geom::Affine t_inv = t.inverse();
Geom::Affine result = t_inv * item->transform * t;
- if ((prefs_parallel || prefs_unmoved) && affine.isTranslation()) {
+ if (transform_clone_with_original && (prefs_parallel || prefs_unmoved) && affine.isTranslation()) {
// we need to cancel out the move compensation, too
// find out the clone move, same as in sp_use_move_compensate
@@ -1426,6 +1426,19 @@ void sp_selection_apply_affine(Inkscape::Selection *selection, Geom::Affine cons
item->doWriteTransform(item->getRepr(), move, &t, compensate);
}
+ } else if (transform_offset_with_source && (prefs_parallel || prefs_unmoved) && affine.isTranslation()){
+ Geom::Affine parent = item->transform;
+ Geom::Affine offset_move = parent.inverse() * t * parent;
+
+ if (prefs_parallel) {
+ Geom::Affine move = result * offset_move * t_inv;
+ item->doWriteTransform(item->getRepr(), move, &move, compensate);
+
+ } else if (prefs_unmoved) {
+ Geom::Affine move = result * offset_move;
+ item->doWriteTransform(item->getRepr(), move, &t, compensate);
+ }
+
} else {
// just apply the result
item->doWriteTransform(item->getRepr(), result, &t, compensate);
diff --git a/src/sp-offset.cpp b/src/sp-offset.cpp
index 5cad7540d..57c04f31f 100644
--- a/src/sp-offset.cpp
+++ b/src/sp-offset.cpp
@@ -1029,30 +1029,37 @@ sp_offset_move_compensate(Geom::Affine const *mp, SPItem */*original*/, SPOffset
{
Inkscape::Preferences *prefs = Inkscape::Preferences::get();
guint mode = prefs->getInt("/options/clonecompensation/value", SP_CLONE_COMPENSATION_PARALLEL);
- if (mode == SP_CLONE_COMPENSATION_NONE) return;
+
+ SPItem *item = SP_ITEM(self);
Geom::Affine m(*mp);
- if (!(m.isTranslation())) return;
+ 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::Affine compensate;
- Geom::Affine 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->transform *= offset_move;
item->doWriteTransform(item->getRepr(), item->transform, &advertized_move);
item->requestDisplayUpdate(SP_OBJECT_MODIFIED_FLAG);
}
@@ -1075,12 +1082,13 @@ sp_offset_delete_self(SPObject */*deleted*/, SPOffset *offset)
}
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
@@ -1111,6 +1119,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.
{
diff --git a/src/splivarot.cpp b/src/splivarot.cpp
index c01296b0e..9c2fc8ff9 100644
--- a/src/splivarot.cpp
+++ b/src/splivarot.cpp
@@ -1487,6 +1487,7 @@ sp_selected_path_create_offset_object(SPDesktop *desktop, int expand, bool updat
if ( updating ) {
//XML Tree being used directly here while it shouldn't be
+ item->doWriteTransform(item->getRepr(), transform);
char const *id = item->getRepr()->attribute("id");
char const *uri = g_strdup_printf("#%s", id);
repr->setAttribute("xlink:href", uri);
@@ -1505,11 +1506,7 @@ sp_selected_path_create_offset_object(SPDesktop *desktop, int expand, bool updat
SPItem *nitem = (SPItem *) sp_desktop_document(desktop)->getObjectByRepr(repr);
- if ( updating ) {
- // on conserve l'original
- // we reapply the transform to the original (offset will feel it)
- item->doWriteTransform(item->getRepr(), transform);
- } else {
+ if ( !updating ) {
// delete original, apply the transform to the offset
item->deleteObject(false);
nitem->doWriteTransform(repr, transform);