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/. */
7 #ifndef LAYOUT_SVG_SVGOUTERSVGFRAME_H_
8 #define LAYOUT_SVG_SVGOUTERSVGFRAME_H_
10 #include "mozilla/Attributes.h"
11 #include "mozilla/ISVGSVGFrame.h"
12 #include "mozilla/SVGContainerFrame.h"
17 class AutoSVGViewHandler
;
18 class SVGFragmentIdentifier
;
20 } // namespace mozilla
22 nsContainerFrame
* NS_NewSVGOuterSVGFrame(mozilla::PresShell
* aPresShell
,
23 mozilla::ComputedStyle
* aStyle
);
24 nsContainerFrame
* NS_NewSVGOuterSVGAnonChildFrame(
25 mozilla::PresShell
* aPresShell
, mozilla::ComputedStyle
* aStyle
);
29 ////////////////////////////////////////////////////////////////////////
30 // SVGOuterSVGFrame class
32 class SVGOuterSVGFrame final
: public SVGDisplayContainerFrame
,
34 using imgDrawingParams
= image::imgDrawingParams
;
36 friend nsContainerFrame
* ::NS_NewSVGOuterSVGFrame(
37 mozilla::PresShell
* aPresShell
, ComputedStyle
* aStyle
);
38 friend class AutoSVGViewHandler
;
39 friend class SVGFragmentIdentifier
;
42 explicit SVGOuterSVGFrame(ComputedStyle
* aStyle
, nsPresContext
* aPresContext
);
46 NS_DECL_FRAMEARENA_HELPERS(SVGOuterSVGFrame
)
49 nscoord
GetMinISize(gfxContext
* aRenderingContext
) override
;
50 nscoord
GetPrefISize(gfxContext
* aRenderingContext
) override
;
52 IntrinsicSize
GetIntrinsicSize() override
;
53 AspectRatio
GetIntrinsicRatio() const override
;
55 SizeComputationResult
ComputeSize(
56 gfxContext
* aRenderingContext
, WritingMode aWritingMode
,
57 const LogicalSize
& aCBSize
, nscoord aAvailableISize
,
58 const LogicalSize
& aMargin
, const LogicalSize
& aBorderPadding
,
59 const mozilla::StyleSizeOverrides
& aSizeOverrides
,
60 ComputeSizeFlags aFlags
) override
;
62 void Reflow(nsPresContext
* aPresContext
, ReflowOutput
& aDesiredSize
,
63 const ReflowInput
& aReflowInput
,
64 nsReflowStatus
& aStatus
) override
;
66 void DidReflow(nsPresContext
* aPresContext
,
67 const ReflowInput
* aReflowInput
) override
;
69 void UnionChildOverflow(mozilla::OverflowAreas
& aOverflowAreas
) override
;
71 void BuildDisplayList(nsDisplayListBuilder
* aBuilder
,
72 const nsDisplayListSet
& aLists
) override
;
74 void Init(nsIContent
* aContent
, nsContainerFrame
* aParent
,
75 nsIFrame
* aPrevInFlow
) override
;
77 bool IsFrameOfType(uint32_t aFlags
) const override
{
78 return SVGDisplayContainerFrame::IsFrameOfType(
80 ~(eSupportsContainLayoutAndPaint
| eReplaced
| eReplacedSizing
));
83 #ifdef DEBUG_FRAME_DUMP
84 nsresult
GetFrameName(nsAString
& aResult
) const override
{
85 return MakeFrameName(u
"SVGOuterSVG"_ns
, aResult
);
89 void DidSetComputedStyle(ComputedStyle
* aOldComputedStyle
) override
;
91 void Destroy(DestroyContext
&) override
;
93 nsresult
AttributeChanged(int32_t aNameSpaceID
, nsAtom
* aAttribute
,
94 int32_t aModType
) override
;
96 nsContainerFrame
* GetContentInsertionFrame() override
{
97 // Any children must be added to our single anonymous inner frame kid.
99 PrincipalChildList().FirstChild() &&
100 PrincipalChildList().FirstChild()->IsSVGOuterSVGAnonChildFrame(),
101 "Where is our anonymous child?");
102 return PrincipalChildList().FirstChild()->GetContentInsertionFrame();
105 bool IsSVGTransformed(Matrix
* aOwnTransform
,
106 Matrix
* aFromParentTransform
) const override
;
108 // Return our anonymous box child.
109 void AppendDirectlyOwnedAnonBoxes(nsTArray
<OwnedAnonBox
>& aResult
) override
;
111 // ISVGSVGFrame interface:
112 void NotifyViewportOrTransformChanged(uint32_t aFlags
) override
;
114 // ISVGDisplayableFrame methods:
115 void PaintSVG(gfxContext
& aContext
, const gfxMatrix
& aTransform
,
116 imgDrawingParams
& aImgParams
) override
;
117 SVGBBox
GetBBoxContribution(const Matrix
& aToBBoxUserspace
,
118 uint32_t aFlags
) override
;
120 // SVGContainerFrame methods:
121 gfxMatrix
GetCanvasTM() override
;
123 bool HasChildrenOnlyTransform(Matrix
* aTransform
) const override
{
124 // Our anonymous wrapper child must claim our children-only transforms as
125 // its own so that our real children (the frames it wraps) are transformed
126 // by them, and we must pretend we don't have any children-only transforms
127 // so that our anonymous child is _not_ transformed by them.
132 * Return true only if the height is unspecified (defaulting to 100%) or else
133 * the height is explicitly set to a percentage value no greater than 100%.
135 bool VerticalScrollbarNotNeeded() const;
137 bool IsCallingReflowSVG() const { return mCallingReflowSVG
; }
140 /* Returns true if our content is the document element and our document is
141 * being used as an image.
143 bool IsRootOfImage();
144 float ComputeFullZoom() const;
146 void MaybeSendIntrinsicSizeAndRatioToEmbedder();
147 void MaybeSendIntrinsicSizeAndRatioToEmbedder(Maybe
<IntrinsicSize
>,
150 float mFullZoom
= 1.0f
;
152 bool mCallingReflowSVG
= false;
153 bool mIsRootContent
= false;
154 bool mIsInObjectOrEmbed
= false;
155 bool mIsInIframe
= false;
158 ////////////////////////////////////////////////////////////////////////
159 // SVGOuterSVGAnonChildFrame class
162 * SVGOuterSVGFrames have a single direct child that is an instance of this
163 * class, and which is used to wrap their real child frames. Such anonymous
164 * wrapper frames created from this class exist because SVG frames need their
165 * GetPosition() offset to be their offset relative to "user space" (in app
166 * units) so that they can play nicely with nsDisplayTransform. This is fine
167 * for all SVG frames except for direct children of an SVGOuterSVGFrame,
168 * since an SVGOuterSVGFrame can have CSS border and padding (unlike other
169 * SVG frames). The direct children can't include the offsets due to any such
170 * border/padding in their mRects since that would break nsDisplayTransform,
171 * but not including these offsets would break other parts of the Mozilla code
172 * that assume a frame's mRect contains its border-box-to-parent-border-box
173 * offset, in particular nsIFrame::GetOffsetTo and the functions that depend on
174 * it. Wrapping an SVGOuterSVGFrame's children in an instance of this class
175 * with its GetPosition() set to its SVGOuterSVGFrame's border/padding offset
176 * keeps both nsDisplayTransform and nsIFrame::GetOffsetTo happy.
178 * The reason that this class inherit from SVGDisplayContainerFrame rather
179 * than simply from nsContainerFrame is so that we can avoid having special
180 * handling for these inner wrappers in multiple parts of the SVG code. For
181 * example, the implementations of IsSVGTransformed and GetCanvasTM assume
182 * SVGContainerFrame instances all the way up to the SVGOuterSVGFrame.
184 class SVGOuterSVGAnonChildFrame final
: public SVGDisplayContainerFrame
{
185 friend nsContainerFrame
* ::NS_NewSVGOuterSVGAnonChildFrame(
186 mozilla::PresShell
* aPresShell
, ComputedStyle
* aStyle
);
188 explicit SVGOuterSVGAnonChildFrame(ComputedStyle
* aStyle
,
189 nsPresContext
* aPresContext
)
190 : SVGDisplayContainerFrame(aStyle
, aPresContext
, kClassID
) {}
193 NS_DECL_FRAMEARENA_HELPERS(SVGOuterSVGAnonChildFrame
)
196 void Init(nsIContent
* aContent
, nsContainerFrame
* aParent
,
197 nsIFrame
* aPrevInFlow
) override
;
200 void BuildDisplayList(nsDisplayListBuilder
* aBuilder
,
201 const nsDisplayListSet
& aLists
) override
;
203 #ifdef DEBUG_FRAME_DUMP
204 nsresult
GetFrameName(nsAString
& aResult
) const override
{
205 return MakeFrameName(u
"SVGOuterSVGAnonChild"_ns
, aResult
);
209 bool IsSVGTransformed(Matrix
* aOwnTransform
,
210 Matrix
* aFromParentTransform
) const override
;
212 // SVGContainerFrame methods:
213 gfxMatrix
GetCanvasTM() override
{
214 // GetCanvasTM returns the transform from an SVG frame to the frame's
215 // SVGOuterSVGFrame's content box, so we do not include any x/y offset
216 // set on us for any CSS border or padding on our SVGOuterSVGFrame.
217 return static_cast<SVGOuterSVGFrame
*>(GetParent())->GetCanvasTM();
221 } // namespace mozilla
223 #endif // LAYOUT_SVG_SVGOUTERSVGFRAME_H_