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