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

#include "gm.h"
#include "SkBlurMask.h"
#include "SkBlurMaskFilter.h"
#include "SkCanvas.h"
#include "SkDrawFilter.h"
#include "SkPaint.h"

#ifdef SK_SUPPORT_LEGACY_DRAWFILTER

/**
 * Initial test coverage for SkDrawFilter.
 * Draws two rectangles; if draw filters are broken, they will match.
 * If draw filters are working correctly, the first will be blue and blurred,
 * the second red and sharp.
 */

namespace {
class TestFilter : public SkDrawFilter {
public:
    bool filter(SkPaint* p, Type) override {
        p->setColor(SK_ColorRED);
        p->setMaskFilter(nullptr);
        return true;
    }
};
}

class DrawFilterGM : public skiagm::GM {
    sk_sp<SkMaskFilter> fBlur;

protected:
    SkISize onISize() override {
        return SkISize::Make(320, 240);
    }

    SkString onShortName() override {
        return SkString("drawfilter");
    }

    void onOnceBeforeDraw() override {
        fBlur = SkBlurMaskFilter::Make(kNormal_SkBlurStyle,
                    SkBlurMask::ConvertRadiusToSigma(10.0f),
                    kLow_SkBlurQuality);
    }

    void onDraw(SkCanvas* canvas) override {
        SkPaint p;
        p.setColor(SK_ColorBLUE);
        p.setMaskFilter(fBlur);
        SkRect r = { 20, 20, 100, 100 };
        canvas->setDrawFilter(nullptr);
        canvas->drawRect(r, p);
        canvas->setDrawFilter(new TestFilter)->unref();
        canvas->translate(120.0f, 40.0f);
        canvas->drawRect(r, p);
        canvas->setDrawFilter(nullptr);
    }

private:
    typedef GM INHERITED;
};

DEF_GM( return new DrawFilterGM; )

#endif
