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