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 15static 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 32static 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 sk_tool_utils::set_portable_typeface(&titlePaint); 80 titlePaint.setTextSize(15 * SK_Scalar1); 81 const char titleNoClose[] = "Line Drawn Into Rectangle Clips With " 82 "Indicated Style, Fill and Linecaps, with stroke width 10"; 83 const char titleClose[] = "Line Closed Drawn Into Rectangle Clips With " 84 "Indicated Style, Fill and Linecaps, with stroke width 10"; 85 const char* title = doClose ? titleClose : titleNoClose; 86 canvas->drawString(title, 87 20 * SK_Scalar1, 88 20 * SK_Scalar1, 89 titlePaint); 90 91 SkRandom rand; 92 SkRect rect = SkRect::MakeWH(100*SK_Scalar1, 30*SK_Scalar1); 93 canvas->save(); 94 canvas->translate(10 * SK_Scalar1, 30 * SK_Scalar1); 95 canvas->save(); 96 for (size_t cap = 0; cap < SK_ARRAY_COUNT(gCaps); ++cap) { 97 if (0 < cap) { 98 canvas->translate((rect.width() + 40 * SK_Scalar1) * SK_ARRAY_COUNT(gStyles), 0); 99 } 100 canvas->save(); 101 for (size_t fill = 0; fill < SK_ARRAY_COUNT(gFills); ++fill) { 102 if (0 < fill) { 103 canvas->translate(0, rect.height() + 40 * SK_Scalar1); 104 } 105 canvas->save(); 106 for (size_t style = 0; style < SK_ARRAY_COUNT(gStyles); ++style) { 107 if (0 < style) { 108 canvas->translate(rect.width() + 40 * SK_Scalar1, 0); 109 } 110 111 SkColor color = sk_tool_utils::color_to_565(0xff007000); 112 drawPath(path.fPath, canvas, color, rect, 113 gCaps[cap].fCap, gCaps[cap].fJoin, gStyles[style].fStyle, 114 gFills[fill].fFill, SK_Scalar1*10); 115 116 SkPaint rectPaint; 117 rectPaint.setColor(SK_ColorBLACK); 118 rectPaint.setStyle(SkPaint::kStroke_Style); 119 rectPaint.setStrokeWidth(-1); 120 rectPaint.setAntiAlias(true); 121 canvas->drawRect(rect, rectPaint); 122 123 SkPaint labelPaint; 124 labelPaint.setColor(color); 125 labelPaint.setAntiAlias(true); 126 sk_tool_utils::set_portable_typeface(&labelPaint); 127 labelPaint.setTextSize(10 * SK_Scalar1); 128 canvas->drawString(gStyles[style].fName, 129 0, rect.height() + 12 * SK_Scalar1, 130 labelPaint); 131 canvas->drawString(gFills[fill].fName, 132 0, rect.height() + 24 * SK_Scalar1, 133 labelPaint); 134 canvas->drawString(gCaps[cap].fName, 135 0, rect.height() + 36 * SK_Scalar1, 136 labelPaint); 137 } 138 canvas->restore(); 139 } 140 canvas->restore(); 141 } 142 canvas->restore(); 143 canvas->restore(); 144} 145DEF_SIMPLE_GM(linepath, canvas, 1240, 390) { 146 draw(canvas, false); 147} 148DEF_SIMPLE_GM(lineclosepath, canvas, 1240, 390) { 149 draw(canvas, true); 150} 151