1 /* 2 * Copyright 2016 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 "sk_tool_utils.h" 10 #include "SkBlurImageFilter.h" 11 #include "SkCanvas.h" 12 #include "SkColorFilter.h" 13 #include "SkColorFilterImageFilter.h" 14 #include "SkDropShadowImageFilter.h" 15 #include "SkSurface.h" 16 17 /////////////////////////////////////////////////////////////////////////////// 18 19 static void show_bounds(SkCanvas* canvas, const SkIRect& subset, const SkIRect& clip) { 20 SkIRect rects[] { subset, clip }; 21 SkColor colors[] { SK_ColorRED, SK_ColorBLUE }; 22 23 SkPaint paint; 24 paint.setStyle(SkPaint::kStroke_Style); 25 26 for (size_t i = 0; i < SK_ARRAY_COUNT(rects); ++i) { 27 paint.setColor(colors[i]); 28 canvas->drawRect(SkRect::Make(rects[i]), paint); 29 } 30 } 31 32 // In this GM, we're going to feed the inner portion of a 100x100 checkboard 33 // (i.e., strip off a 25-wide border) through the makeWithFilter method. 34 // We'll then draw the appropriate subset of the result to the screen at the 35 // given offset. 36 class ImageMakeWithFilterGM : public skiagm::GM { 37 public: 38 ImageMakeWithFilterGM () {} 39 40 protected: 41 SkString onShortName() override { 42 return SkString("imagemakewithfilter"); 43 } 44 45 SkISize onISize() override { return SkISize::Make(440, 530); } 46 47 void onDraw(SkCanvas* canvas) override { 48 auto cf = SkColorFilter::MakeModeFilter(SK_ColorGREEN, SkBlendMode::kSrc); 49 sk_sp<SkImageFilter> filters[] = { 50 SkColorFilterImageFilter::Make(std::move(cf), nullptr), 51 SkBlurImageFilter::Make(2.0f, 2.0f, nullptr), 52 SkDropShadowImageFilter::Make( 53 10.0f, 5.0f, 3.0f, 3.0f, SK_ColorBLUE, 54 SkDropShadowImageFilter::kDrawShadowAndForeground_ShadowMode, 55 nullptr), 56 }; 57 58 SkIRect clipBounds[] { 59 { -20, -20, 100, 100 }, 60 { 0, 0, 75, 75 }, 61 { 20, 20, 100, 100 }, 62 { -20, -20, 50, 50 }, 63 { 20, 20, 50, 50 }, 64 }; 65 66 SkImageInfo info = SkImageInfo::MakeN32(100, 100, kPremul_SkAlphaType); 67 SkScalar MARGIN = SkIntToScalar(40); 68 SkScalar DX = info.width() + MARGIN; 69 SkScalar DY = info.height() + MARGIN; 70 71 canvas->translate(MARGIN, MARGIN); 72 73 sk_sp<SkSurface> surface = canvas->makeSurface(info); 74 if (!surface) { 75 surface = SkSurface::MakeRaster(info); 76 } 77 sk_tool_utils::draw_checkerboard(surface->getCanvas()); 78 sk_sp<SkImage> source = surface->makeImageSnapshot(); 79 80 for (auto clipBound : clipBounds) { 81 canvas->save(); 82 for (size_t i = 0; i < SK_ARRAY_COUNT(filters); ++i) { 83 SkIRect subset = SkIRect::MakeXYWH(25, 25, 50, 50); 84 SkIRect outSubset; 85 SkIPoint offset; 86 sk_sp<SkImage> result = source->makeWithFilter(filters[i].get(), subset, clipBound, 87 &outSubset, &offset); 88 SkASSERT(result); 89 SkASSERT(source->isTextureBacked() == result->isTextureBacked()); 90 result = result->makeSubset(outSubset); 91 canvas->drawImage(result.get(), SkIntToScalar(offset.fX), SkIntToScalar(offset.fY)); 92 show_bounds(canvas, SkIRect::MakeXYWH(offset.x(), offset.y(), outSubset.width(), 93 outSubset.height()), clipBound); 94 canvas->translate(DX, 0); 95 } 96 canvas->restore(); 97 canvas->translate(0, DY); 98 } 99 } 100 101 private: 102 typedef GM INHERITED; 103 }; 104 DEF_GM( return new ImageMakeWithFilterGM; ) 105