8 #ifndef SkMatrix44_DEFINED
9 #define SkMatrix44_DEFINED
14 #ifdef SK_MSCALAR_IS_DOUBLE
15 #ifdef SK_MSCALAR_IS_FLOAT
16 #error "can't define MSCALAR both as DOUBLE and FLOAT"
18 typedef double SkMScalar;
20 static inline double SkFloatToMScalar(
float x) {
21 return static_cast<double>(x);
23 static inline float SkMScalarToFloat(
double x) {
24 return static_cast<float>(x);
26 static inline double SkDoubleToMScalar(
double x) {
29 static inline double SkMScalarToDouble(
double x) {
32 static inline double SkMScalarAbs(
double x) {
35 static const SkMScalar SK_MScalarPI = 3.141592653589793;
37 #define SkMScalarFloor(x) sk_double_floor(x)
38 #define SkMScalarCeil(x) sk_double_ceil(x)
39 #define SkMScalarRound(x) sk_double_round(x)
41 #define SkMScalarFloorToInt(x) sk_double_floor2int(x)
42 #define SkMScalarCeilToInt(x) sk_double_ceil2int(x)
43 #define SkMScalarRoundToInt(x) sk_double_round2int(x)
46 #elif defined SK_MSCALAR_IS_FLOAT
47 #ifdef SK_MSCALAR_IS_DOUBLE
48 #error "can't define MSCALAR both as DOUBLE and FLOAT"
50 typedef float SkMScalar;
52 static inline float SkFloatToMScalar(
float x) {
55 static inline float SkMScalarToFloat(
float x) {
58 static inline float SkDoubleToMScalar(
double x) {
59 return static_cast<float>(x);
61 static inline double SkMScalarToDouble(
float x) {
62 return static_cast<double>(x);
64 static inline float SkMScalarAbs(
float x) {
65 return sk_float_abs(x);
67 static const SkMScalar SK_MScalarPI = 3.14159265f;
69 #define SkMScalarFloor(x) sk_float_floor(x)
70 #define SkMScalarCeil(x) sk_float_ceil(x)
71 #define SkMScalarRound(x) sk_float_round(x)
73 #define SkMScalarFloorToInt(x) sk_float_floor2int(x)
74 #define SkMScalarCeilToInt(x) sk_float_ceil2int(x)
75 #define SkMScalarRoundToInt(x) sk_float_round2int(x)
79 #define SkIntToMScalar(n) static_cast<SkMScalar>(n)
81 #define SkMScalarToScalar(x) SkMScalarToFloat(x)
82 #define SkScalarToMScalar(x) SkFloatToMScalar(x)
84 static const SkMScalar SK_MScalar1 = 1;
92 this->set(0, 0, 0, 1);
95 memcpy(fData, src.fData,
sizeof(fData));
97 SkVector4(SkScalar x, SkScalar y, SkScalar z, SkScalar w = SK_Scalar1) {
105 memcpy(fData, src.fData,
sizeof(fData));
110 return fData[0] == v.fData[0] && fData[1] == v.fData[1] &&
111 fData[2] == v.fData[2] && fData[3] == v.fData[3];
114 return !(*
this == v);
116 bool equals(SkScalar x, SkScalar y, SkScalar z, SkScalar w = SK_Scalar1) {
117 return fData[0] == x && fData[1] == y &&
118 fData[2] == z && fData[3] == w;
121 void set(SkScalar x, SkScalar y, SkScalar z, SkScalar w = SK_Scalar1) {
132 enum Uninitialized_Constructor {
133 kUninitialized_Constructor
135 enum Identity_Constructor {
136 kIdentity_Constructor
142 : fMat{{ 1, 0, 0, 0, },
146 , fTypeMask(kIdentity_Mask)
149 SK_ATTR_DEPRECATED(
"use the constructors that take an enum")
150 SkMatrix44() { this->setIdentity(); }
152 SkMatrix44(
const SkMatrix44& src) {
153 memcpy(fMat, src.fMat,
sizeof(fMat));
154 fTypeMask = src.fTypeMask;
157 SkMatrix44(
const SkMatrix44& a,
const SkMatrix44& b) {
158 this->setConcat(a, b);
161 SkMatrix44& operator=(
const SkMatrix44& src) {
163 memcpy(fMat, src.fMat,
sizeof(fMat));
164 fTypeMask = src.fTypeMask;
169 bool operator==(
const SkMatrix44& other)
const;
170 bool operator!=(
const SkMatrix44& other)
const {
171 return !(other == *
this);
183 SkMatrix44& operator=(
const SkMatrix& src);
189 static const SkMatrix44& I();
193 kTranslate_Mask = 0x01,
196 kPerspective_Mask = 0x08
207 if (fTypeMask & kUnknown_Mask) {
208 fTypeMask = this->computeTypeMask();
210 SkASSERT(!(fTypeMask & kUnknown_Mask));
218 return kIdentity_Mask == this->getType();
225 return !(this->getType() & ~kTranslate_Mask);
232 return !(this->getType() & ~(kScale_Mask | kTranslate_Mask));
239 return !(this->getType() & ~kScale_Mask);
242 inline bool hasPerspective()
const {
243 return SkToBool(this->getType() & kPerspective_Mask);
247 inline void reset() { this->setIdentity();}
255 inline SkMScalar
get(
int row,
int col)
const {
256 SkASSERT((
unsigned)row <= 3);
257 SkASSERT((
unsigned)col <= 3);
258 return fMat[col][row];
267 inline void set(
int row,
int col, SkMScalar value) {
268 SkASSERT((
unsigned)row <= 3);
269 SkASSERT((
unsigned)col <= 3);
270 fMat[col][row] = value;
271 this->dirtyTypeMask();
274 inline double getDouble(
int row,
int col)
const {
275 return SkMScalarToDouble(this->
get(row, col));
277 inline void setDouble(
int row,
int col,
double value) {
278 this->set(row, col, SkDoubleToMScalar(value));
280 inline float getFloat(
int row,
int col)
const {
281 return SkMScalarToFloat(this->
get(row, col));
283 inline void setFloat(
int row,
int col,
float value) {
284 this->set(row, col, SkFloatToMScalar(value));
296 void asColMajorf(
float[])
const;
297 void asColMajord(
double[])
const;
298 void asRowMajorf(
float[])
const;
299 void asRowMajord(
double[])
const;
311 void setColMajorf(
const float[]);
312 void setColMajord(
const double[]);
313 void setRowMajorf(
const float[]);
314 void setRowMajord(
const double[]);
316 #ifdef SK_MSCALAR_IS_FLOAT
317 void setColMajor(
const SkMScalar data[]) { this->setColMajorf(data); }
318 void setRowMajor(
const SkMScalar data[]) { this->setRowMajorf(data); }
320 void setColMajor(
const SkMScalar data[]) { this->setColMajord(data); }
321 void setRowMajor(
const SkMScalar data[]) { this->setRowMajord(data); }
327 void set3x3(SkMScalar m00, SkMScalar m01, SkMScalar m02,
328 SkMScalar m10, SkMScalar m11, SkMScalar m12,
329 SkMScalar m20, SkMScalar m21, SkMScalar m22);
330 void set3x3RowMajorf(
const float[]);
332 void setTranslate(SkMScalar dx, SkMScalar dy, SkMScalar dz);
333 void preTranslate(SkMScalar dx, SkMScalar dy, SkMScalar dz);
334 void postTranslate(SkMScalar dx, SkMScalar dy, SkMScalar dz);
336 void setScale(SkMScalar sx, SkMScalar sy, SkMScalar sz);
337 void preScale(SkMScalar sx, SkMScalar sy, SkMScalar sz);
338 void postScale(SkMScalar sx, SkMScalar sy, SkMScalar sz);
340 inline void setScale(SkMScalar scale) {
341 this->setScale(scale, scale, scale);
343 inline void preScale(SkMScalar scale) {
344 this->preScale(scale, scale, scale);
346 inline void postScale(SkMScalar scale) {
347 this->postScale(scale, scale, scale);
350 void setRotateDegreesAbout(SkMScalar x, SkMScalar y, SkMScalar z,
352 this->setRotateAbout(x, y, z, degrees * SK_MScalarPI / 180);
358 void setRotateAbout(SkMScalar x, SkMScalar y, SkMScalar z,
363 void setRotateAboutUnit(SkMScalar x, SkMScalar y, SkMScalar z,
366 void setConcat(
const SkMatrix44& a,
const SkMatrix44& b);
367 inline void preConcat(
const SkMatrix44& m) {
368 this->setConcat(*
this, m);
370 inline void postConcat(
const SkMatrix44& m) {
371 this->setConcat(m, *
this);
374 friend SkMatrix44 operator*(
const SkMatrix44& a,
const SkMatrix44& b) {
375 return SkMatrix44(a, b);
382 bool invert(SkMatrix44* inverse)
const;
390 void mapScalars(
const SkScalar src[4], SkScalar dst[4])
const;
391 inline void mapScalars(SkScalar vec[4])
const {
392 this->mapScalars(vec, vec);
395 SK_ATTR_DEPRECATED(
"use mapScalars")
396 void map(const SkScalar src[4], SkScalar dst[4])
const {
397 this->mapScalars(src, dst);
400 SK_ATTR_DEPRECATED(
"use mapScalars")
401 void map(SkScalar vec[4])
const {
402 this->mapScalars(vec, vec);
405 #ifdef SK_MSCALAR_IS_DOUBLE
406 void mapMScalars(
const SkMScalar src[4], SkMScalar dst[4])
const;
407 #elif defined SK_MSCALAR_IS_FLOAT
408 inline void mapMScalars(
const SkMScalar src[4], SkMScalar dst[4])
const {
409 this->mapScalars(src, dst);
412 inline void mapMScalars(SkMScalar vec[4])
const {
413 this->mapMScalars(vec, vec);
430 void map2(
const float src2[],
int count,
float dst4[])
const;
431 void map2(
const double src2[],
int count,
double dst4[])
const;
443 bool preserves2dAxisAlignment(SkMScalar epsilon = SK_ScalarNearlyZero)
const;
447 double determinant()
const;
451 SkMScalar fMat[4][4];
452 mutable unsigned fTypeMask;
455 kUnknown_Mask = 0x80,
457 kAllPublic_Masks = 0xF
460 void as4x3ColMajorf(
float[])
const;
461 void set4x3ColMajorf(
const float[]);
463 SkMScalar transX()
const {
return fMat[3][0]; }
464 SkMScalar transY()
const {
return fMat[3][1]; }
465 SkMScalar transZ()
const {
return fMat[3][2]; }
467 SkMScalar scaleX()
const {
return fMat[0][0]; }
468 SkMScalar scaleY()
const {
return fMat[1][1]; }
469 SkMScalar scaleZ()
const {
return fMat[2][2]; }
471 SkMScalar perspX()
const {
return fMat[0][3]; }
472 SkMScalar perspY()
const {
return fMat[1][3]; }
473 SkMScalar perspZ()
const {
return fMat[2][3]; }
475 int computeTypeMask()
const;
477 inline void dirtyTypeMask() {
478 fTypeMask = kUnknown_Mask;
481 inline void setTypeMask(
int mask) {
482 SkASSERT(0 == (~(kAllPublic_Masks | kUnknown_Mask) & mask));
491 return 0 == fTypeMask;
bool isScale() const
Returns true if the matrix only contains scale or is identity.
Definition: SkMatrix44.h:238
void mapScalars(const SkScalar src[4], SkScalar dst[4]) const
Apply the matrix to the src vector, returning the new vector in dst.
Definition: SkColorSpace.h:16
TypeMask getType() const
Returns a bitfield describing the transformations the matrix may perform.
Definition: SkMatrix44.h:206
Definition: SkMatrix44.h:88
bool isTranslate() const
Return true if the matrix contains translate or is identity.
Definition: SkMatrix44.h:224
Definition: SkMatrix44.h:129
bool isIdentity() const
Return true if the matrix is identity.
Definition: SkMatrix44.h:217
The SkMatrix class holds a 3x3 matrix for transforming coordinates.
Definition: SkMatrix.h:26
#define SkToBool(cond)
Returns 0 or 1 based on the condition.
Definition: SkTypes.h:287
bool isTriviallyIdentity() const
Does not take the time to 'compute' the typemask.
Definition: SkMatrix44.h:490
bool isScaleTranslate() const
Return true if the matrix only contains scale or translate or is identity.
Definition: SkMatrix44.h:231
TypeMask
Definition: SkMatrix44.h:191
void set(int row, int col, SkMScalar value)
set a value in the matrix.
Definition: SkMatrix44.h:267