OLD | NEW |
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 "SkIntersections.h" | 7 #include "SkIntersections.h" |
8 #include "SkOpAngle.h" | 8 #include "SkOpAngle.h" |
9 #include "SkOpSegment.h" | 9 #include "SkOpSegment.h" |
10 #include "SkPathOpsCurve.h" | 10 #include "SkPathOpsCurve.h" |
(...skipping 268 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
279 return true; | 279 return true; |
280 } | 280 } |
281 return m0xm1 < 0; | 281 return m0xm1 < 0; |
282 } | 282 } |
283 | 283 |
284 // the original angle is too short to get meaningful sector information | 284 // the original angle is too short to get meaningful sector information |
285 // lengthen it until it is long enough to be meaningful or leave it unset if len
gthening it | 285 // lengthen it until it is long enough to be meaningful or leave it unset if len
gthening it |
286 // would cause it to intersect one of the adjacent angles | 286 // would cause it to intersect one of the adjacent angles |
287 bool SkOpAngle::computeSector() { | 287 bool SkOpAngle::computeSector() { |
288 if (fComputedSector) { | 288 if (fComputedSector) { |
289 // FIXME: logically, this should return !fUnorderable, but doing so brea
ks testQuadratic51 | |
290 // -- but in general, this code may not work so this may be the least of
problems | |
291 // adding the bang fixes testQuads46x in release, however | |
292 return !fUnorderable; | 289 return !fUnorderable; |
293 } | 290 } |
294 SkASSERT(fSegment->verb() != SkPath::kLine_Verb && small()); | 291 // SkASSERT(fSegment->verb() != SkPath::kLine_Verb && small()); |
295 fComputedSector = true; | 292 fComputedSector = true; |
296 int step = fStart < fEnd ? 1 : -1; | 293 int step = fStart < fEnd ? 1 : -1; |
297 int limit = step > 0 ? fSegment->count() : -1; | 294 int limit = step > 0 ? fSegment->count() : -1; |
298 int checkEnd = fEnd; | 295 int checkEnd = fEnd; |
299 do { | 296 do { |
300 // advance end | 297 // advance end |
301 const SkOpSpan& span = fSegment->span(checkEnd); | 298 const SkOpSpan& span = fSegment->span(checkEnd); |
302 const SkOpSegment* other = span.fOther; | 299 const SkOpSegment* other = span.fOther; |
303 int oCount = other->count(); | 300 int oCount = other->count(); |
304 for (int oIndex = 0; oIndex < oCount; ++oIndex) { | 301 for (int oIndex = 0; oIndex < oCount; ++oIndex) { |
(...skipping 321 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
626 // one could coin the term sedecimant for a space divided into 16 sections. | 623 // one could coin the term sedecimant for a space divided into 16 sections. |
627 // http://english.stackexchange.com/questions/133688/word-for-something-parti
tioned-into-16-parts | 624 // http://english.stackexchange.com/questions/133688/word-for-something-parti
tioned-into-16-parts |
628 static const int sedecimant[3][3][3] = { | 625 static const int sedecimant[3][3][3] = { |
629 // y<0 y==0 y>0 | 626 // y<0 y==0 y>0 |
630 // x<0 x==0 x>0 x<0 x==0 x>0 x<0 x==0 x>0 | 627 // x<0 x==0 x>0 x<0 x==0 x>0 x<0 x==0 x>0 |
631 {{ 4, 3, 2}, { 7, -1, 15}, {10, 11, 12}}, // abs(x) < abs(y) | 628 {{ 4, 3, 2}, { 7, -1, 15}, {10, 11, 12}}, // abs(x) < abs(y) |
632 {{ 5, -1, 1}, {-1, -1, -1}, { 9, -1, 13}}, // abs(x) == abs(y) | 629 {{ 5, -1, 1}, {-1, -1, -1}, { 9, -1, 13}}, // abs(x) == abs(y) |
633 {{ 6, 3, 0}, { 7, -1, 15}, { 8, 11, 14}}, // abs(x) > abs(y) | 630 {{ 6, 3, 0}, { 7, -1, 15}, { 8, 11, 14}}, // abs(x) > abs(y) |
634 }; | 631 }; |
635 int sector = sedecimant[(xy >= 0) + (xy > 0)][(y >= 0) + (y > 0)][(x >= 0) +
(x > 0)] * 2 + 1; | 632 int sector = sedecimant[(xy >= 0) + (xy > 0)][(y >= 0) + (y > 0)][(x >= 0) +
(x > 0)] * 2 + 1; |
636 SkASSERT(SkPath::kLine_Verb == verb || sector >= 0); | 633 // SkASSERT(SkPath::kLine_Verb == verb || sector >= 0); |
637 return sector; | 634 return sector; |
638 } | 635 } |
639 | 636 |
640 // OPTIMIZE: if this loops to only one other angle, after first compare fails, i
nsert on other side | 637 // OPTIMIZE: if this loops to only one other angle, after first compare fails, i
nsert on other side |
641 // OPTIMIZE: return where insertion succeeded. Then, start next insertion on opp
osite side | 638 // OPTIMIZE: return where insertion succeeded. Then, start next insertion on opp
osite side |
642 void SkOpAngle::insert(SkOpAngle* angle) { | 639 void SkOpAngle::insert(SkOpAngle* angle) { |
643 if (angle->fNext) { | 640 if (angle->fNext) { |
644 if (loopCount() >= angle->loopCount()) { | 641 if (loopCount() >= angle->loopCount()) { |
645 if (!merge(angle)) { | 642 if (!merge(angle)) { |
646 return; | 643 return; |
(...skipping 280 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
927 SkASSERT(s2x1 * s1x3 > 0); | 924 SkASSERT(s2x1 * s1x3 > 0); |
928 fSweep[0] = fSweep[1]; | 925 fSweep[0] = fSweep[1]; |
929 fUnorderedSweep = true; | 926 fUnorderedSweep = true; |
930 } | 927 } |
931 fSweep[1] = thirdSweep; | 928 fSweep[1] = thirdSweep; |
932 } | 929 } |
933 | 930 |
934 void SkOpAngle::setSector() { | 931 void SkOpAngle::setSector() { |
935 SkPath::Verb verb = fSegment->verb(); | 932 SkPath::Verb verb = fSegment->verb(); |
936 if (SkPath::kLine_Verb != verb && small()) { | 933 if (SkPath::kLine_Verb != verb && small()) { |
937 fSectorStart = fSectorEnd = -1; | 934 goto deferTilLater; |
938 fSectorMask = 0; | |
939 fComputeSector = true; // can't determine sector until segment length c
an be found | |
940 return; | |
941 } | 935 } |
942 fSectorStart = findSector(verb, fSweep[0].fX, fSweep[0].fY); | 936 fSectorStart = findSector(verb, fSweep[0].fX, fSweep[0].fY); |
| 937 if (fSectorStart < 0) { |
| 938 goto deferTilLater; |
| 939 } |
943 if (!fIsCurve) { // if it's a line or line-like, note that both sectors are
the same | 940 if (!fIsCurve) { // if it's a line or line-like, note that both sectors are
the same |
944 SkASSERT(fSectorStart >= 0); | 941 SkASSERT(fSectorStart >= 0); |
945 fSectorEnd = fSectorStart; | 942 fSectorEnd = fSectorStart; |
946 fSectorMask = 1 << fSectorStart; | 943 fSectorMask = 1 << fSectorStart; |
947 return; | 944 return; |
948 } | 945 } |
949 SkASSERT(SkPath::kLine_Verb != verb); | 946 SkASSERT(SkPath::kLine_Verb != verb); |
950 fSectorEnd = findSector(verb, fSweep[1].fX, fSweep[1].fY); | 947 fSectorEnd = findSector(verb, fSweep[1].fX, fSweep[1].fY); |
| 948 if (fSectorEnd < 0) { |
| 949 deferTilLater: |
| 950 fSectorStart = fSectorEnd = -1; |
| 951 fSectorMask = 0; |
| 952 fComputeSector = true; // can't determine sector until segment length c
an be found |
| 953 return; |
| 954 } |
951 if (fSectorEnd == fSectorStart) { | 955 if (fSectorEnd == fSectorStart) { |
952 SkASSERT((fSectorStart & 3) != 3); // if the sector has no span, it can
't be an exact angle | 956 SkASSERT((fSectorStart & 3) != 3); // if the sector has no span, it can
't be an exact angle |
953 fSectorMask = 1 << fSectorStart; | 957 fSectorMask = 1 << fSectorStart; |
954 return; | 958 return; |
955 } | 959 } |
956 bool crossesZero = checkCrossesZero(); | 960 bool crossesZero = checkCrossesZero(); |
957 int start = SkTMin(fSectorStart, fSectorEnd); | 961 int start = SkTMin(fSectorStart, fSectorEnd); |
958 bool curveBendsCCW = (fSectorStart == start) ^ crossesZero; | 962 bool curveBendsCCW = (fSectorStart == start) ^ crossesZero; |
959 // bump the start and end of the sector span if they are on exact compass po
ints | 963 // bump the start and end of the sector span if they are on exact compass po
ints |
960 if ((fSectorStart & 3) == 3) { | 964 if ((fSectorStart & 3) == 3) { |
(...skipping 156 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1117 angle->setID(++fCount); | 1121 angle->setID(++fCount); |
1118 #endif | 1122 #endif |
1119 return *angle; | 1123 return *angle; |
1120 } | 1124 } |
1121 | 1125 |
1122 void SkOpAngleSet::reset() { | 1126 void SkOpAngleSet::reset() { |
1123 if (fAngles) { | 1127 if (fAngles) { |
1124 fAngles->reset(); | 1128 fAngles->reset(); |
1125 } | 1129 } |
1126 } | 1130 } |
OLD | NEW |