• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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:
18     enum Clip {
19         kRect_Clip,
20         kRRect_Clip,
21         kPath_Clip
22     };
23 
ComplexClip2GM(Clip clip,bool antiAlias)24     ComplexClip2GM(Clip clip, bool antiAlias)
25     : fClip(clip)
26     , fAntiAlias(antiAlias) {
27         this->setBGColor(SkColorSetRGB(0xDD,0xA0,0xDD));
28 
29         // offset the rects a bit so we get antialiasing even in the rect case
30         SkScalar xA = 0.65f;
31         SkScalar xB = 10.65f;
32         SkScalar xC = 20.65f;
33         SkScalar xD = 30.65f;
34         SkScalar xE = 40.65f;
35         SkScalar xF = 50.65f;
36 
37         SkScalar yA = 0.65f;
38         SkScalar yB = 10.65f;
39         SkScalar yC = 20.65f;
40         SkScalar yD = 30.65f;
41         SkScalar yE = 40.65f;
42         SkScalar yF = 50.65f;
43 
44         fWidth = xF - xA;
45         fHeight = yF - yA;
46 
47         fRects[0].set(xB, yB, xE, yE);
48         fRRects[0].setRectXY(fRects[0], 7, 7);
49         fPaths[0].addRoundRect(fRects[0], 5, 5);
50         fRectColors[0] = SK_ColorRED;
51 
52         fRects[1].set(xA, yA, xD, yD);
53         fRRects[1].setRectXY(fRects[1], 7, 7);
54         fPaths[1].addRoundRect(fRects[1], 5, 5);
55         fRectColors[1] = SK_ColorGREEN;
56 
57         fRects[2].set(xC, yA, xF, yD);
58         fRRects[2].setRectXY(fRects[2], 7, 7);
59         fPaths[2].addRoundRect(fRects[2], 5, 5);
60         fRectColors[2] = SK_ColorBLUE;
61 
62         fRects[3].set(xA, yC, xD, yF);
63         fRRects[3].setRectXY(fRects[3], 7, 7);
64         fPaths[3].addRoundRect(fRects[3], 5, 5);
65         fRectColors[3] = SK_ColorYELLOW;
66 
67         fRects[4].set(xC, yC, xF, yF);
68         fRRects[4].setRectXY(fRects[4], 7, 7);
69         fPaths[4].addRoundRect(fRects[4], 5, 5);
70         fRectColors[4] = SK_ColorCYAN;
71 
72         fTotalWidth = kCols * fWidth + SK_Scalar1 * (kCols + 1) * kPadX;
73         fTotalHeight = kRows * fHeight + SK_Scalar1 * (kRows + 1) * kPadY;
74 
75         SkRegion::Op ops[] = {
76             SkRegion::kDifference_Op,
77             SkRegion::kIntersect_Op,
78             SkRegion::kUnion_Op,
79             SkRegion::kXOR_Op,
80             SkRegion::kReverseDifference_Op,
81             SkRegion::kReplace_Op,
82         };
83 
84         SkLCGRandom r;
85         for (int i = 0; i < kRows; ++i) {
86             for (int j = 0; j < kCols; ++j) {
87                 for (int k = 0; k < 5; ++k) {
88                     fOps[j*kRows+i][k] = ops[r.nextU() % SK_ARRAY_COUNT(ops)];
89                 }
90             }
91         }
92     }
93 
94 protected:
95 
96     static const int kRows = 5;
97     static const int kCols = 5;
98     static const int kPadX = 20;
99     static const int kPadY = 20;
100 
ClipStr(Clip clip)101     static const char* ClipStr(Clip clip) {
102         switch (clip) {
103         case kRect_Clip:
104             return "rect";
105         case kRRect_Clip:
106             return "rrect";
107         case kPath_Clip:
108             return "path";
109         }
110         SkDEBUGFAIL("Unknown clip type.");
111         return "";
112     }
113 
onGetFlags() const114     virtual uint32_t onGetFlags() const SK_OVERRIDE {
115         if (kRect_Clip != fClip) {
116             return kSkipTiled_Flag;
117         }
118         return 0;
119     }
120 
onShortName()121     virtual SkString onShortName() {
122         if (kRect_Clip == fClip && !fAntiAlias) {
123             return SkString("complexclip2");
124         }
125 
126         SkString str;
127         str.printf("complexclip2_%s_%s",
128                     ClipStr(fClip),
129                     fAntiAlias ? "aa" : "bw");
130         return str;
131     }
132 
onISize()133     virtual SkISize onISize() {
134         return SkISize::Make(SkScalarRoundToInt(fTotalWidth),
135                              SkScalarRoundToInt(fTotalHeight));
136     }
137 
onDraw(SkCanvas * canvas)138     virtual void onDraw(SkCanvas* canvas) {
139         SkPaint rectPaint;
140         rectPaint.setStyle(SkPaint::kStroke_Style);
141         rectPaint.setStrokeWidth(-1);
142 
143         SkPaint fillPaint;
144         fillPaint.setColor(SkColorSetRGB(0xA0,0xDD,0xA0));
145 
146         for (int i = 0; i < kRows; ++i) {
147             for (int j = 0; j < kCols; ++j) {
148                 canvas->save();
149 
150                 canvas->translate(kPadX * SK_Scalar1 + (fWidth + kPadX * SK_Scalar1)*j,
151                                   kPadY * SK_Scalar1 + (fHeight + kPadY * SK_Scalar1)*i);
152 
153                 // draw the original shapes first so we can see the
154                 // antialiasing on the clipped draw
155                 for (int k = 0; k < 5; ++k) {
156                     rectPaint.setColor(fRectColors[k]);
157                     switch (fClip) {
158                         case kRect_Clip:
159                             canvas->drawRect(fRects[k], rectPaint);
160                             break;
161                         case kRRect_Clip:
162                             canvas->drawRRect(fRRects[k], rectPaint);
163                             break;
164                         case kPath_Clip:
165                             canvas->drawPath(fPaths[k], rectPaint);
166                             break;
167                     }
168                 }
169 
170                 for (int k = 0; k < 5; ++k) {
171                     switch (fClip) {
172                         case kRect_Clip:
173                             canvas->clipRect(fRects[k],
174                                              fOps[j*kRows+i][k],
175                                              fAntiAlias);
176                             break;
177                         case kRRect_Clip:
178                             canvas->clipRRect(fRRects[k],
179                                               fOps[j*kRows+i][k],
180                                               fAntiAlias);
181                             break;
182                         case kPath_Clip:
183                             canvas->clipPath(fPaths[k],
184                                              fOps[j*kRows+i][k],
185                                              fAntiAlias);
186                             break;
187                     }
188                 }
189                 canvas->drawRect(SkRect::MakeWH(fWidth, fHeight), fillPaint);
190                 canvas->restore();
191             }
192         }
193     }
194 private:
195     Clip fClip;
196     bool fAntiAlias;
197     SkRect fRects[5];
198     SkRRect fRRects[5];
199     SkPath fPaths[5];
200     SkColor fRectColors[5];
201     SkRegion::Op fOps[kRows * kCols][5];
202     SkScalar fWidth;
203     SkScalar fHeight;
204     SkScalar fTotalWidth;
205     SkScalar fTotalHeight;
206 
207     typedef GM INHERITED;
208 };
209 
210 //////////////////////////////////////////////////////////////////////////////
211 
212 // bw
213 DEF_GM( return new ComplexClip2GM(ComplexClip2GM::kRect_Clip, false); )
214 DEF_GM( return new ComplexClip2GM(ComplexClip2GM::kRRect_Clip, false); )
215 DEF_GM( return new ComplexClip2GM(ComplexClip2GM::kPath_Clip, false); )
216 
217 // aa
218 DEF_GM( return new ComplexClip2GM(ComplexClip2GM::kRect_Clip, true); )
219 DEF_GM( return new ComplexClip2GM(ComplexClip2GM::kRRect_Clip, true); )
220 DEF_GM( return new ComplexClip2GM(ComplexClip2GM::kPath_Clip, true); )
221 
222 }
223