blob: c01a9a30e7fc5bf9516138a92fcb21f5483521db [file] [log] [blame]
bsalomon@google.com7239aab2011-03-02 15:35:28 +00001#include "SampleCode.h"
2#include "SkCanvas.h"
3#include "SkParsePath.h"
4#include "SkPath.h"
5#include "SkRandom.h"
6#include "SkView.h"
7
8static void scale_to_width(SkPath* path, SkScalar dstWidth) {
9 const SkRect& bounds = path->getBounds();
10 SkScalar scale = dstWidth / bounds.width();
11 SkMatrix matrix;
12
13 matrix.setScale(scale, scale);
14 path->transform(matrix);
15}
16
17static const struct {
18 SkPaint::Style fStyle;
19 SkPaint::Join fJoin;
20 int fStrokeWidth;
21} gRec[] = {
22 { SkPaint::kFill_Style, SkPaint::kMiter_Join, 0 },
23 { SkPaint::kStroke_Style, SkPaint::kMiter_Join, 0 },
24 { SkPaint::kStroke_Style, SkPaint::kMiter_Join, 10 },
25 { SkPaint::kStrokeAndFill_Style, SkPaint::kMiter_Join, 10 },
26};
27
28#define TEST_INVERSE 0
29
30class ComplexClipView : public SkView {
31 SkScalar fWidth;
32public:
33 ComplexClipView() {
34 }
35
36protected:
37 // overrides from SkEventSink
38 virtual bool onQuery(SkEvent* evt) {
39 if (SampleCode::TitleQ(*evt)) {
40 SampleCode::TitleR(evt, "ComplexClip");
41 return true;
42 }
43 return this->INHERITED::onQuery(evt);
44 }
45
46 void drawBG(SkCanvas* canvas) {
47 canvas->drawColor(SkColorSetRGB(0xA0,0xDD,0xA0));
48 }
49
50 virtual void onDraw(SkCanvas* canvas) {
51 SkPath path;
52 path.moveTo(SkIntToScalar(0), SkIntToScalar(50));
53 path.quadTo(SkIntToScalar(0), SkIntToScalar(0), SkIntToScalar(50), SkIntToScalar(0));
54 path.lineTo(SkIntToScalar(175), SkIntToScalar(0));
55 path.quadTo(SkIntToScalar(200), SkIntToScalar(0), SkIntToScalar(200), SkIntToScalar(25));
56 path.lineTo(SkIntToScalar(200), SkIntToScalar(150));
57 path.quadTo(SkIntToScalar(200), SkIntToScalar(200), SkIntToScalar(150), SkIntToScalar(200));
58 path.lineTo(SkIntToScalar(0), SkIntToScalar(200));
59 path.close();
60 path.moveTo(SkIntToScalar(50), SkIntToScalar(50));
61 path.lineTo(SkIntToScalar(150), SkIntToScalar(50));
62 path.lineTo(SkIntToScalar(150), SkIntToScalar(125));
63 path.quadTo(SkIntToScalar(150), SkIntToScalar(150), SkIntToScalar(125), SkIntToScalar(150));
64 path.lineTo(SkIntToScalar(50), SkIntToScalar(150));
65 path.close();
66 path.setFillType(SkPath::kEvenOdd_FillType);
67 SkColor pathColor = SK_ColorBLACK;
68 SkPaint pathPaint;
69 pathPaint.setAntiAlias(true);
70 pathPaint.setColor(pathColor);
71
72 SkPath clipA;
73 clipA.moveTo(SkIntToScalar(10), SkIntToScalar(20));
74 clipA.lineTo(SkIntToScalar(165), SkIntToScalar(22));
75 clipA.lineTo(SkIntToScalar(70), SkIntToScalar(105));
76 clipA.lineTo(SkIntToScalar(165), SkIntToScalar(177));
77 clipA.lineTo(SkIntToScalar(-5), SkIntToScalar(180));
78 clipA.close();
79 SkColor colorA = SK_ColorCYAN;
80
81 SkPath clipB;
82 clipB.moveTo(SkIntToScalar(40), SkIntToScalar(10));
83 clipB.lineTo(SkIntToScalar(190), SkIntToScalar(15));
84 clipB.lineTo(SkIntToScalar(195), SkIntToScalar(190));
85 clipB.lineTo(SkIntToScalar(40), SkIntToScalar(185));
86 clipB.lineTo(SkIntToScalar(155), SkIntToScalar(100));
87 clipB.close();
88 SkColor colorB = SK_ColorRED;
89
90 drawBG(canvas);
91 SkPaint paint;
92 paint.setAntiAlias(true);
93
94 paint.setStyle(SkPaint::kStroke_Style);
95 paint.setStrokeWidth(0);
96
97 canvas->translate(SkIntToScalar(10),SkIntToScalar(10));
98 canvas->drawPath(path, pathPaint);
99 paint.setColor(colorA);
100 canvas->drawPath(clipA, paint);
101 paint.setColor(colorB);
102 canvas->drawPath(clipB, paint);
103
104 static const struct {
105 SkRegion::Op fOp;
106 const char* fName;
107 } gOps[] = { //extra spaces in names for measureText
108 {SkRegion::kIntersect_Op, "Isect "},
109 {SkRegion::kDifference_Op, "Diff " },
110 {SkRegion::kUnion_Op, "Union "},
111 {SkRegion::kXOR_Op, "Xor " },
112 {SkRegion::kReverseDifference_Op, "RDiff "}
113 };
114
115 canvas->translate(0, SkIntToScalar(40));
116 canvas->scale(3 * SK_Scalar1 / 4, 3 * SK_Scalar1 / 4);
117 canvas->save();
118
119 int invALimit = TEST_INVERSE ? 1 : 2;
120 for (int invA = 0; invALimit < 2; ++invA) {
121 for (int op = 0; op < SK_ARRAY_COUNT(gOps); ++op) {
122 int idx = invA * SK_ARRAY_COUNT(gOps) + op;
123 if (!(idx % 3)) {
124 canvas->restore();
125 canvas->translate(0, SkIntToScalar(250));
126 canvas->save();
127 }
128 canvas->save();
129 // set clip
130 clipA.setFillType(invA ? SkPath::kInverseEvenOdd_FillType :
131 SkPath::kEvenOdd_FillType);
132 canvas->clipPath(clipA);
133 canvas->clipPath(clipB, gOps[op].fOp);
134
135 // draw path clipped
136 canvas->drawPath(path, pathPaint);
137 canvas->restore();
138
139 // draw path in hairline
140 paint.setColor(pathColor);
141 canvas->drawPath(path, paint);
142
143 // draw clips in hair line
144 paint.setColor(colorA);
145 canvas->drawPath(clipA, paint);
146 paint.setColor(colorB);
147 canvas->drawPath(clipB, paint);
148
149 paint.setTextSize(SkIntToScalar(20));
150
151 SkScalar txtX = SkIntToScalar(55);
152 paint.setColor(colorA);
153 const char* aTxt = invA ? "InverseA " : "A ";
154 canvas->drawText(aTxt, strlen(aTxt), txtX, SkIntToScalar(220), paint);
155 txtX += paint.measureText(aTxt, strlen(aTxt));
156 paint.setColor(SK_ColorBLACK);
157 canvas->drawText(gOps[op].fName, strlen(gOps[op].fName),
158 txtX, SkIntToScalar(220), paint);
159 txtX += paint.measureText(gOps[op].fName, strlen(gOps[op].fName));
160 paint.setColor(colorB);
161 canvas->drawText("B", 1, txtX, SkIntToScalar(220), paint);
162
163 canvas->translate(SkIntToScalar(250),0);
164 }
165 }
166 canvas->restore();
167 }
168
169 virtual SkView::Click* onFindClickHandler(SkScalar x, SkScalar y) {
170 this->inval(NULL);
171 return this->INHERITED::onFindClickHandler(x, y);
172 }
173private:
174 typedef SkView INHERITED;
175};
176
177//////////////////////////////////////////////////////////////////////////////
178
179static SkView* MyFactory() { return new ComplexClipView; }
180static SkViewRegister reg(MyFactory);
181