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