WebKitCSSMatrix.cpp revision 2fc2651226baac27029e38c9d6ef883fa32084db
12cc27de07eb0cbb9196cc8d23a23e313b0861390Scott Su/* 22cc27de07eb0cbb9196cc8d23a23e313b0861390Scott Su * Copyright (C) 2008 Apple Inc. All Rights Reserved. 32cc27de07eb0cbb9196cc8d23a23e313b0861390Scott Su * 42cc27de07eb0cbb9196cc8d23a23e313b0861390Scott Su * Redistribution and use in source and binary forms, with or without 52cc27de07eb0cbb9196cc8d23a23e313b0861390Scott Su * modification, are permitted provided that the following conditions 62cc27de07eb0cbb9196cc8d23a23e313b0861390Scott Su * are met: 72cc27de07eb0cbb9196cc8d23a23e313b0861390Scott Su * 1. Redistributions of source code must retain the above copyright 82cc27de07eb0cbb9196cc8d23a23e313b0861390Scott Su * notice, this list of conditions and the following disclaimer. 92cc27de07eb0cbb9196cc8d23a23e313b0861390Scott Su * 2. Redistributions in binary form must reproduce the above copyright 102cc27de07eb0cbb9196cc8d23a23e313b0861390Scott Su * notice, this list of conditions and the following disclaimer in the 112cc27de07eb0cbb9196cc8d23a23e313b0861390Scott Su * documentation and/or other materials provided with the distribution. 122cc27de07eb0cbb9196cc8d23a23e313b0861390Scott Su * 132cc27de07eb0cbb9196cc8d23a23e313b0861390Scott Su * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY 142cc27de07eb0cbb9196cc8d23a23e313b0861390Scott Su * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 152cc27de07eb0cbb9196cc8d23a23e313b0861390Scott Su * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 162cc27de07eb0cbb9196cc8d23a23e313b0861390Scott Su * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR 172cc27de07eb0cbb9196cc8d23a23e313b0861390Scott Su * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 182cc27de07eb0cbb9196cc8d23a23e313b0861390Scott Su * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 192cc27de07eb0cbb9196cc8d23a23e313b0861390Scott Su * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR 202cc27de07eb0cbb9196cc8d23a23e313b0861390Scott Su * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY 212cc27de07eb0cbb9196cc8d23a23e313b0861390Scott Su * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 222cc27de07eb0cbb9196cc8d23a23e313b0861390Scott Su * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 232cc27de07eb0cbb9196cc8d23a23e313b0861390Scott Su * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 242cc27de07eb0cbb9196cc8d23a23e313b0861390Scott Su */ 252cc27de07eb0cbb9196cc8d23a23e313b0861390Scott Su 262cc27de07eb0cbb9196cc8d23a23e313b0861390Scott Su#include "config.h" 272cc27de07eb0cbb9196cc8d23a23e313b0861390Scott Su#include "WebKitCSSMatrix.h" 282cc27de07eb0cbb9196cc8d23a23e313b0861390Scott Su 292cc27de07eb0cbb9196cc8d23a23e313b0861390Scott Su#include "CSSParser.h" 302cc27de07eb0cbb9196cc8d23a23e313b0861390Scott Su#include "CSSStyleSelector.h" 312cc27de07eb0cbb9196cc8d23a23e313b0861390Scott Su#include "CSSMutableStyleDeclaration.h" 322cc27de07eb0cbb9196cc8d23a23e313b0861390Scott Su#include "CSSPropertyNames.h" 332cc27de07eb0cbb9196cc8d23a23e313b0861390Scott Su#include "CSSValueKeywords.h" 342cc27de07eb0cbb9196cc8d23a23e313b0861390Scott Su#include "ExceptionCode.h" 352cc27de07eb0cbb9196cc8d23a23e313b0861390Scott Su#include <wtf/MathExtras.h> 362cc27de07eb0cbb9196cc8d23a23e313b0861390Scott Su 372cc27de07eb0cbb9196cc8d23a23e313b0861390Scott Sunamespace WebCore { 382cc27de07eb0cbb9196cc8d23a23e313b0861390Scott Su 392cc27de07eb0cbb9196cc8d23a23e313b0861390Scott SuWebKitCSSMatrix::WebKitCSSMatrix(const TransformationMatrix& m) 402cc27de07eb0cbb9196cc8d23a23e313b0861390Scott Su : m_matrix(m) 412cc27de07eb0cbb9196cc8d23a23e313b0861390Scott Su{ 422cc27de07eb0cbb9196cc8d23a23e313b0861390Scott Su} 432cc27de07eb0cbb9196cc8d23a23e313b0861390Scott Su 442cc27de07eb0cbb9196cc8d23a23e313b0861390Scott SuWebKitCSSMatrix::WebKitCSSMatrix(const String& s, ExceptionCode& ec) 452cc27de07eb0cbb9196cc8d23a23e313b0861390Scott Su{ 462cc27de07eb0cbb9196cc8d23a23e313b0861390Scott Su setMatrixValue(s, ec); 472cc27de07eb0cbb9196cc8d23a23e313b0861390Scott Su} 482cc27de07eb0cbb9196cc8d23a23e313b0861390Scott Su 492cc27de07eb0cbb9196cc8d23a23e313b0861390Scott SuWebKitCSSMatrix::~WebKitCSSMatrix() 502cc27de07eb0cbb9196cc8d23a23e313b0861390Scott Su{ 512cc27de07eb0cbb9196cc8d23a23e313b0861390Scott Su} 522cc27de07eb0cbb9196cc8d23a23e313b0861390Scott Su 532cc27de07eb0cbb9196cc8d23a23e313b0861390Scott Suvoid WebKitCSSMatrix::setMatrixValue(const String& string, ExceptionCode& ec) 542cc27de07eb0cbb9196cc8d23a23e313b0861390Scott Su{ 552cc27de07eb0cbb9196cc8d23a23e313b0861390Scott Su CSSParser p(true); 562cc27de07eb0cbb9196cc8d23a23e313b0861390Scott Su RefPtr<CSSMutableStyleDeclaration> styleDeclaration = CSSMutableStyleDeclaration::create(); 572cc27de07eb0cbb9196cc8d23a23e313b0861390Scott Su if (p.parseValue(styleDeclaration.get(), CSSPropertyWebkitTransform, string, true)) { 58 // Convert to TransformOperations. This can fail if a property 59 // requires style (i.e., param uses 'ems' or 'exs') 60 RefPtr<CSSValue> value = styleDeclaration->getPropertyCSSValue(CSSPropertyWebkitTransform); 61 62 // Check for a "none" or empty transform. In these cases we can use the default identity matrix. 63 if (!value || (value->isPrimitiveValue() && (static_cast<CSSPrimitiveValue*>(value.get()))->getIdent() == CSSValueNone)) 64 return; 65 66 TransformOperations operations; 67 if (!CSSStyleSelector::createTransformOperations(value.get(), 0, 0, operations)) { 68 ec = SYNTAX_ERR; 69 return; 70 } 71 72 // Convert transform operations to a TransformationMatrix. This can fail 73 // if a param has a percentage ('%') 74 TransformationMatrix t; 75 for (unsigned i = 0; i < operations.operations().size(); ++i) { 76 if (operations.operations()[i].get()->apply(t, IntSize(0, 0))) { 77 ec = SYNTAX_ERR; 78 return; 79 } 80 } 81 82 // set the matrix 83 m_matrix = t; 84 } else if (!string.isEmpty()) // There is something there but parsing failed 85 ec = SYNTAX_ERR; 86} 87 88// Perform a concatenation of the matrices (this * secondMatrix) 89PassRefPtr<WebKitCSSMatrix> WebKitCSSMatrix::multiply(WebKitCSSMatrix* secondMatrix) const 90{ 91 if (!secondMatrix) 92 return 0; 93 94 return WebKitCSSMatrix::create(TransformationMatrix(m_matrix).multiply(secondMatrix->m_matrix)); 95} 96 97PassRefPtr<WebKitCSSMatrix> WebKitCSSMatrix::inverse(ExceptionCode& ec) const 98{ 99 if (!m_matrix.isInvertible()) { 100 ec = NOT_SUPPORTED_ERR; 101 return 0; 102 } 103 104 return WebKitCSSMatrix::create(m_matrix.inverse()); 105} 106 107PassRefPtr<WebKitCSSMatrix> WebKitCSSMatrix::translate(double x, double y, double z) const 108{ 109 if (isnan(x)) 110 x = 0; 111 if (isnan(y)) 112 y = 0; 113 if (isnan(z)) 114 z = 0; 115 return WebKitCSSMatrix::create(TransformationMatrix(m_matrix).translate3d(x, y, z)); 116} 117 118PassRefPtr<WebKitCSSMatrix> WebKitCSSMatrix::scale(double scaleX, double scaleY, double scaleZ) const 119{ 120 if (isnan(scaleX)) 121 scaleX = 1; 122 if (isnan(scaleY)) 123 scaleY = scaleX; 124 if (isnan(scaleZ)) 125 scaleZ = 1; 126 return WebKitCSSMatrix::create(TransformationMatrix(m_matrix).scale3d(scaleX, scaleY, scaleZ)); 127} 128 129PassRefPtr<WebKitCSSMatrix> WebKitCSSMatrix::rotate(double rotX, double rotY, double rotZ) const 130{ 131 if (isnan(rotX)) 132 rotX = 0; 133 134 if (isnan(rotY) && isnan(rotZ)) { 135 rotZ = rotX; 136 rotX = 0; 137 rotY = 0; 138 } 139 140 if (isnan(rotY)) 141 rotY = 0; 142 if (isnan(rotZ)) 143 rotZ = 0; 144 return WebKitCSSMatrix::create(TransformationMatrix(m_matrix).rotate3d(rotX, rotY, rotZ)); 145} 146 147PassRefPtr<WebKitCSSMatrix> WebKitCSSMatrix::rotateAxisAngle(double x, double y, double z, double angle) const 148{ 149 if (isnan(x)) 150 x = 0; 151 if (isnan(y)) 152 y = 0; 153 if (isnan(z)) 154 z = 0; 155 if (isnan(angle)) 156 angle = 0; 157 if (x == 0 && y == 0 && z == 0) 158 z = 1; 159 return WebKitCSSMatrix::create(TransformationMatrix(m_matrix).rotate3d(x, y, z, angle)); 160} 161 162PassRefPtr<WebKitCSSMatrix> WebKitCSSMatrix::skewX(double angle) const 163{ 164 if (isnan(angle)) 165 angle = 0; 166 return WebKitCSSMatrix::create(TransformationMatrix(m_matrix).skewX(angle)); 167} 168 169PassRefPtr<WebKitCSSMatrix> WebKitCSSMatrix::skewY(double angle) const 170{ 171 if (isnan(angle)) 172 angle = 0; 173 return WebKitCSSMatrix::create(TransformationMatrix(m_matrix).skewY(angle)); 174} 175 176String WebKitCSSMatrix::toString() const 177{ 178 // FIXME - Need to ensure valid CSS floating point values (https://bugs.webkit.org/show_bug.cgi?id=20674) 179 if (m_matrix.isAffine()) 180 return String::format("matrix(%f, %f, %f, %f, %f, %f)", 181 m_matrix.a(), m_matrix.b(), m_matrix.c(), m_matrix.d(), m_matrix.e(), m_matrix.f()); 182 return String::format("matrix3d(%f, %f, %f, %f, %f, %f, %f, %f, %f, %f, %f, %f, %f, %f, %f, %f)", 183 m_matrix.m11(), m_matrix.m12(), m_matrix.m13(), m_matrix.m14(), 184 m_matrix.m21(), m_matrix.m22(), m_matrix.m23(), m_matrix.m24(), 185 m_matrix.m31(), m_matrix.m32(), m_matrix.m33(), m_matrix.m34(), 186 m_matrix.m41(), m_matrix.m42(), m_matrix.m43(), m_matrix.m44()); 187} 188 189} // namespace WebCore 190