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