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