blob: bae5c5a774dff59e989acf092168ec81d1ee0fe0 [file] [log] [blame]
egdanieldf795032014-12-17 11:22:37 -08001
2/*
3 * Copyright 2014 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 "gm.h"
9#include "SkCanvas.h"
10#include "SkPath.h"
11
12namespace skiagm {
13
14static const SkColor gPathColor = SK_ColorYELLOW;
15
16class ComplexClip3GM : public GM {
17public:
18 ComplexClip3GM(bool doSimpleClipFirst)
19 : fDoSimpleClipFirst(doSimpleClipFirst) {
20 this->setBGColor(0xFFDDDDDD);
21 }
22
23protected:
24 uint32_t onGetFlags() const SK_OVERRIDE {
bsalomon51d1f7e2014-12-22 08:40:49 -080025 return kSkipTiled_Flag;
egdanieldf795032014-12-17 11:22:37 -080026 }
27
28 SkString onShortName() {
29 SkString str;
30 str.printf("complexclip3_%s", fDoSimpleClipFirst ? "simple" : "complex");
31 return str;
32 }
33
34 SkISize onISize() { return SkISize::Make(1000, 950); }
35
36 virtual void onDraw(SkCanvas* canvas) {
37 SkPath clipSimple;
38 clipSimple.addCircle(SkIntToScalar(70), SkIntToScalar(50), SkIntToScalar(20));
39
40 SkRect r1 = { 10, 20, 70, 80 };
41 SkPath clipComplex;
42 clipComplex.moveTo(SkIntToScalar(40), SkIntToScalar(50));
43 clipComplex.arcTo(r1, SkIntToScalar(30), SkIntToScalar(300), false);
44 clipComplex.close();
45
46 SkPath* firstClip = &clipSimple;
47 SkPath* secondClip = &clipComplex;
48
49 if (!fDoSimpleClipFirst) {
50 SkTSwap<SkPath*>(firstClip, secondClip);
51 }
52
53 SkPaint paint;
54 paint.setAntiAlias(true);
55 sk_tool_utils::set_portable_typeface(&paint);
56 paint.setTextSize(SkIntToScalar(20));
57
58 static const struct {
59 SkRegion::Op fOp;
60 const char* fName;
61 } gOps[] = {
62 {SkRegion::kIntersect_Op, "I"},
63 {SkRegion::kDifference_Op, "D" },
64 {SkRegion::kUnion_Op, "U"},
65 {SkRegion::kXOR_Op, "X" },
66 {SkRegion::kReverseDifference_Op, "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, SkRegion::kIntersect_Op, 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->drawText(str.c_str(), strlen(str.c_str()), txtX, SkIntToScalar(130),
110 paint);
111 if (doInvB) {
112 canvas->translate(SkIntToScalar(150),0);
113 } else {
114 canvas->translate(SkIntToScalar(120),0);
115 }
116 }
117 }
118 canvas->restore();
119 canvas->translate(0, SkIntToScalar(150));
120 }
121 }
122 }
123
124private:
125 bool fDoSimpleClipFirst;
126
127 typedef GM INHERITED;
128};
129
130//////////////////////////////////////////////////////////////////////////////
131
132// Simple clip first
133DEF_GM( return new ComplexClip3GM(true); )
134// Complex clip first
135DEF_GM( return new ComplexClip3GM(false); )
136}