OLD | NEW |
1 /* | 1 /* |
2 * Copyright (C) 2005, 2006 Apple Computer, Inc. All rights reserved. | 2 * Copyright (C) 2005, 2006 Apple Computer, Inc. All rights reserved. |
3 * | 3 * |
4 * Redistribution and use in source and binary forms, with or without | 4 * Redistribution and use in source and binary forms, with or without |
5 * modification, are permitted provided that the following conditions | 5 * modification, are permitted provided that the following conditions |
6 * are met: | 6 * are met: |
7 * 1. Redistributions of source code must retain the above copyright | 7 * 1. Redistributions of source code must retain the above copyright |
8 * notice, this list of conditions and the following disclaimer. | 8 * notice, this list of conditions and the following disclaimer. |
9 * 2. Redistributions in binary form must reproduce the above copyright | 9 * 2. Redistributions in binary form must reproduce the above copyright |
10 * notice, this list of conditions and the following disclaimer in the | 10 * notice, this list of conditions and the following disclaimer in the |
(...skipping 10 matching lines...) Expand all Loading... |
21 * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT | 21 * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
22 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE | 22 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE |
23 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | 23 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
24 */ | 24 */ |
25 | 25 |
26 #ifndef TransformationMatrix_h | 26 #ifndef TransformationMatrix_h |
27 #define TransformationMatrix_h | 27 #define TransformationMatrix_h |
28 | 28 |
29 #if PLATFORM(CG) | 29 #if PLATFORM(CG) |
30 #include <CoreGraphics/CGAffineTransform.h> | 30 #include <CoreGraphics/CGAffineTransform.h> |
31 typedef CGAffineTransform PlatformTransformationMatrix; | 31 #elif PLATFORM(CAIRO) |
| 32 #include <cairo.h> |
32 #elif PLATFORM(QT) | 33 #elif PLATFORM(QT) |
33 #include <QMatrix> | 34 #include <QMatrix> |
34 typedef QMatrix PlatformTransformationMatrix; | |
35 #elif PLATFORM(CAIRO) | |
36 #include <cairo.h> | |
37 typedef cairo_matrix_t PlatformTransformationMatrix; | |
38 #elif PLATFORM(SKIA) | 35 #elif PLATFORM(SKIA) |
39 #include "SkMatrix.h" | 36 #include <SkMatrix.h> |
40 typedef SkMatrix PlatformTransformationMatrix; | |
41 #elif PLATFORM(WX) && USE(WXGC) | |
42 #include <wx/defs.h> | |
43 #include <wx/graphics.h> | |
44 typedef wxGraphicsMatrix PlatformTransformationMatrix; | |
45 #endif | 37 #endif |
46 | 38 |
| 39 #include <string.h> //for memcpy |
| 40 |
47 namespace WebCore { | 41 namespace WebCore { |
48 | 42 |
49 class IntPoint; | 43 class IntPoint; |
50 class IntRect; | 44 class IntRect; |
51 class FloatPoint; | 45 class FloatPoint; |
| 46 class FloatPoint3D; |
52 class FloatRect; | 47 class FloatRect; |
53 class FloatQuad; | 48 class FloatQuad; |
54 | 49 |
55 class TransformationMatrix { | 50 class TransformationMatrix { |
56 public: | 51 public: |
57 TransformationMatrix(); | 52 typedef double Matrix4[4][4]; |
58 TransformationMatrix(double a, double b, double c, double d, double e, doubl
e f); | 53 |
59 #if !PLATFORM(WX) || USE(WXGC) | 54 TransformationMatrix() { makeIdentity(); } |
60 TransformationMatrix(const PlatformTransformationMatrix&); | 55 TransformationMatrix(const TransformationMatrix& t) { *this = t; } |
61 #endif | 56 TransformationMatrix(double a, double b, double c, double d, double e, doubl
e f) { setMatrix(a, b, c, d, e, f); } |
62 | 57 TransformationMatrix(double m11, double m12, double m13, double m14, |
63 void setMatrix(double a, double b, double c, double d, double e, double f); | 58 double m21, double m22, double m23, double m24, |
64 void map(double x, double y, double *x2, double *y2) const; | 59 double m31, double m32, double m33, double m34, |
65 | 60 double m41, double m42, double m43, double m44) |
66 // Rounds the mapped point to the nearest integer value. | 61 { |
| 62 setMatrix(m11, m12, m13, m14, m21, m22, m23, m24, m31, m32, m33, m34, m4
1, m42, m43, m44); |
| 63 } |
| 64 |
| 65 void setMatrix(double a, double b, double c, double d, double e, double f) |
| 66 { |
| 67 m_matrix[0][0] = a; m_matrix[0][1] = b; m_matrix[0][2] = 0; m_matrix[0][
3] = 0; |
| 68 m_matrix[1][0] = c; m_matrix[1][1] = d; m_matrix[1][2] = 0; m_matrix[1][
3] = 0; |
| 69 m_matrix[2][0] = 0; m_matrix[2][1] = 0; m_matrix[2][2] = 1; m_matrix[2][
3] = 0; |
| 70 m_matrix[3][0] = e; m_matrix[3][1] = f; m_matrix[3][2] = 0; m_matrix[3][
3] = 1; |
| 71 } |
| 72 |
| 73 void setMatrix(double m11, double m12, double m13, double m14, |
| 74 double m21, double m22, double m23, double m24, |
| 75 double m31, double m32, double m33, double m34, |
| 76 double m41, double m42, double m43, double m44) |
| 77 { |
| 78 m_matrix[0][0] = m11; m_matrix[0][1] = m12; m_matrix[0][2] = m13; m_matr
ix[0][3] = m14; |
| 79 m_matrix[1][0] = m21; m_matrix[1][1] = m22; m_matrix[1][2] = m23; m_matr
ix[1][3] = m24; |
| 80 m_matrix[2][0] = m31; m_matrix[2][1] = m32; m_matrix[2][2] = m33; m_matr
ix[2][3] = m34; |
| 81 m_matrix[3][0] = m41; m_matrix[3][1] = m42; m_matrix[3][2] = m43; m_matr
ix[3][3] = m44; |
| 82 } |
| 83 |
| 84 TransformationMatrix& operator =(const TransformationMatrix &t) |
| 85 { |
| 86 setMatrix(t.m_matrix); |
| 87 return *this; |
| 88 } |
| 89 |
| 90 TransformationMatrix& makeIdentity() |
| 91 { |
| 92 setMatrix(1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1); |
| 93 return *this; |
| 94 } |
| 95 |
| 96 bool isIdentity() const |
| 97 { |
| 98 return m_matrix[0][0] == 1 && m_matrix[0][1] == 0 && m_matrix[0][2] == 0
&& m_matrix[0][3] == 0 && |
| 99 m_matrix[1][0] == 0 && m_matrix[1][1] == 1 && m_matrix[1][2] == 0
&& m_matrix[1][3] == 0 && |
| 100 m_matrix[2][0] == 0 && m_matrix[2][1] == 0 && m_matrix[2][2] == 1
&& m_matrix[2][3] == 0 && |
| 101 m_matrix[3][0] == 0 && m_matrix[3][1] == 0 && m_matrix[3][2] == 0
&& m_matrix[3][3] == 1; |
| 102 } |
| 103 |
| 104 // This form preserves the double math from input to output |
| 105 void map(double x, double y, double& x2, double& y2) const { multVecMatrix(x
, y, x2, y2); } |
| 106 |
| 107 // Map a 3D point through the transform, returning a 3D point. |
| 108 FloatPoint3D mapPoint(const FloatPoint3D&) const; |
| 109 |
| 110 // Map a 2D point through the transform, returning a 2D point. |
| 111 // Note that this ignores the z component, effectively projecting the point
into the z=0 plane. |
| 112 FloatPoint mapPoint(const FloatPoint&) const; |
| 113 |
| 114 // Like the version above, except that it rounds the mapped point to the nea
rest integer value. |
67 IntPoint mapPoint(const IntPoint&) const; | 115 IntPoint mapPoint(const IntPoint&) const; |
68 | 116 |
69 FloatPoint mapPoint(const FloatPoint&) const; | 117 // If the matrix has 3D components, the z component of the result is |
| 118 // dropped, effectively projecting the rect into the z=0 plane |
| 119 FloatRect mapRect(const FloatRect&) const; |
70 | 120 |
71 // Rounds the resulting mapped rectangle out. This is helpful for bounding | 121 // Rounds the resulting mapped rectangle out. This is helpful for bounding |
72 // box computations but may not be what is wanted in other contexts. | 122 // box computations but may not be what is wanted in other contexts. |
73 IntRect mapRect(const IntRect&) const; | 123 IntRect mapRect(const IntRect&) const; |
74 | 124 |
75 FloatRect mapRect(const FloatRect&) const; | 125 // If the matrix has 3D components, the z component of the result is |
76 | 126 // dropped, effectively projecting the quad into the z=0 plane |
77 FloatQuad mapQuad(const FloatQuad&) const; | 127 FloatQuad mapQuad(const FloatQuad&) const; |
78 | 128 |
79 bool isIdentity() const; | 129 // Map a point on the z=0 plane into a point on |
80 | 130 // the plane with with the transform applied, by extending |
81 double a() const; | 131 // a ray perpendicular to the source plane and computing |
82 void setA(double a); | 132 // the local x,y position of the point where that ray intersects |
83 | 133 // with the destination plane. |
84 double b() const; | 134 FloatPoint projectPoint(const FloatPoint&) const; |
85 void setB(double b); | 135 |
86 | 136 double m11() const { return m_matrix[0][0]; } |
87 double c() const; | 137 void setM11(double f) { m_matrix[0][0] = f; } |
88 void setC(double c); | 138 double m12() const { return m_matrix[0][1]; } |
89 | 139 void setM12(double f) { m_matrix[0][1] = f; } |
90 double d() const; | 140 double m13() const { return m_matrix[0][2]; } |
91 void setD(double d); | 141 void setM13(double f) { m_matrix[0][2] = f; } |
92 | 142 double m14() const { return m_matrix[0][3]; } |
93 double e() const; | 143 void setM14(double f) { m_matrix[0][3] = f; } |
94 void setE(double e); | 144 double m21() const { return m_matrix[1][0]; } |
95 | 145 void setM21(double f) { m_matrix[1][0] = f; } |
96 double f() const; | 146 double m22() const { return m_matrix[1][1]; } |
97 void setF(double f); | 147 void setM22(double f) { m_matrix[1][1] = f; } |
98 | 148 double m23() const { return m_matrix[1][2]; } |
99 void reset(); | 149 void setM23(double f) { m_matrix[1][2] = f; } |
100 | 150 double m24() const { return m_matrix[1][3]; } |
101 TransformationMatrix& multiply(const TransformationMatrix&); | 151 void setM24(double f) { m_matrix[1][3] = f; } |
| 152 double m31() const { return m_matrix[2][0]; } |
| 153 void setM31(double f) { m_matrix[2][0] = f; } |
| 154 double m32() const { return m_matrix[2][1]; } |
| 155 void setM32(double f) { m_matrix[2][1] = f; } |
| 156 double m33() const { return m_matrix[2][2]; } |
| 157 void setM33(double f) { m_matrix[2][2] = f; } |
| 158 double m34() const { return m_matrix[2][3]; } |
| 159 void setM34(double f) { m_matrix[2][3] = f; } |
| 160 double m41() const { return m_matrix[3][0]; } |
| 161 void setM41(double f) { m_matrix[3][0] = f; } |
| 162 double m42() const { return m_matrix[3][1]; } |
| 163 void setM42(double f) { m_matrix[3][1] = f; } |
| 164 double m43() const { return m_matrix[3][2]; } |
| 165 void setM43(double f) { m_matrix[3][2] = f; } |
| 166 double m44() const { return m_matrix[3][3]; } |
| 167 void setM44(double f) { m_matrix[3][3] = f; } |
| 168 |
| 169 double a() const { return m_matrix[0][0]; } |
| 170 void setA(double a) { m_matrix[0][0] = a; } |
| 171 |
| 172 double b() const { return m_matrix[0][1]; } |
| 173 void setB(double b) { m_matrix[0][1] = b; } |
| 174 |
| 175 double c() const { return m_matrix[1][0]; } |
| 176 void setC(double c) { m_matrix[1][0] = c; } |
| 177 |
| 178 double d() const { return m_matrix[1][1]; } |
| 179 void setD(double d) { m_matrix[1][1] = d; } |
| 180 |
| 181 double e() const { return m_matrix[3][0]; } |
| 182 void setE(double e) { m_matrix[3][0] = e; } |
| 183 |
| 184 double f() const { return m_matrix[3][1]; } |
| 185 void setF(double f) { m_matrix[3][1] = f; } |
| 186 |
| 187 // this = this * mat |
| 188 TransformationMatrix& multiply(const TransformationMatrix& t) { return *this
*= t; } |
| 189 |
| 190 // this = mat * this |
| 191 TransformationMatrix& multLeft(const TransformationMatrix& mat); |
| 192 |
102 TransformationMatrix& scale(double); | 193 TransformationMatrix& scale(double); |
103 TransformationMatrix& scale(double sx, double sy); | |
104 TransformationMatrix& scaleNonUniform(double sx, double sy); | 194 TransformationMatrix& scaleNonUniform(double sx, double sy); |
105 TransformationMatrix& rotate(double d); | 195 TransformationMatrix& scale3d(double sx, double sy, double sz); |
| 196 |
| 197 TransformationMatrix& rotate(double d) { return rotate3d(0, 0, d); } |
106 TransformationMatrix& rotateFromVector(double x, double y); | 198 TransformationMatrix& rotateFromVector(double x, double y); |
| 199 TransformationMatrix& rotate3d(double rx, double ry, double rz); |
| 200 |
| 201 // The vector (x,y,z) is normalized if it's not already. A vector of |
| 202 // (0,0,0) uses a vector of (0,0,1). |
| 203 TransformationMatrix& rotate3d(double x, double y, double z, double angle); |
| 204 |
107 TransformationMatrix& translate(double tx, double ty); | 205 TransformationMatrix& translate(double tx, double ty); |
108 TransformationMatrix& shear(double sx, double sy); | 206 TransformationMatrix& translate3d(double tx, double ty, double tz); |
| 207 |
109 TransformationMatrix& flipX(); | 208 TransformationMatrix& flipX(); |
110 TransformationMatrix& flipY(); | 209 TransformationMatrix& flipY(); |
111 TransformationMatrix& skew(double angleX, double angleY); | 210 TransformationMatrix& skew(double angleX, double angleY); |
112 TransformationMatrix& skewX(double angle); | 211 TransformationMatrix& skewX(double angle) { return skew(angle, 0); } |
113 TransformationMatrix& skewY(double angle); | 212 TransformationMatrix& skewY(double angle) { return skew(0, angle); } |
114 | 213 |
115 double det() const; | 214 TransformationMatrix& applyPerspective(double p); |
| 215 bool hasPerspective() const { return m_matrix[2][3] != 0.0f; } |
| 216 |
116 bool isInvertible() const; | 217 bool isInvertible() const; |
| 218 |
| 219 // This method returns the identity matrix if it is not invertible. |
| 220 // Use isInvertible() before calling this if you need to know. |
117 TransformationMatrix inverse() const; | 221 TransformationMatrix inverse() const; |
118 | 222 |
| 223 // decompose the matrix into its component parts |
| 224 typedef struct { |
| 225 double scaleX, scaleY, scaleZ; |
| 226 double skewXY, skewXZ, skewYZ; |
| 227 double quaternionX, quaternionY, quaternionZ, quaternionW; |
| 228 double translateX, translateY, translateZ; |
| 229 double perspectiveX, perspectiveY, perspectiveZ, perspectiveW; |
| 230 } DecomposedType; |
| 231 |
| 232 bool decompose(DecomposedType& decomp) const; |
| 233 void recompose(const DecomposedType& decomp); |
| 234 |
119 void blend(const TransformationMatrix& from, double progress); | 235 void blend(const TransformationMatrix& from, double progress); |
120 | 236 |
121 #if !PLATFORM(WX) || USE(WXGC) | 237 bool isAffine() const |
122 operator PlatformTransformationMatrix() const; | 238 { |
| 239 return (m13() == 0 && m14() == 0 && m23() == 0 && m24() == 0 && |
| 240 m31() == 0 && m32() == 0 && m33() == 1 && m34() == 0 && m43() ==
0 && m44() == 1); |
| 241 } |
| 242 |
| 243 bool operator==(const TransformationMatrix& m2) const |
| 244 { |
| 245 return (m_matrix[0][0] == m2.m_matrix[0][0] && |
| 246 m_matrix[0][1] == m2.m_matrix[0][1] && |
| 247 m_matrix[0][2] == m2.m_matrix[0][2] && |
| 248 m_matrix[0][3] == m2.m_matrix[0][3] && |
| 249 m_matrix[1][0] == m2.m_matrix[1][0] && |
| 250 m_matrix[1][1] == m2.m_matrix[1][1] && |
| 251 m_matrix[1][2] == m2.m_matrix[1][2] && |
| 252 m_matrix[1][3] == m2.m_matrix[1][3] && |
| 253 m_matrix[2][0] == m2.m_matrix[2][0] && |
| 254 m_matrix[2][1] == m2.m_matrix[2][1] && |
| 255 m_matrix[2][2] == m2.m_matrix[2][2] && |
| 256 m_matrix[2][3] == m2.m_matrix[2][3] && |
| 257 m_matrix[3][0] == m2.m_matrix[3][0] && |
| 258 m_matrix[3][1] == m2.m_matrix[3][1] && |
| 259 m_matrix[3][2] == m2.m_matrix[3][2] && |
| 260 m_matrix[3][3] == m2.m_matrix[3][3]); |
| 261 } |
| 262 |
| 263 bool operator!=(const TransformationMatrix& other) const { return !(*this ==
other); } |
| 264 |
| 265 // *this = *this * t (i.e., a multRight) |
| 266 TransformationMatrix& operator*=(const TransformationMatrix& t) |
| 267 { |
| 268 *this = *this * t; |
| 269 return *this; |
| 270 } |
| 271 |
| 272 // result = *this * t (i.e., a multRight) |
| 273 TransformationMatrix operator*(const TransformationMatrix& t) |
| 274 { |
| 275 TransformationMatrix result = t; |
| 276 result.multLeft(*this); |
| 277 return result; |
| 278 } |
| 279 |
| 280 #if PLATFORM(CG) |
| 281 operator CGAffineTransform() const; |
| 282 #elif PLATFORM(CAIRO) |
| 283 operator cairo_matrix_t() const; |
| 284 #elif PLATFORM(QT) |
| 285 operator QMatrix() const; |
| 286 #elif PLATFORM(SKIA) |
| 287 operator SkMatrix() const; |
123 #endif | 288 #endif |
124 | 289 |
125 bool operator==(const TransformationMatrix&) const; | |
126 bool operator!=(const TransformationMatrix& other) const { return !(*this ==
other); } | |
127 TransformationMatrix& operator*=(const TransformationMatrix&); | |
128 TransformationMatrix operator*(const TransformationMatrix&); | |
129 | |
130 private: | 290 private: |
131 #if !PLATFORM(WX) || USE(WXGC) | 291 TransformationMatrix makeMapBetweenRects(const FloatRect& source, const Floa
tRect& dest); |
132 PlatformTransformationMatrix m_transform; | 292 |
133 #endif | 293 // multiply passed 2D point by matrix (assume z=0) |
| 294 void multVecMatrix(double x, double y, double& dstX, double& dstY) const; |
| 295 |
| 296 // multiply passed 3D point by matrix |
| 297 void multVecMatrix(double x, double y, double z, double& dstX, double& dstY,
double& dstZ) const; |
| 298 |
| 299 void setMatrix(const Matrix4 m) |
| 300 { |
| 301 if (m && m != m_matrix) |
| 302 memcpy(m_matrix, m, sizeof(Matrix4)); |
| 303 } |
| 304 |
| 305 Matrix4 m_matrix; |
134 }; | 306 }; |
135 | 307 |
136 TransformationMatrix makeMapBetweenRects(const FloatRect& source, const FloatRec
t& dest); | |
137 | |
138 } // namespace WebCore | 308 } // namespace WebCore |
139 | 309 |
140 #endif // TransformationMatrix_h | 310 #endif // TransformationMatrix_h |
OLD | NEW |