• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright 2012 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/gm.h"
9 #include "include/core/SkBitmap.h"
10 #include "include/core/SkBlendMode.h"
11 #include "include/core/SkCanvas.h"
12 #include "include/core/SkColor.h"
13 #include "include/core/SkColorFilter.h"
14 #include "include/core/SkImage.h"
15 #include "include/core/SkImageFilter.h"
16 #include "include/core/SkPaint.h"
17 #include "include/core/SkPoint.h"
18 #include "include/core/SkRect.h"
19 #include "include/core/SkRefCnt.h"
20 #include "include/core/SkScalar.h"
21 #include "include/core/SkSize.h"
22 #include "include/core/SkString.h"
23 #include "include/effects/SkImageFilters.h"
24 #include "tools/ToolUtils.h"
25 
26 #include <utility>
27 
28 class ImageFiltersGraphGM : public skiagm::GM {
29 public:
ImageFiltersGraphGM()30     ImageFiltersGraphGM() {}
31 
32 protected:
33 
onShortName()34     SkString onShortName() override {
35         return SkString("imagefiltersgraph");
36     }
37 
onISize()38     SkISize onISize() override { return SkISize::Make(600, 150); }
39 
onOnceBeforeDraw()40     void onOnceBeforeDraw() override {
41         fImage = SkImage::MakeFromBitmap(
42                 ToolUtils::create_string_bitmap(100, 100, SK_ColorWHITE, 20, 70, 96, "e"));
43     }
44 
onDraw(SkCanvas * canvas)45     void onDraw(SkCanvas* canvas) override {
46         canvas->clear(SK_ColorBLACK);
47         {
48             sk_sp<SkImageFilter> bitmapSource(SkImageFilters::Image(fImage));
49             sk_sp<SkColorFilter> cf(SkColorFilters::Blend(SK_ColorRED,
50                                                                   SkBlendMode::kSrcIn));
51             sk_sp<SkImageFilter> blur(SkImageFilters::Blur(4.0f, 4.0f, std::move(bitmapSource)));
52             sk_sp<SkImageFilter> erode(SkImageFilters::Erode(4, 4, blur));
53             sk_sp<SkImageFilter> color(SkImageFilters::ColorFilter(std::move(cf),
54                                                                       std::move(erode)));
55             sk_sp<SkImageFilter> merge(SkImageFilters::Merge(blur, color));
56 
57             SkPaint paint;
58             paint.setImageFilter(std::move(merge));
59             canvas->drawPaint(paint);
60             canvas->translate(SkIntToScalar(100), 0);
61         }
62         {
63             sk_sp<SkImageFilter> morph(SkImageFilters::Dilate(5, 5, nullptr));
64 
65             float matrix[20] = { 1, 0, 0, 0, 0,
66                                  0, 1, 0, 0, 0,
67                                  0, 0, 1, 0, 0,
68                                  0, 0, 0, 0.5f, 0 };
69 
70             sk_sp<SkColorFilter> matrixFilter(SkColorFilters::Matrix(matrix));
71             sk_sp<SkImageFilter> colorMorph(SkImageFilters::ColorFilter(std::move(matrixFilter),
72                                                                            std::move(morph)));
73             SkPaint paint;
74             paint.setImageFilter(SkImageFilters::Xfermode(SkBlendMode::kSrcOver,
75                                                           std::move(colorMorph)));
76 
77             DrawClippedImage(canvas, fImage.get(), paint);
78             canvas->translate(SkIntToScalar(100), 0);
79         }
80         {
81             float matrix[20] = { 1, 0, 0, 0, 0,
82                                  0, 1, 0, 0, 0,
83                                  0, 0, 1, 0, 0,
84                                  0, 0, 0, 0.5f, 0 };
85             sk_sp<SkColorFilter> matrixCF(SkColorFilters::Matrix(matrix));
86             sk_sp<SkImageFilter> matrixFilter(SkImageFilters::ColorFilter(std::move(matrixCF),
87                                                                              nullptr));
88             sk_sp<SkImageFilter> offsetFilter(SkImageFilters::Offset(10.0f, 10.f, matrixFilter));
89 
90             SkPaint paint;
91             paint.setImageFilter(SkImageFilters::Arithmetic(
92                     0, 1, 1, 0, true, std::move(matrixFilter), std::move(offsetFilter), nullptr));
93 
94             DrawClippedImage(canvas, fImage.get(), paint);
95             canvas->translate(SkIntToScalar(100), 0);
96         }
97         {
98             sk_sp<SkImageFilter> blur(SkImageFilters::Blur(10, 10, nullptr));
99 
100             SkIRect cropRect = SkIRect::MakeWH(95, 100);
101             SkPaint paint;
102             paint.setImageFilter(
103                 SkImageFilters::Xfermode(SkBlendMode::kSrcIn, std::move(blur), nullptr, &cropRect));
104             DrawClippedImage(canvas, fImage.get(), paint);
105             canvas->translate(SkIntToScalar(100), 0);
106         }
107         {
108             // Dilate -> matrix convolution.
109             // This tests that a filter using asFragmentProcessor (matrix
110             // convolution) correctly handles a non-zero source offset
111             // (supplied by the dilate).
112             sk_sp<SkImageFilter> dilate(SkImageFilters::Dilate(5, 5, nullptr));
113 
114             SkScalar kernel[9] = { -1, -1, -1,
115                                    -1,  7, -1,
116                                    -1, -1, -1 };
117             SkISize kernelSize = SkISize::Make(3, 3);
118             SkScalar gain = 1.0f, bias = 0;
119             SkIPoint kernelOffset = SkIPoint::Make(1, 1);
120             bool convolveAlpha = false;
121             sk_sp<SkImageFilter> convolve(SkImageFilters::MatrixConvolution(
122                     kernelSize, kernel, gain, bias, kernelOffset, SkTileMode::kClamp, convolveAlpha,
123                     std::move(dilate)));
124 
125             SkPaint paint;
126             paint.setImageFilter(std::move(convolve));
127             DrawClippedImage(canvas, fImage.get(), paint);
128             canvas->translate(SkIntToScalar(100), 0);
129         }
130         {
131             // Test that crop offsets are absolute, not relative to the parent's crop rect.
132             sk_sp<SkColorFilter> cf1(SkColorFilters::Blend(SK_ColorBLUE, SkBlendMode::kSrcIn));
133             sk_sp<SkColorFilter> cf2(SkColorFilters::Blend(SK_ColorGREEN, SkBlendMode::kSrcIn));
134             SkIRect outerRect = SkIRect::MakeXYWH(10, 10, 80, 80);
135             SkIRect innerRect= SkIRect::MakeXYWH(20, 20, 60, 60);
136             sk_sp<SkImageFilter> color1(SkImageFilters::ColorFilter(
137                     std::move(cf1), nullptr, &outerRect));
138             sk_sp<SkImageFilter> color2(SkImageFilters::ColorFilter(
139                     std::move(cf2), std::move(color1),  &innerRect));
140 
141             SkPaint paint;
142             paint.setImageFilter(std::move(color2));
143             paint.setColor(SK_ColorRED);
144             canvas->drawRect(SkRect::MakeXYWH(0, 0, 100, 100), paint);
145             canvas->translate(SkIntToScalar(100), 0);
146         }
147     }
148 
149 private:
DrawClippedImage(SkCanvas * canvas,const SkImage * image,const SkPaint & paint)150     static void DrawClippedImage(SkCanvas* canvas, const SkImage* image, const SkPaint& paint) {
151         canvas->save();
152         canvas->clipRect(SkRect::MakeIWH(image->width(), image->height()));
153         canvas->drawImage(image, 0, 0, &paint);
154         canvas->restore();
155     }
156 
157     sk_sp<SkImage> fImage;
158 
159     typedef GM INHERITED;
160 };
161 
162 ///////////////////////////////////////////////////////////////////////////////
163 
164 DEF_GM(return new ImageFiltersGraphGM;)
165