1/* 2 * Copyright 2013 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 "SkBitmapDevice.h" 10#include "SkBitmapSource.h" 11#include "SkColor.h" 12#include "SkMatrixImageFilter.h" 13#include "SkRefCnt.h" 14 15namespace skiagm { 16 17class ResizeGM : public GM { 18public: 19 ResizeGM() { 20 this->setBGColor(0x00000000); 21 } 22 23protected: 24 virtual SkString onShortName() { 25 return SkString("resizeimagefilter"); 26 } 27 28#ifdef SK_CPU_ARM64 29 // Skip tiled drawing on 64-bit ARM until https://skbug.com/2908 is fixed. 30 virtual uint32_t onGetFlags() const SK_OVERRIDE { 31 return kSkipTiled_Flag; 32 } 33#endif 34 35 void draw(SkCanvas* canvas, 36 const SkRect& rect, 37 const SkSize& deviceSize, 38 SkPaint::FilterLevel filterLevel, 39 SkImageFilter* input = NULL) { 40 SkRect dstRect; 41 canvas->getTotalMatrix().mapRect(&dstRect, rect); 42 canvas->save(); 43 SkScalar deviceScaleX = SkScalarDiv(deviceSize.width(), dstRect.width()); 44 SkScalar deviceScaleY = SkScalarDiv(deviceSize.height(), dstRect.height()); 45 canvas->translate(rect.x(), rect.y()); 46 canvas->scale(deviceScaleX, deviceScaleY); 47 canvas->translate(-rect.x(), -rect.y()); 48 SkMatrix matrix; 49 matrix.setScale(SkScalarInvert(deviceScaleX), 50 SkScalarInvert(deviceScaleY)); 51 SkAutoTUnref<SkImageFilter> imageFilter( 52 SkMatrixImageFilter::Create(matrix, filterLevel, input)); 53 SkPaint filteredPaint; 54 filteredPaint.setImageFilter(imageFilter.get()); 55 canvas->saveLayer(&rect, &filteredPaint); 56 SkPaint paint; 57 paint.setColor(0xFF00FF00); 58 SkRect ovalRect = rect; 59 ovalRect.inset(SkIntToScalar(4), SkIntToScalar(4)); 60 canvas->drawOval(ovalRect, paint); 61 canvas->restore(); // for saveLayer 62 canvas->restore(); 63 } 64 65 virtual SkISize onISize() { 66 return SkISize::Make(520, 100); 67 } 68 69 virtual void onDraw(SkCanvas* canvas) { 70 canvas->clear(0x00000000); 71 72 SkRect srcRect = SkRect::MakeWH(96, 96); 73 74 SkSize deviceSize = SkSize::Make(16, 16); 75 draw(canvas, 76 srcRect, 77 deviceSize, 78 SkPaint::kNone_FilterLevel); 79 80 canvas->translate(srcRect.width() + SkIntToScalar(10), 0); 81 draw(canvas, 82 srcRect, 83 deviceSize, 84 SkPaint::kLow_FilterLevel); 85 86 canvas->translate(srcRect.width() + SkIntToScalar(10), 0); 87 draw(canvas, 88 srcRect, 89 deviceSize, 90 SkPaint::kMedium_FilterLevel); 91 92 canvas->translate(srcRect.width() + SkIntToScalar(10), 0); 93 draw(canvas, 94 srcRect, 95 deviceSize, 96 SkPaint::kHigh_FilterLevel); 97 98 SkBitmap bitmap; 99 bitmap.allocN32Pixels(16, 16); 100 bitmap.eraseARGB(0x00, 0x00, 0x00, 0x00); 101 { 102 SkBitmapDevice bitmapDevice(bitmap); 103 SkCanvas bitmapCanvas(&bitmapDevice); 104 SkPaint paint; 105 paint.setColor(0xFF00FF00); 106 SkRect ovalRect = SkRect::MakeWH(16, 16); 107 ovalRect.inset(SkScalarDiv(2.0f, 3.0f), SkScalarDiv(2.0f, 3.0f)); 108 bitmapCanvas.drawOval(ovalRect, paint); 109 } 110 SkRect inRect = SkRect::MakeXYWH(-4, -4, 20, 20); 111 SkRect outRect = SkRect::MakeXYWH(-24, -24, 120, 120); 112 SkAutoTUnref<SkBitmapSource> source(SkBitmapSource::Create(bitmap, inRect, outRect)); 113 canvas->translate(srcRect.width() + SkIntToScalar(10), 0); 114 draw(canvas, 115 srcRect, 116 deviceSize, 117 SkPaint::kHigh_FilterLevel, 118 source.get()); 119 } 120 121private: 122 typedef GM INHERITED; 123}; 124 125////////////////////////////////////////////////////////////////////////////// 126 127static GM* MyFactory(void*) { return new ResizeGM; } 128static GMRegistry reg(MyFactory); 129 130} 131