Merge lp:~ado-papas/inkscape/bug_167419 into lp:~inkscape.dev/inkscape/trunk

Proposed by Adonis Papaderos
Status: Merged
Approved by: jazzynico
Approved revision: 10088
Merged at revision: 10109
Proposed branch: lp:~ado-papas/inkscape/bug_167419
Merge into: lp:~inkscape.dev/inkscape/trunk
Diff against target: 162 lines (+50/-23)
3 files modified
src/selection-chemistry.cpp (+16/-3)
src/sp-offset.cpp (+32/-15)
src/splivarot.cpp (+2/-5)
To merge this branch: bzr merge lp:~ado-papas/inkscape/bug_167419
Reviewer Review Type Date Requested Status
jazzynico (community) Approve
su_v Pending
Adonis Papaderos Pending
Review via email: mp+52899@code.launchpad.net

This proposal supersedes a proposal from 2010-12-02.

Description of the change

Fix some issues with linked offsets. Changed the rendering of the offset to take into account the transformation of the source object, as is the case with the use element, and copied the move compensation logic from uses to offsets. There is a speed penalty though because of this, since I cannot find a reliable method to predict whether there is a change to the source object data or a transformation applied to it.

The second patch removes an optimization I implemented using the transform event, since this event is not emitted on undo and redo actions.

To post a comment you must log in.
Revision history for this message
Adonis Papaderos (ado-papas) wrote : Posted in a previous version of this proposal

Forced recalculation of shape after transform event.
Removed usage of the SP_OBJECT_REPR macro.

review: Needs Resubmitting
Revision history for this message
su_v (suv-lp) wrote : Posted in a previous version of this proposal
review: Approve
Revision history for this message
su_v (suv-lp) wrote : Posted in a previous version of this proposal

The diff from this branch fails to apply to current trunk r9951 (after the GSoC C++-ificiation merge and cleanup in r9946).

I do not know if (and how) the changes (r9945..r9951) affect the proposed code itself or if 'patch' just can't determine the correct position of the changed lines within the modified files.

review: Needs Fixing
Revision history for this message
Alexandre Prokoudine (alexandre-prokoudine) wrote : Posted in a previous version of this proposal

Adonis, do you think you could find some time to update your patch? It would be most appreciated. I'm using linked offsets all the time and some bugs really drive me nuts :)

Revision history for this message
jazzynico (jazzynico) wrote :

The current diff (updated 2011-03-10) now applies correctly to the trunk.

Revision history for this message
jazzynico (jazzynico) wrote :

Last diff tested successfully on the trunk. All linked bugs seem to be fixed.

