[GTK] Remove unsupported AC backends
[WebKit-https.git] / Source / WebCore / platform / graphics / transforms / TransformationMatrix.h
1 /*
2  * Copyright (C) 2005, 2006 Apple Computer, Inc.  All rights reserved.
3  *
4  * Redistribution and use in source and binary forms, with or without
5  * modification, are permitted provided that the following conditions
6  * are met:
7  * 1. Redistributions of source code must retain the above copyright
8  *    notice, this list of conditions and the following disclaimer.
9  * 2. Redistributions in binary form must reproduce the above copyright
10  *    notice, this list of conditions and the following disclaimer in the
11  *    documentation and/or other materials provided with the distribution.
12  *
13  * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY
14  * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
15  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
16  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE COMPUTER, INC. OR
17  * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
18  * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
19  * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
20  * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
21  * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
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.
24  */
25
26 #ifndef TransformationMatrix_h
27 #define TransformationMatrix_h
28
29 #include "FloatPoint.h"
30 #include "FloatPoint3D.h"
31 #include "IntPoint.h"
32 #include <string.h> //for memcpy
33 #include <wtf/FastAllocBase.h>
34
35 #if USE(CA)
36 typedef struct CATransform3D CATransform3D;
37 #endif
38 #if USE(CG)
39 typedef struct CGAffineTransform CGAffineTransform;
40 #elif USE(CAIRO)
41 #include <cairo.h>
42 #elif PLATFORM(QT)
43 #include <QMatrix4x4>
44 #include <QTransform>
45 #endif
46
47 #if PLATFORM(WIN) || (PLATFORM(GTK) && OS(WINDOWS)) || (PLATFORM(QT) && OS(WINDOWS))
48 #if COMPILER(MINGW) && !COMPILER(MINGW64)
49 typedef struct _XFORM XFORM;
50 #else
51 typedef struct tagXFORM XFORM;
52 #endif
53 #endif
54
55 namespace WebCore {
56
57 class AffineTransform;
58 class IntRect;
59 class LayoutRect;
60 class FloatRect;
61 class FloatQuad;
62
63 #if CPU(X86_64)
64 #define TRANSFORMATION_MATRIX_USE_X86_64_SSE2
65 #endif
66
67 class TransformationMatrix {
68     WTF_MAKE_FAST_ALLOCATED;
69 public:
70
71 #if CPU(APPLE_ARMV7S) || defined(TRANSFORMATION_MATRIX_USE_X86_64_SSE2)
72 #if COMPILER(MSVC)
73     __declspec(align(16)) typedef double Matrix4[4][4];
74 #else
75     typedef double Matrix4[4][4] __attribute__((aligned (16)));
76 #endif
77 #else
78     typedef double Matrix4[4][4];
79 #endif
80
81     TransformationMatrix() { makeIdentity(); }
82     TransformationMatrix(const AffineTransform& t);
83     TransformationMatrix(const TransformationMatrix& t) { *this = t; }
84     TransformationMatrix(double a, double b, double c, double d, double e, double f) { setMatrix(a, b, c, d, e, f); }
85     TransformationMatrix(double m11, double m12, double m13, double m14,
86                          double m21, double m22, double m23, double m24,
87                          double m31, double m32, double m33, double m34,
88                          double m41, double m42, double m43, double m44)
89     {
90         setMatrix(m11, m12, m13, m14, m21, m22, m23, m24, m31, m32, m33, m34, m41, m42, m43, m44);
91     }
92
93 #if PLATFORM(QT)
94     TransformationMatrix(const QTransform&);
95     TransformationMatrix(const QMatrix4x4&);
96 #endif
97
98     void setMatrix(double a, double b, double c, double d, double e, double f)
99     {
100         m_matrix[0][0] = a; m_matrix[0][1] = b; m_matrix[0][2] = 0; m_matrix[0][3] = 0; 
101         m_matrix[1][0] = c; m_matrix[1][1] = d; m_matrix[1][2] = 0; m_matrix[1][3] = 0; 
102         m_matrix[2][0] = 0; m_matrix[2][1] = 0; m_matrix[2][2] = 1; m_matrix[2][3] = 0; 
103         m_matrix[3][0] = e; m_matrix[3][1] = f; m_matrix[3][2] = 0; m_matrix[3][3] = 1;
104     }
105     
106     void setMatrix(double m11, double m12, double m13, double m14,
107                    double m21, double m22, double m23, double m24,
108                    double m31, double m32, double m33, double m34,
109                    double m41, double m42, double m43, double m44)
110     {
111         m_matrix[0][0] = m11; m_matrix[0][1] = m12; m_matrix[0][2] = m13; m_matrix[0][3] = m14; 
112         m_matrix[1][0] = m21; m_matrix[1][1] = m22; m_matrix[1][2] = m23; m_matrix[1][3] = m24; 
113         m_matrix[2][0] = m31; m_matrix[2][1] = m32; m_matrix[2][2] = m33; m_matrix[2][3] = m34; 
114         m_matrix[3][0] = m41; m_matrix[3][1] = m42; m_matrix[3][2] = m43; m_matrix[3][3] = m44;
115     }
116     
117     TransformationMatrix& operator =(const TransformationMatrix &t)
118     {
119         setMatrix(t.m_matrix);
120         return *this;
121     }
122
123     TransformationMatrix& makeIdentity()
124     {
125         setMatrix(1, 0, 0, 0,  0, 1, 0, 0,  0, 0, 1, 0,  0, 0, 0, 1);
126         return *this;
127     }
128
129     bool isIdentity() const
130     {
131         return m_matrix[0][0] == 1 && m_matrix[0][1] == 0 && m_matrix[0][2] == 0 && m_matrix[0][3] == 0 &&
132                m_matrix[1][0] == 0 && m_matrix[1][1] == 1 && m_matrix[1][2] == 0 && m_matrix[1][3] == 0 &&
133                m_matrix[2][0] == 0 && m_matrix[2][1] == 0 && m_matrix[2][2] == 1 && m_matrix[2][3] == 0 &&
134                m_matrix[3][0] == 0 && m_matrix[3][1] == 0 && m_matrix[3][2] == 0 && m_matrix[3][3] == 1;
135     }
136
137     // This form preserves the double math from input to output
138     void map(double x, double y, double& x2, double& y2) const { multVecMatrix(x, y, x2, y2); }
139
140     // Map a 3D point through the transform, returning a 3D point.
141     FloatPoint3D mapPoint(const FloatPoint3D&) const;
142
143     // Map a 2D point through the transform, returning a 2D point.
144     // Note that this ignores the z component, effectively projecting the point into the z=0 plane.
145     FloatPoint mapPoint(const FloatPoint&) const;
146
147     // Like the version above, except that it rounds the mapped point to the nearest integer value.
148     IntPoint mapPoint(const IntPoint& p) const
149     {
150         return roundedIntPoint(mapPoint(FloatPoint(p)));
151     }
152
153     // If the matrix has 3D components, the z component of the result is
154     // dropped, effectively projecting the rect into the z=0 plane
155     FloatRect mapRect(const FloatRect&) const;
156
157     // Rounds the resulting mapped rectangle out. This is helpful for bounding
158     // box computations but may not be what is wanted in other contexts.
159     IntRect mapRect(const IntRect&) const;
160     LayoutRect mapRect(const LayoutRect&) const;
161
162     // If the matrix has 3D components, the z component of the result is
163     // dropped, effectively projecting the quad into the z=0 plane
164     FloatQuad mapQuad(const FloatQuad&) const;
165
166     // Map a point on the z=0 plane into a point on
167     // the plane with with the transform applied, by extending
168     // a ray perpendicular to the source plane and computing
169     // the local x,y position of the point where that ray intersects
170     // with the destination plane.
171     FloatPoint projectPoint(const FloatPoint&, bool* clamped = 0) const;
172     // Projects the four corners of the quad
173     FloatQuad projectQuad(const FloatQuad&,  bool* clamped = 0) const;
174     // Projects the four corners of the quad and takes a bounding box,
175     // while sanitizing values created when the w component is negative.
176     LayoutRect clampedBoundsOfProjectedQuad(const FloatQuad&) const;
177
178     double m11() const { return m_matrix[0][0]; }
179     void setM11(double f) { m_matrix[0][0] = f; }
180     double m12() const { return m_matrix[0][1]; }
181     void setM12(double f) { m_matrix[0][1] = f; }
182     double m13() const { return m_matrix[0][2]; }
183     void setM13(double f) { m_matrix[0][2] = f; }
184     double m14() const { return m_matrix[0][3]; }
185     void setM14(double f) { m_matrix[0][3] = f; }
186     double m21() const { return m_matrix[1][0]; }
187     void setM21(double f) { m_matrix[1][0] = f; }
188     double m22() const { return m_matrix[1][1]; }
189     void setM22(double f) { m_matrix[1][1] = f; }
190     double m23() const { return m_matrix[1][2]; }
191     void setM23(double f) { m_matrix[1][2] = f; }
192     double m24() const { return m_matrix[1][3]; }
193     void setM24(double f) { m_matrix[1][3] = f; }
194     double m31() const { return m_matrix[2][0]; }
195     void setM31(double f) { m_matrix[2][0] = f; }
196     double m32() const { return m_matrix[2][1]; }
197     void setM32(double f) { m_matrix[2][1] = f; }
198     double m33() const { return m_matrix[2][2]; }
199     void setM33(double f) { m_matrix[2][2] = f; }
200     double m34() const { return m_matrix[2][3]; }
201     void setM34(double f) { m_matrix[2][3] = f; }
202     double m41() const { return m_matrix[3][0]; }
203     void setM41(double f) { m_matrix[3][0] = f; }
204     double m42() const { return m_matrix[3][1]; }
205     void setM42(double f) { m_matrix[3][1] = f; }
206     double m43() const { return m_matrix[3][2]; }
207     void setM43(double f) { m_matrix[3][2] = f; }
208     double m44() const { return m_matrix[3][3]; }
209     void setM44(double f) { m_matrix[3][3] = f; }
210     
211     double a() const { return m_matrix[0][0]; }
212     void setA(double a) { m_matrix[0][0] = a; }
213
214     double b() const { return m_matrix[0][1]; }
215     void setB(double b) { m_matrix[0][1] = b; }
216
217     double c() const { return m_matrix[1][0]; }
218     void setC(double c) { m_matrix[1][0] = c; }
219
220     double d() const { return m_matrix[1][1]; }
221     void setD(double d) { m_matrix[1][1] = d; }
222
223     double e() const { return m_matrix[3][0]; }
224     void setE(double e) { m_matrix[3][0] = e; }
225
226     double f() const { return m_matrix[3][1]; }
227     void setF(double f) { m_matrix[3][1] = f; }
228
229     // this = mat * this.
230     TransformationMatrix& multiply(const TransformationMatrix&);
231
232     TransformationMatrix& scale(double);
233     TransformationMatrix& scaleNonUniform(double sx, double sy);
234     TransformationMatrix& scale3d(double sx, double sy, double sz);
235     
236     TransformationMatrix& rotate(double d) { return rotate3d(0, 0, d); }
237     TransformationMatrix& rotateFromVector(double x, double y);
238     TransformationMatrix& rotate3d(double rx, double ry, double rz);
239     
240     // The vector (x,y,z) is normalized if it's not already. A vector of
241     // (0,0,0) uses a vector of (0,0,1).
242     TransformationMatrix& rotate3d(double x, double y, double z, double angle);
243     
244     TransformationMatrix& translate(double tx, double ty);
245     TransformationMatrix& translate3d(double tx, double ty, double tz);
246
247     // translation added with a post-multiply
248     TransformationMatrix& translateRight(double tx, double ty);
249     TransformationMatrix& translateRight3d(double tx, double ty, double tz);
250     
251     TransformationMatrix& flipX();
252     TransformationMatrix& flipY();
253     TransformationMatrix& skew(double angleX, double angleY);
254     TransformationMatrix& skewX(double angle) { return skew(angle, 0); }
255     TransformationMatrix& skewY(double angle) { return skew(0, angle); }
256
257     TransformationMatrix& applyPerspective(double p);
258     bool hasPerspective() const { return m_matrix[2][3] != 0.0f; }
259
260     // returns a transformation that maps a rect to a rect
261     static TransformationMatrix rectToRect(const FloatRect&, const FloatRect&);
262
263     bool isInvertible() const;
264
265     // This method returns the identity matrix if it is not invertible.
266     // Use isInvertible() before calling this if you need to know.
267     TransformationMatrix inverse() const;
268
269     // decompose the matrix into its component parts
270     typedef struct {
271         double scaleX, scaleY, scaleZ;
272         double skewXY, skewXZ, skewYZ;
273         double quaternionX, quaternionY, quaternionZ, quaternionW;
274         double translateX, translateY, translateZ;
275         double perspectiveX, perspectiveY, perspectiveZ, perspectiveW;
276     } DecomposedType;
277     
278     bool decompose(DecomposedType& decomp) const;
279     void recompose(const DecomposedType& decomp);
280     
281     void blend(const TransformationMatrix& from, double progress);
282
283     bool isAffine() const
284     {
285         return (m13() == 0 && m14() == 0 && m23() == 0 && m24() == 0 && 
286                 m31() == 0 && m32() == 0 && m33() == 1 && m34() == 0 && m43() == 0 && m44() == 1);
287     }
288
289     // Throw away the non-affine parts of the matrix (lossy!)
290     void makeAffine();
291
292     AffineTransform toAffineTransform() const;
293
294     bool operator==(const TransformationMatrix& m2) const
295     {
296         return (m_matrix[0][0] == m2.m_matrix[0][0] &&
297                 m_matrix[0][1] == m2.m_matrix[0][1] &&
298                 m_matrix[0][2] == m2.m_matrix[0][2] &&
299                 m_matrix[0][3] == m2.m_matrix[0][3] &&
300                 m_matrix[1][0] == m2.m_matrix[1][0] &&
301                 m_matrix[1][1] == m2.m_matrix[1][1] &&
302                 m_matrix[1][2] == m2.m_matrix[1][2] &&
303                 m_matrix[1][3] == m2.m_matrix[1][3] &&
304                 m_matrix[2][0] == m2.m_matrix[2][0] &&
305                 m_matrix[2][1] == m2.m_matrix[2][1] &&
306                 m_matrix[2][2] == m2.m_matrix[2][2] &&
307                 m_matrix[2][3] == m2.m_matrix[2][3] &&
308                 m_matrix[3][0] == m2.m_matrix[3][0] &&
309                 m_matrix[3][1] == m2.m_matrix[3][1] &&
310                 m_matrix[3][2] == m2.m_matrix[3][2] &&
311                 m_matrix[3][3] == m2.m_matrix[3][3]);
312     }
313
314     bool operator!=(const TransformationMatrix& other) const { return !(*this == other); }
315
316     // *this = *this * t
317     TransformationMatrix& operator*=(const TransformationMatrix& t)
318     {
319         return multiply(t);
320     }
321     
322     // result = *this * t
323     TransformationMatrix operator*(const TransformationMatrix& t) const
324     {
325         TransformationMatrix result = *this;
326         result.multiply(t);
327         return result;
328     }
329
330 #if USE(CA)
331     TransformationMatrix(const CATransform3D&);
332     operator CATransform3D() const;
333 #endif
334 #if USE(CG)
335     TransformationMatrix(const CGAffineTransform&);
336     operator CGAffineTransform() const;
337 #elif USE(CAIRO)
338     operator cairo_matrix_t() const;
339 #elif PLATFORM(QT)
340     operator QTransform() const;
341     operator QMatrix4x4() const;
342 #endif
343
344 #if PLATFORM(WIN) || (PLATFORM(GTK) && OS(WINDOWS)) || (PLATFORM(QT) && OS(WINDOWS))
345     operator XFORM() const;
346 #endif
347
348     bool isIdentityOrTranslation() const
349     {
350         return m_matrix[0][0] == 1 && m_matrix[0][1] == 0 && m_matrix[0][2] == 0 && m_matrix[0][3] == 0
351             && m_matrix[1][0] == 0 && m_matrix[1][1] == 1 && m_matrix[1][2] == 0 && m_matrix[1][3] == 0
352             && m_matrix[2][0] == 0 && m_matrix[2][1] == 0 && m_matrix[2][2] == 1 && m_matrix[2][3] == 0
353             && m_matrix[3][3] == 1;
354     }
355
356     bool isIntegerTranslation() const;
357
358     // This method returns the matrix without 3D components.
359     TransformationMatrix to2dTransform() const;
360     
361     typedef float FloatMatrix4[16];
362     void toColumnMajorFloatArray(FloatMatrix4& result) const;
363
364     // A local-space layer is implicitly defined at the z = 0 plane, with its front side
365     // facing the positive z-axis (i.e. a camera looking along the negative z-axis sees
366     // the front side of the layer). This function checks if the transformed layer's back
367     // face would be visible to a camera looking along the negative z-axis in the target space.
368     bool isBackFaceVisible() const;
369
370 private:
371     // multiply passed 2D point by matrix (assume z=0)
372     void multVecMatrix(double x, double y, double& dstX, double& dstY) const;
373     FloatPoint internalMapPoint(const FloatPoint& sourcePoint) const
374     {
375         double resultX;
376         double resultY;
377         multVecMatrix(sourcePoint.x(), sourcePoint.y(), resultX, resultY);
378         return FloatPoint(static_cast<float>(resultX), static_cast<float>(resultY));
379     }
380
381     // multiply passed 3D point by matrix
382     void multVecMatrix(double x, double y, double z, double& dstX, double& dstY, double& dstZ) const;
383     FloatPoint3D internalMapPoint(const FloatPoint3D& sourcePoint) const
384     {
385         double resultX;
386         double resultY;
387         double resultZ;
388         multVecMatrix(sourcePoint.x(), sourcePoint.y(), sourcePoint.z(), resultX, resultY, resultZ);
389         return FloatPoint3D(static_cast<float>(resultX), static_cast<float>(resultY), static_cast<float>(resultZ));
390     }
391
392     void setMatrix(const Matrix4 m)
393     {
394         if (m && m != m_matrix)
395             memcpy(m_matrix, m, sizeof(Matrix4));
396     }
397
398     Matrix4 m_matrix;
399 };
400
401 } // namespace WebCore
402
403 #endif // TransformationMatrix_h