• 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