18e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project/* 28e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * Copyright (C) 2005, 2006 Apple Computer, Inc. All rights reserved. 38e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * 48e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * Redistribution and use in source and binary forms, with or without 58e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * modification, are permitted provided that the following conditions 68e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * are met: 78e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * 1. Redistributions of source code must retain the above copyright 88e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * notice, this list of conditions and the following disclaimer. 98e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * 2. Redistributions in binary form must reproduce the above copyright 108e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * notice, this list of conditions and the following disclaimer in the 118e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * documentation and/or other materials provided with the distribution. 128e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * 138e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY 148e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 158e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 168e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE COMPUTER, INC. OR 178e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 188e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 198e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR 208e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY 218e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 228e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 23635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 248e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project */ 258e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 26635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project#ifndef TransformationMatrix_h 27635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project#define TransformationMatrix_h 288e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 295f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian#include "FloatPoint.h" 305f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian#include "IntPoint.h" 315f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian#include <string.h> //for memcpy 32643ca7872b450ea4efacab6188849e5aac2ba161Steve Block#include <wtf/FastAllocBase.h> 335f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian 342daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch#if USE(CA) 3581bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdochtypedef struct CATransform3D CATransform3D; 36f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch#endif 372daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch#if USE(CG) 3881bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdochtypedef struct CGAffineTransform CGAffineTransform; 392daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch#elif USE(CAIRO) 408e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#include <cairo.h> 41d0825bca7fe65beaee391d30da42e937db621564Steve Block#elif PLATFORM(OPENVG) 42d0825bca7fe65beaee391d30da42e937db621564Steve Block#include "VGUtils.h" 438f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian#elif PLATFORM(QT) 448f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian#include <QTransform> 4581bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch#elif USE(SKIA) 468f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian#include <SkMatrix.h> 478e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#elif PLATFORM(WX) && USE(WXGC) 488e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#include <wx/graphics.h> 498e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#endif 508e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 51d0825bca7fe65beaee391d30da42e937db621564Steve Block#if PLATFORM(WIN) || (PLATFORM(QT) && OS(WINDOWS)) || (PLATFORM(WX) && OS(WINDOWS)) 5221939df44de1705786c545cd1bf519d47250322dBen Murdoch#if COMPILER(MINGW) && !COMPILER(MINGW64) 53d0825bca7fe65beaee391d30da42e937db621564Steve Blocktypedef struct _XFORM XFORM; 54d0825bca7fe65beaee391d30da42e937db621564Steve Block#else 55d0825bca7fe65beaee391d30da42e937db621564Steve Blocktypedef struct tagXFORM XFORM; 56d0825bca7fe65beaee391d30da42e937db621564Steve Block#endif 57d0825bca7fe65beaee391d30da42e937db621564Steve Block#endif 58d0825bca7fe65beaee391d30da42e937db621564Steve Block 598e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectnamespace WebCore { 608e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 618a0914b749bbe7da7768e07a7db5c6d4bb09472bSteve Blockclass AffineTransform; 628e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectclass IntRect; 638f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qianclass FloatPoint3D; 648e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectclass FloatRect; 65635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Projectclass FloatQuad; 668e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 67ab9e7a118cf1ea2e3a93dce683b2ded3e7291ddbBen Murdochclass TransformationMatrix { 68ab9e7a118cf1ea2e3a93dce683b2ded3e7291ddbBen Murdoch WTF_MAKE_FAST_ALLOCATED; 698e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectpublic: 708f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian typedef double Matrix4[4][4]; 718e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 728f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian TransformationMatrix() { makeIdentity(); } 738f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian TransformationMatrix(const TransformationMatrix& t) { *this = t; } 748f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian TransformationMatrix(double a, double b, double c, double d, double e, double f) { setMatrix(a, b, c, d, e, f); } 758f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian TransformationMatrix(double m11, double m12, double m13, double m14, 768f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian double m21, double m22, double m23, double m24, 778f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian double m31, double m32, double m33, double m34, 788f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian double m41, double m42, double m43, double m44) 798f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian { 808f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian setMatrix(m11, m12, m13, m14, m21, m22, m23, m24, m31, m32, m33, m34, m41, m42, m43, m44); 818f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian } 828e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 838f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian void setMatrix(double a, double b, double c, double d, double e, double f) 848f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian { 858f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian m_matrix[0][0] = a; m_matrix[0][1] = b; m_matrix[0][2] = 0; m_matrix[0][3] = 0; 868f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian m_matrix[1][0] = c; m_matrix[1][1] = d; m_matrix[1][2] = 0; m_matrix[1][3] = 0; 878f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian m_matrix[2][0] = 0; m_matrix[2][1] = 0; m_matrix[2][2] = 1; m_matrix[2][3] = 0; 888f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian m_matrix[3][0] = e; m_matrix[3][1] = f; m_matrix[3][2] = 0; m_matrix[3][3] = 1; 898f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian } 908f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian 918f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian void setMatrix(double m11, double m12, double m13, double m14, 928f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian double m21, double m22, double m23, double m24, 938f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian double m31, double m32, double m33, double m34, 948f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian double m41, double m42, double m43, double m44) 958f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian { 968f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian m_matrix[0][0] = m11; m_matrix[0][1] = m12; m_matrix[0][2] = m13; m_matrix[0][3] = m14; 978f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian m_matrix[1][0] = m21; m_matrix[1][1] = m22; m_matrix[1][2] = m23; m_matrix[1][3] = m24; 988f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian m_matrix[2][0] = m31; m_matrix[2][1] = m32; m_matrix[2][2] = m33; m_matrix[2][3] = m34; 998f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian m_matrix[3][0] = m41; m_matrix[3][1] = m42; m_matrix[3][2] = m43; m_matrix[3][3] = m44; 1008f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian } 1018f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian 1028f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian TransformationMatrix& operator =(const TransformationMatrix &t) 1038f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian { 1048f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian setMatrix(t.m_matrix); 1058f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian return *this; 1068f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian } 1078f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian 1088f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian TransformationMatrix& makeIdentity() 1098f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian { 1108f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian setMatrix(1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1); 1118f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian return *this; 1128f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian } 1138f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian 1148f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian bool isIdentity() const 1158f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian { 1168f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian return m_matrix[0][0] == 1 && m_matrix[0][1] == 0 && m_matrix[0][2] == 0 && m_matrix[0][3] == 0 && 1178f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian m_matrix[1][0] == 0 && m_matrix[1][1] == 1 && m_matrix[1][2] == 0 && m_matrix[1][3] == 0 && 1188f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian m_matrix[2][0] == 0 && m_matrix[2][1] == 0 && m_matrix[2][2] == 1 && m_matrix[2][3] == 0 && 1198f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian m_matrix[3][0] == 0 && m_matrix[3][1] == 0 && m_matrix[3][2] == 0 && m_matrix[3][3] == 1; 1208f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian } 1218f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian 1228f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian // This form preserves the double math from input to output 1238f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian void map(double x, double y, double& x2, double& y2) const { multVecMatrix(x, y, x2, y2); } 1248e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 1258f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian // Map a 3D point through the transform, returning a 3D point. 1268f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian FloatPoint3D mapPoint(const FloatPoint3D&) const; 1278f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian 1288f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian // Map a 2D point through the transform, returning a 2D point. 1298f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian // Note that this ignores the z component, effectively projecting the point into the z=0 plane. 1308e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project FloatPoint mapPoint(const FloatPoint&) const; 1318e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 1328f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian // Like the version above, except that it rounds the mapped point to the nearest integer value. 1335f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian IntPoint mapPoint(const IntPoint& p) const 1345f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian { 1355f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian return roundedIntPoint(mapPoint(FloatPoint(p))); 1365f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian } 1378f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian 1388f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian // If the matrix has 3D components, the z component of the result is 1398f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian // dropped, effectively projecting the rect into the z=0 plane 1408f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian FloatRect mapRect(const FloatRect&) const; 1418f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian 1428e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project // Rounds the resulting mapped rectangle out. This is helpful for bounding 1438e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project // box computations but may not be what is wanted in other contexts. 1448e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project IntRect mapRect(const IntRect&) const; 1458e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 1468f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian // If the matrix has 3D components, the z component of the result is 1478f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian // dropped, effectively projecting the quad into the z=0 plane 148635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project FloatQuad mapQuad(const FloatQuad&) const; 149635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project 1508f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian // Map a point on the z=0 plane into a point on 1518f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian // the plane with with the transform applied, by extending 1528f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian // a ray perpendicular to the source plane and computing 1538f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian // the local x,y position of the point where that ray intersects 1548f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian // with the destination plane. 1558f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian FloatPoint projectPoint(const FloatPoint&) const; 1568f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian // Projects the four corners of the quad 1578f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian FloatQuad projectQuad(const FloatQuad&) const; 1588e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 1598f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian double m11() const { return m_matrix[0][0]; } 1608f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian void setM11(double f) { m_matrix[0][0] = f; } 1618f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian double m12() const { return m_matrix[0][1]; } 1628f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian void setM12(double f) { m_matrix[0][1] = f; } 1638f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian double m13() const { return m_matrix[0][2]; } 1648f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian void setM13(double f) { m_matrix[0][2] = f; } 1658f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian double m14() const { return m_matrix[0][3]; } 1668f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian void setM14(double f) { m_matrix[0][3] = f; } 1678f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian double m21() const { return m_matrix[1][0]; } 1688f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian void setM21(double f) { m_matrix[1][0] = f; } 1698f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian double m22() const { return m_matrix[1][1]; } 1708f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian void setM22(double f) { m_matrix[1][1] = f; } 1718f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian double m23() const { return m_matrix[1][2]; } 1728f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian void setM23(double f) { m_matrix[1][2] = f; } 1738f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian double m24() const { return m_matrix[1][3]; } 1748f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian void setM24(double f) { m_matrix[1][3] = f; } 1758f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian double m31() const { return m_matrix[2][0]; } 1768f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian void setM31(double f) { m_matrix[2][0] = f; } 1778f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian double m32() const { return m_matrix[2][1]; } 1788f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian void setM32(double f) { m_matrix[2][1] = f; } 1798f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian double m33() const { return m_matrix[2][2]; } 1808f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian void setM33(double f) { m_matrix[2][2] = f; } 1818f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian double m34() const { return m_matrix[2][3]; } 1828f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian void setM34(double f) { m_matrix[2][3] = f; } 1838f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian double m41() const { return m_matrix[3][0]; } 1848f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian void setM41(double f) { m_matrix[3][0] = f; } 1858f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian double m42() const { return m_matrix[3][1]; } 1868f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian void setM42(double f) { m_matrix[3][1] = f; } 1878f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian double m43() const { return m_matrix[3][2]; } 1888f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian void setM43(double f) { m_matrix[3][2] = f; } 1898f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian double m44() const { return m_matrix[3][3]; } 1908f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian void setM44(double f) { m_matrix[3][3] = f; } 1918f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian 1928f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian double a() const { return m_matrix[0][0]; } 1938f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian void setA(double a) { m_matrix[0][0] = a; } 1948e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 1958f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian double b() const { return m_matrix[0][1]; } 1968f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian void setB(double b) { m_matrix[0][1] = b; } 1978e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 1988f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian double c() const { return m_matrix[1][0]; } 1998f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian void setC(double c) { m_matrix[1][0] = c; } 2008e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 2018f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian double d() const { return m_matrix[1][1]; } 2028f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian void setD(double d) { m_matrix[1][1] = d; } 2038e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 2048f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian double e() const { return m_matrix[3][0]; } 2058f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian void setE(double e) { m_matrix[3][0] = e; } 2068e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 2078f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian double f() const { return m_matrix[3][1]; } 2088f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian void setF(double f) { m_matrix[3][1] = f; } 2098e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 2108f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian // this = this * mat 2112fc2651226baac27029e38c9d6ef883fa32084dbSteve Block TransformationMatrix& multiply(const TransformationMatrix&); 2128e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 213635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project TransformationMatrix& scale(double); 214635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project TransformationMatrix& scaleNonUniform(double sx, double sy); 2158f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian TransformationMatrix& scale3d(double sx, double sy, double sz); 2168f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian 2178f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian TransformationMatrix& rotate(double d) { return rotate3d(0, 0, d); } 218635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project TransformationMatrix& rotateFromVector(double x, double y); 2198f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian TransformationMatrix& rotate3d(double rx, double ry, double rz); 2208f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian 2218f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian // The vector (x,y,z) is normalized if it's not already. A vector of 2228f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian // (0,0,0) uses a vector of (0,0,1). 2238f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian TransformationMatrix& rotate3d(double x, double y, double z, double angle); 2248f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian 225635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project TransformationMatrix& translate(double tx, double ty); 2268f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian TransformationMatrix& translate3d(double tx, double ty, double tz); 2278f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian 2288f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian // translation added with a post-multiply 2298f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian TransformationMatrix& translateRight(double tx, double ty); 2308f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian TransformationMatrix& translateRight3d(double tx, double ty, double tz); 2318f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian 232635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project TransformationMatrix& flipX(); 233635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project TransformationMatrix& flipY(); 234635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project TransformationMatrix& skew(double angleX, double angleY); 2358f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian TransformationMatrix& skewX(double angle) { return skew(angle, 0); } 2368f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian TransformationMatrix& skewY(double angle) { return skew(0, angle); } 2378f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian 2388f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian TransformationMatrix& applyPerspective(double p); 2398f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian bool hasPerspective() const { return m_matrix[2][3] != 0.0f; } 240635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project 2410bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch // returns a transformation that maps a rect to a rect 2420bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch static TransformationMatrix rectToRect(const FloatRect&, const FloatRect&); 2430bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch 2448e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project bool isInvertible() const; 2458f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian 2468f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian // This method returns the identity matrix if it is not invertible. 2478f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian // Use isInvertible() before calling this if you need to know. 248635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project TransformationMatrix inverse() const; 2498e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 2508f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian // decompose the matrix into its component parts 2518f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian typedef struct { 2528f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian double scaleX, scaleY, scaleZ; 2538f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian double skewXY, skewXZ, skewYZ; 2548f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian double quaternionX, quaternionY, quaternionZ, quaternionW; 2558f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian double translateX, translateY, translateZ; 2568f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian double perspectiveX, perspectiveY, perspectiveZ, perspectiveW; 2578f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian } DecomposedType; 2588f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian 2598f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian bool decompose(DecomposedType& decomp) const; 2608f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian void recompose(const DecomposedType& decomp); 2618f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian 262635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project void blend(const TransformationMatrix& from, double progress); 2638e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 2648f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian bool isAffine() const 2658f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian { 2668f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian return (m13() == 0 && m14() == 0 && m23() == 0 && m24() == 0 && 2678f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian m31() == 0 && m32() == 0 && m33() == 1 && m34() == 0 && m43() == 0 && m44() == 1); 2688f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian } 2698f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian 2708f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian // Throw away the non-affine parts of the matrix (lossy!) 2718f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian void makeAffine(); 2728f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian 2738a0914b749bbe7da7768e07a7db5c6d4bb09472bSteve Block AffineTransform toAffineTransform() const; 2748a0914b749bbe7da7768e07a7db5c6d4bb09472bSteve Block 2758f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian bool operator==(const TransformationMatrix& m2) const 2768f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian { 2778f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian return (m_matrix[0][0] == m2.m_matrix[0][0] && 2788f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian m_matrix[0][1] == m2.m_matrix[0][1] && 2798f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian m_matrix[0][2] == m2.m_matrix[0][2] && 2808f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian m_matrix[0][3] == m2.m_matrix[0][3] && 2818f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian m_matrix[1][0] == m2.m_matrix[1][0] && 2828f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian m_matrix[1][1] == m2.m_matrix[1][1] && 2838f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian m_matrix[1][2] == m2.m_matrix[1][2] && 2848f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian m_matrix[1][3] == m2.m_matrix[1][3] && 2858f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian m_matrix[2][0] == m2.m_matrix[2][0] && 2868f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian m_matrix[2][1] == m2.m_matrix[2][1] && 2878f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian m_matrix[2][2] == m2.m_matrix[2][2] && 2888f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian m_matrix[2][3] == m2.m_matrix[2][3] && 2898f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian m_matrix[3][0] == m2.m_matrix[3][0] && 2908f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian m_matrix[3][1] == m2.m_matrix[3][1] && 2918f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian m_matrix[3][2] == m2.m_matrix[3][2] && 2928f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian m_matrix[3][3] == m2.m_matrix[3][3]); 2938f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian } 2948e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 295635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project bool operator!=(const TransformationMatrix& other) const { return !(*this == other); } 2962fc2651226baac27029e38c9d6ef883fa32084dbSteve Block 2972fc2651226baac27029e38c9d6ef883fa32084dbSteve Block // *this = *this * t 2988f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian TransformationMatrix& operator*=(const TransformationMatrix& t) 2998f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian { 3002fc2651226baac27029e38c9d6ef883fa32084dbSteve Block return multiply(t); 3018f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian } 3028f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian 3032fc2651226baac27029e38c9d6ef883fa32084dbSteve Block // result = *this * t 3040bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch TransformationMatrix operator*(const TransformationMatrix& t) const 3058f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian { 3062fc2651226baac27029e38c9d6ef883fa32084dbSteve Block TransformationMatrix result = *this; 3072fc2651226baac27029e38c9d6ef883fa32084dbSteve Block result.multiply(t); 3088f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian return result; 3098f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian } 310635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project 3112daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch#if USE(CA) 312f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch TransformationMatrix(const CATransform3D&); 313f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch operator CATransform3D() const; 314f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch#endif 3152daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch#if USE(CG) 316f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch TransformationMatrix(const CGAffineTransform&); 3178f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian operator CGAffineTransform() const; 3182daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch#elif USE(CAIRO) 3198f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian operator cairo_matrix_t() const; 320d0825bca7fe65beaee391d30da42e937db621564Steve Block#elif PLATFORM(OPENVG) 321d0825bca7fe65beaee391d30da42e937db621564Steve Block operator VGMatrix() const; 3228f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian#elif PLATFORM(QT) 3238f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian operator QTransform() const; 32481bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch#elif USE(SKIA) 3258f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian operator SkMatrix() const; 3268f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian#elif PLATFORM(WX) && USE(WXGC) 3278f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian operator wxGraphicsMatrix() const; 3288e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#endif 3298e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 330d0825bca7fe65beaee391d30da42e937db621564Steve Block#if PLATFORM(WIN) || (PLATFORM(QT) && OS(WINDOWS)) || (PLATFORM(WX) && OS(WINDOWS)) 3310bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch operator XFORM() const; 3320bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch#endif 3330bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch 334d0825bca7fe65beaee391d30da42e937db621564Steve Block bool isIdentityOrTranslation() const 335d0825bca7fe65beaee391d30da42e937db621564Steve Block { 336d0825bca7fe65beaee391d30da42e937db621564Steve Block return m_matrix[0][0] == 1 && m_matrix[0][1] == 0 && m_matrix[0][2] == 0 && m_matrix[0][3] == 0 337d0825bca7fe65beaee391d30da42e937db621564Steve Block && m_matrix[1][0] == 0 && m_matrix[1][1] == 1 && m_matrix[1][2] == 0 && m_matrix[1][3] == 0 338d0825bca7fe65beaee391d30da42e937db621564Steve Block && m_matrix[2][0] == 0 && m_matrix[2][1] == 0 && m_matrix[2][2] == 1 && m_matrix[2][3] == 0 339d0825bca7fe65beaee391d30da42e937db621564Steve Block && m_matrix[3][3] == 1; 340d0825bca7fe65beaee391d30da42e937db621564Steve Block } 341d0825bca7fe65beaee391d30da42e937db621564Steve Block 3428f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qianprivate: 3438f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian // multiply passed 2D point by matrix (assume z=0) 3448f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian void multVecMatrix(double x, double y, double& dstX, double& dstY) const; 345d0825bca7fe65beaee391d30da42e937db621564Steve Block 3468f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian // multiply passed 3D point by matrix 3478f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian void multVecMatrix(double x, double y, double z, double& dstX, double& dstY, double& dstZ) const; 348d0825bca7fe65beaee391d30da42e937db621564Steve Block 3498f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian void setMatrix(const Matrix4 m) 3508f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian { 3518f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian if (m && m != m_matrix) 3528f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian memcpy(m_matrix, m, sizeof(Matrix4)); 3538f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian } 354d0825bca7fe65beaee391d30da42e937db621564Steve Block 3558f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian Matrix4 m_matrix; 3568f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian}; 3578e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 3588e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project} // namespace WebCore 3598e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 360635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project#endif // TransformationMatrix_h 361