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 2006 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 #ifndef SkMatrix_DEFINED
11 #define SkMatrix_DEFINED
13 #include "SkRect.h"
15 class SkString;
17 // TODO: can we remove these 3 (need to check chrome/android)
18 typedef SkScalar SkPersp;
19 #define SkScalarToPersp(x) (x)
20 #define SkPerspToScalar(x) (x)
22 /** \class SkMatrix
24 The SkMatrix class holds a 3x3 matrix for transforming coordinates.
25 SkMatrix does not have a constructor, so it must be explicitly initialized
26 using either reset() - to construct an identity matrix, or one of the set
27 functions (e.g. setTranslate, setRotate, etc.).
28 */
29 class SK_API SkMatrix {
30 public:
31 /** Enum of bit fields for the mask return by getType().
32 Use this to identify the complexity of the matrix.
33 */
34 enum TypeMask {
35 kIdentity_Mask = 0,
36 kTranslate_Mask = 0x01, //!< set if the matrix has translation
37 kScale_Mask = 0x02, //!< set if the matrix has X or Y scale
38 kAffine_Mask = 0x04, //!< set if the matrix skews or rotates
39 kPerspective_Mask = 0x08 //!< set if the matrix is in perspective
40 };
42 /** Returns a bitfield describing the transformations the matrix may
43 perform. The bitfield is computed conservatively, so it may include
44 false positives. For example, when kPerspective_Mask is true, all
45 other bits may be set to true even in the case of a pure perspective
46 transform.
47 */
48 TypeMask getType() const {
49 if (fTypeMask & kUnknown_Mask) {
50 fTypeMask = this->computeTypeMask();
51 }
52 // only return the public masks
53 return (TypeMask)(fTypeMask & 0xF);
54 }
56 /** Returns true if the matrix is identity.
57 */
58 bool isIdentity() const {
59 return this->getType() == 0;
60 }
62 /** Returns true if will map a rectangle to another rectangle. This can be
63 true if the matrix is identity, scale-only, or rotates a multiple of
64 90 degrees.
65 */
66 bool rectStaysRect() const {
67 if (fTypeMask & kUnknown_Mask) {
68 fTypeMask = this->computeTypeMask();
69 }
70 return (fTypeMask & kRectStaysRect_Mask) != 0;
71 }
72 // alias for rectStaysRect()
73 bool preservesAxisAlignment() const { return this->rectStaysRect(); }
75 /**
76 * Returns true if the matrix contains perspective elements.
77 */
78 bool hasPerspective() const {
79 return SkToBool(this->getPerspectiveTypeMaskOnly() &
80 kPerspective_Mask);
81 }
83 /** Returns true if the matrix contains only translation, rotation or uniform scale
84 Returns false if other transformation types are included or is degenerate
85 */
86 bool isSimilarity(SkScalar tol = SK_ScalarNearlyZero) const;
88 /** Returns true if the matrix contains only translation, rotation or scale
89 (non-uniform scale is allowed).
90 Returns false if other transformation types are included or is degenerate
91 */
92 bool preservesRightAngles(SkScalar tol = SK_ScalarNearlyZero) const;
94 enum {
95 kMScaleX,
96 kMSkewX,
97 kMTransX,
98 kMSkewY,
99 kMScaleY,
100 kMTransY,
101 kMPersp0,
102 kMPersp1,
103 kMPersp2
104 };
106 /** Affine arrays are in column major order
107 because that's how PDF and XPS like it.
108 */
109 enum {
110 kAScaleX,
111 kASkewY,
112 kASkewX,
113 kAScaleY,
114 kATransX,
115 kATransY
116 };
118 SkScalar operator[](int index) const {
119 SkASSERT((unsigned)index < 9);
120 return fMat[index];
121 }
123 SkScalar get(int index) const {
124 SkASSERT((unsigned)index < 9);
125 return fMat[index];
126 }
128 SkScalar getScaleX() const { return fMat[kMScaleX]; }
129 SkScalar getScaleY() const { return fMat[kMScaleY]; }
130 SkScalar getSkewY() const { return fMat[kMSkewY]; }
131 SkScalar getSkewX() const { return fMat[kMSkewX]; }
132 SkScalar getTranslateX() const { return fMat[kMTransX]; }
133 SkScalar getTranslateY() const { return fMat[kMTransY]; }
134 SkPersp getPerspX() const { return fMat[kMPersp0]; }
135 SkPersp getPerspY() const { return fMat[kMPersp1]; }
137 SkScalar& operator[](int index) {
138 SkASSERT((unsigned)index < 9);
139 this->setTypeMask(kUnknown_Mask);
140 return fMat[index];
141 }
143 void set(int index, SkScalar value) {
144 SkASSERT((unsigned)index < 9);
145 fMat[index] = value;
146 this->setTypeMask(kUnknown_Mask);
147 }
149 void setScaleX(SkScalar v) { this->set(kMScaleX, v); }
150 void setScaleY(SkScalar v) { this->set(kMScaleY, v); }
151 void setSkewY(SkScalar v) { this->set(kMSkewY, v); }
152 void setSkewX(SkScalar v) { this->set(kMSkewX, v); }
153 void setTranslateX(SkScalar v) { this->set(kMTransX, v); }
154 void setTranslateY(SkScalar v) { this->set(kMTransY, v); }
155 void setPerspX(SkPersp v) { this->set(kMPersp0, v); }
156 void setPerspY(SkPersp v) { this->set(kMPersp1, v); }
158 void setAll(SkScalar scaleX, SkScalar skewX, SkScalar transX,
159 SkScalar skewY, SkScalar scaleY, SkScalar transY,
160 SkPersp persp0, SkPersp persp1, SkPersp persp2) {
161 fMat[kMScaleX] = scaleX;
162 fMat[kMSkewX] = skewX;
163 fMat[kMTransX] = transX;
164 fMat[kMSkewY] = skewY;
165 fMat[kMScaleY] = scaleY;
166 fMat[kMTransY] = transY;
167 fMat[kMPersp0] = persp0;
168 fMat[kMPersp1] = persp1;
169 fMat[kMPersp2] = persp2;
170 this->setTypeMask(kUnknown_Mask);
171 }
173 /** Set the matrix to identity
174 */
175 void reset();
176 // alias for reset()
177 void setIdentity() { this->reset(); }
179 /** Set the matrix to translate by (dx, dy).
180 */
181 void setTranslate(SkScalar dx, SkScalar dy);
182 void setTranslate(const SkVector& v) { this->setTranslate(v.fX, v.fY); }
184 /** Set the matrix to scale by sx and sy, with a pivot point at (px, py).
185 The pivot point is the coordinate that should remain unchanged by the
186 specified transformation.
187 */
188 void setScale(SkScalar sx, SkScalar sy, SkScalar px, SkScalar py);
189 /** Set the matrix to scale by sx and sy.
190 */
191 void setScale(SkScalar sx, SkScalar sy);
192 /** Set the matrix to scale by 1/divx and 1/divy. Returns false and doesn't
193 touch the matrix if either divx or divy is zero.
194 */
195 bool setIDiv(int divx, int divy);
196 /** Set the matrix to rotate by the specified number of degrees, with a
197 pivot point at (px, py). The pivot point is the coordinate that should
198 remain unchanged by the specified transformation.
199 */
200 void setRotate(SkScalar degrees, SkScalar px, SkScalar py);
201 /** Set the matrix to rotate about (0,0) by the specified number of degrees.
202 */
203 void setRotate(SkScalar degrees);
204 /** Set the matrix to rotate by the specified sine and cosine values, with
205 a pivot point at (px, py). The pivot point is the coordinate that
206 should remain unchanged by the specified transformation.
207 */
208 void setSinCos(SkScalar sinValue, SkScalar cosValue,
209 SkScalar px, SkScalar py);
210 /** Set the matrix to rotate by the specified sine and cosine values.
211 */
212 void setSinCos(SkScalar sinValue, SkScalar cosValue);
213 /** Set the matrix to skew by sx and sy, with a pivot point at (px, py).
214 The pivot point is the coordinate that should remain unchanged by the
215 specified transformation.
216 */
217 void setSkew(SkScalar kx, SkScalar ky, SkScalar px, SkScalar py);
218 /** Set the matrix to skew by sx and sy.
219 */
220 void setSkew(SkScalar kx, SkScalar ky);
221 /** Set the matrix to the concatenation of the two specified matrices,
222 returning true if the the result can be represented. Either of the
223 two matrices may also be the target matrix. *this = a * b;
224 */
225 bool setConcat(const SkMatrix& a, const SkMatrix& b);
227 /** Preconcats the matrix with the specified translation.
228 M' = M * T(dx, dy)
229 */
230 bool preTranslate(SkScalar dx, SkScalar dy);
231 /** Preconcats the matrix with the specified scale.
232 M' = M * S(sx, sy, px, py)
233 */
234 bool preScale(SkScalar sx, SkScalar sy, SkScalar px, SkScalar py);
235 /** Preconcats the matrix with the specified scale.
236 M' = M * S(sx, sy)
237 */
238 bool preScale(SkScalar sx, SkScalar sy);
239 /** Preconcats the matrix with the specified rotation.
240 M' = M * R(degrees, px, py)
241 */
242 bool preRotate(SkScalar degrees, SkScalar px, SkScalar py);
243 /** Preconcats the matrix with the specified rotation.
244 M' = M * R(degrees)
245 */
246 bool preRotate(SkScalar degrees);
247 /** Preconcats the matrix with the specified skew.
248 M' = M * K(kx, ky, px, py)
249 */
250 bool preSkew(SkScalar kx, SkScalar ky, SkScalar px, SkScalar py);
251 /** Preconcats the matrix with the specified skew.
252 M' = M * K(kx, ky)
253 */
254 bool preSkew(SkScalar kx, SkScalar ky);
255 /** Preconcats the matrix with the specified matrix.
256 M' = M * other
257 */
258 bool preConcat(const SkMatrix& other);
260 /** Postconcats the matrix with the specified translation.
261 M' = T(dx, dy) * M
262 */
263 bool postTranslate(SkScalar dx, SkScalar dy);
264 /** Postconcats the matrix with the specified scale.
265 M' = S(sx, sy, px, py) * M
266 */
267 bool postScale(SkScalar sx, SkScalar sy, SkScalar px, SkScalar py);
268 /** Postconcats the matrix with the specified scale.
269 M' = S(sx, sy) * M
270 */
271 bool postScale(SkScalar sx, SkScalar sy);
272 /** Postconcats the matrix by dividing it by the specified integers.
273 M' = S(1/divx, 1/divy, 0, 0) * M
274 */
275 bool postIDiv(int divx, int divy);
276 /** Postconcats the matrix with the specified rotation.
277 M' = R(degrees, px, py) * M
278 */
279 bool postRotate(SkScalar degrees, SkScalar px, SkScalar py);
280 /** Postconcats the matrix with the specified rotation.
281 M' = R(degrees) * M
282 */
283 bool postRotate(SkScalar degrees);
284 /** Postconcats the matrix with the specified skew.
285 M' = K(kx, ky, px, py) * M
286 */
287 bool postSkew(SkScalar kx, SkScalar ky, SkScalar px, SkScalar py);
288 /** Postconcats the matrix with the specified skew.
289 M' = K(kx, ky) * M
290 */
291 bool postSkew(SkScalar kx, SkScalar ky);
292 /** Postconcats the matrix with the specified matrix.
293 M' = other * M
294 */
295 bool postConcat(const SkMatrix& other);
297 enum ScaleToFit {
298 /**
299 * Scale in X and Y independently, so that src matches dst exactly.
300 * This may change the aspect ratio of the src.
301 */
302 kFill_ScaleToFit,
303 /**
304 * Compute a scale that will maintain the original src aspect ratio,
305 * but will also ensure that src fits entirely inside dst. At least one
306 * axis (X or Y) will fit exactly. kStart aligns the result to the
307 * left and top edges of dst.
308 */
309 kStart_ScaleToFit,
310 /**
311 * Compute a scale that will maintain the original src aspect ratio,
312 * but will also ensure that src fits entirely inside dst. At least one
313 * axis (X or Y) will fit exactly. The result is centered inside dst.
314 */
315 kCenter_ScaleToFit,
316 /**
317 * Compute a scale that will maintain the original src aspect ratio,
318 * but will also ensure that src fits entirely inside dst. At least one
319 * axis (X or Y) will fit exactly. kEnd aligns the result to the
320 * right and bottom edges of dst.
321 */
322 kEnd_ScaleToFit
323 };
325 /** Set the matrix to the scale and translate values that map the source
326 rectangle to the destination rectangle, returning true if the the result
327 can be represented.
328 @param src the source rectangle to map from.
329 @param dst the destination rectangle to map to.
330 @param stf the ScaleToFit option
331 @return true if the matrix can be represented by the rectangle mapping.
332 */
333 bool setRectToRect(const SkRect& src, const SkRect& dst, ScaleToFit stf);
335 /** Set the matrix such that the specified src points would map to the
336 specified dst points. count must be within [0..4].
337 @param src The array of src points
338 @param dst The array of dst points
339 @param count The number of points to use for the transformation
340 @return true if the matrix was set to the specified transformation
341 */
342 bool setPolyToPoly(const SkPoint src[], const SkPoint dst[], int count);
344 /** If this matrix can be inverted, return true and if inverse is not null,
345 set inverse to be the inverse of this matrix. If this matrix cannot be
346 inverted, ignore inverse and return false
347 */
348 bool SK_WARN_UNUSED_RESULT invert(SkMatrix* inverse) const {
349 // Allow the trivial case to be inlined.
350 if (this->isIdentity()) {
351 if (NULL != inverse) {
352 inverse->reset();
353 }
354 return true;
355 }
356 return this->invertNonIdentity(inverse);
357 }
359 /** Fills the passed array with affine identity values
360 in column major order.
361 @param affine The array to fill with affine identity values.
362 Must not be NULL.
363 */
364 static void SetAffineIdentity(SkScalar affine[6]);
366 /** Fills the passed array with the affine values in column major order.
367 If the matrix is a perspective transform, returns false
368 and does not change the passed array.
369 @param affine The array to fill with affine values. Ignored if NULL.
370 */
371 bool asAffine(SkScalar affine[6]) const;
373 /** Apply this matrix to the array of points specified by src, and write
374 the transformed points into the array of points specified by dst.
375 dst[] = M * src[]
376 @param dst Where the transformed coordinates are written. It must
377 contain at least count entries
378 @param src The original coordinates that are to be transformed. It
379 must contain at least count entries
380 @param count The number of points in src to read, and then transform
381 into dst.
382 */
383 void mapPoints(SkPoint dst[], const SkPoint src[], int count) const;
385 /** Apply this matrix to the array of points, overwriting it with the
386 transformed values.
387 dst[] = M * pts[]
388 @param pts The points to be transformed. It must contain at least
389 count entries
390 @param count The number of points in pts.
391 */
392 void mapPoints(SkPoint pts[], int count) const {
393 this->mapPoints(pts, pts, count);
394 }
396 /** Like mapPoints but with custom byte stride between the points. Stride
397 * should be a multiple of sizeof(SkScalar).
398 */
399 void mapPointsWithStride(SkPoint pts[], size_t stride, int count) const {
400 SkASSERT(stride >= sizeof(SkPoint));
401 SkASSERT(0 == stride % sizeof(SkScalar));
402 for (int i = 0; i < count; ++i) {
403 this->mapPoints(pts, pts, 1);
404 pts = (SkPoint*)((intptr_t)pts + stride);
405 }
406 }
408 /** Like mapPoints but with custom byte stride between the points.
409 */
410 void mapPointsWithStride(SkPoint dst[], SkPoint src[],
411 size_t stride, int count) const {
412 SkASSERT(stride >= sizeof(SkPoint));
413 SkASSERT(0 == stride % sizeof(SkScalar));
414 for (int i = 0; i < count; ++i) {
415 this->mapPoints(dst, src, 1);
416 src = (SkPoint*)((intptr_t)src + stride);
417 dst = (SkPoint*)((intptr_t)dst + stride);
418 }
419 }
421 /** Apply this matrix to the array of homogeneous points, specified by src,
422 where a homogeneous point is defined by 3 contiguous scalar values,
423 and write the transformed points into the array of scalars specified by dst.
424 dst[] = M * src[]
425 @param dst Where the transformed coordinates are written. It must
426 contain at least 3 * count entries
427 @param src The original coordinates that are to be transformed. It
428 must contain at least 3 * count entries
429 @param count The number of triples (homogeneous points) in src to read,
430 and then transform into dst.
431 */
432 void mapHomogeneousPoints(SkScalar dst[], const SkScalar src[], int count) const;
434 void mapXY(SkScalar x, SkScalar y, SkPoint* result) const {
435 SkASSERT(result);
436 this->getMapXYProc()(*this, x, y, result);
437 }
439 /** Apply this matrix to the array of vectors specified by src, and write
440 the transformed vectors into the array of vectors specified by dst.
441 This is similar to mapPoints, but ignores any translation in the matrix.
442 @param dst Where the transformed coordinates are written. It must
443 contain at least count entries
444 @param src The original coordinates that are to be transformed. It
445 must contain at least count entries
446 @param count The number of vectors in src to read, and then transform
447 into dst.
448 */
449 void mapVectors(SkVector dst[], const SkVector src[], int count) const;
451 /** Apply this matrix to the array of vectors specified by src, and write
452 the transformed vectors into the array of vectors specified by dst.
453 This is similar to mapPoints, but ignores any translation in the matrix.
454 @param vecs The vectors to be transformed. It must contain at least
455 count entries
456 @param count The number of vectors in vecs.
457 */
458 void mapVectors(SkVector vecs[], int count) const {
459 this->mapVectors(vecs, vecs, count);
460 }
462 /** Apply this matrix to the src rectangle, and write the transformed
463 rectangle into dst. This is accomplished by transforming the 4 corners
464 of src, and then setting dst to the bounds of those points.
465 @param dst Where the transformed rectangle is written.
466 @param src The original rectangle to be transformed.
467 @return the result of calling rectStaysRect()
468 */
469 bool mapRect(SkRect* dst, const SkRect& src) const;
471 /** Apply this matrix to the rectangle, and write the transformed rectangle
472 back into it. This is accomplished by transforming the 4 corners of
473 rect, and then setting it to the bounds of those points
474 @param rect The rectangle to transform.
475 @return the result of calling rectStaysRect()
476 */
477 bool mapRect(SkRect* rect) const {
478 return this->mapRect(rect, *rect);
479 }
481 /** Apply this matrix to the src rectangle, and write the four transformed
482 points into dst. The points written to dst will be the original top-left, top-right,
483 bottom-right, and bottom-left points transformed by the matrix.
484 @param dst Where the transformed quad is written.
485 @param rect The original rectangle to be transformed.
486 */
487 void mapRectToQuad(SkPoint dst[4], const SkRect& rect) const {
488 // This could potentially be faster if we only transformed each x and y of the rect once.
489 rect.toQuad(dst);
490 this->mapPoints(dst, 4);
491 }
493 /** Return the mean radius of a circle after it has been mapped by
494 this matrix. NOTE: in perspective this value assumes the circle
495 has its center at the origin.
496 */
497 SkScalar mapRadius(SkScalar radius) const;
499 typedef void (*MapXYProc)(const SkMatrix& mat, SkScalar x, SkScalar y,
500 SkPoint* result);
502 static MapXYProc GetMapXYProc(TypeMask mask) {
503 SkASSERT((mask & ~kAllMasks) == 0);
504 return gMapXYProcs[mask & kAllMasks];
505 }
507 MapXYProc getMapXYProc() const {
508 return GetMapXYProc(this->getType());
509 }
511 typedef void (*MapPtsProc)(const SkMatrix& mat, SkPoint dst[],
512 const SkPoint src[], int count);
514 static MapPtsProc GetMapPtsProc(TypeMask mask) {
515 SkASSERT((mask & ~kAllMasks) == 0);
516 return gMapPtsProcs[mask & kAllMasks];
517 }
519 MapPtsProc getMapPtsProc() const {
520 return GetMapPtsProc(this->getType());
521 }
523 /** If the matrix can be stepped in X (not complex perspective)
524 then return true and if step[XY] is not null, return the step[XY] value.
525 If it cannot, return false and ignore step.
526 */
527 bool fixedStepInX(SkScalar y, SkFixed* stepX, SkFixed* stepY) const;
529 /** Efficient comparison of two matrices. It distinguishes between zero and
530 * negative zero. It will return false when the sign of zero values is the
531 * only difference between the two matrices. It considers NaN values to be
532 * equal to themselves. So a matrix full of NaNs is "cheap equal" to
533 * another matrix full of NaNs iff the NaN values are bitwise identical
534 * while according to strict the strict == test a matrix with a NaN value
535 * is equal to nothing, including itself.
536 */
537 bool cheapEqualTo(const SkMatrix& m) const {
538 return 0 == memcmp(fMat, m.fMat, sizeof(fMat));
539 }
541 friend bool operator==(const SkMatrix& a, const SkMatrix& b);
542 friend bool operator!=(const SkMatrix& a, const SkMatrix& b) {
543 return !(a == b);
544 }
546 enum {
547 // writeTo/readFromMemory will never return a value larger than this
548 kMaxFlattenSize = 9 * sizeof(SkScalar) + sizeof(uint32_t)
549 };
550 // return the number of bytes written, whether or not buffer is null
551 size_t writeToMemory(void* buffer) const;
552 /**
553 * Reads data from the buffer parameter
554 *
555 * @param buffer Memory to read from
556 * @param length Amount of memory available in the buffer
557 * @return number of bytes read (must be a multiple of 4) or
558 * 0 if there was not enough memory available
559 */
560 size_t readFromMemory(const void* buffer, size_t length);
562 SkDEVCODE(void dump() const;)
563 SK_TO_STRING_NONVIRT()
565 /**
566 * Calculates the minimum stretching factor of the matrix. If the matrix has
567 * perspective -1 is returned.
568 *
569 * @return minumum strecthing factor
570 */
571 SkScalar getMinStretch() const;
573 /**
574 * Calculates the maximum stretching factor of the matrix. If the matrix has
575 * perspective -1 is returned.
576 *
577 * @return maximum strecthing factor
578 */
579 SkScalar getMaxStretch() const;
581 /**
582 * Return a reference to a const identity matrix
583 */
584 static const SkMatrix& I();
586 /**
587 * Return a reference to a const matrix that is "invalid", one that could
588 * never be used.
589 */
590 static const SkMatrix& InvalidMatrix();
592 /**
593 * Testing routine; the matrix's type cache should never need to be
594 * manually invalidated during normal use.
595 */
596 void dirtyMatrixTypeCache() {
597 this->setTypeMask(kUnknown_Mask);
598 }
600 private:
601 enum {
602 /** Set if the matrix will map a rectangle to another rectangle. This
603 can be true if the matrix is scale-only, or rotates a multiple of
604 90 degrees.
606 This bit will be set on identity matrices
607 */
608 kRectStaysRect_Mask = 0x10,
610 /** Set if the perspective bit is valid even though the rest of
611 the matrix is Unknown.
612 */
613 kOnlyPerspectiveValid_Mask = 0x40,
615 kUnknown_Mask = 0x80,
617 kORableMasks = kTranslate_Mask |
618 kScale_Mask |
619 kAffine_Mask |
620 kPerspective_Mask,
622 kAllMasks = kTranslate_Mask |
623 kScale_Mask |
624 kAffine_Mask |
625 kPerspective_Mask |
626 kRectStaysRect_Mask
627 };
629 SkScalar fMat[9];
630 mutable uint32_t fTypeMask;
632 uint8_t computeTypeMask() const;
633 uint8_t computePerspectiveTypeMask() const;
635 void setTypeMask(int mask) {
636 // allow kUnknown or a valid mask
637 SkASSERT(kUnknown_Mask == mask || (mask & kAllMasks) == mask ||
638 ((kUnknown_Mask | kOnlyPerspectiveValid_Mask) & mask)
639 == (kUnknown_Mask | kOnlyPerspectiveValid_Mask));
640 fTypeMask = SkToU8(mask);
641 }
643 void orTypeMask(int mask) {
644 SkASSERT((mask & kORableMasks) == mask);
645 fTypeMask = SkToU8(fTypeMask | mask);
646 }
648 void clearTypeMask(int mask) {
649 // only allow a valid mask
650 SkASSERT((mask & kAllMasks) == mask);
651 fTypeMask &= ~mask;
652 }
654 TypeMask getPerspectiveTypeMaskOnly() const {
655 if ((fTypeMask & kUnknown_Mask) &&
656 !(fTypeMask & kOnlyPerspectiveValid_Mask)) {
657 fTypeMask = this->computePerspectiveTypeMask();
658 }
659 return (TypeMask)(fTypeMask & 0xF);
660 }
662 /** Returns true if we already know that the matrix is identity;
663 false otherwise.
664 */
665 bool isTriviallyIdentity() const {
666 if (fTypeMask & kUnknown_Mask) {
667 return false;
668 }
669 return ((fTypeMask & 0xF) == 0);
670 }
672 bool SK_WARN_UNUSED_RESULT invertNonIdentity(SkMatrix* inverse) const;
674 static bool Poly2Proc(const SkPoint[], SkMatrix*, const SkPoint& scale);
675 static bool Poly3Proc(const SkPoint[], SkMatrix*, const SkPoint& scale);
676 static bool Poly4Proc(const SkPoint[], SkMatrix*, const SkPoint& scale);
678 static void Identity_xy(const SkMatrix&, SkScalar, SkScalar, SkPoint*);
679 static void Trans_xy(const SkMatrix&, SkScalar, SkScalar, SkPoint*);
680 static void Scale_xy(const SkMatrix&, SkScalar, SkScalar, SkPoint*);
681 static void ScaleTrans_xy(const SkMatrix&, SkScalar, SkScalar, SkPoint*);
682 static void Rot_xy(const SkMatrix&, SkScalar, SkScalar, SkPoint*);
683 static void RotTrans_xy(const SkMatrix&, SkScalar, SkScalar, SkPoint*);
684 static void Persp_xy(const SkMatrix&, SkScalar, SkScalar, SkPoint*);
686 static const MapXYProc gMapXYProcs[];
688 static void Identity_pts(const SkMatrix&, SkPoint[], const SkPoint[], int);
689 static void Trans_pts(const SkMatrix&, SkPoint dst[], const SkPoint[], int);
690 static void Scale_pts(const SkMatrix&, SkPoint dst[], const SkPoint[], int);
691 static void ScaleTrans_pts(const SkMatrix&, SkPoint dst[], const SkPoint[],
692 int count);
693 static void Rot_pts(const SkMatrix&, SkPoint dst[], const SkPoint[], int);
694 static void RotTrans_pts(const SkMatrix&, SkPoint dst[], const SkPoint[],
695 int count);
696 static void Persp_pts(const SkMatrix&, SkPoint dst[], const SkPoint[], int);
698 static const MapPtsProc gMapPtsProcs[];
700 friend class SkPerspIter;
701 };
703 #endif