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