|
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 nsIAtom; |
|
19 class nsIContent; |
|
20 class nsIFrame; |
|
21 class nsIPresShell; |
|
22 class nsRenderingContext; |
|
23 class nsStyleContext; |
|
24 class nsSVGPathGeometryFrame; |
|
25 |
|
26 namespace mozilla { |
|
27 namespace dom { |
|
28 class SVGSVGElement; |
|
29 } |
|
30 } |
|
31 |
|
32 struct nsSVGMark; |
|
33 |
|
34 typedef nsSVGContainerFrame nsSVGMarkerFrameBase; |
|
35 |
|
36 class nsSVGMarkerFrame : public nsSVGMarkerFrameBase |
|
37 { |
|
38 friend class nsSVGMarkerAnonChildFrame; |
|
39 friend nsIFrame* |
|
40 NS_NewSVGMarkerFrame(nsIPresShell* aPresShell, nsStyleContext* aContext); |
|
41 protected: |
|
42 nsSVGMarkerFrame(nsStyleContext* aContext) |
|
43 : nsSVGMarkerFrameBase(aContext) |
|
44 , mMarkedFrame(nullptr) |
|
45 , mInUse(false) |
|
46 , mInUse2(false) |
|
47 { |
|
48 AddStateBits(NS_FRAME_IS_NONDISPLAY); |
|
49 } |
|
50 |
|
51 public: |
|
52 NS_DECL_FRAMEARENA_HELPERS |
|
53 |
|
54 // nsIFrame interface: |
|
55 #ifdef DEBUG |
|
56 virtual void Init(nsIContent* aContent, |
|
57 nsIFrame* aParent, |
|
58 nsIFrame* aPrevInFlow) MOZ_OVERRIDE; |
|
59 #endif |
|
60 |
|
61 virtual void BuildDisplayList(nsDisplayListBuilder* aBuilder, |
|
62 const nsRect& aDirtyRect, |
|
63 const nsDisplayListSet& aLists) MOZ_OVERRIDE {} |
|
64 |
|
65 virtual nsresult AttributeChanged(int32_t aNameSpaceID, |
|
66 nsIAtom* aAttribute, |
|
67 int32_t aModType) MOZ_OVERRIDE; |
|
68 /** |
|
69 * Get the "type" of the frame |
|
70 * |
|
71 * @see nsGkAtoms::svgMarkerFrame |
|
72 */ |
|
73 virtual nsIAtom* GetType() const MOZ_OVERRIDE; |
|
74 |
|
75 #ifdef DEBUG_FRAME_DUMP |
|
76 virtual nsresult GetFrameName(nsAString& aResult) const MOZ_OVERRIDE |
|
77 { |
|
78 return MakeFrameName(NS_LITERAL_STRING("SVGMarker"), aResult); |
|
79 } |
|
80 #endif |
|
81 |
|
82 virtual nsIFrame* GetContentInsertionFrame() MOZ_OVERRIDE { |
|
83 // Any children must be added to our single anonymous inner frame kid. |
|
84 NS_ABORT_IF_FALSE(GetFirstPrincipalChild() && |
|
85 GetFirstPrincipalChild()->GetType() == |
|
86 nsGkAtoms::svgMarkerAnonChildFrame, |
|
87 "Where is our anonymous child?"); |
|
88 return GetFirstPrincipalChild()->GetContentInsertionFrame(); |
|
89 } |
|
90 |
|
91 // nsSVGMarkerFrame methods: |
|
92 nsresult PaintMark(nsRenderingContext *aContext, |
|
93 nsSVGPathGeometryFrame *aMarkedFrame, |
|
94 nsSVGMark *aMark, |
|
95 float aStrokeWidth); |
|
96 |
|
97 SVGBBox GetMarkBBoxContribution(const Matrix &aToBBoxUserspace, |
|
98 uint32_t aFlags, |
|
99 nsSVGPathGeometryFrame *aMarkedFrame, |
|
100 const nsSVGMark *aMark, |
|
101 float aStrokeWidth); |
|
102 |
|
103 private: |
|
104 // stuff needed for callback |
|
105 nsSVGPathGeometryFrame *mMarkedFrame; |
|
106 float mStrokeWidth, mX, mY, mAutoAngle; |
|
107 bool mIsStart; // whether the callback is for a marker-start marker |
|
108 |
|
109 // nsSVGContainerFrame methods: |
|
110 virtual gfxMatrix GetCanvasTM(uint32_t aFor, |
|
111 nsIFrame* aTransformRoot = nullptr) MOZ_OVERRIDE; |
|
112 |
|
113 // A helper class to allow us to paint markers safely. The helper |
|
114 // automatically sets and clears the mInUse flag on the marker frame (to |
|
115 // prevent nasty reference loops) as well as the reference to the marked |
|
116 // frame and its coordinate context. It's easy to mess this up |
|
117 // and break things, so this helper makes the code far more robust. |
|
118 class MOZ_STACK_CLASS AutoMarkerReferencer |
|
119 { |
|
120 public: |
|
121 AutoMarkerReferencer(nsSVGMarkerFrame *aFrame, |
|
122 nsSVGPathGeometryFrame *aMarkedFrame |
|
123 MOZ_GUARD_OBJECT_NOTIFIER_PARAM); |
|
124 ~AutoMarkerReferencer(); |
|
125 private: |
|
126 nsSVGMarkerFrame *mFrame; |
|
127 MOZ_DECL_USE_GUARD_OBJECT_NOTIFIER |
|
128 }; |
|
129 |
|
130 // nsSVGMarkerFrame methods: |
|
131 void SetParentCoordCtxProvider(mozilla::dom::SVGSVGElement *aContext); |
|
132 |
|
133 // recursion prevention flag |
|
134 bool mInUse; |
|
135 |
|
136 // second recursion prevention flag, for GetCanvasTM() |
|
137 bool mInUse2; |
|
138 }; |
|
139 |
|
140 //////////////////////////////////////////////////////////////////////// |
|
141 // nsMarkerAnonChildFrame class |
|
142 |
|
143 typedef nsSVGDisplayContainerFrame nsSVGMarkerAnonChildFrameBase; |
|
144 |
|
145 /** |
|
146 */ |
|
147 class nsSVGMarkerAnonChildFrame |
|
148 : public nsSVGMarkerAnonChildFrameBase |
|
149 { |
|
150 friend nsIFrame* |
|
151 NS_NewSVGMarkerAnonChildFrame(nsIPresShell* aPresShell, |
|
152 nsStyleContext* aContext); |
|
153 |
|
154 nsSVGMarkerAnonChildFrame(nsStyleContext* aContext) |
|
155 : nsSVGMarkerAnonChildFrameBase(aContext) |
|
156 {} |
|
157 |
|
158 public: |
|
159 NS_DECL_FRAMEARENA_HELPERS |
|
160 |
|
161 #ifdef DEBUG |
|
162 virtual void Init(nsIContent* aContent, |
|
163 nsIFrame* aParent, |
|
164 nsIFrame* aPrevInFlow) MOZ_OVERRIDE; |
|
165 #endif |
|
166 |
|
167 #ifdef DEBUG_FRAME_DUMP |
|
168 virtual nsresult GetFrameName(nsAString& aResult) const MOZ_OVERRIDE { |
|
169 return MakeFrameName(NS_LITERAL_STRING("SVGMarkerAnonChild"), aResult); |
|
170 } |
|
171 #endif |
|
172 |
|
173 /** |
|
174 * Get the "type" of the frame |
|
175 * |
|
176 * @see nsGkAtoms::svgMarkerAnonChildFrame |
|
177 */ |
|
178 virtual nsIAtom* GetType() const MOZ_OVERRIDE; |
|
179 |
|
180 // nsSVGContainerFrame methods: |
|
181 virtual gfxMatrix GetCanvasTM(uint32_t aFor, |
|
182 nsIFrame* aTransformRoot = nullptr) MOZ_OVERRIDE |
|
183 { |
|
184 nsSVGMarkerFrame* marker = static_cast<nsSVGMarkerFrame*>(mParent); |
|
185 return marker->GetCanvasTM(aFor, aTransformRoot); |
|
186 } |
|
187 }; |
|
188 #endif |