Home | History | Annotate | Download | only in css
      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 // This is a multRight (this = this * secondMatrix)
     97 PassRefPtr<WebKitCSSMatrix> WebKitCSSMatrix::multiply(WebKitCSSMatrix* secondMatrix) const
     98 {
     99     if (!secondMatrix)
    100         return 0;
    101 
    102     TransformationMatrix tmp(m_matrix);
    103     tmp.multiply(secondMatrix->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
    187