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 "SVGViewBoxSMILType.h"
9 #include "mozilla/SMILValue.h"
11 #include "SVGAnimatedViewBox.h"
17 SVGViewBoxSMILType
SVGViewBoxSMILType::sSingleton
;
19 void SVGViewBoxSMILType::Init(SMILValue
& aValue
) const {
20 MOZ_ASSERT(aValue
.IsNull(), "Unexpected value type");
22 aValue
.mU
.mPtr
= new SVGViewBox(0.0f
, 0.0f
, 0.0f
, 0.0f
);
26 void SVGViewBoxSMILType::Destroy(SMILValue
& aValue
) const {
27 MOZ_ASSERT(aValue
.mType
== this, "Unexpected SMIL value");
28 delete static_cast<SVGViewBox
*>(aValue
.mU
.mPtr
);
29 aValue
.mU
.mPtr
= nullptr;
30 aValue
.mType
= SMILNullType::Singleton();
33 nsresult
SVGViewBoxSMILType::Assign(SMILValue
& aDest
,
34 const SMILValue
& aSrc
) const {
35 MOZ_ASSERT(aDest
.mType
== aSrc
.mType
, "Incompatible SMIL types");
36 MOZ_ASSERT(aDest
.mType
== this, "Unexpected SMIL value");
38 const SVGViewBox
* src
= static_cast<const SVGViewBox
*>(aSrc
.mU
.mPtr
);
39 SVGViewBox
* dst
= static_cast<SVGViewBox
*>(aDest
.mU
.mPtr
);
44 bool SVGViewBoxSMILType::IsEqual(const SMILValue
& aLeft
,
45 const SMILValue
& aRight
) const {
46 MOZ_ASSERT(aLeft
.mType
== aRight
.mType
, "Incompatible SMIL types");
47 MOZ_ASSERT(aLeft
.mType
== this, "Unexpected type for SMIL value");
49 const SVGViewBox
* leftBox
= static_cast<const SVGViewBox
*>(aLeft
.mU
.mPtr
);
50 const SVGViewBox
* rightBox
= static_cast<SVGViewBox
*>(aRight
.mU
.mPtr
);
51 return *leftBox
== *rightBox
;
54 nsresult
SVGViewBoxSMILType::Add(SMILValue
& aDest
, const SMILValue
& aValueToAdd
,
55 uint32_t aCount
) const {
56 MOZ_ASSERT(aValueToAdd
.mType
== aDest
.mType
, "Trying to add invalid types");
57 MOZ_ASSERT(aValueToAdd
.mType
== this, "Unexpected source type");
59 auto* dest
= static_cast<SVGViewBox
*>(aDest
.mU
.mPtr
);
60 const auto* valueToAdd
= static_cast<const SVGViewBox
*>(aValueToAdd
.mU
.mPtr
);
62 if (dest
->none
|| valueToAdd
->none
) {
63 return NS_ERROR_FAILURE
;
66 dest
->x
+= valueToAdd
->x
* aCount
;
67 dest
->y
+= valueToAdd
->y
* aCount
;
68 dest
->width
+= valueToAdd
->width
* aCount
;
69 dest
->height
+= valueToAdd
->height
* aCount
;
74 nsresult
SVGViewBoxSMILType::ComputeDistance(const SMILValue
& aFrom
,
76 double& aDistance
) const {
77 MOZ_ASSERT(aFrom
.mType
== aTo
.mType
, "Trying to compare different types");
78 MOZ_ASSERT(aFrom
.mType
== this, "Unexpected source type");
80 const SVGViewBox
* from
= static_cast<const SVGViewBox
*>(aFrom
.mU
.mPtr
);
81 const SVGViewBox
* to
= static_cast<const SVGViewBox
*>(aTo
.mU
.mPtr
);
83 if (from
->none
|| to
->none
) {
84 return NS_ERROR_FAILURE
;
87 // We use the distances between the edges rather than the difference between
88 // the x, y, width and height for the "distance". This is necessary in
89 // order for the "distance" result that we calculate to be the same for a
90 // given change in the left side as it is for an equal change in the opposite
91 // side. See https://bugzilla.mozilla.org/show_bug.cgi?id=541884#c12
93 double dLeft
= to
->x
- from
->x
;
94 double dTop
= to
->y
- from
->y
;
95 double dRight
= (to
->x
+ to
->width
) - (from
->x
+ from
->width
);
96 double dBottom
= (to
->y
+ to
->height
) - (from
->y
+ from
->height
);
98 aDistance
= std::sqrt(dLeft
* dLeft
+ dTop
* dTop
+ dRight
* dRight
+
104 nsresult
SVGViewBoxSMILType::Interpolate(const SMILValue
& aStartVal
,
105 const SMILValue
& aEndVal
,
106 double aUnitDistance
,
107 SMILValue
& aResult
) const {
108 MOZ_ASSERT(aStartVal
.mType
== aEndVal
.mType
,
109 "Trying to interpolate different types");
110 MOZ_ASSERT(aStartVal
.mType
== this, "Unexpected types for interpolation");
111 MOZ_ASSERT(aResult
.mType
== this, "Unexpected result type");
113 const SVGViewBox
* start
= static_cast<const SVGViewBox
*>(aStartVal
.mU
.mPtr
);
114 const SVGViewBox
* end
= static_cast<const SVGViewBox
*>(aEndVal
.mU
.mPtr
);
116 if (start
->none
|| end
->none
) {
117 return NS_ERROR_FAILURE
;
120 SVGViewBox
* current
= static_cast<SVGViewBox
*>(aResult
.mU
.mPtr
);
122 float x
= (start
->x
+ (end
->x
- start
->x
) * aUnitDistance
);
123 float y
= (start
->y
+ (end
->y
- start
->y
) * aUnitDistance
);
124 float width
= (start
->width
+ (end
->width
- start
->width
) * aUnitDistance
);
126 (start
->height
+ (end
->height
- start
->height
) * aUnitDistance
);
128 *current
= SVGViewBox(x
, y
, width
, height
);
133 } // namespace mozilla