• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright 2014 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 "gm/gm.h"
9 #include "include/core/SkCanvas.h"
10 #include "include/core/SkClipOp.h"
11 #include "include/core/SkColor.h"
12 #include "include/core/SkFont.h"
13 #include "include/core/SkPaint.h"
14 #include "include/core/SkPath.h"
15 #include "include/core/SkRect.h"
16 #include "include/core/SkScalar.h"
17 #include "include/core/SkSize.h"
18 #include "include/core/SkString.h"
19 #include "include/core/SkTypeface.h"
20 #include "include/core/SkTypes.h"
21 #include "src/core/SkClipOpPriv.h"
22 #include "tools/ToolUtils.h"
23 
24 #include <utility>
25 
26 namespace skiagm {
27 
28 constexpr SkColor gPathColor = SK_ColorYELLOW;
29 
30 class ComplexClip3GM : public GM {
31 public:
ComplexClip3GM(bool doSimpleClipFirst)32     ComplexClip3GM(bool doSimpleClipFirst)
33         : fDoSimpleClipFirst(doSimpleClipFirst) {
34         this->setBGColor(0xFFDDDDDD);
35     }
36 
37 protected:
38 
onShortName()39     SkString onShortName() {
40         SkString str;
41         str.printf("complexclip3_%s", fDoSimpleClipFirst ? "simple" : "complex");
42         return str;
43     }
44 
onISize()45     SkISize onISize() { return SkISize::Make(1000, 950); }
46 
onDraw(SkCanvas * canvas)47     virtual void onDraw(SkCanvas* canvas) {
48         SkPath clipSimple;
49         clipSimple.addCircle(SkIntToScalar(70), SkIntToScalar(50), SkIntToScalar(20));
50 
51         SkRect r1 = { 10, 20, 70, 80 };
52         SkPath clipComplex;
53         clipComplex.moveTo(SkIntToScalar(40),  SkIntToScalar(50));
54         clipComplex.arcTo(r1, SkIntToScalar(30), SkIntToScalar(300), false);
55         clipComplex.close();
56 
57         SkPath* firstClip = &clipSimple;
58         SkPath* secondClip = &clipComplex;
59 
60         if (!fDoSimpleClipFirst) {
61             using std::swap;
62             swap(firstClip, secondClip);
63         }
64 
65         SkPaint paint;
66         paint.setAntiAlias(true);
67 
68         SkFont font(ToolUtils::create_portable_typeface(), 20);
69 
70         constexpr struct {
71             SkClipOp    fOp;
72             const char* fName;
73         } gOps[] = {
74             {kIntersect_SkClipOp,         "I"},
75             {kDifference_SkClipOp,        "D" },
76             {kUnion_SkClipOp,             "U"},
77             {kXOR_SkClipOp,               "X"  },
78             {kReverseDifference_SkClipOp, "R"}
79         };
80 
81         canvas->translate(SkIntToScalar(20), SkIntToScalar(20));
82         canvas->scale(3 * SK_Scalar1 / 4, 3 * SK_Scalar1 / 4);
83 
84         SkPaint pathPaint;
85         pathPaint.setAntiAlias(true);
86         pathPaint.setColor(gPathColor);
87 
88         for (int invA = 0; invA < 2; ++invA) {
89             for (int aaBits = 0; aaBits < 4; ++aaBits) {
90                 canvas->save();
91                 for (size_t op = 0; op < SK_ARRAY_COUNT(gOps); ++op) {
92                     for (int invB = 0; invB < 2; ++invB) {
93                         bool doAAA = SkToBool(aaBits & 1);
94                         bool doAAB = SkToBool(aaBits & 2);
95                         bool doInvA = SkToBool(invA);
96                         bool doInvB = SkToBool(invB);
97                         canvas->save();
98                         // set clip
99                         firstClip->setFillType(doInvA ? SkPath::kInverseEvenOdd_FillType :
100                                                SkPath::kEvenOdd_FillType);
101                         secondClip->setFillType(doInvB ? SkPath::kInverseEvenOdd_FillType :
102                                                 SkPath::kEvenOdd_FillType);
103                         canvas->clipPath(*firstClip, doAAA);
104                         canvas->clipPath(*secondClip, gOps[op].fOp, doAAB);
105 
106                         // draw rect clipped
107                         SkRect r = { 0, 0, 100, 100 };
108                         canvas->drawRect(r, pathPaint);
109                         canvas->restore();
110 
111 
112                         SkScalar txtX = SkIntToScalar(10);
113                         paint.setColor(SK_ColorBLACK);
114                         SkString str;
115                         str.printf("%s%s %s %s%s", doAAA ? "A" : "B",
116                                                    doInvA ? "I" : "N",
117                                                    gOps[op].fName,
118                                                    doAAB ? "A" : "B",
119                                                    doInvB ? "I" : "N");
120 
121                         canvas->drawString(str.c_str(), txtX, SkIntToScalar(130), font, paint);
122                         if (doInvB) {
123                             canvas->translate(SkIntToScalar(150),0);
124                         } else {
125                             canvas->translate(SkIntToScalar(120),0);
126                         }
127                     }
128                 }
129                 canvas->restore();
130                 canvas->translate(0, SkIntToScalar(150));
131             }
132         }
133     }
134 
135 private:
136     bool fDoSimpleClipFirst;
137 
138     typedef GM INHERITED;
139 };
140 
141 //////////////////////////////////////////////////////////////////////////////
142 
143 // Simple clip first
144 DEF_GM( return new ComplexClip3GM(true); )
145 // Complex clip first
146 DEF_GM( return new ComplexClip3GM(false); )
147 }
148