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 "SVGTransform.h"
10 #include "nsContentUtils.h" // for NS_ENSURE_FINITE
11 #include "nsTextFormatter.h"
14 const double kRadPerDegree
= 2.0 * M_PI
/ 360.0;
19 using namespace dom::SVGTransform_Binding
;
21 void SVGTransform::GetValueAsString(nsAString
& aValue
) const {
23 case SVG_TRANSFORM_TRANSLATE
:
24 // The spec say that if Y is not provided, it is assumed to be zero.
26 nsTextFormatter::ssprintf(aValue
, u
"translate(%g, %g)", mMatrix
._31
,
29 nsTextFormatter::ssprintf(aValue
, u
"translate(%g)", mMatrix
._31
);
31 case SVG_TRANSFORM_ROTATE
:
32 if (mOriginX
!= 0.0f
|| mOriginY
!= 0.0f
)
33 nsTextFormatter::ssprintf(aValue
, u
"rotate(%g, %g, %g)", mAngle
,
36 nsTextFormatter::ssprintf(aValue
, u
"rotate(%g)", mAngle
);
38 case SVG_TRANSFORM_SCALE
:
39 if (mMatrix
._11
!= mMatrix
._22
)
40 nsTextFormatter::ssprintf(aValue
, u
"scale(%g, %g)", mMatrix
._11
,
43 nsTextFormatter::ssprintf(aValue
, u
"scale(%g)", mMatrix
._11
);
45 case SVG_TRANSFORM_SKEWX
:
46 nsTextFormatter::ssprintf(aValue
, u
"skewX(%g)", mAngle
);
48 case SVG_TRANSFORM_SKEWY
:
49 nsTextFormatter::ssprintf(aValue
, u
"skewY(%g)", mAngle
);
51 case SVG_TRANSFORM_MATRIX
:
52 nsTextFormatter::ssprintf(aValue
, u
"matrix(%g, %g, %g, %g, %g, %g)",
53 mMatrix
._11
, mMatrix
._12
, mMatrix
._21
,
54 mMatrix
._22
, mMatrix
._31
, mMatrix
._32
);
58 NS_ERROR("unknown transformation type");
63 void SVGTransform::SetMatrix(const gfxMatrix
& aMatrix
) {
64 mType
= SVG_TRANSFORM_MATRIX
;
66 // We set the other members here too, since operator== requires it and
67 // the DOM requires it for mAngle.
73 void SVGTransform::SetTranslate(float aTx
, float aTy
) {
74 mType
= SVG_TRANSFORM_TRANSLATE
;
75 mMatrix
= gfxMatrix::Translation(aTx
, aTy
);
81 void SVGTransform::SetScale(float aSx
, float aSy
) {
82 mType
= SVG_TRANSFORM_SCALE
;
83 mMatrix
= gfxMatrix::Scaling(aSx
, aSy
);
89 void SVGTransform::SetRotate(float aAngle
, float aCx
, float aCy
) {
90 mType
= SVG_TRANSFORM_ROTATE
;
91 mMatrix
= gfxMatrix::Translation(aCx
, aCy
)
92 .PreRotate(aAngle
* kRadPerDegree
)
93 .PreTranslate(-aCx
, -aCy
);
99 nsresult
SVGTransform::SetSkewX(float aAngle
) {
100 double ta
= tan(aAngle
* kRadPerDegree
);
101 // No one actually cares about the exact error return type here.
102 NS_ENSURE_FINITE(ta
, NS_ERROR_INVALID_ARG
);
104 mType
= SVG_TRANSFORM_SKEWX
;
105 mMatrix
= gfxMatrix();
113 nsresult
SVGTransform::SetSkewY(float aAngle
) {
114 double ta
= tan(aAngle
* kRadPerDegree
);
115 // No one actually cares about the exact error return type here.
116 NS_ENSURE_FINITE(ta
, NS_ERROR_INVALID_ARG
);
118 mType
= SVG_TRANSFORM_SKEWY
;
119 mMatrix
= gfxMatrix();
127 SVGTransformSMILData::SVGTransformSMILData(const SVGTransform
& aTransform
)
128 : mTransformType(aTransform
.Type()) {
129 MOZ_ASSERT(mTransformType
>= SVG_TRANSFORM_MATRIX
&&
130 mTransformType
<= SVG_TRANSFORM_SKEWY
,
131 "Unexpected transform type");
133 for (uint32_t i
= 0; i
< NUM_STORED_PARAMS
; ++i
) {
137 switch (mTransformType
) {
138 case SVG_TRANSFORM_MATRIX
: {
139 const gfxMatrix
& mx
= aTransform
.GetMatrix();
140 mParams
[0] = static_cast<float>(mx
._11
);
141 mParams
[1] = static_cast<float>(mx
._12
);
142 mParams
[2] = static_cast<float>(mx
._21
);
143 mParams
[3] = static_cast<float>(mx
._22
);
144 mParams
[4] = static_cast<float>(mx
._31
);
145 mParams
[5] = static_cast<float>(mx
._32
);
148 case SVG_TRANSFORM_TRANSLATE
: {
149 const gfxMatrix
& mx
= aTransform
.GetMatrix();
150 mParams
[0] = static_cast<float>(mx
._31
);
151 mParams
[1] = static_cast<float>(mx
._32
);
154 case SVG_TRANSFORM_SCALE
: {
155 const gfxMatrix
& mx
= aTransform
.GetMatrix();
156 mParams
[0] = static_cast<float>(mx
._11
);
157 mParams
[1] = static_cast<float>(mx
._22
);
160 case SVG_TRANSFORM_ROTATE
:
161 mParams
[0] = aTransform
.Angle();
162 aTransform
.GetRotationOrigin(mParams
[1], mParams
[2]);
165 case SVG_TRANSFORM_SKEWX
:
166 case SVG_TRANSFORM_SKEWY
:
167 mParams
[0] = aTransform
.Angle();
171 MOZ_ASSERT_UNREACHABLE("Unexpected transform type");
176 SVGTransform
SVGTransformSMILData::ToSVGTransform() const {
179 switch (mTransformType
) {
180 case SVG_TRANSFORM_MATRIX
:
181 result
.SetMatrix(gfxMatrix(mParams
[0], mParams
[1], mParams
[2], mParams
[3],
182 mParams
[4], mParams
[5]));
185 case SVG_TRANSFORM_TRANSLATE
:
186 result
.SetTranslate(mParams
[0], mParams
[1]);
189 case SVG_TRANSFORM_SCALE
:
190 result
.SetScale(mParams
[0], mParams
[1]);
193 case SVG_TRANSFORM_ROTATE
:
194 result
.SetRotate(mParams
[0], mParams
[1], mParams
[2]);
197 case SVG_TRANSFORM_SKEWX
:
198 result
.SetSkewX(mParams
[0]);
201 case SVG_TRANSFORM_SKEWY
:
202 result
.SetSkewY(mParams
[0]);
206 MOZ_ASSERT_UNREACHABLE("Unexpected transform type");
212 } // namespace mozilla