1 /* 2 * Copyright 2017 Google Inc. 3 * 4 * Use of this source code is governed by a BD-style license that can be 5 * found in the LICENSE file. 6 */ 7 8 #include "gm/gm.h" 9 #include "include/core/SkBlurTypes.h" 10 #include "include/core/SkCanvas.h" 11 #include "include/core/SkColor.h" 12 #include "include/core/SkFont.h" 13 #include "include/core/SkMaskFilter.h" 14 #include "include/core/SkPaint.h" 15 #include "include/core/SkRRect.h" 16 #include "include/core/SkRect.h" 17 #include "include/core/SkRefCnt.h" 18 #include "include/core/SkScalar.h" 19 #include "include/core/SkSize.h" 20 #include "include/core/SkString.h" 21 #include "include/core/SkTypeface.h" 22 #include "include/core/SkTypes.h" 23 #include "src/core/SkBlurMask.h" 24 #include "tools/ToolUtils.h" 25 26 // This GM tests out the SkBlurMaskFilter's kIgnoreTransform flag. That flag causes the blur mask 27 // filter to not apply the CTM to the blur's radius. 28 class BlurIgnoreXformGM : public skiagm::GM { 29 public: 30 enum class DrawType { 31 kCircle, 32 kRect, 33 kRRect, 34 }; 35 BlurIgnoreXformGM(DrawType drawType)36 BlurIgnoreXformGM(DrawType drawType) : fDrawType(drawType) { } 37 38 protected: runAsBench() const39 bool runAsBench() const override { return true; } 40 onShortName()41 SkString onShortName() override { 42 SkString name; 43 name.printf("blur_ignore_xform_%s", 44 DrawType::kCircle == fDrawType ? "circle" 45 : DrawType::kRect == fDrawType ? "rect" : "rrect"); 46 return name; 47 } 48 onISize()49 SkISize onISize() override { 50 return SkISize::Make(375, 475); 51 } 52 onOnceBeforeDraw()53 void onOnceBeforeDraw() override { 54 for (int i = 0; i < kNumBlurs; ++i) { 55 fBlurFilters[i] = SkMaskFilter::MakeBlur( 56 kNormal_SkBlurStyle, 57 SkBlurMask::ConvertRadiusToSigma(SkIntToScalar(20)), 58 kBlurFlags[i].fRespectCTM); 59 } 60 } 61 onDraw(SkCanvas * canvas)62 void onDraw(SkCanvas* canvas) override { 63 SkPaint paint; 64 paint.setColor(SK_ColorBLACK); 65 paint.setAntiAlias(true); 66 67 canvas->translate(10, 25); 68 canvas->save(); 69 canvas->translate(80, 0); 70 for (size_t i = 0; i < kNumBlurs; ++i) { 71 SkAutoCanvasRestore autoRestore(canvas, true); 72 canvas->translate(SkIntToScalar(i * 150), 0); 73 for (auto scale : kMatrixScales) { 74 canvas->save(); 75 canvas->scale(scale.fScale, scale.fScale); 76 static const SkScalar kRadius = 20.0f; 77 SkScalar coord = 50.0f * 1.0f / scale.fScale; 78 SkRect rect = SkRect::MakeXYWH(coord - kRadius , coord - kRadius, 79 2 * kRadius, 2 * kRadius); 80 SkRRect rrect = SkRRect::MakeRectXY(rect, kRadius/2.0f, kRadius/2.0f); 81 82 paint.setMaskFilter(fBlurFilters[i]); 83 for (int j = 0; j < 2; ++j) { 84 canvas->save(); 85 canvas->translate(10 * (1 - j), 10 * (1 - j)); 86 if (DrawType::kCircle == fDrawType) { 87 canvas->drawCircle(coord, coord, kRadius, paint); 88 } else if (DrawType::kRect == fDrawType) { 89 canvas->drawRect(rect, paint); 90 } else { 91 canvas->drawRRect(rrect, paint); 92 } 93 paint.setMaskFilter(nullptr); 94 canvas->restore(); 95 } 96 canvas->restore(); 97 canvas->translate(0, SkIntToScalar(150)); 98 } 99 } 100 canvas->restore(); 101 if (kBench_Mode != this->getMode()) { 102 this->drawOverlay(canvas); 103 } 104 } 105 drawOverlay(SkCanvas * canvas)106 void drawOverlay(SkCanvas* canvas) { 107 canvas->translate(10, 0); 108 SkFont font(ToolUtils::create_portable_typeface()); 109 canvas->save(); 110 for (int i = 0; i < kNumBlurs; ++i) { 111 canvas->drawString(kBlurFlags[i].fName, 100, 0, font, SkPaint()); 112 canvas->translate(SkIntToScalar(130), 0); 113 } 114 canvas->restore(); 115 for (auto scale : kMatrixScales) { 116 canvas->drawString(scale.fName, 0, 50, font, SkPaint()); 117 canvas->translate(0, SkIntToScalar(150)); 118 } 119 } 120 121 private: 122 inline static constexpr int kNumBlurs = 2; 123 124 static const struct BlurFlags { 125 bool fRespectCTM; 126 const char* fName; 127 } kBlurFlags[kNumBlurs]; 128 129 static const struct MatrixScale { 130 float fScale; 131 const char* fName; 132 } kMatrixScales[3]; 133 134 DrawType fDrawType; 135 sk_sp<SkMaskFilter> fBlurFilters[kNumBlurs]; 136 137 using INHERITED = skiagm::GM; 138 }; 139 140 const BlurIgnoreXformGM::BlurFlags BlurIgnoreXformGM::kBlurFlags[] = { 141 {true, "none"}, 142 {false, "IgnoreTransform"} 143 }; 144 145 const BlurIgnoreXformGM::MatrixScale BlurIgnoreXformGM::kMatrixScales[] = { 146 {1.0f, "Identity"}, 147 {0.5f, "Scale = 0.5"}, 148 {2.0f, "Scale = 2.0"} 149 }; 150 151 DEF_GM(return new BlurIgnoreXformGM(BlurIgnoreXformGM::DrawType::kCircle);) 152 DEF_GM(return new BlurIgnoreXformGM(BlurIgnoreXformGM::DrawType::kRect);) 153 DEF_GM(return new BlurIgnoreXformGM(BlurIgnoreXformGM::DrawType::kRRect);) 154 155 156 157