Sat, 03 Jan 2015 20:18:00 +0100
Conditionally enable double key logic according to:
private browsing mode or privacy.thirdparty.isolate preference and
implement in GetCookieStringCommon and FindCookie where it counts...
With some reservations of how to convince FindCookie users to test
condition and pass a nullptr when disabling double key logic.
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 #ifndef SkOpContour_DEFINED
8 #define SkOpContour_DEFINED
10 #include "SkOpSegment.h"
11 #include "SkTArray.h"
13 class SkIntersections;
14 class SkOpContour;
15 class SkPathWriter;
17 struct SkCoincidence {
18 SkOpContour* fOther;
19 int fSegments[2];
20 double fTs[2][2];
21 SkPoint fPts[2];
22 };
24 class SkOpContour {
25 public:
26 SkOpContour() {
27 reset();
28 #ifdef SK_DEBUG
29 fID = ++SkPathOpsDebug::gContourID;
30 #endif
31 }
33 bool operator<(const SkOpContour& rh) const {
34 return fBounds.fTop == rh.fBounds.fTop
35 ? fBounds.fLeft < rh.fBounds.fLeft
36 : fBounds.fTop < rh.fBounds.fTop;
37 }
39 bool addCoincident(int index, SkOpContour* other, int otherIndex,
40 const SkIntersections& ts, bool swap);
41 void addCoincidentPoints();
43 void addCross(const SkOpContour* crosser) {
44 #ifdef DEBUG_CROSS
45 for (int index = 0; index < fCrosses.count(); ++index) {
46 SkASSERT(fCrosses[index] != crosser);
47 }
48 #endif
49 fCrosses.push_back(crosser);
50 }
52 void addCubic(const SkPoint pts[4]) {
53 fSegments.push_back().addCubic(pts, fOperand, fXor);
54 fContainsCurves = fContainsCubics = true;
55 }
57 int addLine(const SkPoint pts[2]) {
58 fSegments.push_back().addLine(pts, fOperand, fXor);
59 return fSegments.count();
60 }
62 void addOtherT(int segIndex, int tIndex, double otherT, int otherIndex) {
63 fSegments[segIndex].addOtherT(tIndex, otherT, otherIndex);
64 }
66 bool addPartialCoincident(int index, SkOpContour* other, int otherIndex,
67 const SkIntersections& ts, int ptIndex, bool swap);
69 int addQuad(const SkPoint pts[3]) {
70 fSegments.push_back().addQuad(pts, fOperand, fXor);
71 fContainsCurves = true;
72 return fSegments.count();
73 }
75 int addT(int segIndex, SkOpContour* other, int otherIndex, const SkPoint& pt, double newT) {
76 setContainsIntercepts();
77 return fSegments[segIndex].addT(&other->fSegments[otherIndex], pt, newT);
78 }
80 int addSelfT(int segIndex, SkOpContour* other, int otherIndex, const SkPoint& pt, double newT) {
81 setContainsIntercepts();
82 return fSegments[segIndex].addSelfT(&other->fSegments[otherIndex], pt, newT);
83 }
85 const SkPathOpsBounds& bounds() const {
86 return fBounds;
87 }
89 void calcCoincidentWinding();
90 void calcPartialCoincidentWinding();
92 void checkEnds() {
93 if (!fContainsCurves) {
94 return;
95 }
96 int segmentCount = fSegments.count();
97 for (int sIndex = 0; sIndex < segmentCount; ++sIndex) {
98 SkOpSegment* segment = &fSegments[sIndex];
99 if (segment->verb() == SkPath::kLine_Verb) {
100 continue;
101 }
102 if (segment->done()) {
103 continue; // likely coincident, nothing to do
104 }
105 segment->checkEnds();
106 }
107 }
109 // if same point has different T values, choose a common T
110 void checkTiny() {
111 int segmentCount = fSegments.count();
112 if (segmentCount <= 2) {
113 return;
114 }
115 for (int sIndex = 0; sIndex < segmentCount; ++sIndex) {
116 fSegments[sIndex].checkTiny();
117 }
118 }
120 void complete() {
121 setBounds();
122 fContainsIntercepts = false;
123 }
125 bool containsCubics() const {
126 return fContainsCubics;
127 }
129 bool crosses(const SkOpContour* crosser) const {
130 for (int index = 0; index < fCrosses.count(); ++index) {
131 if (fCrosses[index] == crosser) {
132 return true;
133 }
134 }
135 return false;
136 }
138 bool done() const {
139 return fDone;
140 }
142 const SkPoint& end() const {
143 const SkOpSegment& segment = fSegments.back();
144 return segment.pts()[SkPathOpsVerbToPoints(segment.verb())];
145 }
147 void fixOtherTIndex() {
148 int segmentCount = fSegments.count();
149 for (int sIndex = 0; sIndex < segmentCount; ++sIndex) {
150 fSegments[sIndex].fixOtherTIndex();
151 }
152 }
154 void joinCoincidence() {
155 joinCoincidence(fCoincidences, false);
156 joinCoincidence(fPartialCoincidences, true);
157 }
159 SkOpSegment* nonVerticalSegment(int* start, int* end);
161 bool operand() const {
162 return fOperand;
163 }
165 void reset() {
166 fSegments.reset();
167 fBounds.set(SK_ScalarMax, SK_ScalarMax, SK_ScalarMax, SK_ScalarMax);
168 fContainsCurves = fContainsCubics = fContainsIntercepts = fDone = false;
169 }
171 SkTArray<SkOpSegment>& segments() {
172 return fSegments;
173 }
175 void setContainsIntercepts() {
176 fContainsIntercepts = true;
177 }
179 void setOperand(bool isOp) {
180 fOperand = isOp;
181 }
183 void setOppXor(bool isOppXor) {
184 fOppXor = isOppXor;
185 int segmentCount = fSegments.count();
186 for (int test = 0; test < segmentCount; ++test) {
187 fSegments[test].setOppXor(isOppXor);
188 }
189 }
191 void setXor(bool isXor) {
192 fXor = isXor;
193 }
195 void sortSegments();
197 const SkPoint& start() const {
198 return fSegments.front().pts()[0];
199 }
201 void toPath(SkPathWriter* path) const;
203 void toPartialBackward(SkPathWriter* path) const {
204 int segmentCount = fSegments.count();
205 for (int test = segmentCount - 1; test >= 0; --test) {
206 fSegments[test].addCurveTo(1, 0, path, true);
207 }
208 }
210 void toPartialForward(SkPathWriter* path) const {
211 int segmentCount = fSegments.count();
212 for (int test = 0; test < segmentCount; ++test) {
213 fSegments[test].addCurveTo(0, 1, path, true);
214 }
215 }
217 void topSortableSegment(const SkPoint& topLeft, SkPoint* bestXY, SkOpSegment** topStart);
218 SkOpSegment* undoneSegment(int* start, int* end);
220 int updateSegment(int index, const SkPoint* pts) {
221 SkOpSegment& segment = fSegments[index];
222 segment.updatePts(pts);
223 return SkPathOpsVerbToPoints(segment.verb()) + 1;
224 }
226 #if DEBUG_TEST
227 SkTArray<SkOpSegment>& debugSegments() {
228 return fSegments;
229 }
230 #endif
232 #if DEBUG_ACTIVE_SPANS || DEBUG_ACTIVE_SPANS_FIRST_ONLY
233 void debugShowActiveSpans() {
234 for (int index = 0; index < fSegments.count(); ++index) {
235 fSegments[index].debugShowActiveSpans();
236 }
237 }
238 #endif
240 #if DEBUG_SHOW_WINDING
241 int debugShowWindingValues(int totalSegments, int ofInterest);
242 static void debugShowWindingValues(const SkTArray<SkOpContour*, true>& contourList);
243 #endif
245 private:
246 void calcCommonCoincidentWinding(const SkCoincidence& );
247 void joinCoincidence(const SkTArray<SkCoincidence, true>& , bool partial);
248 void setBounds();
250 SkTArray<SkOpSegment> fSegments;
251 SkTArray<SkOpSegment*, true> fSortedSegments;
252 int fFirstSorted;
253 SkTArray<SkCoincidence, true> fCoincidences;
254 SkTArray<SkCoincidence, true> fPartialCoincidences;
255 SkTArray<const SkOpContour*, true> fCrosses;
256 SkPathOpsBounds fBounds;
257 bool fContainsIntercepts; // FIXME: is this used by anybody?
258 bool fContainsCubics;
259 bool fContainsCurves;
260 bool fDone;
261 bool fOperand; // true for the second argument to a binary operator
262 bool fXor;
263 bool fOppXor;
264 #ifdef SK_DEBUG
265 int fID;
266 #endif
267 };
269 #endif