review: Approve

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
=== modified file 'src/selection-chemistry.cpp'
--- src/selection-chemistry.cpp 2011-02-21 07:59:34 +0000
+++ src/selection-chemistry.cpp 2011-03-10 18:26:15 +0000
@@ -1379,7 +1379,7 @@
1379 * Same for textpath if we are also doing ANY transform to its path: do not touch textpath,1379 * Same for textpath if we are also doing ANY transform to its path: do not touch textpath,
1380 * letters cannot be squeezed or rotated anyway, they only refill the changed path.1380 * letters cannot be squeezed or rotated anyway, they only refill the changed path.
1381 * Same for linked offset if we are also moving its source: do not move it. */1381 * Same for linked offset if we are also moving its source: do not move it. */
1382 if (transform_textpath_with_path || transform_offset_with_source) {1382 if (transform_textpath_with_path) {
1383 // Restore item->transform field from the repr, in case it was changed by seltrans.1383 // Restore item->transform field from the repr, in case it was changed by seltrans.
1384 item->readAttr( "transform" );1384 item->readAttr( "transform" );
1385 } else if (transform_flowtext_with_frame) {1385 } else if (transform_flowtext_with_frame) {
@@ -1394,7 +1394,7 @@
1394 }1394 }
1395 }1395 }
1396 }1396 }
1397 } else if (transform_clone_with_original) {1397 } else if (transform_clone_with_original || transform_offset_with_source) {
1398 // We are transforming a clone along with its original. The below matrix juggling is1398 // We are transforming a clone along with its original. The below matrix juggling is
1399 // necessary to ensure that they transform as a whole, i.e. the clone's induced1399 // necessary to ensure that they transform as a whole, i.e. the clone's induced
1400 // transform and its move compensation are both cancelled out.1400 // transform and its move compensation are both cancelled out.
@@ -1408,7 +1408,7 @@
1408 Geom::Affine t_inv = t.inverse();1408 Geom::Affine t_inv = t.inverse();
1409 Geom::Affine result = t_inv * item->transform * t;1409 Geom::Affine result = t_inv * item->transform * t;
14101410
1411 if ((prefs_parallel || prefs_unmoved) && affine.isTranslation()) {1411 if (transform_clone_with_original && (prefs_parallel || prefs_unmoved) && affine.isTranslation()) {
1412 // we need to cancel out the move compensation, too1412 // we need to cancel out the move compensation, too
14131413
1414 // find out the clone move, same as in sp_use_move_compensate1414 // find out the clone move, same as in sp_use_move_compensate
@@ -1426,6 +1426,19 @@
1426 item->doWriteTransform(item->getRepr(), move, &t, compensate);1426 item->doWriteTransform(item->getRepr(), move, &t, compensate);
1427 }1427 }
14281428
1429 } else if (transform_offset_with_source && (prefs_parallel || prefs_unmoved) && affine.isTranslation()){
1430 Geom::Affine parent = item->transform;
1431 Geom::Affine offset_move = parent.inverse() * t * parent;
1432
1433 if (prefs_parallel) {
1434 Geom::Affine move = result * offset_move * t_inv;
1435 item->doWriteTransform(item->getRepr(), move, &move, compensate);
1436
1437 } else if (prefs_unmoved) {
1438 Geom::Affine move = result * offset_move;
1439 item->doWriteTransform(item->getRepr(), move, &t, compensate);
1440 }
1441
1429 } else {1442 } else {
1430 // just apply the result1443 // just apply the result
1431 item->doWriteTransform(item->getRepr(), result, &t, compensate);1444 item->doWriteTransform(item->getRepr(), result, &t, compensate);
14321445
=== modified file 'src/sp-offset.cpp'
--- src/sp-offset.cpp 2011-02-22 09:17:44 +0000
+++ src/sp-offset.cpp 2011-03-10 18:26:15 +0000
@@ -1029,30 +1029,37 @@
1029{1029{
1030 Inkscape::Preferences *prefs = Inkscape::Preferences::get();1030 Inkscape::Preferences *prefs = Inkscape::Preferences::get();
1031 guint mode = prefs->getInt("/options/clonecompensation/value", SP_CLONE_COMPENSATION_PARALLEL);1031 guint mode = prefs->getInt("/options/clonecompensation/value", SP_CLONE_COMPENSATION_PARALLEL);
1032 if (mode == SP_CLONE_COMPENSATION_NONE) return;1032
1033 SPItem *item = SP_ITEM(self);
10331034
1034 Geom::Affine m(*mp);1035 Geom::Affine m(*mp);
1035 if (!(m.isTranslation())) return;1036 if (!(m.isTranslation()) || mode == SP_CLONE_COMPENSATION_NONE) {
1037 self->sourceDirty=true;
1038 item->requestDisplayUpdate(SP_OBJECT_MODIFIED_FLAG);
1039 return;
1040 }
10361041
1037 // calculate the compensation matrix and the advertized movement matrix1042 // calculate the compensation matrix and the advertized movement matrix
1038 SPItem *item = SP_ITEM(self);1043 item->readAttr("transform");
10391044
1040 Geom::Affine compensate;1045 Geom::Affine t = self->transform;
1046 Geom::Affine offset_move = t.inverse() * m * t;
1047
1041 Geom::Affine advertized_move;1048 Geom::Affine advertized_move;
10421049 if (mode == SP_CLONE_COMPENSATION_PARALLEL) {
1043 if (mode == SP_CLONE_COMPENSATION_UNMOVED) {1050 offset_move = offset_move.inverse() * m;
1044 compensate = Geom::identity();1051 advertized_move = m;
1052 } else if (mode == SP_CLONE_COMPENSATION_UNMOVED) {
1053 offset_move = offset_move.inverse();
1045 advertized_move.setIdentity();1054 advertized_move.setIdentity();
1046 } else if (mode == SP_CLONE_COMPENSATION_PARALLEL) {
1047 compensate = m;
1048 advertized_move = m;
1049 } else {1055 } else {
1050 g_assert_not_reached();1056 g_assert_not_reached();
1051 }1057 }
10521058
1053 item->transform *= compensate;1059 self->sourceDirty=true;
10541060
1055 // commit the compensation1061 // commit the compensation
1062 item->transform *= offset_move;
1056 item->doWriteTransform(item->getRepr(), item->transform, &advertized_move);1063 item->doWriteTransform(item->getRepr(), item->transform, &advertized_move);
1057 item->requestDisplayUpdate(SP_OBJECT_MODIFIED_FLAG);1064 item->requestDisplayUpdate(SP_OBJECT_MODIFIED_FLAG);
1058}1065}
@@ -1075,12 +1082,13 @@
1075}1082}
10761083
1077static void1084static void
1078sp_offset_source_modified (SPObject */*iSource*/, guint /*flags*/, SPItem *item)1085sp_offset_source_modified (SPObject */*iSource*/, guint flags, SPItem *item)
1079{1086{
1080 SPOffset *offset = SP_OFFSET(item);1087 SPOffset *offset = SP_OFFSET(item);
1081 offset->sourceDirty=true;1088 offset->sourceDirty=true;
1082 refresh_offset_source(offset);1089 if (flags & (SP_OBJECT_MODIFIED_FLAG | SP_OBJECT_CHILD_MODIFIED_FLAG)) {
1083 ((SPShape *) offset)->setShape ();1090 offset->requestDisplayUpdate(SP_OBJECT_MODIFIED_FLAG);
1091 }
1084}1092}
10851093
1086static void1094static void
@@ -1111,6 +1119,15 @@
1111 orig->LoadPathVector(curve->get_pathvector());1119 orig->LoadPathVector(curve->get_pathvector());
1112 curve->unref();1120 curve->unref();
11131121
1122 if (!item->transform.isIdentity()) {
1123 gchar const *t_attr = item->getRepr()->attribute("transform");
1124 if (t_attr) {
1125 Geom::Affine t;
1126 if (sp_svg_transform_read(t_attr, &t)) {
1127 orig->Transform(t);
1128 }
1129 }
1130 }
11141131
1115 // Finish up.1132 // Finish up.
1116 {1133 {
11171134
=== modified file 'src/splivarot.cpp'
--- src/splivarot.cpp 2011-02-22 00:01:57 +0000
+++ src/splivarot.cpp 2011-03-10 18:26:15 +0000
@@ -1468,6 +1468,7 @@
1468 if ( updating ) {1468 if ( updating ) {
14691469
1470 //XML Tree being used directly here while it shouldn't be1470 //XML Tree being used directly here while it shouldn't be
1471 item->doWriteTransform(item->getRepr(), transform);
1471 char const *id = item->getRepr()->attribute("id");1472 char const *id = item->getRepr()->attribute("id");
1472 char const *uri = g_strdup_printf("#%s", id);1473 char const *uri = g_strdup_printf("#%s", id);
1473 repr->setAttribute("xlink:href", uri);1474 repr->setAttribute("xlink:href", uri);
@@ -1486,11 +1487,7 @@
14861487
1487 SPItem *nitem = (SPItem *) sp_desktop_document(desktop)->getObjectByRepr(repr);1488 SPItem *nitem = (SPItem *) sp_desktop_document(desktop)->getObjectByRepr(repr);
14881489
1489 if ( updating ) {1490 if ( !updating ) {
1490 // on conserve l'original
1491 // we reapply the transform to the original (offset will feel it)
1492 item->doWriteTransform(item->getRepr(), transform);
1493 } else {
1494 // delete original, apply the transform to the offset1491 // delete original, apply the transform to the offset
1495 item->deleteObject(false);1492 item->deleteObject(false);
1496 nitem->doWriteTransform(repr, transform);1493 nitem->doWriteTransform(repr, transform);