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 
13 class ComplexClipView : public SampleView {
14 public:
ComplexClipView()15     ComplexClipView() {
16         this->setBGColor(0xFFA0DDA0);
17     }
18 
19 protected:
20     // overrides from SkEventSink
onQuery(SkEvent * evt)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 
onDrawContent(SkCanvas * canvas)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 
146 private:
147     typedef SampleView INHERITED;
148 };
149 
150 //////////////////////////////////////////////////////////////////////////////
151 
MyFactory()152 static SkView* MyFactory() { return new ComplexClipView; }
153 static SkViewRegister reg(MyFactory);
154