• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
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 
8 #include "gm/gm.h"
9 #include "include/core/SkBitmap.h"
10 #include "include/core/SkCanvas.h"
11 #include "include/core/SkColor.h"
12 #include "include/core/SkPaint.h"
13 #include "include/core/SkPath.h"
14 #include "include/core/SkRect.h"
15 #include "include/core/SkScalar.h"
16 #include "include/core/SkSize.h"
17 #include "include/core/SkString.h"
18 #include "include/pathops/SkPathOps.h"
19 #include "tools/ToolUtils.h"
20 
21 namespace skiagm {
22 
23 class PathOpsInverseGM : public GM {
24 public:
PathOpsInverseGM()25     PathOpsInverseGM() {
26     }
27 
28 protected:
onOnceBeforeDraw()29     void onOnceBeforeDraw() override {
30         const unsigned oneColor   = ToolUtils::color_to_565(0xFF8080FF);
31         const unsigned twoColor = 0x807F1f1f;
32         SkColor blendColor = blend(oneColor, twoColor);
33         makePaint(&fOnePaint, oneColor);
34         makePaint(&fTwoPaint, twoColor);
35         makePaint(&fOpPaint[kDifference_SkPathOp], oneColor);
36         makePaint(&fOpPaint[kIntersect_SkPathOp], blendColor);
37         makePaint(&fOpPaint[kUnion_SkPathOp], ToolUtils::color_to_565(0xFFc0FFc0));
38         makePaint(&fOpPaint[kReverseDifference_SkPathOp], twoColor);
39         makePaint(&fOpPaint[kXOR_SkPathOp], ToolUtils::color_to_565(0xFFa0FFe0));
40         makePaint(&fOutlinePaint, 0xFF000000);
41         fOutlinePaint.setStyle(SkPaint::kStroke_Style);
42     }
43 
blend(SkColor one,SkColor two)44     SkColor blend(SkColor one, SkColor two) {
45         SkBitmap temp;
46         temp.allocN32Pixels(1, 1);
47         SkCanvas canvas(temp);
48         canvas.drawColor(one);
49         canvas.drawColor(two);
50         void* pixels = temp.getPixels();
51         return *(SkColor*) pixels;
52     }
53 
makePaint(SkPaint * paint,SkColor color)54     void makePaint(SkPaint* paint, SkColor color) {
55         paint->setAntiAlias(true);
56         paint->setStyle(SkPaint::kFill_Style);
57         paint->setColor(color);
58     }
59 
onShortName()60     SkString onShortName() override {
61         return SkString("pathopsinverse");
62     }
63 
onISize()64     SkISize onISize() override {
65         return SkISize::Make(1200, 900);
66     }
67 
onDraw(SkCanvas * canvas)68     void onDraw(SkCanvas* canvas) override {
69         SkPath one, two;
70         int yPos = 0;
71         for (int oneFill = 0; oneFill <= 1; ++oneFill) {
72             SkPathFillType oneF = oneFill ? SkPathFillType::kInverseEvenOdd
73                     : SkPathFillType::kEvenOdd;
74             for (int twoFill = 0; twoFill <= 1; ++twoFill) {
75                 SkPathFillType twoF = twoFill ? SkPathFillType::kInverseEvenOdd
76                         : SkPathFillType::kEvenOdd;
77                 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));
85                 canvas->clipRect(SkRect::MakeWH(110, 110), true);
86                 canvas->drawPath(one, fOnePaint);
87                 canvas->drawPath(one, fOutlinePaint);
88                 canvas->drawPath(two, fTwoPaint);
89                 canvas->drawPath(two, fOutlinePaint);
90                 canvas->restore();
91                 int xPos = 150;
92                 for (int op = kDifference_SkPathOp; op <= kReverseDifference_SkPathOp; ++op) {
93                     SkPath result;
94                     Op(one, two, (SkPathOp) op, &result);
95                     canvas->save();
96                     canvas->translate(SkIntToScalar(xPos), SkIntToScalar(yPos));
97                     canvas->clipRect(SkRect::MakeWH(110, 110), true);
98                     canvas->drawPath(result, fOpPaint[op]);
99                     canvas->drawPath(result, fOutlinePaint);
100                     canvas->restore();
101                     xPos += 150;
102                 }
103                 yPos += 150;
104             }
105         }
106     }
107 
108 private:
109     SkPaint fOnePaint;
110     SkPaint fTwoPaint;
111     SkPaint fOutlinePaint;
112     SkPaint fOpPaint[kReverseDifference_SkPathOp - kDifference_SkPathOp + 1];
113     using INHERITED = GM;
114 };
115 
116 //////////////////////////////////////////////////////////////////////////////
117 
118 DEF_GM( return new PathOpsInverseGM; )
119 
120 }  // namespace skiagm
121 
122 #include "include/pathops/SkPathOps.h"
123 #include "include/utils/SkParsePath.h"
124 
125 DEF_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 }
160