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