diff options
Diffstat (limited to 'src/core')
-rw-r--r-- | src/core/SkMaskBlurFilter.cpp | 62 |
1 files changed, 37 insertions, 25 deletions
diff --git a/src/core/SkMaskBlurFilter.cpp b/src/core/SkMaskBlurFilter.cpp index 282f395792..604a44b47e 100644 --- a/src/core/SkMaskBlurFilter.cpp +++ b/src/core/SkMaskBlurFilter.cpp @@ -542,46 +542,58 @@ bool SkMaskBlurFilter::hasNoBlur() const { return (3 * fSigmaW <= 1) && (3 * fSigmaH <= 1); } -SkIPoint SkMaskBlurFilter::blur(const SkMask& src, SkMask* dst) const { +static SkMask prepare_destination(int radiusX, int radiusY, const SkMask& src) { + SkSafeMath safe; - // 1024 is a place holder guess until more analysis can be done. - SkSTArenaAlloc<1024> alloc; + SkMask dst; + // dstW = srcW + 2 * radiusX; + int dstW = safe.add(src.fBounds.width(), safe.add(radiusX, radiusX)); + // dstH = srcH + 2 * radiusY; + int dstH = safe.add(src.fBounds.height(), safe.add(radiusY, radiusY)); - PlanningInterface* planW = make_plan(&alloc, fSigmaW); - PlanningInterface* planH = make_plan(&alloc, fSigmaH); + dst.fBounds.set(0, 0, dstW, dstH); + dst.fBounds.offset(src.fBounds.x(), src.fBounds.y()); + dst.fBounds.offset(-SkTo<int32_t>(radiusX), -SkTo<int32_t>(radiusY)); - size_t borderW = planW->border(); - size_t borderH = planH->border(); + dst.fImage = nullptr; + dst.fRowBytes = SkTo<uint32_t>(dstW); + dst.fFormat = SkMask::kA8_Format; - auto srcW = SkTo<size_t>(src.fBounds.width()); - auto srcH = SkTo<size_t>(src.fBounds.height()); + size_t toAlloc = safe.mul(dstW, dstH); - SkSafeMath safe; + if (safe) { + dst.fImage = SkMask::AllocImage(toAlloc); + } else{ + dst.fBounds = SkIRect::MakeEmpty(); + } + return dst; +} - // size_t dstW = srcW + 2 * borderW; - size_t dstW = safe.add(srcW, safe.add(borderW, borderW)); - //size_t dstH = srcH + 2 * borderH; - size_t dstH = safe.add(srcH, safe.add(borderH, borderH)); +SkIPoint SkMaskBlurFilter::blur(const SkMask& src, SkMask* dst) const { + + // 1024 is a place holder guess until more analysis can be done. + SkSTArenaAlloc<1024> alloc; - dst->fBounds.set(0, 0, dstW, dstH); - dst->fBounds.offset(src.fBounds.x(), src.fBounds.y()); - dst->fBounds.offset(-SkTo<int32_t>(borderW), -SkTo<int32_t>(borderH)); + PlanningInterface* planW = make_plan(&alloc, fSigmaW); + PlanningInterface* planH = make_plan(&alloc, fSigmaH); - dst->fImage = nullptr; - dst->fRowBytes = SkTo<uint32_t>(dstW); - dst->fFormat = SkMask::kA8_Format; + size_t borderW = planW->border(), + borderH = planH->border(); if (src.fImage == nullptr) { return {SkTo<int32_t>(borderW), SkTo<int32_t>(borderH)}; } - size_t toAlloc = safe.mul(dstW, dstH); - if (!safe) { - dst->fBounds = SkIRect::MakeEmpty(); - // There is no border offset because we are not drawing. + *dst = prepare_destination(borderW, borderH, src); + if (dst->fImage == nullptr) { return {0, 0}; } - dst->fImage = SkMask::AllocImage(toAlloc); + + auto srcW = SkTo<size_t>(src.fBounds.width()); + auto srcH = SkTo<size_t>(src.fBounds.height()); + + size_t dstW = dst->fBounds.width(), + dstH = dst->fBounds.height(); auto bufferSize = std::max(planW->bufferSize(), planH->bufferSize()); auto buffer = alloc.makeArrayDefault<uint32_t>(bufferSize); |