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