Bug 1941128 - Turn off network.dns.native_https_query on Mac again
[gecko.git] / dom / svg / SVGPointListSMILType.cpp
blobcae32f3d65774a7acd4cdd1e1be16f5e1da4da29
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 "SVGPointListSMILType.h"
9 #include "mozilla/FloatingPoint.h"
10 #include "mozilla/SMILValue.h"
11 #include "nsMathUtils.h"
12 #include "SVGPointList.h"
13 #include <math.h>
15 namespace mozilla {
17 /*static*/
18 SVGPointListSMILType SVGPointListSMILType::sSingleton;
20 //----------------------------------------------------------------------
21 // nsISMILType implementation
23 void SVGPointListSMILType::Init(SMILValue& aValue) const {
24 MOZ_ASSERT(aValue.IsNull(), "Unexpected value type");
26 aValue.mU.mPtr = new SVGPointListAndInfo();
27 aValue.mType = this;
30 void SVGPointListSMILType::Destroy(SMILValue& aValue) const {
31 MOZ_ASSERT(aValue.mType == this, "Unexpected SMIL value type");
32 delete static_cast<SVGPointListAndInfo*>(aValue.mU.mPtr);
33 aValue.mU.mPtr = nullptr;
34 aValue.mType = SMILNullType::Singleton();
37 nsresult SVGPointListSMILType::Assign(SMILValue& aDest,
38 const SMILValue& aSrc) const {
39 MOZ_ASSERT(aDest.mType == aSrc.mType, "Incompatible SMIL types");
40 MOZ_ASSERT(aDest.mType == this, "Unexpected SMIL value");
42 const SVGPointListAndInfo* src =
43 static_cast<const SVGPointListAndInfo*>(aSrc.mU.mPtr);
44 SVGPointListAndInfo* dest = static_cast<SVGPointListAndInfo*>(aDest.mU.mPtr);
46 return dest->CopyFrom(*src);
49 bool SVGPointListSMILType::IsEqual(const SMILValue& aLeft,
50 const SMILValue& aRight) const {
51 MOZ_ASSERT(aLeft.mType == aRight.mType, "Incompatible SMIL types");
52 MOZ_ASSERT(aLeft.mType == this, "Unexpected type for SMIL value");
54 return *static_cast<const SVGPointListAndInfo*>(aLeft.mU.mPtr) ==
55 *static_cast<const SVGPointListAndInfo*>(aRight.mU.mPtr);
58 nsresult SVGPointListSMILType::Add(SMILValue& aDest,
59 const SMILValue& aValueToAdd,
60 uint32_t aCount) const {
61 MOZ_ASSERT(aDest.mType == this, "Unexpected SMIL type");
62 MOZ_ASSERT(aValueToAdd.mType == this, "Incompatible SMIL type");
64 SVGPointListAndInfo& dest = *static_cast<SVGPointListAndInfo*>(aDest.mU.mPtr);
65 const SVGPointListAndInfo& valueToAdd =
66 *static_cast<const SVGPointListAndInfo*>(aValueToAdd.mU.mPtr);
68 MOZ_ASSERT(dest.Element() || valueToAdd.Element(),
69 "Target element propagation failure");
71 if (valueToAdd.IsIdentity()) {
72 return NS_OK;
74 if (dest.IsIdentity()) {
75 if (!dest.SetLength(valueToAdd.Length())) {
76 return NS_ERROR_OUT_OF_MEMORY;
78 for (uint32_t i = 0; i < dest.Length(); ++i) {
79 dest[i] = aCount * valueToAdd[i];
81 dest.SetInfo(valueToAdd.Element()); // propagate target element info!
82 return NS_OK;
84 MOZ_ASSERT(dest.Element() == valueToAdd.Element(),
85 "adding values from different elements...?");
86 if (dest.Length() != valueToAdd.Length()) {
87 // For now we only support animation between lists with the same number of
88 // items. SVGContentUtils::ReportToConsole
89 return NS_ERROR_FAILURE;
91 for (uint32_t i = 0; i < dest.Length(); ++i) {
92 dest[i] += aCount * valueToAdd[i];
94 dest.SetInfo(valueToAdd.Element()); // propagate target element info!
95 return NS_OK;
98 nsresult SVGPointListSMILType::ComputeDistance(const SMILValue& aFrom,
99 const SMILValue& aTo,
100 double& aDistance) const {
101 MOZ_ASSERT(aFrom.mType == this, "Unexpected SMIL type");
102 MOZ_ASSERT(aTo.mType == this, "Incompatible SMIL type");
104 const SVGPointListAndInfo& from =
105 *static_cast<const SVGPointListAndInfo*>(aFrom.mU.mPtr);
106 const SVGPointListAndInfo& to =
107 *static_cast<const SVGPointListAndInfo*>(aTo.mU.mPtr);
109 if (from.Length() != to.Length()) {
110 // Lists in the 'values' attribute must have the same length.
111 // SVGContentUtils::ReportToConsole
112 return NS_ERROR_FAILURE;
115 // We return the root of the sum of the squares of the distances between the
116 // points at each corresponding index.
118 double total = 0.0;
120 for (uint32_t i = 0; i < to.Length(); ++i) {
121 double dx = to[i].mX - from[i].mX;
122 double dy = to[i].mY - from[i].mY;
123 total += dx * dx + dy * dy;
125 double distance = sqrt(total);
126 if (!std::isfinite(distance)) {
127 return NS_ERROR_FAILURE;
129 aDistance = distance;
131 return NS_OK;
134 nsresult SVGPointListSMILType::Interpolate(const SMILValue& aStartVal,
135 const SMILValue& aEndVal,
136 double aUnitDistance,
137 SMILValue& aResult) const {
138 MOZ_ASSERT(aStartVal.mType == aEndVal.mType,
139 "Trying to interpolate different types");
140 MOZ_ASSERT(aStartVal.mType == this, "Unexpected types for interpolation");
141 MOZ_ASSERT(aResult.mType == this, "Unexpected result type");
143 const SVGPointListAndInfo& start =
144 *static_cast<const SVGPointListAndInfo*>(aStartVal.mU.mPtr);
145 const SVGPointListAndInfo& end =
146 *static_cast<const SVGPointListAndInfo*>(aEndVal.mU.mPtr);
147 SVGPointListAndInfo& result =
148 *static_cast<SVGPointListAndInfo*>(aResult.mU.mPtr);
150 MOZ_ASSERT(end.Element(), "Can't propagate target element");
151 MOZ_ASSERT(start.Element() == end.Element() || !start.Element(),
152 "Different target elements");
154 if (start.Element() && // 'start' is not an "identity" value
155 start.Length() != end.Length()) {
156 // For now we only support animation between lists of the same length.
157 // SVGContentUtils::ReportToConsole
158 return NS_ERROR_FAILURE;
160 if (!result.SetLength(end.Length())) {
161 return NS_ERROR_OUT_OF_MEMORY;
164 result.SetInfo(end.Element()); // propagate target element info!
166 if (start.Length() != end.Length()) {
167 MOZ_ASSERT(start.Length() == 0, "Not an identity value");
168 for (uint32_t i = 0; i < end.Length(); ++i) {
169 result[i] = aUnitDistance * end[i];
171 return NS_OK;
173 for (uint32_t i = 0; i < end.Length(); ++i) {
174 result[i] = start[i] + (end[i] - start[i]) * aUnitDistance;
176 return NS_OK;
179 } // namespace mozilla