15c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)/* 25c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * Copyright (C) 2005, 2006 Apple Computer, Inc. All rights reserved. 35c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * 2010 Dirk Schulze <krit@webkit.org> 45c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * 55c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * Redistribution and use in source and binary forms, with or without 65c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * modification, are permitted provided that the following conditions 75c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * are met: 85c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * 1. Redistributions of source code must retain the above copyright 95c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * notice, this list of conditions and the following disclaimer. 105c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * 2. Redistributions in binary form must reproduce the above copyright 115c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * notice, this list of conditions and the following disclaimer in the 125c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * documentation and/or other materials provided with the distribution. 135c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * 145c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY 155c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 165c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 175c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE COMPUTER, INC. OR 185c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 195c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 205c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR 215c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY 225c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 235c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 2402772c6a72f1ee0b226341a4f4439970c29fc861Ben Murdoch * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 255c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) */ 265c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 275c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)#ifndef AffineTransform_h 285c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)#define AffineTransform_h 295c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 301e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)#include "platform/transforms/TransformationMatrix.h" 315c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 325c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)#include <string.h> // for memcpy 337757ec2eadfa2dd8ac2aeed0a4399e9b07ec38cbBen Murdoch#include "wtf/FastAllocBase.h" 345c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 355c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)namespace WebCore { 365c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 375c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)class FloatPoint; 385c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)class FloatQuad; 395c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)class FloatRect; 405c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)class IntPoint; 415c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)class IntRect; 425c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)class TransformationMatrix; 435c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 441e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)class PLATFORM_EXPORT AffineTransform { 455c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) WTF_MAKE_FAST_ALLOCATED; 465c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)public: 475c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) typedef double Transform[6]; 485c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 495c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) AffineTransform(); 505c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) AffineTransform(double a, double b, double c, double d, double e, double f); 515c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 525c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) void setMatrix(double a, double b, double c, double d, double e, double f); 535c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 545c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) void map(double x, double y, double& x2, double& y2) const; 555c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 565c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) // Rounds the mapped point to the nearest integer value. 575c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) IntPoint mapPoint(const IntPoint&) const; 585c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 595c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) FloatPoint mapPoint(const FloatPoint&) const; 605c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 615c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) IntSize mapSize(const IntSize&) const; 625c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 635c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) FloatSize mapSize(const FloatSize&) const; 645c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 655c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) // Rounds the resulting mapped rectangle out. This is helpful for bounding 665c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) // box computations but may not be what is wanted in other contexts. 675c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) IntRect mapRect(const IntRect&) const; 685c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 695c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) FloatRect mapRect(const FloatRect&) const; 705c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) FloatQuad mapQuad(const FloatQuad&) const; 715c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 725c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) bool isIdentity() const; 735c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 745c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) double a() const { return m_transform[0]; } 755c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) void setA(double a) { m_transform[0] = a; } 765c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) double b() const { return m_transform[1]; } 775c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) void setB(double b) { m_transform[1] = b; } 785c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) double c() const { return m_transform[2]; } 795c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) void setC(double c) { m_transform[2] = c; } 805c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) double d() const { return m_transform[3]; } 815c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) void setD(double d) { m_transform[3] = d; } 825c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) double e() const { return m_transform[4]; } 835c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) void setE(double e) { m_transform[4] = e; } 845c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) double f() const { return m_transform[5]; } 855c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) void setF(double f) { m_transform[5] = f; } 865c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 875c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) void makeIdentity(); 885c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 895c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) AffineTransform& multiply(const AffineTransform& other); 9002772c6a72f1ee0b226341a4f4439970c29fc861Ben Murdoch AffineTransform& scale(double); 9102772c6a72f1ee0b226341a4f4439970c29fc861Ben Murdoch AffineTransform& scale(double sx, double sy); 925c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) AffineTransform& scaleNonUniform(double sx, double sy); 935c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) AffineTransform& rotate(double d); 945c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) AffineTransform& rotateFromVector(double x, double y); 955c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) AffineTransform& translate(double tx, double ty); 965c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) AffineTransform& shear(double sx, double sy); 975c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) AffineTransform& flipX(); 985c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) AffineTransform& flipY(); 995c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) AffineTransform& skew(double angleX, double angleY); 1005c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) AffineTransform& skewX(double angle); 1015c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) AffineTransform& skewY(double angle); 1025c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 1035c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) double xScale() const; 1045c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) double yScale() const; 1055c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 1065c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) double det() const; 1075c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) bool isInvertible() const; 1085c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) AffineTransform inverse() const; 1095c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 1105c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) void blend(const AffineTransform& from, double progress); 1115c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 1125c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) TransformationMatrix toTransformationMatrix() const; 1135c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 1145c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) bool isIdentityOrTranslation() const 1155c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) { 1165c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return m_transform[0] == 1 && m_transform[1] == 0 && m_transform[2] == 0 && m_transform[3] == 1; 1175c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 11802772c6a72f1ee0b226341a4f4439970c29fc861Ben Murdoch 1195c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) bool isIdentityOrTranslationOrFlipped() const 1205c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) { 1215c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return m_transform[0] == 1 && m_transform[1] == 0 && m_transform[2] == 0 && (m_transform[3] == 1 || m_transform[3] == -1); 1225c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 1235c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 1245c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) bool preservesAxisAlignment() const 1255c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) { 1265c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return (m_transform[1] == 0 && m_transform[2] == 0) || (m_transform[0] == 0 && m_transform[3] == 0); 1275c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 1285c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 1295c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) bool operator== (const AffineTransform& m2) const 1305c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) { 1315c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return (m_transform[0] == m2.m_transform[0] 1325c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) && m_transform[1] == m2.m_transform[1] 1335c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) && m_transform[2] == m2.m_transform[2] 1345c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) && m_transform[3] == m2.m_transform[3] 1355c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) && m_transform[4] == m2.m_transform[4] 1365c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) && m_transform[5] == m2.m_transform[5]); 1375c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 1385c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 1395c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) bool operator!=(const AffineTransform& other) const { return !(*this == other); } 1405c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 1415c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) // *this = *this * t (i.e., a multRight) 1425c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) AffineTransform& operator*=(const AffineTransform& t) 1435c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) { 1445c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return multiply(t); 1455c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 14602772c6a72f1ee0b226341a4f4439970c29fc861Ben Murdoch 1475c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) // result = *this * t (i.e., a multRight) 1485c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) AffineTransform operator*(const AffineTransform& t) const 1495c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) { 1505c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) AffineTransform result = *this; 1515c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) result *= t; 1525c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return result; 1535c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 1545c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 1555c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) static AffineTransform translation(double x, double y) 1565c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) { 1575c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return AffineTransform(1, 0, 0, 1, x, y); 1585c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 15902772c6a72f1ee0b226341a4f4439970c29fc861Ben Murdoch 1605c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) // decompose the matrix into its component parts 1615c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) typedef struct { 1625c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) double scaleX, scaleY; 1635c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) double angle; 1645c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) double remainderA, remainderB, remainderC, remainderD; 1655c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) double translateX, translateY; 1665c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } DecomposedType; 16702772c6a72f1ee0b226341a4f4439970c29fc861Ben Murdoch 1685c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) bool decompose(DecomposedType&) const; 1695c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) void recompose(const DecomposedType&); 1705c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 1715c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)private: 1725c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) void setMatrix(const Transform m) 1735c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) { 1745c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (m && m != m_transform) 1755c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) memcpy(m_transform, m, sizeof(Transform)); 1765c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 1775c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 1785c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) Transform m_transform; 1795c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}; 1805c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 1811e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)PLATFORM_EXPORT AffineTransform makeMapBetweenRects(const FloatRect& source, const FloatRect& dest); 1825c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 1835c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} 1845c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 1855c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)#endif 186