blob: 7c74956d9da7abc5be580999e22575ae27f146ee [file] [log] [blame]
caryclark@google.com7dfbb072013-04-22 14:37:05 +00001/*
2 * Copyright 2013 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
Mike Kleinc0bd9f92019-04-23 12:05:21 -05008#include "gm/gm.h"
9#include "include/core/SkBitmap.h"
Ben Wagner7fde8e12019-05-01 17:28:53 -040010#include "include/core/SkCanvas.h"
11#include "include/core/SkColor.h"
12#include "include/core/SkPaint.h"
Mike Kleinc0bd9f92019-04-23 12:05:21 -050013#include "include/core/SkPath.h"
14#include "include/core/SkRect.h"
Ben Wagner7fde8e12019-05-01 17:28:53 -040015#include "include/core/SkScalar.h"
16#include "include/core/SkSize.h"
17#include "include/core/SkString.h"
Mike Kleinc0bd9f92019-04-23 12:05:21 -050018#include "include/pathops/SkPathOps.h"
19#include "tools/ToolUtils.h"
caryclark@google.com7dfbb072013-04-22 14:37:05 +000020
21namespace skiagm {
22
23class PathOpsInverseGM : public GM {
24public:
25 PathOpsInverseGM() {
caryclark@google.com7dfbb072013-04-22 14:37:05 +000026 }
27
28protected:
mtklein36352bf2015-03-25 18:17:31 -070029 void onOnceBeforeDraw() override {
Mike Kleinea3f0142019-03-20 11:12:10 -050030 const unsigned oneColor = ToolUtils::color_to_565(0xFF8080FF);
caryclark@google.com7dfbb072013-04-22 14:37:05 +000031 const unsigned twoColor = 0x807F1f1f;
32 SkColor blendColor = blend(oneColor, twoColor);
caryclark@google.com4eedae62013-04-22 20:12:47 +000033 makePaint(&fOnePaint, oneColor);
34 makePaint(&fTwoPaint, twoColor);
caryclark54359292015-03-26 07:52:43 -070035 makePaint(&fOpPaint[kDifference_SkPathOp], oneColor);
36 makePaint(&fOpPaint[kIntersect_SkPathOp], blendColor);
Mike Kleinea3f0142019-03-20 11:12:10 -050037 makePaint(&fOpPaint[kUnion_SkPathOp], ToolUtils::color_to_565(0xFFc0FFc0));
caryclark54359292015-03-26 07:52:43 -070038 makePaint(&fOpPaint[kReverseDifference_SkPathOp], twoColor);
Mike Kleinea3f0142019-03-20 11:12:10 -050039 makePaint(&fOpPaint[kXOR_SkPathOp], ToolUtils::color_to_565(0xFFa0FFe0));
caryclark@google.com4eedae62013-04-22 20:12:47 +000040 makePaint(&fOutlinePaint, 0xFF000000);
41 fOutlinePaint.setStyle(SkPaint::kStroke_Style);
caryclark@google.com7dfbb072013-04-22 14:37:05 +000042 }
43
44 SkColor blend(SkColor one, SkColor two) {
45 SkBitmap temp;
reed@google.comeb9a46c2014-01-25 16:46:20 +000046 temp.allocN32Pixels(1, 1);
caryclark@google.com7dfbb072013-04-22 14:37:05 +000047 SkCanvas canvas(temp);
48 canvas.drawColor(one);
49 canvas.drawColor(two);
50 void* pixels = temp.getPixels();
51 return *(SkColor*) pixels;
52 }
53
54 void makePaint(SkPaint* paint, SkColor color) {
55 paint->setAntiAlias(true);
56 paint->setStyle(SkPaint::kFill_Style);
57 paint->setColor(color);
58 }
59
mtklein36352bf2015-03-25 18:17:31 -070060 SkString onShortName() override {
caryclark@google.com7dfbb072013-04-22 14:37:05 +000061 return SkString("pathopsinverse");
62 }
63
mtklein36352bf2015-03-25 18:17:31 -070064 SkISize onISize() override {
tfarinaf5393182014-06-09 23:59:03 -070065 return SkISize::Make(1200, 900);
caryclark@google.com7dfbb072013-04-22 14:37:05 +000066 }
67
mtklein36352bf2015-03-25 18:17:31 -070068 void onDraw(SkCanvas* canvas) override {
caryclark@google.com7dfbb072013-04-22 14:37:05 +000069 SkPath one, two;
70 int yPos = 0;
71 for (int oneFill = 0; oneFill <= 1; ++oneFill) {
Mike Reed7d34dc72019-11-26 12:17:17 -050072 SkPathFillType oneF = oneFill ? SkPathFillType::kInverseEvenOdd
73 : SkPathFillType::kEvenOdd;
caryclark@google.com7dfbb072013-04-22 14:37:05 +000074 for (int twoFill = 0; twoFill <= 1; ++twoFill) {
Mike Reed7d34dc72019-11-26 12:17:17 -050075 SkPathFillType twoF = twoFill ? SkPathFillType::kInverseEvenOdd
76 : SkPathFillType::kEvenOdd;
caryclark@google.com7dfbb072013-04-22 14:37:05 +000077 one.reset();
78 one.setFillType(oneF);
79 one.addRect(10, 10, 70, 70);
80 two.reset();
81 two.setFillType(twoF);
82 two.addRect(40, 40, 100, 100);
83 canvas->save();
84 canvas->translate(0, SkIntToScalar(yPos));
reed66998382016-09-21 11:15:07 -070085 canvas->clipRect(SkRect::MakeWH(110, 110), true);
caryclark@google.com4eedae62013-04-22 20:12:47 +000086 canvas->drawPath(one, fOnePaint);
87 canvas->drawPath(one, fOutlinePaint);
88 canvas->drawPath(two, fTwoPaint);
89 canvas->drawPath(two, fOutlinePaint);
caryclark@google.com7dfbb072013-04-22 14:37:05 +000090 canvas->restore();
91 int xPos = 150;
caryclark54359292015-03-26 07:52:43 -070092 for (int op = kDifference_SkPathOp; op <= kReverseDifference_SkPathOp; ++op) {
caryclark@google.com7dfbb072013-04-22 14:37:05 +000093 SkPath result;
94 Op(one, two, (SkPathOp) op, &result);
95 canvas->save();
96 canvas->translate(SkIntToScalar(xPos), SkIntToScalar(yPos));
reed66998382016-09-21 11:15:07 -070097 canvas->clipRect(SkRect::MakeWH(110, 110), true);
caryclark@google.com4eedae62013-04-22 20:12:47 +000098 canvas->drawPath(result, fOpPaint[op]);
99 canvas->drawPath(result, fOutlinePaint);
caryclark@google.com7dfbb072013-04-22 14:37:05 +0000100 canvas->restore();
101 xPos += 150;
102 }
103 yPos += 150;
104 }
105 }
106 }
107
108private:
caryclark@google.com4eedae62013-04-22 20:12:47 +0000109 SkPaint fOnePaint;
110 SkPaint fTwoPaint;
111 SkPaint fOutlinePaint;
caryclark54359292015-03-26 07:52:43 -0700112 SkPaint fOpPaint[kReverseDifference_SkPathOp - kDifference_SkPathOp + 1];
caryclark@google.com7dfbb072013-04-22 14:37:05 +0000113 typedef GM INHERITED;
114};
115
116//////////////////////////////////////////////////////////////////////////////
117
Hal Canarye964c182019-01-23 10:22:01 -0500118DEF_GM( return new PathOpsInverseGM; )
caryclark@google.com7dfbb072013-04-22 14:37:05 +0000119
120}
Mike Reed1174cf82020-04-20 14:01:17 -0400121
122#include "include/pathops/SkPathOps.h"
123#include "include/utils/SkParsePath.h"
124
125DEF_SIMPLE_GM(pathops_skbug_10155, canvas, 256, 256) {
126 const char* svgStr[] = {
127 "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",
128 "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"
129 };
130
131 SkPath path[2], resultPath;
132 SkOpBuilder builder;
133
134 for (int i = 0; i < 2; i++)
135 {
136 SkParsePath::FromSVGString(svgStr[i], &path[i]);
137 builder.add(path[i], kUnion_SkPathOp);
138 }
139
140 builder.resolve(&resultPath);
141
142 auto r = path[0].getBounds();
143 canvas->translate(30, 30);
144 canvas->scale(200 / r.width(), 200 / r.width());
145 canvas->translate(-r.fLeft, -r.fTop);
146
147 SkPaint paint;
148 paint.setColor(SK_ColorRED);
149 paint.setAntiAlias(true);
150 paint.setStyle(SkPaint::kStroke_Style);
151 paint.setStrokeWidth(0);
152
153 canvas->drawPath(path[0], paint);
154 canvas->drawPath(path[1], paint);
155
156 // The blue draw should (nearly) overdraw all of the red (except where the two paths intersect)
157 paint.setColor(SK_ColorBLUE);
158 canvas->drawPath(resultPath, paint);
159}