Merge lp:~7-eric/inkscape/boolop-fix into lp:~inkscape.dev/inkscape/trunk

Proposed by Eric Greveson
Status: Merged
Merged at revision: 12475
Proposed branch: lp:~7-eric/inkscape/boolop-fix
Merge into: lp:~inkscape.dev/inkscape/trunk
Diff against target: 46 lines (+31/-5)
1 file modified
src/splivarot.cpp (+31/-5)
To merge this branch: bzr merge lp:~7-eric/inkscape/boolop-fix
Reviewer Review Type Date Requested Status
Alvin Penner Approve
su_v (community) Approve
Review via email: mp+179223@code.launchpad.net

Description of the change

Fix for Bug #1209281. "Difference" and "Intersection" Boolean operations should now behave in a reasonable way when one or more input shapes is small enough that the automatic quantization step (before the Boolean operation takes place) shrinks it to zero. "Union" and "Exclusion" operations behave as before (already correct).

To post a comment you must log in.
Revision history for this message
su_v (suv-lp) wrote :

I can't review the proposed code itself, but based on tests (r12472+diff on OS X 10.7.5) with files from related bug reports I approve: no regression or unexpected results encountered.

review: Approve
Revision history for this message
Alvin Penner (apenner) wrote :

looks good to me, thanks!

review: Approve

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
=== modified file 'src/splivarot.cpp'
--- src/splivarot.cpp 2013-07-04 14:01:44 +0000
+++ src/splivarot.cpp 2013-08-08 16:13:45 +0000
@@ -277,11 +277,37 @@
277277
278 theShapeB->ConvertToShape(theShape, origWind[curOrig]);278 theShapeB->ConvertToShape(theShape, origWind[curOrig]);
279279
280 if (theShapeA->numberOfEdges() == 0) {280 // Due to quantization of the input shape coordinates, we may end up with A or B being empty.
281 Shape *swap = theShapeB;281 // If this is a union or symdiff operation, we just use the non-empty shape as the result:
282 theShapeB = theShapeA;282 // A=0 => (0 or B) == B
283 theShapeA = swap;283 // B=0 => (A or 0) == A
284 } else if (theShapeB->numberOfEdges() > 0) {284 // A=0 => (0 xor B) == B
285 // B=0 => (A xor 0) == A
286 // If this is an intersection operation, we just use the empty shape as the result:
287 // A=0 => (0 and B) == 0 == A
288 // B=0 => (A and 0) == 0 == B
289 // If this a difference operation, and the upper shape (A) is empty, we keep B.
290 // If the lower shape (B) is empty, we still keep B, as it's empty:
291 // A=0 => (B - 0) == B
292 // B=0 => (0 - A) == 0 == B
293 //
294 // In any case, the output from this operation is stored in shape A, so we may apply
295 // the above rules simply by judicious use of swapping A and B where necessary.
296 bool zeroA = theShapeA->numberOfEdges() == 0;
297 bool zeroB = theShapeB->numberOfEdges() == 0;
298 if (zeroA || zeroB) {
299 // We might need to do a swap. Apply the above rules depending on operation type.
300 bool resultIsB = ((bop == bool_op_union || bop == bool_op_symdiff) && zeroA)
301 || ((bop == bool_op_inters) && zeroB)
302 || (bop == bool_op_diff);
303 if (resultIsB) {
304 // Swap A and B to use B as the result
305 Shape *swap = theShapeB;
306 theShapeB = theShapeA;
307 theShapeA = swap;
308 }
309 } else {
310 // Just do the Boolean operation as usual
285 // les elements arrivent en ordre inverse dans la liste311 // les elements arrivent en ordre inverse dans la liste
286 theShape->Booleen(theShapeB, theShapeA, bop);312 theShape->Booleen(theShapeB, theShapeA, bop);
287 Shape *swap = theShape;313 Shape *swap = theShape;