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_SVGANIMATEDVIEWBOX_H_ 8 #define DOM_SVG_SVGANIMATEDVIEWBOX_H_ 9 10 #include "nsCycleCollectionParticipant.h" 11 #include "nsError.h" 12 #include "SVGAttrTearoffTable.h" 13 #include "mozilla/Attributes.h" 14 #include "mozilla/SMILAttr.h" 15 #include "mozilla/UniquePtr.h" 16 #include "mozilla/dom/SVGAnimatedRect.h" 17 18 namespace mozilla { 19 20 class SMILValue; 21 22 namespace dom { 23 class SVGRect; 24 class SVGAnimationElement; 25 class SVGElement; 26 } // namespace dom 27 28 struct SVGViewBox { 29 float x, y; 30 float width, height; 31 bool none; 32 SVGViewBoxSVGViewBox33 SVGViewBox() : x(0.0), y(0.0), width(0.0), height(0.0), none(true) {} SVGViewBoxSVGViewBox34 SVGViewBox(float aX, float aY, float aWidth, float aHeight) 35 : x(aX), y(aY), width(aWidth), height(aHeight), none(false) {} 36 bool operator==(const SVGViewBox& aOther) const; 37 38 static nsresult FromString(const nsAString& aStr, SVGViewBox* aViewBox); 39 }; 40 41 class SVGAnimatedViewBox { 42 public: 43 friend class AutoChangeViewBoxNotifier; 44 using SVGElement = dom::SVGElement; 45 46 void Init(); 47 48 /** 49 * Returns true if the corresponding "viewBox" attribute defined a rectangle 50 * with finite values and nonnegative width/height. 51 * Returns false if the viewBox was set to an invalid 52 * string, or if any of the four rect values were too big to store in a 53 * float, or the width/height are negative. 54 */ 55 bool HasRect() const; 56 57 /** 58 * Returns true if the corresponding "viewBox" attribute either defined a 59 * rectangle with finite values or the special "none" value. 60 */ IsExplicitlySet()61 bool IsExplicitlySet() const { 62 if (mAnimVal || mHasBaseVal) { 63 const SVGViewBox& rect = GetAnimValue(); 64 return rect.none || (rect.width >= 0 && rect.height >= 0); 65 } 66 return false; 67 } 68 GetBaseValue()69 const SVGViewBox& GetBaseValue() const { return mBaseVal; } 70 void SetBaseValue(const SVGViewBox& aRect, SVGElement* aSVGElement); GetAnimValue()71 const SVGViewBox& GetAnimValue() const { 72 return mAnimVal ? *mAnimVal : mBaseVal; 73 } 74 void SetAnimValue(const SVGViewBox& aRect, SVGElement* aSVGElement); 75 76 nsresult SetBaseValueString(const nsAString& aValue, SVGElement* aSVGElement, 77 bool aDoSetAttr); 78 void GetBaseValueString(nsAString& aValue) const; 79 80 already_AddRefed<dom::SVGAnimatedRect> ToSVGAnimatedRect( 81 SVGElement* aSVGElement); 82 83 already_AddRefed<dom::SVGRect> ToDOMBaseVal(SVGElement* aSVGElement); 84 85 already_AddRefed<dom::SVGRect> ToDOMAnimVal(SVGElement* aSVGElement); 86 87 UniquePtr<SMILAttr> ToSMILAttr(SVGElement* aSVGElement); 88 89 private: 90 SVGViewBox mBaseVal; 91 UniquePtr<SVGViewBox> mAnimVal; 92 bool mHasBaseVal; 93 94 public: 95 struct SMILViewBox : public SMILAttr { 96 public: SMILViewBoxSMILViewBox97 SMILViewBox(SVGAnimatedViewBox* aVal, SVGElement* aSVGElement) 98 : mVal(aVal), mSVGElement(aSVGElement) {} 99 100 // These will stay alive because a SMILAttr only lives as long 101 // as the Compositing step, and DOM elements don't get a chance to 102 // die during that. 103 SVGAnimatedViewBox* mVal; 104 SVGElement* mSVGElement; 105 106 // SMILAttr methods 107 virtual nsresult ValueFromString( 108 const nsAString& aStr, const dom::SVGAnimationElement* aSrcElement, 109 SMILValue& aValue, bool& aPreventCachingOfSandwich) const override; 110 virtual SMILValue GetBaseValue() const override; 111 virtual void ClearAnimValue() override; 112 virtual nsresult SetAnimValue(const SMILValue& aValue) override; 113 }; 114 115 static SVGAttrTearoffTable<SVGAnimatedViewBox, dom::SVGAnimatedRect> 116 sSVGAnimatedRectTearoffTable; 117 }; 118 119 } // namespace mozilla 120 121 #endif // DOM_SVG_SVGANIMATEDVIEWBOX_H_ 122