blob: 2a3392012878c35dd784a7ec25d2efb341f3995a [file] [log] [blame]
schenney@chromium.org4da06ab2011-12-20 15:14:18 +00001/*
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#include "gm.h"
8#include "SkCanvas.h"
9#include "SkPaint.h"
10#include "SkRandom.h"
11
12namespace skiagm {
13
14class LinePathsGM : public GM {
15public:
16 LinePathsGM() {}
17
18protected:
19 SkString onShortName() {
20 return SkString("linepaths");
21 }
22
23 SkISize onISize() { return make_isize(1800, 1110); }
24
25 void drawPath(SkPath& path,SkCanvas* canvas,SkColor color,
26 const SkRect& clip,SkPaint::Cap cap,
27 SkPaint::Style style, SkPath::FillType fill,
28 SkScalar strokeWidth) {
29 path.setFillType(fill);
30 SkPaint paint;
31 paint.setStrokeCap(cap);
32 paint.setStrokeWidth(strokeWidth);
33 paint.setColor(color);
34 paint.setStyle(style);
35 canvas->save();
36 canvas->clipRect(clip);
37 canvas->drawPath(path, paint);
38 canvas->restore();
39 }
40
41 virtual void onDraw(SkCanvas* canvas) {
42 struct FillAndName {
43 SkPath::FillType fFill;
44 const char* fName;
45 };
46 static const FillAndName gFills[] = {
47 {SkPath::kWinding_FillType, "Winding"},
48 {SkPath::kEvenOdd_FillType, "Even / Odd"},
49 {SkPath::kInverseWinding_FillType, "Inverse Winding"},
50 {SkPath::kInverseEvenOdd_FillType, "Inverse Even / Odd"},
51 };
52 struct StyleAndName {
53 SkPaint::Style fStyle;
54 const char* fName;
55 };
56 static const StyleAndName gStyles[] = {
57 {SkPaint::kFill_Style, "Fill"},
58 {SkPaint::kStroke_Style, "Stroke"},
59 {SkPaint::kStrokeAndFill_Style, "Stroke And Fill"},
60 };
61 struct CapAndName {
62 SkPaint::Cap fCap;
63 const char* fName;
64 };
65 static const CapAndName gCaps[] = {
66 {SkPaint::kButt_Cap, "Butt"},
67 {SkPaint::kRound_Cap, "Round"},
68 {SkPaint::kSquare_Cap, "Square"},
69 };
70 struct PathAndName {
71 SkPath fPath;
72 const char* fName;
73 };
74 PathAndName gPaths[4];
75 gPaths[0].fPath.moveTo(50*SK_Scalar1, 15*SK_Scalar1);
76 gPaths[0].fPath.lineTo(50*SK_Scalar1, 15*SK_Scalar1);
77 gPaths[0].fName = "moveTo-zeroline";
78 gPaths[1].fPath.moveTo(50*SK_Scalar1, 15*SK_Scalar1);
79 gPaths[1].fPath.lineTo(50*SK_Scalar1, 15*SK_Scalar1);
80 gPaths[1].fPath.close();
81 gPaths[1].fName = "moveTo-zeroline-close";
82 gPaths[2].fPath.moveTo(30*SK_Scalar1, 15*SK_Scalar1);
83 gPaths[2].fPath.lineTo(70*SK_Scalar1, 15*SK_Scalar1);
84 gPaths[2].fName = "moveTo-line";
85 gPaths[3].fPath.moveTo(30*SK_Scalar1, 15*SK_Scalar1);
86 gPaths[3].fPath.lineTo(70*SK_Scalar1, 15*SK_Scalar1);
87 gPaths[3].fPath.close();
88 gPaths[3].fName = "moveTo-line-close";
89
90 SkPaint titlePaint;
91 titlePaint.setColor(SK_ColorBLACK);
92 titlePaint.setAntiAlias(true);
93 titlePaint.setLCDRenderText(true);
94 titlePaint.setTextSize(15 * SK_Scalar1);
95 const char title[] = "Line Paths Drawn Into Rectangle Clips With "
96 "Indicated Style, Fill and Linecaps, "
97 "with random stroke widths";
98 canvas->drawText(title, strlen(title),
99 20 * SK_Scalar1,
100 20 * SK_Scalar1,
101 titlePaint);
102
103 SkRandom rand;
104 SkRect rect = SkRect::MakeWH(100*SK_Scalar1, 30*SK_Scalar1);
105 canvas->save();
106 canvas->translate(10 * SK_Scalar1, 30 * SK_Scalar1);
107 canvas->save();
108 for (size_t path = 0; path < SK_ARRAY_COUNT(gPaths); ++path) {
109 if (0 < path) {
110 canvas->translate(0, (rect.height() + 60 * SK_Scalar1) * 3);
111 }
112 canvas->save();
113 for (size_t cap = 0; cap < SK_ARRAY_COUNT(gCaps); ++cap) {
114 if (0 < cap) {
115 canvas->translate((rect.width() + 40 * SK_Scalar1) * 4, 0);
116 }
117 canvas->save();
118 for (size_t style = 0; style < SK_ARRAY_COUNT(gStyles); ++style) {
119 if (0 < style) {
120 canvas->translate(0, rect.height() + 60 * SK_Scalar1);
121 }
122 canvas->save();
123 for (size_t fill = 0; fill < SK_ARRAY_COUNT(gFills); ++fill) {
124 if (0 < fill) {
125 canvas->translate(rect.width() + 40 * SK_Scalar1, 0);
126 }
127
128 SkColor color = 0xff007000;
129 this->drawPath(gPaths[path].fPath, canvas, color, rect,
130 gCaps[cap].fCap, gStyles[style].fStyle,
131 gFills[fill].fFill, SK_Scalar1*10);
132
133 SkPaint rectPaint;
134 rectPaint.setColor(SK_ColorBLACK);
135 rectPaint.setStyle(SkPaint::kStroke_Style);
136 rectPaint.setStrokeWidth(-1);
137 rectPaint.setAntiAlias(true);
138 canvas->drawRect(rect, rectPaint);
139
140 SkPaint labelPaint;
141 labelPaint.setColor(color);
142 labelPaint.setAntiAlias(true);
143 labelPaint.setLCDRenderText(true);
144 labelPaint.setTextSize(10 * SK_Scalar1);
145 canvas->drawText(gStyles[style].fName,
146 strlen(gStyles[style].fName),
147 0, rect.height() + 12 * SK_Scalar1,
148 labelPaint);
149 canvas->drawText(gFills[fill].fName,
150 strlen(gFills[fill].fName),
151 0, rect.height() + 24 * SK_Scalar1,
152 labelPaint);
153 canvas->drawText(gCaps[cap].fName,
154 strlen(gCaps[cap].fName),
155 0, rect.height() + 36 * SK_Scalar1,
156 labelPaint);
157 canvas->drawText(gPaths[path].fName,
158 strlen(gPaths[path].fName),
159 0, rect.height() + 48 * SK_Scalar1,
160 labelPaint);
161 }
162 canvas->restore();
163 }
164 canvas->restore();
165 }
166 canvas->restore();
167 }
168 canvas->restore();
169 canvas->restore();
170 }
171
172private:
173 typedef GM INHERITED;
174};
175
176//////////////////////////////////////////////////////////////////////////////
177
178static GM* MyFactory(void*) { return new LinePathsGM; }
179static GMRegistry reg(MyFactory);
180
181}