OLD | NEW |
(Empty) | |
| 1 /* |
| 2 * Copyright 2016 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 "SkAnimTimer.h" |
| 10 #include "SkBlurMask.h" |
| 11 #include "SkBlurMaskFilter.h" |
| 12 #include "SkCanvas.h" |
| 13 #include "SkPaint.h" |
| 14 #include "SkPath.h" |
| 15 #include "SkString.h" |
| 16 |
| 17 /** |
| 18 * In GM mode this draws an array of circles with different radii and different
blur radii. Below |
| 19 * each circle an almost-circle path is drawn with the same blur filter for comp
arison. |
| 20 * |
| 21 * In Sample mode this draws a single circle and almost-circle with animating ra
dius and blur |
| 22 * radius. |
| 23 */ |
| 24 class BlurCircles2GM : public skiagm::GM { |
| 25 public: |
| 26 BlurCircles2GM() { |
| 27 fAnimRadius = SkAnimTimer::PingPong(0, kRadiusPingPoingPeriod, kRadiusPi
ngPoingShift, |
| 28 kMinRadius, kMaxRadius); |
| 29 fAnimBlurRadius = SkAnimTimer::PingPong(0, kBlurRadiusPingPoingPeriod, |
| 30 kBlurRadiusPingPoingShift, kMinB
lurRadius, |
| 31 kMaxBlurRadius); |
| 32 } |
| 33 |
| 34 protected: |
| 35 SkString onShortName() override { return SkString("blurcircles2"); } |
| 36 |
| 37 SkISize onISize() override { |
| 38 return SkISize::Make(730, 1350); |
| 39 } |
| 40 |
| 41 void onDraw(SkCanvas* canvas) override { |
| 42 static constexpr SkScalar kMaxR = kMaxRadius + kMaxBlurRadius; |
| 43 |
| 44 auto almostCircleMaker = [] (SkScalar radius, SkPath* dst) { |
| 45 dst->reset(); |
| 46 dst->addArc(SkRect::MakeXYWH(-radius, -radius, 2 * radius, 2 * radiu
s), 0, 355); |
| 47 dst->setIsVolatile(true); |
| 48 dst->close(); |
| 49 }; |
| 50 |
| 51 auto blurMaker = [] (SkScalar radius) ->sk_sp<SkMaskFilter> { |
| 52 return SkBlurMaskFilter::Make(kNormal_SkBlurStyle, |
| 53 SkBlurMask::ConvertRadiusToSigma(radiu
s), |
| 54 SkBlurMaskFilter::kHighQuality_BlurFla
g); |
| 55 }; |
| 56 |
| 57 SkPaint paint; |
| 58 paint.setColor(SK_ColorBLACK); |
| 59 |
| 60 if (this->getMode() == kSample_Mode) { |
| 61 paint.setMaskFilter(blurMaker(fAnimBlurRadius)); |
| 62 SkISize size = canvas->getBaseLayerSize(); |
| 63 SkPath almostCircle; |
| 64 almostCircleMaker(fAnimRadius, &almostCircle); |
| 65 canvas->save(); |
| 66 canvas->translate(size.fWidth / 2.f, size.fHeight / 4.f); |
| 67 canvas->drawCircle(0, 0, fAnimRadius, paint); |
| 68 canvas->translate(0, 2 * kMaxR); |
| 69 canvas->drawPath(almostCircle, paint); |
| 70 canvas->restore(); |
| 71 } else { |
| 72 canvas->save(); |
| 73 static constexpr SkScalar kPad = 5; |
| 74 static constexpr SkScalar kRadiusSteps = 5; |
| 75 static constexpr SkScalar kBlurRadiusSteps = 5; |
| 76 canvas->translate(kPad + kMinRadius + kMaxBlurRadius, |
| 77 kPad + kMinRadius + kMaxBlurRadius); |
| 78 SkScalar lineWidth = 0; |
| 79 for (int r = 0; r < kRadiusSteps - 1; ++r) { |
| 80 const SkScalar radius = r * (kMaxRadius - kMinRadius) / kBlurRad
iusSteps + |
| 81 kMinRadius; |
| 82 lineWidth += 2 * (radius + kMaxBlurRadius) + kPad; |
| 83 } |
| 84 for (int br = 0; br < kBlurRadiusSteps; ++br) { |
| 85 const SkScalar blurRadius = br * (kMaxBlurRadius - kMinBlurRadiu
s) / |
| 86 kBlurRadiusSteps + kMinBlurRadius; |
| 87 const SkScalar maxRowR = blurRadius + kMaxRadius; |
| 88 paint.setMaskFilter(blurMaker(blurRadius)); |
| 89 canvas->save(); |
| 90 for (int r = 0; r < kRadiusSteps; ++r) { |
| 91 const SkScalar radius = r * (kMaxRadius - kMinRadius) / kBlu
rRadiusSteps + |
| 92 kMinRadius; |
| 93 SkPath almostCircle; |
| 94 almostCircleMaker(radius, &almostCircle); |
| 95 canvas->save(); |
| 96 canvas->drawCircle(0, 0, radius, paint); |
| 97 canvas->translate(0, 2 * maxRowR + kPad); |
| 98 canvas->drawPath(almostCircle, paint); |
| 99 canvas->restore(); |
| 100 const SkScalar maxColR = radius + kMaxBlurRadius; |
| 101 canvas->translate(maxColR * 2 + kPad, 0); |
| 102 } |
| 103 canvas->restore(); |
| 104 SkPaint blackPaint; |
| 105 blackPaint.setColor(SK_ColorBLACK); |
| 106 const SkScalar lineY = 3 * maxRowR + 1.5f * kPad; |
| 107 if (br != kBlurRadiusSteps - 1) { |
| 108 canvas->drawLine(0, lineY, lineWidth, lineY, blackPaint); |
| 109 } |
| 110 canvas->translate(0, maxRowR * 4 + 2 * kPad); |
| 111 } |
| 112 canvas->restore(); |
| 113 } |
| 114 } |
| 115 |
| 116 bool onAnimate(const SkAnimTimer& timer) override { |
| 117 fAnimRadius = timer.pingPong(kRadiusPingPoingPeriod, kRadiusPingPoingShi
ft, kMinRadius, |
| 118 kMaxRadius); |
| 119 fAnimBlurRadius = timer.pingPong(kBlurRadiusPingPoingPeriod, kBlurRadius
PingPoingShift, |
| 120 kMinBlurRadius, kMaxBlurRadius); |
| 121 return true; |
| 122 } |
| 123 |
| 124 private: |
| 125 static constexpr SkScalar kMinRadius = 15; |
| 126 static constexpr SkScalar kMaxRadius = 45; |
| 127 static constexpr SkScalar kRadiusPingPoingPeriod = 8; |
| 128 static constexpr SkScalar kRadiusPingPoingShift = 3; |
| 129 |
| 130 static constexpr SkScalar kMinBlurRadius = 5; |
| 131 static constexpr SkScalar kMaxBlurRadius = 45; |
| 132 static constexpr SkScalar kBlurRadiusPingPoingPeriod = 3; |
| 133 static constexpr SkScalar kBlurRadiusPingPoingShift = 1.5; |
| 134 |
| 135 SkScalar fAnimRadius; |
| 136 SkScalar fAnimBlurRadius; |
| 137 |
| 138 typedef skiagm::GM INHERITED; |
| 139 }; |
| 140 |
| 141 DEF_GM(return new BlurCircles2GM();) |
OLD | NEW |