1 /* 2 * Copyright (C) 2014 Google 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 are 6 * met: 7 * 8 * * Redistributions of source code must retain the above copyright 9 * notice, this list of conditions and the following disclaimer. 10 * * Redistributions in binary form must reproduce the above 11 * copyright notice, this list of conditions and the following disclaimer 12 * in the documentation and/or other materials provided with the 13 * distribution. 14 * * Neither the name of Google Inc. nor the names of its 15 * contributors may be used to endorse or promote products derived from 16 * this software without specific prior written permission. 17 * 18 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 19 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 20 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 21 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 22 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 23 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 24 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 25 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 26 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 27 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 28 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 29 */ 30 31 #include "config.h" 32 #include "core/svg/SVGMatrixTearOff.h" 33 34 #include "bindings/core/v8/ExceptionState.h" 35 #include "core/dom/ExceptionCode.h" 36 #include "core/svg/SVGTransformTearOff.h" 37 38 namespace blink { 39 40 SVGMatrixTearOff::SVGMatrixTearOff(const AffineTransform& staticValue) 41 : m_staticValue(staticValue) 42 , m_contextTransform(0) 43 { 44 } 45 46 SVGMatrixTearOff::SVGMatrixTearOff(SVGTransformTearOff* transform) 47 : m_contextTransform(transform) 48 { 49 ASSERT(transform); 50 } 51 52 SVGMatrixTearOff::~SVGMatrixTearOff() 53 { 54 } 55 56 const AffineTransform& SVGMatrixTearOff::value() const 57 { 58 return m_contextTransform ? m_contextTransform->target()->matrix() : m_staticValue; 59 } 60 61 AffineTransform* SVGMatrixTearOff::mutableValue() 62 { 63 return m_contextTransform ? m_contextTransform->target()->mutableMatrix() : &m_staticValue; 64 } 65 66 void SVGMatrixTearOff::commitChange() 67 { 68 if (!m_contextTransform) 69 return; 70 71 m_contextTransform->target()->onMatrixChange(); 72 m_contextTransform->commitChange(); 73 } 74 75 #define DEFINE_SETTER(ATTRIBUTE) \ 76 void SVGMatrixTearOff::set##ATTRIBUTE(double f, ExceptionState& exceptionState) \ 77 { \ 78 if (m_contextTransform && m_contextTransform->isImmutable()) { \ 79 exceptionState.throwDOMException(NoModificationAllowedError, "The attribute is read-only."); \ 80 return; \ 81 } \ 82 mutableValue()->set##ATTRIBUTE(f); \ 83 commitChange(); \ 84 } 85 86 DEFINE_SETTER(A); 87 DEFINE_SETTER(B); 88 DEFINE_SETTER(C); 89 DEFINE_SETTER(D); 90 DEFINE_SETTER(E); 91 DEFINE_SETTER(F); 92 93 #undef DEFINE_SETTER 94 95 PassRefPtr<SVGMatrixTearOff> SVGMatrixTearOff::translate(double tx, double ty) 96 { 97 RefPtr<SVGMatrixTearOff> matrix = create(value()); 98 matrix->mutableValue()->translate(tx, ty); 99 return matrix.release(); 100 } 101 102 PassRefPtr<SVGMatrixTearOff> SVGMatrixTearOff::scale(double s) 103 { 104 RefPtr<SVGMatrixTearOff> matrix = create(value()); 105 matrix->mutableValue()->scale(s, s); 106 return matrix.release(); 107 } 108 109 PassRefPtr<SVGMatrixTearOff> SVGMatrixTearOff::scaleNonUniform(double sx, double sy) 110 { 111 RefPtr<SVGMatrixTearOff> matrix = create(value()); 112 matrix->mutableValue()->scale(sx, sy); 113 return matrix.release(); 114 } 115 116 PassRefPtr<SVGMatrixTearOff> SVGMatrixTearOff::rotate(double d) 117 { 118 RefPtr<SVGMatrixTearOff> matrix = create(value()); 119 matrix->mutableValue()->rotate(d); 120 return matrix.release(); 121 } 122 123 PassRefPtr<SVGMatrixTearOff> SVGMatrixTearOff::flipX() 124 { 125 RefPtr<SVGMatrixTearOff> matrix = create(value()); 126 matrix->mutableValue()->flipX(); 127 return matrix.release(); 128 } 129 130 PassRefPtr<SVGMatrixTearOff> SVGMatrixTearOff::flipY() 131 { 132 RefPtr<SVGMatrixTearOff> matrix = create(value()); 133 matrix->mutableValue()->flipY(); 134 return matrix.release(); 135 } 136 137 PassRefPtr<SVGMatrixTearOff> SVGMatrixTearOff::skewX(double angle) 138 { 139 RefPtr<SVGMatrixTearOff> matrix = create(value()); 140 matrix->mutableValue()->skewX(angle); 141 return matrix.release(); 142 } 143 144 PassRefPtr<SVGMatrixTearOff> SVGMatrixTearOff::skewY(double angle) 145 { 146 RefPtr<SVGMatrixTearOff> matrix = create(value()); 147 matrix->mutableValue()->skewY(angle); 148 return matrix.release(); 149 } 150 151 PassRefPtr<SVGMatrixTearOff> SVGMatrixTearOff::multiply(PassRefPtr<SVGMatrixTearOff> other) 152 { 153 RefPtr<SVGMatrixTearOff> matrix = create(value()); 154 *matrix->mutableValue() *= other->value(); 155 return matrix.release(); 156 } 157 158 PassRefPtr<SVGMatrixTearOff> SVGMatrixTearOff::inverse(ExceptionState& exceptionState) 159 { 160 AffineTransform transform = value().inverse(); 161 if (!value().isInvertible()) 162 exceptionState.throwDOMException(InvalidStateError, "The matrix is not invertible."); 163 164 return create(transform); 165 } 166 167 PassRefPtr<SVGMatrixTearOff> SVGMatrixTearOff::rotateFromVector(double x, double y, ExceptionState& exceptionState) 168 { 169 if (!x || !y) 170 exceptionState.throwDOMException(InvalidAccessError, "Arguments cannot be zero."); 171 172 AffineTransform copy = value(); 173 copy.rotateFromVector(x, y); 174 return create(copy); 175 } 176 177 } 178