1/*
2 * Copyright (C) 2005, 2006 Apple Computer, Inc.  All rights reserved.
3 *               2010 Dirk Schulze <krit@webkit.org>
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
7 * are met:
8 * 1. Redistributions of source code must retain the above copyright
9 *    notice, this list of conditions and the following disclaimer.
10 * 2. Redistributions in binary form must reproduce the above copyright
11 *    notice, this list of conditions and the following disclaimer in the
12 *    documentation and/or other materials provided with the distribution.
13 *
14 * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY
15 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
16 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
17 * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE COMPUTER, INC. OR
18 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
19 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
20 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
21 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
22 * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
23 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
24 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
25 */
26
27#ifndef AffineTransform_h
28#define AffineTransform_h
29
30#include "TransformationMatrix.h"
31
32#include <string.h> // for memcpy
33#include <wtf/FastAllocBase.h>
34
35#if USE(CG)
36#include <CoreGraphics/CGAffineTransform.h>
37#elif USE(CAIRO)
38#include <cairo.h>
39#elif PLATFORM(OPENVG)
40#include "VGUtils.h"
41#elif PLATFORM(QT)
42#include <QTransform>
43#elif USE(SKIA)
44#include <SkMatrix.h>
45#elif PLATFORM(WX) && USE(WXGC)
46#include <wx/graphics.h>
47#endif
48
49namespace WebCore {
50
51class FloatPoint;
52class FloatQuad;
53class FloatRect;
54class IntPoint;
55class IntRect;
56class TransformationMatrix;
57
58class AffineTransform {
59    WTF_MAKE_FAST_ALLOCATED;
60public:
61    typedef double Transform[6];
62
63    AffineTransform();
64    AffineTransform(double a, double b, double c, double d, double e, double f);
65
66    void setMatrix(double a, double b, double c, double d, double e, double f);
67
68    void map(double x, double y, double& x2, double& y2) const;
69
70    // Rounds the mapped point to the nearest integer value.
71    IntPoint mapPoint(const IntPoint&) const;
72
73    FloatPoint mapPoint(const FloatPoint&) const;
74
75    // Rounds the resulting mapped rectangle out. This is helpful for bounding
76    // box computations but may not be what is wanted in other contexts.
77    IntRect mapRect(const IntRect&) const;
78
79    FloatRect mapRect(const FloatRect&) const;
80    FloatQuad mapQuad(const FloatQuad&) const;
81
82    bool isIdentity() const;
83
84    double a() const { return m_transform[0]; }
85    void setA(double a) { m_transform[0] = a; }
86    double b() const { return m_transform[1]; }
87    void setB(double b) { m_transform[1] = b; }
88    double c() const { return m_transform[2]; }
89    void setC(double c) { m_transform[2] = c; }
90    double d() const { return m_transform[3]; }
91    void setD(double d) { m_transform[3] = d; }
92    double e() const { return m_transform[4]; }
93    void setE(double e) { m_transform[4] = e; }
94    double f() const { return m_transform[5]; }
95    void setF(double f) { m_transform[5] = f; }
96
97    void makeIdentity();
98
99    AffineTransform& multiply(const AffineTransform& other);
100    AffineTransform& scale(double);
101    AffineTransform& scale(double sx, double sy);
102    AffineTransform& scaleNonUniform(double sx, double sy);
103    AffineTransform& rotate(double d);
104    AffineTransform& rotateFromVector(double x, double y);
105    AffineTransform& translate(double tx, double ty);
106    AffineTransform& shear(double sx, double sy);
107    AffineTransform& flipX();
108    AffineTransform& flipY();
109    AffineTransform& skew(double angleX, double angleY);
110    AffineTransform& skewX(double angle);
111    AffineTransform& skewY(double angle);
112
113    double xScale() const;
114    double yScale() const;
115
116    double det() const;
117    bool isInvertible() const;
118    AffineTransform inverse() const;
119
120    void blend(const AffineTransform& from, double progress);
121
122    TransformationMatrix toTransformationMatrix() const;
123
124    bool isIdentityOrTranslation() const
125    {
126        return m_transform[0] == 1 && m_transform[1] == 0 && m_transform[2] == 0 && m_transform[3] == 1;
127    }
128
129    bool isIdentityOrTranslationOrFlipped() const
130    {
131        return m_transform[0] == 1 && m_transform[1] == 0 && m_transform[2] == 0 && (m_transform[3] == 1 || m_transform[3] == -1);
132    }
133
134    bool operator== (const AffineTransform& m2) const
135    {
136        return (m_transform[0] == m2.m_transform[0]
137             && m_transform[1] == m2.m_transform[1]
138             && m_transform[2] == m2.m_transform[2]
139             && m_transform[3] == m2.m_transform[3]
140             && m_transform[4] == m2.m_transform[4]
141             && m_transform[5] == m2.m_transform[5]);
142    }
143
144    bool operator!=(const AffineTransform& other) const { return !(*this == other); }
145
146    // *this = *this * t (i.e., a multRight)
147    AffineTransform& operator*=(const AffineTransform& t)
148    {
149        return multiply(t);
150    }
151
152    // result = *this * t (i.e., a multRight)
153    AffineTransform operator*(const AffineTransform& t) const
154    {
155        AffineTransform result = *this;
156        result *= t;
157        return result;
158    }
159
160#if USE(CG)
161    operator CGAffineTransform() const;
162#elif USE(CAIRO)
163    operator cairo_matrix_t() const;
164#elif PLATFORM(OPENVG)
165    operator VGMatrix() const;
166#elif PLATFORM(QT)
167    operator QTransform() const;
168#elif USE(SKIA)
169    operator SkMatrix() const;
170#elif PLATFORM(WX) && USE(WXGC)
171    operator wxGraphicsMatrix() const;
172#endif
173
174    static AffineTransform translation(double x, double y)
175    {
176        return AffineTransform(1, 0, 0, 1, x, y);
177    }
178
179private:
180    void setMatrix(const Transform m)
181    {
182        if (m && m != m_transform)
183            memcpy(m_transform, m, sizeof(Transform));
184    }
185
186    Transform m_transform;
187};
188
189AffineTransform makeMapBetweenRects(const FloatRect& source, const FloatRect& dest);
190
191}
192
193#endif
194