SVGAnimatedPathSegList.h (4507B)
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 #ifndef DOM_SVG_SVGANIMATEDPATHSEGLIST_H_ 8 #define DOM_SVG_SVGANIMATEDPATHSEGLIST_H_ 9 10 #include "SVGPathData.h" 11 #include "mozilla/MemoryReporting.h" 12 #include "mozilla/SMILAttr.h" 13 #include "mozilla/UniquePtr.h" 14 15 namespace mozilla { 16 17 class SMILValue; 18 19 namespace dom { 20 class SVGAnimationElement; 21 class SVGElement; 22 class SVGPathSegment; 23 struct SVGPathSegmentInit; 24 } // namespace dom 25 26 /** 27 * Class SVGAnimatedPathSegList 28 * 29 * Despite the fact that no SVGAnimatedPathSegList interface or objects exist 30 * in the SVG specification (unlike e.g. SVGAnimated*Length*List), we 31 * nevertheless have this internal class. (Note that there is an 32 * SVGAnimatedPathData interface, but that's quite different to 33 * SVGAnimatedLengthList since it is inherited by elements, as opposed to 34 * elements having members of that type.) The reason that we have this class is 35 * to provide a single locked down point of entry to the SVGPathData objects, 36 * which helps ensure that the DOM wrappers for SVGPathData objects' are always 37 * kept in sync. This is vitally important (see the comment in 38 * DOMSVGPathSegList::InternalListWillChangeTo) and frees consumers from having 39 * to know or worry about wrappers (or forget about them!) for the most part. 40 */ 41 class SVGAnimatedPathSegList final { 42 public: 43 SVGAnimatedPathSegList() = default; 44 45 SVGAnimatedPathSegList& operator=(const SVGAnimatedPathSegList& aOther) { 46 mBaseVal = aOther.mBaseVal; 47 if (aOther.mAnimVal) { 48 mAnimVal = MakeUnique<SVGPathData>(*aOther.mAnimVal); 49 } 50 return *this; 51 } 52 53 /** 54 * Because it's so important that mBaseVal and its DOMSVGPathSegList wrapper 55 * (if any) be kept in sync (see the comment in 56 * DOMSVGPathSegList::InternalListWillChangeTo), this method returns a const 57 * reference. Only our friend classes may get mutable references to mBaseVal. 58 */ 59 const SVGPathData& GetBaseValue() const { return mBaseVal; } 60 61 nsresult SetBaseValueString(const nsAString& aValue); 62 63 void SetBaseValueFromPathSegments( 64 const dom::Sequence<dom::SVGPathSegmentInit>& aValues); 65 66 void ClearBaseValue(); 67 68 /** 69 * const! See comment for GetBaseValue! 70 */ 71 const SVGPathData& GetAnimValue() const { 72 return mAnimVal ? *mAnimVal : mBaseVal; 73 } 74 75 nsresult SetAnimValue(const SVGPathData& aNewAnimValue, 76 dom::SVGElement* aElement); 77 78 void ClearAnimValue(dom::SVGElement* aElement); 79 80 /** 81 * Empty paths are not rendered. 82 */ 83 bool IsRendered() const; 84 85 /** 86 * Needed for correct DOM wrapper construction since GetAnimValue may 87 * actually return the baseVal! 88 */ 89 void* GetBaseValKey() const { return (void*)&mBaseVal; } 90 void* GetAnimValKey() const { return (void*)&mAnimVal; } 91 92 bool IsAnimating() const { return !!mAnimVal; } 93 94 UniquePtr<SMILAttr> ToSMILAttr(dom::SVGElement* aElement); 95 96 size_t SizeOfExcludingThis(MallocSizeOf aMallocSizeOf) const; 97 98 private: 99 // mAnimVal is a pointer to allow us to determine if we're being animated or 100 // not. Making it a non-pointer member and using mAnimVal.IsEmpty() to check 101 // if we're animating is not an option, since that would break animation *to* 102 // the empty string (<set to="">). 103 104 SVGPathData mBaseVal; 105 UniquePtr<SVGPathData> mAnimVal; 106 107 struct SMILAnimatedPathSegList : public SMILAttr { 108 public: 109 SMILAnimatedPathSegList(SVGAnimatedPathSegList* aVal, 110 dom::SVGElement* aElement) 111 : mVal(aVal), mElement(aElement) {} 112 113 // These will stay alive because a SMILAttr only lives as long 114 // as the Compositing step, and DOM elements don't get a chance to 115 // die during that. 116 SVGAnimatedPathSegList* mVal; 117 dom::SVGElement* mElement; 118 119 // SMILAttr methods 120 nsresult ValueFromString(const nsAString& aStr, 121 const dom::SVGAnimationElement* aSrcElement, 122 SMILValue& aValue, 123 bool& aPreventCachingOfSandwich) const override; 124 SMILValue GetBaseValue() const override; 125 void ClearAnimValue() override; 126 nsresult SetAnimValue(const SMILValue& aValue) override; 127 }; 128 }; 129 130 } // namespace mozilla 131 132 #endif // DOM_SVG_SVGANIMATEDPATHSEGLIST_H_