158190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger/*
258190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger * Copyright 2011 Google Inc.
358190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger *
458190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger * Use of this source code is governed by a BSD-style license that can be
558190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger * found in the LICENSE file.
658190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger */
758190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger
858190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger#include "gm.h"
958190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger#include "SkCanvas.h"
1058190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger#include "SkColorFilter.h"
1158190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger#include "SkColorPriv.h"
1258190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger#include "SkShader.h"
1358190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger
1458190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger#include "SkBlurImageFilter.h"
1558190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger#include "SkColorFilterImageFilter.h"
1658190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger#include "SkTestImageFilters.h"
1758190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger
1858190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger///////////////////////////////////////////////////////////////////////////////
1958190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger
2058190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenbergerstatic void draw_paint(SkCanvas* canvas, const SkRect& r, SkImageFilter* imf) {
2158190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger    SkPaint paint;
2258190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger    paint.setImageFilter(imf);
2358190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger    paint.setColor(SK_ColorBLACK);
2458190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger    canvas->save();
2558190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger    canvas->clipRect(r);
2658190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger    canvas->drawPaint(paint);
2758190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger    canvas->restore();
2858190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger}
2958190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger
3058190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenbergerstatic void draw_path(SkCanvas* canvas, const SkRect& r, SkImageFilter* imf) {
3158190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger    SkPaint paint;
3258190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger    paint.setColor(SK_ColorMAGENTA);
3358190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger    paint.setImageFilter(imf);
3458190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger    paint.setAntiAlias(true);
3558190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger    canvas->save();
3658190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger    canvas->clipRect(r);
3758190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger    canvas->drawCircle(r.centerX(), r.centerY(), r.width()*2/5, paint);
3858190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger    canvas->restore();
3958190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger}
4058190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger
4158190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenbergerstatic void draw_text(SkCanvas* canvas, const SkRect& r, SkImageFilter* imf) {
4258190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger    SkPaint paint;
4358190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger    paint.setImageFilter(imf);
4458190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger    paint.setColor(SK_ColorGREEN);
4558190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger    paint.setAntiAlias(true);
4658190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger    paint.setTextSize(r.height()/2);
4758190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger    paint.setTextAlign(SkPaint::kCenter_Align);
4858190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger    canvas->save();
4958190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger    canvas->clipRect(r);
5058190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger    canvas->drawText("Text", 4, r.centerX(), r.centerY(), paint);
5158190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger    canvas->restore();
5258190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger}
5358190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger
5458190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenbergerstatic void draw_bitmap(SkCanvas* canvas, const SkRect& r, SkImageFilter* imf) {
5558190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger    SkPaint paint;
5658190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger
5758190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger    SkIRect bounds;
5858190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger    r.roundOut(&bounds);
5958190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger
6058190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger    SkBitmap bm;
6158190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger    bm.setConfig(SkBitmap::kARGB_8888_Config, bounds.width(), bounds.height());
6258190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger    bm.allocPixels();
6358190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger    bm.eraseColor(SK_ColorTRANSPARENT);
6458190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger    SkCanvas c(bm);
6558190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger    draw_path(&c, r, NULL);
6658190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger
6758190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger    paint.setImageFilter(imf);
6858190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger    canvas->save();
6958190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger    canvas->clipRect(r);
7058190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger    canvas->drawBitmap(bm, 0, 0, &paint);
7158190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger    canvas->restore();
7258190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger}
7358190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger
7458190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenbergerstatic void draw_sprite(SkCanvas* canvas, const SkRect& r, SkImageFilter* imf) {
7558190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger    SkPaint paint;
7658190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger
7758190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger    SkIRect bounds;
7858190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger    r.roundOut(&bounds);
7958190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger
8058190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger    SkBitmap bm;
8158190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger    bm.setConfig(SkBitmap::kARGB_8888_Config, bounds.width(), bounds.height());
8258190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger    bm.allocPixels();
8358190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger    bm.eraseColor(SK_ColorRED);
8458190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger    SkCanvas c(bm);
8558190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger
8658190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger    SkIRect cropRect = SkIRect::MakeXYWH(10, 10, 44, 44);
8758190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger    paint.setColor(SK_ColorGREEN);
8858190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger    c.drawRect(SkRect::Make(cropRect), paint);
8958190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger
9058190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger    paint.setImageFilter(imf);
9158190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger    SkPoint loc = { r.fLeft, r.fTop };
9258190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger    canvas->getTotalMatrix().mapPoints(&loc, 1);
9358190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger    canvas->drawSprite(bm,
9458190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger                       SkScalarRoundToInt(loc.fX), SkScalarRoundToInt(loc.fY),
9558190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger                       &paint);
9658190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger}
9758190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger
9858190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger///////////////////////////////////////////////////////////////////////////////
9958190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger
10058190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenbergerclass ImageFiltersCroppedGM : public skiagm::GM {
10158190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenbergerpublic:
10258190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger    ImageFiltersCroppedGM () {}
10358190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger
10458190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenbergerprotected:
10558190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger
10658190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger    virtual SkString onShortName() {
10758190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger        return SkString("imagefilterscropped");
10858190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger    }
10958190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger
11058190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger    virtual SkISize onISize() { return SkISize::Make(400, 640); }
11158190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger
11258190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger    void draw_frame(SkCanvas* canvas, const SkRect& r) {
11358190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger        SkPaint paint;
11458190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger        paint.setStyle(SkPaint::kStroke_Style);
11558190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger        paint.setColor(SK_ColorRED);
11658190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger        canvas->drawRect(r, paint);
11758190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger    }
11858190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger
11958190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger    virtual uint32_t onGetFlags() const {
12058190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger        // Because of the use of drawSprite, this test is excluded
12158190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger        // from scaled replay tests because drawSprite ignores the
12258190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger        // reciprocal scale that is applied at record time, which is
12358190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger        // the intended behavior of drawSprite.
12458190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger        return kSkipScaledReplay_Flag;
12558190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger    }
12658190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger
12758190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger    virtual void onDraw(SkCanvas* canvas) {
12858190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger        void (*drawProc[])(SkCanvas*, const SkRect&, SkImageFilter*) = {
12958190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger            draw_sprite, draw_bitmap, draw_path, draw_paint, draw_text
13058190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger        };
13158190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger
13258190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger        SkColorFilter* cf = SkColorFilter::CreateModeFilter(SK_ColorRED,
13358190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger                                                     SkXfermode::kSrcIn_Mode);
13458190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger        SkIRect cropRect = SkIRect::MakeXYWH(10, 10, 44, 44);
13558190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger        SkIRect bogusRect = SkIRect::MakeXYWH(-100, -100, 10, 10);
13658190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger
13758190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger        SkImageFilter* filters[] = {
13858190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger            NULL,
13958190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger            SkColorFilterImageFilter::Create(cf, NULL, &cropRect),
14058190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger            new SkBlurImageFilter(1.0f, 1.0f, NULL, &cropRect),
14158190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger            new SkBlurImageFilter(8.0f, 0.0f, NULL, &cropRect),
14258190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger            new SkBlurImageFilter(0.0f, 8.0f, NULL, &cropRect),
14358190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger            new SkBlurImageFilter(8.0f, 8.0f, NULL, &cropRect),
14458190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger            new SkBlurImageFilter(8.0f, 8.0f, NULL, &bogusRect),
14558190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger            SkColorFilterImageFilter::Create(cf, NULL, &bogusRect),
14658190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger        };
14758190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger        cf->unref();
14858190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger
14958190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger        SkRect r = SkRect::MakeWH(SkIntToScalar(64), SkIntToScalar(64));
15058190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger        SkScalar MARGIN = SkIntToScalar(16);
15158190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger        SkScalar DX = r.width() + MARGIN;
15258190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger        SkScalar DY = r.height() + MARGIN;
15358190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger
15458190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger        canvas->translate(MARGIN, MARGIN);
15558190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger        for (size_t j = 0; j < SK_ARRAY_COUNT(drawProc); ++j) {
15658190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger            canvas->save();
15758190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger            for (size_t i = 0; i < SK_ARRAY_COUNT(filters); ++i) {
15858190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger                drawProc[j](canvas, r, filters[i]);
15958190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger                canvas->translate(0, DY);
16058190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger            }
16158190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger            canvas->restore();
16258190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger            canvas->translate(DX, 0);
16358190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger        }
16458190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger
16558190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger        for(size_t j = 0; j < SK_ARRAY_COUNT(filters); ++j) {
16658190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger            SkSafeUnref(filters[j]);
16758190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger        }
16858190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger    }
16958190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger
17058190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenbergerprivate:
17158190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger    typedef GM INHERITED;
17258190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger};
17358190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger
17458190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger///////////////////////////////////////////////////////////////////////////////
17558190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger
17658190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenbergerstatic skiagm::GM* MyFactory(void*) { return new ImageFiltersCroppedGM; }
17758190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenbergerstatic skiagm::GMRegistry reg(MyFactory);
178