SVGImageFrame.h (6514B)
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 LAYOUT_SVG_SVGIMAGEFRAME_H_ 8 #define LAYOUT_SVG_SVGIMAGEFRAME_H_ 9 10 // Keep in (case-insensitive) order: 11 #include "gfxContext.h" 12 #include "gfxPlatform.h" 13 #include "imgIContainer.h" 14 #include "imgINotificationObserver.h" 15 #include "mozilla/DisplaySVGItem.h" 16 #include "mozilla/ISVGDisplayableFrame.h" 17 #include "mozilla/gfx/2D.h" 18 #include "nsContainerFrame.h" 19 #include "nsIReflowCallback.h" 20 21 namespace mozilla { 22 class DisplaySVGImage; 23 class PresShell; 24 } // namespace mozilla 25 26 nsIFrame* NS_NewSVGImageFrame(mozilla::PresShell* aPresShell, 27 mozilla::ComputedStyle* aStyle); 28 29 namespace mozilla { 30 31 class SVGImageFrame final : public nsIFrame, 32 public ISVGDisplayableFrame, 33 public nsIReflowCallback { 34 friend nsIFrame* ::NS_NewSVGImageFrame(mozilla::PresShell* aPresShell, 35 ComputedStyle* aStyle); 36 37 friend class DisplaySVGImage; 38 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); 45 46 private: 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(); 53 } 54 55 virtual ~SVGImageFrame(); 56 57 public: 58 NS_DECL_QUERYFRAME 59 NS_DECL_FRAMEARENA_HELPERS(SVGImageFrame) 60 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(ChangeFlags aFlags) override; 67 SVGBBox GetBBoxContribution(const Matrix& aToBBoxUserspace, 68 uint32_t aFlags) override; 69 bool IsDisplayContainer() override { return false; } 70 71 // nsIFrame interface: 72 void BuildDisplayList(nsDisplayListBuilder* aBuilder, 73 const nsDisplayListSet& aLists) override; 74 75 nsresult AttributeChanged(int32_t aNameSpaceID, nsAtom* aAttribute, 76 AttrModType aModType) override; 77 78 void OnVisibilityChange( 79 Visibility aNewVisibility, 80 const Maybe<OnNonvisible>& aNonvisibleAction = Nothing()) override; 81 82 void Init(nsIContent* aContent, nsContainerFrame* aParent, 83 nsIFrame* aPrevInFlow) override; 84 void Destroy(DestroyContext&) override; 85 86 void DidSetComputedStyle(ComputedStyle* aOldStyle) final; 87 88 bool DoGetParentSVGTransforms(Matrix*) const override; 89 90 bool GetIntrinsicImageDimensions(gfx::Size& aSize, 91 AspectRatio& aAspectRatio) const; 92 93 #ifdef DEBUG_FRAME_DUMP 94 nsresult GetFrameName(nsAString& aResult) const override { 95 return MakeFrameName(u"SVGImage"_ns, aResult); 96 } 97 #endif 98 99 // nsIReflowCallback 100 bool ReflowFinished() override; 101 void ReflowCallbackCanceled() override; 102 103 /// Always sync decode our image when painting if @aForce is true. 104 void SetForceSyncDecoding(bool aForce) { mForceSyncDecoding = aForce; } 105 106 // SVGImageFrame methods: 107 bool IsInvisible() const; 108 109 private: 110 bool IgnoreHitTest() const; 111 112 already_AddRefed<imgIRequest> GetCurrentRequest() const; 113 114 gfx::Matrix GetRasterImageTransform(int32_t aNativeWidth, 115 int32_t aNativeHeight); 116 gfx::Matrix GetVectorImageTransform(); 117 bool TransformContextForPainting(gfxContext* aGfxContext, 118 const gfxMatrix& aTransform); 119 120 nsCOMPtr<imgINotificationObserver> mListener; 121 122 nsCOMPtr<imgIContainer> mImageContainer; 123 124 bool mReflowCallbackPosted; 125 bool mForceSyncDecoding; 126 127 friend class SVGImageListener; 128 }; 129 130 //---------------------------------------------------------------------- 131 // Display list item: 132 133 class DisplaySVGImage final : public DisplaySVGItem { 134 public: 135 DisplaySVGImage(nsDisplayListBuilder* aBuilder, SVGImageFrame* aFrame) 136 : DisplaySVGItem(aBuilder, aFrame) { 137 MOZ_COUNT_CTOR(DisplaySVGImage); 138 } 139 140 MOZ_COUNTED_DTOR_FINAL(DisplaySVGImage) 141 142 NS_DISPLAY_DECL_NAME("DisplaySVGImage", TYPE_SVG_IMAGE) 143 144 // Whether this part of the SVG should be natively handled by webrender, 145 // potentially becoming an "active layer" inside a blob image. 146 bool ShouldBeActive(mozilla::wr::DisplayListBuilder& aBuilder, 147 mozilla::wr::IpcResourceUpdateQueue& aResources, 148 const mozilla::layers::StackingContextHelper& aSc, 149 mozilla::layers::RenderRootStateManager* aManager, 150 nsDisplayListBuilder* aDisplayListBuilder) { 151 auto* frame = static_cast<SVGImageFrame*>(mFrame); 152 return frame->CreateWebRenderCommands(aBuilder, aResources, aSc, aManager, 153 aDisplayListBuilder, this, 154 /*aDryRun=*/true); 155 } 156 157 bool CreateWebRenderCommands( 158 mozilla::wr::DisplayListBuilder& aBuilder, 159 mozilla::wr::IpcResourceUpdateQueue& aResources, 160 const mozilla::layers::StackingContextHelper& aSc, 161 mozilla::layers::RenderRootStateManager* aManager, 162 nsDisplayListBuilder* aDisplayListBuilder) override { 163 auto* frame = static_cast<SVGImageFrame*>(mFrame); 164 bool result = frame->CreateWebRenderCommands(aBuilder, aResources, aSc, 165 aManager, aDisplayListBuilder, 166 this, /*aDryRun=*/false); 167 MOZ_ASSERT(result, "ShouldBeActive inconsistent with CreateWRCommands?"); 168 return result; 169 } 170 171 bool IsInvisible() const override { 172 auto* frame = static_cast<SVGImageFrame*>(mFrame); 173 return frame->IsInvisible(); 174 } 175 }; 176 177 } // namespace mozilla 178 179 #endif // LAYOUT_SVG_SVGIMAGEFRAME_H_