Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(494)

Side by Side Diff: src/pathops/SkOpSegment.cpp

Issue 1140813002: deal more consistently with unsortable edges (Closed) Base URL: https://skia.googlesource.com/skia.git@master
Patch Set: fix linux warning Created 5 years, 7 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « src/pathops/SkOpSegment.h ('k') | src/pathops/SkOpSpan.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 /* 1 /*
2 * Copyright 2012 Google Inc. 2 * Copyright 2012 Google Inc.
3 * 3 *
4 * Use of this source code is governed by a BSD-style license that can be 4 * Use of this source code is governed by a BSD-style license that can be
5 * found in the LICENSE file. 5 * found in the LICENSE file.
6 */ 6 */
7 #include "SkOpCoincidence.h" 7 #include "SkOpCoincidence.h"
8 #include "SkOpContour.h" 8 #include "SkOpContour.h"
9 #include "SkOpSegment.h" 9 #include "SkOpSegment.h"
10 #include "SkPathWriter.h" 10 #include "SkPathWriter.h"
(...skipping 25 matching lines...) Expand all
36 {{{{F, F}, {F, F}}, {{T, F}, {T, F}}}, {{{T, T}, {F, F}}, {{F, T}, {T, F}}}} , // mi - su 36 {{{{F, F}, {F, F}}, {{T, F}, {T, F}}}, {{{T, T}, {F, F}}, {{F, T}, {T, F}}}} , // mi - su
37 {{{{F, F}, {F, F}}, {{F, T}, {F, T}}}, {{{F, F}, {T, T}}, {{F, T}, {T, F}}}} , // mi & su 37 {{{{F, F}, {F, F}}, {{F, T}, {F, T}}}, {{{F, F}, {T, T}}, {{F, T}, {T, F}}}} , // mi & su
38 {{{{F, T}, {T, F}}, {{T, T}, {F, F}}}, {{{T, F}, {T, F}}, {{F, F}, {F, F}}}} , // mi | su 38 {{{{F, T}, {T, F}}, {{T, T}, {F, F}}}, {{{T, F}, {T, F}}, {{F, F}, {F, F}}}} , // mi | su
39 {{{{F, T}, {T, F}}, {{T, F}, {F, T}}}, {{{T, F}, {F, T}}, {{F, T}, {T, F}}}} , // mi ^ su 39 {{{{F, T}, {T, F}}, {{T, F}, {F, T}}}, {{{T, F}, {F, T}}, {{F, T}, {T, F}}}} , // mi ^ su
40 }; 40 };
41 41
42 #undef F 42 #undef F
43 #undef T 43 #undef T
44 44
45 SkOpAngle* SkOpSegment::activeAngle(SkOpSpanBase* start, SkOpSpanBase** startPtr , 45 SkOpAngle* SkOpSegment::activeAngle(SkOpSpanBase* start, SkOpSpanBase** startPtr ,
46 SkOpSpanBase** endPtr, bool* done, bool* sortable) { 46 SkOpSpanBase** endPtr, bool* done) {
47 if (SkOpAngle* result = activeAngleInner(start, startPtr, endPtr, done, sort able)) { 47 if (SkOpAngle* result = activeAngleInner(start, startPtr, endPtr, done)) {
48 return result; 48 return result;
49 } 49 }
50 if (SkOpAngle* result = activeAngleOther(start, startPtr, endPtr, done, sort able)) { 50 if (SkOpAngle* result = activeAngleOther(start, startPtr, endPtr, done)) {
51 return result; 51 return result;
52 } 52 }
53 return NULL; 53 return NULL;
54 } 54 }
55 55
56 SkOpAngle* SkOpSegment::activeAngleInner(SkOpSpanBase* start, SkOpSpanBase** sta rtPtr, 56 SkOpAngle* SkOpSegment::activeAngleInner(SkOpSpanBase* start, SkOpSpanBase** sta rtPtr,
57 SkOpSpanBase** endPtr, bool* done, bool* sortable) { 57 SkOpSpanBase** endPtr, bool* done) {
58 SkOpSpan* upSpan = start->upCastable(); 58 SkOpSpan* upSpan = start->upCastable();
59 if (upSpan) { 59 if (upSpan) {
60 if (upSpan->windValue() || upSpan->oppValue()) { 60 if (upSpan->windValue() || upSpan->oppValue()) {
61 SkOpSpanBase* next = upSpan->next(); 61 SkOpSpanBase* next = upSpan->next();
62 if (!*endPtr) { 62 if (!*endPtr) {
63 *startPtr = start; 63 *startPtr = start;
64 *endPtr = next; 64 *endPtr = next;
65 } 65 }
66 if (!upSpan->done()) { 66 if (!upSpan->done()) {
67 if (upSpan->windSum() != SK_MinS32) { 67 if (upSpan->windSum() != SK_MinS32) {
(...skipping 20 matching lines...) Expand all
88 *done = false; 88 *done = false;
89 } 89 }
90 } else { 90 } else {
91 SkASSERT(downSpan->done()); 91 SkASSERT(downSpan->done());
92 } 92 }
93 } 93 }
94 return NULL; 94 return NULL;
95 } 95 }
96 96
97 SkOpAngle* SkOpSegment::activeAngleOther(SkOpSpanBase* start, SkOpSpanBase** sta rtPtr, 97 SkOpAngle* SkOpSegment::activeAngleOther(SkOpSpanBase* start, SkOpSpanBase** sta rtPtr,
98 SkOpSpanBase** endPtr, bool* done, bool* sortable) { 98 SkOpSpanBase** endPtr, bool* done) {
99 SkOpPtT* oPtT = start->ptT()->next(); 99 SkOpPtT* oPtT = start->ptT()->next();
100 SkOpSegment* other = oPtT->segment(); 100 SkOpSegment* other = oPtT->segment();
101 SkOpSpanBase* oSpan = oPtT->span(); 101 SkOpSpanBase* oSpan = oPtT->span();
102 return other->activeAngleInner(oSpan, startPtr, endPtr, done, sortable); 102 return other->activeAngleInner(oSpan, startPtr, endPtr, done);
103 } 103 }
104 104
105 bool SkOpSegment::activeOp(SkOpSpanBase* start, SkOpSpanBase* end, int xorMiMask , int xorSuMask, 105 bool SkOpSegment::activeOp(SkOpSpanBase* start, SkOpSpanBase* end, int xorMiMask , int xorSuMask,
106 SkPathOp op) { 106 SkPathOp op) {
107 int sumMiWinding = this->updateWinding(end, start); 107 int sumMiWinding = this->updateWinding(end, start);
108 int sumSuWinding = this->updateOppWinding(end, start); 108 int sumSuWinding = this->updateOppWinding(end, start);
109 #if DEBUG_LIMIT_WIND_SUM 109 #if DEBUG_LIMIT_WIND_SUM
110 SkASSERT(abs(sumMiWinding) <= DEBUG_LIMIT_WIND_SUM); 110 SkASSERT(abs(sumMiWinding) <= DEBUG_LIMIT_WIND_SUM);
111 SkASSERT(abs(sumSuWinding) <= DEBUG_LIMIT_WIND_SUM); 111 SkASSERT(abs(sumSuWinding) <= DEBUG_LIMIT_WIND_SUM);
112 #endif 112 #endif
(...skipping 191 matching lines...) Expand 10 before | Expand all | Expand 10 after
304 } 304 }
305 while ((span = span->upCast()->next())) { 305 while ((span = span->upCast()->next())) {
306 if (span == &fTail) { 306 if (span == &fTail) {
307 break; 307 break;
308 } 308 }
309 span->align(); 309 span->align();
310 } 310 }
311 if (!span->aligned()) { 311 if (!span->aligned()) {
312 span->alignEnd(1, fPts[SkPathOpsVerbToPoints(fVerb)]); 312 span->alignEnd(1, fPts[SkPathOpsVerbToPoints(fVerb)]);
313 } 313 }
314 if (this->collapsed()) {
315 SkOpSpan* span = &fHead;
316 do {
317 span->setWindValue(0);
318 span->setOppValue(0);
319 this->markDone(span);
320 } while ((span = span->next()->upCastable()));
321 }
314 debugValidate(); 322 debugValidate();
315 } 323 }
316 324
317 void SkOpSegment::calcAngles(SkChunkAlloc* allocator) { 325 void SkOpSegment::calcAngles(SkChunkAlloc* allocator) {
318 bool activePrior = !fHead.isCanceled(); 326 bool activePrior = !fHead.isCanceled();
319 if (activePrior && !fHead.simple()) { 327 if (activePrior && !fHead.simple()) {
320 addStartSpan(allocator); 328 addStartSpan(allocator);
321 } 329 }
322 SkOpSpan* prior = &fHead; 330 SkOpSpan* prior = &fHead;
323 SkOpSpanBase* spanBase = fHead.next(); 331 SkOpSpanBase* spanBase = fHead.next();
(...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after
356 break; 364 break;
357 } 365 }
358 span = base->upCast(); 366 span = base->upCast();
359 angle = span->toAngle(); 367 angle = span->toAngle();
360 if (angle && angle->fCheckCoincidence) { 368 if (angle && angle->fCheckCoincidence) {
361 angle->checkNearCoincidence(); 369 angle->checkNearCoincidence();
362 } 370 }
363 } while ((base = span->next())); 371 } while ((base = span->next()));
364 } 372 }
365 373
374 bool SkOpSegment::collapsed() const {
375 return fVerb == SkPath::kLine_Verb && fHead.pt() == fTail.pt();
376 }
377
366 void SkOpSegment::ComputeOneSum(const SkOpAngle* baseAngle, SkOpAngle* nextAngle , 378 void SkOpSegment::ComputeOneSum(const SkOpAngle* baseAngle, SkOpAngle* nextAngle ,
367 SkOpAngle::IncludeType includeType) { 379 SkOpAngle::IncludeType includeType) {
368 SkOpSegment* baseSegment = baseAngle->segment(); 380 SkOpSegment* baseSegment = baseAngle->segment();
369 int sumMiWinding = baseSegment->updateWindingReverse(baseAngle); 381 int sumMiWinding = baseSegment->updateWindingReverse(baseAngle);
370 int sumSuWinding; 382 int sumSuWinding;
371 bool binary = includeType >= SkOpAngle::kBinarySingle; 383 bool binary = includeType >= SkOpAngle::kBinarySingle;
372 if (binary) { 384 if (binary) {
373 sumSuWinding = baseSegment->updateOppWindingReverse(baseAngle); 385 sumSuWinding = baseSegment->updateOppWindingReverse(baseAngle);
374 if (baseSegment->operand()) { 386 if (baseSegment->operand()) {
375 SkTSwap<int>(sumMiWinding, sumSuWinding); 387 SkTSwap<int>(sumMiWinding, sumSuWinding);
(...skipping 695 matching lines...) Expand 10 before | Expand all | Expand 10 after
1071 return set_last(last, endSpan); 1083 return set_last(last, endSpan);
1072 } 1084 }
1073 *startPtr = foundSpan; 1085 *startPtr = foundSpan;
1074 *stepPtr = foundStep; 1086 *stepPtr = foundStep;
1075 if (minPtr) { 1087 if (minPtr) {
1076 *minPtr = foundMin; 1088 *minPtr = foundMin;
1077 } 1089 }
1078 return other; 1090 return other;
1079 } 1091 }
1080 1092
1081 static void clear_visited(SkOpSpan* span) { 1093 static void clear_visited(SkOpSpanBase* span) {
1082 // reset visited flag back to false 1094 // reset visited flag back to false
1083 do { 1095 do {
1084 SkOpPtT* ptT = span->ptT(), * stopPtT = ptT; 1096 SkOpPtT* ptT = span->ptT(), * stopPtT = ptT;
1085 while ((ptT = ptT->next()) != stopPtT) { 1097 while ((ptT = ptT->next()) != stopPtT) {
1086 SkOpSegment* opp = ptT->segment(); 1098 SkOpSegment* opp = ptT->segment();
1087 opp->resetVisited(); 1099 opp->resetVisited();
1088 } 1100 }
1089 } while ((span = span->next()->upCastable())); 1101 } while (!span->final() && (span = span->upCast()->next()));
1090 } 1102 }
1091 1103
1092 // look for pairs of undetected coincident curves 1104 // look for pairs of undetected coincident curves
1093 // assumes that segments going in have visited flag clear 1105 // assumes that segments going in have visited flag clear
1094 // curve/curve intersection should now do a pretty good job of finding coinciden t runs so 1106 // curve/curve intersection should now do a pretty good job of finding coinciden t runs so
1095 // this may be only be necessary for line/curve pairs -- so skip unless this is a line and the 1107 // this may be only be necessary for line/curve pairs -- so skip unless this is a line and the
1096 // the opp is not a line 1108 // the opp is not a line
1097 void SkOpSegment::missingCoincidence(SkOpCoincidence* coincidences, SkChunkAlloc * allocator) { 1109 void SkOpSegment::missingCoincidence(SkOpCoincidence* coincidences, SkChunkAlloc * allocator) {
1098 if (this->verb() != SkPath::kLine_Verb) { 1110 if (this->verb() != SkPath::kLine_Verb) {
1099 return; 1111 return;
1100 } 1112 }
1113 if (this->done()) {
1114 return;
1115 }
1101 SkOpSpan* prior = NULL; 1116 SkOpSpan* prior = NULL;
1102 SkOpSpan* span = &fHead; 1117 SkOpSpanBase* spanBase = &fHead;
1103 do { 1118 do {
1104 SkOpPtT* ptT = span->ptT(), * spanStopPtT = ptT; 1119 SkOpPtT* ptT = spanBase->ptT(), * spanStopPtT = ptT;
1105 SkASSERT(ptT->span() == span); 1120 SkASSERT(ptT->span() == spanBase);
1106 while ((ptT = ptT->next()) != spanStopPtT) { 1121 while ((ptT = ptT->next()) != spanStopPtT) {
1107 SkOpSegment* opp = ptT->span()->segment(); 1122 SkOpSegment* opp = ptT->span()->segment();
1108 if (!opp->setVisited()) {
1109 continue;
1110 }
1111 if (opp->verb() == SkPath::kLine_Verb) { 1123 if (opp->verb() == SkPath::kLine_Verb) {
1112 continue; 1124 continue;
1113 } 1125 }
1114 if (span->containsCoincidence(opp)) { // FIXME: this assumes that if the opposite 1126 if (opp->done()) {
1115 // segment is coincident then no more coincidence
1116 // needs to be detected. This may not be true.
1117 continue; 1127 continue;
1118 } 1128 }
1119 if (span->containsCoinEnd(opp)) { 1129 // when opp is encounted the 1st time, continue; on 2nd encounter, l ook for coincidence
1130 if (!opp->visited()) {
1131 continue;
1132 }
1133 if (spanBase == &fHead) {
1134 continue;
1135 }
1136 SkOpSpan* span = spanBase->upCastable();
1137 // FIXME?: this assumes that if the opposite segment is coincident t hen no more
1138 // coincidence needs to be detected. This may not be true.
1139 if (span && span->containsCoincidence(opp)) {
1140 continue;
1141 }
1142 if (spanBase->containsCoinEnd(opp)) {
1120 continue; 1143 continue;
1121 } 1144 }
1122 // if already visited and visited again, check for coin
1123 if (span == &fHead) {
1124 continue;
1125 }
1126 SkOpPtT* priorPtT = NULL, * priorStopPtT; 1145 SkOpPtT* priorPtT = NULL, * priorStopPtT;
1127 // find prior span containing opp segment 1146 // find prior span containing opp segment
1128 SkOpSegment* priorOpp = NULL; 1147 SkOpSegment* priorOpp = NULL;
1129 prior = span; 1148 SkOpSpan* priorTest = spanBase->prev();
1130 while (!priorOpp && (prior = prior->prev())) { 1149 while (!priorOpp && priorTest) {
1131 priorStopPtT = priorPtT = prior->ptT(); 1150 priorStopPtT = priorPtT = priorTest->ptT();
1132 while ((priorPtT = priorPtT->next()) != priorStopPtT) { 1151 while ((priorPtT = priorPtT->next()) != priorStopPtT) {
1133 SkOpSegment* segment = priorPtT->span()->segment(); 1152 SkOpSegment* segment = priorPtT->span()->segment();
1134 if (segment == opp) { 1153 if (segment == opp) {
1154 prior = priorTest;
1135 priorOpp = opp; 1155 priorOpp = opp;
1136 break; 1156 break;
1137 } 1157 }
1138 } 1158 }
1159 priorTest = priorTest->prev();
1139 } 1160 }
1140 if (!priorOpp) { 1161 if (!priorOpp) {
1141 continue; 1162 continue;
1142 } 1163 }
1143 SkOpPtT* oppStart = prior->ptT(); 1164 SkOpPtT* oppStart = prior->ptT();
1144 SkOpPtT* oppEnd = span->ptT(); 1165 SkOpPtT* oppEnd = spanBase->ptT();
1145 bool swapped = priorPtT->fT > ptT->fT; 1166 bool swapped = priorPtT->fT > ptT->fT;
1146 if (swapped) { 1167 if (swapped) {
1147 SkTSwap(priorPtT, ptT); 1168 SkTSwap(priorPtT, ptT);
1148 SkTSwap(oppStart, oppEnd); 1169 SkTSwap(oppStart, oppEnd);
1149 } 1170 }
1150 bool flipped = oppStart->fT > oppEnd->fT; 1171 bool flipped = oppStart->fT > oppEnd->fT;
1151 bool coincident; 1172 bool coincident;
1152 if (coincidences->contains(priorPtT, ptT, oppStart, oppEnd, flipped) ) { 1173 if (coincidences->contains(priorPtT, ptT, oppStart, oppEnd, flipped) ) {
1153 goto swapBack; 1174 goto swapBack;
1154 } 1175 }
1155 { 1176 {
1156 // average t, find mid pt 1177 // average t, find mid pt
1157 double midT = (prior->t() + span->t()) / 2; 1178 double midT = (prior->t() + spanBase->t()) / 2;
1158 SkPoint midPt = this->ptAtT(midT); 1179 SkPoint midPt = this->ptAtT(midT);
1159 coincident = true; 1180 coincident = true;
1160 // if the mid pt is not near either end pt, project perpendicula r through opp seg 1181 // if the mid pt is not near either end pt, project perpendicula r through opp seg
1161 if (!SkDPoint::ApproximatelyEqual(priorPtT->fPt, midPt) 1182 if (!SkDPoint::ApproximatelyEqual(priorPtT->fPt, midPt)
1162 && !SkDPoint::ApproximatelyEqual(ptT->fPt, midPt)) { 1183 && !SkDPoint::ApproximatelyEqual(ptT->fPt, midPt)) {
1163 coincident = false; 1184 coincident = false;
1164 SkIntersections i; 1185 SkIntersections i;
1165 SkVector dxdy = (*CurveSlopeAtT[fVerb])(this->pts(), this->w eight(), midT); 1186 SkVector dxdy = (*CurveSlopeAtT[fVerb])(this->pts(), this->w eight(), midT);
1166 SkDLine ray = {{{midPt.fX, midPt.fY}, 1187 SkDLine ray = {{{midPt.fX, midPt.fY},
1167 {midPt.fX + dxdy.fY, midPt.fY - dxdy.fX}}}; 1188 {midPt.fX + dxdy.fY, midPt.fY - dxdy.fX}}};
1168 (*CurveIntersectRay[opp->verb()])(opp->pts(), opp->weight(), ray, &i); 1189 (*CurveIntersectRay[opp->verb()])(opp->pts(), opp->weight(), ray, &i);
1169 // measure distance and see if it's small enough to denote c oincidence 1190 // measure distance and see if it's small enough to denote c oincidence
1170 for (int index = 0; index < i.used(); ++index) { 1191 for (int index = 0; index < i.used(); ++index) {
1171 SkDPoint oppPt = i.pt(index); 1192 SkDPoint oppPt = i.pt(index);
1172 if (oppPt.approximatelyEqual(midPt)) { 1193 if (oppPt.approximatelyEqual(midPt)) {
1173 SkVector oppDxdy = (*CurveSlopeAtT[opp->verb()])(opp ->pts(), 1194 SkVector oppDxdy = (*CurveSlopeAtT[opp->verb()])(opp ->pts(),
1174 opp->weight(), i[index][0]); 1195 opp->weight(), i[index][0]);
1175 oppDxdy.normalize(); 1196 oppDxdy.normalize();
1176 dxdy.normalize(); 1197 dxdy.normalize();
1177 SkScalar flatness = SkScalarAbs(dxdy.cross(oppDxdy) / FLT_EPSILON); 1198 SkScalar flatness = SkScalarAbs(dxdy.cross(oppDxdy) / FLT_EPSILON);
1178 coincident |= flatness < 5000; // FIXME: replace wi th tuned value 1199 coincident |= flatness < 5000; // FIXME: replace wi th tuned value
1179 } 1200 }
1180 } 1201 }
1181 } 1202 }
1182 } 1203 }
1183 if (coincident) { 1204 if (coincident) {
1184 // mark coincidence 1205 // mark coincidence
1185 coincidences->add(priorPtT, ptT, oppStart, oppEnd, allocator); 1206 if (!coincidences->extend(priorPtT, ptT, oppStart, oppEnd)) {
1207 coincidences->add(priorPtT, ptT, oppStart, oppEnd, allocator );
1208 }
1186 clear_visited(&fHead); 1209 clear_visited(&fHead);
1187 missingCoincidence(coincidences, allocator);
1188 return; 1210 return;
1189 } 1211 }
1190 swapBack: 1212 swapBack:
1191 if (swapped) { 1213 if (swapped) {
1192 SkTSwap(priorPtT, ptT); 1214 SkTSwap(priorPtT, ptT);
1193 } 1215 }
1194 } 1216 }
1195 } while ((span = span->next()->upCastable())); 1217 } while ((spanBase = spanBase->final() ? NULL : spanBase->upCast()->next())) ;
1196 clear_visited(&fHead); 1218 clear_visited(&fHead);
1197 } 1219 }
1198 1220
1199 // if a span has more than one intersection, merge the other segments' span as n eeded 1221 // if a span has more than one intersection, merge the other segments' span as n eeded
1200 void SkOpSegment::moveMultiples() { 1222 void SkOpSegment::moveMultiples() {
1201 debugValidate(); 1223 debugValidate();
1202 SkOpSpanBase* test = &fHead; 1224 SkOpSpanBase* test = &fHead;
1203 do { 1225 do {
1204 int addCount = test->spanAddsCount(); 1226 int addCount = test->spanAddsCount();
1205 SkASSERT(addCount >= 1); 1227 SkASSERT(addCount >= 1);
(...skipping 397 matching lines...) Expand 10 before | Expand all | Expand 10 after
1603 int SkOpSegment::updateOppWindingReverse(const SkOpAngle* angle) const { 1625 int SkOpSegment::updateOppWindingReverse(const SkOpAngle* angle) const {
1604 const SkOpSpanBase* startSpan = angle->start(); 1626 const SkOpSpanBase* startSpan = angle->start();
1605 const SkOpSpanBase* endSpan = angle->end(); 1627 const SkOpSpanBase* endSpan = angle->end();
1606 return updateOppWinding(startSpan, endSpan); 1628 return updateOppWinding(startSpan, endSpan);
1607 } 1629 }
1608 1630
1609 int SkOpSegment::updateWinding(SkOpSpanBase* start, SkOpSpanBase* end) { 1631 int SkOpSegment::updateWinding(SkOpSpanBase* start, SkOpSpanBase* end) {
1610 SkOpSpan* lesser = start->starter(end); 1632 SkOpSpan* lesser = start->starter(end);
1611 int winding = lesser->windSum(); 1633 int winding = lesser->windSum();
1612 if (winding == SK_MinS32) { 1634 if (winding == SK_MinS32) {
1613 SkOpGlobalState* globals = this->globalState(); 1635 winding = lesser->computeWindSum();
1614 SkOpContour* contourHead = globals->contourHead();
1615 int windTry = 0;
1616 while (!lesser->sortableTop(contourHead) && ++windTry < SkOpGlobalState: :kMaxWindingTries) {
1617 ;
1618 }
1619 winding = lesser->windSum();
1620 } 1636 }
1621 if (winding == SK_MinS32) { 1637 if (winding == SK_MinS32) {
1622 return winding; 1638 return winding;
1623 } 1639 }
1624 int spanWinding = SkOpSegment::SpanSign(start, end); 1640 int spanWinding = SkOpSegment::SpanSign(start, end);
1625 if (winding && UseInnerWinding(winding - spanWinding, winding) 1641 if (winding && UseInnerWinding(winding - spanWinding, winding)
1626 && winding != SK_MaxS32) { 1642 && winding != SK_MaxS32) {
1627 winding -= spanWinding; 1643 winding -= spanWinding;
1628 } 1644 }
1629 return winding; 1645 return winding;
(...skipping 20 matching lines...) Expand all
1650 int absOut = abs(outerWinding); 1666 int absOut = abs(outerWinding);
1651 int absIn = abs(innerWinding); 1667 int absIn = abs(innerWinding);
1652 bool result = absOut == absIn ? outerWinding < 0 : absOut < absIn; 1668 bool result = absOut == absIn ? outerWinding < 0 : absOut < absIn;
1653 return result; 1669 return result;
1654 } 1670 }
1655 1671
1656 int SkOpSegment::windSum(const SkOpAngle* angle) const { 1672 int SkOpSegment::windSum(const SkOpAngle* angle) const {
1657 const SkOpSpan* minSpan = angle->start()->starter(angle->end()); 1673 const SkOpSpan* minSpan = angle->start()->starter(angle->end());
1658 return minSpan->windSum(); 1674 return minSpan->windSum();
1659 } 1675 }
OLDNEW
« no previous file with comments | « src/pathops/SkOpSegment.h ('k') | src/pathops/SkOpSpan.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698