Bug 575870 - Enable the firefox button on xp themed, classic, and aero basic. r=dao...
[mozilla-central.git] / layout / generic / nsBlockReflowState.h
blobc8705aec15f03f3ea36b4eb98b41648e3ba7136a
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 "nsFloatManager.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_FLOAT_MGR
60 #define BRS_FLOAT_MGR 0x00000040
61 // Set when nsLineLayout::LineIsEmpty was true at the end of reflowing
62 // the current line
63 #define BRS_LINE_LAYOUT_EMPTY 0x00000080
64 #define BRS_ISOVERFLOWCONTAINER 0x00000100
65 // Our mPushedFloats list is stored on the blocks' proptable
66 #define BRS_PROPTABLE_FLOATCLIST 0x00000200
67 #define BRS_LASTFLAG BRS_PROPTABLE_FLOATCLIST
69 class nsBlockReflowState {
70 public:
71 nsBlockReflowState(const nsHTMLReflowState& aReflowState,
72 nsPresContext* aPresContext,
73 nsBlockFrame* aFrame,
74 const nsHTMLReflowMetrics& aMetrics,
75 PRBool aTopMarginRoot, PRBool aBottomMarginRoot,
76 PRBool aBlockNeedsFloatManager);
78 /**
79 * Get the available reflow space (the area not occupied by floats)
80 * for the current y coordinate. The available space is relative to
81 * our coordinate system, which is the content box, with (0, 0) in the
82 * upper left.
84 * Returns whether there are floats present at the given vertical
85 * coordinate and within the width of the content rect.
87 nsFlowAreaRect GetFloatAvailableSpace() const
88 { return GetFloatAvailableSpace(mY); }
89 nsFlowAreaRect GetFloatAvailableSpace(nscoord aY) const
90 { return GetFloatAvailableSpaceWithState(aY, nsnull); }
91 nsFlowAreaRect
92 GetFloatAvailableSpaceWithState(nscoord aY,
93 nsFloatManager::SavedState *aState) const;
94 nsFlowAreaRect
95 GetFloatAvailableSpaceForHeight(nscoord aY, nscoord aHeight,
96 nsFloatManager::SavedState *aState) const;
99 * The following functions all return PR_TRUE if they were able to
100 * place the float, PR_FALSE if the float did not fit in available
101 * space.
102 * aLineLayout is null when we are reflowing pushed floats (because
103 * they are not associated with a line box).
105 PRBool AddFloat(nsLineLayout* aLineLayout,
106 nsIFrame* aFloat,
107 nscoord aAvailableWidth);
108 private:
109 PRBool CanPlaceFloat(nscoord aFloatWidth,
110 const nsFlowAreaRect& aFloatAvailableSpace);
111 public:
112 PRBool FlowAndPlaceFloat(nsIFrame* aFloat);
113 private:
114 void PushFloatPastBreak(nsIFrame* aFloat);
115 public:
116 void PlaceBelowCurrentLineFloats(nsFloatCacheFreeList& aFloats,
117 nsLineBox* aLine);
119 // Returns the first coordinate >= aY that clears the
120 // floats indicated by aBreakType and has enough width between floats
121 // (or no floats remaining) to accomodate aReplacedBlock.
122 nscoord ClearFloats(nscoord aY, PRUint8 aBreakType,
123 nsIFrame *aReplacedBlock = nsnull,
124 PRUint32 aFlags = 0);
126 PRBool IsAdjacentWithTop() const {
127 return mY ==
128 ((mFlags & BRS_ISFIRSTINFLOW) ? mReflowState.mComputedBorderPadding.top : 0);
132 * Adjusts the border/padding to return 0 for the top if
133 * we are not the first in flow.
135 nsMargin BorderPadding() const {
136 nsMargin result = mReflowState.mComputedBorderPadding;
137 if (!(mFlags & BRS_ISFIRSTINFLOW)) {
138 result.top = 0;
139 if (mFlags & BRS_ISOVERFLOWCONTAINER) {
140 result.bottom = 0;
143 return result;
146 // XXX maybe we should do the same adjustment for continuations here
147 const nsMargin& Margin() const {
148 return mReflowState.mComputedMargin;
151 // Reconstruct the previous bottom margin that goes above |aLine|.
152 void ReconstructMarginAbove(nsLineList::iterator aLine);
154 // Caller must have called GetAvailableSpace for the correct position
155 // (which need not be the current mY). Callers need only pass
156 // aReplacedWidth for outer table frames.
157 void ComputeReplacedBlockOffsetsForFloats(nsIFrame* aFrame,
158 const nsRect& aFloatAvailableSpace,
159 nscoord& aLeftResult,
160 nscoord& aRightResult,
161 nsBlockFrame::ReplacedElementWidthToClear
162 *aReplacedWidth = nsnull);
164 // Caller must have called GetAvailableSpace for the current mY
165 void ComputeBlockAvailSpace(nsIFrame* aFrame,
166 const nsStyleDisplay* aDisplay,
167 const nsFlowAreaRect& aFloatAvailableSpace,
168 PRBool aBlockAvoidsFloats,
169 nsRect& aResult);
171 protected:
172 void RecoverFloats(nsLineList::iterator aLine, nscoord aDeltaY);
174 public:
175 void RecoverStateFrom(nsLineList::iterator aLine, nscoord aDeltaY);
177 void AdvanceToNextLine() {
178 if (GetFlag(BRS_LINE_LAYOUT_EMPTY)) {
179 SetFlag(BRS_LINE_LAYOUT_EMPTY, PR_FALSE);
180 } else {
181 mLineNumber++;
185 nsLineBox* NewLineBox(nsIFrame* aFrame, PRInt32 aCount, PRBool aIsBlock);
187 void FreeLineBox(nsLineBox* aLine);
189 //----------------------------------------
191 // This state is the "global" state computed once for the reflow of
192 // the block.
194 // The block frame that is using this object
195 nsBlockFrame* mBlock;
197 nsPresContext* mPresContext;
199 const nsHTMLReflowState& mReflowState;
201 nsFloatManager* mFloatManager;
203 // The coordinates within the float manager where the block is being
204 // placed <b>after</b> taking into account the blocks border and
205 // padding. This, therefore, represents the inner "content area" (in
206 // spacemanager coordinates) where child frames will be placed,
207 // including child blocks and floats.
208 nscoord mFloatManagerX, mFloatManagerY;
210 // XXX get rid of this
211 nsReflowStatus mReflowStatus;
213 // The float manager state as it was before the contents of this
214 // block. This is needed for positioning bullets, since we only want
215 // to move the bullet to flow around floats that were before this
216 // block, not floats inside of it.
217 nsFloatManager::SavedState mFloatManagerStateBefore;
219 nscoord mBottomEdge;
221 // The content area to reflow child frames within. This is within
222 // this frame's coordinate system, which means mContentArea.x ==
223 // BorderPadding().left and mContentArea.y == BorderPadding().top.
224 // The height may be NS_UNCONSTRAINEDSIZE, which indicates that there
225 // is no page/column boundary below (the common case).
226 // mContentArea.YMost() should only be called after checking that
227 // mContentArea.height is not NS_UNCONSTRAINEDSIZE; otherwise
228 // coordinate overflow may occur.
229 nsRect mContentArea;
231 // Continuation out-of-flow float frames that need to move to our
232 // next in flow are placed here during reflow. It's a pointer to
233 // a frame list stored in the block's property table.
234 nsFrameList *mPushedFloats;
235 // This method makes sure pushed floats are accessible to
236 // StealFrame. Call it before adding any frames to mPushedFloats.
237 void SetupPushedFloatList();
238 // Use this method to append to mPushedFloats.
239 void AppendPushedFloat(nsIFrame* aFloatCont) {
240 SetupPushedFloatList();
241 aFloatCont->AddStateBits(NS_FRAME_IS_PUSHED_FLOAT);
242 mPushedFloats->AppendFrame(mBlock, aFloatCont);
245 // Track child overflow continuations.
246 nsOverflowContinuationTracker* mOverflowTracker;
248 //----------------------------------------
250 // This state is "running" state updated by the reflow of each line
251 // in the block. This same state is "recovered" when a line is not
252 // dirty and is passed over during incremental reflow.
254 // The current line being reflowed
255 // If it is mBlock->end_lines(), then it is invalid.
256 nsLineList::iterator mCurrentLine;
258 // When BRS_HAVELINEADJACENTTOTOP is set, this refers to a line
259 // which we know is adjacent to the top of the block (in other words,
260 // all lines before it are empty and do not have clearance. This line is
261 // always before the current line.
262 nsLineList::iterator mLineAdjacentToTop;
264 // The current Y coordinate in the block
265 nscoord mY;
267 // The combined area of all floats placed so far
268 nsRect mFloatCombinedArea;
270 nsFloatCacheFreeList mFloatCacheFreeList;
272 // Previous child. This is used when pulling up a frame to update
273 // the sibling list.
274 nsIFrame* mPrevChild;
276 // The previous child frames collapsed bottom margin value.
277 nsCollapsingMargin mPrevBottomMargin;
279 // The current next-in-flow for the block. When lines are pulled
280 // from a next-in-flow, this is used to know which next-in-flow to
281 // pull from. When a next-in-flow is emptied of lines, we advance
282 // this to the next next-in-flow.
283 nsBlockFrame* mNextInFlow;
285 //----------------------------------------
287 // Temporary line-reflow state. This state is used during the reflow
288 // of a given line, but doesn't have meaning before or after.
290 // The list of floats that are "current-line" floats. These are
291 // added to the line after the line has been reflowed, to keep the
292 // list fiddling from being N^2.
293 nsFloatCacheFreeList mCurrentLineFloats;
295 // The list of floats which are "below current-line"
296 // floats. These are reflowed/placed after the line is reflowed
297 // and placed. Again, this is done to keep the list fiddling from
298 // being N^2.
299 nsFloatCacheFreeList mBelowCurrentLineFloats;
301 nscoord mMinLineHeight;
303 PRInt32 mLineNumber;
305 PRInt16 mFlags;
307 PRUint8 mFloatBreakType;
309 void SetFlag(PRUint32 aFlag, PRBool aValue)
311 NS_ASSERTION(aFlag<=BRS_LASTFLAG, "bad flag");
312 NS_ASSERTION(aValue==PR_FALSE || aValue==PR_TRUE, "bad value");
313 if (aValue) { // set flag
314 mFlags |= aFlag;
316 else { // unset flag
317 mFlags &= ~aFlag;
321 PRBool GetFlag(PRUint32 aFlag) const
323 NS_ASSERTION(aFlag<=BRS_LASTFLAG, "bad flag");
324 return !!(mFlags & aFlag);
328 #endif // nsBlockReflowState_h__