aboutsummaryrefslogtreecommitdiffhomepage
path: root/src/pathops/SkPathOpsTSect.h
diff options
context:
space:
mode:
authorGravatar caryclark <caryclark@google.com>2015-10-20 13:42:25 -0700
committerGravatar Commit bot <commit-bot@chromium.org>2015-10-20 13:42:25 -0700
commitef33b1e739b23a1201100ff17a572da85b03d9af (patch)
treeaed5e149a4e3b6594fb0c3f556ecd06eebdedd4f /src/pathops/SkPathOpsTSect.h
parent45a1c34f607a970933e5cd05e1df6cd8090db1be (diff)
The remaining 1m skp bugs are asserts that can be harmlessly
suppressed and bugs around conics. The conic calculation for a subdivided w was just wrong. Also added debugging to template intersection to initialize reused structures and dump additional data. TBR=reed@google.com Review URL: https://codereview.chromium.org/1413763002
Diffstat (limited to 'src/pathops/SkPathOpsTSect.h')
-rw-r--r--src/pathops/SkPathOpsTSect.h72
1 files changed, 61 insertions, 11 deletions
diff --git a/src/pathops/SkPathOpsTSect.h b/src/pathops/SkPathOpsTSect.h
index 0da4d7f9f4..56a320aab2 100644
--- a/src/pathops/SkPathOpsTSect.h
+++ b/src/pathops/SkPathOpsTSect.h
@@ -11,6 +11,12 @@
#include "SkIntersections.h"
#include "SkTSort.h"
+#ifdef SK_DEBUG
+typedef uint8_t SkOpDebugBool;
+#else
+typedef bool SkOpDebugBool;
+#endif
+
/* TCurve and OppCurve are one of { SkDQuadratic, SkDConic, SkDCubic } */
template<typename TCurve, typename OppCurve>
class SkTCoincident {
@@ -19,10 +25,20 @@ public:
this->init();
}
+ void debugInit() {
+#ifdef SK_DEBUG
+ this->fPerpPt.fX = this->fPerpPt.fY = SK_ScalarNaN;
+ this->fPerpT = SK_ScalarNaN;
+ this->fCoincident = 0xFF;
+#endif
+ }
+
+ char dumpIsCoincidentStr() const;
void dump() const;
bool isCoincident() const {
- return fCoincident;
+ SkASSERT(!!fCoincident == fCoincident);
+ return SkToBool(fCoincident);
}
void init() {
@@ -51,7 +67,7 @@ public:
private:
SkDPoint fPerpPt;
double fPerpT; // perpendicular intersection on opposite curve
- bool fCoincident;
+ SkOpDebugBool fCoincident;
};
template<typename TCurve, typename OppCurve> class SkTSect;
@@ -185,11 +201,11 @@ private:
double fStartT;
double fEndT;
double fBoundsMax;
- bool fCollapsed;
- bool fHasPerp;
- bool fIsLinear;
- bool fIsLine;
- bool fDeleted;
+ SkOpDebugBool fCollapsed;
+ SkOpDebugBool fHasPerp;
+ SkOpDebugBool fIsLinear;
+ SkOpDebugBool fIsLine;
+ SkOpDebugBool fDeleted;
SkDEBUGCODE_(SkTSect<TCurve, OppCurve>* fDebugSect);
PATH_OPS_DEBUG_T_SECT_CODE(int fID);
friend class SkTSect<TCurve, OppCurve>;
@@ -269,6 +285,7 @@ private:
SkTSpan<TCurve, OppCurve>** lastPtr);
int intersects(SkTSpan<TCurve, OppCurve>* span, SkTSect<OppCurve, TCurve>* opp,
SkTSpan<OppCurve, TCurve>* oppSpan, int* oppResult);
+ bool isParallel(const SkDLine& thisLine, const SkTSect<OppCurve, TCurve>* opp) const;
int linesIntersect(SkTSpan<TCurve, OppCurve>* span, SkTSect<OppCurve, TCurve>* opp,
SkTSpan<OppCurve, TCurve>* oppSpan, SkIntersections* );
void markSpanGone(SkTSpan<TCurve, OppCurve>* span);
@@ -828,21 +845,29 @@ SkTSpan<TCurve, OppCurve>* SkTSect<TCurve, OppCurve>::addOne() {
SkTSpan<TCurve, OppCurve>* result;
if (fDeleted) {
result = fDeleted;
- result->reset();
fDeleted = result->fNext;
} else {
result = new (fHeap.allocThrow(sizeof(SkTSpan<TCurve, OppCurve>)))(
SkTSpan<TCurve, OppCurve>);
- result->fBounded = nullptr;
#if DEBUG_T_SECT
++fDebugAllocatedCount;
#endif
}
+ result->reset();
result->fHasPerp = false;
result->fDeleted = false;
++fActiveCount;
PATH_OPS_DEBUG_T_SECT_CODE(result->fID = fDebugCount++ * 2 + fID);
SkDEBUGCODE(result->fDebugSect = this);
+#ifdef SK_DEBUG
+ result->fPart.debugInit();
+ result->fCoinStart.debugInit();
+ result->fCoinEnd.debugInit();
+ result->fPrev = result->fNext = nullptr;
+ result->fBounds.debugInit();
+ result->fStartT = result->fEndT = result->fBoundsMax = SK_ScalarNaN;
+ result->fCollapsed = result->fIsLinear = result->fIsLine = 0xFF;
+#endif
return result;
}
@@ -1277,6 +1302,31 @@ int SkTSect<TCurve, OppCurve>::intersects(SkTSpan<TCurve, OppCurve>* span,
return *oppResult = 1;
}
+template<typename TCurve>
+static bool is_parallel(const SkDLine& thisLine, const TCurve& opp) {
+ if (!opp.IsConic()) {
+ return false; // FIXME : breaks a lot of stuff now
+ }
+ int finds = 0;
+ SkDLine thisPerp;
+ thisPerp.fPts[0].fX = thisLine.fPts[1].fX + (thisLine.fPts[1].fY - thisLine.fPts[0].fY);
+ thisPerp.fPts[0].fY = thisLine.fPts[1].fY + (thisLine.fPts[0].fX - thisLine.fPts[1].fX);
+ thisPerp.fPts[1] = thisLine.fPts[1];
+ SkIntersections perpRayI;
+ perpRayI.intersectRay(opp, thisPerp);
+ for (int pIndex = 0; pIndex < perpRayI.used(); ++pIndex) {
+ finds += perpRayI.pt(pIndex).approximatelyEqual(thisPerp.fPts[1]);
+ }
+ thisPerp.fPts[1].fX = thisLine.fPts[0].fX + (thisLine.fPts[1].fY - thisLine.fPts[0].fY);
+ thisPerp.fPts[1].fY = thisLine.fPts[0].fY + (thisLine.fPts[0].fX - thisLine.fPts[1].fX);
+ thisPerp.fPts[0] = thisLine.fPts[0];
+ perpRayI.intersectRay(opp, thisPerp);
+ for (int pIndex = 0; pIndex < perpRayI.used(); ++pIndex) {
+ finds += perpRayI.pt(pIndex).approximatelyEqual(thisPerp.fPts[0]);
+ }
+ return finds >= 2;
+}
+
// while the intersection points are sufficiently far apart:
// construct the tangent lines from the intersections
// find the point where the tangent line intersects the opposite curve
@@ -1303,7 +1353,7 @@ int SkTSect<TCurve, OppCurve>::linesIntersect(SkTSpan<TCurve, OppCurve>* span,
ptMatches += thisRayI.pt(tIndex).approximatelyEqual(thisLine.fPts[lIndex]);
}
}
- if (ptMatches == 2) {
+ if (ptMatches == 2 || is_parallel(thisLine, opp->fCurve)) {
return 2;
}
}
@@ -1314,7 +1364,7 @@ int SkTSect<TCurve, OppCurve>::linesIntersect(SkTSpan<TCurve, OppCurve>* span,
ptMatches += oppRayI.pt(oIndex).approximatelyEqual(oppLine.fPts[lIndex]);
}
}
- if (ptMatches == 2) {
+ if (ptMatches == 2|| is_parallel(oppLine, this->fCurve)) {
return 2;
}
}