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