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

#include "include/core/SkString.h"
#include "src/core/SkDistanceFieldGen.h"
#include "src/core/SkMaskFilterBase.h"
#include "src/core/SkReadBuffer.h"
#include "src/core/SkSafeMath.h"
#include "src/core/SkWriteBuffer.h"
#include "src/text/gpu/SDFMaskFilter.h"

namespace sktext::gpu {

class SDFMaskFilterImpl : public SkMaskFilterBase {
public:
    SDFMaskFilterImpl();

    // overrides from SkMaskFilterBase
    //  This method is not exported to java.
    SkMask::Format getFormat() const override;
    //  This method is not exported to java.
    bool filterMask(SkMask* dst, const SkMask& src, const SkMatrix&,
                    SkIPoint* margin) const override;

    void computeFastBounds(const SkRect&, SkRect*) const override;

protected:

private:
    SK_FLATTENABLE_HOOKS(SDFMaskFilterImpl)

    using INHERITED = SkMaskFilter;
    friend void register_sdf_maskfilter_createproc();
};

///////////////////////////////////////////////////////////////////////////////

SDFMaskFilterImpl::SDFMaskFilterImpl() {}

SkMask::Format SDFMaskFilterImpl::getFormat() const {
    return SkMask::kSDF_Format;
}

bool SDFMaskFilterImpl::filterMask(SkMask* dst, const SkMask& src,
                                     const SkMatrix& matrix, SkIPoint* margin) const {
    if (src.fFormat != SkMask::kA8_Format
        && src.fFormat != SkMask::kBW_Format
        && src.fFormat != SkMask::kLCD16_Format) {
        return false;
    }

    *dst = SkMask::PrepareDestination(SK_DistanceFieldPad, SK_DistanceFieldPad, src);
    dst->fFormat = SkMask::kSDF_Format;

    if (margin) {
        margin->set(SK_DistanceFieldPad, SK_DistanceFieldPad);
    }

    if (src.fImage == nullptr) {
        return true;
    }
    if (dst->fImage == nullptr) {
        dst->fBounds.setEmpty();
        return false;
    }

    if (src.fFormat == SkMask::kA8_Format) {
        return SkGenerateDistanceFieldFromA8Image(dst->fImage, src.fImage,
                                                  src.fBounds.width(), src.fBounds.height(),
                                                  src.fRowBytes);
    } else if (src.fFormat == SkMask::kLCD16_Format) {
        return SkGenerateDistanceFieldFromLCD16Mask(dst->fImage, src.fImage,
                                                     src.fBounds.width(), src.fBounds.height(),
                                                     src.fRowBytes);
    } else {
        return SkGenerateDistanceFieldFromBWImage(dst->fImage, src.fImage,
                                                  src.fBounds.width(), src.fBounds.height(),
                                                  src.fRowBytes);
    }
}

void SDFMaskFilterImpl::computeFastBounds(const SkRect& src,
                                            SkRect* dst) const {
    dst->setLTRB(src.fLeft  - SK_DistanceFieldPad, src.fTop    - SK_DistanceFieldPad,
                 src.fRight + SK_DistanceFieldPad, src.fBottom + SK_DistanceFieldPad);
}

sk_sp<SkFlattenable> SDFMaskFilterImpl::CreateProc(SkReadBuffer& buffer) {
    return SDFMaskFilter::Make();
}

void register_sdf_maskfilter_createproc() { SK_REGISTER_FLATTENABLE(SDFMaskFilterImpl); }

///////////////////////////////////////////////////////////////////////////////

sk_sp<SkMaskFilter> SDFMaskFilter::Make() {
    return sk_sp<SkMaskFilter>(new SDFMaskFilterImpl());
}

}  // namespace sktext::gpu
