aboutsummaryrefslogtreecommitdiffhomepage
path: root/src/pathops/SkPathOpsTSect.h
diff options
context:
space:
mode:
authorGravatar caryclark <caryclark@google.com>2015-10-22 07:23:52 -0700
committerGravatar Commit bot <commit-bot@chromium.org>2015-10-22 07:23:52 -0700
commited0935a28a29af7d3b16ac8d9365f291a335c6bd (patch)
treef16bcde492ecfdbf19fcfcec9713c42e52326cb1 /src/pathops/SkPathOpsTSect.h
parent7f53819ea9f8317b4bae1d54239b5b4c18240ef0 (diff)
Reland of path ops: fix conic weight and partial coincidence (patchset #1 id:1 of https://codereview.chromium.org/1408923003/ )
Reason for revert: suppressions have landed in chrome Original issue's description: > Revert of path ops: fix conic weight and partial coincidence (patchset #5 id:80001 of https://codereview.chromium.org/1413763002/ ) > > Reason for revert: > path ops change breaks svg clipping layout tests -- conic is now more accurate, changing edge of circle in clip > > These need to be rebaselined > > svg/clip-path/clip-path-child-clipped.svg > svg/clip-path/clip-path-nonzero.svg > svg/clip-path/clip-path-evenodd-nonzero.svg > svg/clip-path/clip-path-nonzero-evenodd.svg > > Original issue's description: > > 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 > > > > Committed: https://skia.googlesource.com/skia/+/ef33b1e739b23a1201100ff17a572da85b03d9af > > TBR= > NOPRESUBMIT=true > NOTREECHECKS=true > NOTRY=true > > Committed: https://skia.googlesource.com/skia/+/f428df1be3e96d3f8970d0f7f415b862f7da5404 TBR= NOPRESUBMIT=true NOTREECHECKS=true NOTRY=true Review URL: https://codereview.chromium.org/1407003016
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;
}
}