blob: ae9c4db31f22b1a9375333587f059fedebf97fc5 [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);
halcanary96fcdcc2015-08-27 07:41:13 -0700117 canvas->saveLayer(&bounds, nullptr);
robertphillips@google.com50a69a02012-07-12 13:48:46 +0000118 }
119
reed@google.coma8f60f22011-12-08 16:18:29 +0000120 for (int invBits = 0; invBits < 4; ++invBits) {
121 canvas->save();
bsalomon@google.com807cec42011-03-10 19:20:15 +0000122 for (size_t op = 0; op < SK_ARRAY_COUNT(gOps); ++op) {
reed@google.coma8f60f22011-12-08 16:18:29 +0000123 this->drawHairlines(canvas, path, clipA, clipB);
124
125 bool doInvA = SkToBool(invBits & 1);
126 bool doInvB = SkToBool(invBits & 2);
bsalomon@google.com807cec42011-03-10 19:20:15 +0000127 canvas->save();
128 // set clip
reed@google.coma8f60f22011-12-08 16:18:29 +0000129 clipA.setFillType(doInvA ? SkPath::kInverseEvenOdd_FillType :
130 SkPath::kEvenOdd_FillType);
131 clipB.setFillType(doInvB ? SkPath::kInverseEvenOdd_FillType :
132 SkPath::kEvenOdd_FillType);
reed66998382016-09-21 11:15:07 -0700133 canvas->clipPath(clipA, fDoAAClip);
reed@google.coma8f60f22011-12-08 16:18:29 +0000134 canvas->clipPath(clipB, gOps[op].fOp, fDoAAClip);
bsalomon@google.com807cec42011-03-10 19:20:15 +0000135
bsalomon6ae83cf2014-12-17 14:38:49 -0800136 // In the inverse case we need to prevent the draw from covering the whole
137 // canvas.
138 if (fInvertDraw) {
139 SkRect rectClip = clipA.getBounds();
140 rectClip.join(path.getBounds());
141 rectClip.join(path.getBounds());
142 rectClip.outset(5, 5);
143 canvas->clipRect(rectClip);
144 }
145
bsalomon@google.com807cec42011-03-10 19:20:15 +0000146 // draw path clipped
147 canvas->drawPath(path, pathPaint);
148 canvas->restore();
149
bsalomon@google.com807cec42011-03-10 19:20:15 +0000150
reed@google.coma8f60f22011-12-08 16:18:29 +0000151 SkScalar txtX = SkIntToScalar(45);
152 paint.setColor(gClipAColor);
153 const char* aTxt = doInvA ? "InvA " : "A ";
Cary Clark2a475ea2017-04-28 15:35:12 -0400154 canvas->drawString(aTxt, txtX, SkIntToScalar(220), paint);
bsalomon@google.com807cec42011-03-10 19:20:15 +0000155 txtX += paint.measureText(aTxt, strlen(aTxt));
156 paint.setColor(SK_ColorBLACK);
Cary Clark2a475ea2017-04-28 15:35:12 -0400157 canvas->drawString(gOps[op].fName, txtX, SkIntToScalar(220), paint);
bsalomon@google.com807cec42011-03-10 19:20:15 +0000158 txtX += paint.measureText(gOps[op].fName, strlen(gOps[op].fName));
reed@google.coma8f60f22011-12-08 16:18:29 +0000159 paint.setColor(gClipBColor);
160 const char* bTxt = doInvB ? "InvB " : "B ";
Cary Clark2a475ea2017-04-28 15:35:12 -0400161 canvas->drawString(bTxt, txtX, SkIntToScalar(220), paint);
bsalomon@google.com807cec42011-03-10 19:20:15 +0000162
163 canvas->translate(SkIntToScalar(250),0);
164 }
reed@google.coma8f60f22011-12-08 16:18:29 +0000165 canvas->restore();
166 canvas->translate(0, SkIntToScalar(250));
bsalomon@google.com807cec42011-03-10 19:20:15 +0000167 }
robertphillips@google.com50a69a02012-07-12 13:48:46 +0000168
robertphillips@google.com54bb7ab2012-07-13 14:55:25 +0000169 if (fDoSaveLayer) {
robertphillips@google.com50a69a02012-07-12 13:48:46 +0000170 canvas->restore();
171 }
bsalomon@google.com807cec42011-03-10 19:20:15 +0000172 }
173private:
reed@google.coma8f60f22011-12-08 16:18:29 +0000174 void drawHairlines(SkCanvas* canvas, const SkPath& path,
175 const SkPath& clipA, const SkPath& clipB) {
176 SkPaint paint;
177 paint.setAntiAlias(true);
178 paint.setStyle(SkPaint::kStroke_Style);
179 const SkAlpha fade = 0x33;
180
181 // draw path in hairline
182 paint.setColor(gPathColor); paint.setAlpha(fade);
183 canvas->drawPath(path, paint);
rmistry@google.comd6176b02012-08-23 18:14:13 +0000184
reed@google.coma8f60f22011-12-08 16:18:29 +0000185 // draw clips in hair line
186 paint.setColor(gClipAColor); paint.setAlpha(fade);
187 canvas->drawPath(clipA, paint);
188 paint.setColor(gClipBColor); paint.setAlpha(fade);
189 canvas->drawPath(clipB, paint);
190 }
191
bsalomon6ae83cf2014-12-17 14:38:49 -0800192 bool fDoAAClip;
193 bool fDoSaveLayer;
194 bool fInvertDraw;
195
bsalomon@google.com807cec42011-03-10 19:20:15 +0000196 typedef GM INHERITED;
197};
198
199//////////////////////////////////////////////////////////////////////////////
200
halcanary385fe4d2015-08-26 13:07:48 -0700201DEF_GM(return new ComplexClipGM(false, false, false);)
202DEF_GM(return new ComplexClipGM(false, false, true);)
203DEF_GM(return new ComplexClipGM(false, true, false);)
204DEF_GM(return new ComplexClipGM(false, true, true);)
205DEF_GM(return new ComplexClipGM(true, false, false);)
206DEF_GM(return new ComplexClipGM(true, false, true);)
207DEF_GM(return new ComplexClipGM(true, true, false);)
208DEF_GM(return new ComplexClipGM(true, true, true);)
bsalomon@google.com807cec42011-03-10 19:20:15 +0000209}