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