• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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/gm.h"
9 #include "include/core/SkBitmap.h"
10 #include "include/core/SkCanvas.h"
11 #include "include/core/SkColor.h"
12 #include "include/core/SkImage.h"
13 #include "include/core/SkImageFilter.h"
14 #include "include/core/SkMatrix.h"
15 #include "include/core/SkPaint.h"
16 #include "include/core/SkRect.h"
17 #include "include/core/SkRefCnt.h"
18 #include "include/core/SkScalar.h"
19 #include "include/core/SkSize.h"
20 #include "include/core/SkString.h"
21 #include "include/effects/SkImageFilters.h"
22 #include "src/core/SkImageFilter_Base.h"
23 #include "tools/ToolUtils.h"
24 
25 #include <utility>
26 
27 #define WIDTH 600
28 #define HEIGHT 100
29 #define MARGIN 12
30 
31 class OffsetImageFilterGM : public skiagm::GM {
32 public:
OffsetImageFilterGM()33     OffsetImageFilterGM() {
34         this->setBGColor(0xFF000000);
35     }
36 
37 protected:
onShortName()38     SkString onShortName() override {
39         return SkString("offsetimagefilter");
40     }
41 
onISize()42     SkISize onISize() override {
43         return SkISize::Make(WIDTH, HEIGHT);
44     }
45 
onOnceBeforeDraw()46     void onOnceBeforeDraw() override {
47         fBitmap = SkImage::MakeFromBitmap(
48                 ToolUtils::create_string_bitmap(80, 80, 0xD000D000, 15, 65, 96, "e"));
49 
50         fCheckerboard = SkImage::MakeFromBitmap(
51                 ToolUtils::create_checkerboard_bitmap(80, 80, 0xFFA0A0A0, 0xFF404040, 8));
52     }
53 
onDraw(SkCanvas * canvas)54     void onDraw(SkCanvas* canvas) override {
55         canvas->clear(SK_ColorBLACK);
56         SkPaint paint;
57 
58         for (int i = 0; i < 4; i++) {
59             sk_sp<SkImage> image = (i & 0x01) ? fCheckerboard : fBitmap;
60             SkIRect cropRect = SkIRect::MakeXYWH(i * 12,
61                                                  i * 8,
62                                                  image->width() - i * 8,
63                                                  image->height() - i * 12);
64             sk_sp<SkImageFilter> tileInput(SkImageFilters::Image(image));
65             SkScalar dx = SkIntToScalar(i*5);
66             SkScalar dy = SkIntToScalar(i*10);
67             paint.setImageFilter(SkImageFilters::Offset(dx, dy, std::move(tileInput), &cropRect));
68             DrawClippedImage(canvas, image.get(), paint, 1, cropRect);
69             canvas->translate(SkIntToScalar(image->width() + MARGIN), 0);
70         }
71 
72         SkIRect cropRect = SkIRect::MakeXYWH(0, 0, 100, 100);
73         paint.setImageFilter(SkImageFilters::Offset(-5, -10, nullptr, &cropRect));
74         DrawClippedImage(canvas, fBitmap.get(), paint, 2, cropRect);
75     }
76 private:
DrawClippedImage(SkCanvas * canvas,const SkImage * image,const SkPaint & paint,SkScalar scale,const SkIRect & cropRect)77     static void DrawClippedImage(SkCanvas* canvas, const SkImage* image, const SkPaint& paint,
78                           SkScalar scale, const SkIRect& cropRect) {
79         SkRect clipRect = SkRect::MakeIWH(image->width(), image->height());
80 
81         canvas->save();
82         canvas->clipRect(clipRect);
83         canvas->scale(scale, scale);
84         canvas->drawImage(image, 0, 0, &paint);
85         canvas->restore();
86 
87         // Draw a boundary rect around the intersection of the clip rect and crop rect.
88         SkRect cropRectFloat;
89         SkMatrix::MakeScale(scale, scale).mapRect(&cropRectFloat, SkRect::Make(cropRect));
90         if (clipRect.intersect(cropRectFloat)) {
91             SkPaint strokePaint;
92             strokePaint.setStyle(SkPaint::kStroke_Style);
93             strokePaint.setStrokeWidth(2);
94             strokePaint.setColor(SK_ColorRED);
95             canvas->drawRect(clipRect, strokePaint);
96         }
97     }
98 
99     sk_sp<SkImage> fBitmap, fCheckerboard;
100 
101     typedef skiagm::GM INHERITED;
102 };
103 DEF_GM( return new OffsetImageFilterGM; )
104 
105 //////////////////////////////////////////////////////////////////////////////
106 
107 class SimpleOffsetImageFilterGM : public skiagm::GM {
108 public:
SimpleOffsetImageFilterGM()109     SimpleOffsetImageFilterGM() {}
110 
111 protected:
onShortName()112     SkString onShortName() override {
113         return SkString("simple-offsetimagefilter");
114     }
115 
onISize()116     SkISize onISize() override { return SkISize::Make(640, 200); }
117 
doDraw(SkCanvas * canvas,const SkRect & r,sk_sp<SkImageFilter> imgf,const SkRect * clipR=nullptr)118     void doDraw(SkCanvas* canvas, const SkRect& r, sk_sp<SkImageFilter> imgf,
119                 const SkRect* clipR = nullptr) {
120         SkPaint p;
121 
122         if (clipR) {
123             p.setColor(0xFF00FF00);
124             p.setStyle(SkPaint::kStroke_Style);
125             canvas->drawRect(clipR->makeInset(SK_ScalarHalf, SK_ScalarHalf), p);
126             p.setStyle(SkPaint::kFill_Style);
127         }
128 
129         // Visualize the crop rect for debugging
130         if (imgf && as_IFB(imgf)->cropRectIsSet()) {
131             SkImageFilter::CropRect cr = as_IFB(imgf)->getCropRect();
132 
133             p.setColor(0x66FF00FF);
134             p.setStyle(SkPaint::kStroke_Style);
135             canvas->drawRect(cr.rect().makeInset(SK_ScalarHalf, SK_ScalarHalf), p);
136             p.setStyle(SkPaint::kFill_Style);
137         }
138 
139         p.setColor(0x660000FF);
140         canvas->drawRect(r, p);
141 
142         if (clipR) {
143             canvas->save();
144             canvas->clipRect(*clipR);
145         }
146         if (imgf) {
147             p.setImageFilter(std::move(imgf));
148         }
149         p.setColor(0x66FF0000);
150         canvas->drawRect(r, p);
151 
152         if (clipR) {
153             canvas->restore();
154         }
155     }
156 
onDraw(SkCanvas * canvas)157     void onDraw(SkCanvas* canvas) override {
158         SkIRect cr0 = SkIRect::MakeWH(40, 40);
159         SkIRect cr1 = SkIRect::MakeWH(20, 20);
160         SkIRect cr2 = SkIRect::MakeXYWH(40, 0, 40, 40);
161         const SkRect r = SkRect::Make(cr0);
162         const SkRect r2 = SkRect::Make(cr2);
163 
164         canvas->translate(40, 40);
165 
166         canvas->save();
167         this->doDraw(canvas, r, nullptr);
168 
169         canvas->translate(100, 0);
170         this->doDraw(canvas, r, SkImageFilters::Offset(20, 20, nullptr));
171 
172         canvas->translate(100, 0);
173         this->doDraw(canvas, r, SkImageFilters::Offset(20, 20, nullptr, &cr0));
174 
175         canvas->translate(100, 0);
176         this->doDraw(canvas, r, SkImageFilters::Offset(20, 20, nullptr), &r);
177 
178         canvas->translate(100, 0);
179         this->doDraw(canvas, r, SkImageFilters::Offset(20, 20, nullptr, &cr1));
180 
181         SkRect clipR = SkRect::MakeXYWH(40, 40, 40, 40);
182         canvas->translate(100, 0);
183         this->doDraw(canvas, r, SkImageFilters::Offset(20, 20, nullptr, nullptr), &clipR);
184         canvas->restore();
185 
186         // 2nd row
187         canvas->translate(0, 80);
188 
189         /*
190          *  combos of clip and crop rects that align with src and dst
191          */
192 
193         // crop==clip==src
194         this->doDraw(canvas, r, SkImageFilters::Offset(40, 0, nullptr, &cr0), &r);
195 
196         // crop==src, clip==dst
197         canvas->translate(100, 0);
198         this->doDraw(canvas, r, SkImageFilters::Offset(40, 0, nullptr, &cr0), &r2);
199 
200         // crop==dst, clip==src
201         canvas->translate(100, 0);
202         this->doDraw(canvas, r, SkImageFilters::Offset(40, 0, nullptr, &cr2), &r);
203 
204         // crop==clip==dst
205         canvas->translate(100, 0);
206         this->doDraw(canvas, r, SkImageFilters::Offset(40, 0, nullptr, &cr2), &r2);
207     }
208 
209 private:
210     typedef skiagm::GM INHERITED;
211 };
212 DEF_GM( return new SimpleOffsetImageFilterGM; )
213