0a67198990
Pathops uses a template to intersect a pair of curves. This generates six copies: quad/quad, quad/conic, quad/cubic, conic/conic, conic/cubic, cubic/cubic. This CL rewrites the template to generate a single copy, and leverages a new abstract class, SkTCurve, to dispatch to one of SkTQuad, SkTConic, or SkTCubic. These classes are thin wrappers on the existing double curves classes SkDQuad, SkDConic, and SkDCubic, which do work. Kevin's BuildStats bot says this saves around 180K on the release build. Running pathops_unittest shows no significant performance difference, and the smaller version may be slightly faster. Bug: skia: Change-Id: I17f94fd57a317035bc105cd43a06be6da9541cb6 Reviewed-on: https://skia-review.googlesource.com/c/161146 Reviewed-by: Mike Reed <reed@google.com> Reviewed-by: Jim Van Verth <jvanverth@google.com> Commit-Queue: Cary Clark <caryclark@skia.org>
1762 lines
55 KiB
C++
1762 lines
55 KiB
C++
/*
|
|
* 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 "PathOpsDebug.h"
|
|
#include "PathOpsTSectDebug.h"
|
|
#include "SkOpCoincidence.h"
|
|
#include "SkOpContour.h"
|
|
#include "SkIntersectionHelper.h"
|
|
#include "SkMutex.h"
|
|
#include "SkOpSegment.h"
|
|
#include "SkString.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");
|
|
}
|
|
|
|
namespace SkOpDebug {
|
|
|
|
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);
|
|
}
|
|
|
|
} // namespace SkPathOpsDebug
|
|
|
|
#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()));
|
|
}
|
|
|
|
template <typename TCurve, typename OppCurve>
|
|
const SkTSpan<TCurve, OppCurve>* DebugSpan(const SkTSect<TCurve, OppCurve>* sect, int id) {
|
|
return sect->debugSpan(id);
|
|
}
|
|
|
|
void DontCallDebugSpan(int id);
|
|
void DontCallDebugSpan(int id) { // exists to instantiate the templates
|
|
#if !PATH_OP_COMPILE_FOR_SIZE
|
|
SkDQuad quad;
|
|
SkDConic conic;
|
|
SkDCubic cubic;
|
|
SkTSect<SkDQuad, SkDQuad> q1q2(quad SkDEBUGPARAMS(nullptr) PATH_OPS_DEBUG_T_SECT_PARAMS(1));
|
|
SkTSect<SkDQuad, SkDConic> q1k2(quad SkDEBUGPARAMS(nullptr) PATH_OPS_DEBUG_T_SECT_PARAMS(1));
|
|
SkTSect<SkDQuad, SkDCubic> q1c2(quad SkDEBUGPARAMS(nullptr) PATH_OPS_DEBUG_T_SECT_PARAMS(1));
|
|
SkTSect<SkDConic, SkDQuad> k1q2(conic SkDEBUGPARAMS(nullptr) PATH_OPS_DEBUG_T_SECT_PARAMS(1));
|
|
SkTSect<SkDConic, SkDConic> k1k2(conic SkDEBUGPARAMS(nullptr) PATH_OPS_DEBUG_T_SECT_PARAMS(1));
|
|
SkTSect<SkDConic, SkDCubic> k1c2(conic SkDEBUGPARAMS(nullptr) PATH_OPS_DEBUG_T_SECT_PARAMS(1));
|
|
SkTSect<SkDCubic, SkDQuad> c1q2(cubic SkDEBUGPARAMS(nullptr) PATH_OPS_DEBUG_T_SECT_PARAMS(1));
|
|
SkTSect<SkDCubic, SkDConic> c1k2(cubic SkDEBUGPARAMS(nullptr) PATH_OPS_DEBUG_T_SECT_PARAMS(1));
|
|
SkTSect<SkDCubic, SkDCubic> c1c2(cubic SkDEBUGPARAMS(nullptr) PATH_OPS_DEBUG_T_SECT_PARAMS(1));
|
|
DebugSpan(&q1q2, id);
|
|
DebugSpan(&q1k2, id);
|
|
DebugSpan(&q1c2, id);
|
|
DebugSpan(&k1q2, id);
|
|
DebugSpan(&k1k2, id);
|
|
DebugSpan(&k1c2, id);
|
|
DebugSpan(&c1q2, id);
|
|
DebugSpan(&c1k2, id);
|
|
DebugSpan(&c1c2, id);
|
|
#endif
|
|
}
|
|
|
|
template <typename TCurve, typename OppCurve>
|
|
const SkTSpan<TCurve, OppCurve>* DebugT(const SkTSect<TCurve, OppCurve>* sect, double t) {
|
|
return sect->debugT(t);
|
|
}
|
|
|
|
void DontCallDebugT(double t);
|
|
void DontCallDebugT(double t) { // exists to instantiate the templates
|
|
#if !PATH_OP_COMPILE_FOR_SIZE
|
|
SkDQuad quad;
|
|
SkDConic conic;
|
|
SkDCubic cubic;
|
|
SkTSect<SkDQuad, SkDQuad> q1q2(quad SkDEBUGPARAMS(nullptr) PATH_OPS_DEBUG_T_SECT_PARAMS(1));
|
|
SkTSect<SkDQuad, SkDConic> q1k2(quad SkDEBUGPARAMS(nullptr) PATH_OPS_DEBUG_T_SECT_PARAMS(1));
|
|
SkTSect<SkDQuad, SkDCubic> q1c2(quad SkDEBUGPARAMS(nullptr) PATH_OPS_DEBUG_T_SECT_PARAMS(1));
|
|
SkTSect<SkDConic, SkDQuad> k1q2(conic SkDEBUGPARAMS(nullptr) PATH_OPS_DEBUG_T_SECT_PARAMS(1));
|
|
SkTSect<SkDConic, SkDConic> k1k2(conic SkDEBUGPARAMS(nullptr) PATH_OPS_DEBUG_T_SECT_PARAMS(1));
|
|
SkTSect<SkDConic, SkDCubic> k1c2(conic SkDEBUGPARAMS(nullptr) PATH_OPS_DEBUG_T_SECT_PARAMS(1));
|
|
SkTSect<SkDCubic, SkDQuad> c1q2(cubic SkDEBUGPARAMS(nullptr) PATH_OPS_DEBUG_T_SECT_PARAMS(1));
|
|
SkTSect<SkDCubic, SkDConic> c1k2(cubic SkDEBUGPARAMS(nullptr) PATH_OPS_DEBUG_T_SECT_PARAMS(1));
|
|
SkTSect<SkDCubic, SkDCubic> c1c2(cubic SkDEBUGPARAMS(nullptr) PATH_OPS_DEBUG_T_SECT_PARAMS(1));
|
|
DebugT(&q1q2, t);
|
|
DebugT(&q1k2, t);
|
|
DebugT(&q1c2, t);
|
|
DebugT(&k1q2, t);
|
|
DebugT(&k1k2, t);
|
|
DebugT(&k1c2, t);
|
|
DebugT(&c1q2, t);
|
|
DebugT(&c1k2, t);
|
|
DebugT(&c1c2, t);
|
|
#endif
|
|
}
|
|
|
|
template <typename TCurve, typename OppCurve>
|
|
void Dump(const SkTSect<TCurve, OppCurve>* sect) {
|
|
sect->dump();
|
|
}
|
|
|
|
void DontCallDumpTSect();
|
|
void DontCallDumpTSect() { // exists to instantiate the templates
|
|
#if !PATH_OP_COMPILE_FOR_SIZE
|
|
SkDQuad quad;
|
|
SkDConic conic;
|
|
SkDCubic cubic;
|
|
SkTSect<SkDQuad, SkDQuad> q1q2(quad SkDEBUGPARAMS(nullptr) PATH_OPS_DEBUG_T_SECT_PARAMS(1));
|
|
SkTSect<SkDQuad, SkDConic> q1k2(quad SkDEBUGPARAMS(nullptr) PATH_OPS_DEBUG_T_SECT_PARAMS(1));
|
|
SkTSect<SkDQuad, SkDCubic> q1c2(quad SkDEBUGPARAMS(nullptr) PATH_OPS_DEBUG_T_SECT_PARAMS(1));
|
|
SkTSect<SkDConic, SkDQuad> k1q2(conic SkDEBUGPARAMS(nullptr) PATH_OPS_DEBUG_T_SECT_PARAMS(1));
|
|
SkTSect<SkDConic, SkDConic> k1k2(conic SkDEBUGPARAMS(nullptr) PATH_OPS_DEBUG_T_SECT_PARAMS(1));
|
|
SkTSect<SkDConic, SkDCubic> k1c2(conic SkDEBUGPARAMS(nullptr) PATH_OPS_DEBUG_T_SECT_PARAMS(1));
|
|
SkTSect<SkDCubic, SkDQuad> c1q2(cubic SkDEBUGPARAMS(nullptr) PATH_OPS_DEBUG_T_SECT_PARAMS(1));
|
|
SkTSect<SkDCubic, SkDConic> c1k2(cubic SkDEBUGPARAMS(nullptr) PATH_OPS_DEBUG_T_SECT_PARAMS(1));
|
|
SkTSect<SkDCubic, SkDCubic> c1c2(cubic SkDEBUGPARAMS(nullptr) PATH_OPS_DEBUG_T_SECT_PARAMS(1));
|
|
Dump(&q1q2);
|
|
Dump(&q1k2);
|
|
Dump(&q1c2);
|
|
Dump(&k1q2);
|
|
Dump(&k1k2);
|
|
Dump(&k1c2);
|
|
Dump(&c1q2);
|
|
Dump(&c1k2);
|
|
Dump(&c1c2);
|
|
#endif
|
|
}
|
|
|
|
template <typename TCurve, typename OppCurve>
|
|
void DumpBoth(SkTSect<TCurve, OppCurve>* sect1, SkTSect<OppCurve, TCurve>* sect2) {
|
|
sect1->dumpBoth(sect2);
|
|
}
|
|
|
|
void DontCallDumpBoth();
|
|
void DontCallDumpBoth() { // exists to instantiate the templates
|
|
#if !PATH_OP_COMPILE_FOR_SIZE
|
|
SkDQuad quad;
|
|
SkDConic conic;
|
|
SkDCubic cubic;
|
|
SkTSect<SkDQuad, SkDQuad> q1q2(quad SkDEBUGPARAMS(nullptr) PATH_OPS_DEBUG_T_SECT_PARAMS(1));
|
|
SkTSect<SkDQuad, SkDConic> q1k2(quad SkDEBUGPARAMS(nullptr) PATH_OPS_DEBUG_T_SECT_PARAMS(1));
|
|
SkTSect<SkDQuad, SkDCubic> q1c2(quad SkDEBUGPARAMS(nullptr) PATH_OPS_DEBUG_T_SECT_PARAMS(1));
|
|
SkTSect<SkDConic, SkDQuad> k1q2(conic SkDEBUGPARAMS(nullptr) PATH_OPS_DEBUG_T_SECT_PARAMS(1));
|
|
SkTSect<SkDConic, SkDConic> k1k2(conic SkDEBUGPARAMS(nullptr) PATH_OPS_DEBUG_T_SECT_PARAMS(1));
|
|
SkTSect<SkDConic, SkDCubic> k1c2(conic SkDEBUGPARAMS(nullptr) PATH_OPS_DEBUG_T_SECT_PARAMS(1));
|
|
SkTSect<SkDCubic, SkDQuad> c1q2(cubic SkDEBUGPARAMS(nullptr) PATH_OPS_DEBUG_T_SECT_PARAMS(1));
|
|
SkTSect<SkDCubic, SkDConic> c1k2(cubic SkDEBUGPARAMS(nullptr) PATH_OPS_DEBUG_T_SECT_PARAMS(1));
|
|
SkTSect<SkDCubic, SkDCubic> c1c2(cubic SkDEBUGPARAMS(nullptr) PATH_OPS_DEBUG_T_SECT_PARAMS(1));
|
|
DumpBoth(&q1q2, &q1q2);
|
|
DumpBoth(&q1k2, &k1q2);
|
|
DumpBoth(&q1c2, &c1q2);
|
|
DumpBoth(&k1q2, &q1k2);
|
|
DumpBoth(&k1k2, &k1k2);
|
|
DumpBoth(&k1c2, &c1k2);
|
|
DumpBoth(&c1q2, &q1c2);
|
|
DumpBoth(&c1k2, &k1c2);
|
|
DumpBoth(&c1c2, &c1c2);
|
|
#endif
|
|
}
|
|
|
|
template <typename TCurve, typename OppCurve>
|
|
void DumpBounded(SkTSect<TCurve, OppCurve>* sect1, int id) {
|
|
sect1->dumpBounded(id);
|
|
}
|
|
|
|
void DontCallDumpBounded();
|
|
void DontCallDumpBounded() {
|
|
#if !PATH_OP_COMPILE_FOR_SIZE
|
|
SkDQuad quad;
|
|
SkDConic conic;
|
|
SkDCubic cubic;
|
|
SkTSect<SkDQuad, SkDQuad> q1q2(quad SkDEBUGPARAMS(nullptr) PATH_OPS_DEBUG_T_SECT_PARAMS(1));
|
|
SkTSect<SkDQuad, SkDConic> q1k2(quad SkDEBUGPARAMS(nullptr) PATH_OPS_DEBUG_T_SECT_PARAMS(1));
|
|
SkTSect<SkDQuad, SkDCubic> q1c2(quad SkDEBUGPARAMS(nullptr) PATH_OPS_DEBUG_T_SECT_PARAMS(1));
|
|
SkTSect<SkDConic, SkDQuad> k1q2(conic SkDEBUGPARAMS(nullptr) PATH_OPS_DEBUG_T_SECT_PARAMS(1));
|
|
SkTSect<SkDConic, SkDConic> k1k2(conic SkDEBUGPARAMS(nullptr) PATH_OPS_DEBUG_T_SECT_PARAMS(1));
|
|
SkTSect<SkDConic, SkDCubic> k1c2(conic SkDEBUGPARAMS(nullptr) PATH_OPS_DEBUG_T_SECT_PARAMS(1));
|
|
SkTSect<SkDCubic, SkDQuad> c1q2(cubic SkDEBUGPARAMS(nullptr) PATH_OPS_DEBUG_T_SECT_PARAMS(1));
|
|
SkTSect<SkDCubic, SkDConic> c1k2(cubic SkDEBUGPARAMS(nullptr) PATH_OPS_DEBUG_T_SECT_PARAMS(1));
|
|
SkTSect<SkDCubic, SkDCubic> c1c2(cubic SkDEBUGPARAMS(nullptr) PATH_OPS_DEBUG_T_SECT_PARAMS(1));
|
|
DumpBounded(&q1q2, 0);
|
|
DumpBounded(&q1k2, 0);
|
|
DumpBounded(&q1c2, 0);
|
|
DumpBounded(&k1q2, 0);
|
|
DumpBounded(&k1k2, 0);
|
|
DumpBounded(&k1c2, 0);
|
|
DumpBounded(&c1q2, 0);
|
|
DumpBounded(&c1k2, 0);
|
|
DumpBounded(&c1c2, 0);
|
|
#endif
|
|
}
|
|
|
|
template <typename TCurve, typename OppCurve>
|
|
void DumpBounds(SkTSect<TCurve, OppCurve>* sect1) {
|
|
sect1->dumpBounds();
|
|
}
|
|
|
|
void DontCallDumpBounds();
|
|
void DontCallDumpBounds() {
|
|
#if !PATH_OP_COMPILE_FOR_SIZE
|
|
SkDQuad quad;
|
|
SkDConic conic;
|
|
SkDCubic cubic;
|
|
SkTSect<SkDQuad, SkDQuad> q1q2(quad SkDEBUGPARAMS(nullptr) PATH_OPS_DEBUG_T_SECT_PARAMS(1));
|
|
SkTSect<SkDQuad, SkDConic> q1k2(quad SkDEBUGPARAMS(nullptr) PATH_OPS_DEBUG_T_SECT_PARAMS(1));
|
|
SkTSect<SkDQuad, SkDCubic> q1c2(quad SkDEBUGPARAMS(nullptr) PATH_OPS_DEBUG_T_SECT_PARAMS(1));
|
|
SkTSect<SkDConic, SkDQuad> k1q2(conic SkDEBUGPARAMS(nullptr) PATH_OPS_DEBUG_T_SECT_PARAMS(1));
|
|
SkTSect<SkDConic, SkDConic> k1k2(conic SkDEBUGPARAMS(nullptr) PATH_OPS_DEBUG_T_SECT_PARAMS(1));
|
|
SkTSect<SkDConic, SkDCubic> k1c2(conic SkDEBUGPARAMS(nullptr) PATH_OPS_DEBUG_T_SECT_PARAMS(1));
|
|
SkTSect<SkDCubic, SkDQuad> c1q2(cubic SkDEBUGPARAMS(nullptr) PATH_OPS_DEBUG_T_SECT_PARAMS(1));
|
|
SkTSect<SkDCubic, SkDConic> c1k2(cubic SkDEBUGPARAMS(nullptr) PATH_OPS_DEBUG_T_SECT_PARAMS(1));
|
|
SkTSect<SkDCubic, SkDCubic> c1c2(cubic SkDEBUGPARAMS(nullptr) PATH_OPS_DEBUG_T_SECT_PARAMS(1));
|
|
DumpBounds(&q1q2);
|
|
DumpBounds(&q1k2);
|
|
DumpBounds(&q1c2);
|
|
DumpBounds(&k1q2);
|
|
DumpBounds(&k1k2);
|
|
DumpBounds(&k1c2);
|
|
DumpBounds(&c1q2);
|
|
DumpBounds(&c1k2);
|
|
DumpBounds(&c1c2);
|
|
#endif
|
|
}
|
|
|
|
template <typename TCurve, typename OppCurve>
|
|
void DumpCoin(SkTSect<TCurve, OppCurve>* sect1) {
|
|
sect1->dumpCoin();
|
|
}
|
|
|
|
void DontCallDumpCoin();
|
|
void DontCallDumpCoin() { // exists to instantiate the templates
|
|
#if !PATH_OP_COMPILE_FOR_SIZE
|
|
SkDQuad quad;
|
|
SkDConic conic;
|
|
SkDCubic cubic;
|
|
SkTSect<SkDQuad, SkDQuad> q1q2(quad SkDEBUGPARAMS(nullptr) PATH_OPS_DEBUG_T_SECT_PARAMS(1));
|
|
SkTSect<SkDQuad, SkDConic> q1k2(quad SkDEBUGPARAMS(nullptr) PATH_OPS_DEBUG_T_SECT_PARAMS(1));
|
|
SkTSect<SkDQuad, SkDCubic> q1c2(quad SkDEBUGPARAMS(nullptr) PATH_OPS_DEBUG_T_SECT_PARAMS(1));
|
|
SkTSect<SkDConic, SkDQuad> k1q2(conic SkDEBUGPARAMS(nullptr) PATH_OPS_DEBUG_T_SECT_PARAMS(1));
|
|
SkTSect<SkDConic, SkDConic> k1k2(conic SkDEBUGPARAMS(nullptr) PATH_OPS_DEBUG_T_SECT_PARAMS(1));
|
|
SkTSect<SkDConic, SkDCubic> k1c2(conic SkDEBUGPARAMS(nullptr) PATH_OPS_DEBUG_T_SECT_PARAMS(1));
|
|
SkTSect<SkDCubic, SkDQuad> c1q2(cubic SkDEBUGPARAMS(nullptr) PATH_OPS_DEBUG_T_SECT_PARAMS(1));
|
|
SkTSect<SkDCubic, SkDConic> c1k2(cubic SkDEBUGPARAMS(nullptr) PATH_OPS_DEBUG_T_SECT_PARAMS(1));
|
|
SkTSect<SkDCubic, SkDCubic> c1c2(cubic SkDEBUGPARAMS(nullptr) PATH_OPS_DEBUG_T_SECT_PARAMS(1));
|
|
DumpCoin(&q1q2);
|
|
DumpCoin(&q1k2);
|
|
DumpCoin(&q1c2);
|
|
DumpCoin(&k1q2);
|
|
DumpCoin(&k1k2);
|
|
DumpCoin(&k1c2);
|
|
DumpCoin(&c1q2);
|
|
DumpCoin(&c1k2);
|
|
DumpCoin(&c1c2);
|
|
#endif
|
|
}
|
|
|
|
template <typename TCurve, typename OppCurve>
|
|
void DumpCoinCurves(SkTSect<TCurve, OppCurve>* sect1) {
|
|
sect1->dumpCoinCurves();
|
|
}
|
|
|
|
void DontCallDumpCoinCurves();
|
|
void DontCallDumpCoinCurves() { // exists to instantiate the templates
|
|
#if !PATH_OP_COMPILE_FOR_SIZE
|
|
SkDQuad quad;
|
|
SkDConic conic;
|
|
SkDCubic cubic;
|
|
SkTSect<SkDQuad, SkDQuad> q1q2(quad SkDEBUGPARAMS(nullptr) PATH_OPS_DEBUG_T_SECT_PARAMS(1));
|
|
SkTSect<SkDQuad, SkDConic> q1k2(quad SkDEBUGPARAMS(nullptr) PATH_OPS_DEBUG_T_SECT_PARAMS(1));
|
|
SkTSect<SkDQuad, SkDCubic> q1c2(quad SkDEBUGPARAMS(nullptr) PATH_OPS_DEBUG_T_SECT_PARAMS(1));
|
|
SkTSect<SkDConic, SkDQuad> k1q2(conic SkDEBUGPARAMS(nullptr) PATH_OPS_DEBUG_T_SECT_PARAMS(1));
|
|
SkTSect<SkDConic, SkDConic> k1k2(conic SkDEBUGPARAMS(nullptr) PATH_OPS_DEBUG_T_SECT_PARAMS(1));
|
|
SkTSect<SkDConic, SkDCubic> k1c2(conic SkDEBUGPARAMS(nullptr) PATH_OPS_DEBUG_T_SECT_PARAMS(1));
|
|
SkTSect<SkDCubic, SkDQuad> c1q2(cubic SkDEBUGPARAMS(nullptr) PATH_OPS_DEBUG_T_SECT_PARAMS(1));
|
|
SkTSect<SkDCubic, SkDConic> c1k2(cubic SkDEBUGPARAMS(nullptr) PATH_OPS_DEBUG_T_SECT_PARAMS(1));
|
|
SkTSect<SkDCubic, SkDCubic> c1c2(cubic SkDEBUGPARAMS(nullptr) PATH_OPS_DEBUG_T_SECT_PARAMS(1));
|
|
DumpCoinCurves(&q1q2);
|
|
DumpCoinCurves(&q1k2);
|
|
DumpCoinCurves(&q1c2);
|
|
DumpCoinCurves(&k1q2);
|
|
DumpCoinCurves(&k1k2);
|
|
DumpCoinCurves(&k1c2);
|
|
DumpCoinCurves(&c1q2);
|
|
DumpCoinCurves(&c1k2);
|
|
DumpCoinCurves(&c1c2);
|
|
#endif
|
|
}
|
|
|
|
template <typename TCurve, typename OppCurve>
|
|
void DumpCurves(const SkTSect<TCurve, OppCurve>* sect) {
|
|
sect->dumpCurves();
|
|
}
|
|
|
|
void DontCallDumpCurves();
|
|
void DontCallDumpCurves() { // exists to instantiate the templates
|
|
#if !PATH_OP_COMPILE_FOR_SIZE
|
|
SkDQuad quad;
|
|
SkDConic conic;
|
|
SkDCubic cubic;
|
|
SkTSect<SkDQuad, SkDQuad> q1q2(quad SkDEBUGPARAMS(nullptr) PATH_OPS_DEBUG_T_SECT_PARAMS(1));
|
|
SkTSect<SkDQuad, SkDConic> q1k2(quad SkDEBUGPARAMS(nullptr) PATH_OPS_DEBUG_T_SECT_PARAMS(1));
|
|
SkTSect<SkDQuad, SkDCubic> q1c2(quad SkDEBUGPARAMS(nullptr) PATH_OPS_DEBUG_T_SECT_PARAMS(1));
|
|
SkTSect<SkDConic, SkDQuad> k1q2(conic SkDEBUGPARAMS(nullptr) PATH_OPS_DEBUG_T_SECT_PARAMS(1));
|
|
SkTSect<SkDConic, SkDConic> k1k2(conic SkDEBUGPARAMS(nullptr) PATH_OPS_DEBUG_T_SECT_PARAMS(1));
|
|
SkTSect<SkDConic, SkDCubic> k1c2(conic SkDEBUGPARAMS(nullptr) PATH_OPS_DEBUG_T_SECT_PARAMS(1));
|
|
SkTSect<SkDCubic, SkDQuad> c1q2(cubic SkDEBUGPARAMS(nullptr) PATH_OPS_DEBUG_T_SECT_PARAMS(1));
|
|
SkTSect<SkDCubic, SkDConic> c1k2(cubic SkDEBUGPARAMS(nullptr) PATH_OPS_DEBUG_T_SECT_PARAMS(1));
|
|
SkTSect<SkDCubic, SkDCubic> c1c2(cubic SkDEBUGPARAMS(nullptr) PATH_OPS_DEBUG_T_SECT_PARAMS(1));
|
|
DumpCurves(&q1q2);
|
|
DumpCurves(&q1k2);
|
|
DumpCurves(&q1c2);
|
|
DumpCurves(&k1q2);
|
|
DumpCurves(&k1k2);
|
|
DumpCurves(&k1c2);
|
|
DumpCurves(&c1q2);
|
|
DumpCurves(&c1k2);
|
|
DumpCurves(&c1c2);
|
|
#endif
|
|
}
|
|
|
|
template <typename TCurve, typename OppCurve>
|
|
void Dump(const SkTSpan<TCurve, OppCurve>* span) {
|
|
span->dump();
|
|
}
|
|
|
|
void DontCallDumpTSpan();
|
|
void DontCallDumpTSpan() { // exists to instantiate the templates
|
|
#if !PATH_OP_COMPILE_FOR_SIZE
|
|
SkArenaAlloc heap(0);
|
|
SkDQuad quad;
|
|
SkTSpan<SkDQuad, SkDQuad> q1q2(quad, heap); q1q2.debugInit();
|
|
SkTSpan<SkDQuad, SkDConic> q1k2(quad, heap); q1k2.debugInit();
|
|
SkTSpan<SkDQuad, SkDCubic> q1c2(quad, heap); q1c2.debugInit();
|
|
SkDConic conic;
|
|
SkTSpan<SkDConic, SkDQuad> k1q2(conic, heap); k1q2.debugInit();
|
|
SkTSpan<SkDConic, SkDConic> k1k2(conic, heap); k1k2.debugInit();
|
|
SkTSpan<SkDConic, SkDCubic> k1c2(conic, heap); k1c2.debugInit();
|
|
SkDCubic cubic;
|
|
SkTSpan<SkDCubic, SkDQuad> c1q2(cubic, heap); c1q2.debugInit();
|
|
SkTSpan<SkDCubic, SkDConic> c1k2(cubic, heap); c1k2.debugInit();
|
|
SkTSpan<SkDCubic, SkDCubic> c1c2(cubic, heap); c1c2.debugInit();
|
|
Dump(&q1q2);
|
|
Dump(&q1k2);
|
|
Dump(&q1c2);
|
|
Dump(&k1q2);
|
|
Dump(&k1k2);
|
|
Dump(&k1c2);
|
|
Dump(&c1q2);
|
|
Dump(&c1k2);
|
|
Dump(&c1c2);
|
|
#endif
|
|
}
|
|
|
|
template <typename TCurve, typename OppCurve>
|
|
void DumpAll(const SkTSpan<TCurve, OppCurve>* span) {
|
|
span->dumpAll();
|
|
}
|
|
|
|
void DontCallDumpSpanAll();
|
|
void DontCallDumpSpanAll() { // exists to instantiate the templates
|
|
#if !PATH_OP_COMPILE_FOR_SIZE
|
|
SkArenaAlloc heap(0);
|
|
SkDQuad quad;
|
|
SkTSpan<SkDQuad, SkDQuad> q1q2(quad, heap); q1q2.debugInit();
|
|
SkTSpan<SkDQuad, SkDConic> q1k2(quad, heap); q1k2.debugInit();
|
|
SkTSpan<SkDQuad, SkDCubic> q1c2(quad, heap); q1c2.debugInit();
|
|
SkDConic conic;
|
|
SkTSpan<SkDConic, SkDQuad> k1q2(conic, heap); k1q2.debugInit();
|
|
SkTSpan<SkDConic, SkDConic> k1k2(conic, heap); k1k2.debugInit();
|
|
SkTSpan<SkDConic, SkDCubic> k1c2(conic, heap); k1c2.debugInit();
|
|
SkDCubic cubic;
|
|
SkTSpan<SkDCubic, SkDQuad> c1q2(cubic, heap); c1q2.debugInit();
|
|
SkTSpan<SkDCubic, SkDConic> c1k2(cubic, heap); c1k2.debugInit();
|
|
SkTSpan<SkDCubic, SkDCubic> c1c2(cubic, heap); c1c2.debugInit();
|
|
DumpAll(&q1q2);
|
|
DumpAll(&q1k2);
|
|
DumpAll(&q1c2);
|
|
DumpAll(&k1q2);
|
|
DumpAll(&k1k2);
|
|
DumpAll(&k1c2);
|
|
DumpAll(&c1q2);
|
|
DumpAll(&c1k2);
|
|
DumpAll(&c1c2);
|
|
#endif
|
|
}
|
|
|
|
template <typename TCurve, typename OppCurve>
|
|
void DumpBounded(const SkTSpan<TCurve, OppCurve>* span) {
|
|
span->dumpBounded(0);
|
|
}
|
|
|
|
void DontCallDumpSpanBounded();
|
|
void DontCallDumpSpanBounded() { // exists to instantiate the templates
|
|
#if !PATH_OP_COMPILE_FOR_SIZE
|
|
SkArenaAlloc heap(0);
|
|
SkDQuad quad;
|
|
SkTSpan<SkDQuad, SkDQuad> q1q2(quad, heap); q1q2.debugInit();
|
|
SkTSpan<SkDQuad, SkDConic> q1k2(quad, heap); q1k2.debugInit();
|
|
SkTSpan<SkDQuad, SkDCubic> q1c2(quad, heap); q1c2.debugInit();
|
|
SkDConic conic;
|
|
SkTSpan<SkDConic, SkDQuad> k1q2(conic, heap); k1q2.debugInit();
|
|
SkTSpan<SkDConic, SkDConic> k1k2(conic, heap); k1k2.debugInit();
|
|
SkTSpan<SkDConic, SkDCubic> k1c2(conic, heap); k1c2.debugInit();
|
|
SkDCubic cubic;
|
|
SkTSpan<SkDCubic, SkDQuad> c1q2(cubic, heap); c1q2.debugInit();
|
|
SkTSpan<SkDCubic, SkDConic> c1k2(cubic, heap); c1k2.debugInit();
|
|
SkTSpan<SkDCubic, SkDCubic> c1c2(cubic, heap); c1c2.debugInit();
|
|
DumpBounded(&q1q2);
|
|
DumpBounded(&q1k2);
|
|
DumpBounded(&q1c2);
|
|
DumpBounded(&k1q2);
|
|
DumpBounded(&k1k2);
|
|
DumpBounded(&k1c2);
|
|
DumpBounded(&c1q2);
|
|
DumpBounded(&c1k2);
|
|
DumpBounded(&c1c2);
|
|
#endif
|
|
}
|
|
|
|
template <typename TCurve, typename OppCurve>
|
|
void DumpCoin(const SkTSpan<TCurve, OppCurve>* span) {
|
|
span->dumpCoin();
|
|
}
|
|
|
|
void DontCallDumpSpanCoin();
|
|
void DontCallDumpSpanCoin() { // exists to instantiate the templates
|
|
#if !PATH_OP_COMPILE_FOR_SIZE
|
|
SkArenaAlloc heap(0);
|
|
SkDQuad quad;
|
|
SkTSpan<SkDQuad, SkDQuad> q1q2(quad, heap); q1q2.debugInit();
|
|
SkTSpan<SkDQuad, SkDConic> q1k2(quad, heap); q1k2.debugInit();
|
|
SkTSpan<SkDQuad, SkDCubic> q1c2(quad, heap); q1c2.debugInit();
|
|
SkDConic conic;
|
|
SkTSpan<SkDConic, SkDQuad> k1q2(conic, heap); k1q2.debugInit();
|
|
SkTSpan<SkDConic, SkDConic> k1k2(conic, heap); k1k2.debugInit();
|
|
SkTSpan<SkDConic, SkDCubic> k1c2(conic, heap); k1c2.debugInit();
|
|
SkDCubic cubic;
|
|
SkTSpan<SkDCubic, SkDQuad> c1q2(cubic, heap); c1q2.debugInit();
|
|
SkTSpan<SkDCubic, SkDConic> c1k2(cubic, heap); c1k2.debugInit();
|
|
SkTSpan<SkDCubic, SkDCubic> c1c2(cubic, heap); c1c2.debugInit();
|
|
DumpCoin(&q1q2);
|
|
DumpCoin(&q1k2);
|
|
DumpCoin(&q1c2);
|
|
DumpCoin(&k1q2);
|
|
DumpCoin(&k1k2);
|
|
DumpCoin(&k1c2);
|
|
DumpCoin(&c1q2);
|
|
DumpCoin(&c1k2);
|
|
DumpCoin(&c1c2);
|
|
#endif
|
|
}
|
|
|
|
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
|
|
|
|
#if DEBUG_T_SECT_DUMP > 1
|
|
int gDumpTSectNum;
|
|
#endif
|
|
|
|
// global path dumps for msvs Visual Studio 17 to use from Immediate Window
|
|
namespace SkOpDebug {
|
|
|
|
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();
|
|
}
|
|
|
|
// dummy definitions to fool msvs Visual Studio 2018 Immediate Window
|
|
#define DummyDefinitions(a, b) \
|
|
\
|
|
void Dump(const SkDebugTCoincident##a##b& curve) { \
|
|
((const SkTCoincident<SkD##a, SkD##b>& ) curve).dump(); \
|
|
} \
|
|
\
|
|
void Dump(const SkDebugTSect##a##b& curve) { \
|
|
((const SkTSect<SkD##a, SkD##b>& ) curve).dump(); \
|
|
} \
|
|
\
|
|
void DumpBoth(const SkDebugTSect##a##b& curve, SkDebugTSect##a##b* opp) { \
|
|
((const SkTSect<SkD##a, SkD##b>& ) curve).dumpBoth((SkTSect<SkD##b, SkD##a>* ) opp); \
|
|
} \
|
|
\
|
|
void DumpBounded(const SkDebugTSect##a##b& curve, int id) { \
|
|
((const SkTSect<SkD##a, SkD##b>& ) curve).dumpBounded(id); \
|
|
} \
|
|
\
|
|
void DumpBounds(const SkDebugTSect##a##b& curve) { \
|
|
((const SkTSect<SkD##a, SkD##b>& ) curve).dumpBounds(); \
|
|
} \
|
|
\
|
|
void DumpCoin(const SkDebugTSect##a##b& curve) { \
|
|
((const SkTSect<SkD##a, SkD##b>& ) curve).dumpCoin(); \
|
|
} \
|
|
\
|
|
void DumpCoinCurves(const SkDebugTSect##a##b& curve) { \
|
|
((const SkTSect<SkD##a, SkD##b>& ) curve).dumpCoinCurves(); \
|
|
} \
|
|
\
|
|
void DumpCurves(const SkDebugTSect##a##b& curve) { \
|
|
((const SkTSect<SkD##a, SkD##b>& ) curve).dumpCurves(); \
|
|
} \
|
|
\
|
|
void Dump(const SkDebugTSpan##a##b& curve) { \
|
|
((const SkTSpan<SkD##a, SkD##b>& ) curve).dump(); \
|
|
} \
|
|
\
|
|
void DumpAll(const SkDebugTSpan##a##b& curve) { \
|
|
((const SkTSpan<SkD##a, SkD##b>& ) curve).dumpAll(); \
|
|
} \
|
|
\
|
|
void DumpBounded(const SkDebugTSpan##a##b& curve, int id) { \
|
|
((const SkTSpan<SkD##a, SkD##b>& ) curve).dumpBounded(id); \
|
|
} \
|
|
\
|
|
void DumpBounds(const SkDebugTSpan##a##b& curve) { \
|
|
((const SkTSpan<SkD##a, SkD##b>& ) curve).dumpBounds(); \
|
|
} \
|
|
\
|
|
void DumpCoin(const SkDebugTSpan##a##b& curve) { \
|
|
((const SkTSpan<SkD##a, SkD##b>& ) curve).dumpCoin(); \
|
|
}
|
|
|
|
#if !PATH_OP_COMPILE_FOR_SIZE
|
|
DummyDefinitions(Quad, Quad);
|
|
DummyDefinitions(Conic, Quad);
|
|
DummyDefinitions(Conic, Conic);
|
|
DummyDefinitions(Cubic, Quad);
|
|
DummyDefinitions(Cubic, Conic);
|
|
DummyDefinitions(Cubic, Cubic);
|
|
#endif
|
|
|
|
#undef DummyDefinitions
|
|
}
|