3
* Redistribution and use in source and binary forms, with or without
4
* modification, are permitted provided that the following conditions
6
* 1. Redistributions of source code must retain the above copyright
7
* notice, this list of conditions and the following disclaimer.
8
* 2. Redistributions in binary form must reproduce the above copyright
9
* notice, this list of conditions and the following disclaimer in the
10
* documentation and/or other materials provided with the distribution.
12
* THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY
13
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
14
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
15
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE COMPUTER, INC. OR
16
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
17
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
18
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
19
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
20
* OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
21
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
22
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26
#include "AffineTransform.h"
29
#include "FloatRect.h"
35
static const double deg2rad = 0.017453292519943295769; // pi/180
37
AffineTransform::AffineTransform()
39
cairo_matrix_init_identity(&m_transform);
42
AffineTransform::AffineTransform(double a, double b, double c, double d, double tx, double ty)
44
cairo_matrix_init(&m_transform, a, c, b, d, tx, ty);
47
AffineTransform::AffineTransform(const cairo_matrix_t &matrix)
52
void AffineTransform::setMatrix(double a, double b, double c, double d, double tx, double ty)
54
cairo_matrix_init(&m_transform, a, c, b, d, tx, ty);
57
void AffineTransform::map(double x, double y, double* x2, double* y2) const
61
cairo_matrix_transform_point(&m_transform, x2, y2);
64
IntRect AffineTransform::mapRect(const IntRect &rect) const
66
FloatRect floatRect(rect);
67
FloatRect enclosingFloatRect = this->mapRect(floatRect);
69
return enclosingIntRect(enclosingFloatRect);
72
FloatRect AffineTransform::mapRect(const FloatRect &rect) const
74
double rectMinX = rect.x();
75
double rectMaxX = rect.x() + rect.width();
76
double rectMinY = rect.y();
77
double rectMaxY = rect.y() + rect.height();
81
cairo_matrix_transform_point(&m_transform, &px, &py);
83
double enclosingRectMinX = px;
84
double enclosingRectMinY = py;
85
double enclosingRectMaxX = px;
86
double enclosingRectMaxY = py;
90
cairo_matrix_transform_point(&m_transform, &px, &py);
91
if (px < enclosingRectMinX)
92
enclosingRectMinX = px;
93
else if (px > enclosingRectMaxX)
94
enclosingRectMaxX = px;
95
if (py < enclosingRectMinY)
96
enclosingRectMinY = py;
97
else if (py > enclosingRectMaxY)
98
enclosingRectMaxY = py;
102
cairo_matrix_transform_point(&m_transform, &px, &py);
103
if (px < enclosingRectMinX)
104
enclosingRectMinX = px;
105
else if (px > enclosingRectMaxX)
106
enclosingRectMaxX = px;
107
if (py < enclosingRectMinY)
108
enclosingRectMinY = py;
109
else if (py > enclosingRectMaxY)
110
enclosingRectMaxY = py;
114
cairo_matrix_transform_point(&m_transform, &px, &py);
115
if (px < enclosingRectMinX)
116
enclosingRectMinX = px;
117
else if (px > enclosingRectMaxX)
118
enclosingRectMaxX = px;
119
if (py < enclosingRectMinY)
120
enclosingRectMinY = py;
121
else if (py > enclosingRectMaxY)
122
enclosingRectMaxY = py;
125
double enclosingRectWidth = enclosingRectMaxX - enclosingRectMinX;
126
double enclosingRectHeight = enclosingRectMaxY - enclosingRectMinY;
128
return FloatRect(enclosingRectMinX, enclosingRectMinY, enclosingRectWidth, enclosingRectHeight);
131
bool AffineTransform::isIdentity() const
133
return ((m_transform.xx == 1) && (m_transform.yy == 1)
134
&& (m_transform.xy == 0) && (m_transform.yx == 0)
135
&& (m_transform.x0 == 0) && (m_transform.y0 == 0));
138
double AffineTransform::a() const
140
return m_transform.xx;
143
void AffineTransform::setA(double a)
148
double AffineTransform::b() const
150
return m_transform.xy;
153
void AffineTransform::setB(double b)
158
double AffineTransform::c() const
160
return m_transform.yx;
163
void AffineTransform::setC(double c)
168
double AffineTransform::d() const
170
return m_transform.yy;
173
void AffineTransform::setD(double d)
178
double AffineTransform::e() const
180
return m_transform.x0;
183
void AffineTransform::setE(double e)
188
double AffineTransform::f() const
190
return m_transform.y0;
193
void AffineTransform::setF(double f)
198
void AffineTransform::reset()
200
cairo_matrix_init_identity(&m_transform);
203
AffineTransform &AffineTransform::scale(double sx, double sy)
205
cairo_matrix_scale(&m_transform, sx, sy);
209
AffineTransform &AffineTransform::rotate(double d)
211
cairo_matrix_rotate(&m_transform, d * deg2rad);
215
AffineTransform &AffineTransform::translate(double tx, double ty)
217
cairo_matrix_translate(&m_transform, tx, ty);
221
AffineTransform &AffineTransform::shear(double sx, double sy)
223
cairo_matrix_t shear;
224
cairo_matrix_init(&shear, 1, sx, sy, 1, 0, 0);
226
cairo_matrix_t result;
227
cairo_matrix_multiply(&result, &shear, &m_transform);
228
m_transform = result;
233
double AffineTransform::det() const
235
return m_transform.xx * m_transform.yy - m_transform.xy * m_transform.yx;
238
AffineTransform AffineTransform::inverse() const
240
if (!isInvertible()) return AffineTransform();
242
cairo_matrix_t result = m_transform;
243
cairo_matrix_invert(&result);
244
return AffineTransform(result);
247
AffineTransform::operator cairo_matrix_t() const
252
bool AffineTransform::operator== (const AffineTransform &m2) const
254
return ((m_transform.xx == m2.m_transform.xx)
255
&& (m_transform.yy == m2.m_transform.yy)
256
&& (m_transform.xy == m2.m_transform.xy)
257
&& (m_transform.yx == m2.m_transform.yx)
258
&& (m_transform.x0 == m2.m_transform.x0)
259
&& (m_transform.y0 == m2.m_transform.y0));
263
AffineTransform &AffineTransform::operator*= (const AffineTransform &m2)
265
cairo_matrix_t result;
266
cairo_matrix_multiply(&result, &m_transform, &m2.m_transform);
267
m_transform = result;
272
AffineTransform AffineTransform::operator* (const AffineTransform &m2)
274
cairo_matrix_t result;
275
cairo_matrix_multiply(&result, &m_transform, &m2.m_transform);