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