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