blob: f95fa2e9d428bf37158c58f31c347abdf697f6f5 [file] [log] [blame]
egdanieldf795032014-12-17 11:22:37 -08001/*
2 * Copyright 2014 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 */
Ben Wagner7fde8e12019-05-01 17:28:53 -04007
Mike Kleinc0bd9f92019-04-23 12:05:21 -05008#include "gm/gm.h"
9#include "include/core/SkCanvas.h"
Ben Wagner7fde8e12019-05-01 17:28:53 -040010#include "include/core/SkClipOp.h"
11#include "include/core/SkColor.h"
12#include "include/core/SkFont.h"
13#include "include/core/SkPaint.h"
Mike Kleinc0bd9f92019-04-23 12:05:21 -050014#include "include/core/SkPath.h"
Ben Wagner7fde8e12019-05-01 17:28:53 -040015#include "include/core/SkRect.h"
16#include "include/core/SkScalar.h"
17#include "include/core/SkSize.h"
18#include "include/core/SkString.h"
19#include "include/core/SkTypeface.h"
20#include "include/core/SkTypes.h"
21#include "src/core/SkClipOpPriv.h"
Mike Kleinc0bd9f92019-04-23 12:05:21 -050022#include "tools/ToolUtils.h"
egdanieldf795032014-12-17 11:22:37 -080023
Ben Wagnerf08d1d02018-06-18 15:11:00 -040024#include <utility>
25
egdanieldf795032014-12-17 11:22:37 -080026namespace skiagm {
27
mtkleindbfd7ab2016-09-01 11:24:54 -070028constexpr SkColor gPathColor = SK_ColorYELLOW;
egdanieldf795032014-12-17 11:22:37 -080029
30class ComplexClip3GM : public GM {
31public:
32 ComplexClip3GM(bool doSimpleClipFirst)
33 : fDoSimpleClipFirst(doSimpleClipFirst) {
Mike Kleind46dce32018-08-16 10:17:03 -040034 this->setBGColor(0xFFDDDDDD);
egdanieldf795032014-12-17 11:22:37 -080035 }
36
37protected:
egdanieldf795032014-12-17 11:22:37 -080038
39 SkString onShortName() {
40 SkString str;
41 str.printf("complexclip3_%s", fDoSimpleClipFirst ? "simple" : "complex");
42 return str;
halcanary9d524f22016-03-29 09:03:52 -070043 }
egdanieldf795032014-12-17 11:22:37 -080044
Michael Ludwig9689e392020-05-05 10:56:42 -040045 SkISize onISize() { return SkISize::Make(400, 950); }
egdanieldf795032014-12-17 11:22:37 -080046
47 virtual void onDraw(SkCanvas* canvas) {
48 SkPath clipSimple;
49 clipSimple.addCircle(SkIntToScalar(70), SkIntToScalar(50), SkIntToScalar(20));
50
51 SkRect r1 = { 10, 20, 70, 80 };
52 SkPath clipComplex;
53 clipComplex.moveTo(SkIntToScalar(40), SkIntToScalar(50));
54 clipComplex.arcTo(r1, SkIntToScalar(30), SkIntToScalar(300), false);
55 clipComplex.close();
56
57 SkPath* firstClip = &clipSimple;
58 SkPath* secondClip = &clipComplex;
59
60 if (!fDoSimpleClipFirst) {
Ben Wagnerf08d1d02018-06-18 15:11:00 -040061 using std::swap;
62 swap(firstClip, secondClip);
egdanieldf795032014-12-17 11:22:37 -080063 }
64
65 SkPaint paint;
66 paint.setAntiAlias(true);
Mike Reed4de2f1f2019-01-05 16:35:13 -050067
Mike Kleinea3f0142019-03-20 11:12:10 -050068 SkFont font(ToolUtils::create_portable_typeface(), 20);
egdanieldf795032014-12-17 11:22:37 -080069
mtkleindbfd7ab2016-09-01 11:24:54 -070070 constexpr struct {
Mike Reedc1f77742016-12-09 09:00:50 -050071 SkClipOp fOp;
72 const char* fName;
egdanieldf795032014-12-17 11:22:37 -080073 } gOps[] = {
Mike Reedc1f77742016-12-09 09:00:50 -050074 {kIntersect_SkClipOp, "I"},
75 {kDifference_SkClipOp, "D" },
egdanieldf795032014-12-17 11:22:37 -080076 };
77
78 canvas->translate(SkIntToScalar(20), SkIntToScalar(20));
79 canvas->scale(3 * SK_Scalar1 / 4, 3 * SK_Scalar1 / 4);
80
81 SkPaint pathPaint;
82 pathPaint.setAntiAlias(true);
83 pathPaint.setColor(gPathColor);
84
85 for (int invA = 0; invA < 2; ++invA) {
86 for (int aaBits = 0; aaBits < 4; ++aaBits) {
87 canvas->save();
88 for (size_t op = 0; op < SK_ARRAY_COUNT(gOps); ++op) {
89 for (int invB = 0; invB < 2; ++invB) {
90 bool doAAA = SkToBool(aaBits & 1);
91 bool doAAB = SkToBool(aaBits & 2);
92 bool doInvA = SkToBool(invA);
93 bool doInvB = SkToBool(invB);
94 canvas->save();
95 // set clip
Mike Reed7d34dc72019-11-26 12:17:17 -050096 firstClip->setFillType(doInvA ? SkPathFillType::kInverseEvenOdd :
97 SkPathFillType::kEvenOdd);
98 secondClip->setFillType(doInvB ? SkPathFillType::kInverseEvenOdd :
99 SkPathFillType::kEvenOdd);
reed66998382016-09-21 11:15:07 -0700100 canvas->clipPath(*firstClip, doAAA);
egdanieldf795032014-12-17 11:22:37 -0800101 canvas->clipPath(*secondClip, gOps[op].fOp, doAAB);
102
103 // draw rect clipped
104 SkRect r = { 0, 0, 100, 100 };
105 canvas->drawRect(r, pathPaint);
106 canvas->restore();
107
108
109 SkScalar txtX = SkIntToScalar(10);
110 paint.setColor(SK_ColorBLACK);
111 SkString str;
112 str.printf("%s%s %s %s%s", doAAA ? "A" : "B",
113 doInvA ? "I" : "N",
114 gOps[op].fName,
115 doAAB ? "A" : "B",
116 doInvB ? "I" : "N");
117
Mike Reed4de2f1f2019-01-05 16:35:13 -0500118 canvas->drawString(str.c_str(), txtX, SkIntToScalar(130), font, paint);
egdanieldf795032014-12-17 11:22:37 -0800119 if (doInvB) {
120 canvas->translate(SkIntToScalar(150),0);
121 } else {
122 canvas->translate(SkIntToScalar(120),0);
123 }
124 }
125 }
126 canvas->restore();
127 canvas->translate(0, SkIntToScalar(150));
128 }
129 }
130 }
131
132private:
133 bool fDoSimpleClipFirst;
134
135 typedef GM INHERITED;
136};
137
138//////////////////////////////////////////////////////////////////////////////
139
140// Simple clip first
141DEF_GM( return new ComplexClip3GM(true); )
142// Complex clip first
143DEF_GM( return new ComplexClip3GM(false); )
144}