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
9 #include "gm.h"
10 #include "SkCanvas.h"
11 #include "SkPath.h"
12 #include "SkRandom.h"
13
14 namespace skiagm {
15
16 class ComplexClip2GM : public GM {
17 public:
ComplexClip2GM(bool doPaths,bool antiAlias)18 ComplexClip2GM(bool doPaths, bool antiAlias)
19 : fDoPaths(doPaths)
20 , fAntiAlias(antiAlias) {
21 this->setBGColor(SkColorSetRGB(0xDD,0xA0,0xDD));
22
23 // offset the rects a bit so we get antialiasing even in the rect case
24 SkScalar xA = SkFloatToScalar(0.65f);
25 SkScalar xB = SkFloatToScalar(10.65f);
26 SkScalar xC = SkFloatToScalar(20.65f);
27 SkScalar xD = SkFloatToScalar(30.65f);
28 SkScalar xE = SkFloatToScalar(40.65f);
29 SkScalar xF = SkFloatToScalar(50.65f);
30
31 SkScalar yA = SkFloatToScalar(0.65f);
32 SkScalar yB = SkFloatToScalar(10.65f);
33 SkScalar yC = SkFloatToScalar(20.65f);
34 SkScalar yD = SkFloatToScalar(30.65f);
35 SkScalar yE = SkFloatToScalar(40.65f);
36 SkScalar yF = SkFloatToScalar(50.65f);
37
38 fWidth = xF - xA;
39 fHeight = yF - yA;
40
41 fRects[0].set(xB, yB, xE, yE);
42 fPaths[0].addRoundRect(fRects[0], SkIntToScalar(5), SkIntToScalar(5));
43 fRectColors[0] = SK_ColorRED;
44
45 fRects[1].set(xA, yA, xD, yD);
46 fPaths[1].addRoundRect(fRects[1], SkIntToScalar(5), SkIntToScalar(5));
47 fRectColors[1] = SK_ColorGREEN;
48
49 fRects[2].set(xC, yA, xF, yD);
50 fPaths[2].addRoundRect(fRects[2], SkIntToScalar(5), SkIntToScalar(5));
51 fRectColors[2] = SK_ColorBLUE;
52
53 fRects[3].set(xA, yC, xD, yF);
54 fPaths[3].addRoundRect(fRects[3], SkIntToScalar(5), SkIntToScalar(5));
55 fRectColors[3] = SK_ColorYELLOW;
56
57 fRects[4].set(xC, yC, xF, yF);
58 fPaths[4].addRoundRect(fRects[4], SkIntToScalar(5), SkIntToScalar(5));
59 fRectColors[4] = SK_ColorCYAN;
60
61 fTotalWidth = kCols * fWidth + SK_Scalar1 * (kCols + 1) * kPadX;
62 fTotalHeight = kRows * fHeight + SK_Scalar1 * (kRows + 1) * kPadY;
63
64 SkRegion::Op ops[] = {
65 SkRegion::kDifference_Op,
66 SkRegion::kIntersect_Op,
67 SkRegion::kUnion_Op,
68 SkRegion::kXOR_Op,
69 SkRegion::kReverseDifference_Op,
70 SkRegion::kReplace_Op,
71 };
72
73 SkRandom r;
74 for (int i = 0; i < kRows; ++i) {
75 for (int j = 0; j < kCols; ++j) {
76 for (int k = 0; k < 5; ++k) {
77 fOps[j*kRows+i][k] = ops[r.nextU() % SK_ARRAY_COUNT(ops)];
78 }
79 }
80 }
81 }
82
83 protected:
84
85 static const int kRows = 5;
86 static const int kCols = 5;
87 static const int kPadX = 20;
88 static const int kPadY = 20;
89
onShortName()90 virtual SkString onShortName() {
91 if (!fDoPaths && !fAntiAlias) {
92 return SkString("complexclip2");
93 }
94
95 SkString str;
96 str.printf("complexclip2_%s_%s",
97 fDoPaths ? "path" : "rect",
98 fAntiAlias ? "aa" : "bw");
99 return str;
100 }
101
onISize()102 virtual SkISize onISize() {
103 return make_isize(SkScalarRoundToInt(fTotalWidth),
104 SkScalarRoundToInt(fTotalHeight));
105 }
106
onDraw(SkCanvas * canvas)107 virtual void onDraw(SkCanvas* canvas) {
108 SkPaint rectPaint;
109 rectPaint.setStyle(SkPaint::kStroke_Style);
110 rectPaint.setStrokeWidth(-1);
111
112 SkPaint fillPaint;
113 fillPaint.setColor(SkColorSetRGB(0xA0,0xDD,0xA0));
114
115 for (int i = 0; i < kRows; ++i) {
116 for (int j = 0; j < kCols; ++j) {
117 canvas->save();
118
119 canvas->translate(kPadX * SK_Scalar1 + (fWidth + kPadX * SK_Scalar1)*j,
120 kPadY * SK_Scalar1 + (fHeight + kPadY * SK_Scalar1)*i);
121
122 // draw the original shapes first so we can see the
123 // antialiasing on the clipped draw
124 for (int k = 0; k < 5; ++k) {
125 rectPaint.setColor(fRectColors[k]);
126 if (fDoPaths) {
127 canvas->drawPath(fPaths[k], rectPaint);
128 } else {
129 canvas->drawRect(fRects[k], rectPaint);
130 }
131 }
132
133 for (int k = 0; k < 5; ++k) {
134 if (fDoPaths) {
135 canvas->clipPath(fPaths[k],
136 fOps[j*kRows+i][k],
137 fAntiAlias);
138 } else {
139 canvas->clipRect(fRects[k],
140 fOps[j*kRows+i][k],
141 fAntiAlias);
142 }
143 }
144 canvas->drawRect(SkRect::MakeWH(fWidth, fHeight), fillPaint);
145 canvas->restore();
146 }
147 }
148 }
149 private:
150 bool fDoPaths;
151 bool fAntiAlias;
152 SkRect fRects[5];
153 SkPath fPaths[5];
154 SkColor fRectColors[5];
155 SkRegion::Op fOps[kRows * kCols][5];
156 SkScalar fWidth;
157 SkScalar fHeight;
158 SkScalar fTotalWidth;
159 SkScalar fTotalHeight;
160
161 typedef GM INHERITED;
162 };
163
164 //////////////////////////////////////////////////////////////////////////////
165
166 // bw rects
MyFactory(void *)167 static GM* MyFactory(void*) { return new ComplexClip2GM(false, false); }
168 static GMRegistry reg(MyFactory);
169
170 // bw paths
MyFactory2(void *)171 static GM* MyFactory2(void*) { return new ComplexClip2GM(true, false); }
172 static GMRegistry reg2(MyFactory2);
173
174 // aa rects
MyFactory3(void *)175 static GM* MyFactory3(void*) { return new ComplexClip2GM(false, true); }
176 static GMRegistry reg3(MyFactory3);
177
178 // aa paths
MyFactory4(void *)179 static GM* MyFactory4(void*) { return new ComplexClip2GM(true, true); }
180 static GMRegistry reg4(MyFactory4);
181
182 }
183