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