gfx/skia/trunk/src/pathops/SkOpSegment.h

Sat, 03 Jan 2015 20:18:00 +0100

author
Michael Schloh von Bennewitz <michael@schloh.com>
date
Sat, 03 Jan 2015 20:18:00 +0100
branch
TOR_BUG_3246
changeset 7
129ffea94266
permissions
-rw-r--r--

Conditionally enable double key logic according to:
private browsing mode or privacy.thirdparty.isolate preference and
implement in GetCookieStringCommon and FindCookie where it counts...
With some reservations of how to convince FindCookie users to test
condition and pass a nullptr when disabling double key logic.

michael@0 1 /*
michael@0 2 * Copyright 2012 Google Inc.
michael@0 3 *
michael@0 4 * Use of this source code is governed by a BSD-style license that can be
michael@0 5 * found in the LICENSE file.
michael@0 6 */
michael@0 7 #ifndef SkOpSegment_DEFINE
michael@0 8 #define SkOpSegment_DEFINE
michael@0 9
michael@0 10 #include "SkOpAngle.h"
michael@0 11 #include "SkOpSpan.h"
michael@0 12 #include "SkPathOpsBounds.h"
michael@0 13 #include "SkPathOpsCurve.h"
michael@0 14 #include "SkTArray.h"
michael@0 15 #include "SkTDArray.h"
michael@0 16
michael@0 17 class SkPathWriter;
michael@0 18
michael@0 19 class SkOpSegment {
michael@0 20 public:
michael@0 21 SkOpSegment() {
michael@0 22 #ifdef SK_DEBUG
michael@0 23 fID = ++SkPathOpsDebug::gSegmentID;
michael@0 24 #endif
michael@0 25 }
michael@0 26
michael@0 27 bool operator<(const SkOpSegment& rh) const {
michael@0 28 return fBounds.fTop < rh.fBounds.fTop;
michael@0 29 }
michael@0 30
michael@0 31 const SkPathOpsBounds& bounds() const {
michael@0 32 return fBounds;
michael@0 33 }
michael@0 34
michael@0 35 // OPTIMIZE
michael@0 36 // when the edges are initially walked, they don't automatically get the prior and next
michael@0 37 // edges assigned to positions t=0 and t=1. Doing that would remove the need for this check,
michael@0 38 // and would additionally remove the need for similar checks in condition edges. It would
michael@0 39 // also allow intersection code to assume end of segment intersections (maybe?)
michael@0 40 bool complete() const {
michael@0 41 int count = fTs.count();
michael@0 42 return count > 1 && fTs[0].fT == 0 && fTs[--count].fT == 1;
michael@0 43 }
michael@0 44
michael@0 45 int count() const {
michael@0 46 return fTs.count();
michael@0 47 }
michael@0 48
michael@0 49 bool done() const {
michael@0 50 SkASSERT(fDoneSpans <= fTs.count());
michael@0 51 return fDoneSpans == fTs.count();
michael@0 52 }
michael@0 53
michael@0 54 bool done(int min) const {
michael@0 55 return fTs[min].fDone;
michael@0 56 }
michael@0 57
michael@0 58 bool done(const SkOpAngle* angle) const {
michael@0 59 return done(SkMin32(angle->start(), angle->end()));
michael@0 60 }
michael@0 61
michael@0 62 // used only by partial coincidence detection
michael@0 63 SkDPoint dPtAtT(double mid) const {
michael@0 64 return (*CurveDPointAtT[SkPathOpsVerbToPoints(fVerb)])(fPts, mid);
michael@0 65 }
michael@0 66
michael@0 67 SkVector dxdy(int index) const {
michael@0 68 return (*CurveSlopeAtT[SkPathOpsVerbToPoints(fVerb)])(fPts, fTs[index].fT);
michael@0 69 }
michael@0 70
michael@0 71 SkScalar dy(int index) const {
michael@0 72 return dxdy(index).fY;
michael@0 73 }
michael@0 74
michael@0 75 bool intersected() const {
michael@0 76 return fTs.count() > 0;
michael@0 77 }
michael@0 78
michael@0 79 bool isCanceled(int tIndex) const {
michael@0 80 return fTs[tIndex].fWindValue == 0 && fTs[tIndex].fOppValue == 0;
michael@0 81 }
michael@0 82
michael@0 83 bool isConnected(int startIndex, int endIndex) const {
michael@0 84 return fTs[startIndex].fWindSum != SK_MinS32 || fTs[endIndex].fWindSum != SK_MinS32;
michael@0 85 }
michael@0 86
michael@0 87 bool isHorizontal() const {
michael@0 88 return fBounds.fTop == fBounds.fBottom;
michael@0 89 }
michael@0 90
michael@0 91 bool isVertical() const {
michael@0 92 return fBounds.fLeft == fBounds.fRight;
michael@0 93 }
michael@0 94
michael@0 95 bool isVertical(int start, int end) const {
michael@0 96 return (*CurveIsVertical[SkPathOpsVerbToPoints(fVerb)])(fPts, start, end);
michael@0 97 }
michael@0 98
michael@0 99 bool operand() const {
michael@0 100 return fOperand;
michael@0 101 }
michael@0 102
michael@0 103 int oppSign(const SkOpAngle* angle) const {
michael@0 104 SkASSERT(angle->segment() == this);
michael@0 105 return oppSign(angle->start(), angle->end());
michael@0 106 }
michael@0 107
michael@0 108 int oppSign(int startIndex, int endIndex) const {
michael@0 109 int result = startIndex < endIndex ? -fTs[startIndex].fOppValue : fTs[endIndex].fOppValue;
michael@0 110 #if DEBUG_WIND_BUMP
michael@0 111 SkDebugf("%s oppSign=%d\n", __FUNCTION__, result);
michael@0 112 #endif
michael@0 113 return result;
michael@0 114 }
michael@0 115
michael@0 116 int oppSum(int tIndex) const {
michael@0 117 return fTs[tIndex].fOppSum;
michael@0 118 }
michael@0 119
michael@0 120 int oppSum(const SkOpAngle* angle) const {
michael@0 121 int lesser = SkMin32(angle->start(), angle->end());
michael@0 122 return fTs[lesser].fOppSum;
michael@0 123 }
michael@0 124
michael@0 125 int oppValue(int tIndex) const {
michael@0 126 return fTs[tIndex].fOppValue;
michael@0 127 }
michael@0 128
michael@0 129 int oppValue(const SkOpAngle* angle) const {
michael@0 130 int lesser = SkMin32(angle->start(), angle->end());
michael@0 131 return fTs[lesser].fOppValue;
michael@0 132 }
michael@0 133
michael@0 134 const SkOpSegment* other(int index) const {
michael@0 135 return fTs[index].fOther;
michael@0 136 }
michael@0 137
michael@0 138 // was used only by right angle winding finding
michael@0 139 SkPoint ptAtT(double mid) const {
michael@0 140 return (*CurvePointAtT[SkPathOpsVerbToPoints(fVerb)])(fPts, mid);
michael@0 141 }
michael@0 142
michael@0 143 const SkPoint* pts() const {
michael@0 144 return fPts;
michael@0 145 }
michael@0 146
michael@0 147 void reset() {
michael@0 148 init(NULL, (SkPath::Verb) -1, false, false);
michael@0 149 fBounds.set(SK_ScalarMax, SK_ScalarMax, SK_ScalarMax, SK_ScalarMax);
michael@0 150 fTs.reset();
michael@0 151 }
michael@0 152
michael@0 153 void setOppXor(bool isOppXor) {
michael@0 154 fOppXor = isOppXor;
michael@0 155 }
michael@0 156
michael@0 157 void setUpWinding(int index, int endIndex, int* maxWinding, int* sumWinding) {
michael@0 158 int deltaSum = spanSign(index, endIndex);
michael@0 159 *maxWinding = *sumWinding;
michael@0 160 *sumWinding -= deltaSum;
michael@0 161 }
michael@0 162
michael@0 163 // OPTIMIZATION: mark as debugging only if used solely by tests
michael@0 164 const SkOpSpan& span(int tIndex) const {
michael@0 165 return fTs[tIndex];
michael@0 166 }
michael@0 167
michael@0 168 // OPTIMIZATION: mark as debugging only if used solely by tests
michael@0 169 const SkTDArray<SkOpSpan>& spans() const {
michael@0 170 return fTs;
michael@0 171 }
michael@0 172
michael@0 173 int spanSign(const SkOpAngle* angle) const {
michael@0 174 SkASSERT(angle->segment() == this);
michael@0 175 return spanSign(angle->start(), angle->end());
michael@0 176 }
michael@0 177
michael@0 178 int spanSign(int startIndex, int endIndex) const {
michael@0 179 int result = startIndex < endIndex ? -fTs[startIndex].fWindValue : fTs[endIndex].fWindValue;
michael@0 180 #if DEBUG_WIND_BUMP
michael@0 181 SkDebugf("%s spanSign=%d\n", __FUNCTION__, result);
michael@0 182 #endif
michael@0 183 return result;
michael@0 184 }
michael@0 185
michael@0 186 double t(int tIndex) const {
michael@0 187 return fTs[tIndex].fT;
michael@0 188 }
michael@0 189
michael@0 190 double tAtMid(int start, int end, double mid) const {
michael@0 191 return fTs[start].fT * (1 - mid) + fTs[end].fT * mid;
michael@0 192 }
michael@0 193
michael@0 194 bool unsortable(int index) const {
michael@0 195 return fTs[index].fUnsortableStart || fTs[index].fUnsortableEnd;
michael@0 196 }
michael@0 197
michael@0 198 void updatePts(const SkPoint pts[]) {
michael@0 199 fPts = pts;
michael@0 200 }
michael@0 201
michael@0 202 SkPath::Verb verb() const {
michael@0 203 return fVerb;
michael@0 204 }
michael@0 205
michael@0 206 int windSum(int tIndex) const {
michael@0 207 return fTs[tIndex].fWindSum;
michael@0 208 }
michael@0 209
michael@0 210 int windValue(int tIndex) const {
michael@0 211 return fTs[tIndex].fWindValue;
michael@0 212 }
michael@0 213
michael@0 214 #if defined(SK_DEBUG) || DEBUG_WINDING
michael@0 215 SkScalar xAtT(int index) const {
michael@0 216 return xAtT(&fTs[index]);
michael@0 217 }
michael@0 218 #endif
michael@0 219
michael@0 220 const SkPoint& xyAtT(const SkOpSpan* span) const {
michael@0 221 return span->fPt;
michael@0 222 }
michael@0 223
michael@0 224 const SkPoint& xyAtT(int index) const {
michael@0 225 return xyAtT(&fTs[index]);
michael@0 226 }
michael@0 227
michael@0 228 #if defined(SK_DEBUG) || DEBUG_WINDING
michael@0 229 SkScalar yAtT(int index) const {
michael@0 230 return yAtT(&fTs[index]);
michael@0 231 }
michael@0 232 #endif
michael@0 233
michael@0 234 bool activeAngle(int index, int* done, SkTArray<SkOpAngle, true>* angles);
michael@0 235 SkPoint activeLeftTop(bool onlySortable, int* firstT) const;
michael@0 236 bool activeOp(int index, int endIndex, int xorMiMask, int xorSuMask, SkPathOp op);
michael@0 237 bool activeWinding(int index, int endIndex);
michael@0 238 void addCubic(const SkPoint pts[4], bool operand, bool evenOdd);
michael@0 239 void addCurveTo(int start, int end, SkPathWriter* path, bool active) const;
michael@0 240 void addLine(const SkPoint pts[2], bool operand, bool evenOdd);
michael@0 241 void addOtherT(int index, double otherT, int otherIndex);
michael@0 242 void addQuad(const SkPoint pts[3], bool operand, bool evenOdd);
michael@0 243 int addSelfT(SkOpSegment* other, const SkPoint& pt, double newT);
michael@0 244 int addT(SkOpSegment* other, const SkPoint& pt, double newT);
michael@0 245 void addTCancel(const SkPoint& startPt, const SkPoint& endPt, SkOpSegment* other);
michael@0 246 void addTCoincident(const SkPoint& startPt, const SkPoint& endPt, double endT,
michael@0 247 SkOpSegment* other);
michael@0 248 void addTPair(double t, SkOpSegment* other, double otherT, bool borrowWind, const SkPoint& pt);
michael@0 249 bool betweenTs(int lesser, double testT, int greater) const;
michael@0 250 void checkEnds();
michael@0 251 bool checkSmall(int index) const;
michael@0 252 void checkTiny();
michael@0 253 int computeSum(int startIndex, int endIndex, SkOpAngle::IncludeType includeType,
michael@0 254 SkTArray<SkOpAngle, true>* angles, SkTArray<SkOpAngle*, true>* sorted);
michael@0 255 int crossedSpanY(const SkPoint& basePt, SkScalar* bestY, double* hitT, bool* hitSomething,
michael@0 256 double mid, bool opp, bool current) const;
michael@0 257 bool findCoincidentMatch(const SkOpSpan* span, const SkOpSegment* other, int oStart, int oEnd,
michael@0 258 int step, SkPoint* startPt, SkPoint* endPt, double* endT) const;
michael@0 259 SkOpSegment* findNextOp(SkTDArray<SkOpSpan*>* chase, int* nextStart, int* nextEnd,
michael@0 260 bool* unsortable, SkPathOp op, const int xorMiMask,
michael@0 261 const int xorSuMask);
michael@0 262 SkOpSegment* findNextWinding(SkTDArray<SkOpSpan*>* chase, int* nextStart, int* nextEnd,
michael@0 263 bool* unsortable);
michael@0 264 SkOpSegment* findNextXor(int* nextStart, int* nextEnd, bool* unsortable);
michael@0 265 int findT(double t, const SkOpSegment* ) const;
michael@0 266 SkOpSegment* findTop(int* tIndex, int* endIndex, bool* unsortable, bool onlySortable);
michael@0 267 void fixOtherTIndex();
michael@0 268 void initWinding(int start, int end);
michael@0 269 void initWinding(int start, int end, double tHit, int winding, SkScalar hitDx, int oppWind,
michael@0 270 SkScalar hitOppDx);
michael@0 271 bool isMissing(double startT, const SkPoint& pt) const;
michael@0 272 bool isTiny(const SkOpAngle* angle) const;
michael@0 273 bool joinCoincidence(SkOpSegment* other, double otherT, int step, bool cancel);
michael@0 274 SkOpSpan* markAndChaseDoneBinary(int index, int endIndex);
michael@0 275 SkOpSpan* markAndChaseDoneUnary(int index, int endIndex);
michael@0 276 SkOpSpan* markAndChaseWinding(const SkOpAngle* angle, int winding, int oppWinding);
michael@0 277 SkOpSpan* markAngle(int maxWinding, int sumWinding, int oppMaxWinding, int oppSumWinding,
michael@0 278 const SkOpAngle* angle);
michael@0 279 void markDone(int index, int winding);
michael@0 280 void markDoneBinary(int index);
michael@0 281 void markDoneUnary(int index);
michael@0 282 bool nextCandidate(int* start, int* end) const;
michael@0 283 int nextSpan(int from, int step) const;
michael@0 284 void setUpWindings(int index, int endIndex, int* sumMiWinding, int* sumSuWinding,
michael@0 285 int* maxWinding, int* sumWinding, int* oppMaxWinding, int* oppSumWinding);
michael@0 286 enum SortAngleKind {
michael@0 287 kMustBeOrdered_SortAngleKind, // required for winding calc
michael@0 288 kMayBeUnordered_SortAngleKind // ok for find top
michael@0 289 };
michael@0 290 static bool SortAngles(const SkTArray<SkOpAngle, true>& angles, // FIXME: replace with
michael@0 291 SkTArray<SkOpAngle*, true>* angleList, // Sort Angles 2
michael@0 292 SortAngleKind );
michael@0 293 static bool SortAngles2(const SkTArray<SkOpAngle, true>& angles,
michael@0 294 SkTArray<SkOpAngle*, true>* angleList);
michael@0 295 bool subDivide(int start, int end, SkPoint edge[4]) const;
michael@0 296 bool subDivide(int start, int end, SkDCubic* result) const;
michael@0 297 void undoneSpan(int* start, int* end);
michael@0 298 int updateOppWindingReverse(const SkOpAngle* angle) const;
michael@0 299 int updateWindingReverse(const SkOpAngle* angle) const;
michael@0 300 static bool UseInnerWinding(int outerWinding, int innerWinding);
michael@0 301 int windingAtT(double tHit, int tIndex, bool crossOpp, SkScalar* dx) const;
michael@0 302 int windSum(const SkOpAngle* angle) const;
michael@0 303
michael@0 304 #ifdef SK_DEBUG
michael@0 305 int debugID() const {
michael@0 306 return fID;
michael@0 307 }
michael@0 308 #endif
michael@0 309 #if DEBUG_ACTIVE_SPANS || DEBUG_ACTIVE_SPANS_FIRST_ONLY
michael@0 310 void debugShowActiveSpans() const;
michael@0 311 #endif
michael@0 312 #if DEBUG_SORT || DEBUG_SWAP_TOP
michael@0 313 void debugShowSort(const char* fun, const SkTArray<SkOpAngle*, true>& angles, int first,
michael@0 314 const int contourWinding, const int oppContourWinding, bool sortable) const;
michael@0 315 void debugShowSort(const char* fun, const SkTArray<SkOpAngle*, true>& angles, int first,
michael@0 316 bool sortable);
michael@0 317 #endif
michael@0 318 #if DEBUG_CONCIDENT
michael@0 319 void debugShowTs(const char* prefix) const;
michael@0 320 #endif
michael@0 321 #if DEBUG_SHOW_WINDING
michael@0 322 int debugShowWindingValues(int slotCount, int ofInterest) const;
michael@0 323 #endif
michael@0 324
michael@0 325 private:
michael@0 326 struct MissingSpan {
michael@0 327 double fT;
michael@0 328 double fEndT;
michael@0 329 SkOpSegment* fSegment;
michael@0 330 SkOpSegment* fOther;
michael@0 331 double fOtherT;
michael@0 332 SkPoint fPt;
michael@0 333 };
michael@0 334
michael@0 335 bool activeAngleOther(int index, int* done, SkTArray<SkOpAngle, true>* angles);
michael@0 336 bool activeAngleInner(int index, int* done, SkTArray<SkOpAngle, true>* angles);
michael@0 337 bool activeOp(int xorMiMask, int xorSuMask, int index, int endIndex, SkPathOp op,
michael@0 338 int* sumMiWinding, int* sumSuWinding, int* maxWinding, int* sumWinding,
michael@0 339 int* oppMaxWinding, int* oppSumWinding);
michael@0 340 bool activeWinding(int index, int endIndex, int* maxWinding, int* sumWinding);
michael@0 341 void addAngle(SkTArray<SkOpAngle, true>* angles, int start, int end) const;
michael@0 342 void addCancelOutsides(const SkPoint& startPt, const SkPoint& endPt, SkOpSegment* other);
michael@0 343 void addCoinOutsides(const SkPoint& startPt, const SkPoint& endPt, SkOpSegment* other);
michael@0 344 void addTPair(double t, SkOpSegment* other, double otherT, bool borrowWind, const SkPoint& pt,
michael@0 345 const SkPoint& oPt);
michael@0 346 void addTwoAngles(int start, int end, SkTArray<SkOpAngle, true>* angles) const;
michael@0 347 bool betweenPoints(double midT, const SkPoint& pt1, const SkPoint& pt2) const;
michael@0 348 bool buildAngles(int index, SkTArray<SkOpAngle, true>* angles, bool includeOpp) const;
michael@0 349 void buildAnglesInner(int index, SkTArray<SkOpAngle, true>* angles) const;
michael@0 350 void bumpCoincidentThis(const SkOpSpan& oTest, bool binary, int* index,
michael@0 351 SkTArray<SkPoint, true>* outsideTs);
michael@0 352 void bumpCoincidentOther(const SkOpSpan& oTest, int* index,
michael@0 353 SkTArray<SkPoint, true>* outsideTs);
michael@0 354 bool bumpSpan(SkOpSpan* span, int windDelta, int oppDelta);
michael@0 355 bool clockwise(int tStart, int tEnd) const;
michael@0 356 static void ComputeOneSum(const SkOpAngle* baseAngle, SkOpAngle* nextAngle,
michael@0 357 SkOpAngle::IncludeType );
michael@0 358 static void ComputeOneSumReverse(const SkOpAngle* baseAngle, SkOpAngle* nextAngle,
michael@0 359 SkOpAngle::IncludeType );
michael@0 360 bool decrementSpan(SkOpSpan* span);
michael@0 361 int findStartingEdge(const SkTArray<SkOpAngle*, true>& sorted, int start, int end);
michael@0 362 void init(const SkPoint pts[], SkPath::Verb verb, bool operand, bool evenOdd);
michael@0 363 bool isSimple(int end) const;
michael@0 364 bool isTiny(int index) const;
michael@0 365 void matchWindingValue(int tIndex, double t, bool borrowWind);
michael@0 366 SkOpSpan* markAndChaseDone(int index, int endIndex, int winding);
michael@0 367 SkOpSpan* markAndChaseDoneBinary(const SkOpAngle* angle, int winding, int oppWinding);
michael@0 368 SkOpSpan* markAndChaseWinding(const SkOpAngle* angle, const int winding);
michael@0 369 SkOpSpan* markAndChaseWinding(int index, int endIndex, int winding, int oppWinding);
michael@0 370 SkOpSpan* markAngle(int maxWinding, int sumWinding, const SkOpAngle* angle);
michael@0 371 void markDoneBinary(int index, int winding, int oppWinding);
michael@0 372 SkOpSpan* markAndChaseDoneUnary(const SkOpAngle* angle, int winding);
michael@0 373 void markOneDone(const char* funName, int tIndex, int winding);
michael@0 374 void markOneDoneBinary(const char* funName, int tIndex);
michael@0 375 void markOneDoneBinary(const char* funName, int tIndex, int winding, int oppWinding);
michael@0 376 void markOneDoneUnary(const char* funName, int tIndex);
michael@0 377 SkOpSpan* markOneWinding(const char* funName, int tIndex, int winding);
michael@0 378 SkOpSpan* markOneWinding(const char* funName, int tIndex, int winding, int oppWinding);
michael@0 379 void markWinding(int index, int winding);
michael@0 380 void markWinding(int index, int winding, int oppWinding);
michael@0 381 void markUnsortable(int start, int end);
michael@0 382 bool monotonicInY(int tStart, int tEnd) const;
michael@0 383 bool multipleSpans(int end) const;
michael@0 384 SkOpSegment* nextChase(int* index, const int step, int* min, SkOpSpan** last);
michael@0 385 int nextExactSpan(int from, int step) const;
michael@0 386 bool serpentine(int tStart, int tEnd) const;
michael@0 387 void setUpWindings(int index, int endIndex, int* sumMiWinding,
michael@0 388 int* maxWinding, int* sumWinding);
michael@0 389 void subDivideBounds(int start, int end, SkPathOpsBounds* bounds) const;
michael@0 390 static void TrackOutsidePair(SkTArray<SkPoint, true>* outsideTs, const SkPoint& endPt,
michael@0 391 const SkPoint& startPt);
michael@0 392 static void TrackOutside(SkTArray<SkPoint, true>* outsideTs, const SkPoint& startPt);
michael@0 393 int updateOppWinding(int index, int endIndex) const;
michael@0 394 int updateOppWinding(const SkOpAngle* angle) const;
michael@0 395 int updateWinding(int index, int endIndex) const;
michael@0 396 int updateWinding(const SkOpAngle* angle) const;
michael@0 397 int updateWindingReverse(int index, int endIndex) const;
michael@0 398 static bool UseInnerWindingReverse(int outerWinding, int innerWinding);
michael@0 399 SkOpSpan* verifyOneWinding(const char* funName, int tIndex);
michael@0 400 SkOpSpan* verifyOneWindingU(const char* funName, int tIndex);
michael@0 401
michael@0 402 SkScalar xAtT(const SkOpSpan* span) const {
michael@0 403 return xyAtT(span).fX;
michael@0 404 }
michael@0 405
michael@0 406 SkScalar yAtT(const SkOpSpan* span) const {
michael@0 407 return xyAtT(span).fY;
michael@0 408 }
michael@0 409
michael@0 410 void zeroSpan(SkOpSpan* span);
michael@0 411
michael@0 412 #if DEBUG_SWAP_TOP
michael@0 413 bool controlsContainedByEnds(int tStart, int tEnd) const;
michael@0 414 #endif
michael@0 415 #if DEBUG_CONCIDENT
michael@0 416 void debugAddTPair(double t, const SkOpSegment& other, double otherT) const;
michael@0 417 #endif
michael@0 418 #if DEBUG_MARK_DONE || DEBUG_UNSORTABLE
michael@0 419 void debugShowNewWinding(const char* fun, const SkOpSpan& span, int winding);
michael@0 420 void debugShowNewWinding(const char* fun, const SkOpSpan& span, int winding, int oppWinding);
michael@0 421 #endif
michael@0 422 #if DEBUG_WINDING
michael@0 423 static char as_digit(int value) {
michael@0 424 return value < 0 ? '?' : value <= 9 ? '0' + value : '+';
michael@0 425 }
michael@0 426 #endif
michael@0 427 void debugValidate() const;
michael@0 428 #ifdef SK_DEBUG
michael@0 429 void dumpPts() const;
michael@0 430 void dumpDPts() const;
michael@0 431 void dumpSpans() const;
michael@0 432 #endif
michael@0 433
michael@0 434 const SkPoint* fPts;
michael@0 435 SkPathOpsBounds fBounds;
michael@0 436 // FIXME: can't convert to SkTArray because it uses insert
michael@0 437 SkTDArray<SkOpSpan> fTs; // two or more (always includes t=0 t=1)
michael@0 438 // OPTIMIZATION: could pack donespans, verb, operand, xor into 1 int-sized value
michael@0 439 int fDoneSpans; // quick check that segment is finished
michael@0 440 // OPTIMIZATION: force the following to be byte-sized
michael@0 441 SkPath::Verb fVerb;
michael@0 442 bool fOperand;
michael@0 443 bool fXor; // set if original contour had even-odd fill
michael@0 444 bool fOppXor; // set if opposite operand had even-odd fill
michael@0 445 #ifdef SK_DEBUG
michael@0 446 int fID;
michael@0 447 #endif
michael@0 448 };
michael@0 449
michael@0 450 #endif

mercurial