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
1=== modified file 'src/selection-chemistry.cpp'
2--- src/selection-chemistry.cpp 2011-02-21 07:59:34 +0000
3+++ src/selection-chemistry.cpp 2011-03-10 18:26:15 +0000
4@@ -1379,7 +1379,7 @@
5 * Same for textpath if we are also doing ANY transform to its path: do not touch textpath,
6 * letters cannot be squeezed or rotated anyway, they only refill the changed path.
7 * Same for linked offset if we are also moving its source: do not move it. */
8- if (transform_textpath_with_path || transform_offset_with_source) {
9+ if (transform_textpath_with_path) {
10 // Restore item->transform field from the repr, in case it was changed by seltrans.
11 item->readAttr( "transform" );
12 } else if (transform_flowtext_with_frame) {
13@@ -1394,7 +1394,7 @@
14 }
15 }
16 }
17- } else if (transform_clone_with_original) {
18+ } else if (transform_clone_with_original || transform_offset_with_source) {
19 // We are transforming a clone along with its original. The below matrix juggling is
20 // necessary to ensure that they transform as a whole, i.e. the clone's induced
21 // transform and its move compensation are both cancelled out.
22@@ -1408,7 +1408,7 @@
23 Geom::Affine t_inv = t.inverse();
24 Geom::Affine result = t_inv * item->transform * t;
25
26- if ((prefs_parallel || prefs_unmoved) && affine.isTranslation()) {
27+ if (transform_clone_with_original && (prefs_parallel || prefs_unmoved) && affine.isTranslation()) {
28 // we need to cancel out the move compensation, too
29
30 // find out the clone move, same as in sp_use_move_compensate
31@@ -1426,6 +1426,19 @@
32 item->doWriteTransform(item->getRepr(), move, &t, compensate);
33 }
34
35+ } else if (transform_offset_with_source && (prefs_parallel || prefs_unmoved) && affine.isTranslation()){
36+ Geom::Affine parent = item->transform;
37+ Geom::Affine offset_move = parent.inverse() * t * parent;
38+
39+ if (prefs_parallel) {
40+ Geom::Affine move = result * offset_move * t_inv;
41+ item->doWriteTransform(item->getRepr(), move, &move, compensate);
42+
43+ } else if (prefs_unmoved) {
44+ Geom::Affine move = result * offset_move;
45+ item->doWriteTransform(item->getRepr(), move, &t, compensate);
46+ }
47+
48 } else {
49 // just apply the result
50 item->doWriteTransform(item->getRepr(), result, &t, compensate);
51
52=== modified file 'src/sp-offset.cpp'
53--- src/sp-offset.cpp 2011-02-22 09:17:44 +0000
54+++ src/sp-offset.cpp 2011-03-10 18:26:15 +0000
55@@ -1029,30 +1029,37 @@
56 {
57 Inkscape::Preferences *prefs = Inkscape::Preferences::get();
58 guint mode = prefs->getInt("/options/clonecompensation/value", SP_CLONE_COMPENSATION_PARALLEL);
59- if (mode == SP_CLONE_COMPENSATION_NONE) return;
60+
61+ SPItem *item = SP_ITEM(self);
62
63 Geom::Affine m(*mp);
64- if (!(m.isTranslation())) return;
65+ if (!(m.isTranslation()) || mode == SP_CLONE_COMPENSATION_NONE) {
66+ self->sourceDirty=true;
67+ item->requestDisplayUpdate(SP_OBJECT_MODIFIED_FLAG);
68+ return;
69+ }
70
71 // calculate the compensation matrix and the advertized movement matrix
72- SPItem *item = SP_ITEM(self);
73-
74- Geom::Affine compensate;
75+ item->readAttr("transform");
76+
77+ Geom::Affine t = self->transform;
78+ Geom::Affine offset_move = t.inverse() * m * t;
79+
80 Geom::Affine advertized_move;
81-
82- if (mode == SP_CLONE_COMPENSATION_UNMOVED) {
83- compensate = Geom::identity();
84+ if (mode == SP_CLONE_COMPENSATION_PARALLEL) {
85+ offset_move = offset_move.inverse() * m;
86+ advertized_move = m;
87+ } else if (mode == SP_CLONE_COMPENSATION_UNMOVED) {
88+ offset_move = offset_move.inverse();
89 advertized_move.setIdentity();
90- } else if (mode == SP_CLONE_COMPENSATION_PARALLEL) {
91- compensate = m;
92- advertized_move = m;
93 } else {
94 g_assert_not_reached();
95 }
96
97- item->transform *= compensate;
98+ self->sourceDirty=true;
99
100 // commit the compensation
101+ item->transform *= offset_move;
102 item->doWriteTransform(item->getRepr(), item->transform, &advertized_move);
103 item->requestDisplayUpdate(SP_OBJECT_MODIFIED_FLAG);
104 }
105@@ -1075,12 +1082,13 @@
106 }
107
108 static void
109-sp_offset_source_modified (SPObject */*iSource*/, guint /*flags*/, SPItem *item)
110+sp_offset_source_modified (SPObject */*iSource*/, guint flags, SPItem *item)
111 {
112 SPOffset *offset = SP_OFFSET(item);
113 offset->sourceDirty=true;
114- refresh_offset_source(offset);
115- ((SPShape *) offset)->setShape ();
116+ if (flags & (SP_OBJECT_MODIFIED_FLAG | SP_OBJECT_CHILD_MODIFIED_FLAG)) {
117+ offset->requestDisplayUpdate(SP_OBJECT_MODIFIED_FLAG);
118+ }
119 }
120
121 static void
122@@ -1111,6 +1119,15 @@
123 orig->LoadPathVector(curve->get_pathvector());
124 curve->unref();
125
126+ if (!item->transform.isIdentity()) {
127+ gchar const *t_attr = item->getRepr()->attribute("transform");
128+ if (t_attr) {
129+ Geom::Affine t;
130+ if (sp_svg_transform_read(t_attr, &t)) {
131+ orig->Transform(t);
132+ }
133+ }
134+ }
135
136 // Finish up.
137 {
138
139=== modified file 'src/splivarot.cpp'
140--- src/splivarot.cpp 2011-02-22 00:01:57 +0000
141+++ src/splivarot.cpp 2011-03-10 18:26:15 +0000
142@@ -1468,6 +1468,7 @@
143 if ( updating ) {
144
145 //XML Tree being used directly here while it shouldn't be
146+ item->doWriteTransform(item->getRepr(), transform);
147 char const *id = item->getRepr()->attribute("id");
148 char const *uri = g_strdup_printf("#%s", id);
149 repr->setAttribute("xlink:href", uri);
150@@ -1486,11 +1487,7 @@
151
152 SPItem *nitem = (SPItem *) sp_desktop_document(desktop)->getObjectByRepr(repr);
153
154- if ( updating ) {
155- // on conserve l'original
156- // we reapply the transform to the original (offset will feel it)
157- item->doWriteTransform(item->getRepr(), transform);
158- } else {
159+ if ( !updating ) {
160 // delete original, apply the transform to the offset
161 item->deleteObject(false);
162 nitem->doWriteTransform(repr, transform);