1 /* 2 * Copyright 2011 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 #include "gm.h" 8 #include "SkCanvas.h" 9 #include "SkPaint.h" 10 #include "SkRandom.h" 11 12 namespace skiagm { 13 14 class LinePathGM : public GM { 15 public: 16 LinePathGM() {} 17 18 protected: 19 SkString onShortName() { 20 return SkString("linepath"); 21 } 22 23 SkISize onISize() { return make_isize(1240, 390); } 24 25 void drawPath(SkPath& path,SkCanvas* canvas,SkColor color, 26 const SkRect& clip,SkPaint::Cap cap, SkPaint::Join join, 27 SkPaint::Style style, SkPath::FillType fill, 28 SkScalar strokeWidth) { 29 path.setFillType(fill); 30 SkPaint paint; 31 paint.setStrokeCap(cap); 32 paint.setStrokeWidth(strokeWidth); 33 paint.setStrokeJoin(join); 34 paint.setColor(color); 35 paint.setStyle(style); 36 canvas->save(); 37 canvas->clipRect(clip); 38 canvas->drawPath(path, paint); 39 canvas->restore(); 40 } 41 42 virtual void onDraw(SkCanvas* canvas) { 43 struct FillAndName { 44 SkPath::FillType fFill; 45 const char* fName; 46 }; 47 static const FillAndName gFills[] = { 48 {SkPath::kWinding_FillType, "Winding"}, 49 {SkPath::kEvenOdd_FillType, "Even / Odd"}, 50 {SkPath::kInverseWinding_FillType, "Inverse Winding"}, 51 {SkPath::kInverseEvenOdd_FillType, "Inverse Even / Odd"}, 52 }; 53 struct StyleAndName { 54 SkPaint::Style fStyle; 55 const char* fName; 56 }; 57 static const StyleAndName gStyles[] = { 58 {SkPaint::kFill_Style, "Fill"}, 59 {SkPaint::kStroke_Style, "Stroke"}, 60 {SkPaint::kStrokeAndFill_Style, "Stroke And Fill"}, 61 }; 62 struct CapAndName { 63 SkPaint::Cap fCap; 64 SkPaint::Join fJoin; 65 const char* fName; 66 }; 67 static const CapAndName gCaps[] = { 68 {SkPaint::kButt_Cap, SkPaint::kBevel_Join, "Butt"}, 69 {SkPaint::kRound_Cap, SkPaint::kRound_Join, "Round"}, 70 {SkPaint::kSquare_Cap, SkPaint::kBevel_Join, "Square"} 71 }; 72 struct PathAndName { 73 SkPath fPath; 74 const char* fName; 75 }; 76 PathAndName path; 77 path.fPath.moveTo(25*SK_Scalar1, 15*SK_Scalar1); 78 path.fPath.lineTo(75*SK_Scalar1, 15*SK_Scalar1); 79 path.fName = "moveTo-line"; 80 81 SkPaint titlePaint; 82 titlePaint.setColor(SK_ColorBLACK); 83 titlePaint.setAntiAlias(true); 84 titlePaint.setLCDRenderText(true); 85 titlePaint.setTextSize(15 * SK_Scalar1); 86 const char title[] = "Line Drawn Into Rectangle Clips With " 87 "Indicated Style, Fill and Linecaps, with stroke width 10"; 88 canvas->drawText(title, strlen(title), 89 20 * SK_Scalar1, 90 20 * SK_Scalar1, 91 titlePaint); 92 93 SkLCGRandom rand; 94 SkRect rect = SkRect::MakeWH(100*SK_Scalar1, 30*SK_Scalar1); 95 canvas->save(); 96 canvas->translate(10 * SK_Scalar1, 30 * SK_Scalar1); 97 canvas->save(); 98 for (size_t cap = 0; cap < SK_ARRAY_COUNT(gCaps); ++cap) { 99 if (0 < cap) { 100 canvas->translate((rect.width() + 40 * SK_Scalar1) * SK_ARRAY_COUNT(gStyles), 0); 101 } 102 canvas->save(); 103 for (size_t fill = 0; fill < SK_ARRAY_COUNT(gFills); ++fill) { 104 if (0 < fill) { 105 canvas->translate(0, rect.height() + 40 * SK_Scalar1); 106 } 107 canvas->save(); 108 for (size_t style = 0; style < SK_ARRAY_COUNT(gStyles); ++style) { 109 if (0 < style) { 110 canvas->translate(rect.width() + 40 * SK_Scalar1, 0); 111 } 112 113 SkColor color = 0xff007000; 114 this->drawPath(path.fPath, canvas, color, rect, 115 gCaps[cap].fCap, gCaps[cap].fJoin, gStyles[style].fStyle, 116 gFills[fill].fFill, SK_Scalar1*10); 117 118 SkPaint rectPaint; 119 rectPaint.setColor(SK_ColorBLACK); 120 rectPaint.setStyle(SkPaint::kStroke_Style); 121 rectPaint.setStrokeWidth(-1); 122 rectPaint.setAntiAlias(true); 123 canvas->drawRect(rect, rectPaint); 124 125 SkPaint labelPaint; 126 labelPaint.setColor(color); 127 labelPaint.setAntiAlias(true); 128 labelPaint.setLCDRenderText(true); 129 labelPaint.setTextSize(10 * SK_Scalar1); 130 canvas->drawText(gStyles[style].fName, 131 strlen(gStyles[style].fName), 132 0, rect.height() + 12 * SK_Scalar1, 133 labelPaint); 134 canvas->drawText(gFills[fill].fName, 135 strlen(gFills[fill].fName), 136 0, rect.height() + 24 * SK_Scalar1, 137 labelPaint); 138 canvas->drawText(gCaps[cap].fName, 139 strlen(gCaps[cap].fName), 140 0, rect.height() + 36 * SK_Scalar1, 141 labelPaint); 142 } 143 canvas->restore(); 144 } 145 canvas->restore(); 146 } 147 canvas->restore(); 148 canvas->restore(); 149 } 150 151 private: 152 typedef GM INHERITED; 153 }; 154 155 class LineClosePathGM : public GM { 156 public: 157 LineClosePathGM() {} 158 159 protected: 160 SkString onShortName() { 161 return SkString("lineclosepath"); 162 } 163 164 SkISize onISize() { return make_isize(1240, 390); } 165 166 void drawPath(SkPath& path,SkCanvas* canvas,SkColor color, 167 const SkRect& clip,SkPaint::Cap cap, SkPaint::Join join, 168 SkPaint::Style style, SkPath::FillType fill, 169 SkScalar strokeWidth) { 170 path.setFillType(fill); 171 SkPaint paint; 172 paint.setStrokeCap(cap); 173 paint.setStrokeWidth(strokeWidth); 174 paint.setStrokeJoin(join); 175 paint.setColor(color); 176 paint.setStyle(style); 177 canvas->save(); 178 canvas->clipRect(clip); 179 canvas->drawPath(path, paint); 180 canvas->restore(); 181 } 182 183 virtual void onDraw(SkCanvas* canvas) { 184 struct FillAndName { 185 SkPath::FillType fFill; 186 const char* fName; 187 }; 188 static const FillAndName gFills[] = { 189 {SkPath::kWinding_FillType, "Winding"}, 190 {SkPath::kEvenOdd_FillType, "Even / Odd"}, 191 {SkPath::kInverseWinding_FillType, "Inverse Winding"}, 192 {SkPath::kInverseEvenOdd_FillType, "Inverse Even / Odd"}, 193 }; 194 struct StyleAndName { 195 SkPaint::Style fStyle; 196 const char* fName; 197 }; 198 static const StyleAndName gStyles[] = { 199 {SkPaint::kFill_Style, "Fill"}, 200 {SkPaint::kStroke_Style, "Stroke"}, 201 {SkPaint::kStrokeAndFill_Style, "Stroke And Fill"}, 202 }; 203 struct CapAndName { 204 SkPaint::Cap fCap; 205 SkPaint::Join fJoin; 206 const char* fName; 207 }; 208 static const CapAndName gCaps[] = { 209 {SkPaint::kButt_Cap, SkPaint::kBevel_Join, "Butt"}, 210 {SkPaint::kRound_Cap, SkPaint::kRound_Join, "Round"}, 211 {SkPaint::kSquare_Cap, SkPaint::kBevel_Join, "Square"} 212 }; 213 struct PathAndName { 214 SkPath fPath; 215 const char* fName; 216 }; 217 PathAndName path; 218 path.fPath.moveTo(25*SK_Scalar1, 15*SK_Scalar1); 219 path.fPath.lineTo(75*SK_Scalar1, 15*SK_Scalar1); 220 path.fPath.close(); 221 path.fName = "moveTo-line-close"; 222 223 SkPaint titlePaint; 224 titlePaint.setColor(SK_ColorBLACK); 225 titlePaint.setAntiAlias(true); 226 titlePaint.setLCDRenderText(true); 227 titlePaint.setTextSize(15 * SK_Scalar1); 228 const char title[] = "Line Closed Drawn Into Rectangle Clips With " 229 "Indicated Style, Fill and Linecaps, with stroke width 10"; 230 canvas->drawText(title, strlen(title), 231 20 * SK_Scalar1, 232 20 * SK_Scalar1, 233 titlePaint); 234 235 SkLCGRandom rand; 236 SkRect rect = SkRect::MakeWH(100*SK_Scalar1, 30*SK_Scalar1); 237 canvas->save(); 238 canvas->translate(10 * SK_Scalar1, 30 * SK_Scalar1); 239 canvas->save(); 240 for (size_t cap = 0; cap < SK_ARRAY_COUNT(gCaps); ++cap) { 241 if (0 < cap) { 242 canvas->translate((rect.width() + 40 * SK_Scalar1) * SK_ARRAY_COUNT(gStyles), 0); 243 } 244 canvas->save(); 245 for (size_t fill = 0; fill < SK_ARRAY_COUNT(gFills); ++fill) { 246 if (0 < fill) { 247 canvas->translate(0, rect.height() + 40 * SK_Scalar1); 248 } 249 canvas->save(); 250 for (size_t style = 0; style < SK_ARRAY_COUNT(gStyles); ++style) { 251 if (0 < style) { 252 canvas->translate(rect.width() + 40 * SK_Scalar1, 0); 253 } 254 255 SkColor color = 0xff007000; 256 this->drawPath(path.fPath, canvas, color, rect, 257 gCaps[cap].fCap, gCaps[cap].fJoin, gStyles[style].fStyle, 258 gFills[fill].fFill, SK_Scalar1*10); 259 260 SkPaint rectPaint; 261 rectPaint.setColor(SK_ColorBLACK); 262 rectPaint.setStyle(SkPaint::kStroke_Style); 263 rectPaint.setStrokeWidth(-1); 264 rectPaint.setAntiAlias(true); 265 canvas->drawRect(rect, rectPaint); 266 267 SkPaint labelPaint; 268 labelPaint.setColor(color); 269 labelPaint.setAntiAlias(true); 270 labelPaint.setLCDRenderText(true); 271 labelPaint.setTextSize(10 * SK_Scalar1); 272 canvas->drawText(gStyles[style].fName, 273 strlen(gStyles[style].fName), 274 0, rect.height() + 12 * SK_Scalar1, 275 labelPaint); 276 canvas->drawText(gFills[fill].fName, 277 strlen(gFills[fill].fName), 278 0, rect.height() + 24 * SK_Scalar1, 279 labelPaint); 280 canvas->drawText(gCaps[cap].fName, 281 strlen(gCaps[cap].fName), 282 0, rect.height() + 36 * SK_Scalar1, 283 labelPaint); 284 } 285 canvas->restore(); 286 } 287 canvas->restore(); 288 } 289 canvas->restore(); 290 canvas->restore(); 291 } 292 293 private: 294 typedef GM INHERITED; 295 }; 296 297 ////////////////////////////////////////////////////////////////////////////// 298 299 static GM* LinePathFactory(void*) { return new LinePathGM; } 300 static GMRegistry regLinePath(LinePathFactory); 301 302 static GM* LineClosePathFactory(void*) { return new LineClosePathGM; } 303 static GMRegistry regLineClosePath(LineClosePathFactory); 304 305 } 306