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();
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 // See https://bugzilla.mozilla.org/show_bug.cgi?id=541884#c3 and the two
60 // comments that follow that one for arguments for and against allowing
61 // viewBox to be additive.
63 return NS_ERROR_FAILURE
;
66 nsresult
SVGViewBoxSMILType::ComputeDistance(const SMILValue
& aFrom
,
68 double& aDistance
) const {
69 MOZ_ASSERT(aFrom
.mType
== aTo
.mType
, "Trying to compare different types");
70 MOZ_ASSERT(aFrom
.mType
== this, "Unexpected source type");
72 const SVGViewBox
* from
= static_cast<const SVGViewBox
*>(aFrom
.mU
.mPtr
);
73 const SVGViewBox
* to
= static_cast<const SVGViewBox
*>(aTo
.mU
.mPtr
);
75 if (from
->none
|| to
->none
) {
76 return NS_ERROR_FAILURE
;
79 // We use the distances between the edges rather than the difference between
80 // the x, y, width and height for the "distance". This is necessary in
81 // order for the "distance" result that we calculate to be the same for a
82 // given change in the left side as it is for an equal change in the opposite
83 // side. See https://bugzilla.mozilla.org/show_bug.cgi?id=541884#c12
85 float dLeft
= to
->x
- from
->x
;
86 float dTop
= to
->y
- from
->y
;
87 float dRight
= (to
->x
+ to
->width
) - (from
->x
+ from
->width
);
88 float dBottom
= (to
->y
+ to
->height
) - (from
->y
+ from
->height
);
90 aDistance
= std::sqrt(dLeft
* dLeft
+ dTop
* dTop
+ dRight
* dRight
+
96 nsresult
SVGViewBoxSMILType::Interpolate(const SMILValue
& aStartVal
,
97 const SMILValue
& aEndVal
,
99 SMILValue
& aResult
) const {
100 MOZ_ASSERT(aStartVal
.mType
== aEndVal
.mType
,
101 "Trying to interpolate different types");
102 MOZ_ASSERT(aStartVal
.mType
== this, "Unexpected types for interpolation");
103 MOZ_ASSERT(aResult
.mType
== this, "Unexpected result type");
105 const SVGViewBox
* start
= static_cast<const SVGViewBox
*>(aStartVal
.mU
.mPtr
);
106 const SVGViewBox
* end
= static_cast<const SVGViewBox
*>(aEndVal
.mU
.mPtr
);
108 if (start
->none
|| end
->none
) {
109 return NS_ERROR_FAILURE
;
112 SVGViewBox
* current
= static_cast<SVGViewBox
*>(aResult
.mU
.mPtr
);
114 float x
= (start
->x
+ (end
->x
- start
->x
) * aUnitDistance
);
115 float y
= (start
->y
+ (end
->y
- start
->y
) * aUnitDistance
);
116 float width
= (start
->width
+ (end
->width
- start
->width
) * aUnitDistance
);
118 (start
->height
+ (end
->height
- start
->height
) * aUnitDistance
);
120 *current
= SVGViewBox(x
, y
, width
, height
);
125 } // namespace mozilla