|
1 /* |
|
2 * Copyright (C) 2008 Apple 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 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 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 #include "config.h" |
|
27 #include "WebKitCSSMatrix.h" |
|
28 |
|
29 #include "CSSParser.h" |
|
30 #include "CSSStyleSelector.h" |
|
31 #include "CSSMutableStyleDeclaration.h" |
|
32 #include "CSSPropertyNames.h" |
|
33 #include "ExceptionCode.h" |
|
34 #include "RenderStyle.h" |
|
35 #include <wtf/MathExtras.h> |
|
36 |
|
37 namespace WebCore { |
|
38 |
|
39 WebKitCSSMatrix::WebKitCSSMatrix() |
|
40 : StyleBase(0) |
|
41 { |
|
42 } |
|
43 |
|
44 WebKitCSSMatrix::WebKitCSSMatrix(const WebKitCSSMatrix& m) |
|
45 : StyleBase(0) |
|
46 , m_matrix(m.m_matrix) |
|
47 { |
|
48 } |
|
49 |
|
50 WebKitCSSMatrix::WebKitCSSMatrix(const TransformationMatrix& m) |
|
51 : StyleBase(0) |
|
52 , m_matrix(m) |
|
53 { |
|
54 } |
|
55 |
|
56 WebKitCSSMatrix::WebKitCSSMatrix(const String& s, ExceptionCode& ec) |
|
57 : StyleBase(0) |
|
58 { |
|
59 setMatrixValue(s, ec); |
|
60 } |
|
61 |
|
62 WebKitCSSMatrix::~WebKitCSSMatrix() |
|
63 { |
|
64 } |
|
65 |
|
66 void WebKitCSSMatrix::setMatrixValue(const String& string, ExceptionCode& ec) |
|
67 { |
|
68 CSSParser p(useStrictParsing()); |
|
69 RefPtr<CSSMutableStyleDeclaration> styleDeclaration = CSSMutableStyleDeclaration::create(); |
|
70 if (p.parseValue(styleDeclaration.get(), CSSPropertyWebkitTransform, string, true)) { |
|
71 // Convert to TransformOperations. This can fail if a property |
|
72 // requires style (i.e., param uses 'ems' or 'exs') |
|
73 PassRefPtr<CSSValue> val = styleDeclaration->getPropertyCSSValue(CSSPropertyWebkitTransform); |
|
74 TransformOperations operations; |
|
75 if (!CSSStyleSelector::createTransformOperations(val.get(), 0, 0, operations)) { |
|
76 ec = SYNTAX_ERR; |
|
77 return; |
|
78 } |
|
79 |
|
80 // Convert transform operations to a TransformationMatrix. This can fail |
|
81 // if a param has a percentage ('%') |
|
82 TransformationMatrix t; |
|
83 for (unsigned i = 0; i < operations.operations().size(); ++i) { |
|
84 if (operations.operations()[i].get()->apply(t, IntSize(0, 0))) { |
|
85 ec = SYNTAX_ERR; |
|
86 return; |
|
87 } |
|
88 } |
|
89 |
|
90 // set the matrix |
|
91 m_matrix = t; |
|
92 } else if (!string.isEmpty()) // There is something there but parsing failed |
|
93 ec = SYNTAX_ERR; |
|
94 } |
|
95 |
|
96 // Perform a concatenation of the matrices (this * secondMatrix) |
|
97 PassRefPtr<WebKitCSSMatrix> WebKitCSSMatrix::multiply(WebKitCSSMatrix* secondMatrix) const |
|
98 { |
|
99 if (!secondMatrix) |
|
100 return 0; |
|
101 |
|
102 TransformationMatrix tmp(secondMatrix->m_matrix); |
|
103 tmp.multiply(m_matrix); |
|
104 return WebKitCSSMatrix::create(tmp); |
|
105 } |
|
106 |
|
107 PassRefPtr<WebKitCSSMatrix> WebKitCSSMatrix::inverse(ExceptionCode& ec) const |
|
108 { |
|
109 if (!m_matrix.isInvertible()) { |
|
110 ec = NOT_SUPPORTED_ERR; |
|
111 return 0; |
|
112 } |
|
113 |
|
114 return WebKitCSSMatrix::create(m_matrix.inverse()); |
|
115 } |
|
116 |
|
117 PassRefPtr<WebKitCSSMatrix> WebKitCSSMatrix::translate(double x, double y, double z) const |
|
118 { |
|
119 if (isnan(x)) |
|
120 x = 0; |
|
121 if (isnan(y)) |
|
122 y = 0; |
|
123 if (isnan(z)) |
|
124 z = 0; |
|
125 return WebKitCSSMatrix::create(TransformationMatrix(m_matrix).translate3d(x, y, z)); |
|
126 } |
|
127 |
|
128 PassRefPtr<WebKitCSSMatrix> WebKitCSSMatrix::scale(double scaleX, double scaleY, double scaleZ) const |
|
129 { |
|
130 if (isnan(scaleX)) |
|
131 scaleX = 1; |
|
132 if (isnan(scaleY)) |
|
133 scaleY = scaleX; |
|
134 if (isnan(scaleZ)) |
|
135 scaleZ = 1; |
|
136 return WebKitCSSMatrix::create(TransformationMatrix(m_matrix).scale3d(scaleX, scaleY, scaleZ)); |
|
137 } |
|
138 |
|
139 PassRefPtr<WebKitCSSMatrix> WebKitCSSMatrix::rotate(double rotX, double rotY, double rotZ) const |
|
140 { |
|
141 if (isnan(rotX)) |
|
142 rotX = 0; |
|
143 |
|
144 if (isnan(rotY) && isnan(rotZ)) { |
|
145 rotZ = rotX; |
|
146 rotX = 0; |
|
147 rotY = 0; |
|
148 } |
|
149 |
|
150 if (isnan(rotY)) |
|
151 rotY = 0; |
|
152 if (isnan(rotZ)) |
|
153 rotZ = 0; |
|
154 return WebKitCSSMatrix::create(TransformationMatrix(m_matrix).rotate3d(rotX, rotY, rotZ)); |
|
155 } |
|
156 |
|
157 PassRefPtr<WebKitCSSMatrix> WebKitCSSMatrix::rotateAxisAngle(double x, double y, double z, double angle) const |
|
158 { |
|
159 if (isnan(x)) |
|
160 x = 0; |
|
161 if (isnan(y)) |
|
162 y = 0; |
|
163 if (isnan(z)) |
|
164 z = 0; |
|
165 if (isnan(angle)) |
|
166 angle = 0; |
|
167 if (x == 0 && y == 0 && z == 0) |
|
168 z = 1; |
|
169 return WebKitCSSMatrix::create(TransformationMatrix(m_matrix).rotate3d(x, y, z, angle)); |
|
170 } |
|
171 |
|
172 |
|
173 String WebKitCSSMatrix::toString() const |
|
174 { |
|
175 // FIXME - Need to ensure valid CSS floating point values (https://bugs.webkit.org/show_bug.cgi?id=20674) |
|
176 if (m_matrix.isAffine()) |
|
177 return String::format("matrix(%f, %f, %f, %f, %f, %f)", |
|
178 m_matrix.a(), m_matrix.b(), m_matrix.c(), m_matrix.d(), m_matrix.e(), m_matrix.f()); |
|
179 return String::format("matrix3d(%f, %f, %f, %f, %f, %f, %f, %f, %f, %f, %f, %f, %f, %f, %f, %f)", |
|
180 m_matrix.m11(), m_matrix.m12(), m_matrix.m13(), m_matrix.m14(), |
|
181 m_matrix.m21(), m_matrix.m22(), m_matrix.m23(), m_matrix.m24(), |
|
182 m_matrix.m31(), m_matrix.m32(), m_matrix.m33(), m_matrix.m34(), |
|
183 m_matrix.m41(), m_matrix.m42(), m_matrix.m43(), m_matrix.m44()); |
|
184 } |
|
185 |
|
186 } // namespace WebCore |