1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525 |
- /*
- * Copyright 2014 Google Inc.
- *
- * Use of this source code is governed by a BSD-style license that can be
- * found in the LICENSE file.
- */
- #include "include/core/SkString.h"
- #include "include/private/SkMutex.h"
- #include "src/pathops/SkIntersectionHelper.h"
- #include "src/pathops/SkOpCoincidence.h"
- #include "src/pathops/SkOpContour.h"
- #include "src/pathops/SkOpSegment.h"
- #include "tests/PathOpsDebug.h"
- #include "tests/PathOpsTSectDebug.h"
- bool PathOpsDebug::gJson;
- bool PathOpsDebug::gMarkJsonFlaky;
- bool PathOpsDebug::gOutFirst;
- bool PathOpsDebug::gCheckForDuplicateNames;
- bool PathOpsDebug::gOutputSVG;
- FILE* PathOpsDebug::gOut;
- inline void DebugDumpDouble(double x) {
- if (x == floor(x)) {
- SkDebugf("%.0f", x);
- } else {
- SkDebugf("%1.19g", x);
- }
- }
- inline void DebugDumpFloat(float x) {
- if (x == floorf(x)) {
- SkDebugf("%.0f", x);
- } else {
- SkDebugf("%1.9gf", x);
- }
- }
- inline void DebugDumpHexFloat(float x) {
- SkDebugf("SkBits2Float(0x%08x)", SkFloat2Bits(x));
- }
- // if not defined by PathOpsDebug.cpp ...
- #if !defined SK_DEBUG && FORCE_RELEASE
- bool SkPathOpsDebug::ValidWind(int wind) {
- return wind > SK_MinS32 + 0xFFFF && wind < SK_MaxS32 - 0xFFFF;
- }
- void SkPathOpsDebug::WindingPrintf(int wind) {
- if (wind == SK_MinS32) {
- SkDebugf("?");
- } else {
- SkDebugf("%d", wind);
- }
- }
- #endif
- static void DumpID(int id) {
- SkDebugf("} ");
- if (id >= 0) {
- SkDebugf("id=%d", id);
- }
- SkDebugf("\n");
- }
- void SkDConic::dump() const {
- dumpInner();
- SkDebugf("},\n");
- }
- void SkDConic::dumpID(int id) const {
- dumpInner();
- DumpID(id);
- }
- void SkDConic::dumpInner() const {
- SkDebugf("{");
- fPts.dumpInner();
- SkDebugf("}}, %1.9gf", fWeight);
- }
- void SkDCubic::dump() const {
- this->dumpInner();
- SkDebugf("}},\n");
- }
- void SkDCubic::dumpID(int id) const {
- this->dumpInner();
- SkDebugf("}");
- DumpID(id);
- }
- static inline bool double_is_NaN(double x) { return x != x; }
- void SkDCubic::dumpInner() const {
- SkDebugf("{{");
- int index = 0;
- do {
- if (index != 0) {
- if (double_is_NaN(fPts[index].fX) && double_is_NaN(fPts[index].fY)) {
- return;
- }
- SkDebugf(", ");
- }
- fPts[index].dump();
- } while (++index < 3);
- if (double_is_NaN(fPts[index].fX) && double_is_NaN(fPts[index].fY)) {
- return;
- }
- SkDebugf(", ");
- fPts[index].dump();
- }
- void SkDCurve::dump() const {
- dumpID(-1);
- }
- void SkDCurve::dumpID(int id) const {
- #ifndef SK_RELEASE
- switch(fVerb) {
- case SkPath::kLine_Verb:
- fLine.dumpID(id);
- break;
- case SkPath::kQuad_Verb:
- fQuad.dumpID(id);
- break;
- case SkPath::kConic_Verb:
- fConic.dumpID(id);
- break;
- case SkPath::kCubic_Verb:
- fCubic.dumpID(id);
- break;
- default:
- SkASSERT(0);
- }
- #else
- fCubic.dumpID(id);
- #endif
- }
- void SkDLine::dump() const {
- this->dumpInner();
- SkDebugf("}},\n");
- }
- void SkDLine::dumpID(int id) const {
- this->dumpInner();
- SkDebugf("}");
- DumpID(id);
- }
- void SkDLine::dumpInner() const {
- SkDebugf("{{");
- fPts[0].dump();
- SkDebugf(", ");
- fPts[1].dump();
- }
- void SkDPoint::dump() const {
- SkDebugf("{");
- DebugDumpDouble(fX);
- SkDebugf(", ");
- DebugDumpDouble(fY);
- SkDebugf("}");
- }
- void SkDPoint::Dump(const SkPoint& pt) {
- SkDebugf("{");
- DebugDumpFloat(pt.fX);
- SkDebugf(", ");
- DebugDumpFloat(pt.fY);
- SkDebugf("}");
- }
- void SkDPoint::DumpHex(const SkPoint& pt) {
- SkDebugf("{");
- DebugDumpHexFloat(pt.fX);
- SkDebugf(", ");
- DebugDumpHexFloat(pt.fY);
- SkDebugf("}");
- }
- void SkDQuad::dump() const {
- dumpInner();
- SkDebugf("}},\n");
- }
- void SkDQuad::dumpID(int id) const {
- dumpInner();
- SkDebugf("}");
- DumpID(id);
- }
- void SkDQuad::dumpInner() const {
- SkDebugf("{{");
- int index = 0;
- do {
- fPts[index].dump();
- SkDebugf(", ");
- } while (++index < 2);
- fPts[index].dump();
- }
- void SkIntersections::dump() const {
- SkDebugf("used=%d of %d", fUsed, fMax);
- for (int index = 0; index < fUsed; ++index) {
- SkDebugf(" t=(%s%1.9g,%s%1.9g) pt=(%1.9g,%1.9g)",
- fIsCoincident[0] & (1 << index) ? "*" : "", fT[0][index],
- fIsCoincident[1] & (1 << index) ? "*" : "", fT[1][index],
- fPt[index].fX, fPt[index].fY);
- if (index < 2 && fNearlySame[index]) {
- SkDebugf(" pt2=(%1.9g,%1.9g)",fPt2[index].fX, fPt2[index].fY);
- }
- }
- SkDebugf("\n");
- }
- const SkOpAngle* AngleAngle(const SkOpAngle* angle, int id) {
- return angle->debugAngle(id);
- }
- SkOpContour* AngleContour(SkOpAngle* angle, int id) {
- return angle->debugContour(id);
- }
- const SkOpPtT* AnglePtT(const SkOpAngle* angle, int id) {
- return angle->debugPtT(id);
- }
- const SkOpSegment* AngleSegment(const SkOpAngle* angle, int id) {
- return angle->debugSegment(id);
- }
- const SkOpSpanBase* AngleSpan(const SkOpAngle* angle, int id) {
- return angle->debugSpan(id);
- }
- const SkOpAngle* ContourAngle(SkOpContour* contour, int id) {
- return contour->debugAngle(id);
- }
- SkOpContour* ContourContour(SkOpContour* contour, int id) {
- return contour->debugContour(id);
- }
- const SkOpPtT* ContourPtT(SkOpContour* contour, int id) {
- return contour->debugPtT(id);
- }
- const SkOpSegment* ContourSegment(SkOpContour* contour, int id) {
- return contour->debugSegment(id);
- }
- const SkOpSpanBase* ContourSpan(SkOpContour* contour, int id) {
- return contour->debugSpan(id);
- }
- const SkOpAngle* CoincidenceAngle(SkOpCoincidence* coin, int id) {
- return coin->debugAngle(id);
- }
- SkOpContour* CoincidenceContour(SkOpCoincidence* coin, int id) {
- return coin->debugContour(id);
- }
- const SkOpPtT* CoincidencePtT(SkOpCoincidence* coin, int id) {
- return coin->debugPtT(id);
- }
- const SkOpSegment* CoincidenceSegment(SkOpCoincidence* coin, int id) {
- return coin->debugSegment(id);
- }
- const SkOpSpanBase* CoincidenceSpan(SkOpCoincidence* coin, int id) {
- return coin->debugSpan(id);
- }
- const SkOpAngle* PtTAngle(const SkOpPtT* ptT, int id) {
- return ptT->debugAngle(id);
- }
- SkOpContour* PtTContour(SkOpPtT* ptT, int id) {
- return ptT->debugContour(id);
- }
- const SkOpPtT* PtTPtT(const SkOpPtT* ptT, int id) {
- return ptT->debugPtT(id);
- }
- const SkOpSegment* PtTSegment(const SkOpPtT* ptT, int id) {
- return ptT->debugSegment(id);
- }
- const SkOpSpanBase* PtTSpan(const SkOpPtT* ptT, int id) {
- return ptT->debugSpan(id);
- }
- const SkOpAngle* SegmentAngle(const SkOpSegment* span, int id) {
- return span->debugAngle(id);
- }
- SkOpContour* SegmentContour(SkOpSegment* span, int id) {
- return span->debugContour(id);
- }
- const SkOpPtT* SegmentPtT(const SkOpSegment* span, int id) {
- return span->debugPtT(id);
- }
- const SkOpSegment* SegmentSegment(const SkOpSegment* span, int id) {
- return span->debugSegment(id);
- }
- const SkOpSpanBase* SegmentSpan(const SkOpSegment* span, int id) {
- return span->debugSpan(id);
- }
- const SkOpAngle* SpanAngle(const SkOpSpanBase* span, int id) {
- return span->debugAngle(id);
- }
- SkOpContour* SpanContour(SkOpSpanBase* span, int id) {
- return span->debugContour(id);
- }
- const SkOpPtT* SpanPtT(const SkOpSpanBase* span, int id) {
- return span->debugPtT(id);
- }
- const SkOpSegment* SpanSegment(const SkOpSpanBase* span, int id) {
- return span->debugSegment(id);
- }
- const SkOpSpanBase* SpanSpan(const SkOpSpanBase* span, int id) {
- return span->debugSpan(id);
- }
- #if DEBUG_COIN
- void SkPathOpsDebug::DumpCoinDict() {
- SkPathOpsDebug::gCoinSumChangedDict.dump("unused coin algorithm", false);
- SkPathOpsDebug::gCoinSumVisitedDict.dump("visited coin function", true);
- }
- void SkPathOpsDebug::CoinDict::dump(const char* str, bool visitCheck) const {
- int count = fDict.count();
- for (int index = 0; index < count; ++index) {
- const auto& entry = fDict[index];
- if (visitCheck || entry.fGlitchType == kUninitialized_Glitch) {
- SkDebugf("%s %s : line %d iteration %d", str, entry.fFunctionName,
- entry.fLineNumber, entry.fIteration);
- DumpGlitchType(entry.fGlitchType);
- SkDebugf("\n");
- }
- }
- }
- #endif
- void SkOpContour::dumpContours() const {
- SkOpContour* contour = this->globalState()->contourHead();
- do {
- contour->dump();
- } while ((contour = contour->next()));
- }
- void SkOpContour::dumpContoursAll() const {
- SkOpContour* contour = this->globalState()->contourHead();
- do {
- contour->dumpAll();
- } while ((contour = contour->next()));
- }
- void SkOpContour::dumpContoursAngles() const {
- SkOpContour* contour = this->globalState()->contourHead();
- do {
- contour->dumpAngles();
- } while ((contour = contour->next()));
- }
- void SkOpContour::dumpContoursPts() const {
- SkOpContour* contour = this->globalState()->contourHead();
- do {
- contour->dumpPts();
- } while ((contour = contour->next()));
- }
- void SkOpContour::dumpContoursPt(int segmentID) const {
- SkOpContour* contour = this->globalState()->contourHead();
- do {
- contour->dumpPt(segmentID);
- } while ((contour = contour->next()));
- }
- void SkOpContour::dumpContoursSegment(int segmentID) const {
- SkOpContour* contour = this->globalState()->contourHead();
- do {
- contour->dumpSegment(segmentID);
- } while ((contour = contour->next()));
- }
- void SkOpContour::dumpContoursSpan(int spanID) const {
- SkOpContour* contour = this->globalState()->contourHead();
- do {
- contour->dumpSpan(spanID);
- } while ((contour = contour->next()));
- }
- void SkOpContour::dumpContoursSpans() const {
- SkOpContour* contour = this->globalState()->contourHead();
- do {
- contour->dumpSpans();
- } while ((contour = contour->next()));
- }
- #ifdef SK_DEBUG
- const SkTSpan* DebugSpan(const SkTSect* sect, int id) {
- return sect->debugSpan(id);
- }
- const SkTSpan* DebugT(const SkTSect* sect, double t) {
- return sect->debugT(t);
- }
- #endif
- void Dump(const SkTSect* sect) {
- sect->dump();
- }
- void DumpBoth(SkTSect* sect1, SkTSect* sect2) {
- sect1->dumpBoth(sect2);
- }
- void DumpBounded(SkTSect* sect1, int id) {
- sect1->dumpBounded(id);
- }
- void DumpBounds(SkTSect* sect1) {
- sect1->dumpBounds();
- }
- void DumpCoin(SkTSect* sect1) {
- sect1->dumpCoin();
- }
- void DumpCoinCurves(SkTSect* sect1) {
- sect1->dumpCoinCurves();
- }
- void DumpCurves(const SkTSect* sect) {
- sect->dumpCurves();
- }
- void Dump(const SkTSpan* span) {
- span->dump();
- }
- void DumpAll(const SkTSpan* span) {
- span->dumpAll();
- }
- void DumpBounded(const SkTSpan* span) {
- span->dumpBounded(0);
- }
- void DumpCoin(const SkTSpan* span) {
- span->dumpCoin();
- }
- static void dumpTestCase(const SkDQuad& quad1, const SkDQuad& quad2, int testNo) {
- SkDebugf("\n<div id=\"quad%d\">\n", testNo);
- quad1.dumpInner();
- SkDebugf("}}, ");
- quad2.dump();
- SkDebugf("</div>\n\n");
- }
- static void dumpTestTrailer() {
- SkDebugf("</div>\n\n<script type=\"text/javascript\">\n\n");
- SkDebugf(" var testDivs = [\n");
- }
- static void dumpTestList(int testNo, double min) {
- SkDebugf(" quad%d,", testNo);
- if (min > 0) {
- SkDebugf(" // %1.9g", min);
- }
- SkDebugf("\n");
- }
- void DumpQ(const SkDQuad& quad1, const SkDQuad& quad2, int testNo) {
- SkDebugf("\n");
- dumpTestCase(quad1, quad2, testNo);
- dumpTestTrailer();
- dumpTestList(testNo, 0);
- SkDebugf("\n");
- }
- void DumpT(const SkDQuad& quad, double t) {
- SkDLine line = {{quad.ptAtT(t), quad[0]}};
- line.dump();
- }
- const SkOpAngle* SkOpAngle::debugAngle(int id) const {
- return this->segment()->debugAngle(id);
- }
- const SkOpCoincidence* SkOpAngle::debugCoincidence() const {
- return this->segment()->debugCoincidence();
- }
- SkOpContour* SkOpAngle::debugContour(int id) const {
- return this->segment()->debugContour(id);
- }
- const SkOpPtT* SkOpAngle::debugPtT(int id) const {
- return this->segment()->debugPtT(id);
- }
- const SkOpSegment* SkOpAngle::debugSegment(int id) const {
- return this->segment()->debugSegment(id);
- }
- int SkOpAngle::debugSign() const {
- SkASSERT(fStart->t() != fEnd->t());
- return fStart->t() < fEnd->t() ? -1 : 1;
- }
- const SkOpSpanBase* SkOpAngle::debugSpan(int id) const {
- return this->segment()->debugSpan(id);
- }
- void SkOpAngle::dump() const {
- dumpOne(true);
- SkDebugf("\n");
- }
- void SkOpAngle::dumpOne(bool functionHeader) const {
- // fSegment->debugValidate();
- const SkOpSegment* segment = this->segment();
- const SkOpSpan& mSpan = *fStart->starter(fEnd);
- if (functionHeader) {
- SkDebugf("%s ", __FUNCTION__);
- }
- SkDebugf("[%d", segment->debugID());
- SkDebugf("/%d", debugID());
- SkDebugf("] next=");
- if (fNext) {
- SkDebugf("%d", fNext->fStart->segment()->debugID());
- SkDebugf("/%d", fNext->debugID());
- } else {
- SkDebugf("?");
- }
- SkDebugf(" sect=%d/%d ", fSectorStart, fSectorEnd);
- SkDebugf(" s=%1.9g [%d] e=%1.9g [%d]", fStart->t(), fStart->debugID(),
- fEnd->t(), fEnd->debugID());
- SkDebugf(" sgn=%d windVal=%d", this->debugSign(), mSpan.windValue());
- SkDebugf(" windSum=");
- SkPathOpsDebug::WindingPrintf(mSpan.windSum());
- if (mSpan.oppValue() != 0 || mSpan.oppSum() != SK_MinS32) {
- SkDebugf(" oppVal=%d", mSpan.oppValue());
- SkDebugf(" oppSum=");
- SkPathOpsDebug::WindingPrintf(mSpan.oppSum());
- }
- if (mSpan.done()) {
- SkDebugf(" done");
- }
- if (unorderable()) {
- SkDebugf(" unorderable");
- }
- if (segment->operand()) {
- SkDebugf(" operand");
- }
- }
- void SkOpAngle::dumpTo(const SkOpSegment* segment, const SkOpAngle* to) const {
- const SkOpAngle* first = this;
- const SkOpAngle* next = this;
- const char* indent = "";
- do {
- SkDebugf("%s", indent);
- next->dumpOne(false);
- if (segment == next->fStart->segment()) {
- if (this == fNext) {
- SkDebugf(" << from");
- }
- if (to == fNext) {
- SkDebugf(" << to");
- }
- }
- SkDebugf("\n");
- indent = " ";
- next = next->fNext;
- } while (next && next != first);
- }
- void SkOpAngle::dumpCurves() const {
- const SkOpAngle* first = this;
- const SkOpAngle* next = this;
- do {
- next->fPart.fCurve.dumpID(next->segment()->debugID());
- next = next->fNext;
- } while (next && next != first);
- }
- void SkOpAngle::dumpLoop() const {
- const SkOpAngle* first = this;
- const SkOpAngle* next = this;
- do {
- next->dumpOne(false);
- SkDebugf("\n");
- next = next->fNext;
- } while (next && next != first);
- }
- void SkOpAngle::dumpTest() const {
- const SkOpAngle* first = this;
- const SkOpAngle* next = this;
- do {
- SkDebugf("{ ");
- SkOpSegment* segment = next->segment();
- segment->dumpPts();
- SkDebugf(", %d, %1.9g, %1.9g, {} },\n", SkPathOpsVerbToPoints(segment->verb()) + 1,
- next->start()->t(), next->end()->t());
- next = next->fNext;
- } while (next && next != first);
- }
- bool SkOpPtT::debugMatchID(int id) const {
- int limit = this->debugLoopLimit(false);
- int loop = 0;
- const SkOpPtT* ptT = this;
- do {
- if (ptT->debugID() == id) {
- return true;
- }
- } while ((!limit || ++loop <= limit) && (ptT = ptT->next()) && ptT != this);
- return false;
- }
- const SkOpAngle* SkOpPtT::debugAngle(int id) const {
- return this->span()->debugAngle(id);
- }
- SkOpContour* SkOpPtT::debugContour(int id) const {
- return this->span()->debugContour(id);
- }
- const SkOpCoincidence* SkOpPtT::debugCoincidence() const {
- return this->span()->debugCoincidence();
- }
- const SkOpPtT* SkOpPtT::debugPtT(int id) const {
- return this->span()->debugPtT(id);
- }
- const SkOpSegment* SkOpPtT::debugSegment(int id) const {
- return this->span()->debugSegment(id);
- }
- const SkOpSpanBase* SkOpPtT::debugSpan(int id) const {
- return this->span()->debugSpan(id);
- }
- void SkOpPtT::dump() const {
- SkDebugf("seg=%d span=%d ptT=%d",
- this->segment()->debugID(), this->span()->debugID(), this->debugID());
- this->dumpBase();
- SkDebugf("\n");
- }
- void SkOpPtT::dumpAll() const {
- contour()->indentDump();
- const SkOpPtT* next = this;
- int limit = debugLoopLimit(true);
- int loop = 0;
- do {
- SkDebugf("%.*s", contour()->debugIndent(), " ");
- SkDebugf("seg=%d span=%d ptT=%d",
- next->segment()->debugID(), next->span()->debugID(), next->debugID());
- next->dumpBase();
- SkDebugf("\n");
- if (limit && ++loop >= limit) {
- SkDebugf("*** abort loop ***\n");
- break;
- }
- } while ((next = next->fNext) && next != this);
- contour()->outdentDump();
- }
- void SkOpPtT::dumpBase() const {
- SkDebugf(" t=%1.9g pt=(%1.9g,%1.9g)%s%s%s", this->fT, this->fPt.fX, this->fPt.fY,
- this->fCoincident ? " coin" : "",
- this->fDuplicatePt ? " dup" : "", this->fDeleted ? " deleted" : "");
- }
- const SkOpAngle* SkOpSpanBase::debugAngle(int id) const {
- return this->segment()->debugAngle(id);
- }
- const SkOpCoincidence* SkOpSpanBase::debugCoincidence() const {
- return this->segment()->debugCoincidence();
- }
- SkOpContour* SkOpSpanBase::debugContour(int id) const {
- return this->segment()->debugContour(id);
- }
- const SkOpPtT* SkOpSpanBase::debugPtT(int id) const {
- return this->segment()->debugPtT(id);
- }
- const SkOpSegment* SkOpSpanBase::debugSegment(int id) const {
- return this->segment()->debugSegment(id);
- }
- const SkOpSpanBase* SkOpSpanBase::debugSpan(int id) const {
- return this->segment()->debugSpan(id);
- }
- void SkOpSpanBase::dump() const {
- this->dumpHead();
- this->fPtT.dump();
- }
- void SkOpSpanBase::dumpHead() const {
- SkDebugf("%.*s", contour()->debugIndent(), " ");
- SkDebugf("seg=%d span=%d", this->segment()->debugID(), this->debugID());
- this->dumpBase();
- SkDebugf("\n");
- }
- void SkOpSpanBase::dumpAll() const {
- this->dumpHead();
- this->fPtT.dumpAll();
- }
- void SkOpSpanBase::dumpBase() const {
- if (this->fAligned) {
- SkDebugf(" aligned");
- }
- if (this->fChased) {
- SkDebugf(" chased");
- }
- #ifdef SK_DEBUG
- if (this->fDebugDeleted) {
- SkDebugf(" deleted");
- }
- #endif
- if (!this->final()) {
- this->upCast()->dumpSpan();
- }
- const SkOpSpanBase* coin = this->coinEnd();
- if (this != coin) {
- SkDebugf(" coinEnd seg/span=%d/%d", coin->segment()->debugID(), coin->debugID());
- } else if (this->final() || !this->upCast()->isCoincident()) {
- const SkOpPtT* oPt = this->ptT()->next();
- SkDebugf(" seg/span=%d/%d", oPt->segment()->debugID(), oPt->span()->debugID());
- }
- SkDebugf(" adds=%d", fSpanAdds);
- }
- void SkOpSpanBase::dumpCoin() const {
- const SkOpSpan* span = this->upCastable();
- if (!span) {
- return;
- }
- if (!span->isCoincident()) {
- return;
- }
- span->dumpCoin();
- }
- void SkOpSpan::dumpCoin() const {
- const SkOpSpan* coincident = fCoincident;
- bool ok = debugCoinLoopCheck();
- this->dump();
- int loop = 0;
- do {
- coincident->dump();
- if (!ok && ++loop > 10) {
- SkDebugf("*** abort loop ***\n");
- break;
- }
- } while ((coincident = coincident->fCoincident) != this);
- }
- bool SkOpSpan::dumpSpan() const {
- SkOpSpan* coin = fCoincident;
- if (this != coin) {
- SkDebugf(" coinStart seg/span=%d/%d", coin->segment()->debugID(), coin->debugID());
- }
- SkDebugf(" windVal=%d", this->windValue());
- SkDebugf(" windSum=");
- SkPathOpsDebug::WindingPrintf(this->windSum());
- if (this->oppValue() != 0 || this->oppSum() != SK_MinS32) {
- SkDebugf(" oppVal=%d", this->oppValue());
- SkDebugf(" oppSum=");
- SkPathOpsDebug::WindingPrintf(this->oppSum());
- }
- if (this->done()) {
- SkDebugf(" done");
- }
- return this != coin;
- }
- const SkOpAngle* SkOpSegment::debugAngle(int id) const {
- return this->contour()->debugAngle(id);
- }
- const SkOpCoincidence* SkOpSegment::debugCoincidence() const {
- return this->contour()->debugCoincidence();
- }
- SkOpContour* SkOpSegment::debugContour(int id) const {
- return this->contour()->debugContour(id);
- }
- const SkOpPtT* SkOpSegment::debugPtT(int id) const {
- return this->contour()->debugPtT(id);
- }
- const SkOpSegment* SkOpSegment::debugSegment(int id) const {
- return this->contour()->debugSegment(id);
- }
- const SkOpSpanBase* SkOpSegment::debugSpan(int id) const {
- return this->contour()->debugSpan(id);
- }
- void SkOpSegment::dump() const {
- SkDebugf("%.*s", contour()->debugIndent(), " ");
- this->dumpPts();
- const SkOpSpanBase* span = &fHead;
- contour()->indentDump();
- do {
- SkDebugf("%.*s span=%d ", contour()->debugIndent(), " ", span->debugID());
- span->ptT()->dumpBase();
- span->dumpBase();
- SkDebugf("\n");
- } while (!span->final() && (span = span->upCast()->next()));
- contour()->outdentDump();
- }
- void SkOpSegment::dumpAll() const {
- SkDebugf("%.*s", contour()->debugIndent(), " ");
- this->dumpPts();
- const SkOpSpanBase* span = &fHead;
- contour()->indentDump();
- do {
- span->dumpAll();
- } while (!span->final() && (span = span->upCast()->next()));
- contour()->outdentDump();
- }
- void SkOpSegment::dumpAngles() const {
- SkDebugf("seg=%d\n", debugID());
- const SkOpSpanBase* span = &fHead;
- do {
- const SkOpAngle* fAngle = span->fromAngle();
- const SkOpAngle* tAngle = span->final() ? nullptr : span->upCast()->toAngle();
- if (fAngle) {
- SkDebugf(" span=%d from=%d ", span->debugID(), fAngle->debugID());
- fAngle->dumpTo(this, tAngle);
- }
- if (tAngle) {
- SkDebugf(" span=%d to=%d ", span->debugID(), tAngle->debugID());
- tAngle->dumpTo(this, fAngle);
- }
- } while (!span->final() && (span = span->upCast()->next()));
- }
- void SkOpSegment::dumpCoin() const {
- const SkOpSpan* span = &fHead;
- do {
- span->dumpCoin();
- } while ((span = span->next()->upCastable()));
- }
- void SkOpSegment::dumpPtsInner(const char* prefix) const {
- int last = SkPathOpsVerbToPoints(fVerb);
- SkDebugf("%s=%d {{", prefix, this->debugID());
- if (fVerb == SkPath::kConic_Verb) {
- SkDebugf("{");
- }
- int index = 0;
- do {
- SkDPoint::Dump(fPts[index]);
- SkDebugf(", ");
- } while (++index < last);
- SkDPoint::Dump(fPts[index]);
- SkDebugf("}}");
- if (fVerb == SkPath::kConic_Verb) {
- SkDebugf(", %1.9gf}", fWeight);
- }
- }
- void SkOpSegment::dumpPts(const char* prefix) const {
- dumpPtsInner(prefix);
- SkDebugf("\n");
- }
- void SkCoincidentSpans::dump() const {
- SkDebugf("- seg=%d span=%d ptT=%d ", fCoinPtTStart->segment()->debugID(),
- fCoinPtTStart->span()->debugID(), fCoinPtTStart->debugID());
- fCoinPtTStart->dumpBase();
- SkDebugf(" span=%d ptT=%d ", fCoinPtTEnd->span()->debugID(), fCoinPtTEnd->debugID());
- fCoinPtTEnd->dumpBase();
- if (fCoinPtTStart->segment()->operand()) {
- SkDebugf(" operand");
- }
- if (fCoinPtTStart->segment()->isXor()) {
- SkDebugf(" xor");
- }
- SkDebugf("\n");
- SkDebugf("+ seg=%d span=%d ptT=%d ", fOppPtTStart->segment()->debugID(),
- fOppPtTStart->span()->debugID(), fOppPtTStart->debugID());
- fOppPtTStart->dumpBase();
- SkDebugf(" span=%d ptT=%d ", fOppPtTEnd->span()->debugID(), fOppPtTEnd->debugID());
- fOppPtTEnd->dumpBase();
- if (fOppPtTStart->segment()->operand()) {
- SkDebugf(" operand");
- }
- if (fOppPtTStart->segment()->isXor()) {
- SkDebugf(" xor");
- }
- SkDebugf("\n");
- }
- void SkOpCoincidence::dump() const {
- SkCoincidentSpans* span = fHead;
- while (span) {
- span->dump();
- span = span->next();
- }
- if (!fTop || fHead == fTop) {
- return;
- }
- SkDebugf("top:\n");
- span = fTop;
- int count = 0;
- while (span) {
- span->dump();
- span = span->next();
- SkCoincidentSpans* check = fTop;
- ++count;
- for (int index = 0; index < count; ++index) {
- if (span == check) {
- SkDebugf("(loops to #%d)\n", index);
- return;
- }
- check = check->next();
- }
- }
- }
- void SkOpContour::dump() const {
- SkDebugf("contour=%d count=%d op=%d xor=%d\n", this->debugID(), fCount, fOperand, fXor);
- if (!fCount) {
- return;
- }
- const SkOpSegment* segment = &fHead;
- SkDEBUGCODE(fDebugIndent = 0);
- this->indentDump();
- do {
- segment->dump();
- } while ((segment = segment->next()));
- this->outdentDump();
- }
- void SkOpContour::dumpAll() const {
- SkDebugf("contour=%d count=%d op=%d xor=%d\n", this->debugID(), fCount, fOperand, fXor);
- if (!fCount) {
- return;
- }
- const SkOpSegment* segment = &fHead;
- SkDEBUGCODE(fDebugIndent = 0);
- this->indentDump();
- do {
- segment->dumpAll();
- } while ((segment = segment->next()));
- this->outdentDump();
- }
- void SkOpContour::dumpAngles() const {
- SkDebugf("contour=%d\n", this->debugID());
- const SkOpSegment* segment = &fHead;
- do {
- SkDebugf(" seg=%d ", segment->debugID());
- segment->dumpAngles();
- } while ((segment = segment->next()));
- }
- void SkOpContour::dumpPt(int index) const {
- const SkOpSegment* segment = &fHead;
- do {
- if (segment->debugID() == index) {
- segment->dumpPts();
- }
- } while ((segment = segment->next()));
- }
- void SkOpContour::dumpPts(const char* prefix) const {
- SkDebugf("contour=%d\n", this->debugID());
- const SkOpSegment* segment = &fHead;
- do {
- SkDebugf(" %s=%d ", prefix, segment->debugID());
- segment->dumpPts(prefix);
- } while ((segment = segment->next()));
- }
- void SkOpContour::dumpPtsX(const char* prefix) const {
- if (!this->fCount) {
- SkDebugf("<empty>\n");
- return;
- }
- const SkOpSegment* segment = &fHead;
- do {
- segment->dumpPts(prefix);
- } while ((segment = segment->next()));
- }
- void SkOpContour::dumpSegment(int index) const {
- debugSegment(index)->dump();
- }
- void SkOpContour::dumpSegments(const char* prefix, SkPathOp op) const {
- bool firstOp = false;
- const SkOpContour* c = this;
- do {
- if (!firstOp && c->operand()) {
- #if DEBUG_ACTIVE_OP
- SkDebugf("op %s\n", SkPathOpsDebug::kPathOpStr[op]);
- #endif
- firstOp = true;
- }
- c->dumpPtsX(prefix);
- } while ((c = c->next()));
- }
- void SkOpContour::dumpSpan(int index) const {
- debugSpan(index)->dump();
- }
- void SkOpContour::dumpSpans() const {
- SkDebugf("contour=%d\n", this->debugID());
- const SkOpSegment* segment = &fHead;
- do {
- SkDebugf(" seg=%d ", segment->debugID());
- segment->dump();
- } while ((segment = segment->next()));
- }
- void SkOpCurve::dump() const {
- int count = SkPathOpsVerbToPoints(SkDEBUGRELEASE(fVerb, SkPath::kCubic_Verb));
- SkDebugf("{{");
- int index;
- for (index = 0; index <= count - 1; ++index) {
- SkDebugf("{%1.9gf,%1.9gf}, ", fPts[index].fX, fPts[index].fY);
- }
- SkDebugf("{%1.9gf,%1.9gf}}}\n", fPts[index].fX, fPts[index].fY);
- }
- #ifdef SK_DEBUG
- const SkOpAngle* SkOpGlobalState::debugAngle(int id) const {
- const SkOpContour* contour = fContourHead;
- do {
- const SkOpSegment* segment = contour->first();
- while (segment) {
- const SkOpSpan* span = segment->head();
- do {
- SkOpAngle* angle = span->fromAngle();
- if (angle && angle->debugID() == id) {
- return angle;
- }
- angle = span->toAngle();
- if (angle && angle->debugID() == id) {
- return angle;
- }
- } while ((span = span->next()->upCastable()));
- const SkOpSpanBase* tail = segment->tail();
- SkOpAngle* angle = tail->fromAngle();
- if (angle && angle->debugID() == id) {
- return angle;
- }
- segment = segment->next();
- }
- } while ((contour = contour->next()));
- return nullptr;
- }
- SkOpContour* SkOpGlobalState::debugContour(int id) const {
- SkOpContour* contour = fContourHead;
- do {
- if (contour->debugID() == id) {
- return contour;
- }
- } while ((contour = contour->next()));
- return nullptr;
- }
- const SkOpPtT* SkOpGlobalState::debugPtT(int id) const {
- const SkOpContour* contour = fContourHead;
- do {
- const SkOpSegment* segment = contour->first();
- while (segment) {
- const SkOpSpan* span = segment->head();
- do {
- const SkOpPtT* ptT = span->ptT();
- if (ptT->debugMatchID(id)) {
- return ptT;
- }
- } while ((span = span->next()->upCastable()));
- const SkOpSpanBase* tail = segment->tail();
- const SkOpPtT* ptT = tail->ptT();
- if (ptT->debugMatchID(id)) {
- return ptT;
- }
- segment = segment->next();
- }
- } while ((contour = contour->next()));
- return nullptr;
- }
- const SkOpSegment* SkOpGlobalState::debugSegment(int id) const {
- const SkOpContour* contour = fContourHead;
- do {
- const SkOpSegment* segment = contour->first();
- while (segment) {
- if (segment->debugID() == id) {
- return segment;
- }
- segment = segment->next();
- }
- } while ((contour = contour->next()));
- return nullptr;
- }
- const SkOpSpanBase* SkOpGlobalState::debugSpan(int id) const {
- const SkOpContour* contour = fContourHead;
- do {
- const SkOpSegment* segment = contour->first();
- while (segment) {
- const SkOpSpan* span = segment->head();
- do {
- if (span->debugID() == id) {
- return span;
- }
- } while ((span = span->next()->upCastable()));
- const SkOpSpanBase* tail = segment->tail();
- if (tail->debugID() == id) {
- return tail;
- }
- segment = segment->next();
- }
- } while ((contour = contour->next()));
- return nullptr;
- }
- #endif
- char SkTCoincident::dumpIsCoincidentStr() const {
- if (!!fMatch != fMatch) {
- return '?';
- }
- return fMatch ? '*' : 0;
- }
- void SkTCoincident::dump() const {
- SkDebugf("t=%1.9g pt=(%1.9g,%1.9g)%s\n", fPerpT, fPerpPt.fX, fPerpPt.fY,
- fMatch ? " match" : "");
- }
- #ifdef SK_DEBUG
- const SkTSpan* SkTSect::debugSpan(int id) const {
- const SkTSpan* test = fHead;
- do {
- if (test->debugID() == id) {
- return test;
- }
- } while ((test = test->next()));
- return nullptr;
- }
- const SkTSpan* SkTSect::debugT(double t) const {
- const SkTSpan* test = fHead;
- const SkTSpan* closest = nullptr;
- double bestDist = DBL_MAX;
- do {
- if (between(test->fStartT, t, test->fEndT)) {
- return test;
- }
- double testDist = SkTMin(fabs(test->fStartT - t), fabs(test->fEndT - t));
- if (bestDist > testDist) {
- bestDist = testDist;
- closest = test;
- }
- } while ((test = test->next()));
- SkASSERT(closest);
- return closest;
- }
- #endif
- void SkTSect::dump() const {
- dumpCommon(fHead);
- }
- extern int gDumpTSectNum;
- void SkTSect::dumpBoth(SkTSect* opp) const {
- #if DEBUG_T_SECT_DUMP <= 2
- #if DEBUG_T_SECT_DUMP == 2
- SkDebugf("%d ", ++gDumpTSectNum);
- #endif
- this->dump();
- SkDebugf("\n");
- opp->dump();
- SkDebugf("\n");
- #elif DEBUG_T_SECT_DUMP == 3
- SkDebugf("<div id=\"sect%d\">\n", ++gDumpTSectNum);
- if (this->fHead) {
- this->dumpCurves();
- }
- if (opp->fHead) {
- opp->dumpCurves();
- }
- SkDebugf("</div>\n\n");
- #endif
- }
- void SkTSect::dumpBounded(int id) const {
- #ifdef SK_DEBUG
- const SkTSpan* bounded = debugSpan(id);
- if (!bounded) {
- SkDebugf("no span matches %d\n", id);
- return;
- }
- const SkTSpan* test = bounded->debugOpp()->fHead;
- do {
- if (test->findOppSpan(bounded)) {
- test->dump();
- SkDebugf(" ");
- }
- } while ((test = test->next()));
- SkDebugf("\n");
- #endif
- }
- void SkTSect::dumpBounds() const {
- const SkTSpan* test = fHead;
- do {
- test->dumpBounds();
- } while ((test = test->next()));
- }
- void SkTSect::dumpCoin() const {
- dumpCommon(fCoincident);
- }
- void SkTSect::dumpCoinCurves() const {
- dumpCommonCurves(fCoincident);
- }
- void SkTSect::dumpCommon(const SkTSpan* test) const {
- SkDebugf("id=%d", debugID());
- if (!test) {
- SkDebugf(" (empty)");
- return;
- }
- do {
- SkDebugf(" ");
- test->dump();
- } while ((test = test->next()));
- }
- void SkTSect::dumpCommonCurves(const SkTSpan* test) const {
- #if DEBUG_T_SECT
- do {
- test->fPart->dumpID(test->debugID());
- } while ((test = test->next()));
- #endif
- }
- void SkTSect::dumpCurves() const {
- dumpCommonCurves(fHead);
- }
- #ifdef SK_DEBUG
- const SkTSpan* SkTSpan::debugSpan(int id) const {
- return fDebugSect->debugSpan(id);
- }
- const SkTSpan* SkTSpan::debugT(double t) const {
- return fDebugSect->debugT(t);
- }
- #endif
- void SkTSpan::dumpAll() const {
- dumpID();
- SkDebugf("=(%g,%g) [", fStartT, fEndT);
- const SkTSpanBounded* testBounded = fBounded;
- while (testBounded) {
- const SkTSpan* span = testBounded->fBounded;
- const SkTSpanBounded* next = testBounded->fNext;
- span->dumpID();
- SkDebugf("=(%g,%g)", span->fStartT, span->fEndT);
- if (next) {
- SkDebugf(" ");
- }
- testBounded = next;
- }
- SkDebugf("]\n");
- }
- void SkTSpan::dump() const {
- dumpID();
- SkDebugf("=(%g,%g) [", fStartT, fEndT);
- const SkTSpanBounded* testBounded = fBounded;
- while (testBounded) {
- const SkTSpan* span = testBounded->fBounded;
- const SkTSpanBounded* next = testBounded->fNext;
- span->dumpID();
- if (next) {
- SkDebugf(",");
- }
- testBounded = next;
- }
- SkDebugf("]");
- }
- void SkTSpan::dumpBounded(int id) const {
- SkDEBUGCODE(fDebugSect->dumpBounded(id));
- }
- void SkTSpan::dumpBounds() const {
- dumpID();
- SkDebugf(" bounds=(%1.9g,%1.9g, %1.9g,%1.9g) boundsMax=%1.9g%s\n",
- fBounds.fLeft, fBounds.fTop, fBounds.fRight, fBounds.fBottom, fBoundsMax,
- fCollapsed ? " collapsed" : "");
- }
- void SkTSpan::dumpCoin() const {
- dumpID();
- SkDebugf(" coinStart ");
- fCoinStart.dump();
- SkDebugf(" coinEnd ");
- fCoinEnd.dump();
- }
- void SkTSpan::dumpID() const {
- char cS = fCoinStart.dumpIsCoincidentStr();
- if (cS) {
- SkDebugf("%c", cS);
- }
- SkDebugf("%d", debugID());
- char cE = fCoinEnd.dumpIsCoincidentStr();
- if (cE) {
- SkDebugf("%c", cE);
- }
- }
- #if DEBUG_T_SECT_DUMP > 1
- int gDumpTSectNum;
- #endif
- // global path dumps for msvs Visual Studio 17 to use from Immediate Window
- void Dump(const SkOpContour& contour) {
- contour.dump();
- }
- void DumpAll(const SkOpContour& contour) {
- contour.dumpAll();
- }
- void DumpAngles(const SkOpContour& contour) {
- contour.dumpAngles();
- }
- void DumpContours(const SkOpContour& contour) {
- contour.dumpContours();
- }
- void DumpContoursAll(const SkOpContour& contour) {
- contour.dumpContoursAll();
- }
- void DumpContoursAngles(const SkOpContour& contour) {
- contour.dumpContoursAngles();
- }
- void DumpContoursPts(const SkOpContour& contour) {
- contour.dumpContoursPts();
- }
- void DumpContoursPt(const SkOpContour& contour, int segmentID) {
- contour.dumpContoursPt(segmentID);
- }
- void DumpContoursSegment(const SkOpContour& contour, int segmentID) {
- contour.dumpContoursSegment(segmentID);
- }
- void DumpContoursSpan(const SkOpContour& contour, int segmentID) {
- contour.dumpContoursSpan(segmentID);
- }
- void DumpContoursSpans(const SkOpContour& contour) {
- contour.dumpContoursSpans();
- }
- void DumpPt(const SkOpContour& contour, int pt) {
- contour.dumpPt(pt);
- }
- void DumpPts(const SkOpContour& contour, const char* prefix) {
- contour.dumpPts(prefix);
- }
- void DumpSegment(const SkOpContour& contour, int seg) {
- contour.dumpSegment(seg);
- }
- void DumpSegments(const SkOpContour& contour, const char* prefix, SkPathOp op) {
- contour.dumpSegments(prefix, op);
- }
- void DumpSpan(const SkOpContour& contour, int span) {
- contour.dumpSpan(span);
- }
- void DumpSpans(const SkOpContour& contour ) {
- contour.dumpSpans();
- }
- void Dump(const SkOpSegment& segment) {
- segment.dump();
- }
- void DumpAll(const SkOpSegment& segment) {
- segment.dumpAll();
- }
- void DumpAngles(const SkOpSegment& segment) {
- segment.dumpAngles();
- }
- void DumpCoin(const SkOpSegment& segment) {
- segment.dumpCoin();
- }
- void DumpPts(const SkOpSegment& segment, const char* prefix) {
- segment.dumpPts(prefix);
- }
- void Dump(const SkOpPtT& ptT) {
- ptT.dump();
- }
- void DumpAll(const SkOpPtT& ptT) {
- ptT.dumpAll();
- }
- void Dump(const SkOpSpanBase& spanBase) {
- spanBase.dump();
- }
- void DumpCoin(const SkOpSpanBase& spanBase) {
- spanBase.dumpCoin();
- }
- void DumpAll(const SkOpSpanBase& spanBase) {
- spanBase.dumpAll();
- }
- void DumpCoin(const SkOpSpan& span) {
- span.dumpCoin();
- }
- bool DumpSpan(const SkOpSpan& span) {
- return span.dumpSpan();
- }
- void Dump(const SkDConic& conic) {
- conic.dump();
- }
- void DumpID(const SkDConic& conic, int id) {
- conic.dumpID(id);
- }
- void Dump(const SkDCubic& cubic) {
- cubic.dump();
- }
- void DumpID(const SkDCubic& cubic, int id) {
- cubic.dumpID(id);
- }
- void Dump(const SkDLine& line) {
- line.dump();
- }
- void DumpID(const SkDLine& line, int id) {
- line.dumpID(id);
- }
- void Dump(const SkDQuad& quad) {
- quad.dump();
- }
- void DumpID(const SkDQuad& quad, int id) {
- quad.dumpID(id);
- }
- void Dump(const SkDPoint& point) {
- point.dump();
- }
- void Dump(const SkOpAngle& angle) {
- angle.dump();
- }
|