| OLD | NEW |
| 1 | 1 |
| 2 /* | 2 /* |
| 3 * Copyright 2006 The Android Open Source Project | 3 * Copyright 2006 The Android Open Source Project |
| 4 * | 4 * |
| 5 * Use of this source code is governed by a BSD-style license that can be | 5 * Use of this source code is governed by a BSD-style license that can be |
| 6 * found in the LICENSE file. | 6 * found in the LICENSE file. |
| 7 */ | 7 */ |
| 8 | 8 |
| 9 | 9 |
| 10 #include "SkRegionPriv.h" | 10 #include "SkRegionPriv.h" |
| 11 #include "SkBlitter.h" | 11 #include "SkBlitter.h" |
| 12 #include "SkScan.h" | 12 #include "SkScan.h" |
| 13 #include "SkTDArray.h" | 13 #include "SkTDArray.h" |
| 14 #include "SkPath.h" | 14 #include "SkPath.h" |
| 15 | 15 |
| 16 class SkRgnBuilder : public SkBlitter { | 16 class SkRgnBuilder : public SkBlitter { |
| 17 public: | 17 public: |
| 18 virtual ~SkRgnBuilder(); | 18 virtual ~SkRgnBuilder(); |
| 19 | 19 |
| 20 // returns true if it could allocate the working storage needed | 20 // returns true if it could allocate the working storage needed |
| 21 bool init(int maxHeight, int maxTransitions); | 21 bool init(int maxHeight, int maxTransitions, bool pathIsInverse); |
| 22 | 22 |
| 23 void done() { | 23 void done() { |
| 24 if (fCurrScanline != NULL) { | 24 if (fCurrScanline != NULL) { |
| 25 fCurrScanline->fXCount = (SkRegion::RunType)((int)(fCurrXPtr - fCurr
Scanline->firstX())); | 25 fCurrScanline->fXCount = (SkRegion::RunType)((int)(fCurrXPtr - fCurr
Scanline->firstX())); |
| 26 if (!this->collapsWithPrev()) { // flush the last line | 26 if (!this->collapsWithPrev()) { // flush the last line |
| 27 fCurrScanline = fCurrScanline->nextScanline(); | 27 fCurrScanline = fCurrScanline->nextScanline(); |
| 28 } | 28 } |
| 29 } | 29 } |
| 30 } | 30 } |
| 31 | 31 |
| (...skipping 63 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 95 return true; | 95 return true; |
| 96 } | 96 } |
| 97 return false; | 97 return false; |
| 98 } | 98 } |
| 99 }; | 99 }; |
| 100 | 100 |
| 101 SkRgnBuilder::~SkRgnBuilder() { | 101 SkRgnBuilder::~SkRgnBuilder() { |
| 102 sk_free(fStorage); | 102 sk_free(fStorage); |
| 103 } | 103 } |
| 104 | 104 |
| 105 bool SkRgnBuilder::init(int maxHeight, int maxTransitions) { | 105 bool SkRgnBuilder::init(int maxHeight, int maxTransitions, bool pathIsInverse) { |
| 106 if ((maxHeight | maxTransitions) < 0) { | 106 if ((maxHeight | maxTransitions) < 0) { |
| 107 return false; | 107 return false; |
| 108 } | 108 } |
| 109 | 109 |
| 110 Sk64 count, size; | 110 Sk64 count, size; |
| 111 | 111 |
| 112 if (pathIsInverse) { |
| 113 // allow for additional X transitions to "invert" each scanline |
| 114 // [ L' ... normal transitions ... R' ] |
| 115 // |
| 116 maxTransitions += 2; |
| 117 } |
| 118 |
| 112 // compute the count with +1 and +3 slop for the working buffer | 119 // compute the count with +1 and +3 slop for the working buffer |
| 113 count.setMul(maxHeight + 1, 3 + maxTransitions); | 120 count.setMul(maxHeight + 1, 3 + maxTransitions); |
| 121 |
| 122 if (pathIsInverse) { |
| 123 // allow for two "empty" rows for the top and bottom |
| 124 // [ Y, 1, L, R, S] == 5 (*2 for top and bottom) |
| 125 count.add(10); |
| 126 } |
| 127 |
| 114 if (!count.is32() || count.isNeg()) { | 128 if (!count.is32() || count.isNeg()) { |
| 115 return false; | 129 return false; |
| 116 } | 130 } |
| 117 fStorageCount = count.get32(); | 131 fStorageCount = count.get32(); |
| 118 | 132 |
| 119 size.setMul(fStorageCount, sizeof(SkRegion::RunType)); | 133 size.setMul(fStorageCount, sizeof(SkRegion::RunType)); |
| 120 if (!size.is32() || size.isNeg()) { | 134 if (!size.is32() || size.isNeg()) { |
| 121 return false; | 135 return false; |
| 122 } | 136 } |
| 123 | 137 |
| 124 fStorage = (SkRegion::RunType*)sk_malloc_flags(size.get32(), 0); | 138 fStorage = (SkRegion::RunType*)sk_malloc_flags(size.get32(), 0); |
| 125 if (NULL == fStorage) { | 139 if (NULL == fStorage) { |
| 126 return false; | 140 return false; |
| 127 } | 141 } |
| 128 | 142 |
| 129 fCurrScanline = NULL; // signal empty collection | 143 fCurrScanline = NULL; // signal empty collection |
| 130 fPrevScanline = NULL; // signal first scanline | 144 fPrevScanline = NULL; // signal first scanline |
| 131 return true; | 145 return true; |
| 132 } | 146 } |
| 133 | 147 |
| (...skipping 171 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 305 clipTransitions = clip.count_runtype_values(&clipTop, &clipBot); | 319 clipTransitions = clip.count_runtype_values(&clipTop, &clipBot); |
| 306 | 320 |
| 307 int top = SkMax32(pathTop, clipTop); | 321 int top = SkMax32(pathTop, clipTop); |
| 308 int bot = SkMin32(pathBot, clipBot); | 322 int bot = SkMin32(pathBot, clipBot); |
| 309 | 323 |
| 310 if (top >= bot) | 324 if (top >= bot) |
| 311 return this->setEmpty(); | 325 return this->setEmpty(); |
| 312 | 326 |
| 313 SkRgnBuilder builder; | 327 SkRgnBuilder builder; |
| 314 | 328 |
| 315 if (!builder.init(bot - top, SkMax32(pathTransitions, clipTransitions))) { | 329 if (!builder.init(bot - top, |
| 330 SkMax32(pathTransitions, clipTransitions), |
| 331 path.isInverseFillType())) { |
| 316 // can't allocate working space, so return false | 332 // can't allocate working space, so return false |
| 317 return this->setEmpty(); | 333 return this->setEmpty(); |
| 318 } | 334 } |
| 319 | 335 |
| 320 SkScan::FillPath(path, clip, &builder); | 336 SkScan::FillPath(path, clip, &builder); |
| 321 builder.done(); | 337 builder.done(); |
| 322 | 338 |
| 323 int count = builder.computeRunCount(); | 339 int count = builder.computeRunCount(); |
| 324 if (count == 0) { | 340 if (count == 0) { |
| 325 return this->setEmpty(); | 341 return this->setEmpty(); |
| (...skipping 166 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 492 #endif | 508 #endif |
| 493 | 509 |
| 494 path->incReserve(count << 1); | 510 path->incReserve(count << 1); |
| 495 do { | 511 do { |
| 496 SkASSERT(count > 1); | 512 SkASSERT(count > 1); |
| 497 count -= extract_path(start, stop, path); | 513 count -= extract_path(start, stop, path); |
| 498 } while (count > 0); | 514 } while (count > 0); |
| 499 | 515 |
| 500 return true; | 516 return true; |
| 501 } | 517 } |
| OLD | NEW |