1 2/* 3 * Copyright 2011 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 "SkParsePath.h" 11#include "SkPath.h" 12//#include "SkRandom.h" 13 14namespace skiagm { 15 16static const SkColor gPathColor = SK_ColorBLACK; 17static const SkColor gClipAColor = SK_ColorBLUE; 18static const SkColor gClipBColor = SK_ColorRED; 19 20class ComplexClipGM : public GM { 21 bool fDoAAClip; 22public: 23 ComplexClipGM(bool aaclip) : fDoAAClip(aaclip) { 24 this->setBGColor(0xFFDDDDDD); 25// this->setBGColor(SkColorSetRGB(0xB0,0xDD,0xB0)); 26 } 27 28protected: 29 30 SkString onShortName() { 31 SkString str; 32 str.printf("complexclip_%s", fDoAAClip ? "aa" : "bw"); 33 return str; 34 } 35 36 SkISize onISize() { return make_isize(970, 780); } 37 38 virtual void onDraw(SkCanvas* canvas) { 39 SkPath path; 40 path.moveTo(SkIntToScalar(0), SkIntToScalar(50)); 41 path.quadTo(SkIntToScalar(0), SkIntToScalar(0), SkIntToScalar(50), SkIntToScalar(0)); 42 path.lineTo(SkIntToScalar(175), SkIntToScalar(0)); 43 path.quadTo(SkIntToScalar(200), SkIntToScalar(0), SkIntToScalar(200), SkIntToScalar(25)); 44 path.lineTo(SkIntToScalar(200), SkIntToScalar(150)); 45 path.quadTo(SkIntToScalar(200), SkIntToScalar(200), SkIntToScalar(150), SkIntToScalar(200)); 46 path.lineTo(SkIntToScalar(0), SkIntToScalar(200)); 47 path.close(); 48 path.moveTo(SkIntToScalar(50), SkIntToScalar(50)); 49 path.lineTo(SkIntToScalar(150), SkIntToScalar(50)); 50 path.lineTo(SkIntToScalar(150), SkIntToScalar(125)); 51 path.quadTo(SkIntToScalar(150), SkIntToScalar(150), SkIntToScalar(125), SkIntToScalar(150)); 52 path.lineTo(SkIntToScalar(50), SkIntToScalar(150)); 53 path.close(); 54 path.setFillType(SkPath::kEvenOdd_FillType); 55 SkPaint pathPaint; 56 pathPaint.setAntiAlias(true); 57 pathPaint.setColor(gPathColor); 58 59 SkPath clipA; 60 clipA.moveTo(SkIntToScalar(10), SkIntToScalar(20)); 61 clipA.lineTo(SkIntToScalar(165), SkIntToScalar(22)); 62 clipA.lineTo(SkIntToScalar(70), SkIntToScalar(105)); 63 clipA.lineTo(SkIntToScalar(165), SkIntToScalar(177)); 64 clipA.lineTo(SkIntToScalar(-5), SkIntToScalar(180)); 65 clipA.close(); 66 67 SkPath clipB; 68 clipB.moveTo(SkIntToScalar(40), SkIntToScalar(10)); 69 clipB.lineTo(SkIntToScalar(190), SkIntToScalar(15)); 70 clipB.lineTo(SkIntToScalar(195), SkIntToScalar(190)); 71 clipB.lineTo(SkIntToScalar(40), SkIntToScalar(185)); 72 clipB.lineTo(SkIntToScalar(155), SkIntToScalar(100)); 73 clipB.close(); 74 75 SkPaint paint; 76 paint.setAntiAlias(true); 77 paint.setTextSize(SkIntToScalar(20)); 78 79 static const struct { 80 SkRegion::Op fOp; 81 const char* fName; 82 } gOps[] = { //extra spaces in names for measureText 83 {SkRegion::kIntersect_Op, "Isect "}, 84 {SkRegion::kDifference_Op, "Diff " }, 85 {SkRegion::kUnion_Op, "Union "}, 86 {SkRegion::kXOR_Op, "Xor " }, 87 {SkRegion::kReverseDifference_Op, "RDiff "} 88 }; 89 90 canvas->translate(SkIntToScalar(20), SkIntToScalar(20)); 91 canvas->scale(3 * SK_Scalar1 / 4, 3 * SK_Scalar1 / 4); 92 93 for (int invBits = 0; invBits < 4; ++invBits) { 94 canvas->save(); 95 for (size_t op = 0; op < SK_ARRAY_COUNT(gOps); ++op) { 96 this->drawHairlines(canvas, path, clipA, clipB); 97 98 bool doInvA = SkToBool(invBits & 1); 99 bool doInvB = SkToBool(invBits & 2); 100 canvas->save(); 101 // set clip 102 clipA.setFillType(doInvA ? SkPath::kInverseEvenOdd_FillType : 103 SkPath::kEvenOdd_FillType); 104 clipB.setFillType(doInvB ? SkPath::kInverseEvenOdd_FillType : 105 SkPath::kEvenOdd_FillType); 106 canvas->clipPath(clipA, SkRegion::kIntersect_Op, fDoAAClip); 107 canvas->clipPath(clipB, gOps[op].fOp, fDoAAClip); 108 109 // draw path clipped 110 canvas->drawPath(path, pathPaint); 111 canvas->restore(); 112 113 114 SkScalar txtX = SkIntToScalar(45); 115 paint.setColor(gClipAColor); 116 const char* aTxt = doInvA ? "InvA " : "A "; 117 canvas->drawText(aTxt, strlen(aTxt), txtX, SkIntToScalar(220), paint); 118 txtX += paint.measureText(aTxt, strlen(aTxt)); 119 paint.setColor(SK_ColorBLACK); 120 canvas->drawText(gOps[op].fName, strlen(gOps[op].fName), 121 txtX, SkIntToScalar(220), paint); 122 txtX += paint.measureText(gOps[op].fName, strlen(gOps[op].fName)); 123 paint.setColor(gClipBColor); 124 const char* bTxt = doInvB ? "InvB " : "B "; 125 canvas->drawText(bTxt, strlen(bTxt), txtX, SkIntToScalar(220), paint); 126 127 canvas->translate(SkIntToScalar(250),0); 128 } 129 canvas->restore(); 130 canvas->translate(0, SkIntToScalar(250)); 131 } 132 } 133private: 134 void drawHairlines(SkCanvas* canvas, const SkPath& path, 135 const SkPath& clipA, const SkPath& clipB) { 136 SkPaint paint; 137 paint.setAntiAlias(true); 138 paint.setStyle(SkPaint::kStroke_Style); 139 const SkAlpha fade = 0x33; 140 141 // draw path in hairline 142 paint.setColor(gPathColor); paint.setAlpha(fade); 143 canvas->drawPath(path, paint); 144 145 // draw clips in hair line 146 paint.setColor(gClipAColor); paint.setAlpha(fade); 147 canvas->drawPath(clipA, paint); 148 paint.setColor(gClipBColor); paint.setAlpha(fade); 149 canvas->drawPath(clipB, paint); 150 } 151 152 typedef GM INHERITED; 153}; 154 155////////////////////////////////////////////////////////////////////////////// 156 157static GM* gFact0(void*) { return new ComplexClipGM(false); } 158static GM* gFact1(void*) { return new ComplexClipGM(true); } 159 160static GMRegistry gReg0(gFact0); 161static GMRegistry gReg1(gFact1); 162 163} 164