Line data Source code
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 : /* rendering object for CSS display:inline objects */
7 :
8 : #ifndef nsInlineFrame_h___
9 : #define nsInlineFrame_h___
10 :
11 : #include "mozilla/Attributes.h"
12 : #include "nsContainerFrame.h"
13 :
14 : class nsLineLayout;
15 :
16 : /**
17 : * Inline frame class.
18 : *
19 : * This class manages a list of child frames that are inline frames. Working with
20 : * nsLineLayout, the class will reflow and place inline frames on a line.
21 : */
22 0 : class nsInlineFrame : public nsContainerFrame
23 : {
24 : public:
25 : NS_DECL_QUERYFRAME
26 0 : NS_DECL_FRAMEARENA_HELPERS(nsInlineFrame)
27 :
28 : friend nsInlineFrame* NS_NewInlineFrame(nsIPresShell* aPresShell,
29 : nsStyleContext* aContext);
30 :
31 : // nsIFrame overrides
32 : virtual void BuildDisplayList(nsDisplayListBuilder* aBuilder,
33 : const nsRect& aDirtyRect,
34 : const nsDisplayListSet& aLists) override;
35 :
36 : #ifdef ACCESSIBILITY
37 : virtual mozilla::a11y::AccType AccessibleType() override;
38 : #endif
39 :
40 : #ifdef DEBUG_FRAME_DUMP
41 : virtual nsresult GetFrameName(nsAString& aResult) const override;
42 : #endif
43 :
44 0 : virtual bool IsFrameOfType(uint32_t aFlags) const override
45 : {
46 0 : if (aFlags & eSupportsCSSTransforms) {
47 0 : return false;
48 : }
49 0 : return nsContainerFrame::IsFrameOfType(aFlags &
50 0 : ~(nsIFrame::eBidiInlineContainer | nsIFrame::eLineParticipant));
51 : }
52 :
53 : virtual void InvalidateFrame(uint32_t aDisplayItemKey = 0) override;
54 : virtual void InvalidateFrameWithRect(const nsRect& aRect, uint32_t aDisplayItemKey = 0) override;
55 :
56 : virtual bool IsEmpty() override;
57 : virtual bool IsSelfEmpty() override;
58 :
59 : virtual FrameSearchResult
60 : PeekOffsetCharacter(bool aForward, int32_t* aOffset,
61 : PeekOffsetCharacterOptions aOptions =
62 : PeekOffsetCharacterOptions()) override;
63 :
64 : virtual void DestroyFrom(nsIFrame* aDestructRoot) override;
65 : virtual nsresult StealFrame(nsIFrame* aChild) override;
66 :
67 : // nsIHTMLReflow overrides
68 : virtual void AddInlineMinISize(gfxContext *aRenderingContext,
69 : InlineMinISizeData *aData) override;
70 : virtual void AddInlinePrefISize(gfxContext *aRenderingContext,
71 : InlinePrefISizeData *aData) override;
72 : virtual mozilla::LogicalSize
73 : ComputeSize(gfxContext *aRenderingContext,
74 : mozilla::WritingMode aWritingMode,
75 : const mozilla::LogicalSize& aCBSize,
76 : nscoord aAvailableISize,
77 : const mozilla::LogicalSize& aMargin,
78 : const mozilla::LogicalSize& aBorder,
79 : const mozilla::LogicalSize& aPadding,
80 : ComputeSizeFlags aFlags) override;
81 : virtual nsRect ComputeTightBounds(DrawTarget* aDrawTarget) const override;
82 : virtual void Reflow(nsPresContext* aPresContext,
83 : ReflowOutput& aDesiredSize,
84 : const ReflowInput& aReflowInput,
85 : nsReflowStatus& aStatus) override;
86 :
87 : virtual nsresult AttributeChanged(int32_t aNameSpaceID,
88 : nsIAtom* aAttribute,
89 : int32_t aModType) override;
90 :
91 : virtual bool CanContinueTextRun() const override;
92 :
93 : virtual void PullOverflowsFromPrevInFlow() override;
94 : virtual nscoord GetLogicalBaseline(mozilla::WritingMode aWritingMode) const override;
95 : virtual bool DrainSelfOverflowList() override;
96 :
97 : /**
98 : * Return true if the frame is first visual frame or first continuation
99 : */
100 0 : bool IsFirst() const {
101 : // If the frame's bidi visual state is set, return is-first state
102 : // else return true if it's the first continuation.
103 0 : return (GetStateBits() & NS_INLINE_FRAME_BIDI_VISUAL_STATE_IS_SET)
104 0 : ? !!(GetStateBits() & NS_INLINE_FRAME_BIDI_VISUAL_IS_FIRST)
105 0 : : (!GetPrevInFlow());
106 : }
107 :
108 : /**
109 : * Return true if the frame is last visual frame or last continuation.
110 : */
111 0 : bool IsLast() const {
112 : // If the frame's bidi visual state is set, return is-last state
113 : // else return true if it's the last continuation.
114 0 : return (GetStateBits() & NS_INLINE_FRAME_BIDI_VISUAL_STATE_IS_SET)
115 0 : ? !!(GetStateBits() & NS_INLINE_FRAME_BIDI_VISUAL_IS_LAST)
116 0 : : (!GetNextInFlow());
117 : }
118 :
119 : // Restyles the block wrappers around our non-inline-outside kids.
120 : // This will only be called when such wrappers in fact exist.
121 : void UpdateStyleOfOwnedAnonBoxesForIBSplit(
122 : mozilla::ServoRestyleState& aRestyleState);
123 :
124 : protected:
125 : // Additional reflow state used during our reflow methods
126 : struct InlineReflowInput {
127 : nsIFrame* mPrevFrame;
128 : nsInlineFrame* mNextInFlow;
129 : nsIFrame* mLineContainer;
130 : nsLineLayout* mLineLayout;
131 : bool mSetParentPointer; // when reflowing child frame first set its
132 : // parent frame pointer
133 :
134 0 : InlineReflowInput() {
135 0 : mPrevFrame = nullptr;
136 0 : mNextInFlow = nullptr;
137 0 : mLineContainer = nullptr;
138 0 : mLineLayout = nullptr;
139 0 : mSetParentPointer = false;
140 0 : }
141 : };
142 :
143 0 : nsInlineFrame(nsStyleContext* aContext, ClassID aID)
144 0 : : nsContainerFrame(aContext, aID)
145 0 : , mBaseline(NS_INTRINSIC_WIDTH_UNKNOWN)
146 0 : {}
147 :
148 : virtual LogicalSides GetLogicalSkipSides(const ReflowInput* aReflowInput = nullptr) const override;
149 :
150 : void ReflowFrames(nsPresContext* aPresContext,
151 : const ReflowInput& aReflowInput,
152 : InlineReflowInput& rs,
153 : ReflowOutput& aMetrics,
154 : nsReflowStatus& aStatus);
155 :
156 : void ReflowInlineFrame(nsPresContext* aPresContext,
157 : const ReflowInput& aReflowInput,
158 : InlineReflowInput& rs,
159 : nsIFrame* aFrame,
160 : nsReflowStatus& aStatus);
161 :
162 : /**
163 : * Reparent floats whose placeholders are inline descendants of aFrame from
164 : * whatever block they're currently parented by to aOurBlock.
165 : * @param aReparentSiblings if this is true, we follow aFrame's
166 : * GetNextSibling chain reparenting them all
167 : */
168 : void ReparentFloatsForInlineChild(nsIFrame* aOurBlock, nsIFrame* aFrame,
169 : bool aReparentSiblings);
170 :
171 : virtual nsIFrame* PullOneFrame(nsPresContext* aPresContext,
172 : InlineReflowInput& rs,
173 : bool* aIsComplete);
174 :
175 : virtual void PushFrames(nsPresContext* aPresContext,
176 : nsIFrame* aFromChild,
177 : nsIFrame* aPrevSibling,
178 : InlineReflowInput& aState);
179 :
180 : private:
181 0 : explicit nsInlineFrame(nsStyleContext* aContext)
182 0 : : nsInlineFrame(aContext, kClassID)
183 0 : {}
184 :
185 : // Helper method for DrainSelfOverflowList() to deal with lazy parenting
186 : // (which we only do for nsInlineFrame, not nsFirstLineFrame).
187 : enum DrainFlags {
188 : eDontReparentFrames = 1, // skip reparenting the overflow list frames
189 : eInFirstLine = 2, // the request is for an inline descendant of a nsFirstLineFrame
190 : eForDestroy = 4, // the request is from DestroyFrom; in this case we do the
191 : // minimal work required since the frame is about to be
192 : // destroyed (just fixup parent pointers)
193 : };
194 : /**
195 : * Move any frames on our overflow list to the end of our principal list.
196 : * @param aFlags one or more of the above DrainFlags
197 : * @param aLineContainer the nearest line container ancestor
198 : * @return true if there were any overflow frames
199 : */
200 : bool DrainSelfOverflowListInternal(DrainFlags aFlags,
201 : nsIFrame* aLineContainer);
202 : protected:
203 : nscoord mBaseline;
204 : };
205 :
206 : //----------------------------------------------------------------------
207 :
208 : /**
209 : * Variation on inline-frame used to manage lines for line layout in
210 : * special situations (:first-line style in particular).
211 : */
212 0 : class nsFirstLineFrame final : public nsInlineFrame {
213 : public:
214 0 : NS_DECL_FRAMEARENA_HELPERS(nsFirstLineFrame)
215 :
216 : friend nsFirstLineFrame* NS_NewFirstLineFrame(nsIPresShell* aPresShell,
217 : nsStyleContext* aContext);
218 :
219 : #ifdef DEBUG_FRAME_DUMP
220 : virtual nsresult GetFrameName(nsAString& aResult) const override;
221 : #endif
222 : virtual void Reflow(nsPresContext* aPresContext,
223 : ReflowOutput& aDesiredSize,
224 : const ReflowInput& aReflowInput,
225 : nsReflowStatus& aStatus) override;
226 :
227 : virtual void Init(nsIContent* aContent,
228 : nsContainerFrame* aParent,
229 : nsIFrame* aPrevInFlow) override;
230 : virtual void PullOverflowsFromPrevInFlow() override;
231 : virtual bool DrainSelfOverflowList() override;
232 :
233 : protected:
234 0 : explicit nsFirstLineFrame(nsStyleContext* aContext)
235 0 : : nsInlineFrame(aContext, kClassID)
236 0 : {}
237 :
238 : virtual nsIFrame* PullOneFrame(nsPresContext* aPresContext,
239 : InlineReflowInput& rs,
240 : bool* aIsComplete) override;
241 : };
242 :
243 : #endif /* nsInlineFrame_h___ */
|