summaryrefslogtreecommitdiffstats
path: root/dom/svg/nsSVGLength2.h
diff options
context:
space:
mode:
Diffstat (limited to 'dom/svg/nsSVGLength2.h')
-rw-r--r--dom/svg/nsSVGLength2.h209
1 files changed, 209 insertions, 0 deletions
diff --git a/dom/svg/nsSVGLength2.h b/dom/svg/nsSVGLength2.h
new file mode 100644
index 000000000..d67bbdaad
--- /dev/null
+++ b/dom/svg/nsSVGLength2.h
@@ -0,0 +1,209 @@
+/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* vim: set ts=8 sts=2 et sw=2 tw=80: */
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+#ifndef __NS_SVGLENGTH2_H__
+#define __NS_SVGLENGTH2_H__
+
+#include "mozilla/Attributes.h"
+#include "nsCoord.h"
+#include "nsCycleCollectionParticipant.h"
+#include "nsError.h"
+#include "nsIDOMSVGLength.h"
+#include "nsISMILAttr.h"
+#include "nsMathUtils.h"
+#include "nsSVGElement.h"
+#include "SVGContentUtils.h"
+#include "mozilla/gfx/Rect.h"
+
+class nsIFrame;
+class nsSMILValue;
+
+namespace mozilla {
+class DOMSVGLength;
+namespace dom {
+class SVGAnimatedLength;
+class SVGAnimationElement;
+class SVGSVGElement;
+} // namespace dom
+} // namespace mozilla
+
+namespace mozilla {
+namespace dom {
+
+class UserSpaceMetrics
+{
+public:
+ virtual ~UserSpaceMetrics() {}
+
+ virtual float GetEmLength() const = 0;
+ virtual float GetExLength() const = 0;
+ virtual float GetAxisLength(uint8_t aCtxType) const = 0;
+};
+
+class UserSpaceMetricsWithSize : public UserSpaceMetrics
+{
+public:
+ virtual gfx::Size GetSize() const = 0;
+ virtual float GetAxisLength(uint8_t aCtxType) const override;
+};
+
+class SVGElementMetrics : public UserSpaceMetrics
+{
+public:
+ explicit SVGElementMetrics(nsSVGElement* aSVGElement,
+ mozilla::dom::SVGSVGElement* aCtx = nullptr);
+
+ virtual float GetEmLength() const override;
+ virtual float GetExLength() const override;
+ virtual float GetAxisLength(uint8_t aCtxType) const override;
+
+private:
+ bool EnsureCtx() const;
+
+ nsSVGElement* mSVGElement;
+ mutable mozilla::dom::SVGSVGElement* mCtx;
+};
+
+class NonSVGFrameUserSpaceMetrics : public UserSpaceMetricsWithSize
+{
+public:
+ explicit NonSVGFrameUserSpaceMetrics(nsIFrame* aFrame);
+
+ virtual float GetEmLength() const override;
+ virtual float GetExLength() const override;
+ virtual gfx::Size GetSize() const override;
+
+private:
+ nsIFrame* mFrame;
+};
+
+} // namespace dom
+} // namespace mozilla
+
+class nsSVGLength2
+{
+ friend class mozilla::dom::SVGAnimatedLength;
+ friend class mozilla::DOMSVGLength;
+ typedef mozilla::dom::UserSpaceMetrics UserSpaceMetrics;
+public:
+ void Init(uint8_t aCtxType = SVGContentUtils::XY,
+ uint8_t aAttrEnum = 0xff,
+ float aValue = 0,
+ uint8_t aUnitType = nsIDOMSVGLength::SVG_LENGTHTYPE_NUMBER) {
+ mAnimVal = mBaseVal = aValue;
+ mSpecifiedUnitType = aUnitType;
+ mAttrEnum = aAttrEnum;
+ mCtxType = aCtxType;
+ mIsAnimated = false;
+ mIsBaseSet = false;
+ }
+
+ nsSVGLength2& operator=(const nsSVGLength2& aLength) {
+ mBaseVal = aLength.mBaseVal;
+ mAnimVal = aLength.mAnimVal;
+ mSpecifiedUnitType = aLength.mSpecifiedUnitType;
+ mIsAnimated = aLength.mIsAnimated;
+ mIsBaseSet = aLength.mIsBaseSet;
+ return *this;
+ }
+
+ nsresult SetBaseValueString(const nsAString& aValue,
+ nsSVGElement *aSVGElement,
+ bool aDoSetAttr);
+ void GetBaseValueString(nsAString& aValue) const;
+ void GetAnimValueString(nsAString& aValue) const;
+
+ float GetBaseValue(nsSVGElement* aSVGElement) const
+ { return mBaseVal / GetUnitScaleFactor(aSVGElement, mSpecifiedUnitType); }
+
+ float GetAnimValue(nsSVGElement* aSVGElement) const
+ { return mAnimVal / GetUnitScaleFactor(aSVGElement, mSpecifiedUnitType); }
+ float GetAnimValue(nsIFrame* aFrame) const
+ { return mAnimVal / GetUnitScaleFactor(aFrame, mSpecifiedUnitType); }
+ float GetAnimValue(mozilla::dom::SVGSVGElement* aCtx) const
+ { return mAnimVal / GetUnitScaleFactor(aCtx, mSpecifiedUnitType); }
+ float GetAnimValue(const UserSpaceMetrics& aMetrics) const
+ { return mAnimVal / GetUnitScaleFactor(aMetrics, mSpecifiedUnitType); }
+
+ uint8_t GetCtxType() const { return mCtxType; }
+ uint8_t GetSpecifiedUnitType() const { return mSpecifiedUnitType; }
+ bool IsPercentage() const
+ { return mSpecifiedUnitType == nsIDOMSVGLength::SVG_LENGTHTYPE_PERCENTAGE; }
+ float GetAnimValInSpecifiedUnits() const { return mAnimVal; }
+ float GetBaseValInSpecifiedUnits() const { return mBaseVal; }
+
+ float GetBaseValue(mozilla::dom::SVGSVGElement* aCtx) const
+ { return mBaseVal / GetUnitScaleFactor(aCtx, mSpecifiedUnitType); }
+
+ bool HasBaseVal() const {
+ return mIsBaseSet;
+ }
+ // Returns true if the animated value of this length has been explicitly
+ // set (either by animation, or by taking on the base value which has been
+ // explicitly set by markup or a DOM call), false otherwise.
+ // If this returns false, the animated value is still valid, that is,
+ // useable, and represents the default base value of the attribute.
+ bool IsExplicitlySet() const
+ { return mIsAnimated || mIsBaseSet; }
+
+ already_AddRefed<mozilla::dom::SVGAnimatedLength>
+ ToDOMAnimatedLength(nsSVGElement* aSVGElement);
+
+ // Returns a new nsISMILAttr object that the caller must delete
+ nsISMILAttr* ToSMILAttr(nsSVGElement* aSVGElement);
+
+private:
+
+ float mAnimVal;
+ float mBaseVal;
+ uint8_t mSpecifiedUnitType;
+ uint8_t mAttrEnum; // element specified tracking for attribute
+ uint8_t mCtxType; // X, Y or Unspecified
+ bool mIsAnimated:1;
+ bool mIsBaseSet:1;
+
+ float GetUnitScaleFactor(nsIFrame *aFrame, uint8_t aUnitType) const;
+ float GetUnitScaleFactor(const UserSpaceMetrics& aMetrics, uint8_t aUnitType) const;
+ float GetUnitScaleFactor(nsSVGElement *aSVGElement, uint8_t aUnitType) const;
+ float GetUnitScaleFactor(mozilla::dom::SVGSVGElement *aCtx, uint8_t aUnitType) const;
+
+ // SetBaseValue and SetAnimValue set the value in user units
+ void SetBaseValue(float aValue, nsSVGElement *aSVGElement, bool aDoSetAttr);
+ void SetBaseValueInSpecifiedUnits(float aValue, nsSVGElement *aSVGElement,
+ bool aDoSetAttr);
+ void SetAnimValue(float aValue, nsSVGElement *aSVGElement);
+ void SetAnimValueInSpecifiedUnits(float aValue, nsSVGElement *aSVGElement);
+ nsresult NewValueSpecifiedUnits(uint16_t aUnitType, float aValue,
+ nsSVGElement *aSVGElement);
+ nsresult ConvertToSpecifiedUnits(uint16_t aUnitType, nsSVGElement *aSVGElement);
+ nsresult ToDOMBaseVal(mozilla::DOMSVGLength **aResult, nsSVGElement* aSVGElement);
+ nsresult ToDOMAnimVal(mozilla::DOMSVGLength **aResult, nsSVGElement* aSVGElement);
+
+public:
+ struct SMILLength : public nsISMILAttr
+ {
+ public:
+ SMILLength(nsSVGLength2* aVal, nsSVGElement *aSVGElement)
+ : mVal(aVal), mSVGElement(aSVGElement) {}
+
+ // These will stay alive because a nsISMILAttr only lives as long
+ // as the Compositing step, and DOM elements don't get a chance to
+ // die during that.
+ nsSVGLength2* mVal;
+ nsSVGElement* mSVGElement;
+
+ // nsISMILAttr methods
+ virtual nsresult ValueFromString(const nsAString& aStr,
+ const mozilla::dom::SVGAnimationElement* aSrcElement,
+ nsSMILValue &aValue,
+ bool& aPreventCachingOfSandwich) const override;
+ virtual nsSMILValue GetBaseValue() const override;
+ virtual void ClearAnimValue() override;
+ virtual nsresult SetAnimValue(const nsSMILValue& aValue) override;
+ };
+};
+
+#endif // __NS_SVGLENGTH2_H__