Bug 54488 - "[Mac] Non-draggable widgets in background windows should look disabled...
[mozilla-central.git] / layout / generic / nsBlockReflowState.h
blob8c2a49920bb2d8054098ee02ec11e4641fbf2c69
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
13 * License.
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.
22 * Contributor(s):
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 {
65 public:
66 nsBlockReflowState(const nsHTMLReflowState& aReflowState,
67 nsPresContext* aPresContext,
68 nsBlockFrame* aFrame,
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();
82 /**
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
85 * upper left corner.
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
93 * space.
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,
108 PRBool aForceFit);
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 {
118 return mY ==
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)) {
129 result.top = 0;
130 if (mFlags & BRS_ISOVERFLOWCONTAINER) {
131 result.bottom = 0;
134 return result;
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,
158 nsRect& aResult);
160 protected:
161 void RecoverFloats(nsLineList::iterator aLine, nscoord aDeltaY);
163 public:
164 void RecoverStateFrom(nsLineList::iterator aLine, nscoord aDeltaY);
166 void AdvanceToNextLine() {
167 mLineNumber++;
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
179 // the block.
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;
207 nscoord mBottomEdge;
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.
214 nsSize mContentArea;
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
244 nscoord mY;
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
256 // the sibling list.
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
284 // being N^2.
285 nsFloatCacheFreeList mBelowCurrentLineFloats;
287 nscoord mMinLineHeight;
289 PRInt32 mLineNumber;
291 PRInt16 mFlags;
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
300 mFlags |= aFlag;
302 else { // unset flag
303 mFlags &= ~aFlag;
307 PRBool GetFlag(PRUint32 aFlag) const
309 NS_ASSERTION(aFlag<=BRS_LASTFLAG, "bad flag");
310 return !!(mFlags & aFlag);
314 #endif // nsBlockReflowState_h__