gfx/skia/trunk/include/core/SkGeometry.h

Sat, 03 Jan 2015 20:18:00 +0100

author
Michael Schloh von Bennewitz <michael@schloh.com>
date
Sat, 03 Jan 2015 20:18:00 +0100
branch
TOR_BUG_3246
changeset 7
129ffea94266
permissions
-rw-r--r--

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.

michael@0 1
michael@0 2 /*
michael@0 3 * Copyright 2006 The Android Open Source Project
michael@0 4 *
michael@0 5 * Use of this source code is governed by a BSD-style license that can be
michael@0 6 * found in the LICENSE file.
michael@0 7 */
michael@0 8
michael@0 9
michael@0 10 #ifndef SkGeometry_DEFINED
michael@0 11 #define SkGeometry_DEFINED
michael@0 12
michael@0 13 #include "SkMatrix.h"
michael@0 14
michael@0 15 /** An XRay is a half-line that runs from the specific point/origin to
michael@0 16 +infinity in the X direction. e.g. XRay(3,5) is the half-line
michael@0 17 (3,5)....(infinity, 5)
michael@0 18 */
michael@0 19 typedef SkPoint SkXRay;
michael@0 20
michael@0 21 /** Given a line segment from pts[0] to pts[1], and an xray, return true if
michael@0 22 they intersect. Optional outgoing "ambiguous" argument indicates
michael@0 23 whether the answer is ambiguous because the query occurred exactly at
michael@0 24 one of the endpoints' y coordinates, indicating that another query y
michael@0 25 coordinate is preferred for robustness.
michael@0 26 */
michael@0 27 bool SkXRayCrossesLine(const SkXRay& pt, const SkPoint pts[2],
michael@0 28 bool* ambiguous = NULL);
michael@0 29
michael@0 30 /** Given a quadratic equation Ax^2 + Bx + C = 0, return 0, 1, 2 roots for the
michael@0 31 equation.
michael@0 32 */
michael@0 33 int SkFindUnitQuadRoots(SkScalar A, SkScalar B, SkScalar C, SkScalar roots[2]);
michael@0 34
michael@0 35 ///////////////////////////////////////////////////////////////////////////////
michael@0 36
michael@0 37 /** Set pt to the point on the src quadratic specified by t. t must be
michael@0 38 0 <= t <= 1.0
michael@0 39 */
michael@0 40 void SkEvalQuadAt(const SkPoint src[3], SkScalar t, SkPoint* pt,
michael@0 41 SkVector* tangent = NULL);
michael@0 42 void SkEvalQuadAtHalf(const SkPoint src[3], SkPoint* pt,
michael@0 43 SkVector* tangent = NULL);
michael@0 44
michael@0 45 /** Given a src quadratic bezier, chop it at the specified t value,
michael@0 46 where 0 < t < 1, and return the two new quadratics in dst:
michael@0 47 dst[0..2] and dst[2..4]
michael@0 48 */
michael@0 49 void SkChopQuadAt(const SkPoint src[3], SkPoint dst[5], SkScalar t);
michael@0 50
michael@0 51 /** Given a src quadratic bezier, chop it at the specified t == 1/2,
michael@0 52 The new quads are returned in dst[0..2] and dst[2..4]
michael@0 53 */
michael@0 54 void SkChopQuadAtHalf(const SkPoint src[3], SkPoint dst[5]);
michael@0 55
michael@0 56 /** Given the 3 coefficients for a quadratic bezier (either X or Y values), look
michael@0 57 for extrema, and return the number of t-values that are found that represent
michael@0 58 these extrema. If the quadratic has no extrema betwee (0..1) exclusive, the
michael@0 59 function returns 0.
michael@0 60 Returned count tValues[]
michael@0 61 0 ignored
michael@0 62 1 0 < tValues[0] < 1
michael@0 63 */
michael@0 64 int SkFindQuadExtrema(SkScalar a, SkScalar b, SkScalar c, SkScalar tValues[1]);
michael@0 65
michael@0 66 /** Given 3 points on a quadratic bezier, chop it into 1, 2 beziers such that
michael@0 67 the resulting beziers are monotonic in Y. This is called by the scan converter.
michael@0 68 Depending on what is returned, dst[] is treated as follows
michael@0 69 0 dst[0..2] is the original quad
michael@0 70 1 dst[0..2] and dst[2..4] are the two new quads
michael@0 71 */
michael@0 72 int SkChopQuadAtYExtrema(const SkPoint src[3], SkPoint dst[5]);
michael@0 73 int SkChopQuadAtXExtrema(const SkPoint src[3], SkPoint dst[5]);
michael@0 74
michael@0 75 /** Given 3 points on a quadratic bezier, if the point of maximum
michael@0 76 curvature exists on the segment, returns the t value for this
michael@0 77 point along the curve. Otherwise it will return a value of 0.
michael@0 78 */
michael@0 79 float SkFindQuadMaxCurvature(const SkPoint src[3]);
michael@0 80
michael@0 81 /** Given 3 points on a quadratic bezier, divide it into 2 quadratics
michael@0 82 if the point of maximum curvature exists on the quad segment.
michael@0 83 Depending on what is returned, dst[] is treated as follows
michael@0 84 1 dst[0..2] is the original quad
michael@0 85 2 dst[0..2] and dst[2..4] are the two new quads
michael@0 86 If dst == null, it is ignored and only the count is returned.
michael@0 87 */
michael@0 88 int SkChopQuadAtMaxCurvature(const SkPoint src[3], SkPoint dst[5]);
michael@0 89
michael@0 90 /** Given 3 points on a quadratic bezier, use degree elevation to
michael@0 91 convert it into the cubic fitting the same curve. The new cubic
michael@0 92 curve is returned in dst[0..3].
michael@0 93 */
michael@0 94 SK_API void SkConvertQuadToCubic(const SkPoint src[3], SkPoint dst[4]);
michael@0 95
michael@0 96 ///////////////////////////////////////////////////////////////////////////////
michael@0 97
michael@0 98 /** Convert from parametric from (pts) to polynomial coefficients
michael@0 99 coeff[0]*T^3 + coeff[1]*T^2 + coeff[2]*T + coeff[3]
michael@0 100 */
michael@0 101 void SkGetCubicCoeff(const SkPoint pts[4], SkScalar cx[4], SkScalar cy[4]);
michael@0 102
michael@0 103 /** Set pt to the point on the src cubic specified by t. t must be
michael@0 104 0 <= t <= 1.0
michael@0 105 */
michael@0 106 void SkEvalCubicAt(const SkPoint src[4], SkScalar t, SkPoint* locOrNull,
michael@0 107 SkVector* tangentOrNull, SkVector* curvatureOrNull);
michael@0 108
michael@0 109 /** Given a src cubic bezier, chop it at the specified t value,
michael@0 110 where 0 < t < 1, and return the two new cubics in dst:
michael@0 111 dst[0..3] and dst[3..6]
michael@0 112 */
michael@0 113 void SkChopCubicAt(const SkPoint src[4], SkPoint dst[7], SkScalar t);
michael@0 114 /** Given a src cubic bezier, chop it at the specified t values,
michael@0 115 where 0 < t < 1, and return the new cubics in dst:
michael@0 116 dst[0..3],dst[3..6],...,dst[3*t_count..3*(t_count+1)]
michael@0 117 */
michael@0 118 void SkChopCubicAt(const SkPoint src[4], SkPoint dst[], const SkScalar t[],
michael@0 119 int t_count);
michael@0 120
michael@0 121 /** Given a src cubic bezier, chop it at the specified t == 1/2,
michael@0 122 The new cubics are returned in dst[0..3] and dst[3..6]
michael@0 123 */
michael@0 124 void SkChopCubicAtHalf(const SkPoint src[4], SkPoint dst[7]);
michael@0 125
michael@0 126 /** Given the 4 coefficients for a cubic bezier (either X or Y values), look
michael@0 127 for extrema, and return the number of t-values that are found that represent
michael@0 128 these extrema. If the cubic has no extrema betwee (0..1) exclusive, the
michael@0 129 function returns 0.
michael@0 130 Returned count tValues[]
michael@0 131 0 ignored
michael@0 132 1 0 < tValues[0] < 1
michael@0 133 2 0 < tValues[0] < tValues[1] < 1
michael@0 134 */
michael@0 135 int SkFindCubicExtrema(SkScalar a, SkScalar b, SkScalar c, SkScalar d,
michael@0 136 SkScalar tValues[2]);
michael@0 137
michael@0 138 /** Given 4 points on a cubic bezier, chop it into 1, 2, 3 beziers such that
michael@0 139 the resulting beziers are monotonic in Y. This is called by the scan converter.
michael@0 140 Depending on what is returned, dst[] is treated as follows
michael@0 141 0 dst[0..3] is the original cubic
michael@0 142 1 dst[0..3] and dst[3..6] are the two new cubics
michael@0 143 2 dst[0..3], dst[3..6], dst[6..9] are the three new cubics
michael@0 144 If dst == null, it is ignored and only the count is returned.
michael@0 145 */
michael@0 146 int SkChopCubicAtYExtrema(const SkPoint src[4], SkPoint dst[10]);
michael@0 147 int SkChopCubicAtXExtrema(const SkPoint src[4], SkPoint dst[10]);
michael@0 148
michael@0 149 /** Given a cubic bezier, return 0, 1, or 2 t-values that represent the
michael@0 150 inflection points.
michael@0 151 */
michael@0 152 int SkFindCubicInflections(const SkPoint src[4], SkScalar tValues[2]);
michael@0 153
michael@0 154 /** Return 1 for no chop, 2 for having chopped the cubic at a single
michael@0 155 inflection point, 3 for having chopped at 2 inflection points.
michael@0 156 dst will hold the resulting 1, 2, or 3 cubics.
michael@0 157 */
michael@0 158 int SkChopCubicAtInflections(const SkPoint src[4], SkPoint dst[10]);
michael@0 159
michael@0 160 int SkFindCubicMaxCurvature(const SkPoint src[4], SkScalar tValues[3]);
michael@0 161 int SkChopCubicAtMaxCurvature(const SkPoint src[4], SkPoint dst[13],
michael@0 162 SkScalar tValues[3] = NULL);
michael@0 163
michael@0 164 /** Given a monotonic cubic bezier, determine whether an xray intersects the
michael@0 165 cubic.
michael@0 166 By definition the cubic is open at the starting point; in other
michael@0 167 words, if pt.fY is equivalent to cubic[0].fY, and pt.fX is to the
michael@0 168 left of the curve, the line is not considered to cross the curve,
michael@0 169 but if it is equal to cubic[3].fY then it is considered to
michael@0 170 cross.
michael@0 171 Optional outgoing "ambiguous" argument indicates whether the answer is
michael@0 172 ambiguous because the query occurred exactly at one of the endpoints' y
michael@0 173 coordinates, indicating that another query y coordinate is preferred
michael@0 174 for robustness.
michael@0 175 */
michael@0 176 bool SkXRayCrossesMonotonicCubic(const SkXRay& pt, const SkPoint cubic[4],
michael@0 177 bool* ambiguous = NULL);
michael@0 178
michael@0 179 /** Given an arbitrary cubic bezier, return the number of times an xray crosses
michael@0 180 the cubic. Valid return values are [0..3]
michael@0 181 By definition the cubic is open at the starting point; in other
michael@0 182 words, if pt.fY is equivalent to cubic[0].fY, and pt.fX is to the
michael@0 183 left of the curve, the line is not considered to cross the curve,
michael@0 184 but if it is equal to cubic[3].fY then it is considered to
michael@0 185 cross.
michael@0 186 Optional outgoing "ambiguous" argument indicates whether the answer is
michael@0 187 ambiguous because the query occurred exactly at one of the endpoints' y
michael@0 188 coordinates or at a tangent point, indicating that another query y
michael@0 189 coordinate is preferred for robustness.
michael@0 190 */
michael@0 191 int SkNumXRayCrossingsForCubic(const SkXRay& pt, const SkPoint cubic[4],
michael@0 192 bool* ambiguous = NULL);
michael@0 193
michael@0 194 ///////////////////////////////////////////////////////////////////////////////
michael@0 195
michael@0 196 enum SkRotationDirection {
michael@0 197 kCW_SkRotationDirection,
michael@0 198 kCCW_SkRotationDirection
michael@0 199 };
michael@0 200
michael@0 201 /** Maximum number of points needed in the quadPoints[] parameter for
michael@0 202 SkBuildQuadArc()
michael@0 203 */
michael@0 204 #define kSkBuildQuadArcStorage 17
michael@0 205
michael@0 206 /** Given 2 unit vectors and a rotation direction, fill out the specified
michael@0 207 array of points with quadratic segments. Return is the number of points
michael@0 208 written to, which will be { 0, 3, 5, 7, ... kSkBuildQuadArcStorage }
michael@0 209
michael@0 210 matrix, if not null, is appled to the points before they are returned.
michael@0 211 */
michael@0 212 int SkBuildQuadArc(const SkVector& unitStart, const SkVector& unitStop,
michael@0 213 SkRotationDirection, const SkMatrix*, SkPoint quadPoints[]);
michael@0 214
michael@0 215 // experimental
michael@0 216 struct SkConic {
michael@0 217 SkPoint fPts[3];
michael@0 218 SkScalar fW;
michael@0 219
michael@0 220 void set(const SkPoint pts[3], SkScalar w) {
michael@0 221 memcpy(fPts, pts, 3 * sizeof(SkPoint));
michael@0 222 fW = w;
michael@0 223 }
michael@0 224
michael@0 225 /**
michael@0 226 * Given a t-value [0...1] return its position and/or tangent.
michael@0 227 * If pos is not null, return its position at the t-value.
michael@0 228 * If tangent is not null, return its tangent at the t-value. NOTE the
michael@0 229 * tangent value's length is arbitrary, and only its direction should
michael@0 230 * be used.
michael@0 231 */
michael@0 232 void evalAt(SkScalar t, SkPoint* pos, SkVector* tangent = NULL) const;
michael@0 233 void chopAt(SkScalar t, SkConic dst[2]) const;
michael@0 234 void chop(SkConic dst[2]) const;
michael@0 235
michael@0 236 void computeAsQuadError(SkVector* err) const;
michael@0 237 bool asQuadTol(SkScalar tol) const;
michael@0 238
michael@0 239 /**
michael@0 240 * return the power-of-2 number of quads needed to approximate this conic
michael@0 241 * with a sequence of quads. Will be >= 0.
michael@0 242 */
michael@0 243 int computeQuadPOW2(SkScalar tol) const;
michael@0 244
michael@0 245 /**
michael@0 246 * Chop this conic into N quads, stored continguously in pts[], where
michael@0 247 * N = 1 << pow2. The amount of storage needed is (1 + 2 * N)
michael@0 248 */
michael@0 249 int chopIntoQuadsPOW2(SkPoint pts[], int pow2) const;
michael@0 250
michael@0 251 bool findXExtrema(SkScalar* t) const;
michael@0 252 bool findYExtrema(SkScalar* t) const;
michael@0 253 bool chopAtXExtrema(SkConic dst[2]) const;
michael@0 254 bool chopAtYExtrema(SkConic dst[2]) const;
michael@0 255
michael@0 256 void computeTightBounds(SkRect* bounds) const;
michael@0 257 void computeFastBounds(SkRect* bounds) const;
michael@0 258
michael@0 259 /** Find the parameter value where the conic takes on its maximum curvature.
michael@0 260 *
michael@0 261 * @param t output scalar for max curvature. Will be unchanged if
michael@0 262 * max curvature outside 0..1 range.
michael@0 263 *
michael@0 264 * @return true if max curvature found inside 0..1 range, false otherwise
michael@0 265 */
michael@0 266 bool findMaxCurvature(SkScalar* t) const;
michael@0 267 };
michael@0 268
michael@0 269 #include "SkTemplates.h"
michael@0 270
michael@0 271 /**
michael@0 272 * Help class to allocate storage for approximating a conic with N quads.
michael@0 273 */
michael@0 274 class SkAutoConicToQuads {
michael@0 275 public:
michael@0 276 SkAutoConicToQuads() : fQuadCount(0) {}
michael@0 277
michael@0 278 /**
michael@0 279 * Given a conic and a tolerance, return the array of points for the
michael@0 280 * approximating quad(s). Call countQuads() to know the number of quads
michael@0 281 * represented in these points.
michael@0 282 *
michael@0 283 * The quads are allocated to share end-points. e.g. if there are 4 quads,
michael@0 284 * there will be 9 points allocated as follows
michael@0 285 * quad[0] == pts[0..2]
michael@0 286 * quad[1] == pts[2..4]
michael@0 287 * quad[2] == pts[4..6]
michael@0 288 * quad[3] == pts[6..8]
michael@0 289 */
michael@0 290 const SkPoint* computeQuads(const SkConic& conic, SkScalar tol) {
michael@0 291 int pow2 = conic.computeQuadPOW2(tol);
michael@0 292 fQuadCount = 1 << pow2;
michael@0 293 SkPoint* pts = fStorage.reset(1 + 2 * fQuadCount);
michael@0 294 conic.chopIntoQuadsPOW2(pts, pow2);
michael@0 295 return pts;
michael@0 296 }
michael@0 297
michael@0 298 const SkPoint* computeQuads(const SkPoint pts[3], SkScalar weight,
michael@0 299 SkScalar tol) {
michael@0 300 SkConic conic;
michael@0 301 conic.set(pts, weight);
michael@0 302 return computeQuads(conic, tol);
michael@0 303 }
michael@0 304
michael@0 305 int countQuads() const { return fQuadCount; }
michael@0 306
michael@0 307 private:
michael@0 308 enum {
michael@0 309 kQuadCount = 8, // should handle most conics
michael@0 310 kPointCount = 1 + 2 * kQuadCount,
michael@0 311 };
michael@0 312 SkAutoSTMalloc<kPointCount, SkPoint> fStorage;
michael@0 313 int fQuadCount; // #quads for current usage
michael@0 314 };
michael@0 315
michael@0 316 #endif

mercurial