53 , fRespectCTM(respectCTM) {
80 const float ctmScaleFactor = fSigma / ctm.
mapRadius(fSigma);
81 sigma *= ctmScaleFactor;
106 return std::min(xformedSigma, kMaxBlurSigma);
137 mask->
bounds() = bounds.roundOut();
142 if (
nullptr == mask->
fImage) {
171 paint.setAntiAlias(
true);
194 draw.drawRRect(rrect, paint);
207 memcpy(data->writable_data(), mask->
fImage, size);
209 mask->
image() = (uint8_t*)data->writable_data();
285 bool filterResult =
false;
289 filterResult = this->filterRRectMask(&dstM, rrect, matrix, &margin,
294 filterResult = this->
filterMask(&dstM, srcM, matrix, &margin);
316 const SkScalar totalSmallWidth = leftUnstretched + rightUnstretched + stretchSize;
317 if (totalSmallWidth >= rrect.
rect().
width()) {
325 const SkScalar totalSmallHeight = topUnstretched + bottomUnstretched + stretchSize;
326 if (totalSmallHeight >= rrect.
rect().
height()) {
346 bool analyticBlurWorked =
false;
349 this->filterRRectMask(&filterM, smallRR, matrix, &margin,
353 if (!analyticBlurWorked) {
359 if (!this->
filterMask(&filterM, srcM, matrix, &margin)) {
364 cachedMask.
init(filterM);
367 SkIRect bounds = cachedMask->fBounds;
368 bounds.offsetTo(0, 0);
369 patch->
init(
SkMask{cachedMask->fImage, bounds, cachedMask->fRowBytes, cachedMask->fFormat},
385 if (count < 1 || count > 2) {
404 bool filterResult =
false;
408 filterResult = this->filterRectMask(&dstM, rects[0], matrix, &margin,
411 filterResult = this->
filterMask(&dstM, srcM, matrix, &margin);
436 int smallW = dstM.
fBounds.
width() - srcM.fBounds.width() + 2;
437 int smallH = dstM.
fBounds.
height() - srcM.fBounds.height() + 2;
441 innerIR = srcM.fBounds;
442 center.set(smallW, smallH);
446 center.set(smallW + (innerIR.
left() - srcM.fBounds.left()),
447 smallH + (innerIR.
top() - srcM.fBounds.top()));
458 if (dx < 0 || dy < 0) {
465 rects[0].
right() - dx, rects[0].bottom() - dy);
466 if (smallR[0].
width() < 2 || smallR[0].
height() < 2) {
471 rects[1].
right() - dx, rects[1].bottom() - dy);
487 if (!this->
filterMask(&filterM, srcM, matrix, &margin)) {
491 if (!this->filterRectMask(&filterM, smallR[0], matrix, &margin,
497 cachedMask.
init(filterM);
499 SkIRect bounds = cachedMask->fBounds;
500 bounds.offsetTo(0, 0);
501 patch->
init(
SkMask{cachedMask->fImage, bounds, cachedMask->fRowBytes, cachedMask->fFormat},
513 dst->setLTRB(src.fLeft - pad, src.fTop - pad,
514 src.fRight + pad, src.fBottom + pad);
522 bool respectCTM = !(
flags & 1);
528 buffer.writeScalar(fSigma);
529 buffer.writeUInt(fBlurStyle);
530 buffer.writeUInt(!fRespectCTM);
static void info(const char *fmt,...) SK_PRINTF_LIKE(1
static constexpr T SkAlign4(T x)
@ kSrcOver
r = s + (1-sa)*d
SkBlitter * SkA8Blitter_Choose(const SkPixmap &dst, const SkMatrix &ctm, const SkPaint &paint, SkArenaAlloc *alloc, bool drawCoverage, sk_sp< SkShader > clipShader, const SkSurfaceProps &)
static SkCachedData * find_cached_rects(SkTLazy< SkMask > *mask, SkScalar sigma, SkBlurStyle style, const SkRect rects[], int count)
static bool draw_rrect_into_mask(const SkRRect rrect, SkMaskBuilder *mask)
static bool rect_exceeds(const SkRect &r, SkScalar v)
static SkCachedData * add_cached_rrect(SkMaskBuilder *mask, SkScalar sigma, SkBlurStyle style, const SkRRect &rrect)
bool draw_into_mask(SkMaskBuilder *mask, const SkRect &bounds, Proc proc)
static bool draw_rects_into_mask(const SkRect rects[], int count, SkMaskBuilder *mask)
static SkCachedData * add_cached_rects(SkMaskBuilder *mask, SkScalar sigma, SkBlurStyle style, const SkRect rects[], int count)
static const bool c_analyticBlurRRect
static SkCachedData * copy_mask_to_cacheddata(SkMaskBuilder *mask)
static const bool c_analyticBlurNinepatch
void sk_register_blur_maskfilter_createproc()
static bool prepare_to_draw_into_mask(const SkRect &bounds, SkMaskBuilder *mask)
static SkCachedData * find_cached_rrect(SkTLazy< SkMask > *mask, SkScalar sigma, SkBlurStyle style, const SkRRect &rrect)
@ kOuter_SkBlurStyle
nothing inside, fuzzy outside
@ kSolid_SkBlurStyle
solid inside, fuzzy outside
@ kInner_SkBlurStyle
fuzzy inside, nothing outside
@ kNormal_SkBlurStyle
fuzzy inside and outside
#define SK_REGISTER_FLATTENABLE(type)
static bool SkIsFinite(T x, Pack... values)
std::unique_ptr< uint8_t, SkFunctionObject< SkMaskBuilder::FreeImage > > SkAutoMaskFreeImage
static bool left(const SkPoint &p0, const SkPoint &p1)
static bool right(const SkPoint &p0, const SkPoint &p1)
#define SkScalarCeilToInt(x)
static SkScalar center(float pos0, float pos1)
static void draw(SkCanvas *canvas, SkRect &target, int x, int y)
void(* Proc)(SkCanvas *, const SkRect &, const SkPaint &)
FilterReturn filterRRectToNine(const SkRRect &, const SkMatrix &, const SkIRect &clipBounds, SkTLazy< NinePatch > *) const override
void flatten(SkWriteBuffer &) const override
SkMask::Format getFormat() const override
bool asABlur(BlurRec *) const override
SkBlurMaskFilterImpl(SkScalar sigma, SkBlurStyle, bool respectCTM)
sk_sp< SkImageFilter > asImageFilter(const SkMatrix &ctm) const override
bool filterMask(SkMaskBuilder *dst, const SkMask &src, const SkMatrix &, SkIPoint *margin) const override
SkScalar computeXformedSigma(const SkMatrix &ctm) const
void computeFastBounds(const SkRect &, SkRect *) const override
FilterReturn filterRectsToNine(const SkRect[], int count, const SkMatrix &, const SkIRect &clipBounds, SkTLazy< NinePatch > *) const override
static bool BlurRect(SkScalar sigma, SkMaskBuilder *dst, const SkRect &src, SkBlurStyle, SkIPoint *margin=nullptr, SkMaskBuilder::CreateMode createMode=SkMaskBuilder::kComputeBoundsAndRenderImage_CreateMode)
static bool BlurRRect(SkScalar sigma, SkMaskBuilder *dst, const SkRRect &src, SkBlurStyle, SkIPoint *margin=nullptr, SkMaskBuilder::CreateMode createMode=SkMaskBuilder::kComputeBoundsAndRenderImage_CreateMode)
static bool BoxBlur(SkMaskBuilder *dst, const SkMask &src, SkScalar sigma, SkBlurStyle style, SkIPoint *margin=nullptr)
BlitterChooser * fBlitterChooser
static sk_sp< SkImageFilter > Blur(SkScalar sigmaX, SkScalar sigmaY, SkTileMode tileMode, sk_sp< SkImageFilter > input, const CropRect &cropRect={})
static sk_sp< SkImageFilter > Blend(SkBlendMode mode, sk_sp< SkImageFilter > background, sk_sp< SkImageFilter > foreground=nullptr, const CropRect &cropRect={})
static void Add(SkScalar sigma, SkBlurStyle style, const SkRRect &rrect, const SkMask &mask, SkCachedData *data, SkResourceCache *localCache=nullptr)
static SkCachedData * FindAndRef(SkScalar sigma, SkBlurStyle style, const SkRRect &rrect, SkTLazy< SkMask > *mask, SkResourceCache *localCache=nullptr)
@ kUnimplemented_FilterReturn
static sk_sp< SkMaskFilter > MakeBlur(SkBlurStyle style, SkScalar sigma, bool respectCTM=true)
SkScalar mapRadius(SkScalar radius) const
static SkMatrix Translate(SkScalar dx, SkScalar dy)
SkPathBuilder & addRect(const SkRect &, SkPathDirection, unsigned startIndex)
SkPathBuilder & setFillType(SkPathFillType ft)
const SkRect & rect() const
SkVector radii(Corner corner) const
@ kOval_Type
non-zero width and height filled with radii
@ kSimple_Type
non-zero width and height with equal radii
@ kEmpty_Type
zero width or height
@ kNinePatch_Type
non-zero width and height with axis-aligned radii
@ kRect_Type
non-zero width and height, and zeroed radii
@ kComplex_Type
non-zero width and height with arbitrary radii
@ kUpperLeft_Corner
index of top-left corner radii
@ kLowerRight_Corner
index of bottom-right corner radii
@ kUpperRight_Corner
index of top-right corner radii
@ kLowerLeft_Corner
index of bottom-left corner radii
void setRectRadii(const SkRect &rect, const SkVector radii[4])
bool setRect(const SkIRect &)
static SkCachedData * NewCachedData(size_t bytes)
T * init(Args &&... args)
FlutterSemanticsFlag flags
static const uint8_t buffer[]
constexpr int32_t top() const
constexpr int32_t height() const
int32_t fTop
smaller y-axis bounds
constexpr int32_t width() const
constexpr SkIRect makeOffset(int32_t dx, int32_t dy) const
int32_t fLeft
smaller x-axis bounds
constexpr int32_t left() const
static SkImageInfo MakeA8(int width, int height)
static void FreeImage(void *image)
@ kComputeBoundsAndRenderImage_CreateMode
compute bounds, alloc image and render into it
@ kJustComputeBounds_CreateMode
compute bounds and return
static uint8_t * AllocImage(size_t bytes, AllocType=kUninit_Alloc)
@ kA8_Format
8bits per pixel mask (e.g. antialiasing)
uint8_t const *const fImage
size_t computeTotalImageSize() const
size_t computeImageSize() const
SkScalar fBottom
larger y-axis bounds
void roundIn(SkIRect *dst) const
SkScalar fLeft
smaller x-axis bounds
SkScalar fRight
larger x-axis bounds
void roundOut(SkIRect *dst) const
constexpr float height() const
void setLTRB(float left, float top, float right, float bottom)
constexpr float width() const
static constexpr SkRect MakeWH(float w, float h)
SkScalar fTop
smaller y-axis bounds