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) {
138 enum Uninitialized_Constructor {
139 kUninitialized_Constructor
141 enum Identity_Constructor {
142 kIdentity_Constructor
148 : fMat{{ 1, 0, 0, 0, },
152 , fTypeMask(kIdentity_Mask)
155 SK_ATTR_DEPRECATED(
"use the constructors that take an enum")
156 SkMatrix44() { this->setIdentity(); }
158 SkMatrix44(
const SkMatrix44& src) {
159 memcpy(fMat, src.fMat,
sizeof(fMat));
160 fTypeMask = src.fTypeMask;
163 SkMatrix44(
const SkMatrix44& a,
const SkMatrix44& b) {
164 this->setConcat(a, b);
167 SkMatrix44& operator=(
const SkMatrix44& src) {
169 memcpy(fMat, src.fMat,
sizeof(fMat));
170 fTypeMask = src.fTypeMask;
175 bool operator==(
const SkMatrix44& other)
const;
176 bool operator!=(
const SkMatrix44& other)
const {
177 return !(other == *
this);
189 SkMatrix44& operator=(
const SkMatrix& src);
195 static const SkMatrix44& I();
199 kTranslate_Mask = 0x01,
202 kPerspective_Mask = 0x08
213 if (fTypeMask & kUnknown_Mask) {
214 fTypeMask = this->computeTypeMask();
216 SkASSERT(!(fTypeMask & kUnknown_Mask));
224 return kIdentity_Mask == this->getType();
231 return !(this->getType() & ~kTranslate_Mask);
238 return !(this->getType() & ~(kScale_Mask | kTranslate_Mask));
245 return !(this->getType() & ~kScale_Mask);
248 inline bool hasPerspective()
const {
249 return SkToBool(this->getType() & kPerspective_Mask);
253 inline void reset() { this->setIdentity();}
261 inline SkMScalar
get(
int row,
int col)
const {
262 SkASSERT((
unsigned)row <= 3);
263 SkASSERT((
unsigned)col <= 3);
264 return fMat[col][row];
273 inline void set(
int row,
int col, SkMScalar value) {
274 SkASSERT((
unsigned)row <= 3);
275 SkASSERT((
unsigned)col <= 3);
276 fMat[col][row] = value;
277 this->dirtyTypeMask();
280 inline double getDouble(
int row,
int col)
const {
281 return SkMScalarToDouble(this->
get(row, col));
283 inline void setDouble(
int row,
int col,
double value) {
284 this->set(row, col, SkDoubleToMScalar(value));
286 inline float getFloat(
int row,
int col)
const {
287 return SkMScalarToFloat(this->
get(row, col));
289 inline void setFloat(
int row,
int col,
float value) {
290 this->set(row, col, SkFloatToMScalar(value));
302 void asColMajorf(
float[])
const;
303 void asColMajord(
double[])
const;
304 void asRowMajorf(
float[])
const;
305 void asRowMajord(
double[])
const;
317 void setColMajorf(
const float[]);
318 void setColMajord(
const double[]);
319 void setRowMajorf(
const float[]);
320 void setRowMajord(
const double[]);
322 #ifdef SK_MSCALAR_IS_FLOAT
323 void setColMajor(
const SkMScalar data[]) { this->setColMajorf(data); }
324 void setRowMajor(
const SkMScalar data[]) { this->setRowMajorf(data); }
326 void setColMajor(
const SkMScalar data[]) { this->setColMajord(data); }
327 void setRowMajor(
const SkMScalar data[]) { this->setRowMajord(data); }
333 void set3x3(SkMScalar m00, SkMScalar m01, SkMScalar m02,
334 SkMScalar m10, SkMScalar m11, SkMScalar m12,
335 SkMScalar m20, SkMScalar m21, SkMScalar m22);
336 void set3x3RowMajorf(
const float[]);
338 void setTranslate(SkMScalar dx, SkMScalar dy, SkMScalar dz);
339 void preTranslate(SkMScalar dx, SkMScalar dy, SkMScalar dz);
340 void postTranslate(SkMScalar dx, SkMScalar dy, SkMScalar dz);
342 void setScale(SkMScalar sx, SkMScalar sy, SkMScalar sz);
343 void preScale(SkMScalar sx, SkMScalar sy, SkMScalar sz);
344 void postScale(SkMScalar sx, SkMScalar sy, SkMScalar sz);
346 inline void setScale(SkMScalar scale) {
347 this->setScale(scale, scale, scale);
349 inline void preScale(SkMScalar scale) {
350 this->preScale(scale, scale, scale);
352 inline void postScale(SkMScalar scale) {
353 this->postScale(scale, scale, scale);
356 void setRotateDegreesAbout(SkMScalar x, SkMScalar y, SkMScalar z,
358 this->setRotateAbout(x, y, z, degrees * SK_MScalarPI / 180);
364 void setRotateAbout(SkMScalar x, SkMScalar y, SkMScalar z,
369 void setRotateAboutUnit(SkMScalar x, SkMScalar y, SkMScalar z,
372 void setConcat(
const SkMatrix44& a,
const SkMatrix44& b);
373 inline void preConcat(
const SkMatrix44& m) {
374 this->setConcat(*
this, m);
376 inline void postConcat(
const SkMatrix44& m) {
377 this->setConcat(m, *
this);
380 friend SkMatrix44 operator*(
const SkMatrix44& a,
const SkMatrix44& b) {
381 return SkMatrix44(a, b);
388 bool invert(SkMatrix44* inverse)
const;
396 void mapScalars(
const SkScalar src[4], SkScalar dst[4])
const;
397 inline void mapScalars(SkScalar vec[4])
const {
398 this->mapScalars(vec, vec);
401 SK_ATTR_DEPRECATED(
"use mapScalars")
402 void map(const SkScalar src[4], SkScalar dst[4])
const {
403 this->mapScalars(src, dst);
406 SK_ATTR_DEPRECATED(
"use mapScalars")
407 void map(SkScalar vec[4])
const {
408 this->mapScalars(vec, vec);
411 #ifdef SK_MSCALAR_IS_DOUBLE
412 void mapMScalars(
const SkMScalar src[4], SkMScalar dst[4])
const;
413 #elif defined SK_MSCALAR_IS_FLOAT
414 inline void mapMScalars(
const SkMScalar src[4], SkMScalar dst[4])
const {
415 this->mapScalars(src, dst);
418 inline void mapMScalars(SkMScalar vec[4])
const {
419 this->mapMScalars(vec, vec);
436 void map2(
const float src2[],
int count,
float dst4[])
const;
437 void map2(
const double src2[],
int count,
double dst4[])
const;
449 bool preserves2dAxisAlignment(SkMScalar epsilon = SK_ScalarNearlyZero)
const;
453 double determinant()
const;
457 SkMScalar fMat[4][4];
458 mutable unsigned fTypeMask;
461 kUnknown_Mask = 0x80,
463 kAllPublic_Masks = 0xF
466 void as3x4RowMajorf(
float[])
const;
467 void set3x4RowMajorf(
const float[]);
469 SkMScalar transX()
const {
return fMat[3][0]; }
470 SkMScalar transY()
const {
return fMat[3][1]; }
471 SkMScalar transZ()
const {
return fMat[3][2]; }
473 SkMScalar scaleX()
const {
return fMat[0][0]; }
474 SkMScalar scaleY()
const {
return fMat[1][1]; }
475 SkMScalar scaleZ()
const {
return fMat[2][2]; }
477 SkMScalar perspX()
const {
return fMat[0][3]; }
478 SkMScalar perspY()
const {
return fMat[1][3]; }
479 SkMScalar perspZ()
const {
return fMat[2][3]; }
481 int computeTypeMask()
const;
483 inline void dirtyTypeMask() {
484 fTypeMask = kUnknown_Mask;
487 inline void setTypeMask(
int mask) {
488 SkASSERT(0 == (~(kAllPublic_Masks | kUnknown_Mask) & mask));
497 return 0 == fTypeMask;
500 inline const SkMScalar* values()
const {
return &fMat[0][0]; }
503 friend class SkColorSpace_XYZ;
bool isScale() const
Returns true if the matrix only contains scale or is identity.
Definition: SkMatrix44.h:244
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:59
TypeMask getType() const
Returns a bitfield describing the transformations the matrix may perform.
Definition: SkMatrix44.h:212
Definition: SkMatrix44.h:88
bool isTranslate() const
Return true if the matrix contains translate or is identity.
Definition: SkMatrix44.h:230
The SkMatrix44 class holds a 4x4 matrix.
Definition: SkMatrix44.h:135
bool isIdentity() const
Return true if the matrix is identity.
Definition: SkMatrix44.h:223
The SkMatrix class holds a 3x3 matrix for transforming coordinates.
Definition: SkMatrix.h:28
#define SkToBool(cond)
Returns 0 or 1 based on the condition.
Definition: SkTypes.h:227
bool isTriviallyIdentity() const
Does not take the time to 'compute' the typemask.
Definition: SkMatrix44.h:496
bool isScaleTranslate() const
Return true if the matrix only contains scale or translate or is identity.
Definition: SkMatrix44.h:237
TypeMask
Definition: SkMatrix44.h:197
void set(int row, int col, SkMScalar value)
set a value in the matrix.
Definition: SkMatrix44.h:273