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].setLTRB(xB, yB, xE, yE); 69 fRRects[0].setRectXY(fRects[0], 7, 7); 70 fPaths[0] = SkPath::RRect(fRects[0], 5, 5); 71 fRectColors[0] = SK_ColorRED; 72 73 fRects[1].setLTRB(xA, yA, xD, yD); 74 fRRects[1].setRectXY(fRects[1], 7, 7); 75 fPaths[1] = SkPath::RRect(fRects[1], 5, 5); 76 fRectColors[1] = SK_ColorGREEN; 77 78 fRects[2].setLTRB(xC, yA, xF, yD); 79 fRRects[2].setRectXY(fRects[2], 7, 7); 80 fPaths[2] = SkPath::RRect(fRects[2], 5, 5); 81 fRectColors[2] = SK_ColorBLUE; 82 83 fRects[3].setLTRB(xA, yC, xD, yF); 84 fRRects[3].setRectXY(fRects[3], 7, 7); 85 fPaths[3] = SkPath::RRect(fRects[3], 5, 5); 86 fRectColors[3] = SK_ColorYELLOW; 87 88 fRects[4].setLTRB(xC, yC, xF, yF); 89 fRRects[4].setRectXY(fRects[4], 7, 7); 90 fPaths[4] = SkPath::RRect(fRects[4], 5, 5); 91 fRectColors[4] = SK_ColorCYAN; 92 93 const SkClipOp ops[] = { 94 kDifference_SkClipOp, 95 kIntersect_SkClipOp, 96 }; 97 98 SkRandom r; 99 for (int i = 0; i < kRows; ++i) { 100 for (int j = 0; j < kCols; ++j) { 101 for (int k = 0; k < 5; ++k) { 102 fOps[j*kRows+i][k] = ops[r.nextU() % SK_ARRAY_COUNT(ops)]; 103 } 104 } 105 } 106 } 107 108 static constexpr int kRows = 5; 109 static constexpr int kCols = 5; 110 static constexpr int kPadX = 20; 111 static constexpr int kPadY = 20; 112 ClipStr(Clip clip)113 static const char* ClipStr(Clip clip) { 114 switch (clip) { 115 case kRect_Clip: 116 return "rect"; 117 case kRRect_Clip: 118 return "rrect"; 119 case kPath_Clip: 120 return "path"; 121 } 122 SkDEBUGFAIL("Unknown clip type."); 123 return ""; 124 } 125 onShortName()126 SkString onShortName() override { 127 if (kRect_Clip == fClip && !fAntiAlias) { 128 return SkString("complexclip2"); 129 } 130 131 SkString str; 132 str.printf("complexclip2_%s_%s", 133 ClipStr(fClip), 134 fAntiAlias ? "aa" : "bw"); 135 return str; 136 } 137 onISize()138 SkISize onISize() override { 139 return SkISize::Make(SkScalarRoundToInt(fTotalWidth), 140 SkScalarRoundToInt(fTotalHeight)); 141 } 142 onDraw(SkCanvas * canvas)143 void onDraw(SkCanvas* canvas) override { 144 SkPaint rectPaint; 145 rectPaint.setStyle(SkPaint::kStroke_Style); 146 rectPaint.setStrokeWidth(-1); 147 148 SkPaint fillPaint; 149 fillPaint.setColor(SkColorSetRGB(0xA0,0xDD,0xA0)); 150 151 for (int i = 0; i < kRows; ++i) { 152 for (int j = 0; j < kCols; ++j) { 153 canvas->save(); 154 155 canvas->translate(kPadX * SK_Scalar1 + (fWidth + kPadX * SK_Scalar1)*j, 156 kPadY * SK_Scalar1 + (fHeight + kPadY * SK_Scalar1)*i); 157 158 // draw the original shapes first so we can see the 159 // antialiasing on the clipped draw 160 for (int k = 0; k < 5; ++k) { 161 rectPaint.setColor(fRectColors[k]); 162 switch (fClip) { 163 case kRect_Clip: 164 canvas->drawRect(fRects[k], rectPaint); 165 break; 166 case kRRect_Clip: 167 canvas->drawRRect(fRRects[k], rectPaint); 168 break; 169 case kPath_Clip: 170 canvas->drawPath(fPaths[k], rectPaint); 171 break; 172 } 173 } 174 175 for (int k = 0; k < 5; ++k) { 176 switch (fClip) { 177 case kRect_Clip: 178 canvas->clipRect(fRects[k], 179 fOps[j*kRows+i][k], 180 fAntiAlias); 181 break; 182 case kRRect_Clip: 183 canvas->clipRRect(fRRects[k], 184 fOps[j*kRows+i][k], 185 fAntiAlias); 186 break; 187 case kPath_Clip: 188 canvas->clipPath(fPaths[k], 189 fOps[j*kRows+i][k], 190 fAntiAlias); 191 break; 192 } 193 } 194 canvas->drawRect(SkRect::MakeWH(fWidth, fHeight), fillPaint); 195 canvas->restore(); 196 } 197 } 198 } 199 private: 200 Clip fClip; 201 bool fAntiAlias; 202 SkRect fRects[5]; 203 SkRRect fRRects[5]; 204 SkPath fPaths[5]; 205 SkColor fRectColors[5]; 206 SkClipOp fOps[kRows * kCols][5]; 207 SkScalar fWidth; 208 SkScalar fHeight; 209 SkScalar fTotalWidth; 210 SkScalar fTotalHeight; 211 212 using INHERITED = GM; 213 }; 214 215 ////////////////////////////////////////////////////////////////////////////// 216 217 // bw 218 DEF_GM( return new ComplexClip2GM(ComplexClip2GM::kRect_Clip, false); ) 219 DEF_GM( return new ComplexClip2GM(ComplexClip2GM::kRRect_Clip, false); ) 220 DEF_GM( return new ComplexClip2GM(ComplexClip2GM::kPath_Clip, false); ) 221 222 // aa 223 DEF_GM( return new ComplexClip2GM(ComplexClip2GM::kRect_Clip, true); ) 224 DEF_GM( return new ComplexClip2GM(ComplexClip2GM::kRRect_Clip, true); ) 225 DEF_GM( return new ComplexClip2GM(ComplexClip2GM::kPath_Clip, true); ) 226 227 } // namespace skiagm 228