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 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: 72 SimpleMagnificationGM() { 73 this->setBGColor(0xFFCCCCCC); 74 } 75 76 protected: 77 SkString onShortName() override { 78 return SkString("simple-magnification"); 79 } 80 81 SkISize onISize() override { 82 return SkISize::Make(3*kPad+2*kImgSize, 3*kPad+2*kImgSize); 83 } 84 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 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