1 2 /* 3 * Copyright 2011 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 10 11 #include "gm.h" 12 #include "SkRandom.h" 13 14 #define W 400 15 #define H 400 16 #define N 50 17 18 static const SkScalar SW = SkIntToScalar(W); 19 static const SkScalar SH = SkIntToScalar(H); 20 21 static void rnd_rect(SkRect* r, SkPaint* paint, SkLCGRandom& rand) { 22 SkScalar x = rand.nextUScalar1() * W; 23 SkScalar y = rand.nextUScalar1() * H; 24 SkScalar w = rand.nextUScalar1() * (W >> 2); 25 SkScalar h = rand.nextUScalar1() * (H >> 2); 26 SkScalar hoffset = rand.nextSScalar1(); 27 SkScalar woffset = rand.nextSScalar1(); 28 29 r->set(x, y, x + w, y + h); 30 r->offset(-w/2 + woffset, -h/2 + hoffset); 31 32 paint->setColor(rand.nextU()); 33 paint->setAlpha(0xFF); 34 } 35 36 37 class StrokesGM : public skiagm::GM { 38 public: 39 StrokesGM() {} 40 41 protected: 42 virtual uint32_t onGetFlags() const SK_OVERRIDE { 43 return kSkipTiled_Flag; 44 } 45 46 virtual SkString onShortName() { 47 return SkString("strokes_round"); 48 } 49 50 virtual SkISize onISize() { 51 return SkISize::Make(W, H*2); 52 } 53 54 virtual void onDraw(SkCanvas* canvas) { 55 SkPaint paint; 56 paint.setStyle(SkPaint::kStroke_Style); 57 paint.setStrokeWidth(SkIntToScalar(9)/2); 58 59 for (int y = 0; y < 2; y++) { 60 paint.setAntiAlias(!!y); 61 SkAutoCanvasRestore acr(canvas, true); 62 canvas->translate(0, SH * y); 63 canvas->clipRect(SkRect::MakeLTRB( 64 SkIntToScalar(2), SkIntToScalar(2) 65 , SW - SkIntToScalar(2), SH - SkIntToScalar(2) 66 )); 67 68 SkLCGRandom rand; 69 for (int i = 0; i < N; i++) { 70 SkRect r; 71 rnd_rect(&r, &paint, rand); 72 canvas->drawOval(r, paint); 73 rnd_rect(&r, &paint, rand); 74 canvas->drawRoundRect(r, r.width()/4, r.height()/4, paint); 75 rnd_rect(&r, &paint, rand); 76 } 77 } 78 } 79 80 private: 81 typedef skiagm::GM INHERITED; 82 }; 83 84 class Strokes2GM : public skiagm::GM { 85 SkPath fPath; 86 public: 87 Strokes2GM() { 88 SkLCGRandom rand; 89 fPath.moveTo(0, 0); 90 for (int i = 0; i < 13; i++) { 91 SkScalar x = rand.nextUScalar1() * (W >> 1); 92 SkScalar y = rand.nextUScalar1() * (H >> 1); 93 fPath.lineTo(x, y); 94 } 95 } 96 97 protected: 98 virtual uint32_t onGetFlags() const SK_OVERRIDE { 99 return kSkipTiled_Flag; 100 } 101 102 virtual SkString onShortName() { 103 return SkString("strokes_poly"); 104 } 105 106 virtual SkISize onISize() { 107 return SkISize::Make(W, H*2); 108 } 109 110 static void rotate(SkScalar angle, SkScalar px, SkScalar py, SkCanvas* canvas) { 111 SkMatrix matrix; 112 matrix.setRotate(angle, px, py); 113 canvas->concat(matrix); 114 } 115 116 virtual void onDraw(SkCanvas* canvas) { 117 canvas->drawColor(SK_ColorWHITE); 118 119 SkPaint paint; 120 paint.setStyle(SkPaint::kStroke_Style); 121 paint.setStrokeWidth(SkIntToScalar(9)/2); 122 123 for (int y = 0; y < 2; y++) { 124 paint.setAntiAlias(!!y); 125 SkAutoCanvasRestore acr(canvas, true); 126 canvas->translate(0, SH * y); 127 canvas->clipRect(SkRect::MakeLTRB(SkIntToScalar(2), 128 SkIntToScalar(2), 129 SW - SkIntToScalar(2), 130 SH - SkIntToScalar(2))); 131 132 SkLCGRandom rand; 133 for (int i = 0; i < N/2; i++) { 134 SkRect r; 135 rnd_rect(&r, &paint, rand); 136 rotate(SkIntToScalar(15), SW/2, SH/2, canvas); 137 canvas->drawPath(fPath, paint); 138 } 139 } 140 } 141 142 private: 143 typedef skiagm::GM INHERITED; 144 }; 145 146 ////////////////////////////////////////////////////////////////////////////// 147 148 static SkRect inset(const SkRect& r) { 149 SkRect rr(r); 150 rr.inset(r.width()/10, r.height()/10); 151 return rr; 152 } 153 154 class Strokes3GM : public skiagm::GM { 155 static void make0(SkPath* path, const SkRect& bounds, SkString* title) { 156 path->addRect(bounds, SkPath::kCW_Direction); 157 path->addRect(inset(bounds), SkPath::kCW_Direction); 158 title->set("CW CW"); 159 } 160 161 static void make1(SkPath* path, const SkRect& bounds, SkString* title) { 162 path->addRect(bounds, SkPath::kCW_Direction); 163 path->addRect(inset(bounds), SkPath::kCCW_Direction); 164 title->set("CW CCW"); 165 } 166 167 static void make2(SkPath* path, const SkRect& bounds, SkString* title) { 168 path->addOval(bounds, SkPath::kCW_Direction); 169 path->addOval(inset(bounds), SkPath::kCW_Direction); 170 title->set("CW CW"); 171 } 172 173 static void make3(SkPath* path, const SkRect& bounds, SkString* title) { 174 path->addOval(bounds, SkPath::kCW_Direction); 175 path->addOval(inset(bounds), SkPath::kCCW_Direction); 176 title->set("CW CCW"); 177 } 178 179 static void make4(SkPath* path, const SkRect& bounds, SkString* title) { 180 path->addRect(bounds, SkPath::kCW_Direction); 181 SkRect r = bounds; 182 r.inset(bounds.width() / 10, -bounds.height() / 10); 183 path->addOval(r, SkPath::kCW_Direction); 184 title->set("CW CW"); 185 } 186 187 static void make5(SkPath* path, const SkRect& bounds, SkString* title) { 188 path->addRect(bounds, SkPath::kCW_Direction); 189 SkRect r = bounds; 190 r.inset(bounds.width() / 10, -bounds.height() / 10); 191 path->addOval(r, SkPath::kCCW_Direction); 192 title->set("CW CCW"); 193 } 194 195 public: 196 Strokes3GM() {} 197 198 protected: 199 virtual uint32_t onGetFlags() const SK_OVERRIDE { 200 return kSkipTiled_Flag; 201 } 202 203 virtual SkString onShortName() { 204 return SkString("strokes3"); 205 } 206 207 virtual SkISize onISize() { 208 return SkISize::Make(W, H*2); 209 } 210 211 virtual void onDraw(SkCanvas* canvas) { 212 SkPaint origPaint; 213 origPaint.setAntiAlias(true); 214 origPaint.setStyle(SkPaint::kStroke_Style); 215 SkPaint fillPaint(origPaint); 216 fillPaint.setColor(SK_ColorRED); 217 SkPaint strokePaint(origPaint); 218 strokePaint.setColor(0xFF4444FF); 219 220 void (*procs[])(SkPath*, const SkRect&, SkString*) = { 221 make0, make1, make2, make3, make4, make5 222 }; 223 224 canvas->translate(SkIntToScalar(20), SkIntToScalar(20)); 225 226 SkRect bounds = SkRect::MakeWH(SkIntToScalar(50), SkIntToScalar(50)); 227 SkScalar dx = bounds.width() * 4/3; 228 SkScalar dy = bounds.height() * 5; 229 230 for (size_t i = 0; i < SK_ARRAY_COUNT(procs); ++i) { 231 SkPath orig; 232 SkString str; 233 procs[i](&orig, bounds, &str); 234 235 canvas->save(); 236 for (int j = 0; j < 13; ++j) { 237 strokePaint.setStrokeWidth(SK_Scalar1 * j * j); 238 canvas->drawPath(orig, strokePaint); 239 canvas->drawPath(orig, origPaint); 240 SkPath fill; 241 strokePaint.getFillPath(orig, &fill); 242 canvas->drawPath(fill, fillPaint); 243 canvas->translate(dx + strokePaint.getStrokeWidth(), 0); 244 } 245 canvas->restore(); 246 canvas->translate(0, dy); 247 } 248 } 249 250 private: 251 typedef skiagm::GM INHERITED; 252 }; 253 254 ////////////////////////////////////////////////////////////////////////////// 255 256 static skiagm::GM* F0(void*) { return new StrokesGM; } 257 static skiagm::GM* F1(void*) { return new Strokes2GM; } 258 static skiagm::GM* F2(void*) { return new Strokes3GM; } 259 260 static skiagm::GMRegistry R0(F0); 261 static skiagm::GMRegistry R1(F1); 262 static skiagm::GMRegistry R2(F2); 263