160 lines
		
	
	
		
			5.3 KiB
		
	
	
	
		
			C++
		
	
	
	
			
		
		
	
	
			160 lines
		
	
	
		
			5.3 KiB
		
	
	
	
		
			C++
		
	
	
	
| /*
 | |
|  * Copyright 2013 Google Inc.
 | |
|  *
 | |
|  * Use of this source code is governed by a BSD-style license that can be
 | |
|  * found in the LICENSE file.
 | |
|  */
 | |
| 
 | |
| #include "gm/gm.h"
 | |
| #include "include/core/SkBitmap.h"
 | |
| #include "include/core/SkCanvas.h"
 | |
| #include "include/core/SkColor.h"
 | |
| #include "include/core/SkPaint.h"
 | |
| #include "include/core/SkPath.h"
 | |
| #include "include/core/SkRect.h"
 | |
| #include "include/core/SkScalar.h"
 | |
| #include "include/core/SkSize.h"
 | |
| #include "include/core/SkString.h"
 | |
| #include "include/pathops/SkPathOps.h"
 | |
| #include "tools/ToolUtils.h"
 | |
| 
 | |
| namespace skiagm {
 | |
| 
 | |
| class PathOpsInverseGM : public GM {
 | |
| public:
 | |
|     PathOpsInverseGM() {
 | |
|     }
 | |
| 
 | |
| protected:
 | |
|     void onOnceBeforeDraw() override {
 | |
|         const unsigned oneColor   = ToolUtils::color_to_565(0xFF8080FF);
 | |
|         const unsigned twoColor = 0x807F1f1f;
 | |
|         SkColor blendColor = blend(oneColor, twoColor);
 | |
|         makePaint(&fOnePaint, oneColor);
 | |
|         makePaint(&fTwoPaint, twoColor);
 | |
|         makePaint(&fOpPaint[kDifference_SkPathOp], oneColor);
 | |
|         makePaint(&fOpPaint[kIntersect_SkPathOp], blendColor);
 | |
|         makePaint(&fOpPaint[kUnion_SkPathOp], ToolUtils::color_to_565(0xFFc0FFc0));
 | |
|         makePaint(&fOpPaint[kReverseDifference_SkPathOp], twoColor);
 | |
|         makePaint(&fOpPaint[kXOR_SkPathOp], ToolUtils::color_to_565(0xFFa0FFe0));
 | |
|         makePaint(&fOutlinePaint, 0xFF000000);
 | |
|         fOutlinePaint.setStyle(SkPaint::kStroke_Style);
 | |
|     }
 | |
| 
 | |
|     SkColor blend(SkColor one, SkColor two) {
 | |
|         SkBitmap temp;
 | |
|         temp.allocN32Pixels(1, 1);
 | |
|         SkCanvas canvas(temp);
 | |
|         canvas.drawColor(one);
 | |
|         canvas.drawColor(two);
 | |
|         void* pixels = temp.getPixels();
 | |
|         return *(SkColor*) pixels;
 | |
|     }
 | |
| 
 | |
|     void makePaint(SkPaint* paint, SkColor color) {
 | |
|         paint->setAntiAlias(true);
 | |
|         paint->setStyle(SkPaint::kFill_Style);
 | |
|         paint->setColor(color);
 | |
|     }
 | |
| 
 | |
|     SkString onShortName() override {
 | |
|         return SkString("pathopsinverse");
 | |
|     }
 | |
| 
 | |
|     SkISize onISize() override {
 | |
|         return SkISize::Make(1200, 900);
 | |
|     }
 | |
| 
 | |
|     void onDraw(SkCanvas* canvas) override {
 | |
|         SkPath one, two;
 | |
|         int yPos = 0;
 | |
|         for (int oneFill = 0; oneFill <= 1; ++oneFill) {
 | |
|             SkPathFillType oneF = oneFill ? SkPathFillType::kInverseEvenOdd
 | |
|                     : SkPathFillType::kEvenOdd;
 | |
|             for (int twoFill = 0; twoFill <= 1; ++twoFill) {
 | |
|                 SkPathFillType twoF = twoFill ? SkPathFillType::kInverseEvenOdd
 | |
|                         : SkPathFillType::kEvenOdd;
 | |
|                 one.reset();
 | |
|                 one.setFillType(oneF);
 | |
|                 one.addRect(10, 10, 70, 70);
 | |
|                 two.reset();
 | |
|                 two.setFillType(twoF);
 | |
|                 two.addRect(40, 40, 100, 100);
 | |
|                 canvas->save();
 | |
|                 canvas->translate(0, SkIntToScalar(yPos));
 | |
|                 canvas->clipRect(SkRect::MakeWH(110, 110), true);
 | |
|                 canvas->drawPath(one, fOnePaint);
 | |
|                 canvas->drawPath(one, fOutlinePaint);
 | |
|                 canvas->drawPath(two, fTwoPaint);
 | |
|                 canvas->drawPath(two, fOutlinePaint);
 | |
|                 canvas->restore();
 | |
|                 int xPos = 150;
 | |
|                 for (int op = kDifference_SkPathOp; op <= kReverseDifference_SkPathOp; ++op) {
 | |
|                     SkPath result;
 | |
|                     Op(one, two, (SkPathOp) op, &result);
 | |
|                     canvas->save();
 | |
|                     canvas->translate(SkIntToScalar(xPos), SkIntToScalar(yPos));
 | |
|                     canvas->clipRect(SkRect::MakeWH(110, 110), true);
 | |
|                     canvas->drawPath(result, fOpPaint[op]);
 | |
|                     canvas->drawPath(result, fOutlinePaint);
 | |
|                     canvas->restore();
 | |
|                     xPos += 150;
 | |
|                 }
 | |
|                 yPos += 150;
 | |
|             }
 | |
|         }
 | |
|     }
 | |
| 
 | |
| private:
 | |
|     SkPaint fOnePaint;
 | |
|     SkPaint fTwoPaint;
 | |
|     SkPaint fOutlinePaint;
 | |
|     SkPaint fOpPaint[kReverseDifference_SkPathOp - kDifference_SkPathOp + 1];
 | |
|     using INHERITED = GM;
 | |
| };
 | |
| 
 | |
| //////////////////////////////////////////////////////////////////////////////
 | |
| 
 | |
| DEF_GM( return new PathOpsInverseGM; )
 | |
| 
 | |
| }  // namespace skiagm
 | |
