| Index: src/pathops/SkPathOpsQuad.cpp
|
| diff --git a/src/pathops/SkPathOpsQuad.cpp b/src/pathops/SkPathOpsQuad.cpp
|
| index dafa3f5b7588cbebbcb64465fb527526d1efba5b..ab1ba05c5691646c010a2677c2a0b79c50da6174 100644
|
| --- a/src/pathops/SkPathOpsQuad.cpp
|
| +++ b/src/pathops/SkPathOpsQuad.cpp
|
| @@ -10,6 +10,28 @@
|
| #include "SkPathOpsCurve.h"
|
| #include "SkPathOpsQuad.h"
|
|
|
| +// from blackpawn.com/texts/pointinpoly
|
| +static bool pointInTriangle(const SkDPoint fPts[3], const SkDPoint& test) {
|
| + SkDVector v0 = fPts[2] - fPts[0];
|
| + SkDVector v1 = fPts[1] - fPts[0];
|
| + SkDVector v2 = test - fPts[0];
|
| + double dot00 = v0.dot(v0);
|
| + double dot01 = v0.dot(v1);
|
| + double dot02 = v0.dot(v2);
|
| + double dot11 = v1.dot(v1);
|
| + double dot12 = v1.dot(v2);
|
| + // Compute barycentric coordinates
|
| + double invDenom = 1 / (dot00 * dot11 - dot01 * dot01);
|
| + double u = (dot11 * dot02 - dot01 * dot12) * invDenom;
|
| + double v = (dot00 * dot12 - dot01 * dot02) * invDenom;
|
| + // Check if point is in triangle
|
| + return u >= 0 && v >= 0 && u + v < 1;
|
| +}
|
| +
|
| +static bool matchesEnd(const SkDPoint fPts[3], const SkDPoint& test) {
|
| + return fPts[0] == test || fPts[2] == test;
|
| +}
|
| +
|
| /* started with at_most_end_pts_in_common from SkDQuadIntersection.cpp */
|
| // Do a quick reject by rotating all points relative to a line formed by
|
| // a pair of one quad's points. If the 2nd quad's points
|
| @@ -44,6 +66,14 @@ bool SkDQuad::hullIntersects(const SkDQuad& q2, bool* isLinear) const {
|
| return false;
|
| }
|
| }
|
| + if (linear && !matchesEnd(fPts, q2.fPts[0]) && !matchesEnd(fPts, q2.fPts[2])) {
|
| + // if the end point of the opposite quad is inside the hull that is nearly a line,
|
| + // then representing the quad as a line may cause the intersection to be missed.
|
| + // Check to see if the endpoint is in the triangle.
|
| + if (pointInTriangle(fPts, q2.fPts[0]) || pointInTriangle(fPts, q2.fPts[2])) {
|
| + linear = false;
|
| + }
|
| + }
|
| *isLinear = linear;
|
| return true;
|
| }
|
|
|