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