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