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