SVGMarkerFrame.h (5303B)
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_SVGMARKERFRAME_H_ 8 #define LAYOUT_SVG_SVGMARKERFRAME_H_ 9 10 #include "gfxMatrix.h" 11 #include "gfxRect.h" 12 #include "mozilla/Attributes.h" 13 #include "mozilla/SVGContainerFrame.h" 14 #include "nsIFrame.h" 15 #include "nsLiteralString.h" 16 #include "nsQueryFrame.h" 17 18 class gfxContext; 19 20 namespace mozilla { 21 22 class PresShell; 23 class SVGGeometryFrame; 24 25 struct SVGMark; 26 27 namespace dom { 28 class SVGViewportElement; 29 } // namespace dom 30 } // namespace mozilla 31 32 nsContainerFrame* NS_NewSVGMarkerFrame(mozilla::PresShell* aPresShell, 33 mozilla::ComputedStyle* aStyle); 34 nsContainerFrame* NS_NewSVGMarkerAnonChildFrame(mozilla::PresShell* aPresShell, 35 mozilla::ComputedStyle* aStyle); 36 37 namespace mozilla { 38 39 class SVGMarkerFrame final : public SVGContainerFrame { 40 using imgDrawingParams = image::imgDrawingParams; 41 42 friend class SVGMarkerAnonChildFrame; 43 friend nsContainerFrame* ::NS_NewSVGMarkerFrame( 44 mozilla::PresShell* aPresShell, ComputedStyle* aStyle); 45 46 protected: 47 explicit SVGMarkerFrame(ComputedStyle* aStyle, nsPresContext* aPresContext) 48 : SVGContainerFrame(aStyle, aPresContext, kClassID), 49 mMarkedFrame(nullptr), 50 mInUse(false), 51 mInUse2(false) { 52 AddStateBits(NS_FRAME_IS_NONDISPLAY); 53 } 54 55 public: 56 NS_DECL_FRAMEARENA_HELPERS(SVGMarkerFrame) 57 58 // nsIFrame interface: 59 #ifdef DEBUG 60 void Init(nsIContent* aContent, nsContainerFrame* aParent, 61 nsIFrame* aPrevInFlow) override; 62 #endif 63 64 void BuildDisplayList(nsDisplayListBuilder* aBuilder, 65 const nsDisplayListSet& aLists) override {} 66 67 nsresult AttributeChanged(int32_t aNameSpaceID, nsAtom* aAttribute, 68 AttrModType aModType) override; 69 70 #ifdef DEBUG_FRAME_DUMP 71 nsresult GetFrameName(nsAString& aResult) const override { 72 return MakeFrameName(u"SVGMarker"_ns, aResult); 73 } 74 #endif 75 76 nsContainerFrame* GetContentInsertionFrame() override { 77 // Any children must be added to our single anonymous inner frame kid. 78 MOZ_ASSERT( 79 PrincipalChildList().FirstChild() && 80 PrincipalChildList().FirstChild()->IsSVGMarkerAnonChildFrame(), 81 "Where is our anonymous child?"); 82 return PrincipalChildList().FirstChild()->GetContentInsertionFrame(); 83 } 84 85 // SVGMarkerFrame methods: 86 void PaintMark(gfxContext& aContext, const gfxMatrix& aToMarkedFrameUserSpace, 87 SVGGeometryFrame* aMarkedFrame, const SVGMark& aMark, 88 float aStrokeWidth, imgDrawingParams& aImgParams); 89 90 SVGBBox GetMarkBBoxContribution(const Matrix& aToBBoxUserspace, 91 uint32_t aFlags, 92 SVGGeometryFrame* aMarkedFrame, 93 const SVGMark& aMark, float aStrokeWidth); 94 95 // Return our anonymous box child. 96 void AppendDirectlyOwnedAnonBoxes(nsTArray<OwnedAnonBox>& aResult) override; 97 98 private: 99 // stuff needed for callback 100 SVGGeometryFrame* mMarkedFrame; 101 Matrix mMarkerTM; 102 103 // SVGContainerFrame methods: 104 gfxMatrix GetCanvasTM() override; 105 106 // A helper class to allow us to paint markers safely. The helper 107 // automatically sets and clears the mInUse flag on the marker frame (to 108 // prevent nasty reference loops) as well as the reference to the marked 109 // frame and its coordinate context. It's easy to mess this up 110 // and break things, so this helper makes the code far more robust. 111 class MOZ_RAII AutoMarkerReferencer { 112 public: 113 AutoMarkerReferencer(SVGMarkerFrame* aFrame, 114 SVGGeometryFrame* aMarkedFrame); 115 ~AutoMarkerReferencer(); 116 117 private: 118 SVGMarkerFrame* mFrame; 119 }; 120 121 // SVGMarkerFrame methods: 122 void SetParentCoordCtxProvider(dom::SVGViewportElement* aContext); 123 124 // recursion prevention flag 125 bool mInUse; 126 127 // second recursion prevention flag, for GetCanvasTM() 128 bool mInUse2; 129 }; 130 131 //////////////////////////////////////////////////////////////////////// 132 // nsMarkerAnonChildFrame class 133 134 class SVGMarkerAnonChildFrame final : public SVGDisplayContainerFrame { 135 friend nsContainerFrame* ::NS_NewSVGMarkerAnonChildFrame( 136 mozilla::PresShell* aPresShell, ComputedStyle* aStyle); 137 138 explicit SVGMarkerAnonChildFrame(ComputedStyle* aStyle, 139 nsPresContext* aPresContext) 140 : SVGDisplayContainerFrame(aStyle, aPresContext, kClassID) {} 141 142 public: 143 NS_DECL_FRAMEARENA_HELPERS(SVGMarkerAnonChildFrame) 144 145 #ifdef DEBUG 146 void Init(nsIContent* aContent, nsContainerFrame* aParent, 147 nsIFrame* aPrevInFlow) override; 148 #endif 149 150 #ifdef DEBUG_FRAME_DUMP 151 nsresult GetFrameName(nsAString& aResult) const override { 152 return MakeFrameName(u"SVGMarkerAnonChild"_ns, aResult); 153 } 154 #endif 155 156 // SVGContainerFrame methods: 157 gfxMatrix GetCanvasTM() override { 158 return static_cast<SVGMarkerFrame*>(GetParent())->GetCanvasTM(); 159 } 160 }; 161 162 } // namespace mozilla 163 164 #endif // LAYOUT_SVG_SVGMARKERFRAME_H_