/*
 * Copyright 2023 Google LLC
 *
 * Use of this source code is governed by a BSD-style license that can be
 * found in the LICENSE file.
 */

#ifndef SkBlurMaskFilterImpl_DEFINED
#define SkBlurMaskFilterImpl_DEFINED

#include "include/core/SkFlattenable.h"
#include "include/core/SkScalar.h"
#include "src/core/SkMask.h"
#include "src/core/SkMaskFilterBase.h"
class SkMatrix;
class SkRRect;
class SkReadBuffer;
class SkWriteBuffer;
enum SkBlurStyle : int;
struct SkIPoint;
struct SkIRect;
struct SkRect;

class SkBlurMaskFilterImpl : public SkMaskFilterBase {
public:
    SkBlurMaskFilterImpl(SkScalar sigma, SkBlurStyle, bool respectCTM);

    // From SkMaskFilterBase.h
    SkMask::Format getFormat() const override;
    bool filterMask(SkMask* dst, const SkMask& src, const SkMatrix&,
                    SkIPoint* margin) const override;
    SkMaskFilterBase::Type type() const override { return SkMaskFilterBase::Type::kBlur; }

    void computeFastBounds(const SkRect&, SkRect*) const override;
    bool asABlur(BlurRec*) const override;


    SkScalar computeXformedSigma(const SkMatrix& ctm) const;
    SkBlurStyle blurStyle() const {return fBlurStyle;}
    SkScalar sigma() const {return fSigma;}
    bool ignoreXform() const { return !fRespectCTM; }

private:
    FilterReturn filterRectsToNine(const SkRect[], int count, const SkMatrix&,
                                   const SkIRect& clipBounds,
                                   NinePatch*) const override;

    FilterReturn filterRRectToNine(const SkRRect&, const SkMatrix&,
                                   const SkIRect& clipBounds,
                                   NinePatch*) const override;

    bool filterRectMask(SkMask* dstM, const SkRect& r, const SkMatrix& matrix,
                        SkIPoint* margin, SkMask::CreateMode createMode) const;
    bool filterRRectMask(SkMask* dstM, const SkRRect& r, const SkMatrix& matrix,
                        SkIPoint* margin, SkMask::CreateMode createMode) const;

    SK_FLATTENABLE_HOOKS(SkBlurMaskFilterImpl)

    SkScalar    fSigma;
    SkBlurStyle fBlurStyle;
    bool        fRespectCTM;

    SkBlurMaskFilterImpl(SkReadBuffer&);
    void flatten(SkWriteBuffer&) const override;

    friend class SkBlurMaskFilter;

    friend void sk_register_blur_maskfilter_createproc();
};

#endif
