1 /* 2 * Copyright 2012 Intel 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/SkDrawLooper.h" 13 #include "include/core/SkMaskFilter.h" 14 #include "include/core/SkMatrix.h" 15 #include "include/core/SkPaint.h" 16 #include "include/core/SkPoint.h" 17 #include "include/core/SkScalar.h" 18 #include "include/core/SkShader.h" 19 #include "include/core/SkSize.h" 20 #include "include/core/SkString.h" 21 #include "include/core/SkTileMode.h" 22 #include "include/core/SkTypes.h" 23 #include "include/effects/SkBlurDrawLooper.h" 24 #include "include/effects/SkGradientShader.h" 25 #include "include/private/SkTArray.h" 26 #include "include/utils/SkRandom.h" 27 #include "src/core/SkBlurMask.h" 28 29 namespace skiagm { 30 31 class CircleGM : public GM { 32 sk_sp<SkDrawLooper> fLooper; 33 enum { 34 kLooperColorSentinel = 0x01020304 35 }; 36 37 protected: onOnceBeforeDraw()38 void onOnceBeforeDraw() override { 39 this->setBGColor(0xFF000000); 40 this->makePaints(); 41 this->makeMatrices(); 42 } 43 onShortName()44 SkString onShortName() override { 45 return SkString("circles"); 46 } 47 onISize()48 SkISize onISize() override { 49 return SkISize::Make(1200, 900); 50 } 51 makePaints()52 void makePaints() { 53 { 54 // no AA 55 SkPaint p; 56 fPaints.push_back(p); 57 } 58 59 { 60 // AA 61 SkPaint p; 62 p.setAntiAlias(true); 63 fPaints.push_back(p); 64 } 65 66 { 67 // AA with mask filter 68 SkPaint p; 69 p.setAntiAlias(true); 70 p.setMaskFilter(SkMaskFilter::MakeBlur( 71 kNormal_SkBlurStyle, 72 SkBlurMask::ConvertRadiusToSigma(SkIntToScalar(5)))); 73 fPaints.push_back(p); 74 } 75 76 { 77 // AA with radial shader 78 SkPaint p; 79 p.setAntiAlias(true); 80 SkPoint center = SkPoint::Make(SkIntToScalar(40), SkIntToScalar(40)); 81 SkColor colors[] = { SK_ColorBLUE, SK_ColorRED, SK_ColorGREEN }; 82 SkScalar pos[] = { 0, SK_ScalarHalf, SK_Scalar1 }; 83 p.setShader(SkGradientShader::MakeRadial(center, 20, colors, pos, SK_ARRAY_COUNT(colors), 84 SkTileMode::kClamp)); 85 fPaints.push_back(p); 86 } 87 88 fLooper = SkBlurDrawLooper::Make(SK_ColorBLUE, SkBlurMask::ConvertRadiusToSigma(10),5,10); 89 { 90 SkPaint p; 91 p.setColor(kLooperColorSentinel); 92 p.setAntiAlias(true); 93 fPaints.push_back(p); 94 } 95 { 96 // AA with stroke style 97 SkPaint p; 98 p.setAntiAlias(true); 99 p.setStroke(true); 100 p.setStrokeWidth(SkIntToScalar(3)); 101 fPaints.push_back(p); 102 } 103 104 { 105 // AA with stroke style, width = 0 106 SkPaint p; 107 p.setAntiAlias(true); 108 p.setStroke(true); 109 fPaints.push_back(p); 110 } 111 112 { 113 // AA with stroke and fill style 114 SkPaint p; 115 p.setAntiAlias(true); 116 p.setStyle(SkPaint::kStrokeAndFill_Style); 117 p.setStrokeWidth(SkIntToScalar(2)); 118 fPaints.push_back(p); 119 } 120 } 121 makeMatrices()122 void makeMatrices() { 123 { 124 SkMatrix m; 125 m.setScale(SkIntToScalar(2), SkIntToScalar(3)); 126 fMatrices.push_back(m); 127 } 128 129 { 130 SkMatrix m; 131 m.setScale(SkIntToScalar(2), SkIntToScalar(2)); 132 fMatrices.push_back(m); 133 } 134 135 { 136 SkMatrix m; 137 m.setSkew(SkIntToScalar(2), SkIntToScalar(3)); 138 fMatrices.push_back(m); 139 } 140 141 { 142 SkMatrix m; 143 m.setSkew(SkIntToScalar(2), SkIntToScalar(2)); 144 fMatrices.push_back(m); 145 } 146 147 { 148 SkMatrix m; 149 m.setRotate(SkIntToScalar(30)); 150 fMatrices.push_back(m); 151 } 152 } 153 onDraw(SkCanvas * canvas)154 void onDraw(SkCanvas* canvas) override { 155 // Draw a giant AA circle as the background. 156 SkISize size = this->getISize(); 157 SkScalar giantRadius = std::min(SkIntToScalar(size.fWidth), 158 SkIntToScalar(size.fHeight)) / 2.f; 159 SkPoint giantCenter = SkPoint::Make(SkIntToScalar(size.fWidth/2), 160 SkIntToScalar(size.fHeight/2)); 161 SkPaint giantPaint; 162 giantPaint.setAntiAlias(true); 163 giantPaint.setColor(0x80808080); 164 canvas->drawCircle(giantCenter, giantRadius, giantPaint); 165 166 SkRandom rand; 167 canvas->translate(20 * SK_Scalar1, 20 * SK_Scalar1); 168 int i; 169 for (i = 0; i < fPaints.count(); ++i) { 170 canvas->save(); 171 // position the path, and make it at off-integer coords. 172 canvas->translate(SK_Scalar1 * 200 * (i % 5) + SK_Scalar1 / 4, 173 SK_Scalar1 * 200 * (i / 5) + 3 * SK_Scalar1 / 4); 174 SkPaint p = fPaints[i]; 175 p.setColor(rand.nextU() | 0xff000000); 176 if (fPaints[i].getColor() == kLooperColorSentinel) { 177 fLooper->apply(canvas, p, [](SkCanvas* c, const SkPaint& p) { 178 c->drawCircle(40, 40, 20, p); 179 }); 180 } else { 181 canvas->drawCircle(40, 40, 20, p); 182 } 183 canvas->restore(); 184 } 185 186 for (int j = 0; j < fMatrices.count(); ++j, ++i) { 187 canvas->save(); 188 189 canvas->translate(SK_Scalar1 * 200 * (i % 5) + SK_Scalar1 / 4, 190 SK_Scalar1 * 200 * (i / 5) + 3 * SK_Scalar1 / 4); 191 192 canvas->concat(fMatrices[j]); 193 194 SkPaint paint; 195 paint.setAntiAlias(true); 196 paint.setColor(rand.nextU() | 0xff000000); 197 canvas->drawCircle(40, 40, 20, paint); 198 199 canvas->restore(); 200 } 201 } 202 203 private: 204 using INHERITED = GM; 205 SkTArray<SkPaint> fPaints; 206 SkTArray<SkMatrix> fMatrices; 207 }; 208 209 ////////////////////////////////////////////////////////////////////////////// 210 211 DEF_GM( return new CircleGM; ) 212 213 } // namespace skiagm 214