1*c8dee2aaSAndroid Build Coastguard Worker /* 2*c8dee2aaSAndroid Build Coastguard Worker * Copyright 2013 Google Inc. 3*c8dee2aaSAndroid Build Coastguard Worker * 4*c8dee2aaSAndroid Build Coastguard Worker * Use of this source code is governed by a BSD-style license that can be 5*c8dee2aaSAndroid Build Coastguard Worker * found in the LICENSE file. 6*c8dee2aaSAndroid Build Coastguard Worker */ 7*c8dee2aaSAndroid Build Coastguard Worker 8*c8dee2aaSAndroid Build Coastguard Worker #include "gm/gm.h" 9*c8dee2aaSAndroid Build Coastguard Worker #include "include/core/SkBitmap.h" 10*c8dee2aaSAndroid Build Coastguard Worker #include "include/core/SkCanvas.h" 11*c8dee2aaSAndroid Build Coastguard Worker #include "include/core/SkColor.h" 12*c8dee2aaSAndroid Build Coastguard Worker #include "include/core/SkPaint.h" 13*c8dee2aaSAndroid Build Coastguard Worker #include "include/core/SkPath.h" 14*c8dee2aaSAndroid Build Coastguard Worker #include "include/core/SkRect.h" 15*c8dee2aaSAndroid Build Coastguard Worker #include "include/core/SkScalar.h" 16*c8dee2aaSAndroid Build Coastguard Worker #include "include/core/SkSize.h" 17*c8dee2aaSAndroid Build Coastguard Worker #include "include/core/SkString.h" 18*c8dee2aaSAndroid Build Coastguard Worker #include "include/pathops/SkPathOps.h" 19*c8dee2aaSAndroid Build Coastguard Worker #include "tools/ToolUtils.h" 20*c8dee2aaSAndroid Build Coastguard Worker 21*c8dee2aaSAndroid Build Coastguard Worker namespace skiagm { 22*c8dee2aaSAndroid Build Coastguard Worker 23*c8dee2aaSAndroid Build Coastguard Worker class PathOpsInverseGM : public GM { 24*c8dee2aaSAndroid Build Coastguard Worker public: PathOpsInverseGM()25*c8dee2aaSAndroid Build Coastguard Worker PathOpsInverseGM() { 26*c8dee2aaSAndroid Build Coastguard Worker } 27*c8dee2aaSAndroid Build Coastguard Worker 28*c8dee2aaSAndroid Build Coastguard Worker protected: onOnceBeforeDraw()29*c8dee2aaSAndroid Build Coastguard Worker void onOnceBeforeDraw() override { 30*c8dee2aaSAndroid Build Coastguard Worker const unsigned oneColor = ToolUtils::color_to_565(0xFF8080FF); 31*c8dee2aaSAndroid Build Coastguard Worker const unsigned twoColor = 0x807F1f1f; 32*c8dee2aaSAndroid Build Coastguard Worker SkColor blendColor = blend(oneColor, twoColor); 33*c8dee2aaSAndroid Build Coastguard Worker makePaint(&fOnePaint, oneColor); 34*c8dee2aaSAndroid Build Coastguard Worker makePaint(&fTwoPaint, twoColor); 35*c8dee2aaSAndroid Build Coastguard Worker makePaint(&fOpPaint[kDifference_SkPathOp], oneColor); 36*c8dee2aaSAndroid Build Coastguard Worker makePaint(&fOpPaint[kIntersect_SkPathOp], blendColor); 37*c8dee2aaSAndroid Build Coastguard Worker makePaint(&fOpPaint[kUnion_SkPathOp], ToolUtils::color_to_565(0xFFc0FFc0)); 38*c8dee2aaSAndroid Build Coastguard Worker makePaint(&fOpPaint[kReverseDifference_SkPathOp], twoColor); 39*c8dee2aaSAndroid Build Coastguard Worker makePaint(&fOpPaint[kXOR_SkPathOp], ToolUtils::color_to_565(0xFFa0FFe0)); 40*c8dee2aaSAndroid Build Coastguard Worker makePaint(&fOutlinePaint, 0xFF000000); 41*c8dee2aaSAndroid Build Coastguard Worker fOutlinePaint.setStyle(SkPaint::kStroke_Style); 42*c8dee2aaSAndroid Build Coastguard Worker } 43*c8dee2aaSAndroid Build Coastguard Worker blend(SkColor one,SkColor two)44*c8dee2aaSAndroid Build Coastguard Worker SkColor blend(SkColor one, SkColor two) { 45*c8dee2aaSAndroid Build Coastguard Worker SkBitmap temp; 46*c8dee2aaSAndroid Build Coastguard Worker temp.allocN32Pixels(1, 1); 47*c8dee2aaSAndroid Build Coastguard Worker SkCanvas canvas(temp); 48*c8dee2aaSAndroid Build Coastguard Worker canvas.drawColor(one); 49*c8dee2aaSAndroid Build Coastguard Worker canvas.drawColor(two); 50*c8dee2aaSAndroid Build Coastguard Worker void* pixels = temp.getPixels(); 51*c8dee2aaSAndroid Build Coastguard Worker return *(SkColor*) pixels; 52*c8dee2aaSAndroid Build Coastguard Worker } 53*c8dee2aaSAndroid Build Coastguard Worker makePaint(SkPaint * paint,SkColor color)54*c8dee2aaSAndroid Build Coastguard Worker void makePaint(SkPaint* paint, SkColor color) { 55*c8dee2aaSAndroid Build Coastguard Worker paint->setAntiAlias(true); 56*c8dee2aaSAndroid Build Coastguard Worker paint->setStyle(SkPaint::kFill_Style); 57*c8dee2aaSAndroid Build Coastguard Worker paint->setColor(color); 58*c8dee2aaSAndroid Build Coastguard Worker } 59*c8dee2aaSAndroid Build Coastguard Worker getName() const60*c8dee2aaSAndroid Build Coastguard Worker SkString getName() const override { return SkString("pathopsinverse"); } 61*c8dee2aaSAndroid Build Coastguard Worker getISize()62*c8dee2aaSAndroid Build Coastguard Worker SkISize getISize() override { return SkISize::Make(1200, 900); } 63*c8dee2aaSAndroid Build Coastguard Worker onDraw(SkCanvas * canvas)64*c8dee2aaSAndroid Build Coastguard Worker void onDraw(SkCanvas* canvas) override { 65*c8dee2aaSAndroid Build Coastguard Worker SkPath one, two; 66*c8dee2aaSAndroid Build Coastguard Worker int yPos = 0; 67*c8dee2aaSAndroid Build Coastguard Worker for (int oneFill = 0; oneFill <= 1; ++oneFill) { 68*c8dee2aaSAndroid Build Coastguard Worker SkPathFillType oneF = oneFill ? SkPathFillType::kInverseEvenOdd 69*c8dee2aaSAndroid Build Coastguard Worker : SkPathFillType::kEvenOdd; 70*c8dee2aaSAndroid Build Coastguard Worker for (int twoFill = 0; twoFill <= 1; ++twoFill) { 71*c8dee2aaSAndroid Build Coastguard Worker SkPathFillType twoF = twoFill ? SkPathFillType::kInverseEvenOdd 72*c8dee2aaSAndroid Build Coastguard Worker : SkPathFillType::kEvenOdd; 73*c8dee2aaSAndroid Build Coastguard Worker one.reset(); 74*c8dee2aaSAndroid Build Coastguard Worker one.setFillType(oneF); 75*c8dee2aaSAndroid Build Coastguard Worker one.addRect(10, 10, 70, 70); 76*c8dee2aaSAndroid Build Coastguard Worker two.reset(); 77*c8dee2aaSAndroid Build Coastguard Worker two.setFillType(twoF); 78*c8dee2aaSAndroid Build Coastguard Worker two.addRect(40, 40, 100, 100); 79*c8dee2aaSAndroid Build Coastguard Worker canvas->save(); 80*c8dee2aaSAndroid Build Coastguard Worker canvas->translate(0, SkIntToScalar(yPos)); 81*c8dee2aaSAndroid Build Coastguard Worker canvas->clipRect(SkRect::MakeWH(110, 110), true); 82*c8dee2aaSAndroid Build Coastguard Worker canvas->drawPath(one, fOnePaint); 83*c8dee2aaSAndroid Build Coastguard Worker canvas->drawPath(one, fOutlinePaint); 84*c8dee2aaSAndroid Build Coastguard Worker canvas->drawPath(two, fTwoPaint); 85*c8dee2aaSAndroid Build Coastguard Worker canvas->drawPath(two, fOutlinePaint); 86*c8dee2aaSAndroid Build Coastguard Worker canvas->restore(); 87*c8dee2aaSAndroid Build Coastguard Worker int xPos = 150; 88*c8dee2aaSAndroid Build Coastguard Worker for (int op = kDifference_SkPathOp; op <= kReverseDifference_SkPathOp; ++op) { 89*c8dee2aaSAndroid Build Coastguard Worker SkPath result; 90*c8dee2aaSAndroid Build Coastguard Worker Op(one, two, (SkPathOp) op, &result); 91*c8dee2aaSAndroid Build Coastguard Worker canvas->save(); 92*c8dee2aaSAndroid Build Coastguard Worker canvas->translate(SkIntToScalar(xPos), SkIntToScalar(yPos)); 93*c8dee2aaSAndroid Build Coastguard Worker canvas->clipRect(SkRect::MakeWH(110, 110), true); 94*c8dee2aaSAndroid Build Coastguard Worker canvas->drawPath(result, fOpPaint[op]); 95*c8dee2aaSAndroid Build Coastguard Worker canvas->drawPath(result, fOutlinePaint); 96*c8dee2aaSAndroid Build Coastguard Worker canvas->restore(); 97*c8dee2aaSAndroid Build Coastguard Worker xPos += 150; 98*c8dee2aaSAndroid Build Coastguard Worker } 99*c8dee2aaSAndroid Build Coastguard Worker yPos += 150; 100*c8dee2aaSAndroid Build Coastguard Worker } 101*c8dee2aaSAndroid Build Coastguard Worker } 102*c8dee2aaSAndroid Build Coastguard Worker } 103*c8dee2aaSAndroid Build Coastguard Worker 104*c8dee2aaSAndroid Build Coastguard Worker private: 105*c8dee2aaSAndroid Build Coastguard Worker SkPaint fOnePaint; 106*c8dee2aaSAndroid Build Coastguard Worker SkPaint fTwoPaint; 107*c8dee2aaSAndroid Build Coastguard Worker SkPaint fOutlinePaint; 108*c8dee2aaSAndroid Build Coastguard Worker SkPaint fOpPaint[kReverseDifference_SkPathOp - kDifference_SkPathOp + 1]; 109*c8dee2aaSAndroid Build Coastguard Worker using INHERITED = GM; 110*c8dee2aaSAndroid Build Coastguard Worker }; 111*c8dee2aaSAndroid Build Coastguard Worker 112*c8dee2aaSAndroid Build Coastguard Worker ////////////////////////////////////////////////////////////////////////////// 113*c8dee2aaSAndroid Build Coastguard Worker 114*c8dee2aaSAndroid Build Coastguard Worker DEF_GM( return new PathOpsInverseGM; ) 115*c8dee2aaSAndroid Build Coastguard Worker 116*c8dee2aaSAndroid Build Coastguard Worker } // namespace skiagm 117*c8dee2aaSAndroid Build Coastguard Worker 118*c8dee2aaSAndroid Build Coastguard Worker #include "include/utils/SkParsePath.h" 119*c8dee2aaSAndroid Build Coastguard Worker 120*c8dee2aaSAndroid Build Coastguard Worker DEF_SIMPLE_GM(pathops_skbug_10155, canvas, 256, 256) { 121*c8dee2aaSAndroid Build Coastguard Worker const char* svgStr[] = { 122*c8dee2aaSAndroid Build Coastguard Worker "M474.889 27.0952C474.889 27.1002 474.888 27.1018 474.889 27.1004L479.872 27.5019C479.883 27.3656 479.889 27.2299 479.889 27.0952L474.889 27.0952L474.889 27.0952Z", 123*c8dee2aaSAndroid Build Coastguard Worker "M474.94 26.9405C474.93 26.9482 474.917 26.9576 474.901 26.9683L477.689 31.1186C477.789 31.0512 477.888 30.9804 477.985 30.9059L474.94 26.9405L474.94 26.9405Z" 124*c8dee2aaSAndroid Build Coastguard Worker }; 125*c8dee2aaSAndroid Build Coastguard Worker 126*c8dee2aaSAndroid Build Coastguard Worker SkPath path[2], resultPath; 127*c8dee2aaSAndroid Build Coastguard Worker SkOpBuilder builder; 128*c8dee2aaSAndroid Build Coastguard Worker 129*c8dee2aaSAndroid Build Coastguard Worker for (int i = 0; i < 2; i++) 130*c8dee2aaSAndroid Build Coastguard Worker { 131*c8dee2aaSAndroid Build Coastguard Worker SkParsePath::FromSVGString(svgStr[i], &path[i]); 132*c8dee2aaSAndroid Build Coastguard Worker builder.add(path[i], kUnion_SkPathOp); 133*c8dee2aaSAndroid Build Coastguard Worker } 134*c8dee2aaSAndroid Build Coastguard Worker 135*c8dee2aaSAndroid Build Coastguard Worker builder.resolve(&resultPath); 136*c8dee2aaSAndroid Build Coastguard Worker 137*c8dee2aaSAndroid Build Coastguard Worker auto r = path[0].getBounds(); 138*c8dee2aaSAndroid Build Coastguard Worker canvas->translate(30, 30); 139*c8dee2aaSAndroid Build Coastguard Worker canvas->scale(200 / r.width(), 200 / r.width()); 140*c8dee2aaSAndroid Build Coastguard Worker canvas->translate(-r.fLeft, -r.fTop); 141*c8dee2aaSAndroid Build Coastguard Worker 142*c8dee2aaSAndroid Build Coastguard Worker SkPaint paint; 143*c8dee2aaSAndroid Build Coastguard Worker paint.setColor(SK_ColorRED); 144*c8dee2aaSAndroid Build Coastguard Worker paint.setAntiAlias(true); 145*c8dee2aaSAndroid Build Coastguard Worker paint.setStyle(SkPaint::kStroke_Style); 146*c8dee2aaSAndroid Build Coastguard Worker paint.setStrokeWidth(0); 147*c8dee2aaSAndroid Build Coastguard Worker 148*c8dee2aaSAndroid Build Coastguard Worker canvas->drawPath(path[0], paint); 149*c8dee2aaSAndroid Build Coastguard Worker canvas->drawPath(path[1], paint); 150*c8dee2aaSAndroid Build Coastguard Worker 151*c8dee2aaSAndroid Build Coastguard Worker // The blue draw should (nearly) overdraw all of the red (except where the two paths intersect) 152*c8dee2aaSAndroid Build Coastguard Worker paint.setColor(SK_ColorBLUE); 153*c8dee2aaSAndroid Build Coastguard Worker canvas->drawPath(resultPath, paint); 154*c8dee2aaSAndroid Build Coastguard Worker } 155