10 #ifndef SkMatrix_DEFINED
11 #define SkMatrix_DEFINED
25 SK_BEGIN_REQUIRE_DENSE
28 static SkMatrix SK_WARN_UNUSED_RESULT MakeScale(SkScalar sx, SkScalar sy) {
34 static SkMatrix SK_WARN_UNUSED_RESULT MakeScale(SkScalar scale) {
40 static SkMatrix SK_WARN_UNUSED_RESULT MakeTrans(SkScalar dx, SkScalar dy) {
51 kTranslate_Mask = 0x01,
54 kPerspective_Mask = 0x08
64 if (fTypeMask & kUnknown_Mask) {
65 fTypeMask = this->computeTypeMask();
74 return this->getType() == 0;
77 bool isScaleTranslate()
const {
78 return !(this->getType() & ~(kScale_Mask | kTranslate_Mask));
86 if (fTypeMask & kUnknown_Mask) {
87 fTypeMask = this->computeTypeMask();
89 return (fTypeMask & kRectStaysRect_Mask) != 0;
92 bool preservesAxisAlignment()
const {
return this->rectStaysRect(); }
98 return SkToBool(this->getPerspectiveTypeMaskOnly() &
105 bool isSimilarity(SkScalar tol = SK_ScalarNearlyZero)
const;
111 bool preservesRightAngles(SkScalar tol = SK_ScalarNearlyZero)
const;
137 SkScalar operator[](
int index)
const {
138 SkASSERT((
unsigned)index < 9);
142 SkScalar
get(
int index)
const {
143 SkASSERT((
unsigned)index < 9);
147 SkScalar getScaleX()
const {
return fMat[kMScaleX]; }
148 SkScalar getScaleY()
const {
return fMat[kMScaleY]; }
149 SkScalar getSkewY()
const {
return fMat[kMSkewY]; }
150 SkScalar getSkewX()
const {
return fMat[kMSkewX]; }
151 SkScalar getTranslateX()
const {
return fMat[kMTransX]; }
152 SkScalar getTranslateY()
const {
return fMat[kMTransY]; }
153 SkScalar getPerspX()
const {
return fMat[kMPersp0]; }
154 SkScalar getPerspY()
const {
return fMat[kMPersp1]; }
156 SkScalar& operator[](
int index) {
157 SkASSERT((
unsigned)index < 9);
158 this->setTypeMask(kUnknown_Mask);
162 void set(
int index, SkScalar value) {
163 SkASSERT((
unsigned)index < 9);
165 this->setTypeMask(kUnknown_Mask);
168 void setScaleX(SkScalar v) { this->set(kMScaleX, v); }
169 void setScaleY(SkScalar v) { this->set(kMScaleY, v); }
170 void setSkewY(SkScalar v) { this->set(kMSkewY, v); }
171 void setSkewX(SkScalar v) { this->set(kMSkewX, v); }
172 void setTranslateX(SkScalar v) { this->set(kMTransX, v); }
173 void setTranslateY(SkScalar v) { this->set(kMTransY, v); }
174 void setPerspX(SkScalar v) { this->set(kMPersp0, v); }
175 void setPerspY(SkScalar v) { this->set(kMPersp1, v); }
177 void setAll(SkScalar scaleX, SkScalar skewX, SkScalar transX,
178 SkScalar skewY, SkScalar scaleY, SkScalar transY,
179 SkScalar persp0, SkScalar persp1, SkScalar persp2) {
180 fMat[kMScaleX] = scaleX;
181 fMat[kMSkewX] = skewX;
182 fMat[kMTransX] = transX;
183 fMat[kMSkewY] = skewY;
184 fMat[kMScaleY] = scaleY;
185 fMat[kMTransY] = transY;
186 fMat[kMPersp0] = persp0;
187 fMat[kMPersp1] = persp1;
188 fMat[kMPersp2] = persp2;
189 this->setTypeMask(kUnknown_Mask);
196 void get9(SkScalar buffer[9])
const {
197 memcpy(buffer, fMat, 9 *
sizeof(SkScalar));
207 void set9(
const SkScalar buffer[9]);
213 void setIdentity() { this->reset(); }
217 void setTranslate(SkScalar dx, SkScalar dy);
218 void setTranslate(
const SkVector& v) { this->setTranslate(v.fX, v.fY); }
224 void setScale(SkScalar sx, SkScalar sy, SkScalar px, SkScalar py);
227 void setScale(SkScalar sx, SkScalar sy);
231 bool setIDiv(
int divx,
int divy);
236 void setRotate(SkScalar degrees, SkScalar px, SkScalar py);
239 void setRotate(SkScalar degrees);
244 void setSinCos(SkScalar sinValue, SkScalar cosValue,
245 SkScalar px, SkScalar py);
248 void setSinCos(SkScalar sinValue, SkScalar cosValue);
256 void setSkew(SkScalar kx, SkScalar ky, SkScalar px, SkScalar py);
259 void setSkew(SkScalar kx, SkScalar ky);
269 void preTranslate(SkScalar dx, SkScalar dy);
273 void preScale(SkScalar sx, SkScalar sy, SkScalar px, SkScalar py);
277 void preScale(SkScalar sx, SkScalar sy);
281 void preRotate(SkScalar degrees, SkScalar px, SkScalar py);
285 void preRotate(SkScalar degrees);
289 void preSkew(SkScalar kx, SkScalar ky, SkScalar px, SkScalar py);
293 void preSkew(SkScalar kx, SkScalar ky);
297 void preConcat(
const SkMatrix& other);
302 void postTranslate(SkScalar dx, SkScalar dy);
306 void postScale(SkScalar sx, SkScalar sy, SkScalar px, SkScalar py);
310 void postScale(SkScalar sx, SkScalar sy);
314 bool postIDiv(
int divx,
int divy);
318 void postRotate(SkScalar degrees, SkScalar px, SkScalar py);
322 void postRotate(SkScalar degrees);
326 void postSkew(SkScalar kx, SkScalar ky, SkScalar px, SkScalar py);
330 void postSkew(SkScalar kx, SkScalar ky);
334 void postConcat(
const SkMatrix& other);
372 bool setRectToRect(
const SkRect& src,
const SkRect& dst, ScaleToFit stf);
386 bool setPolyToPoly(
const SkPoint src[],
const SkPoint dst[],
int count);
394 if (this->isIdentity()) {
400 return this->invertNonIdentity(inverse);
408 static void SetAffineIdentity(SkScalar affine[6]);
415 bool SK_WARN_UNUSED_RESULT asAffine(SkScalar affine[6])
const;
420 void setAffine(
const SkScalar affine[6]);
433 SkASSERT((dst && src && count > 0) || 0 == count);
435 SkASSERT(src == dst || &dst[count] <= &src[0] || &src[count] <= &dst[0]);
436 this->getMapPtsProc()(*
this, dst, src, count);
447 this->mapPoints(pts, pts, count);
454 SkASSERT(stride >=
sizeof(
SkPoint));
455 SkASSERT(0 == stride %
sizeof(SkScalar));
456 for (
int i = 0; i < count; ++i) {
457 this->mapPoints(pts, pts, 1);
458 pts = (
SkPoint*)((intptr_t)pts + stride);
465 size_t stride,
int count)
const {
466 SkASSERT(stride >=
sizeof(
SkPoint));
467 SkASSERT(0 == stride %
sizeof(SkScalar));
468 for (
int i = 0; i < count; ++i) {
469 this->mapPoints(dst, src, 1);
470 src = (
SkPoint*)((intptr_t)src + stride);
471 dst = (
SkPoint*)((intptr_t)dst + stride);
486 void mapHomogeneousPoints(SkScalar dst[],
const SkScalar src[],
int count)
const;
488 void mapXY(SkScalar x, SkScalar y,
SkPoint* result)
const {
490 this->getMapXYProc()(*
this, x, y, result);
493 SkPoint mapXY(SkScalar x, SkScalar y)
const {
495 this->getMapXYProc()(*
this, x, y, &result);
519 this->mapVectors(vecs, vecs, count);
522 void mapVector(SkScalar dx, SkScalar dy,
SkVector* result)
const {
524 this->mapVectors(result, &vec, 1);
527 SkVector mapVector(SkScalar dx, SkScalar dy)
const {
529 this->mapVectors(&vec, &vec, 1);
549 return this->mapRect(rect, *rect);
561 this->mapPoints(dst, 4);
568 void mapRectScaleTranslate(
SkRect* dst,
const SkRect& src)
const;
574 SkScalar mapRadius(SkScalar radius)
const;
576 typedef void (*MapXYProc)(
const SkMatrix& mat, SkScalar x, SkScalar y,
579 static MapXYProc GetMapXYProc(TypeMask mask) {
580 SkASSERT((mask & ~kAllMasks) == 0);
581 return gMapXYProcs[mask & kAllMasks];
584 MapXYProc getMapXYProc()
const {
585 return GetMapXYProc(this->getType());
589 const SkPoint src[],
int count);
591 static MapPtsProc GetMapPtsProc(TypeMask mask) {
592 SkASSERT((mask & ~kAllMasks) == 0);
593 return gMapPtsProcs[mask & kAllMasks];
596 MapPtsProc getMapPtsProc()
const {
597 return GetMapPtsProc(this->getType());
603 bool isFixedStepInX()
const;
609 SkVector fixedStepInX(SkScalar y)
const;
620 return 0 == memcmp(fMat, m.fMat,
sizeof(fMat));
630 kMaxFlattenSize = 9 *
sizeof(SkScalar) +
sizeof(uint32_t)
633 size_t writeToMemory(
void* buffer)
const;
642 size_t readFromMemory(
const void* buffer,
size_t length);
654 SkScalar getMinScale()
const;
663 SkScalar getMaxScale()
const;
670 bool SK_WARN_UNUSED_RESULT getMinMaxScales(SkScalar scaleFactors[2])
const;
683 bool decomposeScale(
SkSize* scale,
SkMatrix* remaining = NULL)
const;
694 static const SkMatrix& InvalidMatrix();
710 this->setTypeMask(kUnknown_Mask);
730 if (sx != 1 || sy != 1) {
734 mask |= kTranslate_Mask;
736 this->setTypeMask(mask | kRectStaysRect_Mask);
747 kRectStaysRect_Mask = 0x10,
752 kOnlyPerspectiveValid_Mask = 0x40,
754 kUnknown_Mask = 0x80,
756 kORableMasks = kTranslate_Mask |
761 kAllMasks = kTranslate_Mask |
769 mutable uint32_t fTypeMask;
773 bool isFinite()
const {
return SkScalarsAreFinite(fMat, 9); }
775 static void ComputeInv(SkScalar dst[9],
const SkScalar src[9],
double invDet,
bool isPersp);
777 uint8_t computeTypeMask()
const;
778 uint8_t computePerspectiveTypeMask()
const;
780 void setTypeMask(
int mask) {
782 SkASSERT(kUnknown_Mask == mask || (mask & kAllMasks) == mask ||
783 ((kUnknown_Mask | kOnlyPerspectiveValid_Mask) & mask)
784 == (kUnknown_Mask | kOnlyPerspectiveValid_Mask));
785 fTypeMask = SkToU8(mask);
788 void orTypeMask(
int mask) {
789 SkASSERT((mask & kORableMasks) == mask);
790 fTypeMask = SkToU8(fTypeMask | mask);
793 void clearTypeMask(
int mask) {
795 SkASSERT((mask & kAllMasks) == mask);
796 fTypeMask = fTypeMask & ~mask;
799 TypeMask getPerspectiveTypeMaskOnly()
const {
800 if ((fTypeMask & kUnknown_Mask) &&
801 !(fTypeMask & kOnlyPerspectiveValid_Mask)) {
802 fTypeMask = this->computePerspectiveTypeMask();
804 return (TypeMask)(fTypeMask & 0xF);
811 if (fTypeMask & kUnknown_Mask) {
814 return ((fTypeMask & 0xF) == 0);
817 bool SK_WARN_UNUSED_RESULT invertNonIdentity(
SkMatrix* inverse)
const;
823 static void Identity_xy(
const SkMatrix&, SkScalar, SkScalar,
SkPoint*);
826 static void ScaleTrans_xy(
const SkMatrix&, SkScalar, SkScalar,
SkPoint*);
828 static void RotTrans_xy(
const SkMatrix&, SkScalar, SkScalar,
SkPoint*);
831 static const MapXYProc gMapXYProcs[];
842 static const MapPtsProc gMapPtsProcs[];
844 friend class SkPerspIter;
845 friend class SkMatrixPriv;
TypeMask
Enum of bit fields for the mask return by getType().
Definition: SkMatrix.h:49
bool isFinite() const
Are all elements of the matrix finite?
Definition: SkMatrix.h:773
ScaleToFit
Definition: SkMatrix.h:336
bool isIdentity() const
Returns true if the matrix is identity.
Definition: SkMatrix.h:73
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:196
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:432
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:709
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:518
The SkMatrix class holds a 3x3 matrix for transforming coordinates.
Definition: SkMatrix.h:26
void setTranslate(SkScalar dx, SkScalar dy)
Set the matrix to translate by (dx, dy).
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:392
#define SkToBool(cond)
Returns 0 or 1 based on the condition.
Definition: SkTypes.h:287
Compute a scale that will maintain the original src aspect ratio, but will also ensure that src fits ...
Definition: SkMatrix.h:354
void mapPoints(SkPoint pts[], int count) const
Apply this matrix to the array of points, overwriting it with the transformed values.
Definition: SkMatrix.h:446
Scale in X and Y independently, so that src matches dst exactly.
Definition: SkMatrix.h:341
TypeMask getType() const
Returns a bitfield describing the transformations the matrix may perform.
Definition: SkMatrix.h:63
bool mapRect(SkRect *rect) const
Apply this matrix to the rectangle, and write the transformed rectangle back into it...
Definition: SkMatrix.h:548
static SkMatrix Concat(const SkMatrix &a, const SkMatrix &b)
Return the concatenation of two matrices, a * b.
Definition: SkMatrix.h:699
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:810
void mapPointsWithStride(SkPoint dst[], SkPoint src[], size_t stride, int count) const
Like mapPoints but with custom byte stride between the points.
Definition: SkMatrix.h:464
bool hasPerspective() const
Returns true if the matrix contains perspective elements.
Definition: SkMatrix.h:97
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:558
bool cheapEqualTo(const SkMatrix &m) const
Efficient comparison of two matrices.
Definition: SkMatrix.h:619
void setScaleTranslate(SkScalar sx, SkScalar sy, SkScalar tx, SkScalar ty)
Initialize the matrix to be scale + post-translate.
Definition: SkMatrix.h:716
Compute a scale that will maintain the original src aspect ratio, but will also ensure that src fits ...
Definition: SkMatrix.h:348
void mapPointsWithStride(SkPoint pts[], size_t stride, int count) const
Like mapPoints but with custom byte stride between the points.
Definition: SkMatrix.h:453
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:85