SVGGeometryFrame.h (6414B)
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_SVGGEOMETRYFRAME_H_ 8 #define LAYOUT_SVG_SVGGEOMETRYFRAME_H_ 9 10 #include "gfxMatrix.h" 11 #include "gfxRect.h" 12 #include "mozilla/DisplaySVGItem.h" 13 #include "mozilla/EnumSet.h" 14 #include "mozilla/ISVGDisplayableFrame.h" 15 #include "nsIFrame.h" 16 17 namespace mozilla { 18 19 class DisplaySVGGeometry; 20 class PresShell; 21 class SVGGeometryFrame; 22 class SVGMarkerObserver; 23 24 namespace gfx { 25 class DrawTarget; 26 } // namespace gfx 27 28 namespace image { 29 struct imgDrawingParams; 30 } // namespace image 31 32 } // namespace mozilla 33 34 class gfxContext; 35 class nsAtom; 36 class nsIFrame; 37 38 struct nsRect; 39 40 nsIFrame* NS_NewSVGGeometryFrame(mozilla::PresShell* aPresShell, 41 mozilla::ComputedStyle* aStyle); 42 43 namespace mozilla { 44 45 class SVGGeometryFrame final : public nsIFrame, public ISVGDisplayableFrame { 46 using DrawTarget = gfx::DrawTarget; 47 48 friend nsIFrame* ::NS_NewSVGGeometryFrame(mozilla::PresShell* aPresShell, 49 ComputedStyle* aStyle); 50 51 friend class DisplaySVGGeometry; 52 53 protected: 54 SVGGeometryFrame(ComputedStyle* aStyle, nsPresContext* aPresContext, 55 nsIFrame::ClassID aID = kClassID) 56 : nsIFrame(aStyle, aPresContext, aID) { 57 AddStateBits(NS_FRAME_SVG_LAYOUT | NS_FRAME_MAY_BE_TRANSFORMED); 58 } 59 60 public: 61 NS_DECL_QUERYFRAME 62 NS_DECL_FRAMEARENA_HELPERS(SVGGeometryFrame) 63 64 // nsIFrame interface: 65 void Init(nsIContent* aContent, nsContainerFrame* aParent, 66 nsIFrame* aPrevInFlow) override; 67 68 nsresult AttributeChanged(int32_t aNameSpaceID, nsAtom* aAttribute, 69 AttrModType aModType) override; 70 71 void DidSetComputedStyle(ComputedStyle* aOldComputedStyle) override; 72 73 bool DoGetParentSVGTransforms(Matrix*) const override; 74 75 #ifdef DEBUG_FRAME_DUMP 76 nsresult GetFrameName(nsAString& aResult) const override { 77 return MakeFrameName(u"SVGGeometry"_ns, aResult); 78 } 79 #endif 80 81 void BuildDisplayList(nsDisplayListBuilder* aBuilder, 82 const nsDisplayListSet& aLists) override; 83 84 // SVGGeometryFrame methods 85 gfxMatrix GetCanvasTM(); 86 87 bool IsInvisible() const; 88 89 private: 90 // ISVGDisplayableFrame interface: 91 void PaintSVG(gfxContext& aContext, const gfxMatrix& aTransform, 92 imgDrawingParams& aImgParams) override; 93 nsIFrame* GetFrameForPoint(const gfxPoint& aPoint) override; 94 void ReflowSVG() override; 95 void NotifySVGChanged(ChangeFlags aFlags) override; 96 SVGBBox GetBBoxContribution(const Matrix& aToBBoxUserspace, 97 uint32_t aFlags) override; 98 bool IsDisplayContainer() override { return false; } 99 100 enum class RenderFlag { Fill, Stroke }; 101 using RenderFlags = EnumSet<RenderFlag>; 102 void Render(gfxContext* aContext, RenderFlags aRenderComponents, 103 const gfxMatrix& aTransform, imgDrawingParams& aImgParams); 104 105 bool CreateWebRenderCommands( 106 mozilla::wr::DisplayListBuilder& aBuilder, 107 mozilla::wr::IpcResourceUpdateQueue& aResources, 108 const mozilla::layers::StackingContextHelper& aSc, 109 mozilla::layers::RenderRootStateManager* aManager, 110 nsDisplayListBuilder* aDisplayListBuilder, DisplaySVGGeometry* aItem, 111 bool aDryRun); 112 /** 113 * @param aMatrix The transform that must be multiplied onto aContext to 114 * establish this frame's SVG user space. 115 */ 116 void PaintMarkers(gfxContext& aContext, const gfxMatrix& aTransform, 117 imgDrawingParams& aImgParams); 118 119 /* 120 * Get the stroke width that markers should use, accounting for 121 * non-scaling stroke. 122 */ 123 float GetStrokeWidthForMarkers(); 124 }; 125 126 //---------------------------------------------------------------------- 127 // Display list item: 128 129 class DisplaySVGGeometry final : public DisplaySVGItem { 130 public: 131 DisplaySVGGeometry(nsDisplayListBuilder* aBuilder, SVGGeometryFrame* aFrame) 132 : DisplaySVGItem(aBuilder, aFrame) { 133 MOZ_COUNT_CTOR(DisplaySVGGeometry); 134 } 135 136 MOZ_COUNTED_DTOR_FINAL(DisplaySVGGeometry) 137 138 NS_DISPLAY_DECL_NAME("DisplaySVGGeometry", TYPE_SVG_GEOMETRY) 139 140 // Whether this part of the SVG should be natively handled by webrender, 141 // potentially becoming an "active layer" inside a blob image. 142 bool ShouldBeActive(mozilla::wr::DisplayListBuilder& aBuilder, 143 mozilla::wr::IpcResourceUpdateQueue& aResources, 144 const mozilla::layers::StackingContextHelper& aSc, 145 mozilla::layers::RenderRootStateManager* aManager, 146 nsDisplayListBuilder* aDisplayListBuilder) { 147 // We delegate this question to the parent frame to take advantage of 148 // the SVGGeometryFrame inheritance hierarchy which provides actual 149 // implementation details. The dryRun flag prevents serious side-effects. 150 auto* frame = static_cast<SVGGeometryFrame*>(mFrame); 151 return frame->CreateWebRenderCommands(aBuilder, aResources, aSc, aManager, 152 aDisplayListBuilder, this, 153 /*aDryRun=*/true); 154 } 155 156 bool CreateWebRenderCommands( 157 mozilla::wr::DisplayListBuilder& aBuilder, 158 mozilla::wr::IpcResourceUpdateQueue& aResources, 159 const mozilla::layers::StackingContextHelper& aSc, 160 mozilla::layers::RenderRootStateManager* aManager, 161 nsDisplayListBuilder* aDisplayListBuilder) override { 162 // We delegate this question to the parent frame to take advantage of 163 // the SVGGeometryFrame inheritance hierarchy which provides actual 164 // implementation details. 165 auto* frame = static_cast<SVGGeometryFrame*>(mFrame); 166 bool result = frame->CreateWebRenderCommands(aBuilder, aResources, aSc, 167 aManager, aDisplayListBuilder, 168 this, /*aDryRun=*/false); 169 MOZ_ASSERT(result, "ShouldBeActive inconsistent with CreateWRCommands?"); 170 return result; 171 } 172 173 bool IsInvisible() const override { 174 auto* frame = static_cast<SVGGeometryFrame*>(mFrame); 175 return frame->IsInvisible(); 176 } 177 }; 178 179 } // namespace mozilla 180 181 #endif // LAYOUT_SVG_SVGGEOMETRYFRAME_H_