SVGPathSegListSMILType.cpp (4596B)
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 "SVGPathSegListSMILType.h" 8 9 #include "SVGPathData.h" 10 #include "SVGPathSegUtils.h" 11 #include "mozilla/SMILValue.h" 12 13 namespace mozilla { 14 15 //---------------------------------------------------------------------- 16 // nsISMILType implementation 17 18 void SVGPathSegListSMILType::InitValue(SMILValue& aValue) const { 19 MOZ_ASSERT(aValue.IsNull(), "Unexpected value type"); 20 aValue.mU.mPtr = new SVGPathDataAndInfo(); 21 aValue.mType = this; 22 } 23 24 void SVGPathSegListSMILType::DestroyValue(SMILValue& aValue) const { 25 MOZ_ASSERT(aValue.mType == this, "Unexpected SMIL value type"); 26 delete static_cast<SVGPathDataAndInfo*>(aValue.mU.mPtr); 27 aValue.mU.mPtr = nullptr; 28 aValue.mType = SMILNullType::Singleton(); 29 } 30 31 nsresult SVGPathSegListSMILType::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 const SVGPathDataAndInfo* src = 37 static_cast<const SVGPathDataAndInfo*>(aSrc.mU.mPtr); 38 SVGPathDataAndInfo* dest = static_cast<SVGPathDataAndInfo*>(aDest.mU.mPtr); 39 dest->CopyFrom(*src); 40 return NS_OK; 41 } 42 43 bool SVGPathSegListSMILType::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 SVGPathDataAndInfo*>(aLeft.mU.mPtr) == 49 *static_cast<const SVGPathDataAndInfo*>(aRight.mU.mPtr); 50 } 51 52 nsresult SVGPathSegListSMILType::Add(SMILValue& aDest, 53 const SMILValue& aValueToAdd, 54 uint32_t aCount) const { 55 MOZ_ASSERT(aDest.mType == this, "Unexpected SMIL type"); 56 MOZ_ASSERT(aValueToAdd.mType == this, "Incompatible SMIL type"); 57 58 SVGPathDataAndInfo& dest = *static_cast<SVGPathDataAndInfo*>(aDest.mU.mPtr); 59 const SVGPathDataAndInfo& valueToAdd = 60 *static_cast<const SVGPathDataAndInfo*>(aValueToAdd.mU.mPtr); 61 62 if (valueToAdd.IsIdentity()) { // Adding identity value - no-op 63 return NS_OK; 64 } 65 66 if (dest.IsIdentity()) { 67 dest.CopyFrom(valueToAdd); 68 aCount--; 69 } 70 71 if (aCount && 72 !Servo_SVGPathData_Add(&dest.RawData(), &valueToAdd.RawData(), aCount)) { 73 // SVGContentUtils::ReportToConsole - can't add path segment lists with 74 // different numbers of segments, with arcs that have different flag 75 // values, or with incompatible segment types. 76 return NS_ERROR_FAILURE; 77 } 78 return NS_OK; 79 } 80 81 nsresult SVGPathSegListSMILType::ComputeDistance(const SMILValue& aFrom, 82 const SMILValue& aTo, 83 double& aDistance) const { 84 MOZ_ASSERT(aFrom.mType == this, "Unexpected SMIL type"); 85 MOZ_ASSERT(aTo.mType == this, "Incompatible SMIL type"); 86 87 // See https://bugzilla.mozilla.org/show_bug.cgi?id=522306#c18 88 89 // SVGContentUtils::ReportToConsole 90 return NS_ERROR_NOT_IMPLEMENTED; 91 } 92 93 nsresult SVGPathSegListSMILType::Interpolate(const SMILValue& aStartVal, 94 const SMILValue& aEndVal, 95 double aUnitDistance, 96 SMILValue& aResult) const { 97 MOZ_ASSERT(aStartVal.mType == aEndVal.mType, 98 "Trying to interpolate different types"); 99 MOZ_ASSERT(aStartVal.mType == this, "Unexpected types for interpolation"); 100 MOZ_ASSERT(aResult.mType == this, "Unexpected result type"); 101 102 const SVGPathDataAndInfo& start = 103 *static_cast<const SVGPathDataAndInfo*>(aStartVal.mU.mPtr); 104 const SVGPathDataAndInfo& end = 105 *static_cast<const SVGPathDataAndInfo*>(aEndVal.mU.mPtr); 106 SVGPathDataAndInfo& result = 107 *static_cast<SVGPathDataAndInfo*>(aResult.mU.mPtr); 108 MOZ_ASSERT(result.IsIdentity(), 109 "expecting outparam to start out as identity"); 110 result.SetElement(end.Element()); 111 if (!Servo_SVGPathData_Interpolate( 112 start.IsIdentity() ? nullptr : &start.RawData(), &end.RawData(), 113 aUnitDistance, &result.RawData())) { 114 return NS_ERROR_FAILURE; 115 } 116 return NS_OK; 117 } 118 119 } // namespace mozilla