SVGViewBoxSMILType.cpp (5010B)
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 "SVGViewBoxSMILType.h" 8 9 #include <math.h> 10 11 #include "SVGAnimatedViewBox.h" 12 #include "mozilla/SMILValue.h" 13 #include "nsDebug.h" 14 15 namespace mozilla { 16 17 /*static*/ 18 SVGViewBoxSMILType SVGViewBoxSMILType::sSingleton; 19 20 void SVGViewBoxSMILType::InitValue(SMILValue& aValue) const { 21 MOZ_ASSERT(aValue.IsNull(), "Unexpected value type"); 22 23 aValue.mU.mPtr = new SVGViewBox(0.0f, 0.0f, 0.0f, 0.0f); 24 aValue.mType = this; 25 } 26 27 void SVGViewBoxSMILType::DestroyValue(SMILValue& aValue) const { 28 MOZ_ASSERT(aValue.mType == this, "Unexpected SMIL value"); 29 delete static_cast<SVGViewBox*>(aValue.mU.mPtr); 30 aValue.mU.mPtr = nullptr; 31 aValue.mType = SMILNullType::Singleton(); 32 } 33 34 nsresult SVGViewBoxSMILType::Assign(SMILValue& aDest, 35 const SMILValue& aSrc) const { 36 MOZ_ASSERT(aDest.mType == aSrc.mType, "Incompatible SMIL types"); 37 MOZ_ASSERT(aDest.mType == this, "Unexpected SMIL value"); 38 39 const SVGViewBox* src = static_cast<const SVGViewBox*>(aSrc.mU.mPtr); 40 SVGViewBox* dst = static_cast<SVGViewBox*>(aDest.mU.mPtr); 41 *dst = *src; 42 return NS_OK; 43 } 44 45 bool SVGViewBoxSMILType::IsEqual(const SMILValue& aLeft, 46 const SMILValue& aRight) const { 47 MOZ_ASSERT(aLeft.mType == aRight.mType, "Incompatible SMIL types"); 48 MOZ_ASSERT(aLeft.mType == this, "Unexpected type for SMIL value"); 49 50 const SVGViewBox* leftBox = static_cast<const SVGViewBox*>(aLeft.mU.mPtr); 51 const SVGViewBox* rightBox = static_cast<SVGViewBox*>(aRight.mU.mPtr); 52 return *leftBox == *rightBox; 53 } 54 55 nsresult SVGViewBoxSMILType::Add(SMILValue& aDest, const SMILValue& aValueToAdd, 56 uint32_t aCount) const { 57 MOZ_ASSERT(aValueToAdd.mType == aDest.mType, "Trying to add invalid types"); 58 MOZ_ASSERT(aValueToAdd.mType == this, "Unexpected source type"); 59 60 auto* dest = static_cast<SVGViewBox*>(aDest.mU.mPtr); 61 const auto* valueToAdd = static_cast<const SVGViewBox*>(aValueToAdd.mU.mPtr); 62 63 if (dest->none || valueToAdd->none) { 64 return NS_ERROR_FAILURE; 65 } 66 67 dest->x += valueToAdd->x * aCount; 68 dest->y += valueToAdd->y * aCount; 69 dest->width += valueToAdd->width * aCount; 70 dest->height += valueToAdd->height * aCount; 71 72 return NS_OK; 73 } 74 75 nsresult SVGViewBoxSMILType::ComputeDistance(const SMILValue& aFrom, 76 const SMILValue& aTo, 77 double& aDistance) const { 78 MOZ_ASSERT(aFrom.mType == aTo.mType, "Trying to compare different types"); 79 MOZ_ASSERT(aFrom.mType == this, "Unexpected source type"); 80 81 const SVGViewBox* from = static_cast<const SVGViewBox*>(aFrom.mU.mPtr); 82 const SVGViewBox* to = static_cast<const SVGViewBox*>(aTo.mU.mPtr); 83 84 if (from->none || to->none) { 85 return NS_ERROR_FAILURE; 86 } 87 88 // We use the distances between the edges rather than the difference between 89 // the x, y, width and height for the "distance". This is necessary in 90 // order for the "distance" result that we calculate to be the same for a 91 // given change in the left side as it is for an equal change in the opposite 92 // side. See https://bugzilla.mozilla.org/show_bug.cgi?id=541884#c12 93 94 double dLeft = to->x - from->x; 95 double dTop = to->y - from->y; 96 double dRight = (to->x + to->width) - (from->x + from->width); 97 double dBottom = (to->y + to->height) - (from->y + from->height); 98 99 aDistance = std::sqrt(dLeft * dLeft + dTop * dTop + dRight * dRight + 100 dBottom * dBottom); 101 102 return NS_OK; 103 } 104 105 nsresult SVGViewBoxSMILType::Interpolate(const SMILValue& aStartVal, 106 const SMILValue& aEndVal, 107 double aUnitDistance, 108 SMILValue& aResult) const { 109 MOZ_ASSERT(aStartVal.mType == aEndVal.mType, 110 "Trying to interpolate different types"); 111 MOZ_ASSERT(aStartVal.mType == this, "Unexpected types for interpolation"); 112 MOZ_ASSERT(aResult.mType == this, "Unexpected result type"); 113 114 const SVGViewBox* start = static_cast<const SVGViewBox*>(aStartVal.mU.mPtr); 115 const SVGViewBox* end = static_cast<const SVGViewBox*>(aEndVal.mU.mPtr); 116 117 if (start->none || end->none) { 118 return NS_ERROR_FAILURE; 119 } 120 121 SVGViewBox* current = static_cast<SVGViewBox*>(aResult.mU.mPtr); 122 123 float x = (start->x + (end->x - start->x) * aUnitDistance); 124 float y = (start->y + (end->y - start->y) * aUnitDistance); 125 float width = (start->width + (end->width - start->width) * aUnitDistance); 126 float height = 127 (start->height + (end->height - start->height) * aUnitDistance); 128 129 *current = SVGViewBox(x, y, width, height); 130 131 return NS_OK; 132 } 133 134 } // namespace mozilla