1 /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ 2 /* This Source Code Form is subject to the terms of the Mozilla Public 3 * License, v. 2.0. If a copy of the MPL was not distributed with this 4 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ 5 6 #ifndef __NS_SVGMARKERFRAME_H__ 7 #define __NS_SVGMARKERFRAME_H__ 8 9 #include "mozilla/Attributes.h" 10 #include "gfxMatrix.h" 11 #include "gfxRect.h" 12 #include "nsFrame.h" 13 #include "nsLiteralString.h" 14 #include "nsQueryFrame.h" 15 #include "nsSVGContainerFrame.h" 16 #include "nsSVGUtils.h" 17 18 class gfxContext; 19 class nsSVGPathGeometryFrame; 20 21 namespace mozilla { 22 namespace dom { 23 class SVGSVGElement; 24 } // namespace dom 25 } // namespace mozilla 26 27 struct nsSVGMark; 28 29 class nsSVGMarkerFrame : public nsSVGContainerFrame 30 { 31 friend class nsSVGMarkerAnonChildFrame; 32 friend nsContainerFrame* 33 NS_NewSVGMarkerFrame(nsIPresShell* aPresShell, nsStyleContext* aContext); 34 protected: nsSVGMarkerFrame(nsStyleContext * aContext)35 explicit nsSVGMarkerFrame(nsStyleContext* aContext) 36 : nsSVGContainerFrame(aContext) 37 , mMarkedFrame(nullptr) 38 , mInUse(false) 39 , mInUse2(false) 40 { 41 AddStateBits(NS_FRAME_IS_NONDISPLAY); 42 } 43 44 public: 45 NS_DECL_FRAMEARENA_HELPERS 46 47 // nsIFrame interface: 48 #ifdef DEBUG 49 virtual void Init(nsIContent* aContent, 50 nsContainerFrame* aParent, 51 nsIFrame* aPrevInFlow) override; 52 #endif 53 BuildDisplayList(nsDisplayListBuilder * aBuilder,const nsRect & aDirtyRect,const nsDisplayListSet & aLists)54 virtual void BuildDisplayList(nsDisplayListBuilder* aBuilder, 55 const nsRect& aDirtyRect, 56 const nsDisplayListSet& aLists) override {} 57 58 virtual nsresult AttributeChanged(int32_t aNameSpaceID, 59 nsIAtom* aAttribute, 60 int32_t aModType) override; 61 /** 62 * Get the "type" of the frame 63 * 64 * @see nsGkAtoms::svgMarkerFrame 65 */ 66 virtual nsIAtom* GetType() const override; 67 68 #ifdef DEBUG_FRAME_DUMP GetFrameName(nsAString & aResult)69 virtual nsresult GetFrameName(nsAString& aResult) const override 70 { 71 return MakeFrameName(NS_LITERAL_STRING("SVGMarker"), aResult); 72 } 73 #endif 74 GetContentInsertionFrame()75 virtual nsContainerFrame* GetContentInsertionFrame() override { 76 // Any children must be added to our single anonymous inner frame kid. 77 MOZ_ASSERT(PrincipalChildList().FirstChild() && 78 PrincipalChildList().FirstChild()->GetType() == 79 nsGkAtoms::svgMarkerAnonChildFrame, 80 "Where is our anonymous child?"); 81 return PrincipalChildList().FirstChild()->GetContentInsertionFrame(); 82 } 83 84 // nsSVGMarkerFrame methods: 85 nsresult PaintMark(gfxContext& aContext, 86 const gfxMatrix& aToMarkedFrameUserSpace, 87 nsSVGPathGeometryFrame *aMarkedFrame, 88 nsSVGMark *aMark, 89 float aStrokeWidth); 90 91 SVGBBox GetMarkBBoxContribution(const Matrix &aToBBoxUserspace, 92 uint32_t aFlags, 93 nsSVGPathGeometryFrame *aMarkedFrame, 94 const nsSVGMark *aMark, 95 float aStrokeWidth); 96 97 private: 98 // stuff needed for callback 99 nsSVGPathGeometryFrame *mMarkedFrame; 100 float mStrokeWidth, mX, mY, mAutoAngle; 101 bool mIsStart; // whether the callback is for a marker-start marker 102 103 // nsSVGContainerFrame methods: 104 virtual 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 { 113 public: 114 AutoMarkerReferencer(nsSVGMarkerFrame *aFrame, 115 nsSVGPathGeometryFrame *aMarkedFrame 116 MOZ_GUARD_OBJECT_NOTIFIER_PARAM); 117 ~AutoMarkerReferencer(); 118 private: 119 nsSVGMarkerFrame *mFrame; 120 MOZ_DECL_USE_GUARD_OBJECT_NOTIFIER 121 }; 122 123 // nsSVGMarkerFrame methods: 124 void SetParentCoordCtxProvider(mozilla::dom::SVGSVGElement *aContext); 125 126 // recursion prevention flag 127 bool mInUse; 128 129 // second recursion prevention flag, for GetCanvasTM() 130 bool mInUse2; 131 }; 132 133 //////////////////////////////////////////////////////////////////////// 134 // nsMarkerAnonChildFrame class 135 136 class nsSVGMarkerAnonChildFrame : public nsSVGDisplayContainerFrame 137 { 138 friend nsContainerFrame* 139 NS_NewSVGMarkerAnonChildFrame(nsIPresShell* aPresShell, 140 nsStyleContext* aContext); 141 nsSVGMarkerAnonChildFrame(nsStyleContext * aContext)142 explicit nsSVGMarkerAnonChildFrame(nsStyleContext* aContext) 143 : nsSVGDisplayContainerFrame(aContext) 144 {} 145 146 public: 147 NS_DECL_FRAMEARENA_HELPERS 148 149 #ifdef DEBUG 150 virtual void Init(nsIContent* aContent, 151 nsContainerFrame* aParent, 152 nsIFrame* aPrevInFlow) override; 153 #endif 154 155 #ifdef DEBUG_FRAME_DUMP GetFrameName(nsAString & aResult)156 virtual nsresult GetFrameName(nsAString& aResult) const override { 157 return MakeFrameName(NS_LITERAL_STRING("SVGMarkerAnonChild"), aResult); 158 } 159 #endif 160 161 /** 162 * Get the "type" of the frame 163 * 164 * @see nsGkAtoms::svgMarkerAnonChildFrame 165 */ 166 virtual nsIAtom* GetType() const override; 167 168 // nsSVGContainerFrame methods: GetCanvasTM()169 virtual gfxMatrix GetCanvasTM() override 170 { 171 return static_cast<nsSVGMarkerFrame*>(GetParent())->GetCanvasTM(); 172 } 173 }; 174 #endif 175