SVGLengthSMILType.cpp (3862B)
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/. */ 6 7 #include "SVGLengthSMILType.h" 8 9 #include <math.h> 10 11 #include "SVGAnimatedLengthList.h" 12 #include "mozilla/SMILValue.h" 13 #include "nsDebug.h" 14 15 namespace mozilla { 16 17 void SVGLengthSMILType::InitValue(SMILValue& aValue) const { 18 MOZ_ASSERT(aValue.IsNull(), "Unexpected value type"); 19 20 aValue.mU.mPtr = new SVGLengthAndInfo(); 21 aValue.mType = this; 22 } 23 24 void SVGLengthSMILType::DestroyValue(SMILValue& aValue) const { 25 MOZ_ASSERT(aValue.mType == this, "Unexpected SMIL value"); 26 delete static_cast<SVGLengthAndInfo*>(aValue.mU.mPtr); 27 aValue.mU.mPtr = nullptr; 28 aValue.mType = SMILNullType::Singleton(); 29 } 30 31 nsresult SVGLengthSMILType::Assign(SMILValue& aDest, 32 const SMILValue& aSrc) const { 33 MOZ_ASSERT(aDest.mType == aSrc.mType, "Incompatible SMIL types"); 34 MOZ_ASSERT(aDest.mType == this, "Unexpected SMIL value"); 35 36 auto* src = static_cast<const SVGLengthAndInfo*>(aSrc.mU.mPtr); 37 auto* dest = static_cast<SVGLengthAndInfo*>(aDest.mU.mPtr); 38 dest->CopyFrom(*src); 39 40 return NS_OK; 41 } 42 43 bool SVGLengthSMILType::IsEqual(const SMILValue& aLeft, 44 const SMILValue& aRight) const { 45 MOZ_ASSERT(aLeft.mType == aRight.mType, "Incompatible SMIL types"); 46 MOZ_ASSERT(aLeft.mType == this, "Unexpected type for SMIL value"); 47 48 return *static_cast<const SVGLengthAndInfo*>(aLeft.mU.mPtr) == 49 *static_cast<const SVGLengthAndInfo*>(aRight.mU.mPtr); 50 } 51 52 nsresult SVGLengthSMILType::Add(SMILValue& aDest, const SMILValue& aValueToAdd, 53 uint32_t aCount) const { 54 MOZ_ASSERT(aValueToAdd.mType == aDest.mType, "Trying to add invalid types"); 55 MOZ_ASSERT(aValueToAdd.mType == this, "Unexpected source type"); 56 57 auto& dest = *static_cast<SVGLengthAndInfo*>(aDest.mU.mPtr); 58 const auto& valueToAdd = 59 *static_cast<const SVGLengthAndInfo*>(aValueToAdd.mU.mPtr); 60 61 dest.Add(valueToAdd, aCount); 62 return NS_OK; 63 } 64 65 nsresult SVGLengthSMILType::ComputeDistance(const SMILValue& aFrom, 66 const SMILValue& aTo, 67 double& aDistance) const { 68 MOZ_ASSERT(aFrom.mType == aTo.mType, "Trying to compare different types"); 69 MOZ_ASSERT(aFrom.mType == this, "Unexpected source type"); 70 71 const auto& from = *static_cast<SVGLengthAndInfo*>(aFrom.mU.mPtr); 72 const auto& to = *static_cast<const SVGLengthAndInfo*>(aTo.mU.mPtr); 73 74 MOZ_ASSERT(from.Element() == to.Element()); 75 76 dom::SVGElementMetrics metrics(from.Element()); 77 78 // Normalize both to pixels in case they're different units: 79 aDistance = fabs(to.ValueInPixels(metrics) - from.ValueInPixels(metrics)); 80 81 return std::isfinite(aDistance) ? NS_OK : NS_ERROR_FAILURE; 82 } 83 84 nsresult SVGLengthSMILType::Interpolate(const SMILValue& aStartVal, 85 const SMILValue& aEndVal, 86 double aUnitDistance, 87 SMILValue& aResult) const { 88 MOZ_ASSERT(aStartVal.mType == aEndVal.mType, 89 "Trying to interpolate different types"); 90 MOZ_ASSERT(aStartVal.mType == this, "Unexpected types for interpolation"); 91 MOZ_ASSERT(aResult.mType == this, "Unexpected result type"); 92 93 const auto& start = *static_cast<SVGLengthAndInfo*>(aStartVal.mU.mPtr); 94 const auto& end = *static_cast<const SVGLengthAndInfo*>(aEndVal.mU.mPtr); 95 auto& result = *static_cast<SVGLengthAndInfo*>(aResult.mU.mPtr); 96 97 SVGLengthAndInfo::Interpolate(start, end, aUnitDistance, result); 98 99 return NS_OK; 100 } 101 102 } // namespace mozilla