SVGViewportElement.h (6163B)
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_SVGVIEWPORTELEMENT_H_ 8 #define DOM_SVG_SVGVIEWPORTELEMENT_H_ 9 10 #include "SVGAnimatedEnumeration.h" 11 #include "SVGAnimatedLength.h" 12 #include "SVGAnimatedPreserveAspectRatio.h" 13 #include "SVGAnimatedViewBox.h" 14 #include "SVGGraphicsElement.h" 15 #include "SVGPoint.h" 16 #include "SVGPreserveAspectRatio.h" 17 #include "nsIContentInlines.h" 18 19 namespace mozilla { 20 class AutoPreserveAspectRatioOverride; 21 class SVGOuterSVGFrame; 22 class SVGViewportFrame; 23 24 namespace dom { 25 class DOMSVGAnimatedPreserveAspectRatio; 26 class SVGAnimatedRect; 27 class SVGViewElement; 28 class SVGViewportElement; 29 30 class SVGViewportElement : public SVGGraphicsElement { 31 friend class mozilla::SVGOuterSVGFrame; 32 friend class mozilla::SVGViewportFrame; 33 34 protected: 35 explicit SVGViewportElement( 36 already_AddRefed<mozilla::dom::NodeInfo>&& aNodeInfo); 37 ~SVGViewportElement() = default; 38 39 public: 40 // nsIContent interface 41 NS_IMETHOD_(bool) IsAttributeMapped(const nsAtom* aAttribute) const override; 42 43 // SVGElement specializations: 44 gfxMatrix ChildToUserSpaceTransform() const override; 45 46 bool HasValidDimensions() const override; 47 48 // SVGViewportElement methods: 49 50 float GetLength(uint8_t aCtxType) const; 51 52 // public helpers: 53 54 /** 55 * Returns true if this element has a base/anim value for its "viewBox" 56 * attribute that defines a viewBox rectangle with finite values, or 57 * if there is a view element overriding this element's viewBox and it 58 * has a valid viewBox. 59 * 60 * Note that this does not check whether we need to synthesize a viewBox, 61 * so you must call ShouldSynthesizeViewBox() if you need to chck that too. 62 * 63 * Note also that this method does not pay attention to whether the width or 64 * height values of the viewBox rect are positive! 65 */ 66 bool HasViewBox() const { return GetViewBoxInternal().HasRect(); } 67 68 /** 69 * Returns true if we should synthesize a viewBox for ourselves (that is, if 70 * we're the root element in an image document, and we're not currently being 71 * painted for an <svg:image> element). 72 * 73 * Only call this method if HasViewBox() returns false. 74 */ 75 bool ShouldSynthesizeViewBox() const; 76 77 bool HasViewBoxOrSyntheticViewBox() const { 78 return HasViewBox() || ShouldSynthesizeViewBox(); 79 } 80 81 bool HasChildrenOnlyTransform() const { return mHasChildrenOnlyTransform; } 82 83 void UpdateHasChildrenOnlyTransform(); 84 85 enum class ChildrenOnlyTransformChangedFlag { DuringReflow }; 86 87 using ChildrenOnlyTransformChangedFlags = 88 EnumSet<ChildrenOnlyTransformChangedFlag>; 89 90 /** 91 * This method notifies the style system that the overflow rects of our 92 * immediate childrens' frames need to be updated. It is called by our own 93 * frame when changes (e.g. to currentScale) cause our children-only 94 * transform to change. 95 * 96 * The reason we have this method instead of overriding 97 * GetAttributeChangeHint is because we need to act on non-attribute (e.g. 98 * currentScale) changes in addition to attribute (e.g. viewBox) changes. 99 */ 100 void ChildrenOnlyTransformChanged( 101 ChildrenOnlyTransformChangedFlags aFlags = {}); 102 103 gfx::Matrix GetViewBoxTransform() const; 104 105 gfx::Size GetViewportSize() const { return mViewportSize; } 106 107 void SetViewportSize(const gfx::Size& aSize) { mViewportSize = aSize; } 108 109 /** 110 * Returns true if either this is an SVG <svg> element that is the child of 111 * another non-foreignObject SVG element, or this is a SVG <symbol> element 112 * that is the root of a use-element shadow tree. 113 */ 114 bool IsInner() const { 115 const nsIContent* parent = GetFlattenedTreeParent(); 116 return parent && parent->IsSVGElement() && 117 !parent->IsSVGElement(nsGkAtoms::foreignObject); 118 } 119 120 // WebIDL 121 already_AddRefed<SVGAnimatedRect> ViewBox(); 122 already_AddRefed<DOMSVGAnimatedPreserveAspectRatio> PreserveAspectRatio(); 123 SVGAnimatedViewBox* GetAnimatedViewBox() override; 124 125 protected: 126 // implementation helpers: 127 128 bool IsRootSVGSVGElement() const { 129 NS_ASSERTION((IsInUncomposedDoc() && !GetParent()) == 130 (OwnerDoc()->GetRootElement() == this), 131 "Can't determine if we're root"); 132 return !GetParent() && IsInUncomposedDoc() && IsSVGElement(nsGkAtoms::svg); 133 } 134 135 /** 136 * Returns the explicit or default preserveAspectRatio, unless we're 137 * synthesizing a viewBox, in which case it returns the "none" value. 138 */ 139 virtual SVGPreserveAspectRatio GetPreserveAspectRatioWithOverride() const { 140 return mPreserveAspectRatio.GetAnimValue(); 141 } 142 143 /** 144 * Returns the explicit viewBox rect, if specified, or else a synthesized 145 * viewBox, if appropriate, or else a viewBox matching the dimensions of the 146 * SVG viewport. 147 */ 148 SVGViewBox GetViewBoxWithSynthesis(float aViewportWidth, 149 float aViewportHeight) const; 150 151 enum { ATTR_X, ATTR_Y, ATTR_WIDTH, ATTR_HEIGHT }; 152 SVGAnimatedLength mLengthAttributes[4]; 153 static LengthInfo sLengthInfo[4]; 154 LengthAttributesInfo GetLengthInfo() override; 155 156 SVGAnimatedPreserveAspectRatio* GetAnimatedPreserveAspectRatio() override; 157 158 virtual const SVGAnimatedViewBox& GetViewBoxInternal() const { 159 return mViewBox; 160 } 161 SVGAnimatedViewBox mViewBox; 162 SVGAnimatedPreserveAspectRatio mPreserveAspectRatio; 163 164 // The size of the rectangular SVG viewport into which we render. This is 165 // not (necessarily) the same as the content area. See: 166 // 167 // http://www.w3.org/TR/SVG11/coords.html#ViewportSpace 168 // 169 // XXXjwatt Currently only used for outer <svg>, but maybe we could use -1 to 170 // flag this as an inner <svg> to save the overhead of GetCtx calls? 171 // XXXjwatt our frame should probably reset this when it's destroyed. 172 gfx::Size mViewportSize; 173 174 bool mHasChildrenOnlyTransform; 175 }; 176 177 } // namespace dom 178 179 } // namespace mozilla 180 181 #endif // DOM_SVG_SVGVIEWPORTELEMENT_H_