1 /*
2 * Copyright 2017 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 "SkColorPriv.h"
10 #include "SkImageSource.h"
11 #include "SkMagnifierImageFilter.h"
12 #include "SkSurface.h"
13
make_image(GrContext * context,int size,GrSurfaceOrigin origin)14 static sk_sp<SkImage> make_image(GrContext* context, int size, GrSurfaceOrigin origin) {
15 if (context) {
16 SkImageInfo ii = SkImageInfo::Make(size, size, kN32_SkColorType, kPremul_SkAlphaType);
17 sk_sp<SkSurface> surf(SkSurface::MakeRenderTarget(context, SkBudgeted::kYes, ii, 0,
18 origin, nullptr));
19 if (!surf) {
20 return nullptr;
21 }
22
23 SkCanvas* canvas = surf->getCanvas();
24
25 canvas->clear(SK_ColorRED);
26 const struct {
27 SkPoint fPt;
28 SkColor fColor;
29 } rec[] = {
30 { { 1.5f, 1.5f }, SK_ColorGREEN },
31 { { 2.5f, 1.5f }, SK_ColorBLUE },
32 { { 1.5f, 2.5f }, SK_ColorCYAN },
33 { { 2.5f, 2.5f }, SK_ColorGRAY },
34 };
35 SkPaint paint;
36 for (const auto& r : rec) {
37 paint.setColor(r.fColor);
38 canvas->drawPoints(SkCanvas::kPoints_PointMode, 1, &r.fPt, paint);
39 }
40 return surf->makeImageSnapshot();
41 } else {
42 SkBitmap bm;
43 bm.allocN32Pixels(size, size);
44 bm.eraseColor(SK_ColorRED);
45 *bm.getAddr32(1, 1) = SkPackARGB32(0xFF, 0x00, 0xFF, 0x00);
46 *bm.getAddr32(2, 1) = SkPackARGB32(0xFF, 0x00, 0x00, 0xFF);
47 *bm.getAddr32(1, 2) = SkPackARGB32(0xFF, 0x00, 0xFF, 0xFF);
48 *bm.getAddr32(2, 2) = SkPackARGB32(0xFF, 0x88, 0x88, 0x88);
49
50 return SkImage::MakeFromBitmap(bm);
51 }
52 }
53
54 /*
55 * This GM creates an image with a 2x2:
56 * Green | Blue
57 * ------------
58 * Cyan | Gray
59 * block of pixels in one corner of a 33x33 field. The 'srcRect' feature of the
60 * SkMagnifierImageFilter is then used to blow it up with different inset border widths.
61 *
62 * In GPU-mode we wind up drawing 4 rects:
63 *
64 * BottomLeft origin + 1-wide inset | TopLeft origin + 1-wide inset
65 * ----------------------------------------------------------------
66 * BottomLeft origin + 7-wide inset | TopLeft origin + 7-wide inset
67 *
68 * In Raster-mode the source origin isn't used.
69 */
70 class SimpleMagnificationGM : public skiagm::GM {
71 public:
SimpleMagnificationGM()72 SimpleMagnificationGM() {
73 this->setBGColor(0xFFCCCCCC);
74 }
75
76 protected:
onShortName()77 SkString onShortName() override {
78 return SkString("simple-magnification");
79 }
80
onISize()81 SkISize onISize() override {
82 return SkISize::Make(3*kPad+2*kImgSize, 3*kPad+2*kImgSize);
83 }
84
draw(SkCanvas * canvas,sk_sp<SkImage> image,const SkIPoint & offset,int inset)85 void draw(SkCanvas* canvas, sk_sp<SkImage> image, const SkIPoint& offset, int inset) {
86 sk_sp<SkImageFilter> imgSrc(SkImageSource::Make(std::move(image)));
87
88 SkRect srcRect = SkRect::MakeXYWH(1.0f, 1.0f, 2.0f, 2.0f);
89 sk_sp<SkImageFilter> magFilter(SkMagnifierImageFilter::Make(srcRect, inset, imgSrc));
90
91 SkPaint paint;
92 paint.setImageFilter(std::move(magFilter));
93
94 canvas->save();
95 canvas->translate(offset.fX, offset.fY);
96 SkRect rect = SkRect::MakeWH(kImgSize, kImgSize);
97 canvas->drawRect(rect, paint);
98
99 canvas->restore();
100 }
101
onDraw(SkCanvas * canvas)102 void onDraw(SkCanvas* canvas) override {
103 GrContext* context = canvas->getGrContext();
104
105 sk_sp<SkImage> bottomLImg = make_image(context, kImgSize, kBottomLeft_GrSurfaceOrigin);
106 sk_sp<SkImage> topLImg = make_image(context, kImgSize, kTopLeft_GrSurfaceOrigin);
107 if (!bottomLImg || !topLImg) {
108 return;
109 }
110
111 int bigOffset = 2 * kPad + kImgSize;
112
113 this->draw(canvas, bottomLImg, SkIPoint::Make(kPad, kPad), 1);
114 this->draw(canvas, topLImg, SkIPoint::Make(bigOffset, kPad), 1);
115 this->draw(canvas, bottomLImg, SkIPoint::Make(kPad, bigOffset), 7);
116 this->draw(canvas, topLImg, SkIPoint::Make(bigOffset, bigOffset), 7);
117 }
118
119 private:
120 static const int kImgSize = 33;
121 static const int kPad = 2;
122
123 typedef skiagm::GM INHERITED;
124 };
125
126 //////////////////////////////////////////////////////////////////////////////
127
128 DEF_GM(return new SimpleMagnificationGM;)
129