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.

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

mercurial