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 "SampleCode.h" 9 #include "SkCanvas.h" 10 #include "SkPath.h" 11 #include "SkView.h" 12 #include "SkClipOpPriv.h" 13 14 class ComplexClipView : public SampleView { 15 public: 16 ComplexClipView() { 17 this->setBGColor(0xFFA0DDA0); 18 } 19 20 protected: 21 // overrides from SkEventSink 22 virtual bool onQuery(SkEvent* evt) { 23 if (SampleCode::TitleQ(*evt)) { 24 SampleCode::TitleR(evt, "ComplexClip"); 25 return true; 26 } 27 return this->INHERITED::onQuery(evt); 28 } 29 30 virtual void onDrawContent(SkCanvas* canvas) { 31 SkPath path; 32 path.moveTo(SkIntToScalar(0), SkIntToScalar(50)); 33 path.quadTo(SkIntToScalar(0), SkIntToScalar(0), SkIntToScalar(50), SkIntToScalar(0)); 34 path.lineTo(SkIntToScalar(175), SkIntToScalar(0)); 35 path.quadTo(SkIntToScalar(200), SkIntToScalar(0), SkIntToScalar(200), SkIntToScalar(25)); 36 path.lineTo(SkIntToScalar(200), SkIntToScalar(150)); 37 path.quadTo(SkIntToScalar(200), SkIntToScalar(200), SkIntToScalar(150), SkIntToScalar(200)); 38 path.lineTo(SkIntToScalar(0), SkIntToScalar(200)); 39 path.close(); 40 path.moveTo(SkIntToScalar(50), SkIntToScalar(50)); 41 path.lineTo(SkIntToScalar(150), SkIntToScalar(50)); 42 path.lineTo(SkIntToScalar(150), SkIntToScalar(125)); 43 path.quadTo(SkIntToScalar(150), SkIntToScalar(150), SkIntToScalar(125), SkIntToScalar(150)); 44 path.lineTo(SkIntToScalar(50), SkIntToScalar(150)); 45 path.close(); 46 path.setFillType(SkPath::kEvenOdd_FillType); 47 SkColor pathColor = SK_ColorBLACK; 48 SkPaint pathPaint; 49 pathPaint.setAntiAlias(true); 50 pathPaint.setColor(pathColor); 51 52 SkPath clipA; 53 clipA.moveTo(SkIntToScalar(10), SkIntToScalar(20)); 54 clipA.lineTo(SkIntToScalar(165), SkIntToScalar(22)); 55 clipA.lineTo(SkIntToScalar(70), SkIntToScalar(105)); 56 clipA.lineTo(SkIntToScalar(165), SkIntToScalar(177)); 57 clipA.lineTo(SkIntToScalar(-5), SkIntToScalar(180)); 58 clipA.close(); 59 SkColor colorA = SK_ColorCYAN; 60 61 SkPath clipB; 62 clipB.moveTo(SkIntToScalar(40), SkIntToScalar(10)); 63 clipB.lineTo(SkIntToScalar(190), SkIntToScalar(15)); 64 clipB.lineTo(SkIntToScalar(195), SkIntToScalar(190)); 65 clipB.lineTo(SkIntToScalar(40), SkIntToScalar(185)); 66 clipB.lineTo(SkIntToScalar(155), SkIntToScalar(100)); 67 clipB.close(); 68 SkColor colorB = SK_ColorRED; 69 70 SkPaint paint; 71 paint.setAntiAlias(true); 72 73 paint.setStyle(SkPaint::kStroke_Style); 74 paint.setStrokeWidth(0); 75 76 canvas->translate(SkIntToScalar(10),SkIntToScalar(10)); 77 canvas->drawPath(path, pathPaint); 78 paint.setColor(colorA); 79 canvas->drawPath(clipA, paint); 80 paint.setColor(colorB); 81 canvas->drawPath(clipB, paint); 82 83 static const struct { 84 SkClipOp fOp; 85 const char* fName; 86 } gOps[] = { //extra spaces in names for measureText 87 {kIntersect_SkClipOp, "Isect "}, 88 {kDifference_SkClipOp, "Diff " }, 89 {kUnion_SkClipOp, "Union "}, 90 {kXOR_SkClipOp, "Xor " }, 91 {kReverseDifference_SkClipOp, "RDiff "} 92 }; 93 94 canvas->translate(0, SkIntToScalar(40)); 95 canvas->scale(3 * SK_Scalar1 / 4, 3 * SK_Scalar1 / 4); 96 canvas->save(); 97 98 for (int invA = 0; invA < 2; ++invA) { 99 for (size_t op = 0; op < SK_ARRAY_COUNT(gOps); ++op) { 100 size_t idx = invA * SK_ARRAY_COUNT(gOps) + op; 101 if (!(idx % 3)) { 102 canvas->restore(); 103 canvas->translate(0, SkIntToScalar(250)); 104 canvas->save(); 105 } 106 canvas->save(); 107 // set clip 108 clipA.setFillType(invA ? SkPath::kInverseEvenOdd_FillType : 109 SkPath::kEvenOdd_FillType); 110 canvas->clipPath(clipA); 111 canvas->clipPath(clipB, gOps[op].fOp); 112 113 // draw path clipped 114 canvas->drawPath(path, pathPaint); 115 canvas->restore(); 116 117 // draw path in hairline 118 paint.setColor(pathColor); 119 canvas->drawPath(path, paint); 120 121 // draw clips in hair line 122 paint.setColor(colorA); 123 canvas->drawPath(clipA, paint); 124 paint.setColor(colorB); 125 canvas->drawPath(clipB, paint); 126 127 paint.setTextSize(SkIntToScalar(20)); 128 129 SkScalar txtX = SkIntToScalar(55); 130 paint.setColor(colorA); 131 const char* aTxt = invA ? "InverseA " : "A "; 132 canvas->drawString(aTxt, txtX, SkIntToScalar(220), paint); 133 txtX += paint.measureText(aTxt, strlen(aTxt)); 134 paint.setColor(SK_ColorBLACK); 135 canvas->drawString(gOps[op].fName, 136 txtX, SkIntToScalar(220), paint); 137 txtX += paint.measureText(gOps[op].fName, strlen(gOps[op].fName)); 138 paint.setColor(colorB); 139 canvas->drawString("B", txtX, SkIntToScalar(220), paint); 140 141 canvas->translate(SkIntToScalar(250),0); 142 } 143 } 144 canvas->restore(); 145 } 146 147 private: 148 typedef SampleView INHERITED; 149 }; 150 151 ////////////////////////////////////////////////////////////////////////////// 152 153 static SkView* MyFactory() { return new ComplexClipView; } 154 static SkViewRegister reg(MyFactory); 155