blob: f138ee0c4b94e3a094f427310f53ecbdad673dbb [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
45 SkISize onISize() { return SkISize::Make(1000, 950); }
46
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" },
76 {kUnion_SkClipOp, "U"},
77 {kXOR_SkClipOp, "X" },
78 {kReverseDifference_SkClipOp, "R"}
egdanieldf795032014-12-17 11:22:37 -080079 };
80
81 canvas->translate(SkIntToScalar(20), SkIntToScalar(20));
82 canvas->scale(3 * SK_Scalar1 / 4, 3 * SK_Scalar1 / 4);
83
84 SkPaint pathPaint;
85 pathPaint.setAntiAlias(true);
86 pathPaint.setColor(gPathColor);
87
88 for (int invA = 0; invA < 2; ++invA) {
89 for (int aaBits = 0; aaBits < 4; ++aaBits) {
90 canvas->save();
91 for (size_t op = 0; op < SK_ARRAY_COUNT(gOps); ++op) {
92 for (int invB = 0; invB < 2; ++invB) {
93 bool doAAA = SkToBool(aaBits & 1);
94 bool doAAB = SkToBool(aaBits & 2);
95 bool doInvA = SkToBool(invA);
96 bool doInvB = SkToBool(invB);
97 canvas->save();
98 // set clip
99 firstClip->setFillType(doInvA ? SkPath::kInverseEvenOdd_FillType :
100 SkPath::kEvenOdd_FillType);
101 secondClip->setFillType(doInvB ? SkPath::kInverseEvenOdd_FillType :
102 SkPath::kEvenOdd_FillType);
reed66998382016-09-21 11:15:07 -0700103 canvas->clipPath(*firstClip, doAAA);
egdanieldf795032014-12-17 11:22:37 -0800104 canvas->clipPath(*secondClip, gOps[op].fOp, doAAB);
105
106 // draw rect clipped
107 SkRect r = { 0, 0, 100, 100 };
108 canvas->drawRect(r, pathPaint);
109 canvas->restore();
110
111
112 SkScalar txtX = SkIntToScalar(10);
113 paint.setColor(SK_ColorBLACK);
114 SkString str;
115 str.printf("%s%s %s %s%s", doAAA ? "A" : "B",
116 doInvA ? "I" : "N",
117 gOps[op].fName,
118 doAAB ? "A" : "B",
119 doInvB ? "I" : "N");
120
Mike Reed4de2f1f2019-01-05 16:35:13 -0500121 canvas->drawString(str.c_str(), txtX, SkIntToScalar(130), font, paint);
egdanieldf795032014-12-17 11:22:37 -0800122 if (doInvB) {
123 canvas->translate(SkIntToScalar(150),0);
124 } else {
125 canvas->translate(SkIntToScalar(120),0);
126 }
127 }
128 }
129 canvas->restore();
130 canvas->translate(0, SkIntToScalar(150));
131 }
132 }
133 }
134
135private:
136 bool fDoSimpleClipFirst;
137
138 typedef GM INHERITED;
139};
140
141//////////////////////////////////////////////////////////////////////////////
142
143// Simple clip first
144DEF_GM( return new ComplexClip3GM(true); )
145// Complex clip first
146DEF_GM( return new ComplexClip3GM(false); )
147}