1#include "SampleCode.h"
2#include "SkCanvas.h"
3#include "SkPath.h"
4#include "SkView.h"
5
6class ComplexClipView : public SampleView {
7public:
8	ComplexClipView() {
9        this->setBGColor(0xFFA0DDA0);
10    }
11
12protected:
13    // overrides from SkEventSink
14    virtual bool onQuery(SkEvent* evt) {
15        if (SampleCode::TitleQ(*evt)) {
16            SampleCode::TitleR(evt, "ComplexClip");
17            return true;
18        }
19        return this->INHERITED::onQuery(evt);
20    }
21
22    virtual void onDrawContent(SkCanvas* canvas) {
23        SkPath path;
24        path.moveTo(SkIntToScalar(0),   SkIntToScalar(50));
25        path.quadTo(SkIntToScalar(0),   SkIntToScalar(0),   SkIntToScalar(50),  SkIntToScalar(0));
26        path.lineTo(SkIntToScalar(175), SkIntToScalar(0));
27        path.quadTo(SkIntToScalar(200), SkIntToScalar(0),   SkIntToScalar(200), SkIntToScalar(25));
28        path.lineTo(SkIntToScalar(200), SkIntToScalar(150));
29        path.quadTo(SkIntToScalar(200), SkIntToScalar(200), SkIntToScalar(150), SkIntToScalar(200));
30        path.lineTo(SkIntToScalar(0),   SkIntToScalar(200));
31        path.close();
32        path.moveTo(SkIntToScalar(50),  SkIntToScalar(50));
33        path.lineTo(SkIntToScalar(150), SkIntToScalar(50));
34        path.lineTo(SkIntToScalar(150), SkIntToScalar(125));
35        path.quadTo(SkIntToScalar(150), SkIntToScalar(150), SkIntToScalar(125), SkIntToScalar(150));
36        path.lineTo(SkIntToScalar(50),  SkIntToScalar(150));
37        path.close();
38        path.setFillType(SkPath::kEvenOdd_FillType);
39        SkColor pathColor = SK_ColorBLACK;
40        SkPaint pathPaint;
41        pathPaint.setAntiAlias(true);
42        pathPaint.setColor(pathColor);
43
44        SkPath clipA;
45        clipA.moveTo(SkIntToScalar(10),  SkIntToScalar(20));
46        clipA.lineTo(SkIntToScalar(165), SkIntToScalar(22));
47        clipA.lineTo(SkIntToScalar(70),  SkIntToScalar(105));
48        clipA.lineTo(SkIntToScalar(165), SkIntToScalar(177));
49        clipA.lineTo(SkIntToScalar(-5),  SkIntToScalar(180));
50        clipA.close();
51        SkColor colorA = SK_ColorCYAN;
52
53        SkPath clipB;
54        clipB.moveTo(SkIntToScalar(40),  SkIntToScalar(10));
55        clipB.lineTo(SkIntToScalar(190), SkIntToScalar(15));
56        clipB.lineTo(SkIntToScalar(195), SkIntToScalar(190));
57        clipB.lineTo(SkIntToScalar(40),  SkIntToScalar(185));
58        clipB.lineTo(SkIntToScalar(155), SkIntToScalar(100));
59        clipB.close();
60        SkColor colorB = SK_ColorRED;
61
62        SkPaint paint;
63        paint.setAntiAlias(true);
64
65        paint.setStyle(SkPaint::kStroke_Style);
66        paint.setStrokeWidth(0);
67
68        canvas->translate(SkIntToScalar(10),SkIntToScalar(10));
69        canvas->drawPath(path, pathPaint);
70        paint.setColor(colorA);
71        canvas->drawPath(clipA, paint);
72        paint.setColor(colorB);
73        canvas->drawPath(clipB, paint);
74
75        static const struct {
76            SkRegion::Op fOp;
77            const char*  fName;
78        } gOps[] = { //extra spaces in names for measureText
79            {SkRegion::kIntersect_Op,         "Isect "},
80            {SkRegion::kDifference_Op,        "Diff " },
81            {SkRegion::kUnion_Op,             "Union "},
82            {SkRegion::kXOR_Op,               "Xor "  },
83            {SkRegion::kReverseDifference_Op, "RDiff "}
84        };
85
86        canvas->translate(0, SkIntToScalar(40));
87        canvas->scale(3 * SK_Scalar1 / 4, 3 * SK_Scalar1 / 4);
88        canvas->save();
89
90        for (int invA = 0; invA < 2; ++invA) {
91            for (size_t op = 0; op < SK_ARRAY_COUNT(gOps); ++op) {
92                int idx = invA * SK_ARRAY_COUNT(gOps) + op;
93                if (!(idx % 3)) {
94                    canvas->restore();
95                    canvas->translate(0, SkIntToScalar(250));
96                    canvas->save();
97                }
98                canvas->save();
99                    // set clip
100                    clipA.setFillType(invA ? SkPath::kInverseEvenOdd_FillType :
101                                             SkPath::kEvenOdd_FillType);
102                    canvas->clipPath(clipA);
103                    canvas->clipPath(clipB, gOps[op].fOp);
104
105                    // draw path clipped
106                    canvas->drawPath(path, pathPaint);
107                canvas->restore();
108
109                // draw path in hairline
110                paint.setColor(pathColor);
111                canvas->drawPath(path, paint);
112
113                // draw clips in hair line
114                paint.setColor(colorA);
115                canvas->drawPath(clipA, paint);
116                paint.setColor(colorB);
117                canvas->drawPath(clipB, paint);
118
119                paint.setTextSize(SkIntToScalar(20));
120
121                SkScalar txtX = SkIntToScalar(55);
122                paint.setColor(colorA);
123                const char* aTxt = invA ? "InverseA " : "A ";
124                canvas->drawText(aTxt, strlen(aTxt), txtX, SkIntToScalar(220), paint);
125                txtX += paint.measureText(aTxt, strlen(aTxt));
126                paint.setColor(SK_ColorBLACK);
127                canvas->drawText(gOps[op].fName, strlen(gOps[op].fName),
128                                    txtX, SkIntToScalar(220), paint);
129                txtX += paint.measureText(gOps[op].fName, strlen(gOps[op].fName));
130                paint.setColor(colorB);
131                canvas->drawText("B", 1, txtX, SkIntToScalar(220), paint);
132
133                canvas->translate(SkIntToScalar(250),0);
134            }
135        }
136        canvas->restore();
137    }
138
139private:
140    typedef SampleView INHERITED;
141};
142
143//////////////////////////////////////////////////////////////////////////////
144
145static SkView* MyFactory() { return new ComplexClipView; }
146static SkViewRegister reg(MyFactory);
147
148