layout/generic/nsBlockReflowState.h

Wed, 31 Dec 2014 06:09:35 +0100

author
Michael Schloh von Bennewitz <michael@schloh.com>
date
Wed, 31 Dec 2014 06:09:35 +0100
changeset 0
6474c204b198
permissions
-rw-r--r--

Cloned upstream origin tor-browser at tor-browser-31.3.0esr-4.5-1-build1
revision ID fc1c9ff7c1b2defdbc039f12214767608f46423f for hacking purpose.

michael@0 1 /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
michael@0 2 /* This Source Code Form is subject to the terms of the Mozilla Public
michael@0 3 * License, v. 2.0. If a copy of the MPL was not distributed with this
michael@0 4 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
michael@0 5
michael@0 6 /* state used in reflow of block frames */
michael@0 7
michael@0 8 #ifndef nsBlockReflowState_h__
michael@0 9 #define nsBlockReflowState_h__
michael@0 10
michael@0 11 #include "nsFloatManager.h"
michael@0 12 #include "nsLineBox.h"
michael@0 13 #include "nsHTMLReflowState.h"
michael@0 14
michael@0 15 class nsBlockFrame;
michael@0 16 class nsFrameList;
michael@0 17 class nsOverflowContinuationTracker;
michael@0 18
michael@0 19 // block reflow state flags
michael@0 20 #define BRS_UNCONSTRAINEDHEIGHT 0x00000001
michael@0 21 #define BRS_ISTOPMARGINROOT 0x00000002 // Is this frame a root for top/bottom margin collapsing?
michael@0 22 #define BRS_ISBOTTOMMARGINROOT 0x00000004
michael@0 23 #define BRS_APPLYTOPMARGIN 0x00000008 // See ShouldApplyTopMargin
michael@0 24 #define BRS_ISFIRSTINFLOW 0x00000010
michael@0 25 // Set when mLineAdjacentToTop is valid
michael@0 26 #define BRS_HAVELINEADJACENTTOTOP 0x00000020
michael@0 27 // Set when the block has the equivalent of NS_BLOCK_FLOAT_MGR
michael@0 28 #define BRS_FLOAT_MGR 0x00000040
michael@0 29 // Set when nsLineLayout::LineIsEmpty was true at the end of reflowing
michael@0 30 // the current line
michael@0 31 #define BRS_LINE_LAYOUT_EMPTY 0x00000080
michael@0 32 #define BRS_ISOVERFLOWCONTAINER 0x00000100
michael@0 33 // Our mPushedFloats list is stored on the blocks' proptable
michael@0 34 #define BRS_PROPTABLE_FLOATCLIST 0x00000200
michael@0 35 #define BRS_LASTFLAG BRS_PROPTABLE_FLOATCLIST
michael@0 36
michael@0 37 class nsBlockReflowState {
michael@0 38 public:
michael@0 39 nsBlockReflowState(const nsHTMLReflowState& aReflowState,
michael@0 40 nsPresContext* aPresContext,
michael@0 41 nsBlockFrame* aFrame,
michael@0 42 bool aTopMarginRoot, bool aBottomMarginRoot,
michael@0 43 bool aBlockNeedsFloatManager,
michael@0 44 nscoord aConsumedHeight = NS_INTRINSICSIZE);
michael@0 45
michael@0 46 /**
michael@0 47 * Get the available reflow space (the area not occupied by floats)
michael@0 48 * for the current y coordinate. The available space is relative to
michael@0 49 * our coordinate system, which is the content box, with (0, 0) in the
michael@0 50 * upper left.
michael@0 51 *
michael@0 52 * Returns whether there are floats present at the given vertical
michael@0 53 * coordinate and within the width of the content rect.
michael@0 54 */
michael@0 55 nsFlowAreaRect GetFloatAvailableSpace() const
michael@0 56 { return GetFloatAvailableSpace(mY); }
michael@0 57 nsFlowAreaRect GetFloatAvailableSpace(nscoord aY) const
michael@0 58 { return GetFloatAvailableSpaceWithState(aY, nullptr); }
michael@0 59 nsFlowAreaRect
michael@0 60 GetFloatAvailableSpaceWithState(nscoord aY,
michael@0 61 nsFloatManager::SavedState *aState) const;
michael@0 62 nsFlowAreaRect
michael@0 63 GetFloatAvailableSpaceForHeight(nscoord aY, nscoord aHeight,
michael@0 64 nsFloatManager::SavedState *aState) const;
michael@0 65
michael@0 66 /*
michael@0 67 * The following functions all return true if they were able to
michael@0 68 * place the float, false if the float did not fit in available
michael@0 69 * space.
michael@0 70 * aLineLayout is null when we are reflowing pushed floats (because
michael@0 71 * they are not associated with a line box).
michael@0 72 */
michael@0 73 bool AddFloat(nsLineLayout* aLineLayout,
michael@0 74 nsIFrame* aFloat,
michael@0 75 nscoord aAvailableWidth);
michael@0 76 private:
michael@0 77 bool CanPlaceFloat(nscoord aFloatWidth,
michael@0 78 const nsFlowAreaRect& aFloatAvailableSpace);
michael@0 79 public:
michael@0 80 bool FlowAndPlaceFloat(nsIFrame* aFloat);
michael@0 81 private:
michael@0 82 void PushFloatPastBreak(nsIFrame* aFloat);
michael@0 83 public:
michael@0 84 void PlaceBelowCurrentLineFloats(nsFloatCacheFreeList& aFloats,
michael@0 85 nsLineBox* aLine);
michael@0 86
michael@0 87 // Returns the first coordinate >= aY that clears the
michael@0 88 // floats indicated by aBreakType and has enough width between floats
michael@0 89 // (or no floats remaining) to accomodate aReplacedBlock.
michael@0 90 nscoord ClearFloats(nscoord aY, uint8_t aBreakType,
michael@0 91 nsIFrame *aReplacedBlock = nullptr,
michael@0 92 uint32_t aFlags = 0);
michael@0 93
michael@0 94 bool IsAdjacentWithTop() const {
michael@0 95 return mY ==
michael@0 96 ((mFlags & BRS_ISFIRSTINFLOW) ? mReflowState.ComputedPhysicalBorderPadding().top : 0);
michael@0 97 }
michael@0 98
michael@0 99 /**
michael@0 100 * Adjusts the border/padding to return 0 for the top if
michael@0 101 * we are not the first in flow.
michael@0 102 */
michael@0 103 nsMargin BorderPadding() const {
michael@0 104 nsMargin result = mReflowState.ComputedPhysicalBorderPadding();
michael@0 105 if (!(mFlags & BRS_ISFIRSTINFLOW)) {
michael@0 106 result.top = 0;
michael@0 107 if (mFlags & BRS_ISOVERFLOWCONTAINER) {
michael@0 108 result.bottom = 0;
michael@0 109 }
michael@0 110 }
michael@0 111 return result;
michael@0 112 }
michael@0 113
michael@0 114 /**
michael@0 115 * Retrieve the height "consumed" by any previous-in-flows.
michael@0 116 */
michael@0 117 nscoord GetConsumedHeight();
michael@0 118
michael@0 119 // Reconstruct the previous bottom margin that goes above |aLine|.
michael@0 120 void ReconstructMarginAbove(nsLineList::iterator aLine);
michael@0 121
michael@0 122 // Caller must have called GetAvailableSpace for the correct position
michael@0 123 // (which need not be the current mY).
michael@0 124 void ComputeReplacedBlockOffsetsForFloats(nsIFrame* aFrame,
michael@0 125 const nsRect& aFloatAvailableSpace,
michael@0 126 nscoord& aLeftResult,
michael@0 127 nscoord& aRightResult);
michael@0 128
michael@0 129 // Caller must have called GetAvailableSpace for the current mY
michael@0 130 void ComputeBlockAvailSpace(nsIFrame* aFrame,
michael@0 131 const nsStyleDisplay* aDisplay,
michael@0 132 const nsFlowAreaRect& aFloatAvailableSpace,
michael@0 133 bool aBlockAvoidsFloats,
michael@0 134 nsRect& aResult);
michael@0 135
michael@0 136 protected:
michael@0 137 void RecoverFloats(nsLineList::iterator aLine, nscoord aDeltaY);
michael@0 138
michael@0 139 public:
michael@0 140 void RecoverStateFrom(nsLineList::iterator aLine, nscoord aDeltaY);
michael@0 141
michael@0 142 void AdvanceToNextLine() {
michael@0 143 if (GetFlag(BRS_LINE_LAYOUT_EMPTY)) {
michael@0 144 SetFlag(BRS_LINE_LAYOUT_EMPTY, false);
michael@0 145 } else {
michael@0 146 mLineNumber++;
michael@0 147 }
michael@0 148 }
michael@0 149
michael@0 150 //----------------------------------------
michael@0 151
michael@0 152 // This state is the "global" state computed once for the reflow of
michael@0 153 // the block.
michael@0 154
michael@0 155 // The block frame that is using this object
michael@0 156 nsBlockFrame* mBlock;
michael@0 157
michael@0 158 nsPresContext* mPresContext;
michael@0 159
michael@0 160 const nsHTMLReflowState& mReflowState;
michael@0 161
michael@0 162 nsFloatManager* mFloatManager;
michael@0 163
michael@0 164 // The coordinates within the float manager where the block is being
michael@0 165 // placed <b>after</b> taking into account the blocks border and
michael@0 166 // padding. This, therefore, represents the inner "content area" (in
michael@0 167 // spacemanager coordinates) where child frames will be placed,
michael@0 168 // including child blocks and floats.
michael@0 169 nscoord mFloatManagerX, mFloatManagerY;
michael@0 170
michael@0 171 // XXX get rid of this
michael@0 172 nsReflowStatus mReflowStatus;
michael@0 173
michael@0 174 // The float manager state as it was before the contents of this
michael@0 175 // block. This is needed for positioning bullets, since we only want
michael@0 176 // to move the bullet to flow around floats that were before this
michael@0 177 // block, not floats inside of it.
michael@0 178 nsFloatManager::SavedState mFloatManagerStateBefore;
michael@0 179
michael@0 180 nscoord mBottomEdge;
michael@0 181
michael@0 182 // The content area to reflow child frames within. This is within
michael@0 183 // this frame's coordinate system, which means mContentArea.x ==
michael@0 184 // BorderPadding().left and mContentArea.y == BorderPadding().top.
michael@0 185 // The height may be NS_UNCONSTRAINEDSIZE, which indicates that there
michael@0 186 // is no page/column boundary below (the common case).
michael@0 187 // mContentArea.YMost() should only be called after checking that
michael@0 188 // mContentArea.height is not NS_UNCONSTRAINEDSIZE; otherwise
michael@0 189 // coordinate overflow may occur.
michael@0 190 nsRect mContentArea;
michael@0 191 nscoord mContainerWidth;
michael@0 192
michael@0 193 // Continuation out-of-flow float frames that need to move to our
michael@0 194 // next in flow are placed here during reflow. It's a pointer to
michael@0 195 // a frame list stored in the block's property table.
michael@0 196 nsFrameList *mPushedFloats;
michael@0 197 // This method makes sure pushed floats are accessible to
michael@0 198 // StealFrame. Call it before adding any frames to mPushedFloats.
michael@0 199 void SetupPushedFloatList();
michael@0 200 // Use this method to append to mPushedFloats.
michael@0 201 void AppendPushedFloat(nsIFrame* aFloatCont);
michael@0 202
michael@0 203 // Track child overflow continuations.
michael@0 204 nsOverflowContinuationTracker* mOverflowTracker;
michael@0 205
michael@0 206 //----------------------------------------
michael@0 207
michael@0 208 // This state is "running" state updated by the reflow of each line
michael@0 209 // in the block. This same state is "recovered" when a line is not
michael@0 210 // dirty and is passed over during incremental reflow.
michael@0 211
michael@0 212 // The current line being reflowed
michael@0 213 // If it is mBlock->end_lines(), then it is invalid.
michael@0 214 nsLineList::iterator mCurrentLine;
michael@0 215
michael@0 216 // When BRS_HAVELINEADJACENTTOTOP is set, this refers to a line
michael@0 217 // which we know is adjacent to the top of the block (in other words,
michael@0 218 // all lines before it are empty and do not have clearance. This line is
michael@0 219 // always before the current line.
michael@0 220 nsLineList::iterator mLineAdjacentToTop;
michael@0 221
michael@0 222 // The current Y coordinate in the block
michael@0 223 nscoord mY;
michael@0 224
michael@0 225 // The overflow areas of all floats placed so far
michael@0 226 nsOverflowAreas mFloatOverflowAreas;
michael@0 227
michael@0 228 nsFloatCacheFreeList mFloatCacheFreeList;
michael@0 229
michael@0 230 // Previous child. This is used when pulling up a frame to update
michael@0 231 // the sibling list.
michael@0 232 nsIFrame* mPrevChild;
michael@0 233
michael@0 234 // The previous child frames collapsed bottom margin value.
michael@0 235 nsCollapsingMargin mPrevBottomMargin;
michael@0 236
michael@0 237 // The current next-in-flow for the block. When lines are pulled
michael@0 238 // from a next-in-flow, this is used to know which next-in-flow to
michael@0 239 // pull from. When a next-in-flow is emptied of lines, we advance
michael@0 240 // this to the next next-in-flow.
michael@0 241 nsBlockFrame* mNextInFlow;
michael@0 242
michael@0 243 //----------------------------------------
michael@0 244
michael@0 245 // Temporary line-reflow state. This state is used during the reflow
michael@0 246 // of a given line, but doesn't have meaning before or after.
michael@0 247
michael@0 248 // The list of floats that are "current-line" floats. These are
michael@0 249 // added to the line after the line has been reflowed, to keep the
michael@0 250 // list fiddling from being N^2.
michael@0 251 nsFloatCacheFreeList mCurrentLineFloats;
michael@0 252
michael@0 253 // The list of floats which are "below current-line"
michael@0 254 // floats. These are reflowed/placed after the line is reflowed
michael@0 255 // and placed. Again, this is done to keep the list fiddling from
michael@0 256 // being N^2.
michael@0 257 nsFloatCacheFreeList mBelowCurrentLineFloats;
michael@0 258
michael@0 259 nscoord mMinLineHeight;
michael@0 260
michael@0 261 int32_t mLineNumber;
michael@0 262
michael@0 263 int16_t mFlags;
michael@0 264
michael@0 265 uint8_t mFloatBreakType;
michael@0 266
michael@0 267 // The amount of computed height "consumed" by previous-in-flows.
michael@0 268 nscoord mConsumedHeight;
michael@0 269
michael@0 270 void SetFlag(uint32_t aFlag, bool aValue)
michael@0 271 {
michael@0 272 NS_ASSERTION(aFlag<=BRS_LASTFLAG, "bad flag");
michael@0 273 if (aValue) { // set flag
michael@0 274 mFlags |= aFlag;
michael@0 275 }
michael@0 276 else { // unset flag
michael@0 277 mFlags &= ~aFlag;
michael@0 278 }
michael@0 279 }
michael@0 280
michael@0 281 bool GetFlag(uint32_t aFlag) const
michael@0 282 {
michael@0 283 NS_ASSERTION(aFlag<=BRS_LASTFLAG, "bad flag");
michael@0 284 return !!(mFlags & aFlag);
michael@0 285 }
michael@0 286 };
michael@0 287
michael@0 288 #endif // nsBlockReflowState_h__

mercurial