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 "SkPath.h" 12 #include "SkPaint.h" 13 #include "SkRandom.h" 14 15 static void drawPath(SkPath& path,SkCanvas* canvas,SkColor color, 16 const SkRect& clip,SkPaint::Cap cap, SkPaint::Join join, 17 SkPaint::Style style, SkPath::FillType fill, 18 SkScalar strokeWidth) { 19 path.setFillType(fill); 20 SkPaint paint; 21 paint.setStrokeCap(cap); 22 paint.setStrokeWidth(strokeWidth); 23 paint.setStrokeJoin(join); 24 paint.setColor(color); 25 paint.setStyle(style); 26 canvas->save(); 27 canvas->clipRect(clip); 28 canvas->drawPath(path, paint); 29 canvas->restore(); 30 } 31 32 static void draw(SkCanvas* canvas, bool doClose) { 33 struct FillAndName { 34 SkPath::FillType fFill; 35 const char* fName; 36 }; 37 constexpr FillAndName gFills[] = { 38 {SkPath::kWinding_FillType, "Winding"}, 39 {SkPath::kEvenOdd_FillType, "Even / Odd"}, 40 {SkPath::kInverseWinding_FillType, "Inverse Winding"}, 41 {SkPath::kInverseEvenOdd_FillType, "Inverse Even / Odd"}, 42 }; 43 struct StyleAndName { 44 SkPaint::Style fStyle; 45 const char* fName; 46 }; 47 constexpr StyleAndName gStyles[] = { 48 {SkPaint::kFill_Style, "Fill"}, 49 {SkPaint::kStroke_Style, "Stroke"}, 50 {SkPaint::kStrokeAndFill_Style, "Stroke And Fill"}, 51 }; 52 struct CapAndName { 53 SkPaint::Cap fCap; 54 SkPaint::Join fJoin; 55 const char* fName; 56 }; 57 constexpr CapAndName gCaps[] = { 58 {SkPaint::kButt_Cap, SkPaint::kBevel_Join, "Butt"}, 59 {SkPaint::kRound_Cap, SkPaint::kRound_Join, "Round"}, 60 {SkPaint::kSquare_Cap, SkPaint::kBevel_Join, "Square"} 61 }; 62 struct PathAndName { 63 SkPath fPath; 64 const char* fName; 65 }; 66 PathAndName path; 67 path.fPath.moveTo(25*SK_Scalar1, 15*SK_Scalar1); 68 path.fPath.lineTo(75*SK_Scalar1, 15*SK_Scalar1); 69 if (doClose) { 70 path.fPath.close(); 71 path.fName = "moveTo-line-close"; 72 } else { 73 path.fName = "moveTo-line"; 74 } 75 76 SkPaint titlePaint; 77 titlePaint.setColor(SK_ColorBLACK); 78 titlePaint.setAntiAlias(true); 79 80 SkFont font(sk_tool_utils::create_portable_typeface(), 15.0f); 81 82 const char titleNoClose[] = "Line Drawn Into Rectangle Clips With " 83 "Indicated Style, Fill and Linecaps, with stroke width 10"; 84 const char titleClose[] = "Line Closed Drawn Into Rectangle Clips With " 85 "Indicated Style, Fill and Linecaps, with stroke width 10"; 86 const char* title = doClose ? titleClose : titleNoClose; 87 canvas->drawString(title, 20.0f, 20.0f, font, titlePaint); 88 89 SkRandom rand; 90 SkRect rect = SkRect::MakeWH(100*SK_Scalar1, 30*SK_Scalar1); 91 canvas->save(); 92 canvas->translate(10 * SK_Scalar1, 30 * SK_Scalar1); 93 canvas->save(); 94 for (size_t cap = 0; cap < SK_ARRAY_COUNT(gCaps); ++cap) { 95 if (0 < cap) { 96 canvas->translate((rect.width() + 40 * SK_Scalar1) * SK_ARRAY_COUNT(gStyles), 0); 97 } 98 canvas->save(); 99 for (size_t fill = 0; fill < SK_ARRAY_COUNT(gFills); ++fill) { 100 if (0 < fill) { 101 canvas->translate(0, rect.height() + 40 * SK_Scalar1); 102 } 103 canvas->save(); 104 for (size_t style = 0; style < SK_ARRAY_COUNT(gStyles); ++style) { 105 if (0 < style) { 106 canvas->translate(rect.width() + 40 * SK_Scalar1, 0); 107 } 108 109 SkColor color = sk_tool_utils::color_to_565(0xff007000); 110 drawPath(path.fPath, canvas, color, rect, 111 gCaps[cap].fCap, gCaps[cap].fJoin, gStyles[style].fStyle, 112 gFills[fill].fFill, SK_Scalar1*10); 113 114 SkPaint rectPaint; 115 rectPaint.setColor(SK_ColorBLACK); 116 rectPaint.setStyle(SkPaint::kStroke_Style); 117 rectPaint.setStrokeWidth(-1); 118 rectPaint.setAntiAlias(true); 119 canvas->drawRect(rect, rectPaint); 120 121 SkPaint labelPaint; 122 labelPaint.setColor(color); 123 font.setSize(10); 124 canvas->drawString(gStyles[style].fName, 0, rect.height() + 12.0f, 125 font, labelPaint); 126 canvas->drawString(gFills[fill].fName, 0, rect.height() + 24.0f, 127 font, labelPaint); 128 canvas->drawString(gCaps[cap].fName, 0, rect.height() + 36.0f, 129 font, labelPaint); 130 } 131 canvas->restore(); 132 } 133 canvas->restore(); 134 } 135 canvas->restore(); 136 canvas->restore(); 137 } 138 DEF_SIMPLE_GM(linepath, canvas, 1240, 390) { 139 draw(canvas, false); 140 } 141 DEF_SIMPLE_GM(lineclosepath, canvas, 1240, 390) { 142 draw(canvas, true); 143 } 144