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_SVGIMAGEFRAME_H_
8 #define LAYOUT_SVG_SVGIMAGEFRAME_H_
10 // Keep in (case-insensitive) order:
11 #include "mozilla/gfx/2D.h"
12 #include "mozilla/DisplaySVGItem.h"
13 #include "mozilla/ISVGDisplayableFrame.h"
14 #include "gfxContext.h"
15 #include "gfxPlatform.h"
16 #include "imgIContainer.h"
17 #include "nsContainerFrame.h"
18 #include "imgINotificationObserver.h"
19 #include "nsIReflowCallback.h"
22 class DisplaySVGImage
;
24 } // namespace mozilla
26 nsIFrame
* NS_NewSVGImageFrame(mozilla::PresShell
* aPresShell
,
27 mozilla::ComputedStyle
* aStyle
);
31 class SVGImageFrame final
: public nsIFrame
,
32 public ISVGDisplayableFrame
,
33 public nsIReflowCallback
{
34 friend nsIFrame
* ::NS_NewSVGImageFrame(mozilla::PresShell
* aPresShell
,
35 ComputedStyle
* aStyle
);
37 friend class DisplaySVGImage
;
39 bool CreateWebRenderCommands(wr::DisplayListBuilder
& aBuilder
,
40 wr::IpcResourceUpdateQueue
& aResources
,
41 const layers::StackingContextHelper
& aSc
,
42 layers::RenderRootStateManager
* aManager
,
43 nsDisplayListBuilder
* aDisplayListBuilder
,
44 DisplaySVGImage
* aItem
, bool aDryRun
);
47 explicit SVGImageFrame(ComputedStyle
* aStyle
, nsPresContext
* aPresContext
)
48 : nsIFrame(aStyle
, aPresContext
, kClassID
),
49 mReflowCallbackPosted(false),
50 mForceSyncDecoding(false) {
51 AddStateBits(NS_FRAME_SVG_LAYOUT
| NS_FRAME_MAY_BE_TRANSFORMED
);
52 EnableVisibilityTracking();
55 virtual ~SVGImageFrame();
59 NS_DECL_FRAMEARENA_HELPERS(SVGImageFrame
)
61 // ISVGDisplayableFrame interface:
62 void PaintSVG(gfxContext
& aContext
, const gfxMatrix
& aTransform
,
63 imgDrawingParams
& aImgParams
) override
;
64 nsIFrame
* GetFrameForPoint(const gfxPoint
& aPoint
) override
;
65 void ReflowSVG() override
;
66 void NotifySVGChanged(uint32_t aFlags
) override
;
67 SVGBBox
GetBBoxContribution(const Matrix
& aToBBoxUserspace
,
68 uint32_t aFlags
) override
;
69 bool IsDisplayContainer() override
{ return false; }
71 // nsIFrame interface:
72 void BuildDisplayList(nsDisplayListBuilder
* aBuilder
,
73 const nsDisplayListSet
& aLists
) override
;
75 nsresult
AttributeChanged(int32_t aNameSpaceID
, nsAtom
* aAttribute
,
76 int32_t aModType
) override
;
78 void OnVisibilityChange(
79 Visibility aNewVisibility
,
80 const Maybe
<OnNonvisible
>& aNonvisibleAction
= Nothing()) override
;
82 void Init(nsIContent
* aContent
, nsContainerFrame
* aParent
,
83 nsIFrame
* aPrevInFlow
) override
;
84 void Destroy(DestroyContext
&) override
;
86 void DidSetComputedStyle(ComputedStyle
* aOldStyle
) final
;
88 bool IsSVGTransformed(Matrix
* aOwnTransforms
= nullptr,
89 Matrix
* aFromParentTransforms
= nullptr) const override
;
91 bool GetIntrinsicImageDimensions(gfx::Size
& aSize
,
92 AspectRatio
& aAspectRatio
) const;
94 #ifdef DEBUG_FRAME_DUMP
95 nsresult
GetFrameName(nsAString
& aResult
) const override
{
96 return MakeFrameName(u
"SVGImage"_ns
, aResult
);
101 bool ReflowFinished() override
;
102 void ReflowCallbackCanceled() override
;
104 /// Always sync decode our image when painting if @aForce is true.
105 void SetForceSyncDecoding(bool aForce
) { mForceSyncDecoding
= aForce
; }
107 // SVGImageFrame methods:
108 bool IsInvisible() const;
111 bool IgnoreHitTest() const;
113 already_AddRefed
<imgIRequest
> GetCurrentRequest() const;
115 gfx::Matrix
GetRasterImageTransform(int32_t aNativeWidth
,
116 int32_t aNativeHeight
);
117 gfx::Matrix
GetVectorImageTransform();
118 bool TransformContextForPainting(gfxContext
* aGfxContext
,
119 const gfxMatrix
& aTransform
);
121 nsCOMPtr
<imgINotificationObserver
> mListener
;
123 nsCOMPtr
<imgIContainer
> mImageContainer
;
125 bool mReflowCallbackPosted
;
126 bool mForceSyncDecoding
;
128 friend class SVGImageListener
;
131 //----------------------------------------------------------------------
132 // Display list item:
134 class DisplaySVGImage final
: public DisplaySVGItem
{
136 DisplaySVGImage(nsDisplayListBuilder
* aBuilder
, SVGImageFrame
* aFrame
)
137 : DisplaySVGItem(aBuilder
, aFrame
) {
138 MOZ_COUNT_CTOR(DisplaySVGImage
);
141 MOZ_COUNTED_DTOR_OVERRIDE(DisplaySVGImage
)
143 NS_DISPLAY_DECL_NAME("DisplaySVGImage", TYPE_SVG_IMAGE
)
145 // Whether this part of the SVG should be natively handled by webrender,
146 // potentially becoming an "active layer" inside a blob image.
147 bool ShouldBeActive(mozilla::wr::DisplayListBuilder
& aBuilder
,
148 mozilla::wr::IpcResourceUpdateQueue
& aResources
,
149 const mozilla::layers::StackingContextHelper
& aSc
,
150 mozilla::layers::RenderRootStateManager
* aManager
,
151 nsDisplayListBuilder
* aDisplayListBuilder
) {
152 auto* frame
= static_cast<SVGImageFrame
*>(mFrame
);
153 return frame
->CreateWebRenderCommands(aBuilder
, aResources
, aSc
, aManager
,
154 aDisplayListBuilder
, this,
158 bool CreateWebRenderCommands(
159 mozilla::wr::DisplayListBuilder
& aBuilder
,
160 mozilla::wr::IpcResourceUpdateQueue
& aResources
,
161 const mozilla::layers::StackingContextHelper
& aSc
,
162 mozilla::layers::RenderRootStateManager
* aManager
,
163 nsDisplayListBuilder
* aDisplayListBuilder
) override
{
164 auto* frame
= static_cast<SVGImageFrame
*>(mFrame
);
165 bool result
= frame
->CreateWebRenderCommands(aBuilder
, aResources
, aSc
,
166 aManager
, aDisplayListBuilder
,
167 this, /*aDryRun=*/false);
168 MOZ_ASSERT(result
, "ShouldBeActive inconsistent with CreateWRCommands?");
172 bool IsInvisible() const override
{
173 auto* frame
= static_cast<SVGImageFrame
*>(mFrame
);
174 return frame
->IsInvisible();
178 } // namespace mozilla
180 #endif // LAYOUT_SVG_SVGIMAGEFRAME_H_