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