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