Bug 1936278 - Prevent search mode chiclet from being dismissed when clicking in page...
[gecko.git] / dom / svg / SVGMatrix.cpp
blobe967bc24133b951bcc32a1227ee9d51bbe1caca8
1 /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
2 /* vim: set ts=8 sts=2 et sw=2 tw=80: */
3 /* This Source Code Form is subject to the terms of the Mozilla Public
4 * License, v. 2.0. If a copy of the MPL was not distributed with this
5 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
7 #include "mozilla/dom/SVGMatrix.h"
8 #include "nsError.h"
9 #include <math.h>
10 #include "mozilla/dom/SVGMatrixBinding.h"
11 #include "mozilla/FloatingPoint.h"
13 const double radPerDegree = 2.0 * M_PI / 360.0;
15 namespace mozilla::dom {
17 NS_IMPL_CYCLE_COLLECTION_WRAPPERCACHE(SVGMatrix, mTransform)
19 DOMSVGTransform* SVGMatrix::GetParentObject() const { return mTransform; }
21 JSObject* SVGMatrix::WrapObject(JSContext* aCx,
22 JS::Handle<JSObject*> aGivenProto) {
23 return SVGMatrix_Binding::Wrap(aCx, this, aGivenProto);
26 void SVGMatrix::SetA(float aA, ErrorResult& rv) {
27 if (IsAnimVal()) {
28 rv.Throw(NS_ERROR_DOM_NO_MODIFICATION_ALLOWED_ERR);
29 return;
32 gfxMatrix mx = GetMatrix();
33 mx._11 = aA;
34 SetMatrix(mx);
37 void SVGMatrix::SetB(float aB, ErrorResult& rv) {
38 if (IsAnimVal()) {
39 rv.Throw(NS_ERROR_DOM_NO_MODIFICATION_ALLOWED_ERR);
40 return;
43 gfxMatrix mx = GetMatrix();
44 mx._12 = aB;
45 SetMatrix(mx);
48 void SVGMatrix::SetC(float aC, ErrorResult& rv) {
49 if (IsAnimVal()) {
50 rv.Throw(NS_ERROR_DOM_NO_MODIFICATION_ALLOWED_ERR);
51 return;
54 gfxMatrix mx = GetMatrix();
55 mx._21 = aC;
56 SetMatrix(mx);
59 void SVGMatrix::SetD(float aD, ErrorResult& rv) {
60 if (IsAnimVal()) {
61 rv.Throw(NS_ERROR_DOM_NO_MODIFICATION_ALLOWED_ERR);
62 return;
65 gfxMatrix mx = GetMatrix();
66 mx._22 = aD;
67 SetMatrix(mx);
70 void SVGMatrix::SetE(float aE, ErrorResult& rv) {
71 if (IsAnimVal()) {
72 rv.Throw(NS_ERROR_DOM_NO_MODIFICATION_ALLOWED_ERR);
73 return;
76 gfxMatrix mx = GetMatrix();
77 mx._31 = aE;
78 SetMatrix(mx);
81 void SVGMatrix::SetF(float aF, ErrorResult& rv) {
82 if (IsAnimVal()) {
83 rv.Throw(NS_ERROR_DOM_NO_MODIFICATION_ALLOWED_ERR);
84 return;
87 gfxMatrix mx = GetMatrix();
88 mx._32 = aF;
89 SetMatrix(mx);
92 already_AddRefed<SVGMatrix> SVGMatrix::Multiply(SVGMatrix& aMatrix) {
93 return do_AddRef(new SVGMatrix(aMatrix.GetMatrix() * GetMatrix()));
96 already_AddRefed<SVGMatrix> SVGMatrix::Inverse(ErrorResult& rv) {
97 gfxMatrix mat = GetMatrix();
98 if (!mat.Invert()) {
99 rv.Throw(NS_ERROR_DOM_INVALID_STATE_ERR);
100 return nullptr;
102 return do_AddRef(new SVGMatrix(mat));
105 already_AddRefed<SVGMatrix> SVGMatrix::Translate(float x, float y) {
106 return do_AddRef(
107 new SVGMatrix(gfxMatrix(GetMatrix()).PreTranslate(gfxPoint(x, y))));
110 already_AddRefed<SVGMatrix> SVGMatrix::Scale(float scaleFactor) {
111 return ScaleNonUniform(scaleFactor, scaleFactor);
114 already_AddRefed<SVGMatrix> SVGMatrix::ScaleNonUniform(float scaleFactorX,
115 float scaleFactorY) {
116 return do_AddRef(new SVGMatrix(
117 gfxMatrix(GetMatrix()).PreScale(scaleFactorX, scaleFactorY)));
120 already_AddRefed<SVGMatrix> SVGMatrix::Rotate(float angle) {
121 return do_AddRef(
122 new SVGMatrix(gfxMatrix(GetMatrix()).PreRotate(angle * radPerDegree)));
125 already_AddRefed<SVGMatrix> SVGMatrix::RotateFromVector(float x, float y,
126 ErrorResult& rv) {
127 if (x == 0.0 || y == 0.0) {
128 rv.Throw(NS_ERROR_DOM_INVALID_ACCESS_ERR);
129 return nullptr;
132 return do_AddRef(
133 new SVGMatrix(gfxMatrix(GetMatrix()).PreRotate(atan2(y, x))));
136 already_AddRefed<SVGMatrix> SVGMatrix::FlipX() {
137 const gfxMatrix& mx = GetMatrix();
138 return do_AddRef(new SVGMatrix(
139 gfxMatrix(-mx._11, -mx._12, mx._21, mx._22, mx._31, mx._32)));
142 already_AddRefed<SVGMatrix> SVGMatrix::FlipY() {
143 const gfxMatrix& mx = GetMatrix();
144 return do_AddRef(new SVGMatrix(
145 gfxMatrix(mx._11, mx._12, -mx._21, -mx._22, mx._31, mx._32)));
148 already_AddRefed<SVGMatrix> SVGMatrix::SkewX(float angle, ErrorResult& rv) {
149 double ta = tan(angle * radPerDegree);
150 if (!std::isfinite(ta)) {
151 rv.Throw(NS_ERROR_DOM_INVALID_ACCESS_ERR);
152 return nullptr;
155 const gfxMatrix& mx = GetMatrix();
156 gfxMatrix skewMx(mx._11, mx._12, mx._21 + mx._11 * ta, mx._22 + mx._12 * ta,
157 mx._31, mx._32);
158 return do_AddRef(new SVGMatrix(skewMx));
161 already_AddRefed<SVGMatrix> SVGMatrix::SkewY(float angle, ErrorResult& rv) {
162 double ta = tan(angle * radPerDegree);
163 if (!std::isfinite(ta)) {
164 rv.Throw(NS_ERROR_DOM_INVALID_ACCESS_ERR);
165 return nullptr;
168 const gfxMatrix& mx = GetMatrix();
169 gfxMatrix skewMx(mx._11 + mx._21 * ta, mx._12 + mx._22 * ta, mx._21, mx._22,
170 mx._31, mx._32);
172 return do_AddRef(new SVGMatrix(skewMx));
175 } // namespace mozilla::dom