1 /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
2 /* ***** BEGIN LICENSE BLOCK *****
3 * Version: MPL 1.1/GPL 2.0/LGPL 2.1
5 * The contents of this file are subject to the Mozilla Public License Version
6 * 1.1 (the "License"); you may not use this file except in compliance with
7 * the License. You may obtain a copy of the License at
8 * http://www.mozilla.org/MPL/
10 * Software distributed under the License is distributed on an "AS IS" basis,
11 * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
12 * for the specific language governing rights and limitations under the
15 * The Original Code is Mozilla Communicator client code.
17 * The Initial Developer of the Original Code is
18 * Netscape Communications Corporation.
19 * Portions created by the Initial Developer are Copyright (C) 1998
20 * the Initial Developer. All Rights Reserved.
23 * Steve Clark <buster@netscape.com>
24 * Robert O'Callahan <roc+moz@cs.cmu.edu>
25 * L. David Baron <dbaron@dbaron.org>
27 * Alternatively, the contents of this file may be used under the terms of
28 * either of the GNU General Public License Version 2 or later (the "GPL"),
29 * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
30 * in which case the provisions of the GPL or the LGPL are applicable instead
31 * of those above. If you wish to allow use of your version of this file only
32 * under the terms of either the GPL or the LGPL, and not to allow others to
33 * use your version of this file under the terms of the MPL, indicate your
34 * decision by deleting the provisions above and replace them with the notice
35 * and other provisions required by the GPL or the LGPL. If you do not delete
36 * the provisions above, a recipient may use your version of this file under
37 * the terms of any one of the MPL, the GPL or the LGPL.
39 * ***** END LICENSE BLOCK ***** */
41 /* state used in reflow of block frames */
43 #ifndef nsBlockReflowState_h__
44 #define nsBlockReflowState_h__
46 #include "nsBlockBandData.h"
47 #include "nsLineBox.h"
48 #include "nsFrameList.h"
49 #include "nsBlockFrame.h"
51 // block reflow state flags
52 #define BRS_UNCONSTRAINEDHEIGHT 0x00000001
53 #define BRS_ISTOPMARGINROOT 0x00000002 // Is this frame a root for top/bottom margin collapsing?
54 #define BRS_ISBOTTOMMARGINROOT 0x00000004
55 #define BRS_APPLYTOPMARGIN 0x00000008 // See ShouldApplyTopMargin
56 #define BRS_ISFIRSTINFLOW 0x00000010
57 // Set when mLineAdjacentToTop is valid
58 #define BRS_HAVELINEADJACENTTOTOP 0x00000020
59 // Set when the block has the equivalent of NS_BLOCK_SPACE_MGR
60 #define BRS_SPACE_MGR 0x00000040
61 #define BRS_ISOVERFLOWCONTAINER 0x00000100
62 #define BRS_LASTFLAG BRS_ISOVERFLOWCONTAINER
64 class nsBlockReflowState
{
66 nsBlockReflowState(const nsHTMLReflowState
& aReflowState
,
67 nsPresContext
* aPresContext
,
69 const nsHTMLReflowMetrics
& aMetrics
,
70 PRBool aTopMarginRoot
, PRBool aBottomMarginRoot
,
71 PRBool aBlockNeedsSpaceManager
);
73 ~nsBlockReflowState();
75 // Set up a property on the block that points to our temporary mOverflowPlaceholders
76 // list, if that list is or could become non-empty during this reflow. Must be
77 // called after the block has done DrainOverflowLines because DrainOverflowLines
78 // can setup mOverflowPlaceholders even if the block is in unconstrained height
79 // reflow (it may have previously been reflowed with constrained height).
80 void SetupOverflowPlaceholdersProperty();
83 * Get the available reflow space for the current y coordinate. The
84 * available space is relative to our coordinate system (0,0) is our
87 void GetAvailableSpace() { GetAvailableSpace(mY
, PR_FALSE
); }
88 void GetAvailableSpace(nscoord aY
, PRBool aRelaxHeightConstraint
);
91 * The following functions all return PR_TRUE if they were able to
92 * place the float, PR_FALSE if the float did not fit in available
95 PRBool
InitFloat(nsLineLayout
& aLineLayout
,
96 nsPlaceholderFrame
* aPlaceholderFrame
,
97 nscoord aAvailableWidth
,
98 nsReflowStatus
& aReflowStatus
);
99 PRBool
AddFloat(nsLineLayout
& aLineLayout
,
100 nsPlaceholderFrame
* aPlaceholderFrame
,
101 PRBool aInitialReflow
,
102 nscoord aAvailableWidth
,
103 nsReflowStatus
& aReflowStatus
);
104 PRBool
CanPlaceFloat(const nsSize
& aFloatSize
, PRUint8 aFloats
, PRBool aForceFit
);
105 PRBool
FlowAndPlaceFloat(nsFloatCache
* aFloatCache
,
106 PRBool
* aIsLeftFloat
,
107 nsReflowStatus
& aReflowStatus
,
109 PRBool
PlaceBelowCurrentLineFloats(nsFloatCacheFreeList
& aFloats
, PRBool aForceFit
);
111 // Returns the first coordinate >= aY that clears the
112 // floats indicated by aBreakType and has enough width between floats
113 // (or no floats remaining) to accomodate aReplacedBlock.
114 nscoord
ClearFloats(nscoord aY
, PRUint8 aBreakType
,
115 nsIFrame
*aReplacedBlock
= nsnull
);
117 PRBool
IsAdjacentWithTop() const {
119 ((mFlags
& BRS_ISFIRSTINFLOW
) ? mReflowState
.mComputedBorderPadding
.top
: 0);
123 * Adjusts the border/padding to return 0 for the top if
124 * we are not the first in flow.
126 nsMargin
BorderPadding() const {
127 nsMargin result
= mReflowState
.mComputedBorderPadding
;
128 if (!(mFlags
& BRS_ISFIRSTINFLOW
)) {
130 if (mFlags
& BRS_ISOVERFLOWCONTAINER
) {
137 // XXX maybe we should do the same adjustment for continuations here
138 const nsMargin
& Margin() const {
139 return mReflowState
.mComputedMargin
;
142 // Reconstruct the previous bottom margin that goes above |aLine|.
143 void ReconstructMarginAbove(nsLineList::iterator aLine
);
145 // Caller must have called GetAvailableSpace for the correct position
146 // (which need not be the current mY). Callers need only pass
147 // aReplacedWidth for outer table frames.
148 void ComputeReplacedBlockOffsetsForFloats(nsIFrame
* aFrame
,
149 nscoord
& aLeftResult
,
150 nscoord
& aRightResult
,
151 nsBlockFrame::ReplacedElementWidthToClear
152 *aReplacedWidth
= nsnull
);
154 // Caller must have called GetAvailableSpace for the current mY
155 void ComputeBlockAvailSpace(nsIFrame
* aFrame
,
156 const nsStyleDisplay
* aDisplay
,
157 PRBool aBlockAvoidsFloats
,
161 void RecoverFloats(nsLineList::iterator aLine
, nscoord aDeltaY
);
164 void RecoverStateFrom(nsLineList::iterator aLine
, nscoord aDeltaY
);
166 void AdvanceToNextLine() {
170 PRBool
IsImpactedByFloat() const;
172 nsLineBox
* NewLineBox(nsIFrame
* aFrame
, PRInt32 aCount
, PRBool aIsBlock
);
174 void FreeLineBox(nsLineBox
* aLine
);
176 //----------------------------------------
178 // This state is the "global" state computed once for the reflow of
181 // The block frame that is using this object
182 nsBlockFrame
* mBlock
;
184 nsPresContext
* mPresContext
;
186 const nsHTMLReflowState
& mReflowState
;
188 nsSpaceManager
* mSpaceManager
;
190 // The coordinates within the spacemanager where the block is being
191 // placed <b>after</b> taking into account the blocks border and
192 // padding. This, therefore, represents the inner "content area" (in
193 // spacemanager coordinates) where child frames will be placed,
194 // including child blocks and floats.
195 nscoord mSpaceManagerX
, mSpaceManagerY
;
197 // XXX get rid of this
198 nsReflowStatus mReflowStatus
;
200 // The x-position we should place an outside bullet relative to.
201 // This is the border-box edge of the principal box. However, if a line box
202 // would be displaced by floats, we want to displace it by the same amount.
203 // That is, we act as though the edge of the floats is the content-edge of
204 // the block, displaced by the block's padding and border.
205 nscoord mOutsideBulletX
;
209 // The content area to reflow child frames within. The x/y
210 // coordinates are known to be mBorderPadding.left and
211 // mBorderPadding.top. The width/height may be NS_UNCONSTRAINEDSIZE
212 // if the container reflowing this frame has given the frame an
213 // unconstrained area.
216 // Placeholders for continuation out-of-flow frames that need to
217 // move to our next in flow are placed here during reflow. At the end of reflow
218 // they move to the end of the overflow lines.
219 // Their out-of-flows are not in any child list during reflow, but are added
220 // to the overflow-out-of-flow list when the placeholders are appended to
221 // the overflow lines.
222 nsFrameList mOverflowPlaceholders
;
224 // Track child overflow continuations.
225 nsOverflowContinuationTracker mOverflowTracker
;
227 //----------------------------------------
229 // This state is "running" state updated by the reflow of each line
230 // in the block. This same state is "recovered" when a line is not
231 // dirty and is passed over during incremental reflow.
233 // The current line being reflowed
234 // If it is mBlock->end_lines(), then it is invalid.
235 nsLineList::iterator mCurrentLine
;
237 // When BRS_HAVELINEADJACENTTOTOP is set, this refers to a line
238 // which we know is adjacent to the top of the block (in other words,
239 // all lines before it are empty and do not have clearance. This line is
240 // always before the current line.
241 nsLineList::iterator mLineAdjacentToTop
;
243 // The current Y coordinate in the block
246 // The available space within the current band.
247 // (relative to the *content*-rect of the block)
248 nsRect mAvailSpaceRect
;
250 // The combined area of all floats placed so far
251 nsRect mFloatCombinedArea
;
253 nsFloatCacheFreeList mFloatCacheFreeList
;
255 // Previous child. This is used when pulling up a frame to update
257 nsIFrame
* mPrevChild
;
259 // The previous child frames collapsed bottom margin value.
260 nsCollapsingMargin mPrevBottomMargin
;
262 // The current next-in-flow for the block. When lines are pulled
263 // from a next-in-flow, this is used to know which next-in-flow to
264 // pull from. When a next-in-flow is emptied of lines, we advance
265 // this to the next next-in-flow.
266 nsBlockFrame
* mNextInFlow
;
268 // The current band data for the current Y coordinate
269 nsBlockBandData mBand
;
271 //----------------------------------------
273 // Temporary line-reflow state. This state is used during the reflow
274 // of a given line, but doesn't have meaning before or after.
276 // The list of floats that are "current-line" floats. These are
277 // added to the line after the line has been reflowed, to keep the
278 // list fiddling from being N^2.
279 nsFloatCacheFreeList mCurrentLineFloats
;
281 // The list of floats which are "below current-line"
282 // floats. These are reflowed/placed after the line is reflowed
283 // and placed. Again, this is done to keep the list fiddling from
285 nsFloatCacheFreeList mBelowCurrentLineFloats
;
287 nscoord mMinLineHeight
;
293 PRUint8 mFloatBreakType
;
295 void SetFlag(PRUint32 aFlag
, PRBool aValue
)
297 NS_ASSERTION(aFlag
<=BRS_LASTFLAG
, "bad flag");
298 NS_ASSERTION(aValue
==PR_FALSE
|| aValue
==PR_TRUE
, "bad value");
299 if (aValue
) { // set flag
307 PRBool
GetFlag(PRUint32 aFlag
) const
309 NS_ASSERTION(aFlag
<=BRS_LASTFLAG
, "bad flag");
310 return !!(mFlags
& aFlag
);
314 #endif // nsBlockReflowState_h__