Index: gm/blurcircles2.cpp |
diff --git a/gm/blurcircles2.cpp b/gm/blurcircles2.cpp |
new file mode 100644 |
index 0000000000000000000000000000000000000000..284c1ab24e1a4399b3cb5852d45bc8f8cae716c7 |
--- /dev/null |
+++ b/gm/blurcircles2.cpp |
@@ -0,0 +1,141 @@ |
+/* |
+* Copyright 2016 Google Inc. |
+* |
+* Use of this source code is governed by a BSD-style license that can be |
+* found in the LICENSE file. |
+*/ |
+ |
+#include "gm.h" |
+#include "SkAnimTimer.h" |
+#include "SkBlurMask.h" |
+#include "SkBlurMaskFilter.h" |
+#include "SkCanvas.h" |
+#include "SkPaint.h" |
+#include "SkPath.h" |
+#include "SkString.h" |
+ |
+/** |
+ * In GM mode this draws an array of circles with different radii and different blur radii. Below |
+ * each circle an almost-circle path is drawn with the same blur filter for comparison. |
+ * |
+ * In Sample mode this draws a single circle and almost-circle with animating radius and blur |
+ * radius. |
+ */ |
+class BlurCircles2GM : public skiagm::GM { |
+public: |
+ BlurCircles2GM() { |
+ fAnimRadius = SkAnimTimer::PingPong(0, kRadiusPingPoingPeriod, kRadiusPingPoingShift, |
+ kMinRadius, kMaxRadius); |
+ fAnimBlurRadius = SkAnimTimer::PingPong(0, kBlurRadiusPingPoingPeriod, |
+ kBlurRadiusPingPoingShift, kMinBlurRadius, |
+ kMaxBlurRadius); |
+ } |
+ |
+protected: |
+ SkString onShortName() override { return SkString("blurcircles2"); } |
+ |
+ SkISize onISize() override { |
+ return SkISize::Make(730, 1350); |
+ } |
+ |
+ void onDraw(SkCanvas* canvas) override { |
+ static constexpr SkScalar kMaxR = kMaxRadius + kMaxBlurRadius; |
+ |
+ auto almostCircleMaker = [] (SkScalar radius, SkPath* dst) { |
+ dst->reset(); |
+ dst->addArc(SkRect::MakeXYWH(-radius, -radius, 2 * radius, 2 * radius), 0, 355); |
+ dst->setIsVolatile(true); |
+ dst->close(); |
+ }; |
+ |
+ auto blurMaker = [] (SkScalar radius) ->sk_sp<SkMaskFilter> { |
+ return SkBlurMaskFilter::Make(kNormal_SkBlurStyle, |
+ SkBlurMask::ConvertRadiusToSigma(radius), |
+ SkBlurMaskFilter::kHighQuality_BlurFlag); |
+ }; |
+ |
+ SkPaint paint; |
+ paint.setColor(SK_ColorBLACK); |
+ |
+ if (this->getMode() == kSample_Mode) { |
+ paint.setMaskFilter(blurMaker(fAnimBlurRadius)); |
+ SkISize size = canvas->getBaseLayerSize(); |
+ SkPath almostCircle; |
+ almostCircleMaker(fAnimRadius, &almostCircle); |
+ canvas->save(); |
+ canvas->translate(size.fWidth / 2.f, size.fHeight / 4.f); |
+ canvas->drawCircle(0, 0, fAnimRadius, paint); |
+ canvas->translate(0, 2 * kMaxR); |
+ canvas->drawPath(almostCircle, paint); |
+ canvas->restore(); |
+ } else { |
+ canvas->save(); |
+ static constexpr SkScalar kPad = 5; |
+ static constexpr SkScalar kRadiusSteps = 5; |
+ static constexpr SkScalar kBlurRadiusSteps = 5; |
+ canvas->translate(kPad + kMinRadius + kMaxBlurRadius, |
+ kPad + kMinRadius + kMaxBlurRadius); |
+ SkScalar lineWidth = 0; |
+ for (int r = 0; r < kRadiusSteps - 1; ++r) { |
+ const SkScalar radius = r * (kMaxRadius - kMinRadius) / kBlurRadiusSteps + |
+ kMinRadius; |
+ lineWidth += 2 * (radius + kMaxBlurRadius) + kPad; |
+ } |
+ for (int br = 0; br < kBlurRadiusSteps; ++br) { |
+ const SkScalar blurRadius = br * (kMaxBlurRadius - kMinBlurRadius) / |
+ kBlurRadiusSteps + kMinBlurRadius; |
+ const SkScalar maxRowR = blurRadius + kMaxRadius; |
+ paint.setMaskFilter(blurMaker(blurRadius)); |
+ canvas->save(); |
+ for (int r = 0; r < kRadiusSteps; ++r) { |
+ const SkScalar radius = r * (kMaxRadius - kMinRadius) / kBlurRadiusSteps + |
+ kMinRadius; |
+ SkPath almostCircle; |
+ almostCircleMaker(radius, &almostCircle); |
+ canvas->save(); |
+ canvas->drawCircle(0, 0, radius, paint); |
+ canvas->translate(0, 2 * maxRowR + kPad); |
+ canvas->drawPath(almostCircle, paint); |
+ canvas->restore(); |
+ const SkScalar maxColR = radius + kMaxBlurRadius; |
+ canvas->translate(maxColR * 2 + kPad, 0); |
+ } |
+ canvas->restore(); |
+ SkPaint blackPaint; |
+ blackPaint.setColor(SK_ColorBLACK); |
+ const SkScalar lineY = 3 * maxRowR + 1.5f * kPad; |
+ if (br != kBlurRadiusSteps - 1) { |
+ canvas->drawLine(0, lineY, lineWidth, lineY, blackPaint); |
+ } |
+ canvas->translate(0, maxRowR * 4 + 2 * kPad); |
+ } |
+ canvas->restore(); |
+ } |
+ } |
+ |
+ bool onAnimate(const SkAnimTimer& timer) override { |
+ fAnimRadius = timer.pingPong(kRadiusPingPoingPeriod, kRadiusPingPoingShift, kMinRadius, |
+ kMaxRadius); |
+ fAnimBlurRadius = timer.pingPong(kBlurRadiusPingPoingPeriod, kBlurRadiusPingPoingShift, |
+ kMinBlurRadius, kMaxBlurRadius); |
+ return true; |
+ } |
+ |
+private: |
+ static constexpr SkScalar kMinRadius = 15; |
+ static constexpr SkScalar kMaxRadius = 45; |
+ static constexpr SkScalar kRadiusPingPoingPeriod = 8; |
+ static constexpr SkScalar kRadiusPingPoingShift = 3; |
+ |
+ static constexpr SkScalar kMinBlurRadius = 5; |
+ static constexpr SkScalar kMaxBlurRadius = 45; |
+ static constexpr SkScalar kBlurRadiusPingPoingPeriod = 3; |
+ static constexpr SkScalar kBlurRadiusPingPoingShift = 1.5; |
+ |
+ SkScalar fAnimRadius; |
+ SkScalar fAnimBlurRadius; |
+ |
+ typedef skiagm::GM INHERITED; |
+}; |
+ |
+DEF_GM(return new BlurCircles2GM();) |