Bumping manifests a=b2g-bump
[gecko.git] / dom / svg / SVGSVGElement.h
blob30591581218dc79d50edcd629d7802958195f361
1 /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
2 /* This Source Code Form is subject to the terms of the Mozilla Public
3 * License, v. 2.0. If a copy of the MPL was not distributed with this
4 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
6 #ifndef mozilla_dom_SVGSVGElement_h
7 #define mozilla_dom_SVGSVGElement_h
9 #include "mozilla/dom/FromParser.h"
10 #include "nsISVGPoint.h"
11 #include "nsSVGEnum.h"
12 #include "nsSVGLength2.h"
13 #include "SVGGraphicsElement.h"
14 #include "SVGImageContext.h"
15 #include "nsSVGViewBox.h"
16 #include "SVGPreserveAspectRatio.h"
17 #include "SVGAnimatedPreserveAspectRatio.h"
18 #include "mozilla/Attributes.h"
20 nsresult NS_NewSVGSVGElement(nsIContent **aResult,
21 already_AddRefed<mozilla::dom::NodeInfo>&& aNodeInfo,
22 mozilla::dom::FromParser aFromParser);
24 class nsSMILTimeContainer;
25 class nsSVGOuterSVGFrame;
26 class nsSVGInnerSVGFrame;
27 class nsSVGImageFrame;
29 namespace mozilla {
30 class AutoSVGRenderingState;
31 class DOMSVGAnimatedPreserveAspectRatio;
32 class DOMSVGLength;
33 class DOMSVGNumber;
34 class EventChainPreVisitor;
35 class SVGFragmentIdentifier;
37 namespace dom {
38 class SVGAngle;
39 class SVGAnimatedRect;
40 class SVGMatrix;
41 class SVGTransform;
42 class SVGViewElement;
43 class SVGIRect;
45 class SVGSVGElement;
47 class DOMSVGTranslatePoint MOZ_FINAL : public nsISVGPoint {
48 public:
49 DOMSVGTranslatePoint(SVGPoint* aPt, SVGSVGElement *aElement)
50 : nsISVGPoint(aPt, true), mElement(aElement) {}
52 explicit DOMSVGTranslatePoint(DOMSVGTranslatePoint* aPt)
53 : nsISVGPoint(&aPt->mPt, true), mElement(aPt->mElement) {}
55 NS_DECL_ISUPPORTS_INHERITED
56 NS_DECL_CYCLE_COLLECTION_CLASS_INHERITED(DOMSVGTranslatePoint, nsISVGPoint)
58 virtual DOMSVGPoint* Copy() MOZ_OVERRIDE;
60 // WebIDL
61 virtual float X() MOZ_OVERRIDE { return mPt.GetX(); }
62 virtual float Y() MOZ_OVERRIDE { return mPt.GetY(); }
63 virtual void SetX(float aValue, ErrorResult& rv) MOZ_OVERRIDE;
64 virtual void SetY(float aValue, ErrorResult& rv) MOZ_OVERRIDE;
65 virtual already_AddRefed<nsISVGPoint> MatrixTransform(SVGMatrix& matrix) MOZ_OVERRIDE;
67 virtual nsISupports* GetParentObject() MOZ_OVERRIDE;
69 nsRefPtr<SVGSVGElement> mElement;
71 private:
72 ~DOMSVGTranslatePoint() {}
75 class svgFloatSize {
76 public:
77 svgFloatSize(float aWidth, float aHeight)
78 : width(aWidth)
79 , height(aHeight)
81 bool operator!=(const svgFloatSize& rhs) {
82 return width != rhs.width || height != rhs.height;
84 float width;
85 float height;
88 typedef SVGGraphicsElement SVGSVGElementBase;
90 class SVGSVGElement MOZ_FINAL : public SVGSVGElementBase
92 friend class ::nsSVGOuterSVGFrame;
93 friend class ::nsSVGInnerSVGFrame;
94 friend class mozilla::SVGFragmentIdentifier;
95 friend class mozilla::AutoSVGRenderingState;
97 SVGSVGElement(already_AddRefed<mozilla::dom::NodeInfo>& aNodeInfo,
98 FromParser aFromParser);
99 virtual JSObject* WrapNode(JSContext *aCx) MOZ_OVERRIDE;
101 friend nsresult (::NS_NewSVGSVGElement(nsIContent **aResult,
102 already_AddRefed<mozilla::dom::NodeInfo>&& aNodeInfo,
103 mozilla::dom::FromParser aFromParser));
105 ~SVGSVGElement();
107 public:
108 // interfaces:
109 NS_DECL_ISUPPORTS_INHERITED
110 NS_DECL_CYCLE_COLLECTION_CLASS_INHERITED(SVGSVGElement, SVGSVGElementBase)
113 * For use by zoom controls to allow currentScale, currentTranslate.x and
114 * currentTranslate.y to be set by a single operation that dispatches a
115 * single SVGZoom event (instead of one SVGZoom and two SVGScroll events).
117 void SetCurrentScaleTranslate(float s, float x, float y);
120 * Retrieve the value of currentScale and currentTranslate.
122 const SVGPoint& GetCurrentTranslate() { return mCurrentTranslate; }
123 float GetCurrentScale() { return mCurrentScale; }
126 * Retrieve the value of currentScale, currentTranslate.x or
127 * currentTranslate.y prior to the last change made to any one of them.
129 const SVGPoint& GetPreviousTranslate() { return mPreviousTranslate; }
130 float GetPreviousScale() { return mPreviousScale; }
132 nsSMILTimeContainer* GetTimedDocumentRoot();
134 // nsIContent interface
135 NS_IMETHOD_(bool) IsAttributeMapped(const nsIAtom* aAttribute) const MOZ_OVERRIDE;
136 virtual nsresult PreHandleEvent(EventChainPreVisitor& aVisitor) MOZ_OVERRIDE;
138 virtual bool IsEventAttributeName(nsIAtom* aName) MOZ_OVERRIDE;
140 // nsSVGElement specializations:
141 virtual gfxMatrix PrependLocalTransformsTo(const gfxMatrix &aMatrix,
142 TransformTypes aWhich = eAllTransforms) const MOZ_OVERRIDE;
143 virtual bool HasValidDimensions() const MOZ_OVERRIDE;
145 // SVGSVGElement methods:
146 float GetLength(uint8_t mCtxType);
148 // public helpers:
151 * Returns true if this element has a base/anim value for its "viewBox"
152 * attribute that defines a viewBox rectangle with finite values, or
153 * if there is a view element overriding this element's viewBox and it
154 * has a valid viewBox.
156 * Note that this does not check whether we need to synthesize a viewBox,
157 * so you must call ShouldSynthesizeViewBox() if you need to check that too.
159 * Note also that this method does not pay attention to whether the width or
160 * height values of the viewBox rect are positive!
162 bool HasViewBoxRect() const;
165 * Returns true if we should synthesize a viewBox for ourselves (that is, if
166 * we're the root element in an image document, and we're not currently being
167 * painted for an <svg:image> element).
169 * Only call this method if HasViewBoxRect() returns false.
171 bool ShouldSynthesizeViewBox() const;
173 bool HasViewBoxOrSyntheticViewBox() const {
174 return HasViewBoxRect() || ShouldSynthesizeViewBox();
177 gfx::Matrix GetViewBoxTransform() const;
179 bool HasChildrenOnlyTransform() const {
180 return mHasChildrenOnlyTransform;
183 void UpdateHasChildrenOnlyTransform();
185 enum ChildrenOnlyTransformChangedFlags {
186 eDuringReflow = 1
190 * This method notifies the style system that the overflow rects of our
191 * immediate childrens' frames need to be updated. It is called by our own
192 * frame when changes (e.g. to currentScale) cause our children-only
193 * transform to change.
195 * The reason we have this method instead of overriding
196 * GetAttributeChangeHint is because we need to act on non-attribute (e.g.
197 * currentScale) changes in addition to attribute (e.g. viewBox) changes.
199 void ChildrenOnlyTransformChanged(uint32_t aFlags = 0);
201 // This services any pending notifications for the transform on on this root
202 // <svg> node needing to be recalculated. (Only applicable in
203 // SVG-as-an-image documents.)
204 virtual void FlushImageTransformInvalidation();
206 virtual nsresult Clone(mozilla::dom::NodeInfo *aNodeInfo, nsINode **aResult) const MOZ_OVERRIDE;
208 // Returns true IFF our attributes are currently overridden by a <view>
209 // element and that element's ID matches the passed-in string.
210 bool IsOverriddenBy(const nsAString &aViewID) const {
211 return mCurrentViewID && mCurrentViewID->Equals(aViewID);
214 svgFloatSize GetViewportSize() const {
215 return svgFloatSize(mViewportWidth, mViewportHeight);
218 void SetViewportSize(const svgFloatSize& aSize) {
219 mViewportWidth = aSize.width;
220 mViewportHeight = aSize.height;
223 // WebIDL
224 already_AddRefed<SVGAnimatedLength> X();
225 already_AddRefed<SVGAnimatedLength> Y();
226 already_AddRefed<SVGAnimatedLength> Width();
227 already_AddRefed<SVGAnimatedLength> Height();
228 float PixelUnitToMillimeterX();
229 float PixelUnitToMillimeterY();
230 float ScreenPixelToMillimeterX();
231 float ScreenPixelToMillimeterY();
232 bool UseCurrentView();
233 float CurrentScale();
234 void SetCurrentScale(float aCurrentScale);
235 already_AddRefed<nsISVGPoint> CurrentTranslate();
236 void SetCurrentTranslate(float x, float y);
237 uint32_t SuspendRedraw(uint32_t max_wait_milliseconds);
238 void UnsuspendRedraw(uint32_t suspend_handle_id);
239 void UnsuspendRedrawAll();
240 void ForceRedraw(ErrorResult& rv);
241 void PauseAnimations();
242 void UnpauseAnimations();
243 bool AnimationsPaused();
244 float GetCurrentTime();
245 void SetCurrentTime(float seconds);
246 void DeselectAll();
247 already_AddRefed<DOMSVGNumber> CreateSVGNumber();
248 already_AddRefed<DOMSVGLength> CreateSVGLength();
249 already_AddRefed<SVGAngle> CreateSVGAngle();
250 already_AddRefed<nsISVGPoint> CreateSVGPoint();
251 already_AddRefed<SVGMatrix> CreateSVGMatrix();
252 already_AddRefed<SVGIRect> CreateSVGRect();
253 already_AddRefed<SVGTransform> CreateSVGTransform();
254 already_AddRefed<SVGTransform> CreateSVGTransformFromMatrix(SVGMatrix& matrix);
255 using nsINode::GetElementById; // This does what we want
256 already_AddRefed<SVGAnimatedRect> ViewBox();
257 already_AddRefed<DOMSVGAnimatedPreserveAspectRatio> PreserveAspectRatio();
258 uint16_t ZoomAndPan();
259 void SetZoomAndPan(uint16_t aZoomAndPan, ErrorResult& rv);
261 private:
262 // nsSVGElement overrides
264 virtual nsresult BindToTree(nsIDocument* aDocument, nsIContent* aParent,
265 nsIContent* aBindingParent,
266 bool aCompileEventHandlers) MOZ_OVERRIDE;
267 virtual void UnbindFromTree(bool aDeep, bool aNullParent) MOZ_OVERRIDE;
269 // implementation helpers:
271 SVGViewElement* GetCurrentViewElement() const;
273 // Methods for <image> elements to override my "PreserveAspectRatio" value.
274 // These are private so that only our friends (AutoSVGRenderingState in
275 // particular) have access.
276 void SetImageOverridePreserveAspectRatio(const SVGPreserveAspectRatio& aPAR);
277 void ClearImageOverridePreserveAspectRatio();
279 // Set/Clear properties to hold old or override versions of attributes
280 bool SetPreserveAspectRatioProperty(const SVGPreserveAspectRatio& aPAR);
281 const SVGPreserveAspectRatio* GetPreserveAspectRatioProperty() const;
282 bool ClearPreserveAspectRatioProperty();
283 bool SetViewBoxProperty(const nsSVGViewBoxRect& aViewBox);
284 const nsSVGViewBoxRect* GetViewBoxProperty() const;
285 bool ClearViewBoxProperty();
286 bool SetZoomAndPanProperty(uint16_t aValue);
287 uint16_t GetZoomAndPanProperty() const;
288 bool ClearZoomAndPanProperty();
289 bool SetTransformProperty(const SVGTransformList& aValue);
290 const SVGTransformList* GetTransformProperty() const;
291 bool ClearTransformProperty();
293 bool IsRoot() const {
294 NS_ASSERTION((IsInDoc() && !GetParent()) ==
295 (OwnerDoc() && (OwnerDoc()->GetRootElement() == this)),
296 "Can't determine if we're root");
297 return IsInDoc() && !GetParent();
301 * Returns true if this is an SVG <svg> element that is the child of
302 * another non-foreignObject SVG element.
304 bool IsInner() const {
305 const nsIContent *parent = GetFlattenedTreeParent();
306 return parent && parent->IsSVG() &&
307 parent->Tag() != nsGkAtoms::foreignObject;
311 * While binding to the tree we need to determine if we will be the outermost
312 * <svg> element _before_ the children are bound (as they want to know what
313 * timed document root to register with) and therefore _before_ our parent is
314 * set (both actions are performed by Element::BindToTree) so we
315 * can't use GetOwnerSVGElement() as it relies on GetParent(). This code is
316 * basically a simplified version of GetOwnerSVGElement that uses the parent
317 * parameters passed in instead.
319 bool WillBeOutermostSVG(nsIContent* aParent,
320 nsIContent* aBindingParent) const;
322 // invalidate viewbox -> viewport xform & inform frames
323 void InvalidateTransformNotifyFrame();
325 // Returns true if we have at least one of the following:
326 // - a (valid or invalid) value for the preserveAspectRatio attribute
327 // - a SMIL-animated value for the preserveAspectRatio attribute
328 bool HasPreserveAspectRatio();
331 * Returns the explicit viewBox rect, if specified, or else a synthesized
332 * viewBox, if appropriate, or else a viewBox matching the dimensions of the
333 * SVG viewport.
335 nsSVGViewBoxRect GetViewBoxWithSynthesis(
336 float aViewportWidth, float aViewportHeight) const;
338 * Returns the explicit or default preserveAspectRatio, unless we're
339 * synthesizing a viewBox, in which case it returns the "none" value.
341 SVGPreserveAspectRatio GetPreserveAspectRatioWithOverride() const;
343 virtual LengthAttributesInfo GetLengthInfo() MOZ_OVERRIDE;
345 enum { ATTR_X, ATTR_Y, ATTR_WIDTH, ATTR_HEIGHT };
346 nsSVGLength2 mLengthAttributes[4];
347 static LengthInfo sLengthInfo[4];
349 virtual EnumAttributesInfo GetEnumInfo() MOZ_OVERRIDE;
351 enum { ZOOMANDPAN };
352 nsSVGEnum mEnumAttributes[1];
353 static nsSVGEnumMapping sZoomAndPanMap[];
354 static EnumInfo sEnumInfo[1];
356 virtual nsSVGViewBox *GetViewBox() MOZ_OVERRIDE;
357 virtual SVGAnimatedPreserveAspectRatio *GetPreserveAspectRatio() MOZ_OVERRIDE;
359 nsSVGViewBox mViewBox;
360 SVGAnimatedPreserveAspectRatio mPreserveAspectRatio;
362 nsAutoPtr<nsString> mCurrentViewID;
364 // The size of the rectangular SVG viewport into which we render. This is
365 // not (necessarily) the same as the content area. See:
367 // http://www.w3.org/TR/SVG11/coords.html#ViewportSpace
369 // XXXjwatt Currently only used for outer <svg>, but maybe we could use -1 to
370 // flag this as an inner <svg> to save the overhead of GetCtx calls?
371 // XXXjwatt our frame should probably reset these when it's destroyed.
372 float mViewportWidth, mViewportHeight;
374 // The time container for animations within this SVG document fragment. Set
375 // for all outermost <svg> elements (not nested <svg> elements).
376 nsAutoPtr<nsSMILTimeContainer> mTimedDocumentRoot;
378 // zoom and pan
379 // IMPORTANT: see the comment in RecordCurrentScaleTranslate before writing
380 // code to change any of these!
381 SVGPoint mCurrentTranslate;
382 float mCurrentScale;
383 SVGPoint mPreviousTranslate;
384 float mPreviousScale;
386 // For outermost <svg> elements created from parsing, animation is started by
387 // the onload event in accordance with the SVG spec, but for <svg> elements
388 // created by script or promoted from inner <svg> to outermost <svg> we need
389 // to manually kick off animation when they are bound to the tree.
390 bool mStartAnimationOnBindToTree;
391 bool mImageNeedsTransformInvalidation;
392 bool mIsPaintingSVGImageElement;
393 bool mHasChildrenOnlyTransform;
394 bool mUseCurrentView;
397 } // namespace dom
399 // Helper class to automatically manage temporary changes to an SVG document's
400 // state for rendering purposes.
401 class MOZ_STACK_CLASS AutoSVGRenderingState
403 public:
404 AutoSVGRenderingState(const Maybe<SVGImageContext>& aSVGContext,
405 float aFrameTime,
406 dom::SVGSVGElement* aRootElem
407 MOZ_GUARD_OBJECT_NOTIFIER_PARAM)
408 : mHaveOverrides(aSVGContext.isSome() &&
409 aSVGContext->GetPreserveAspectRatio().isSome())
410 , mRootElem(aRootElem)
412 MOZ_GUARD_OBJECT_NOTIFIER_INIT;
413 MOZ_ASSERT(mRootElem, "No SVG node to manage?");
414 if (mHaveOverrides) {
415 // Override preserveAspectRatio in our helper document.
416 // XXXdholbert We should technically be overriding the helper doc's clip
417 // and overflow properties here, too. See bug 272288 comment 36.
418 mRootElem->SetImageOverridePreserveAspectRatio(
419 *aSVGContext->GetPreserveAspectRatio());
422 mOriginalTime = mRootElem->GetCurrentTime();
423 mRootElem->SetCurrentTime(aFrameTime); // Does nothing if there's no change.
426 ~AutoSVGRenderingState()
428 mRootElem->SetCurrentTime(mOriginalTime);
429 if (mHaveOverrides) {
430 mRootElem->ClearImageOverridePreserveAspectRatio();
434 private:
435 const bool mHaveOverrides;
436 float mOriginalTime;
437 const nsRefPtr<dom::SVGSVGElement> mRootElem;
438 MOZ_DECL_USE_GUARD_OBJECT_NOTIFIER
441 } // namespace mozilla
443 #endif // SVGSVGElement_h