summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorAlvin Penner <penner@vaxxine.com>2015-05-18 15:03:15 +0000
committerapenner <penner@vaxxine.com>2015-05-18 15:03:15 +0000
commitb59c753a013f60192a6d4528fbd4b011d69b313f (patch)
tree266c7453772718d2e414a25e7232bf6ffbe97ee3 /src
parentMerge in Tomasz's fill-n-stroke-cppify branch (diff)
downloadinkscape-b59c753a013f60192a6d4528fbd4b011d69b313f.tar.gz
inkscape-b59c753a013f60192a6d4528fbd4b011d69b313f.zip
sbasis-to-bezier. avoid ill-conditioned behavior for anti-symmetric case. (Bug 1428267)
Fixed bugs: - https://launchpad.net/bugs/1428267 (bzr r14161)
Diffstat (limited to 'src')
-rw-r--r--src/2geom/sbasis-to-bezier.cpp6
1 files changed, 6 insertions, 0 deletions
diff --git a/src/2geom/sbasis-to-bezier.cpp b/src/2geom/sbasis-to-bezier.cpp
index a2e4253d2..98c400197 100644
--- a/src/2geom/sbasis-to-bezier.cpp
+++ b/src/2geom/sbasis-to-bezier.cpp
@@ -245,6 +245,8 @@ void sbasis_to_cubic_bezier (std::vector<Point> & bz, D2<SBasis> const& sb)
midx = 8*midx - 4*bz[0][X] - 4*bz[3][X]; // re-define relative to center
midy = 8*midy - 4*bz[0][Y] - 4*bz[3][Y];
+ if ((std::abs(midx) < EPSILON) && (std::abs(midy) < EPSILON))
+ return;
if ((std::abs(xprime[0]) < EPSILON) && (std::abs(yprime[0]) < EPSILON)
&& ((std::abs(xprime[1]) > EPSILON) || (std::abs(yprime[1]) > EPSILON))) { // degenerate handle at 0 : use distance of closest approach
@@ -264,6 +266,10 @@ void sbasis_to_cubic_bezier (std::vector<Point> & bz, D2<SBasis> const& sb)
dely[1] = 0;
} else if (std::abs(xprime[1]*yprime[0] - yprime[1]*xprime[0]) > // general case : fit mid fxn value
0.002 * std::abs(xprime[1]*xprime[0] + yprime[1]*yprime[0])) { // approx. 0.1 degree of angle
+ double test1 = (bz[1][Y] - bz[0][Y])*(bz[3][X] - bz[0][X]) - (bz[1][X] - bz[0][X])*(bz[3][Y] - bz[0][Y]);
+ double test2 = (bz[2][Y] - bz[0][Y])*(bz[3][X] - bz[0][X]) - (bz[2][X] - bz[0][X])*(bz[3][Y] - bz[0][Y]);
+ if (test1*test2 < 0) // reject anti-symmetric case, LP Bug 1428267 & Bug 1428683
+ return;
denom = xprime[1]*yprime[0] - yprime[1]*xprime[0];
for (int i = 0; i < 2; ++i) {
numer = xprime[1 - i]*midy - yprime[1 - i]*midx;