diff options
Diffstat (limited to 'libsgl/sgl/SkRegion_path.cpp')
-rw-r--r-- | libsgl/sgl/SkRegion_path.cpp | 37 |
1 files changed, 30 insertions, 7 deletions
diff --git a/libsgl/sgl/SkRegion_path.cpp b/libsgl/sgl/SkRegion_path.cpp index 6f56bff..d00baf9 100644 --- a/libsgl/sgl/SkRegion_path.cpp +++ b/libsgl/sgl/SkRegion_path.cpp @@ -25,7 +25,8 @@ class SkRgnBuilder : public SkBlitter { public: virtual ~SkRgnBuilder(); - void init(int maxHeight, int maxTransitions); + // returns true if it could allocate the working storage needed + bool init(int maxHeight, int maxTransitions); void done() { if (fCurrScanline != NULL) { @@ -96,15 +97,33 @@ SkRgnBuilder::~SkRgnBuilder() { sk_free(fStorage); } -void SkRgnBuilder::init(int maxHeight, int maxTransitions) { - int count = maxHeight * (3 + maxTransitions); +bool SkRgnBuilder::init(int maxHeight, int maxTransitions) { + if ((maxHeight | maxTransitions) < 0) { + return false; + } + + Sk64 count, size; + + // compute the count with +1 and +3 slop for the working buffer + count.setMul(maxHeight + 1, 3 + maxTransitions); + if (!count.is32() || count.isNeg()) { + return false; + } + fStorageCount = count.get32(); - // add maxTransitions to have slop for working buffer - fStorageCount = count + 3 + maxTransitions; - fStorage = (SkRegion::RunType*)sk_malloc_throw(fStorageCount * sizeof(SkRegion::RunType)); + size.setMul(fStorageCount, sizeof(SkRegion::RunType)); + if (!size.is32() || size.isNeg()) { + return false; + } + + fStorage = (SkRegion::RunType*)sk_malloc_flags(size.get32(), 0); + if (NULL == fStorage) { + return false; + } fCurrScanline = NULL; // signal empty collection fPrevScanline = NULL; // signal first scanline + return true; } void SkRgnBuilder::blitH(int x, int y, int width) { @@ -275,7 +294,11 @@ bool SkRegion::setPath(const SkPath& path, const SkRegion& clip) { SkRgnBuilder builder; - builder.init(bot - top, SkMax32(pathTransitions, clipTransitions)); + if (!builder.init(bot - top, SkMax32(pathTransitions, clipTransitions))) { + // can't allocate working space, so return false + return this->setEmpty(); + } + SkScan::FillPath(path, clip, &builder); builder.done(); |