Commit ab5c39d6 authored by Nicolas Dufour's avatar Nicolas Dufour Committed by Nicolas Dufour

Linked Offset. Merge branch lp:~ado-papas/inkscape/bug_167419 (Bug #167419,...

Linked Offset. Merge branch lp:~ado-papas/inkscape/bug_167419 (Bug #167419, Bug #184341, Bug #239430).

(bzr r10109)
parent fec61fd3
......@@ -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);
......
......@@ -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.
{
......
......@@ -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);
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment