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