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