blob: 897c41ea2c0bbc7c1bd91db907f9b845086af8c2 [file] [log] [blame]
epoger@google.comec3ed6a2011-07-28 14:26:00 +00001/*
2 * Copyright 2011 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 */
Mike Reedebfce6d2016-12-12 10:02:12 -05007
bsalomon@google.com807cec42011-03-10 19:20:15 +00008#include "gm.h"
Mike Klein33d20552017-03-22 13:47:51 -04009#include "sk_tool_utils.h"
bsalomon@google.com807cec42011-03-10 19:20:15 +000010#include "SkCanvas.h"
bsalomon@google.com807cec42011-03-10 19:20:15 +000011#include "SkPath.h"
bsalomon@google.com807cec42011-03-10 19:20:15 +000012
13namespace skiagm {
14
mtkleindbfd7ab2016-09-01 11:24:54 -070015constexpr SkColor gPathColor = SK_ColorBLACK;
16constexpr SkColor gClipAColor = SK_ColorBLUE;
17constexpr SkColor gClipBColor = SK_ColorRED;
reed@google.coma8f60f22011-12-08 16:18:29 +000018
bsalomon@google.com807cec42011-03-10 19:20:15 +000019class ComplexClipGM : public GM {
20public:
bsalomon6ae83cf2014-12-17 14:38:49 -080021 ComplexClipGM(bool aaclip, bool saveLayer, bool invertDraw)
robertphillips@google.com50a69a02012-07-12 13:48:46 +000022 : fDoAAClip(aaclip)
bsalomon6ae83cf2014-12-17 14:38:49 -080023 , fDoSaveLayer(saveLayer)
24 , fInvertDraw(invertDraw) {
caryclarkceb9f3b2015-06-12 10:00:11 -070025 this->setBGColor(0xFFDEDFDE);
bsalomon@google.com807cec42011-03-10 19:20:15 +000026 }
27
28protected:
commit-bot@chromium.orga90c6802014-04-30 13:20:45 +000029
bsalomon@google.com807cec42011-03-10 19:20:15 +000030
31 SkString onShortName() {
reed@google.coma8f60f22011-12-08 16:18:29 +000032 SkString str;
bsalomon6ae83cf2014-12-17 14:38:49 -080033 str.printf("complexclip_%s%s%s",
robertphillips@google.com50a69a02012-07-12 13:48:46 +000034 fDoAAClip ? "aa" : "bw",
bsalomon6ae83cf2014-12-17 14:38:49 -080035 fDoSaveLayer ? "_layer" : "",
36 fInvertDraw ? "_invert" : "");
reed@google.coma8f60f22011-12-08 16:18:29 +000037 return str;
bsalomon@google.com807cec42011-03-10 19:20:15 +000038 }
39
tfarinaf5393182014-06-09 23:59:03 -070040 SkISize onISize() { return SkISize::Make(970, 780); }
bsalomon@google.com807cec42011-03-10 19:20:15 +000041
bsalomon@google.com807cec42011-03-10 19:20:15 +000042 virtual void onDraw(SkCanvas* canvas) {
43 SkPath path;
44 path.moveTo(SkIntToScalar(0), SkIntToScalar(50));
45 path.quadTo(SkIntToScalar(0), SkIntToScalar(0), SkIntToScalar(50), SkIntToScalar(0));
46 path.lineTo(SkIntToScalar(175), SkIntToScalar(0));
47 path.quadTo(SkIntToScalar(200), SkIntToScalar(0), SkIntToScalar(200), SkIntToScalar(25));
48 path.lineTo(SkIntToScalar(200), SkIntToScalar(150));
49 path.quadTo(SkIntToScalar(200), SkIntToScalar(200), SkIntToScalar(150), SkIntToScalar(200));
50 path.lineTo(SkIntToScalar(0), SkIntToScalar(200));
51 path.close();
52 path.moveTo(SkIntToScalar(50), SkIntToScalar(50));
53 path.lineTo(SkIntToScalar(150), SkIntToScalar(50));
54 path.lineTo(SkIntToScalar(150), SkIntToScalar(125));
55 path.quadTo(SkIntToScalar(150), SkIntToScalar(150), SkIntToScalar(125), SkIntToScalar(150));
56 path.lineTo(SkIntToScalar(50), SkIntToScalar(150));
57 path.close();
bsalomon6ae83cf2014-12-17 14:38:49 -080058 if (fInvertDraw) {
59 path.setFillType(SkPath::kInverseEvenOdd_FillType);
60 } else {
61 path.setFillType(SkPath::kEvenOdd_FillType);
62 }
bsalomon@google.com807cec42011-03-10 19:20:15 +000063 SkPaint pathPaint;
64 pathPaint.setAntiAlias(true);
reed@google.coma8f60f22011-12-08 16:18:29 +000065 pathPaint.setColor(gPathColor);
bsalomon@google.com807cec42011-03-10 19:20:15 +000066
67 SkPath clipA;
68 clipA.moveTo(SkIntToScalar(10), SkIntToScalar(20));
69 clipA.lineTo(SkIntToScalar(165), SkIntToScalar(22));
70 clipA.lineTo(SkIntToScalar(70), SkIntToScalar(105));
71 clipA.lineTo(SkIntToScalar(165), SkIntToScalar(177));
72 clipA.lineTo(SkIntToScalar(-5), SkIntToScalar(180));
73 clipA.close();
bsalomon@google.com807cec42011-03-10 19:20:15 +000074
75 SkPath clipB;
76 clipB.moveTo(SkIntToScalar(40), SkIntToScalar(10));
77 clipB.lineTo(SkIntToScalar(190), SkIntToScalar(15));
78 clipB.lineTo(SkIntToScalar(195), SkIntToScalar(190));
79 clipB.lineTo(SkIntToScalar(40), SkIntToScalar(185));
80 clipB.lineTo(SkIntToScalar(155), SkIntToScalar(100));
81 clipB.close();
bsalomon@google.com807cec42011-03-10 19:20:15 +000082
bsalomon@google.com807cec42011-03-10 19:20:15 +000083 SkPaint paint;
84 paint.setAntiAlias(true);
caryclark1818acb2015-07-24 12:09:25 -070085 sk_tool_utils::set_portable_typeface(&paint);
reed@google.coma8f60f22011-12-08 16:18:29 +000086 paint.setTextSize(SkIntToScalar(20));
bsalomon@google.com807cec42011-03-10 19:20:15 +000087
mtkleindbfd7ab2016-09-01 11:24:54 -070088 constexpr struct {
Mike Reedc1f77742016-12-09 09:00:50 -050089 SkClipOp fOp;
reed73603f32016-09-20 08:42:38 -070090 const char* fName;
bsalomon@google.com807cec42011-03-10 19:20:15 +000091 } gOps[] = { //extra spaces in names for measureText
Mike Reedc1f77742016-12-09 09:00:50 -050092 {kIntersect_SkClipOp, "Isect "},
93 {kDifference_SkClipOp, "Diff " },
94 {kUnion_SkClipOp, "Union "},
95 {kXOR_SkClipOp, "Xor " },
96 {kReverseDifference_SkClipOp, "RDiff "}
bsalomon@google.com807cec42011-03-10 19:20:15 +000097 };
98
reed@google.coma8f60f22011-12-08 16:18:29 +000099 canvas->translate(SkIntToScalar(20), SkIntToScalar(20));
bsalomon@google.com807cec42011-03-10 19:20:15 +0000100 canvas->scale(3 * SK_Scalar1 / 4, 3 * SK_Scalar1 / 4);
bsalomon@google.com807cec42011-03-10 19:20:15 +0000101
robertphillips@google.com54bb7ab2012-07-13 14:55:25 +0000102 if (fDoSaveLayer) {
103 // We want the layer to appear symmetric relative to actual
104 // device boundaries so we need to "undo" the effect of the
105 // scale and translate
106 SkRect bounds = SkRect::MakeLTRB(
commit-bot@chromium.org4b413c82013-11-25 19:44:07 +0000107 4.0f/3.0f * -20,
108 4.0f/3.0f * -20,
109 4.0f/3.0f * (this->getISize().fWidth - 20),
110 4.0f/3.0f * (this->getISize().fHeight - 20));
robertphillips@google.com54bb7ab2012-07-13 14:55:25 +0000111
112 bounds.inset(SkIntToScalar(100), SkIntToScalar(100));
robertphillips@google.com50a69a02012-07-12 13:48:46 +0000113 SkPaint boundPaint;
114 boundPaint.setColor(SK_ColorRED);
115 boundPaint.setStyle(SkPaint::kStroke_Style);
116 canvas->drawRect(bounds, boundPaint);
Ben Wagner788a2dc2018-05-09 13:23:38 -0400117 canvas->clipRect(bounds);
halcanary96fcdcc2015-08-27 07:41:13 -0700118 canvas->saveLayer(&bounds, nullptr);
robertphillips@google.com50a69a02012-07-12 13:48:46 +0000119 }
120
reed@google.coma8f60f22011-12-08 16:18:29 +0000121 for (int invBits = 0; invBits < 4; ++invBits) {
122 canvas->save();
bsalomon@google.com807cec42011-03-10 19:20:15 +0000123 for (size_t op = 0; op < SK_ARRAY_COUNT(gOps); ++op) {
reed@google.coma8f60f22011-12-08 16:18:29 +0000124 this->drawHairlines(canvas, path, clipA, clipB);
125
126 bool doInvA = SkToBool(invBits & 1);
127 bool doInvB = SkToBool(invBits & 2);
bsalomon@google.com807cec42011-03-10 19:20:15 +0000128 canvas->save();
129 // set clip
reed@google.coma8f60f22011-12-08 16:18:29 +0000130 clipA.setFillType(doInvA ? SkPath::kInverseEvenOdd_FillType :
131 SkPath::kEvenOdd_FillType);
132 clipB.setFillType(doInvB ? SkPath::kInverseEvenOdd_FillType :
133 SkPath::kEvenOdd_FillType);
reed66998382016-09-21 11:15:07 -0700134 canvas->clipPath(clipA, fDoAAClip);
reed@google.coma8f60f22011-12-08 16:18:29 +0000135 canvas->clipPath(clipB, gOps[op].fOp, fDoAAClip);
bsalomon@google.com807cec42011-03-10 19:20:15 +0000136
bsalomon6ae83cf2014-12-17 14:38:49 -0800137 // In the inverse case we need to prevent the draw from covering the whole
138 // canvas.
139 if (fInvertDraw) {
140 SkRect rectClip = clipA.getBounds();
141 rectClip.join(path.getBounds());
142 rectClip.join(path.getBounds());
143 rectClip.outset(5, 5);
144 canvas->clipRect(rectClip);
145 }
146
bsalomon@google.com807cec42011-03-10 19:20:15 +0000147 // draw path clipped
148 canvas->drawPath(path, pathPaint);
149 canvas->restore();
150
bsalomon@google.com807cec42011-03-10 19:20:15 +0000151
reed@google.coma8f60f22011-12-08 16:18:29 +0000152 SkScalar txtX = SkIntToScalar(45);
153 paint.setColor(gClipAColor);
154 const char* aTxt = doInvA ? "InvA " : "A ";
Cary Clark2a475ea2017-04-28 15:35:12 -0400155 canvas->drawString(aTxt, txtX, SkIntToScalar(220), paint);
bsalomon@google.com807cec42011-03-10 19:20:15 +0000156 txtX += paint.measureText(aTxt, strlen(aTxt));
157 paint.setColor(SK_ColorBLACK);
Cary Clark2a475ea2017-04-28 15:35:12 -0400158 canvas->drawString(gOps[op].fName, txtX, SkIntToScalar(220), paint);
bsalomon@google.com807cec42011-03-10 19:20:15 +0000159 txtX += paint.measureText(gOps[op].fName, strlen(gOps[op].fName));
reed@google.coma8f60f22011-12-08 16:18:29 +0000160 paint.setColor(gClipBColor);
161 const char* bTxt = doInvB ? "InvB " : "B ";
Cary Clark2a475ea2017-04-28 15:35:12 -0400162 canvas->drawString(bTxt, txtX, SkIntToScalar(220), paint);
bsalomon@google.com807cec42011-03-10 19:20:15 +0000163
164 canvas->translate(SkIntToScalar(250),0);
165 }
reed@google.coma8f60f22011-12-08 16:18:29 +0000166 canvas->restore();
167 canvas->translate(0, SkIntToScalar(250));
bsalomon@google.com807cec42011-03-10 19:20:15 +0000168 }
robertphillips@google.com50a69a02012-07-12 13:48:46 +0000169
robertphillips@google.com54bb7ab2012-07-13 14:55:25 +0000170 if (fDoSaveLayer) {
robertphillips@google.com50a69a02012-07-12 13:48:46 +0000171 canvas->restore();
172 }
bsalomon@google.com807cec42011-03-10 19:20:15 +0000173 }
174private:
reed@google.coma8f60f22011-12-08 16:18:29 +0000175 void drawHairlines(SkCanvas* canvas, const SkPath& path,
176 const SkPath& clipA, const SkPath& clipB) {
177 SkPaint paint;
178 paint.setAntiAlias(true);
179 paint.setStyle(SkPaint::kStroke_Style);
180 const SkAlpha fade = 0x33;
181
182 // draw path in hairline
183 paint.setColor(gPathColor); paint.setAlpha(fade);
184 canvas->drawPath(path, paint);
rmistry@google.comd6176b02012-08-23 18:14:13 +0000185
reed@google.coma8f60f22011-12-08 16:18:29 +0000186 // draw clips in hair line
187 paint.setColor(gClipAColor); paint.setAlpha(fade);
188 canvas->drawPath(clipA, paint);
189 paint.setColor(gClipBColor); paint.setAlpha(fade);
190 canvas->drawPath(clipB, paint);
191 }
192
bsalomon6ae83cf2014-12-17 14:38:49 -0800193 bool fDoAAClip;
194 bool fDoSaveLayer;
195 bool fInvertDraw;
196
bsalomon@google.com807cec42011-03-10 19:20:15 +0000197 typedef GM INHERITED;
198};
199
200//////////////////////////////////////////////////////////////////////////////
201
halcanary385fe4d2015-08-26 13:07:48 -0700202DEF_GM(return new ComplexClipGM(false, false, false);)
203DEF_GM(return new ComplexClipGM(false, false, true);)
204DEF_GM(return new ComplexClipGM(false, true, false);)
205DEF_GM(return new ComplexClipGM(false, true, true);)
206DEF_GM(return new ComplexClipGM(true, false, false);)
207DEF_GM(return new ComplexClipGM(true, false, true);)
208DEF_GM(return new ComplexClipGM(true, true, false);)
209DEF_GM(return new ComplexClipGM(true, true, true);)
bsalomon@google.com807cec42011-03-10 19:20:15 +0000210}