1 /*
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 
8 #include "include/core/SkCanvas.h"
9 #include "include/core/SkFont.h"
10 #include "include/core/SkPath.h"
11 #include "samplecode/Sample.h"
12 #include "src/core/SkClipOpPriv.h"
13 
14 class ComplexClipView : public Sample {
onOnceBeforeDraw()15     void onOnceBeforeDraw() override {
16         this->setBGColor(0xFFA0DDA0);
17     }
18 
name()19     SkString name() override { return SkString("ComplexClip"); }
20 
onDrawContent(SkCanvas * canvas)21     void onDrawContent(SkCanvas* canvas) override {
22         SkPath path;
23         path.moveTo(SkIntToScalar(0),   SkIntToScalar(50));
24         path.quadTo(SkIntToScalar(0),   SkIntToScalar(0),   SkIntToScalar(50),  SkIntToScalar(0));
25         path.lineTo(SkIntToScalar(175), SkIntToScalar(0));
26         path.quadTo(SkIntToScalar(200), SkIntToScalar(0),   SkIntToScalar(200), SkIntToScalar(25));
27         path.lineTo(SkIntToScalar(200), SkIntToScalar(150));
28         path.quadTo(SkIntToScalar(200), SkIntToScalar(200), SkIntToScalar(150), SkIntToScalar(200));
29         path.lineTo(SkIntToScalar(0),   SkIntToScalar(200));
30         path.close();
31         path.moveTo(SkIntToScalar(50),  SkIntToScalar(50));
32         path.lineTo(SkIntToScalar(150), SkIntToScalar(50));
33         path.lineTo(SkIntToScalar(150), SkIntToScalar(125));
34         path.quadTo(SkIntToScalar(150), SkIntToScalar(150), SkIntToScalar(125), SkIntToScalar(150));
35         path.lineTo(SkIntToScalar(50),  SkIntToScalar(150));
36         path.close();
37         path.setFillType(SkPathFillType::kEvenOdd);
38         SkColor pathColor = SK_ColorBLACK;
39         SkPaint pathPaint;
40         pathPaint.setAntiAlias(true);
41         pathPaint.setColor(pathColor);
42 
43         SkPath clipA;
44         clipA.moveTo(SkIntToScalar(10),  SkIntToScalar(20));
45         clipA.lineTo(SkIntToScalar(165), SkIntToScalar(22));
46         clipA.lineTo(SkIntToScalar(70),  SkIntToScalar(105));
47         clipA.lineTo(SkIntToScalar(165), SkIntToScalar(177));
48         clipA.lineTo(SkIntToScalar(-5),  SkIntToScalar(180));
49         clipA.close();
50         SkColor colorA = SK_ColorCYAN;
51 
52         SkPath clipB;
53         clipB.moveTo(SkIntToScalar(40),  SkIntToScalar(10));
54         clipB.lineTo(SkIntToScalar(190), SkIntToScalar(15));
55         clipB.lineTo(SkIntToScalar(195), SkIntToScalar(190));
56         clipB.lineTo(SkIntToScalar(40),  SkIntToScalar(185));
57         clipB.lineTo(SkIntToScalar(155), SkIntToScalar(100));
58         clipB.close();
59         SkColor colorB = SK_ColorRED;
60 
61         SkFont font;
62         font.setSize(20);
63 
64         SkPaint paint;
65         paint.setAntiAlias(true);
66 
67         paint.setStyle(SkPaint::kStroke_Style);
68         paint.setStrokeWidth(0);
69 
70         canvas->translate(SkIntToScalar(10),SkIntToScalar(10));
71         canvas->drawPath(path, pathPaint);
72         paint.setColor(colorA);
73         canvas->drawPath(clipA, paint);
74         paint.setColor(colorB);
75         canvas->drawPath(clipB, paint);
76 
77         static const struct {
78             SkClipOp    fOp;
79             const char* fName;
80         } gOps[] = { //extra spaces in names for measureText
81             {kIntersect_SkClipOp,         "Isect "},
82             {kDifference_SkClipOp,        "Diff " },
83             {kUnion_SkClipOp,             "Union "},
84             {kXOR_SkClipOp,               "Xor "  },
85             {kReverseDifference_SkClipOp, "RDiff "}
86         };
87 
88         canvas->translate(0, SkIntToScalar(40));
89         canvas->scale(3 * SK_Scalar1 / 4, 3 * SK_Scalar1 / 4);
90         canvas->save();
91 
92         for (int invA = 0; invA < 2; ++invA) {
93             for (size_t op = 0; op < SK_ARRAY_COUNT(gOps); ++op) {
94                 size_t idx = invA * SK_ARRAY_COUNT(gOps) + op;
95                 if (!(idx % 3)) {
96                     canvas->restore();
97                     canvas->translate(0, SkIntToScalar(250));
98                     canvas->save();
99                 }
100                 canvas->save();
101                     // set clip
102                     clipA.setFillType(invA ? SkPathFillType::kInverseEvenOdd :
103                                              SkPathFillType::kEvenOdd);
104                     canvas->clipPath(clipA);
105                     canvas->clipPath(clipB, gOps[op].fOp);
106 
107                     // draw path clipped
108                     canvas->drawPath(path, pathPaint);
109                 canvas->restore();
110 
111                 // draw path in hairline
112                 paint.setColor(pathColor);
113                 canvas->drawPath(path, paint);
114 
115                 // draw clips in hair line
116                 paint.setColor(colorA);
117                 canvas->drawPath(clipA, paint);
118                 paint.setColor(colorB);
119                 canvas->drawPath(clipB, paint);
120 
121                 SkScalar txtX = SkIntToScalar(55);
122                 paint.setColor(colorA);
123                 const char* aTxt = invA ? "InverseA " : "A ";
124                 canvas->drawSimpleText(aTxt, strlen(aTxt), SkTextEncoding::kUTF8, txtX, SkIntToScalar(220), font, paint);
125                 txtX += font.measureText(aTxt, strlen(aTxt), SkTextEncoding::kUTF8);
126                 paint.setColor(SK_ColorBLACK);
127                 canvas->drawSimpleText(gOps[op].fName, strlen(gOps[op].fName), SkTextEncoding::kUTF8,
128                                     txtX, 220, font, paint);
129                 txtX += font.measureText(gOps[op].fName, strlen(gOps[op].fName), SkTextEncoding::kUTF8);
130                 paint.setColor(colorB);
131                 canvas->drawSimpleText("B", 1, SkTextEncoding::kUTF8, txtX, 220, font, paint);
132 
133                 canvas->translate(SkIntToScalar(250),0);
134             }
135         }
136         canvas->restore();
137     }
138 };
139 
140 DEF_SAMPLE( return new ComplexClipView(); )
141