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