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 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 = 0.65f; 25 SkScalar xB = 10.65f; 26 SkScalar xC = 20.65f; 27 SkScalar xD = 30.65f; 28 SkScalar xE = 40.65f; 29 SkScalar xF = 50.65f; 30 31 SkScalar yA = 0.65f; 32 SkScalar yB = 10.65f; 33 SkScalar yC = 20.65f; 34 SkScalar yD = 30.65f; 35 SkScalar yE = 40.65f; 36 SkScalar yF = 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 SkLCGRandom 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 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 102 virtual SkISize onISize() { 103 return make_isize(SkScalarRoundToInt(fTotalWidth), 104 SkScalarRoundToInt(fTotalHeight)); 105 } 106 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 167 static GM* MyFactory(void*) { return new ComplexClip2GM(false, false); } 168 static GMRegistry reg(MyFactory); 169 170 // bw paths 171 static GM* MyFactory2(void*) { return new ComplexClip2GM(true, false); } 172 static GMRegistry reg2(MyFactory2); 173 174 // aa rects 175 static GM* MyFactory3(void*) { return new ComplexClip2GM(false, true); } 176 static GMRegistry reg3(MyFactory3); 177 178 // aa paths 179 static GM* MyFactory4(void*) { return new ComplexClip2GM(true, true); } 180 static GMRegistry reg4(MyFactory4); 181 182 } 183