| 
 | |
| #include "include/pathops/SkPathOps.h"
 | |
| #include "include/utils/SkParsePath.h"
 | |
| 
 | |
| DEF_SIMPLE_GM(pathops_skbug_10155, canvas, 256, 256) {
 | |
|     const char* svgStr[] = {
 | |
|         "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",
 | |
|         "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"
 | |
|     };
 | |
| 
 | |
|     SkPath path[2], resultPath;
 | |
|     SkOpBuilder builder;
 | |
| 
 | |
|     for (int i = 0; i < 2; i++)
 | |
|     {
 | |
|         SkParsePath::FromSVGString(svgStr[i], &path[i]);
 | |
|         builder.add(path[i], kUnion_SkPathOp);
 | |
|     }
 | |
| 
 | |
|     builder.resolve(&resultPath);
 | |
| 
 | |
|     auto r = path[0].getBounds();
 | |
|     canvas->translate(30, 30);
 | |
|     canvas->scale(200 / r.width(), 200 / r.width());
 | |
|     canvas->translate(-r.fLeft, -r.fTop);
 | |
| 
 | |
|     SkPaint paint;
 | |
|     paint.setColor(SK_ColorRED);
 | |
|     paint.setAntiAlias(true);
 | |
|     paint.setStyle(SkPaint::kStroke_Style);
 | |
|     paint.setStrokeWidth(0);
 | |
| 
 | |
|     canvas->drawPath(path[0], paint);
 | |
|     canvas->drawPath(path[1], paint);
 | |
| 
 | |
|     // The blue draw should (nearly) overdraw all of the red (except where the two paths intersect)
 | |
|     paint.setColor(SK_ColorBLUE);
 | |
|     canvas->drawPath(resultPath, paint);
 | |
| }
 |