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