OLD | NEW |
1 /* | 1 /* |
2 * Copyright 2006 The Android Open Source Project | 2 * Copyright 2006 The Android Open Source Project |
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 | 7 |
8 #include "SkRegionPriv.h" | 8 #include "SkRegionPriv.h" |
9 #include "SkBlitter.h" | 9 #include "SkBlitter.h" |
10 #include "SkScan.h" | 10 #include "SkScan.h" |
(...skipping 14 matching lines...) Expand all Loading... |
25 | 25 |
26 class SkRgnBuilder : public SkBlitter { | 26 class SkRgnBuilder : public SkBlitter { |
27 public: | 27 public: |
28 SkRgnBuilder(); | 28 SkRgnBuilder(); |
29 virtual ~SkRgnBuilder(); | 29 virtual ~SkRgnBuilder(); |
30 | 30 |
31 // returns true if it could allocate the working storage needed | 31 // returns true if it could allocate the working storage needed |
32 bool init(int maxHeight, int maxTransitions, bool pathIsInverse); | 32 bool init(int maxHeight, int maxTransitions, bool pathIsInverse); |
33 | 33 |
34 void done() { | 34 void done() { |
35 if (fCurrScanline != NULL) { | 35 if (fCurrScanline != nullptr) { |
36 fCurrScanline->fXCount = (SkRegion::RunType)((int)(fCurrXPtr - fCurr
Scanline->firstX())); | 36 fCurrScanline->fXCount = (SkRegion::RunType)((int)(fCurrXPtr - fCurr
Scanline->firstX())); |
37 if (!this->collapsWithPrev()) { // flush the last line | 37 if (!this->collapsWithPrev()) { // flush the last line |
38 fCurrScanline = fCurrScanline->nextScanline(); | 38 fCurrScanline = fCurrScanline->nextScanline(); |
39 } | 39 } |
40 } | 40 } |
41 } | 41 } |
42 | 42 |
43 int computeRunCount() const; | 43 int computeRunCount() const; |
44 void copyToRect(SkIRect*) const; | 44 void copyToRect(SkIRect*) const; |
45 void copyToRgn(SkRegion::RunType runs[]) const; | 45 void copyToRgn(SkRegion::RunType runs[]) const; |
(...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
87 SkRegion::RunType* fStorage; | 87 SkRegion::RunType* fStorage; |
88 Scanline* fCurrScanline; | 88 Scanline* fCurrScanline; |
89 Scanline* fPrevScanline; | 89 Scanline* fPrevScanline; |
90 // points at next avialable x[] in fCurrScanline | 90 // points at next avialable x[] in fCurrScanline |
91 SkRegion::RunType* fCurrXPtr; | 91 SkRegion::RunType* fCurrXPtr; |
92 SkRegion::RunType fTop; // first Y value | 92 SkRegion::RunType fTop; // first Y value |
93 | 93 |
94 int fStorageCount; | 94 int fStorageCount; |
95 | 95 |
96 bool collapsWithPrev() { | 96 bool collapsWithPrev() { |
97 if (fPrevScanline != NULL && | 97 if (fPrevScanline != nullptr && |
98 fPrevScanline->fLastY + 1 == fCurrScanline->fLastY && | 98 fPrevScanline->fLastY + 1 == fCurrScanline->fLastY && |
99 fPrevScanline->fXCount == fCurrScanline->fXCount && | 99 fPrevScanline->fXCount == fCurrScanline->fXCount && |
100 sk_memeq32(fPrevScanline->firstX(), fCurrScanline->firstX(), fCurrSc
anline->fXCount)) | 100 sk_memeq32(fPrevScanline->firstX(), fCurrScanline->firstX(), fCurrSc
anline->fXCount)) |
101 { | 101 { |
102 // update the height of fPrevScanline | 102 // update the height of fPrevScanline |
103 fPrevScanline->fLastY = fCurrScanline->fLastY; | 103 fPrevScanline->fLastY = fCurrScanline->fLastY; |
104 return true; | 104 return true; |
105 } | 105 } |
106 return false; | 106 return false; |
107 } | 107 } |
108 }; | 108 }; |
109 | 109 |
110 SkRgnBuilder::SkRgnBuilder() | 110 SkRgnBuilder::SkRgnBuilder() |
111 : fStorage(NULL) { | 111 : fStorage(nullptr) { |
112 } | 112 } |
113 | 113 |
114 SkRgnBuilder::~SkRgnBuilder() { | 114 SkRgnBuilder::~SkRgnBuilder() { |
115 sk_free(fStorage); | 115 sk_free(fStorage); |
116 } | 116 } |
117 | 117 |
118 bool SkRgnBuilder::init(int maxHeight, int maxTransitions, bool pathIsInverse) { | 118 bool SkRgnBuilder::init(int maxHeight, int maxTransitions, bool pathIsInverse) { |
119 if ((maxHeight | maxTransitions) < 0) { | 119 if ((maxHeight | maxTransitions) < 0) { |
120 return false; | 120 return false; |
121 } | 121 } |
(...skipping 18 matching lines...) Expand all Loading... |
140 return false; | 140 return false; |
141 } | 141 } |
142 fStorageCount = sk_64_asS32(count); | 142 fStorageCount = sk_64_asS32(count); |
143 | 143 |
144 int64_t size = sk_64_mul(fStorageCount, sizeof(SkRegion::RunType)); | 144 int64_t size = sk_64_mul(fStorageCount, sizeof(SkRegion::RunType)); |
145 if (size < 0 || !sk_64_isS32(size)) { | 145 if (size < 0 || !sk_64_isS32(size)) { |
146 return false; | 146 return false; |
147 } | 147 } |
148 | 148 |
149 fStorage = (SkRegion::RunType*)sk_malloc_flags(sk_64_asS32(size), 0); | 149 fStorage = (SkRegion::RunType*)sk_malloc_flags(sk_64_asS32(size), 0); |
150 if (NULL == fStorage) { | 150 if (nullptr == fStorage) { |
151 return false; | 151 return false; |
152 } | 152 } |
153 | 153 |
154 fCurrScanline = NULL; // signal empty collection | 154 fCurrScanline = nullptr; // signal empty collection |
155 fPrevScanline = NULL; // signal first scanline | 155 fPrevScanline = nullptr; // signal first scanline |
156 return true; | 156 return true; |
157 } | 157 } |
158 | 158 |
159 void SkRgnBuilder::blitH(int x, int y, int width) { | 159 void SkRgnBuilder::blitH(int x, int y, int width) { |
160 if (fCurrScanline == NULL) { // first time | 160 if (fCurrScanline == nullptr) { // first time |
161 fTop = (SkRegion::RunType)(y); | 161 fTop = (SkRegion::RunType)(y); |
162 fCurrScanline = (Scanline*)fStorage; | 162 fCurrScanline = (Scanline*)fStorage; |
163 fCurrScanline->fLastY = (SkRegion::RunType)(y); | 163 fCurrScanline->fLastY = (SkRegion::RunType)(y); |
164 fCurrXPtr = fCurrScanline->firstX(); | 164 fCurrXPtr = fCurrScanline->firstX(); |
165 } else { | 165 } else { |
166 SkASSERT(y >= fCurrScanline->fLastY); | 166 SkASSERT(y >= fCurrScanline->fLastY); |
167 | 167 |
168 if (y > fCurrScanline->fLastY) { | 168 if (y > fCurrScanline->fLastY) { |
169 // if we get here, we're done with fCurrScanline | 169 // if we get here, we're done with fCurrScanline |
170 fCurrScanline->fXCount = (SkRegion::RunType)((int)(fCurrXPtr - fCurr
Scanline->firstX())); | 170 fCurrScanline->fXCount = (SkRegion::RunType)((int)(fCurrXPtr - fCurr
Scanline->firstX())); |
(...skipping 19 matching lines...) Expand all Loading... |
190 fCurrXPtr[-1] = (SkRegion::RunType)(x + width); | 190 fCurrXPtr[-1] = (SkRegion::RunType)(x + width); |
191 } else { | 191 } else { |
192 fCurrXPtr[0] = (SkRegion::RunType)(x); | 192 fCurrXPtr[0] = (SkRegion::RunType)(x); |
193 fCurrXPtr[1] = (SkRegion::RunType)(x + width); | 193 fCurrXPtr[1] = (SkRegion::RunType)(x + width); |
194 fCurrXPtr += 2; | 194 fCurrXPtr += 2; |
195 } | 195 } |
196 SkASSERT(fCurrXPtr - fStorage < fStorageCount); | 196 SkASSERT(fCurrXPtr - fStorage < fStorageCount); |
197 } | 197 } |
198 | 198 |
199 int SkRgnBuilder::computeRunCount() const { | 199 int SkRgnBuilder::computeRunCount() const { |
200 if (fCurrScanline == NULL) { | 200 if (fCurrScanline == nullptr) { |
201 return 0; | 201 return 0; |
202 } | 202 } |
203 | 203 |
204 const SkRegion::RunType* line = fStorage; | 204 const SkRegion::RunType* line = fStorage; |
205 const SkRegion::RunType* stop = (const SkRegion::RunType*)fCurrScanline; | 205 const SkRegion::RunType* stop = (const SkRegion::RunType*)fCurrScanline; |
206 | 206 |
207 return 2 + (int)(stop - line); | 207 return 2 + (int)(stop - line); |
208 } | 208 } |
209 | 209 |
210 void SkRgnBuilder::copyToRect(SkIRect* r) const { | 210 void SkRgnBuilder::copyToRect(SkIRect* r) const { |
211 SkASSERT(fCurrScanline != NULL); | 211 SkASSERT(fCurrScanline != nullptr); |
212 // A rect's scanline is [bottom intervals left right sentinel] == 5 | 212 // A rect's scanline is [bottom intervals left right sentinel] == 5 |
213 SkASSERT((const SkRegion::RunType*)fCurrScanline - fStorage == 5); | 213 SkASSERT((const SkRegion::RunType*)fCurrScanline - fStorage == 5); |
214 | 214 |
215 const Scanline* line = (const Scanline*)fStorage; | 215 const Scanline* line = (const Scanline*)fStorage; |
216 SkASSERT(line->fXCount == 2); | 216 SkASSERT(line->fXCount == 2); |
217 | 217 |
218 r->set(line->firstX()[0], fTop, line->firstX()[1], line->fLastY + 1); | 218 r->set(line->firstX()[0], fTop, line->firstX()[1], line->fLastY + 1); |
219 } | 219 } |
220 | 220 |
221 void SkRgnBuilder::copyToRgn(SkRegion::RunType runs[]) const { | 221 void SkRgnBuilder::copyToRgn(SkRegion::RunType runs[]) const { |
222 SkASSERT(fCurrScanline != NULL); | 222 SkASSERT(fCurrScanline != nullptr); |
223 SkASSERT((const SkRegion::RunType*)fCurrScanline - fStorage > 4); | 223 SkASSERT((const SkRegion::RunType*)fCurrScanline - fStorage > 4); |
224 | 224 |
225 const Scanline* line = (const Scanline*)fStorage; | 225 const Scanline* line = (const Scanline*)fStorage; |
226 const Scanline* stop = fCurrScanline; | 226 const Scanline* stop = fCurrScanline; |
227 | 227 |
228 *runs++ = fTop; | 228 *runs++ = fTop; |
229 do { | 229 do { |
230 *runs++ = (SkRegion::RunType)(line->fLastY + 1); | 230 *runs++ = (SkRegion::RunType)(line->fLastY + 1); |
231 int count = line->fXCount; | 231 int count = line->fXCount; |
232 *runs++ = count >> 1; // intervalCount | 232 *runs++ = count >> 1; // intervalCount |
(...skipping 157 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
390 uint8_t fFlags; | 390 uint8_t fFlags; |
391 Edge* fNext; | 391 Edge* fNext; |
392 | 392 |
393 void set(int x, int y0, int y1) { | 393 void set(int x, int y0, int y1) { |
394 SkASSERT(y0 != y1); | 394 SkASSERT(y0 != y1); |
395 | 395 |
396 fX = (SkRegion::RunType)(x); | 396 fX = (SkRegion::RunType)(x); |
397 fY0 = (SkRegion::RunType)(y0); | 397 fY0 = (SkRegion::RunType)(y0); |
398 fY1 = (SkRegion::RunType)(y1); | 398 fY1 = (SkRegion::RunType)(y1); |
399 fFlags = 0; | 399 fFlags = 0; |
400 SkDEBUGCODE(fNext = NULL;) | 400 SkDEBUGCODE(fNext = nullptr;) |
401 } | 401 } |
402 | 402 |
403 int top() const { | 403 int top() const { |
404 return SkFastMin32(fY0, fY1); | 404 return SkFastMin32(fY0, fY1); |
405 } | 405 } |
406 }; | 406 }; |
407 | 407 |
408 static void find_link(Edge* base, Edge* stop) { | 408 static void find_link(Edge* base, Edge* stop) { |
409 SkASSERT(base < stop); | 409 SkASSERT(base < stop); |
410 | 410 |
411 if (base->fFlags == Edge::kCompleteLink) { | 411 if (base->fFlags == Edge::kCompleteLink) { |
412 SkASSERT(base->fNext); | 412 SkASSERT(base->fNext); |
413 return; | 413 return; |
414 } | 414 } |
415 | 415 |
416 SkASSERT(base + 1 < stop); | 416 SkASSERT(base + 1 < stop); |
417 | 417 |
418 int y0 = base->fY0; | 418 int y0 = base->fY0; |
419 int y1 = base->fY1; | 419 int y1 = base->fY1; |
420 | 420 |
421 Edge* e = base; | 421 Edge* e = base; |
422 if ((base->fFlags & Edge::kY0Link) == 0) { | 422 if ((base->fFlags & Edge::kY0Link) == 0) { |
423 for (;;) { | 423 for (;;) { |
424 e += 1; | 424 e += 1; |
425 if ((e->fFlags & Edge::kY1Link) == 0 && y0 == e->fY1) { | 425 if ((e->fFlags & Edge::kY1Link) == 0 && y0 == e->fY1) { |
426 SkASSERT(NULL == e->fNext); | 426 SkASSERT(nullptr == e->fNext); |
427 e->fNext = base; | 427 e->fNext = base; |
428 e->fFlags = SkToU8(e->fFlags | Edge::kY1Link); | 428 e->fFlags = SkToU8(e->fFlags | Edge::kY1Link); |
429 break; | 429 break; |
430 } | 430 } |
431 } | 431 } |
432 } | 432 } |
433 | 433 |
434 e = base; | 434 e = base; |
435 if ((base->fFlags & Edge::kY1Link) == 0) { | 435 if ((base->fFlags & Edge::kY1Link) == 0) { |
436 for (;;) { | 436 for (;;) { |
437 e += 1; | 437 e += 1; |
438 if ((e->fFlags & Edge::kY0Link) == 0 && y1 == e->fY0) { | 438 if ((e->fFlags & Edge::kY0Link) == 0 && y1 == e->fY0) { |
439 SkASSERT(NULL == base->fNext); | 439 SkASSERT(nullptr == base->fNext); |
440 base->fNext = e; | 440 base->fNext = e; |
441 e->fFlags = SkToU8(e->fFlags | Edge::kY0Link); | 441 e->fFlags = SkToU8(e->fFlags | Edge::kY0Link); |
442 break; | 442 break; |
443 } | 443 } |
444 } | 444 } |
445 } | 445 } |
446 | 446 |
447 base->fFlags = Edge::kCompleteLink; | 447 base->fFlags = Edge::kCompleteLink; |
448 } | 448 } |
449 | 449 |
(...skipping 27 matching lines...) Expand all Loading... |
477 return count; | 477 return count; |
478 } | 478 } |
479 | 479 |
480 struct EdgeLT { | 480 struct EdgeLT { |
481 bool operator()(const Edge& a, const Edge& b) const { | 481 bool operator()(const Edge& a, const Edge& b) const { |
482 return (a.fX == b.fX) ? a.top() < b.top() : a.fX < b.fX; | 482 return (a.fX == b.fX) ? a.top() < b.top() : a.fX < b.fX; |
483 } | 483 } |
484 }; | 484 }; |
485 | 485 |
486 bool SkRegion::getBoundaryPath(SkPath* path) const { | 486 bool SkRegion::getBoundaryPath(SkPath* path) const { |
487 // path could safely be NULL if we're empty, but the caller shouldn't | 487 // path could safely be nullptr if we're empty, but the caller shouldn't |
488 // *know* that | 488 // *know* that |
489 SkASSERT(path); | 489 SkASSERT(path); |
490 | 490 |
491 if (this->isEmpty()) { | 491 if (this->isEmpty()) { |
492 return false; | 492 return false; |
493 } | 493 } |
494 | 494 |
495 const SkIRect& bounds = this->getBounds(); | 495 const SkIRect& bounds = this->getBounds(); |
496 | 496 |
497 if (this->isRect()) { | 497 if (this->isRect()) { |
(...skipping 17 matching lines...) Expand all Loading... |
515 Edge* stop = start + count; | 515 Edge* stop = start + count; |
516 SkTQSort<Edge>(start, stop - 1, EdgeLT()); | 516 SkTQSort<Edge>(start, stop - 1, EdgeLT()); |
517 | 517 |
518 Edge* e; | 518 Edge* e; |
519 for (e = start; e != stop; e++) { | 519 for (e = start; e != stop; e++) { |
520 find_link(e, stop); | 520 find_link(e, stop); |
521 } | 521 } |
522 | 522 |
523 #ifdef SK_DEBUG | 523 #ifdef SK_DEBUG |
524 for (e = start; e != stop; e++) { | 524 for (e = start; e != stop; e++) { |
525 SkASSERT(e->fNext != NULL); | 525 SkASSERT(e->fNext != nullptr); |
526 SkASSERT(e->fFlags == Edge::kCompleteLink); | 526 SkASSERT(e->fFlags == Edge::kCompleteLink); |
527 } | 527 } |
528 #endif | 528 #endif |
529 | 529 |
530 path->incReserve(count << 1); | 530 path->incReserve(count << 1); |
531 do { | 531 do { |
532 SkASSERT(count > 1); | 532 SkASSERT(count > 1); |
533 count -= extract_path(start, stop, path); | 533 count -= extract_path(start, stop, path); |
534 } while (count > 0); | 534 } while (count > 0); |
535 | 535 |
536 return true; | 536 return true; |
537 } | 537 } |
OLD | NEW |