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/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/SkRect.h" 18 #include "include/core/SkScalar.h" 19 #include "include/core/SkShader.h" 20 #include "include/core/SkSize.h" 21 #include "include/core/SkString.h" 22 #include "include/core/SkTileMode.h" 23 #include "include/core/SkTypes.h" 24 #include "include/effects/SkBlurDrawLooper.h" 25 #include "include/effects/SkGradientShader.h" 26 #include "include/private/SkTArray.h" 27 #include "src/core/SkBlurMask.h" 28 29 namespace skiagm { 30 31 class RectsGM : public GM { 32 sk_sp<SkDrawLooper> fLooper; 33 enum { 34 kLooperColorSentinel = 0x01020304 35 }; 36 public: RectsGM()37 RectsGM() { 38 this->setBGColor(0xFF000000); 39 this->makePaints(); 40 this->makeMatrices(); 41 this->makeRects(); 42 } 43 44 protected: 45 onShortName()46 SkString onShortName() override { 47 return SkString("rects"); 48 } 49 onISize()50 SkISize onISize() override { 51 return SkISize::Make(1200, 900); 52 } 53 makePaints()54 void makePaints() { 55 { 56 // no AA 57 SkPaint p; 58 p.setColor(SK_ColorWHITE); 59 fPaints.push_back(p); 60 } 61 62 { 63 // AA 64 SkPaint p; 65 p.setColor(SK_ColorWHITE); 66 p.setAntiAlias(true); 67 fPaints.push_back(p); 68 } 69 70 { 71 // AA with translucent 72 SkPaint p; 73 p.setColor(SK_ColorWHITE); 74 p.setAntiAlias(true); 75 p.setAlpha(0x66); 76 fPaints.push_back(p); 77 } 78 79 { 80 // AA with mask filter 81 SkPaint p; 82 p.setColor(SK_ColorWHITE); 83 p.setAntiAlias(true); 84 p.setMaskFilter(SkMaskFilter::MakeBlur( 85 kNormal_SkBlurStyle, 86 SkBlurMask::ConvertRadiusToSigma(SkIntToScalar(5)))); 87 fPaints.push_back(p); 88 } 89 90 { 91 // AA with radial shader 92 SkPaint p; 93 p.setColor(SK_ColorWHITE); 94 p.setAntiAlias(true); 95 SkPoint center = SkPoint::Make(SkIntToScalar(-5), SkIntToScalar(30)); 96 SkColor colors[] = { SK_ColorBLUE, SK_ColorRED, SK_ColorGREEN }; 97 SkScalar pos[] = { 0, SK_ScalarHalf, SK_Scalar1 }; 98 p.setShader(SkGradientShader::MakeRadial(center, 20, colors, pos, 99 SK_ARRAY_COUNT(colors), 100 SkTileMode::kClamp)); 101 fPaints.push_back(p); 102 } 103 104 fLooper = SkBlurDrawLooper::Make(SK_ColorWHITE, SkBlurMask::ConvertRadiusToSigma(10),5,10); 105 { 106 SkPaint p; 107 p.setColor(kLooperColorSentinel); 108 p.setAntiAlias(true); 109 fPaints.push_back(p); 110 } 111 { 112 // AA with stroke style 113 SkPaint p; 114 p.setColor(SK_ColorWHITE); 115 p.setAntiAlias(true); 116 p.setStyle(SkPaint::kStroke_Style); 117 p.setStrokeWidth(SkIntToScalar(3)); 118 fPaints.push_back(p); 119 } 120 121 { 122 // AA with bevel-stroke style 123 SkPaint p; 124 p.setColor(SK_ColorWHITE); 125 p.setAntiAlias(true); 126 p.setStyle(SkPaint::kStroke_Style); 127 p.setStrokeJoin(SkPaint::kBevel_Join); 128 p.setStrokeWidth(SkIntToScalar(3)); 129 fPaints.push_back(p); 130 } 131 132 { 133 // AA with round-stroke style 134 SkPaint p; 135 p.setColor(SK_ColorWHITE); 136 p.setAntiAlias(true); 137 p.setStyle(SkPaint::kStroke_Style); 138 p.setStrokeJoin(SkPaint::kRound_Join); 139 p.setStrokeWidth(SkIntToScalar(3)); 140 fPaints.push_back(p); 141 } 142 143 { 144 // AA with stroke style, width = 0 145 SkPaint p; 146 p.setColor(SK_ColorWHITE); 147 p.setAntiAlias(true); 148 p.setStyle(SkPaint::kStroke_Style); 149 fPaints.push_back(p); 150 } 151 152 { 153 // AA with stroke style, width wider than rect width and/or height 154 SkPaint p; 155 p.setColor(SK_ColorWHITE); 156 p.setAntiAlias(true); 157 p.setStyle(SkPaint::kStroke_Style); 158 p.setStrokeWidth(SkIntToScalar(40)); 159 fPaints.push_back(p); 160 } 161 162 { 163 // AA with stroke and fill style 164 SkPaint p; 165 p.setColor(SK_ColorWHITE); 166 p.setAntiAlias(true); 167 p.setStyle(SkPaint::kStrokeAndFill_Style); 168 p.setStrokeWidth(SkIntToScalar(2)); 169 fPaints.push_back(p); 170 } 171 } 172 makeMatrices()173 void makeMatrices() { 174 { 175 // 1x1.5 scale 176 SkMatrix m; 177 m.setScale(1, 1.5f); 178 fMatrices.push_back(m); 179 } 180 181 { 182 // 1.5x1.5 scale 183 SkMatrix m; 184 m.setScale(1.5f, 1.5f); 185 fMatrices.push_back(m); 186 } 187 188 { 189 // 1x1.5 skew 190 SkMatrix m; 191 m.setSkew(1, 1.5f); 192 fMatrices.push_back(m); 193 } 194 195 { 196 // 1.5x1.5 skew 197 SkMatrix m; 198 m.setSkew(1.5f, 1.5f); 199 fMatrices.push_back(m); 200 } 201 202 { 203 // 30 degree rotation 204 SkMatrix m; 205 m.setRotate(SkIntToScalar(30)); 206 fMatrices.push_back(m); 207 } 208 209 { 210 // 90 degree rotation 211 SkMatrix m; 212 m.setRotate(SkIntToScalar(90)); 213 fMatrices.push_back(m); 214 } 215 } 216 makeRects()217 void makeRects() { 218 { 219 // small square 220 SkRect r = SkRect::MakeLTRB(0, 0, 30, 30); 221 fRects.push_back(r); 222 } 223 224 { 225 // thin vertical 226 SkRect r = SkRect::MakeLTRB(0, 0, 2, 40); 227 fRects.push_back(r); 228 } 229 230 { 231 // thin horizontal 232 SkRect r = SkRect::MakeLTRB(0, 0, 40, 2); 233 fRects.push_back(r); 234 } 235 236 { 237 // very thin 238 SkRect r = SkRect::MakeLTRB(0, 0, 0.25f, 10); 239 fRects.push_back(r); 240 } 241 242 { 243 // zaftig 244 SkRect r = SkRect::MakeLTRB(0, 0, 60, 60); 245 fRects.push_back(r); 246 } 247 } 248 249 // position the current test on the canvas position(SkCanvas * canvas,int testCount)250 static void position(SkCanvas* canvas, int testCount) { 251 canvas->translate(SK_Scalar1 * 100 * (testCount % 10) + SK_Scalar1 / 4, 252 SK_Scalar1 * 100 * (testCount / 10) + 3 * SK_Scalar1 / 4); 253 } 254 onDraw(SkCanvas * canvas)255 void onDraw(SkCanvas* canvas) override { 256 canvas->translate(20 * SK_Scalar1, 20 * SK_Scalar1); 257 258 int testCount = 0; 259 260 for (int i = 0; i < fPaints.count(); ++i) { 261 for (int j = 0; j < fRects.count(); ++j, ++testCount) { 262 canvas->save(); 263 this->position(canvas, testCount); 264 SkPaint p = fPaints[i]; 265 if (p.getColor() == kLooperColorSentinel) { 266 p.setColor(SK_ColorWHITE); 267 SkRect r = fRects[j]; 268 fLooper->apply(canvas, p, [r](SkCanvas* c, const SkPaint& p) { 269 c->drawRect(r, p); 270 }); 271 } else { 272 canvas->drawRect(fRects[j], p); 273 } 274 canvas->restore(); 275 } 276 } 277 278 SkPaint paint; 279 paint.setColor(SK_ColorWHITE); 280 paint.setAntiAlias(true); 281 282 for (int i = 0; i < fMatrices.count(); ++i) { 283 for (int j = 0; j < fRects.count(); ++j, ++testCount) { 284 canvas->save(); 285 this->position(canvas, testCount); 286 canvas->concat(fMatrices[i]); 287 canvas->drawRect(fRects[j], paint); 288 canvas->restore(); 289 } 290 } 291 } 292 293 private: 294 SkTArray<SkPaint> fPaints; 295 SkTArray<SkMatrix> fMatrices; 296 SkTArray<SkRect> fRects; 297 298 typedef GM INHERITED; 299 }; 300 301 ////////////////////////////////////////////////////////////////////////////// 302 303 DEF_GM( return new RectsGM; ) 304 305 } 306