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 SkScalar xA = 0.65f; 28 SkScalar xF = 50.65f; 29 30 SkScalar yA = 0.65f; 31 SkScalar yF = 50.65f; 32 33 fWidth = xF - xA; 34 fHeight = yF - yA; 35 36 fTotalWidth = kCols * fWidth + SK_Scalar1 * (kCols + 1) * kPadX; 37 fTotalHeight = kRows * fHeight + SK_Scalar1 * (kRows + 1) * kPadY; 38 } 39 40 protected: onOnceBeforeDraw()41 void onOnceBeforeDraw() override { 42 this->setBGColor(SkColorSetRGB(0xDD,0xA0,0xDD)); 43 44 // offset the rects a bit so we get antialiasing even in the rect case 45 SkScalar xA = 0.65f; 46 SkScalar xB = 10.65f; 47 SkScalar xC = 20.65f; 48 SkScalar xD = 30.65f; 49 SkScalar xE = 40.65f; 50 SkScalar xF = 50.65f; 51 52 SkScalar yA = 0.65f; 53 SkScalar yB = 10.65f; 54 SkScalar yC = 20.65f; 55 SkScalar yD = 30.65f; 56 SkScalar yE = 40.65f; 57 SkScalar yF = 50.65f; 58 59 fRects[0].set(xB, yB, xE, yE); 60 fRRects[0].setRectXY(fRects[0], 7, 7); 61 fPaths[0].addRoundRect(fRects[0], 5, 5); 62 fRectColors[0] = SK_ColorRED; 63 64 fRects[1].set(xA, yA, xD, yD); 65 fRRects[1].setRectXY(fRects[1], 7, 7); 66 fPaths[1].addRoundRect(fRects[1], 5, 5); 67 fRectColors[1] = SK_ColorGREEN; 68 69 fRects[2].set(xC, yA, xF, yD); 70 fRRects[2].setRectXY(fRects[2], 7, 7); 71 fPaths[2].addRoundRect(fRects[2], 5, 5); 72 fRectColors[2] = SK_ColorBLUE; 73 74 fRects[3].set(xA, yC, xD, yF); 75 fRRects[3].setRectXY(fRects[3], 7, 7); 76 fPaths[3].addRoundRect(fRects[3], 5, 5); 77 fRectColors[3] = SK_ColorYELLOW; 78 79 fRects[4].set(xC, yC, xF, yF); 80 fRRects[4].setRectXY(fRects[4], 7, 7); 81 fPaths[4].addRoundRect(fRects[4], 5, 5); 82 fRectColors[4] = SK_ColorCYAN; 83 84 SkRegion::Op ops[] = { 85 SkRegion::kDifference_Op, 86 SkRegion::kIntersect_Op, 87 SkRegion::kUnion_Op, 88 SkRegion::kXOR_Op, 89 SkRegion::kReverseDifference_Op, 90 SkRegion::kReplace_Op, 91 }; 92 93 SkRandom r; 94 for (int i = 0; i < kRows; ++i) { 95 for (int j = 0; j < kCols; ++j) { 96 for (int k = 0; k < 5; ++k) { 97 fOps[j*kRows+i][k] = ops[r.nextU() % SK_ARRAY_COUNT(ops)]; 98 } 99 } 100 } 101 } 102 103 static const int kRows = 5; 104 static const int kCols = 5; 105 static const int kPadX = 20; 106 static const int kPadY = 20; 107 ClipStr(Clip clip)108 static const char* ClipStr(Clip clip) { 109 switch (clip) { 110 case kRect_Clip: 111 return "rect"; 112 case kRRect_Clip: 113 return "rrect"; 114 case kPath_Clip: 115 return "path"; 116 } 117 SkDEBUGFAIL("Unknown clip type."); 118 return ""; 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