SMILIntegerType.cpp (3287B)
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 "SMILIntegerType.h" 8 9 #include <math.h> 10 11 #include "mozilla/SMILValue.h" 12 #include "nsDebug.h" 13 14 namespace mozilla { 15 16 void SMILIntegerType::InitValue(SMILValue& aValue) const { 17 MOZ_ASSERT(aValue.IsNull(), "Unexpected value type"); 18 aValue.mU.mInt = 0; 19 aValue.mType = this; 20 } 21 22 void SMILIntegerType::DestroyValue(SMILValue& aValue) const { 23 MOZ_ASSERT(aValue.mType == this, "Unexpected SMIL value"); 24 aValue.mU.mInt = 0; 25 aValue.mType = SMILNullType::Singleton(); 26 } 27 28 nsresult SMILIntegerType::Assign(SMILValue& aDest, 29 const SMILValue& aSrc) const { 30 MOZ_ASSERT(aDest.mType == aSrc.mType, "Incompatible SMIL types"); 31 MOZ_ASSERT(aDest.mType == this, "Unexpected SMIL value"); 32 aDest.mU.mInt = aSrc.mU.mInt; 33 return NS_OK; 34 } 35 36 bool SMILIntegerType::IsEqual(const SMILValue& aLeft, 37 const SMILValue& aRight) const { 38 MOZ_ASSERT(aLeft.mType == aRight.mType, "Incompatible SMIL types"); 39 MOZ_ASSERT(aLeft.mType == this, "Unexpected type for SMIL value"); 40 41 return aLeft.mU.mInt == aRight.mU.mInt; 42 } 43 44 nsresult SMILIntegerType::Add(SMILValue& aDest, const SMILValue& aValueToAdd, 45 uint32_t aCount) const { 46 MOZ_ASSERT(aValueToAdd.mType == aDest.mType, "Trying to add invalid types"); 47 MOZ_ASSERT(aValueToAdd.mType == this, "Unexpected source type"); 48 aDest.mU.mInt += aValueToAdd.mU.mInt * aCount; 49 return NS_OK; 50 } 51 52 nsresult SMILIntegerType::ComputeDistance(const SMILValue& aFrom, 53 const SMILValue& aTo, 54 double& aDistance) const { 55 MOZ_ASSERT(aFrom.mType == aTo.mType, "Trying to compare different types"); 56 MOZ_ASSERT(aFrom.mType == this, "Unexpected source type"); 57 aDistance = fabs(double(aTo.mU.mInt - aFrom.mU.mInt)); 58 return NS_OK; 59 } 60 61 nsresult SMILIntegerType::Interpolate(const SMILValue& aStartVal, 62 const SMILValue& aEndVal, 63 double aUnitDistance, 64 SMILValue& aResult) const { 65 MOZ_ASSERT(aStartVal.mType == aEndVal.mType, 66 "Trying to interpolate different types"); 67 MOZ_ASSERT(aStartVal.mType == this, "Unexpected types for interpolation"); 68 MOZ_ASSERT(aResult.mType == this, "Unexpected result type"); 69 70 const double startVal = double(aStartVal.mU.mInt); 71 const double endVal = double(aEndVal.mU.mInt); 72 const double currentVal = startVal + (endVal - startVal) * aUnitDistance; 73 74 // When currentVal is exactly midway between its two nearest integers, we 75 // jump to the "next" integer to provide simple, easy to remember and 76 // consistent behaviour (from the SMIL author's point of view). 77 78 if (startVal < endVal) { 79 aResult.mU.mInt = int64_t(floor(currentVal + 0.5)); // round mid up 80 } else { 81 aResult.mU.mInt = int64_t(ceil(currentVal - 0.5)); // round mid down 82 } 83 84 return NS_OK; 85 } 86 87 } // namespace mozilla