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