1 2 /* 3 * Copyright 2013 Google Inc. 4 * 5 * Use of this source code is governed by a BSD-style license that can be 6 * found in the LICENSE file. 7 */ 8 9 #include "gm.h" 10 #include "SkTArray.h" 11 #include "SkRandom.h" 12 #include "SkMatrix.h" 13 #include "SkBlurMaskFilter.h" 14 #include "SkGradientShader.h" 15 #include "SkBlurDrawLooper.h" 16 #include "SkRect.h" 17 18 namespace skiagm { 19 20 class OvalGM : public GM { 21 public: 22 OvalGM() { 23 this->setBGColor(0xFF000000); 24 this->makePaints(); 25 this->makeMatrices(); 26 } 27 28 protected: 29 30 SkString onShortName() override { 31 return SkString("ovals"); 32 } 33 34 SkISize onISize() override { 35 return SkISize::Make(1200, 900); 36 } 37 38 void makePaints() { 39 { 40 // no AA 41 SkPaint p; 42 fPaints.push_back(p); 43 } 44 45 { 46 // AA 47 SkPaint p; 48 p.setAntiAlias(true); 49 fPaints.push_back(p); 50 } 51 52 { 53 // AA with stroke style 54 SkPaint p; 55 p.setAntiAlias(true); 56 p.setStyle(SkPaint::kStroke_Style); 57 p.setStrokeWidth(SkIntToScalar(5)); 58 fPaints.push_back(p); 59 } 60 61 { 62 // AA with stroke style, width = 0 63 SkPaint p; 64 p.setAntiAlias(true); 65 p.setStyle(SkPaint::kStroke_Style); 66 fPaints.push_back(p); 67 } 68 69 { 70 // AA with stroke and fill style 71 SkPaint p; 72 p.setAntiAlias(true); 73 p.setStyle(SkPaint::kStrokeAndFill_Style); 74 p.setStrokeWidth(SkIntToScalar(3)); 75 fPaints.push_back(p); 76 } 77 } 78 79 void makeMatrices() { 80 { 81 SkMatrix m; 82 m.setIdentity(); 83 fMatrices.push_back(m); 84 } 85 86 { 87 SkMatrix m; 88 m.setScale(SkIntToScalar(3), SkIntToScalar(2)); 89 fMatrices.push_back(m); 90 } 91 92 { 93 SkMatrix m; 94 m.setScale(SkIntToScalar(2), SkIntToScalar(2)); 95 fMatrices.push_back(m); 96 } 97 98 { 99 SkMatrix m; 100 m.setScale(SkIntToScalar(1), SkIntToScalar(2)); 101 fMatrices.push_back(m); 102 } 103 104 { 105 SkMatrix m; 106 m.setScale(SkIntToScalar(4), SkIntToScalar(1)); 107 fMatrices.push_back(m); 108 } 109 110 { 111 SkMatrix m; 112 m.setRotate(SkIntToScalar(90)); 113 fMatrices.push_back(m); 114 } 115 116 { 117 SkMatrix m; 118 m.setSkew(SkIntToScalar(2), SkIntToScalar(3)); 119 fMatrices.push_back(m); 120 } 121 122 { 123 SkMatrix m; 124 m.setRotate(SkIntToScalar(60)); 125 fMatrices.push_back(m); 126 } 127 } 128 129 SkColor genColor(SkRandom* rand) { 130 SkScalar hsv[3]; 131 hsv[0] = rand->nextRangeF(0.0f, 360.0f); 132 hsv[1] = rand->nextRangeF(0.75f, 1.0f); 133 hsv[2] = rand->nextRangeF(0.75f, 1.0f); 134 135 return SkHSVToColor(hsv); 136 } 137 138 void onDraw(SkCanvas* canvas) override { 139 SkRandom rand(1); 140 canvas->translate(20 * SK_Scalar1, 20 * SK_Scalar1); 141 SkRect oval = SkRect::MakeLTRB(-20, -30, 20, 30); 142 143 const SkScalar kXStart = 60.0f; 144 const SkScalar kYStart = 80.0f; 145 const int kXStep = 150; 146 const int kYStep = 160; 147 int maxX = fMatrices.count(); 148 149 SkPaint rectPaint; 150 rectPaint.setAntiAlias(true); 151 rectPaint.setStyle(SkPaint::kStroke_Style); 152 rectPaint.setStrokeWidth(SkIntToScalar(0)); 153 rectPaint.setColor(SK_ColorLTGRAY); 154 155 int testCount = 0; 156 for (int i = 0; i < fPaints.count(); ++i) { 157 for (int j = 0; j < fMatrices.count(); ++j) { 158 canvas->save(); 159 SkMatrix mat = fMatrices[j]; 160 // position the oval, and make it at off-integer coords. 161 mat.postTranslate(kXStart + SK_Scalar1 * kXStep * (testCount % maxX) + 162 SK_Scalar1 / 4, 163 kYStart + SK_Scalar1 * kYStep * (testCount / maxX) + 164 3 * SK_Scalar1 / 4); 165 canvas->concat(mat); 166 167 SkColor color = genColor(&rand); 168 fPaints[i].setColor(color); 169 170 canvas->drawRect(oval, rectPaint); 171 canvas->drawOval(oval, fPaints[i]); 172 173 canvas->restore(); 174 175 ++testCount; 176 } 177 } 178 179 // special cases 180 181 // non-scaled tall and skinny oval 182 for (int i = 0; i < fPaints.count(); ++i) { 183 SkRect oval = SkRect::MakeLTRB(-20, -60, 20, 60); 184 canvas->save(); 185 // position the oval, and make it at off-integer coords. 186 canvas->translate(kXStart + SK_Scalar1 * kXStep * 2.55f + SK_Scalar1 / 4, 187 kYStart + SK_Scalar1 * kYStep * i + 3 * SK_Scalar1 / 4); 188 189 SkColor color = genColor(&rand); 190 fPaints[i].setColor(color); 191 192 canvas->drawRect(oval, rectPaint); 193 canvas->drawOval(oval, fPaints[i]); 194 canvas->restore(); 195 } 196 197 // non-scaled wide and short oval 198 for (int i = 0; i < fPaints.count(); ++i) { 199 SkRect oval = SkRect::MakeLTRB(-80, -30, 80, 30); 200 canvas->save(); 201 // position the oval, and make it at off-integer coords. 202 canvas->translate(kXStart + SK_Scalar1 * kXStep * 4 + SK_Scalar1 / 4, 203 kYStart + SK_Scalar1 * kYStep * i + 3 * SK_Scalar1 / 4 + 204 SK_ScalarHalf * kYStep); 205 206 SkColor color = genColor(&rand); 207 fPaints[i].setColor(color); 208 209 canvas->drawRect(oval, rectPaint); 210 canvas->drawOval(oval, fPaints[i]); 211 canvas->restore(); 212 } 213 214 // super skinny oval 215 for (int i = 0; i < fPaints.count(); ++i) { 216 SkRect oval = SkRect::MakeLTRB(0, -60, 1, 60); 217 canvas->save(); 218 // position the oval, and make it at off-integer coords. 219 canvas->translate(kXStart + SK_Scalar1 * kXStep * 3.25f + SK_Scalar1 / 4, 220 kYStart + SK_Scalar1 * kYStep * i + 3 * SK_Scalar1 / 4); 221 222 SkColor color = genColor(&rand); 223 fPaints[i].setColor(color); 224 225 canvas->drawOval(oval, fPaints[i]); 226 canvas->restore(); 227 } 228 229 // super short oval 230 for (int i = 0; i < fPaints.count(); ++i) { 231 SkRect oval = SkRect::MakeLTRB(-80, -1, 80, 0); 232 canvas->save(); 233 // position the oval, and make it at off-integer coords. 234 canvas->translate(kXStart + SK_Scalar1 * kXStep * 2.5f + SK_Scalar1 / 4, 235 kYStart + SK_Scalar1 * kYStep * i + 3 * SK_Scalar1 / 4 + 236 SK_ScalarHalf * kYStep); 237 238 SkColor color = genColor(&rand); 239 fPaints[i].setColor(color); 240 241 canvas->drawOval(oval, fPaints[i]); 242 canvas->restore(); 243 } 244 245 // radial gradient 246 SkPoint center = SkPoint::Make(SkIntToScalar(0), SkIntToScalar(0)); 247 SkColor colors[] = { SK_ColorBLUE, SK_ColorRED, SK_ColorGREEN }; 248 SkScalar pos[] = { 0, SK_ScalarHalf, SK_Scalar1 }; 249 SkAutoTUnref<SkShader> shader(SkGradientShader::CreateRadial(center, 250 SkIntToScalar(20), 251 colors, 252 pos, 253 SK_ARRAY_COUNT(colors), 254 SkShader::kClamp_TileMode)); 255 256 for (int i = 0; i < fPaints.count(); ++i) { 257 canvas->save(); 258 // position the path, and make it at off-integer coords. 259 canvas->translate(kXStart + SK_Scalar1 * kXStep * 0 + SK_Scalar1 / 4, 260 kYStart + SK_Scalar1 * kYStep * i + 3 * SK_Scalar1 / 4 + 261 SK_ScalarHalf * kYStep); 262 263 SkColor color = genColor(&rand); 264 fPaints[i].setColor(color); 265 fPaints[i].setShader(shader); 266 267 canvas->drawRect(oval, rectPaint); 268 canvas->drawOval(oval, fPaints[i]); 269 270 fPaints[i].setShader(NULL); 271 272 canvas->restore(); 273 } 274 } 275 276 private: 277 SkTArray<SkPaint> fPaints; 278 SkTArray<SkMatrix> fMatrices; 279 280 typedef GM INHERITED; 281 }; 282 283 ////////////////////////////////////////////////////////////////////////////// 284 285 static GM* MyFactory(void*) { return new OvalGM; } 286 static GMRegistry reg(MyFactory); 287 288 } 289