1/*
2 * Copyright 2013 Google Inc.
3 *
4 * Use of this source code is governed by a BSD-style license that can be
5 * found in the LICENSE file.
6 */
7
8#include "gm.h"
9#include "SkAlphaThresholdFilter.h"
10#include "SkOffsetImageFilter.h"
11#include "SkRegion.h"
12#include "SkSurface.h"
13
14#define WIDTH 500
15#define HEIGHT 500
16
17static void draw_rects(SkCanvas* canvas) {
18    SkPaint rectPaint;
19    rectPaint.setColor(SK_ColorBLUE);
20    canvas->drawRect(SkRect::MakeXYWH(0, 0, WIDTH / 2, HEIGHT / 2), rectPaint);
21    rectPaint.setColor(0xBFFF0000);
22    canvas->drawRect(SkRect::MakeXYWH(WIDTH / 2, 0, WIDTH / 2, HEIGHT / 2), rectPaint);
23    rectPaint.setColor(0x3F00FF00);
24    canvas->drawRect(SkRect::MakeXYWH(0, HEIGHT / 2, WIDTH / 2, HEIGHT / 2), rectPaint);
25    rectPaint.setColor(SK_ColorTRANSPARENT);
26    canvas->drawRect(SkRect::MakeXYWH(WIDTH / 2, HEIGHT / 2, WIDTH / 2, HEIGHT / 2), rectPaint);
27}
28
29static SkPaint create_filter_paint(SkImageFilter::CropRect* cropRect = nullptr) {
30    SkIRect rects[2];
31    rects[0] = SkIRect::MakeXYWH(0, 150, WIDTH, HEIGHT - 300);
32    rects[1] = SkIRect::MakeXYWH(150, 0, WIDTH - 300, HEIGHT);
33    SkRegion region;
34    region.setRects(rects, 2);
35
36    SkPaint paint;
37    sk_sp<SkImageFilter> offset(SkOffsetImageFilter::Make(25, 25, nullptr));
38    paint.setImageFilter(SkAlphaThresholdFilter::Make(region, 0.2f, 0.7f, std::move(offset), cropRect));
39    return paint;
40}
41
42class ImageAlphaThresholdGM : public skiagm::GM {
43public:
44    ImageAlphaThresholdGM(bool useCropRect) : fUseCropRect(useCropRect) {
45        this->setBGColor(SK_ColorWHITE);
46    }
47
48protected:
49
50    SkString onShortName() override {
51        if (fUseCropRect) {
52            return SkString("imagealphathreshold_crop");
53        }
54
55        return SkString("imagealphathreshold");
56    }
57
58    SkISize onISize() override {
59        return SkISize::Make(WIDTH, HEIGHT);
60    }
61
62    void onDraw(SkCanvas* canvas) override {
63        SkMatrix matrix;
64        matrix.reset();
65        matrix.setTranslate(WIDTH * .1f, HEIGHT * .1f);
66        matrix.postScale(.8f, .8f);
67
68        canvas->concat(matrix);
69
70        SkRect r = SkRect::MakeLTRB(100, 100, WIDTH - 100, HEIGHT - 100);
71        SkImageFilter::CropRect cropRect(r);
72
73        SkPaint paint = create_filter_paint(fUseCropRect ? &cropRect : nullptr);
74        canvas->saveLayer(nullptr, &paint);
75        draw_rects(canvas);
76
77        canvas->restore();
78    }
79
80private:
81    bool fUseCropRect;
82
83    typedef GM INHERITED;
84};
85
86// Create a 'width' x 'height' SkSurface that matches the colorType of 'canvas' as
87// best we can
88static sk_sp<SkSurface> make_color_matching_surface(SkCanvas* canvas, int width, int height,
89                                                    SkAlphaType alphaType) {
90
91    SkColorType ct = canvas->imageInfo().colorType();
92    sk_sp<SkColorSpace> cs(canvas->imageInfo().refColorSpace());
93
94    if (kUnknown_SkColorType == ct) {
95        // For backends that aren't yet color-space aware we just fallback to N32.
96        ct = kN32_SkColorType;
97        cs = nullptr;
98    }
99
100    SkImageInfo info = SkImageInfo::Make(width, height, ct, alphaType, std::move(cs));
101
102    sk_sp<SkSurface> result = canvas->makeSurface(info);
103    if (!result) {
104        result = SkSurface::MakeRaster(info);
105    }
106
107    return result;
108}
109
110class ImageAlphaThresholdSurfaceGM : public skiagm::GM {
111public:
112    ImageAlphaThresholdSurfaceGM() {
113        this->setBGColor(0xFFFFFFFF);
114    }
115
116protected:
117    SkString onShortName() override {
118        return SkString("imagealphathreshold_surface");
119    }
120
121    SkISize onISize() override {
122        return SkISize::Make(WIDTH, HEIGHT);
123    }
124
125    void onDraw(SkCanvas* canvas) override {
126        SkMatrix matrix;
127        matrix.reset();
128        matrix.setTranslate(WIDTH * .1f, HEIGHT * .1f);
129        matrix.postScale(.8f, .8f);
130
131        canvas->concat(matrix);
132
133        sk_sp<SkSurface> surface(make_color_matching_surface(canvas, WIDTH, HEIGHT,
134                                                             kPremul_SkAlphaType));
135        if (!surface) {
136            return;
137        }
138
139        surface->getCanvas()->clear(SK_ColorTRANSPARENT);
140        draw_rects(surface->getCanvas());
141
142        SkPaint paint = create_filter_paint();
143        canvas->clipRect(SkRect::MakeLTRB(100, 100, WIDTH - 100, HEIGHT - 100));
144        canvas->drawImage(surface->makeImageSnapshot().get(), 0, 0, &paint);
145    }
146
147private:
148    typedef skiagm::GM INHERITED;
149};
150
151//////////////////////////////////////////////////////////////////////////////
152
153DEF_GM(return new ImageAlphaThresholdGM(true);)
154DEF_GM(return new ImageAlphaThresholdGM(false);)
155DEF_GM(return new ImageAlphaThresholdSurfaceGM();)
156