10 #ifndef SkMatrix_DEFINED
11 #define SkMatrix_DEFINED
27 SK_BEGIN_REQUIRE_DENSE
30 static SkMatrix SK_WARN_UNUSED_RESULT MakeScale(SkScalar sx, SkScalar sy) {
36 static SkMatrix SK_WARN_UNUSED_RESULT MakeScale(SkScalar scale) {
42 static SkMatrix SK_WARN_UNUSED_RESULT MakeTrans(SkScalar dx, SkScalar dy) {
53 kTranslate_Mask = 0x01,
56 kPerspective_Mask = 0x08
66 if (fTypeMask & kUnknown_Mask) {
67 fTypeMask = this->computeTypeMask();
76 return this->getType() == 0;
79 bool isScaleTranslate()
const {
80 return !(this->getType() & ~(kScale_Mask | kTranslate_Mask));
88 if (fTypeMask & kUnknown_Mask) {
89 fTypeMask = this->computeTypeMask();
91 return (fTypeMask & kRectStaysRect_Mask) != 0;
94 bool preservesAxisAlignment()
const {
return this->rectStaysRect(); }
100 return SkToBool(this->getPerspectiveTypeMaskOnly() &
107 bool isSimilarity(SkScalar tol = SK_ScalarNearlyZero)
const;
113 bool preservesRightAngles(SkScalar tol = SK_ScalarNearlyZero)
const;
139 SkScalar operator[](
int index)
const {
140 SkASSERT((
unsigned)index < 9);
144 SkScalar
get(
int index)
const {
145 SkASSERT((
unsigned)index < 9);
149 SkScalar getScaleX()
const {
return fMat[kMScaleX]; }
150 SkScalar getScaleY()
const {
return fMat[kMScaleY]; }
151 SkScalar getSkewY()
const {
return fMat[kMSkewY]; }
152 SkScalar getSkewX()
const {
return fMat[kMSkewX]; }
153 SkScalar getTranslateX()
const {
return fMat[kMTransX]; }
154 SkScalar getTranslateY()
const {
return fMat[kMTransY]; }
155 SkScalar getPerspX()
const {
return fMat[kMPersp0]; }
156 SkScalar getPerspY()
const {
return fMat[kMPersp1]; }
158 SkScalar& operator[](
int index) {
159 SkASSERT((
unsigned)index < 9);
160 this->setTypeMask(kUnknown_Mask);
164 void set(
int index, SkScalar value) {
165 SkASSERT((
unsigned)index < 9);
167 this->setTypeMask(kUnknown_Mask);
170 void setScaleX(SkScalar v) { this->set(kMScaleX, v); }
171 void setScaleY(SkScalar v) { this->set(kMScaleY, v); }
172 void setSkewY(SkScalar v) { this->set(kMSkewY, v); }
173 void setSkewX(SkScalar v) { this->set(kMSkewX, v); }
174 void setTranslateX(SkScalar v) { this->set(kMTransX, v); }
175 void setTranslateY(SkScalar v) { this->set(kMTransY, v); }
176 void setPerspX(SkScalar v) { this->set(kMPersp0, v); }
177 void setPerspY(SkScalar v) { this->set(kMPersp1, v); }
179 void setAll(SkScalar scaleX, SkScalar skewX, SkScalar transX,
180 SkScalar skewY, SkScalar scaleY, SkScalar transY,
181 SkScalar persp0, SkScalar persp1, SkScalar persp2) {
182 fMat[kMScaleX] = scaleX;
183 fMat[kMSkewX] = skewX;
184 fMat[kMTransX] = transX;
185 fMat[kMSkewY] = skewY;
186 fMat[kMScaleY] = scaleY;
187 fMat[kMTransY] = transY;
188 fMat[kMPersp0] = persp0;
189 fMat[kMPersp1] = persp1;
190 fMat[kMPersp2] = persp2;
191 this->setTypeMask(kUnknown_Mask);
198 void get9(SkScalar buffer[9])
const {
199 memcpy(buffer, fMat, 9 *
sizeof(SkScalar));
209 void set9(
const SkScalar buffer[9]);
215 void setIdentity() { this->reset(); }
219 void setTranslate(SkScalar dx, SkScalar dy);
220 void setTranslate(
const SkVector& v) { this->setTranslate(v.fX, v.fY); }
226 void setScale(SkScalar sx, SkScalar sy, SkScalar px, SkScalar py);
229 void setScale(SkScalar sx, SkScalar sy);
233 bool setIDiv(
int divx,
int divy);
238 void setRotate(SkScalar degrees, SkScalar px, SkScalar py);
241 void setRotate(SkScalar degrees);
246 void setSinCos(SkScalar sinValue, SkScalar cosValue,
247 SkScalar px, SkScalar py);
250 void setSinCos(SkScalar sinValue, SkScalar cosValue);
258 void setSkew(SkScalar kx, SkScalar ky, SkScalar px, SkScalar py);
261 void setSkew(SkScalar kx, SkScalar ky);
271 void preTranslate(SkScalar dx, SkScalar dy);
275 void preScale(SkScalar sx, SkScalar sy, SkScalar px, SkScalar py);
279 void preScale(SkScalar sx, SkScalar sy);
283 void preRotate(SkScalar degrees, SkScalar px, SkScalar py);
287 void preRotate(SkScalar degrees);
291 void preSkew(SkScalar kx, SkScalar ky, SkScalar px, SkScalar py);
295 void preSkew(SkScalar kx, SkScalar ky);
299 void preConcat(
const SkMatrix& other);
304 void postTranslate(SkScalar dx, SkScalar dy);
308 void postScale(SkScalar sx, SkScalar sy, SkScalar px, SkScalar py);
312 void postScale(SkScalar sx, SkScalar sy);
316 bool postIDiv(
int divx,
int divy);
320 void postRotate(SkScalar degrees, SkScalar px, SkScalar py);
324 void postRotate(SkScalar degrees);
328 void postSkew(SkScalar kx, SkScalar ky, SkScalar px, SkScalar py);
332 void postSkew(SkScalar kx, SkScalar ky);
336 void postConcat(
const SkMatrix& other);
374 bool setRectToRect(
const SkRect& src,
const SkRect& dst, ScaleToFit stf);
388 bool setPolyToPoly(
const SkPoint src[],
const SkPoint dst[],
int count);
396 if (this->isIdentity()) {
402 return this->invertNonIdentity(inverse);
410 static void SetAffineIdentity(SkScalar affine[6]);
417 bool SK_WARN_UNUSED_RESULT asAffine(SkScalar affine[6])
const;
422 void setAffine(
const SkScalar affine[6]);
435 SkASSERT((dst && src && count > 0) || 0 == count);
437 SkASSERT(src == dst || &dst[count] <= &src[0] || &src[count] <= &dst[0]);
438 this->getMapPtsProc()(*
this, dst, src, count);
449 this->mapPoints(pts, pts, count);
456 SkASSERT(stride >=
sizeof(
SkPoint));
457 SkASSERT(0 == stride %
sizeof(SkScalar));
458 for (
int i = 0; i < count; ++i) {
459 this->mapPoints(pts, pts, 1);
460 pts = (
SkPoint*)((intptr_t)pts + stride);
467 SkASSERT(stride >=
sizeof(
SkPoint));
468 SkASSERT(0 == stride %
sizeof(SkScalar));
469 for (
int i = 0; i < count; ++i) {
470 this->mapPoints(dst, src, 1);
471 src = (
SkPoint*)((intptr_t)src + stride);
472 dst = (
SkPoint*)((intptr_t)dst + stride);
487 void mapHomogeneousPoints(SkScalar dst[],
const SkScalar src[],
int count)
const;
489 void mapXY(SkScalar x, SkScalar y,
SkPoint* result)
const {
491 this->getMapXYProc()(*
this, x, y, result);
494 SkPoint mapXY(SkScalar x, SkScalar y)
const {
496 this->getMapXYProc()(*
this, x, y, &result);
520 this->mapVectors(vecs, vecs, count);
523 void mapVector(SkScalar dx, SkScalar dy,
SkVector* result)
const {
525 this->mapVectors(result, &vec, 1);
528 SkVector mapVector(SkScalar dx, SkScalar dy)
const {
530 this->mapVectors(&vec, &vec, 1);
550 return this->mapRect(rect, *rect);
562 this->mapPoints(dst, 4);
569 void mapRectScaleTranslate(
SkRect* dst,
const SkRect& src)
const;
575 SkScalar mapRadius(SkScalar radius)
const;
577 typedef void (*MapXYProc)(
const SkMatrix& mat, SkScalar x, SkScalar y,
580 static MapXYProc GetMapXYProc(TypeMask mask) {
581 SkASSERT((mask & ~kAllMasks) == 0);
582 return gMapXYProcs[mask & kAllMasks];
585 MapXYProc getMapXYProc()
const {
586 return GetMapXYProc(this->getType());
590 const SkPoint src[],
int count);
592 static MapPtsProc GetMapPtsProc(TypeMask mask) {
593 SkASSERT((mask & ~kAllMasks) == 0);
594 return gMapPtsProcs[mask & kAllMasks];
597 MapPtsProc getMapPtsProc()
const {
598 return GetMapPtsProc(this->getType());
604 bool isFixedStepInX()
const;
610 SkVector fixedStepInX(SkScalar y)
const;
621 return 0 == memcmp(fMat, m.fMat,
sizeof(fMat));
632 kMaxFlattenSize = 9 *
sizeof(SkScalar) +
sizeof(uint32_t)
635 size_t writeToMemory(
void* buffer)
const;
644 size_t readFromMemory(
const void* buffer,
size_t length);
656 SkScalar getMinScale()
const;
665 SkScalar getMaxScale()
const;
672 bool SK_WARN_UNUSED_RESULT getMinMaxScales(SkScalar scaleFactors[2])
const;
685 bool decomposeScale(
SkSize* scale,
SkMatrix* remaining = NULL)
const;
696 static const SkMatrix& InvalidMatrix();
712 this->setTypeMask(kUnknown_Mask);
732 if (sx != 1 || sy != 1) {
736 mask |= kTranslate_Mask;
738 this->setTypeMask(mask | kRectStaysRect_Mask);
744 bool isFinite()
const {
return SkScalarsAreFinite(fMat, 9); }
754 kRectStaysRect_Mask = 0x10,
759 kOnlyPerspectiveValid_Mask = 0x40,
761 kUnknown_Mask = 0x80,
763 kORableMasks = kTranslate_Mask |
768 kAllMasks = kTranslate_Mask |
776 mutable uint32_t fTypeMask;
778 static void ComputeInv(SkScalar dst[9],
const SkScalar src[9],
double invDet,
bool isPersp);
780 uint8_t computeTypeMask()
const;
781 uint8_t computePerspectiveTypeMask()
const;
783 void setTypeMask(
int mask) {
785 SkASSERT(kUnknown_Mask == mask || (mask & kAllMasks) == mask ||
786 ((kUnknown_Mask | kOnlyPerspectiveValid_Mask) & mask)
787 == (kUnknown_Mask | kOnlyPerspectiveValid_Mask));
788 fTypeMask = SkToU8(mask);
791 void orTypeMask(
int mask) {
792 SkASSERT((mask & kORableMasks) == mask);
793 fTypeMask = SkToU8(fTypeMask | mask);
796 void clearTypeMask(
int mask) {
798 SkASSERT((mask & kAllMasks) == mask);
799 fTypeMask = fTypeMask & ~mask;
802 TypeMask getPerspectiveTypeMaskOnly()
const {
803 if ((fTypeMask & kUnknown_Mask) &&
804 !(fTypeMask & kOnlyPerspectiveValid_Mask)) {
805 fTypeMask = this->computePerspectiveTypeMask();
807 return (TypeMask)(fTypeMask & 0xF);
814 if (fTypeMask & kUnknown_Mask) {
817 return ((fTypeMask & 0xF) == 0);
820 inline void updateTranslateMask() {
821 if ((fMat[kMTransX] != 0) | (fMat[kMTransY] != 0)) {
822 fTypeMask |= kTranslate_Mask;
824 fTypeMask &= ~kTranslate_Mask;
828 bool SK_WARN_UNUSED_RESULT invertNonIdentity(
SkMatrix* inverse)
const;
834 static void Identity_xy(
const SkMatrix&, SkScalar, SkScalar,
SkPoint*);
837 static void ScaleTrans_xy(
const SkMatrix&, SkScalar, SkScalar,
SkPoint*);
839 static void RotTrans_xy(
const SkMatrix&, SkScalar, SkScalar,
SkPoint*);
842 static const MapXYProc gMapXYProcs[];
853 static const MapPtsProc gMapPtsProcs[];
855 friend class SkPerspIter;
856 friend class SkMatrixPriv;
TypeMask
Enum of bit fields for the mask return by getType().
Definition: SkMatrix.h:51
bool isFinite() const
Are all elements of the matrix finite?
Definition: SkMatrix.h:744
ScaleToFit
Definition: SkMatrix.h:338
bool isIdentity() const
Returns true if the matrix is identity.
Definition: SkMatrix.h:75
void get9(SkScalar buffer[9]) const
Copy the 9 scalars for this matrix into buffer, in the same order as the kMScaleX enum...
Definition: SkMatrix.h:198
void setScale(SkScalar sx, SkScalar sy, SkScalar px, SkScalar py)
Set the matrix to scale by sx and sy, with a pivot point at (px, py).
void mapPoints(SkPoint dst[], const SkPoint src[], int count) const
Apply this matrix to the array of points specified by src, and write the transformed points into the ...
Definition: SkMatrix.h:434
void setConcat(const SkMatrix &a, const SkMatrix &b)
Set the matrix to the concatenation of the two specified matrices.
Definition: SkPoint.h:156
void dirtyMatrixTypeCache()
Testing routine; the matrix's type cache should never need to be manually invalidated during normal u...
Definition: SkMatrix.h:711
bool setRectToRect(const SkRect &src, const SkRect &dst, ScaleToFit stf)
Set the matrix to the scale and translate values that map the source rectangle to the destination rec...
void mapVectors(SkVector vecs[], int count) const
Apply this matrix to the array of vectors specified by src, and write the transformed vectors into th...
Definition: SkMatrix.h:519
The SkMatrix class holds a 3x3 matrix for transforming coordinates.
Definition: SkMatrix.h:28
void setTranslate(SkScalar dx, SkScalar dy)
Set the matrix to translate by (dx, dy).
void mapPointsWithStride(SkPoint dst[], const SkPoint src[], size_t stride, int count) const
Like mapPoints but with custom byte stride between the points.
Definition: SkMatrix.h:466
bool SK_WARN_UNUSED_RESULT invert(SkMatrix *inverse) const
If this matrix can be inverted, return true and if inverse is not null, set inverse to be the inverse...
Definition: SkMatrix.h:394
#define SkToBool(cond)
Returns 0 or 1 based on the condition.
Definition: SkTypes.h:227
Compute a scale that will maintain the original src aspect ratio, but will also ensure that src fits ...
Definition: SkMatrix.h:356
void mapPoints(SkPoint pts[], int count) const
Apply this matrix to the array of points, overwriting it with the transformed values.
Definition: SkMatrix.h:448
Scale in X and Y independently, so that src matches dst exactly.
Definition: SkMatrix.h:343
TypeMask getType() const
Returns a bitfield describing the transformations the matrix may perform.
Definition: SkMatrix.h:65
bool mapRect(SkRect *rect) const
Apply this matrix to the rectangle, and write the transformed rectangle back into it...
Definition: SkMatrix.h:549
static SkMatrix Concat(const SkMatrix &a, const SkMatrix &b)
Return the concatenation of two matrices, a * b.
Definition: SkMatrix.h:701
void toQuad(SkPoint quad[4]) const
return the 4 points that enclose the rectangle (top-left, top-right, bottom-right, bottom-left).
void reset()
Set the matrix to identity.
bool isTriviallyIdentity() const
Returns true if we already know that the matrix is identity; false otherwise.
Definition: SkMatrix.h:813
bool hasPerspective() const
Returns true if the matrix contains perspective elements.
Definition: SkMatrix.h:99
void mapRectToQuad(SkPoint dst[4], const SkRect &rect) const
Apply this matrix to the src rectangle, and write the four transformed points into dst...
Definition: SkMatrix.h:559
bool cheapEqualTo(const SkMatrix &m) const
Efficient comparison of two matrices.
Definition: SkMatrix.h:620
void setScaleTranslate(SkScalar sx, SkScalar sy, SkScalar tx, SkScalar ty)
Initialize the matrix to be scale + post-translate.
Definition: SkMatrix.h:718
Compute a scale that will maintain the original src aspect ratio, but will also ensure that src fits ...
Definition: SkMatrix.h:350
void mapPointsWithStride(SkPoint pts[], size_t stride, int count) const
Like mapPoints but with custom byte stride between the points.
Definition: SkMatrix.h:455
Light weight class for managing strings.
Definition: SkString.h:121
bool rectStaysRect() const
Returns true if will map a rectangle to another rectangle.
Definition: SkMatrix.h:87