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.
2 /*
3 * Copyright 2008 The Android Open Source Project
4 *
5 * Use of this source code is governed by a BSD-style license that can be
6 * found in the LICENSE file.
7 */
10 #include "SkPoint.h"
12 void SkIPoint::rotateCW(SkIPoint* dst) const {
13 SkASSERT(dst);
15 // use a tmp in case this == dst
16 int32_t tmp = fX;
17 dst->fX = -fY;
18 dst->fY = tmp;
19 }
21 void SkIPoint::rotateCCW(SkIPoint* dst) const {
22 SkASSERT(dst);
24 // use a tmp in case this == dst
25 int32_t tmp = fX;
26 dst->fX = fY;
27 dst->fY = -tmp;
28 }
30 ///////////////////////////////////////////////////////////////////////////////
32 void SkPoint::setIRectFan(int l, int t, int r, int b, size_t stride) {
33 SkASSERT(stride >= sizeof(SkPoint));
35 ((SkPoint*)((intptr_t)this + 0 * stride))->set(SkIntToScalar(l),
36 SkIntToScalar(t));
37 ((SkPoint*)((intptr_t)this + 1 * stride))->set(SkIntToScalar(l),
38 SkIntToScalar(b));
39 ((SkPoint*)((intptr_t)this + 2 * stride))->set(SkIntToScalar(r),
40 SkIntToScalar(b));
41 ((SkPoint*)((intptr_t)this + 3 * stride))->set(SkIntToScalar(r),
42 SkIntToScalar(t));
43 }
45 void SkPoint::setRectFan(SkScalar l, SkScalar t, SkScalar r, SkScalar b,
46 size_t stride) {
47 SkASSERT(stride >= sizeof(SkPoint));
49 ((SkPoint*)((intptr_t)this + 0 * stride))->set(l, t);
50 ((SkPoint*)((intptr_t)this + 1 * stride))->set(l, b);
51 ((SkPoint*)((intptr_t)this + 2 * stride))->set(r, b);
52 ((SkPoint*)((intptr_t)this + 3 * stride))->set(r, t);
53 }
55 void SkPoint::rotateCW(SkPoint* dst) const {
56 SkASSERT(dst);
58 // use a tmp in case this == dst
59 SkScalar tmp = fX;
60 dst->fX = -fY;
61 dst->fY = tmp;
62 }
64 void SkPoint::rotateCCW(SkPoint* dst) const {
65 SkASSERT(dst);
67 // use a tmp in case this == dst
68 SkScalar tmp = fX;
69 dst->fX = fY;
70 dst->fY = -tmp;
71 }
73 void SkPoint::scale(SkScalar scale, SkPoint* dst) const {
74 SkASSERT(dst);
75 dst->set(SkScalarMul(fX, scale), SkScalarMul(fY, scale));
76 }
78 bool SkPoint::normalize() {
79 return this->setLength(fX, fY, SK_Scalar1);
80 }
82 bool SkPoint::setNormalize(SkScalar x, SkScalar y) {
83 return this->setLength(x, y, SK_Scalar1);
84 }
86 bool SkPoint::setLength(SkScalar length) {
87 return this->setLength(fX, fY, length);
88 }
90 // Returns the square of the Euclidian distance to (dx,dy).
91 static inline float getLengthSquared(float dx, float dy) {
92 return dx * dx + dy * dy;
93 }
95 // Calculates the square of the Euclidian distance to (dx,dy) and stores it in
96 // *lengthSquared. Returns true if the distance is judged to be "nearly zero".
97 //
98 // This logic is encapsulated in a helper method to make it explicit that we
99 // always perform this check in the same manner, to avoid inconsistencies
100 // (see http://code.google.com/p/skia/issues/detail?id=560 ).
101 static inline bool isLengthNearlyZero(float dx, float dy,
102 float *lengthSquared) {
103 *lengthSquared = getLengthSquared(dx, dy);
104 return *lengthSquared <= (SK_ScalarNearlyZero * SK_ScalarNearlyZero);
105 }
107 SkScalar SkPoint::Normalize(SkPoint* pt) {
108 float x = pt->fX;
109 float y = pt->fY;
110 float mag2;
111 if (isLengthNearlyZero(x, y, &mag2)) {
112 return 0;
113 }
115 float mag, scale;
116 if (SkScalarIsFinite(mag2)) {
117 mag = sk_float_sqrt(mag2);
118 scale = 1 / mag;
119 } else {
120 // our mag2 step overflowed to infinity, so use doubles instead.
121 // much slower, but needed when x or y are very large, other wise we
122 // divide by inf. and return (0,0) vector.
123 double xx = x;
124 double yy = y;
125 double magmag = sqrt(xx * xx + yy * yy);
126 mag = (float)magmag;
127 // we perform the divide with the double magmag, to stay exactly the
128 // same as setLength. It would be faster to perform the divide with
129 // mag, but it is possible that mag has overflowed to inf. but still
130 // have a non-zero value for scale (thanks to denormalized numbers).
131 scale = (float)(1 / magmag);
132 }
133 pt->set(x * scale, y * scale);
134 return mag;
135 }
137 SkScalar SkPoint::Length(SkScalar dx, SkScalar dy) {
138 float mag2 = dx * dx + dy * dy;
139 if (SkScalarIsFinite(mag2)) {
140 return sk_float_sqrt(mag2);
141 } else {
142 double xx = dx;
143 double yy = dy;
144 return (float)sqrt(xx * xx + yy * yy);
145 }
146 }
148 /*
149 * We have to worry about 2 tricky conditions:
150 * 1. underflow of mag2 (compared against nearlyzero^2)
151 * 2. overflow of mag2 (compared w/ isfinite)
152 *
153 * If we underflow, we return false. If we overflow, we compute again using
154 * doubles, which is much slower (3x in a desktop test) but will not overflow.
155 */
156 bool SkPoint::setLength(float x, float y, float length) {
157 float mag2;
158 if (isLengthNearlyZero(x, y, &mag2)) {
159 return false;
160 }
162 float scale;
163 if (SkScalarIsFinite(mag2)) {
164 scale = length / sk_float_sqrt(mag2);
165 } else {
166 // our mag2 step overflowed to infinity, so use doubles instead.
167 // much slower, but needed when x or y are very large, other wise we
168 // divide by inf. and return (0,0) vector.
169 double xx = x;
170 double yy = y;
171 scale = (float)(length / sqrt(xx * xx + yy * yy));
172 }
173 fX = x * scale;
174 fY = y * scale;
175 return true;
176 }
178 bool SkPoint::setLengthFast(float length) {
179 return this->setLengthFast(fX, fY, length);
180 }
182 bool SkPoint::setLengthFast(float x, float y, float length) {
183 float mag2;
184 if (isLengthNearlyZero(x, y, &mag2)) {
185 return false;
186 }
188 float scale;
189 if (SkScalarIsFinite(mag2)) {
190 scale = length * sk_float_rsqrt(mag2); // <--- this is the difference
191 } else {
192 // our mag2 step overflowed to infinity, so use doubles instead.
193 // much slower, but needed when x or y are very large, other wise we
194 // divide by inf. and return (0,0) vector.
195 double xx = x;
196 double yy = y;
197 scale = (float)(length / sqrt(xx * xx + yy * yy));
198 }
199 fX = x * scale;
200 fY = y * scale;
201 return true;
202 }
205 ///////////////////////////////////////////////////////////////////////////////
207 SkScalar SkPoint::distanceToLineBetweenSqd(const SkPoint& a,
208 const SkPoint& b,
209 Side* side) const {
211 SkVector u = b - a;
212 SkVector v = *this - a;
214 SkScalar uLengthSqd = u.lengthSqd();
215 SkScalar det = u.cross(v);
216 if (NULL != side) {
217 SkASSERT(-1 == SkPoint::kLeft_Side &&
218 0 == SkPoint::kOn_Side &&
219 1 == kRight_Side);
220 *side = (Side) SkScalarSignAsInt(det);
221 }
222 return SkScalarMulDiv(det, det, uLengthSqd);
223 }
225 SkScalar SkPoint::distanceToLineSegmentBetweenSqd(const SkPoint& a,
226 const SkPoint& b) const {
227 // See comments to distanceToLineBetweenSqd. If the projection of c onto
228 // u is between a and b then this returns the same result as that
229 // function. Otherwise, it returns the distance to the closer of a and
230 // b. Let the projection of v onto u be v'. There are three cases:
231 // 1. v' points opposite to u. c is not between a and b and is closer
232 // to a than b.
233 // 2. v' points along u and has magnitude less than y. c is between
234 // a and b and the distance to the segment is the same as distance
235 // to the line ab.
236 // 3. v' points along u and has greater magnitude than u. c is not
237 // not between a and b and is closer to b than a.
238 // v' = (u dot v) * u / |u|. So if (u dot v)/|u| is less than zero we're
239 // in case 1. If (u dot v)/|u| is > |u| we are in case 3. Otherwise
240 // we're in case 2. We actually compare (u dot v) to 0 and |u|^2 to
241 // avoid a sqrt to compute |u|.
243 SkVector u = b - a;
244 SkVector v = *this - a;
246 SkScalar uLengthSqd = u.lengthSqd();
247 SkScalar uDotV = SkPoint::DotProduct(u, v);
249 if (uDotV <= 0) {
250 return v.lengthSqd();
251 } else if (uDotV > uLengthSqd) {
252 return b.distanceToSqd(*this);
253 } else {
254 SkScalar det = u.cross(v);
255 return SkScalarMulDiv(det, det, uLengthSqd);
256 }
257 }