/* * Copyright 2017 Google Inc. * * Use of this source code is governed by a BD-style license that can be * found in the LICENSE file. */ #include "gm/gm.h" #include "include/core/SkBlurTypes.h" #include "include/core/SkCanvas.h" #include "include/core/SkColor.h" #include "include/core/SkFont.h" #include "include/core/SkMaskFilter.h" #include "include/core/SkPaint.h" #include "include/core/SkRRect.h" #include "include/core/SkRect.h" #include "include/core/SkRefCnt.h" #include "include/core/SkScalar.h" #include "include/core/SkSize.h" #include "include/core/SkString.h" #include "include/core/SkTypeface.h" #include "include/core/SkTypes.h" #include "src/core/SkBlurMask.h" #include "tools/ToolUtils.h" // This GM tests out the SkBlurMaskFilter's kIgnoreTransform flag. That flag causes the blur mask // filter to not apply the CTM to the blur's radius. class BlurIgnoreXformGM : public skiagm::GM { public: enum class DrawType { kCircle, kRect, kRRect, }; BlurIgnoreXformGM(DrawType drawType) : fDrawType(drawType) { } protected: bool runAsBench() const override { return true; } SkString onShortName() override { SkString name; name.printf("blur_ignore_xform_%s", DrawType::kCircle == fDrawType ? "circle" : DrawType::kRect == fDrawType ? "rect" : "rrect"); return name; } SkISize onISize() override { return SkISize::Make(375, 475); } void onOnceBeforeDraw() override { for (int i = 0; i < kNumBlurs; ++i) { fBlurFilters[i] = SkMaskFilter::MakeBlur( kNormal_SkBlurStyle, SkBlurMask::ConvertRadiusToSigma(SkIntToScalar(20)), kBlurFlags[i].fRespectCTM); } } void onDraw(SkCanvas* canvas) override { SkPaint paint; paint.setColor(SK_ColorBLACK); paint.setAntiAlias(true); canvas->translate(10, 25); canvas->save(); canvas->translate(80, 0); for (size_t i = 0; i < kNumBlurs; ++i) { SkAutoCanvasRestore autoRestore(canvas, true); canvas->translate(SkIntToScalar(i * 150), 0); for (auto scale : kMatrixScales) { canvas->save(); canvas->scale(scale.fScale, scale.fScale); static const SkScalar kRadius = 20.0f; SkScalar coord = 50.0f * 1.0f / scale.fScale; SkRect rect = SkRect::MakeXYWH(coord - kRadius , coord - kRadius, 2 * kRadius, 2 * kRadius); SkRRect rrect = SkRRect::MakeRectXY(rect, kRadius/2.0f, kRadius/2.0f); paint.setMaskFilter(fBlurFilters[i]); for (int j = 0; j < 2; ++j) { canvas->save(); canvas->translate(10 * (1 - j), 10 * (1 - j)); if (DrawType::kCircle == fDrawType) { canvas->drawCircle(coord, coord, kRadius, paint); } else if (DrawType::kRect == fDrawType) { canvas->drawRect(rect, paint); } else { canvas->drawRRect(rrect, paint); } paint.setMaskFilter(nullptr); canvas->restore(); } canvas->restore(); canvas->translate(0, SkIntToScalar(150)); } } canvas->restore(); if (kBench_Mode != this->getMode()) { this->drawOverlay(canvas); } } void drawOverlay(SkCanvas* canvas) { canvas->translate(10, 0); SkFont font(ToolUtils::create_portable_typeface()); canvas->save(); for (int i = 0; i < kNumBlurs; ++i) { canvas->drawString(kBlurFlags[i].fName, 100, 0, font, SkPaint()); canvas->translate(SkIntToScalar(130), 0); } canvas->restore(); for (auto scale : kMatrixScales) { canvas->drawString(scale.fName, 0, 50, font, SkPaint()); canvas->translate(0, SkIntToScalar(150)); } } private: inline static constexpr int kNumBlurs = 2; static const struct BlurFlags { bool fRespectCTM; const char* fName; } kBlurFlags[kNumBlurs]; static const struct MatrixScale { float fScale; const char* fName; } kMatrixScales[3]; DrawType fDrawType; sk_sp fBlurFilters[kNumBlurs]; using INHERITED = skiagm::GM; }; const BlurIgnoreXformGM::BlurFlags BlurIgnoreXformGM::kBlurFlags[] = { {true, "none"}, {false, "IgnoreTransform"} }; const BlurIgnoreXformGM::MatrixScale BlurIgnoreXformGM::kMatrixScales[] = { {1.0f, "Identity"}, {0.5f, "Scale = 0.5"}, {2.0f, "Scale = 2.0"} }; DEF_GM(return new BlurIgnoreXformGM(BlurIgnoreXformGM::DrawType::kCircle);) DEF_GM(return new BlurIgnoreXformGM(BlurIgnoreXformGM::DrawType::kRect);) DEF_GM(return new BlurIgnoreXformGM(BlurIgnoreXformGM::DrawType::kRRect);)