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