1 /* 2 * Copyright 2013 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/gm.h" 9 #include "include/core/SkBlurTypes.h" 10 #include "include/core/SkCanvas.h" 11 #include "include/core/SkColor.h" 12 #include "include/core/SkMaskFilter.h" 13 #include "include/core/SkPaint.h" 14 #include "include/core/SkPathBuilder.h" 15 #include "include/core/SkPoint.h" 16 #include "include/core/SkRect.h" 17 #include "include/core/SkScalar.h" 18 #include "include/core/SkSize.h" 19 #include "include/core/SkString.h" 20 #include "include/core/SkTypes.h" 21 #include "src/core/SkBlurMask.h" 22 23 namespace skiagm { 24 25 // This GM exercises the blurred rect nine-patching special cases when the 26 // blurred rect is very large and/or very far from the origin. 27 // It creates a large blurred rect/rectori then renders the 4 corners and the 28 // middle. 29 class BigBlursGM : public GM { 30 public: BigBlursGM()31 BigBlursGM() { 32 this->setBGColor(0xFFDDDDDD); 33 } 34 35 protected: onShortName()36 SkString onShortName() override { 37 return SkString("bigblurs"); 38 } 39 onISize()40 SkISize onISize() override { 41 return SkISize::Make(kWidth, kHeight); 42 } 43 onDraw(SkCanvas * canvas)44 void onDraw(SkCanvas* canvas) override { 45 constexpr int kBig = 65536; 46 const SkScalar kSigma = SkBlurMask::ConvertRadiusToSigma(SkIntToScalar(4)); 47 48 const SkRect bigRect = SkRect::MakeWH(SkIntToScalar(kBig), SkIntToScalar(kBig)); 49 SkRect insetRect = bigRect; 50 insetRect.inset(20, 20); 51 52 SkPath rectori = SkPathBuilder().addRect(bigRect) 53 .addRect(insetRect, SkPathDirection::kCCW) 54 .detach(); 55 56 // The blur extends 3*kSigma out from the big rect. 57 // Offset the close-up windows so we get the entire blur 58 const SkScalar kLeftTopPad = 3*kSigma; // use on left & up of big rect 59 const SkScalar kRightBotPad = kCloseUpSize-3*kSigma; // use on right and bot sides 60 61 // UL hand corners of the rendered closeups 62 const SkPoint origins[] = { 63 { -kLeftTopPad, -kLeftTopPad }, // UL 64 { kBig-kRightBotPad, -kLeftTopPad }, // UR 65 { kBig-kRightBotPad, kBig-kRightBotPad }, // LR 66 { -kLeftTopPad, kBig-kRightBotPad }, // LL 67 { kBig/2-kCloseUpSize/2, kBig/2-kCloseUpSize/2 }, // center 68 }; 69 70 SkPaint outlinePaint; 71 outlinePaint.setColor(SK_ColorRED); 72 outlinePaint.setStyle(SkPaint::kStroke_Style); 73 74 SkPaint blurPaint; 75 blurPaint.setAntiAlias(true); 76 blurPaint.setColor(SK_ColorBLACK); 77 78 int desiredX = 0, desiredY = 0; 79 80 for (int i = 0; i < 2; ++i) { 81 for (int j = 0; j <= kLastEnum_SkBlurStyle; ++j) { 82 blurPaint.setMaskFilter(SkMaskFilter::MakeBlur((SkBlurStyle)j, kSigma)); 83 84 for (int k = 0; k < (int)SK_ARRAY_COUNT(origins); ++k) { 85 canvas->save(); 86 87 SkRect clipRect = SkRect::MakeXYWH(SkIntToScalar(desiredX), 88 SkIntToScalar(desiredY), 89 SkIntToScalar(kCloseUpSize), 90 SkIntToScalar(kCloseUpSize)); 91 92 canvas->clipRect(clipRect); 93 94 canvas->translate(desiredX-origins[k].fX, 95 desiredY-origins[k].fY); 96 97 if (0 == i) { 98 canvas->drawRect(bigRect, blurPaint); 99 } else { 100 canvas->drawPath(rectori, blurPaint); 101 } 102 canvas->restore(); 103 canvas->drawRect(clipRect, outlinePaint); 104 105 desiredX += kCloseUpSize; 106 } 107 108 desiredX = 0; 109 desiredY += kCloseUpSize; 110 } 111 } 112 } 113 114 private: 115 inline static constexpr int kCloseUpSize = 64; 116 inline static constexpr int kWidth = 5 * kCloseUpSize; 117 inline static constexpr int kHeight = 2 * (kLastEnum_SkBlurStyle + 1) * kCloseUpSize; 118 119 using INHERITED = GM; 120 }; 121 122 DEF_GM(return new BigBlursGM;) 123 } // namespace skiagm 124