1 2 /* 3 * Copyright 2014 Google Inc. 4 * 5 * Use of this source code is governed by a BSD-style license that can be 6 * found in the LICENSE file. 7 */ 8 #include "gm.h" 9 #include "SkCanvas.h" 10 #include "SkPath.h" 11 12 namespace skiagm { 13 14 static const SkColor gPathColor = SK_ColorYELLOW; 15 16 class ComplexClip3GM : public GM { 17 public: ComplexClip3GM(bool doSimpleClipFirst)18 ComplexClip3GM(bool doSimpleClipFirst) 19 : fDoSimpleClipFirst(doSimpleClipFirst) { 20 this->setBGColor(sk_tool_utils::color_to_565(0xFFDDDDDD)); 21 } 22 23 protected: 24 onShortName()25 SkString onShortName() { 26 SkString str; 27 str.printf("complexclip3_%s", fDoSimpleClipFirst ? "simple" : "complex"); 28 return str; 29 } 30 onISize()31 SkISize onISize() { return SkISize::Make(1000, 950); } 32 onDraw(SkCanvas * canvas)33 virtual void onDraw(SkCanvas* canvas) { 34 SkPath clipSimple; 35 clipSimple.addCircle(SkIntToScalar(70), SkIntToScalar(50), SkIntToScalar(20)); 36 37 SkRect r1 = { 10, 20, 70, 80 }; 38 SkPath clipComplex; 39 clipComplex.moveTo(SkIntToScalar(40), SkIntToScalar(50)); 40 clipComplex.arcTo(r1, SkIntToScalar(30), SkIntToScalar(300), false); 41 clipComplex.close(); 42 43 SkPath* firstClip = &clipSimple; 44 SkPath* secondClip = &clipComplex; 45 46 if (!fDoSimpleClipFirst) { 47 SkTSwap<SkPath*>(firstClip, secondClip); 48 } 49 50 SkPaint paint; 51 paint.setAntiAlias(true); 52 sk_tool_utils::set_portable_typeface(&paint); 53 paint.setTextSize(SkIntToScalar(20)); 54 55 static const struct { 56 SkRegion::Op fOp; 57 const char* fName; 58 } gOps[] = { 59 {SkRegion::kIntersect_Op, "I"}, 60 {SkRegion::kDifference_Op, "D" }, 61 {SkRegion::kUnion_Op, "U"}, 62 {SkRegion::kXOR_Op, "X" }, 63 {SkRegion::kReverseDifference_Op, "R"} 64 }; 65 66 canvas->translate(SkIntToScalar(20), SkIntToScalar(20)); 67 canvas->scale(3 * SK_Scalar1 / 4, 3 * SK_Scalar1 / 4); 68 69 SkPaint pathPaint; 70 pathPaint.setAntiAlias(true); 71 pathPaint.setColor(gPathColor); 72 73 for (int invA = 0; invA < 2; ++invA) { 74 for (int aaBits = 0; aaBits < 4; ++aaBits) { 75 canvas->save(); 76 for (size_t op = 0; op < SK_ARRAY_COUNT(gOps); ++op) { 77 for (int invB = 0; invB < 2; ++invB) { 78 bool doAAA = SkToBool(aaBits & 1); 79 bool doAAB = SkToBool(aaBits & 2); 80 bool doInvA = SkToBool(invA); 81 bool doInvB = SkToBool(invB); 82 canvas->save(); 83 // set clip 84 firstClip->setFillType(doInvA ? SkPath::kInverseEvenOdd_FillType : 85 SkPath::kEvenOdd_FillType); 86 secondClip->setFillType(doInvB ? SkPath::kInverseEvenOdd_FillType : 87 SkPath::kEvenOdd_FillType); 88 canvas->clipPath(*firstClip, SkRegion::kIntersect_Op, doAAA); 89 canvas->clipPath(*secondClip, gOps[op].fOp, doAAB); 90 91 // draw rect clipped 92 SkRect r = { 0, 0, 100, 100 }; 93 canvas->drawRect(r, pathPaint); 94 canvas->restore(); 95 96 97 SkScalar txtX = SkIntToScalar(10); 98 paint.setColor(SK_ColorBLACK); 99 SkString str; 100 str.printf("%s%s %s %s%s", doAAA ? "A" : "B", 101 doInvA ? "I" : "N", 102 gOps[op].fName, 103 doAAB ? "A" : "B", 104 doInvB ? "I" : "N"); 105 106 canvas->drawText(str.c_str(), strlen(str.c_str()), txtX, SkIntToScalar(130), 107 paint); 108 if (doInvB) { 109 canvas->translate(SkIntToScalar(150),0); 110 } else { 111 canvas->translate(SkIntToScalar(120),0); 112 } 113 } 114 } 115 canvas->restore(); 116 canvas->translate(0, SkIntToScalar(150)); 117 } 118 } 119 } 120 121 private: 122 bool fDoSimpleClipFirst; 123 124 typedef GM INHERITED; 125 }; 126 127 ////////////////////////////////////////////////////////////////////////////// 128 129 // Simple clip first 130 DEF_GM( return new ComplexClip3GM(true); ) 131 // Complex clip first 132 DEF_GM( return new ComplexClip3GM(false); ) 133 } 134