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