layout/generic/nsHTMLReflowState.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 /* struct containing the input to nsIFrame::Reflow */
     8 #ifndef nsHTMLReflowState_h___
     9 #define nsHTMLReflowState_h___
    11 #include "nsMargin.h"
    12 #include "nsStyleCoord.h"
    13 #include "nsIFrame.h"
    14 #include "mozilla/Assertions.h"
    15 #include <algorithm>
    17 class nsPresContext;
    18 class nsRenderingContext;
    19 class nsFloatManager;
    20 class nsLineLayout;
    21 class nsIPercentHeightObserver;
    22 struct nsHypotheticalBox;
    24 /**
    25  * @return aValue clamped to [aMinValue, aMaxValue].
    26  *
    27  * @note This function needs to handle aMinValue > aMaxValue. In that case,
    28  *       aMinValue is returned.
    29  * @see http://www.w3.org/TR/CSS21/visudet.html#min-max-widths
    30  * @see http://www.w3.org/TR/CSS21/visudet.html#min-max-heights
    31  */
    32 template <class NumericType>
    33 NumericType
    34 NS_CSS_MINMAX(NumericType aValue, NumericType aMinValue, NumericType aMaxValue)
    35 {
    36   NumericType result = aValue;
    37   if (aMaxValue < result)
    38     result = aMaxValue;
    39   if (aMinValue > result)
    40     result = aMinValue;
    41   return result;
    42 }
    44 /**
    45  * CSS Frame type. Included as part of the reflow state.
    46  */
    47 typedef uint32_t  nsCSSFrameType;
    49 #define NS_CSS_FRAME_TYPE_UNKNOWN         0
    50 #define NS_CSS_FRAME_TYPE_INLINE          1
    51 #define NS_CSS_FRAME_TYPE_BLOCK           2  /* block-level in normal flow */
    52 #define NS_CSS_FRAME_TYPE_FLOATING        3
    53 #define NS_CSS_FRAME_TYPE_ABSOLUTE        4
    54 #define NS_CSS_FRAME_TYPE_INTERNAL_TABLE  5  /* row group frame, row frame, cell frame, ... */
    56 /**
    57  * Bit-flag that indicates whether the element is replaced. Applies to inline,
    58  * block-level, floating, and absolutely positioned elements
    59  */
    60 #define NS_CSS_FRAME_TYPE_REPLACED                0x08000
    62 /**
    63  * Bit-flag that indicates that the element is replaced and contains a block
    64  * (eg some form controls).  Applies to inline, block-level, floating, and
    65  * absolutely positioned elements.  Mutually exclusive with
    66  * NS_CSS_FRAME_TYPE_REPLACED.
    67  */
    68 #define NS_CSS_FRAME_TYPE_REPLACED_CONTAINS_BLOCK 0x10000
    70 /**
    71  * Helper macros for telling whether items are replaced
    72  */
    73 #define NS_FRAME_IS_REPLACED_NOBLOCK(_ft) \
    74   (NS_CSS_FRAME_TYPE_REPLACED == ((_ft) & NS_CSS_FRAME_TYPE_REPLACED))
    76 #define NS_FRAME_IS_REPLACED(_ft)            \
    77   (NS_FRAME_IS_REPLACED_NOBLOCK(_ft) ||      \
    78    NS_FRAME_IS_REPLACED_CONTAINS_BLOCK(_ft))
    80 #define NS_FRAME_REPLACED(_ft) \
    81   (NS_CSS_FRAME_TYPE_REPLACED | (_ft))
    83 #define NS_FRAME_IS_REPLACED_CONTAINS_BLOCK(_ft)         \
    84   (NS_CSS_FRAME_TYPE_REPLACED_CONTAINS_BLOCK ==         \
    85    ((_ft) & NS_CSS_FRAME_TYPE_REPLACED_CONTAINS_BLOCK))
    87 #define NS_FRAME_REPLACED_CONTAINS_BLOCK(_ft) \
    88   (NS_CSS_FRAME_TYPE_REPLACED_CONTAINS_BLOCK | (_ft))
    90 /**
    91  * A macro to extract the type. Masks off the 'replaced' bit-flag
    92  */
    93 #define NS_FRAME_GET_TYPE(_ft)                           \
    94   ((_ft) & ~(NS_CSS_FRAME_TYPE_REPLACED |                \
    95              NS_CSS_FRAME_TYPE_REPLACED_CONTAINS_BLOCK))
    97 // A base class of nsHTMLReflowState that computes only the padding,
    98 // border, and margin, since those values are needed more often.
    99 struct nsCSSOffsetState {
   100 public:
   101   typedef mozilla::WritingMode WritingMode;
   102   typedef mozilla::LogicalMargin LogicalMargin;
   104   // the frame being reflowed
   105   nsIFrame*           frame;
   107   // rendering context to use for measurement
   108   nsRenderingContext* rendContext;
   110   const nsMargin& ComputedPhysicalMargin() const { return mComputedMargin; }
   111   const nsMargin& ComputedPhysicalBorderPadding() const { return mComputedBorderPadding; }
   112   const nsMargin& ComputedPhysicalPadding() const { return mComputedPadding; }
   114   // We may need to eliminate the (few) users of these writable-reference accessors
   115   // as part of migrating to logical coordinates.
   116   nsMargin& ComputedPhysicalMargin() { return mComputedMargin; }
   117   nsMargin& ComputedPhysicalBorderPadding() { return mComputedBorderPadding; }
   118   nsMargin& ComputedPhysicalPadding() { return mComputedPadding; }
   120   LogicalMargin ComputedLogicalMargin() const
   121     { return LogicalMargin(mWritingMode, mComputedMargin); }
   122   LogicalMargin ComputedLogicalBorderPadding() const
   123     { return LogicalMargin(mWritingMode, mComputedBorderPadding); }
   124   LogicalMargin ComputedLogicalPadding() const
   125     { return LogicalMargin(mWritingMode, mComputedPadding); }
   127   WritingMode GetWritingMode() const { return mWritingMode; }
   129 protected:
   130   // cached copy of the frame's writing-mode, for logical coordinates
   131   WritingMode      mWritingMode;
   133   // These are PHYSICAL coordinates (for now).
   134   // Will probably become logical in due course.
   136   // Computed margin values
   137   nsMargin         mComputedMargin;
   139   // Cached copy of the border + padding values
   140   nsMargin         mComputedBorderPadding;
   142   // Computed padding values
   143   nsMargin         mComputedPadding;
   145 public:
   146   // Callers using this constructor must call InitOffsets on their own.
   147   nsCSSOffsetState(nsIFrame *aFrame, nsRenderingContext *aRenderingContext)
   148     : frame(aFrame)
   149     , rendContext(aRenderingContext)
   150     , mWritingMode(aFrame->GetWritingMode())
   151   {
   152   }
   154   nsCSSOffsetState(nsIFrame *aFrame, nsRenderingContext *aRenderingContext,
   155                    nscoord aContainingBlockWidth);
   157 #ifdef DEBUG
   158   // Reflow trace methods.  Defined in nsFrame.cpp so they have access
   159   // to the display-reflow infrastructure.
   160   static void* DisplayInitOffsetsEnter(nsIFrame* aFrame,
   161                                        nsCSSOffsetState* aState,
   162                                        nscoord aHorizontalPercentBasis,
   163                                        nscoord aVerticalPercentBasis,
   164                                        const nsMargin* aBorder,
   165                                        const nsMargin* aPadding);
   166   static void DisplayInitOffsetsExit(nsIFrame* aFrame,
   167                                      nsCSSOffsetState* aState,
   168                                      void* aValue);
   169 #endif
   171 private:
   172   /**
   173    * Computes margin values from the specified margin style information, and
   174    * fills in the mComputedMargin member.
   175    *
   176    * @param aHorizontalPercentBasis
   177    *    Length to use for resolving percentage margin values in the horizontal
   178    *    axis. Usually the containing block width.
   179    * @param aVerticalPercentBasis
   180    *    Length to use for resolving percentage margin values in the vertical
   181    *    axis.  Usually the containing block width, per CSS21 sec 8.3, but may
   182    *    be the containing block *height*, e.g. in CSS3 Flexbox and Grid.
   183    * @return true if the margin is dependent on the containing block size.
   184    */
   185   bool ComputeMargin(nscoord aHorizontalPercentBasis,
   186                      nscoord aVerticalPercentBasis);
   188   /**
   189    * Computes padding values from the specified padding style information, and
   190    * fills in the mComputedPadding member.
   191    *
   192    * @param aHorizontalPercentBasis
   193    *    Length to use for resolving percentage padding values in the horizontal
   194    *    axis. Usually the containing block width.
   195    * @param aVerticalPercentBasis
   196    *    Length to use for resolving percentage padding values in the vertical
   197    *    axis.  Usually the containing block width, per CSS21 sec 8.4, but may
   198    *    be the containing block *height* in e.g. CSS3 Flexbox and Grid.
   199    * @return true if the padding is dependent on the containing block size.
   200    */
   201    bool ComputePadding(nscoord aHorizontalPercentBasis,
   202                        nscoord aVerticalPercentBasis, nsIAtom* aFrameType);
   204 protected:
   206   void InitOffsets(nscoord aHorizontalPercentBasis,
   207                    nscoord aVerticalPercentBasis,
   208                    nsIAtom* aFrameType,
   209                    const nsMargin *aBorder = nullptr,
   210                    const nsMargin *aPadding = nullptr);
   212   /*
   213    * Convert nsStyleCoord to nscoord when percentages depend on the
   214    * containing block width, and enumerated values are for width,
   215    * min-width, or max-width.  Does not handle auto widths.
   216    */
   217   inline nscoord ComputeWidthValue(nscoord aContainingBlockWidth,
   218                                    nscoord aContentEdgeToBoxSizing,
   219                                    nscoord aBoxSizingToMarginEdge,
   220                                    const nsStyleCoord& aCoord);
   221   // same as previous, but using mComputedBorderPadding, mComputedPadding,
   222   // and mComputedMargin
   223   nscoord ComputeWidthValue(nscoord aContainingBlockWidth,
   224                             uint8_t aBoxSizing,
   225                             const nsStyleCoord& aCoord);
   227   nscoord ComputeHeightValue(nscoord aContainingBlockHeight,
   228                              uint8_t aBoxSizing,
   229                              const nsStyleCoord& aCoord);
   230 };
   232 /**
   233  * State passed to a frame during reflow or intrinsic size calculation.
   234  *
   235  * XXX Refactor so only a base class (nsSizingState?) is used for intrinsic
   236  * size calculation.
   237  *
   238  * @see nsIFrame#Reflow()
   239  */
   240 struct nsHTMLReflowState : public nsCSSOffsetState {
   241   // the reflow states are linked together. this is the pointer to the
   242   // parent's reflow state
   243   const nsHTMLReflowState* parentReflowState;
   245   // pointer to the float manager associated with this area
   246   nsFloatManager* mFloatManager;
   248   // LineLayout object (only for inline reflow; set to nullptr otherwise)
   249   nsLineLayout*    mLineLayout;
   251   // The appropriate reflow state for the containing block (for
   252   // percentage widths, etc.) of this reflow state's frame.
   253   const nsHTMLReflowState *mCBReflowState;
   255   // The type of frame, from css's perspective. This value is
   256   // initialized by the Init method below.
   257   nsCSSFrameType   mFrameType;
   259   // The amount the in-flow position of the block is moving vertically relative
   260   // to its previous in-flow position (i.e. the amount the line containing the
   261   // block is moving).
   262   // This should be zero for anything which is not a block outside, and it
   263   // should be zero for anything which has a non-block parent.
   264   // The intended use of this value is to allow the accurate determination
   265   // of the potential impact of a float
   266   // This takes on an arbitrary value the first time a block is reflowed
   267   nscoord mBlockDelta;
   269   // Accessors for the private fields below. Forcing all callers to use these
   270   // will allow us to introduce logical-coordinate versions and gradually
   271   // change clients from physical to logical as needed; and potentially switch
   272   // the internal fields from physical to logical coordinates in due course,
   273   // while maintaining compatibility with not-yet-updated code.
   274   nscoord AvailableWidth() const { return mAvailableWidth; }
   275   nscoord AvailableHeight() const { return mAvailableHeight; }
   276   nscoord ComputedWidth() const { return mComputedWidth; }
   277   nscoord ComputedHeight() const { return mComputedHeight; }
   278   nscoord ComputedMinWidth() const { return mComputedMinWidth; }
   279   nscoord ComputedMaxWidth() const { return mComputedMaxWidth; }
   280   nscoord ComputedMinHeight() const { return mComputedMinHeight; }
   281   nscoord ComputedMaxHeight() const { return mComputedMaxHeight; }
   283   nscoord& AvailableWidth() { return mAvailableWidth; }
   284   nscoord& AvailableHeight() { return mAvailableHeight; }
   285   nscoord& ComputedWidth() { return mComputedWidth; }
   286   nscoord& ComputedHeight() { return mComputedHeight; }
   287   nscoord& ComputedMinWidth() { return mComputedMinWidth; }
   288   nscoord& ComputedMaxWidth() { return mComputedMaxWidth; }
   289   nscoord& ComputedMinHeight() { return mComputedMinHeight; }
   290   nscoord& ComputedMaxHeight() { return mComputedMaxHeight; }
   292   // ISize and BSize are logical-coordinate dimensions:
   293   // ISize is the size in the writing mode's inline direction (which equates to
   294   // width in horizontal writing modes, height in vertical ones), and BSize is
   295   // the size in the block-progression direction.
   296   nscoord AvailableISize() const
   297     { return mWritingMode.IsVertical() ? mAvailableHeight : mAvailableWidth; }
   298   nscoord AvailableBSize() const
   299     { return mWritingMode.IsVertical() ? mAvailableWidth : mAvailableHeight; }
   300   nscoord ComputedISize() const
   301     { return mWritingMode.IsVertical() ? mComputedHeight : mComputedWidth; }
   302   nscoord ComputedBSize() const
   303     { return mWritingMode.IsVertical() ? mComputedWidth : mComputedHeight; }
   304   nscoord ComputedMinISize() const
   305     { return mWritingMode.IsVertical() ? mComputedMinHeight : mComputedMinWidth; }
   306   nscoord ComputedMaxISize() const
   307     { return mWritingMode.IsVertical() ? mComputedMaxHeight : mComputedMaxWidth; }
   308   nscoord ComputedMinBSize() const
   309     { return mWritingMode.IsVertical() ? mComputedMinWidth : mComputedMinHeight; }
   310   nscoord ComputedMaxBSize() const
   311     { return mWritingMode.IsVertical() ? mComputedMaxWidth : mComputedMaxHeight; }
   313   nscoord& AvailableISize()
   314     { return mWritingMode.IsVertical() ? mAvailableHeight : mAvailableWidth; }
   315   nscoord& AvailableBSize()
   316     { return mWritingMode.IsVertical() ? mAvailableWidth : mAvailableHeight; }
   317   nscoord& ComputedISize()
   318     { return mWritingMode.IsVertical() ? mComputedHeight : mComputedWidth; }
   319   nscoord& ComputedBSize()
   320     { return mWritingMode.IsVertical() ? mComputedWidth : mComputedHeight; }
   321   nscoord& ComputedMinISize()
   322     { return mWritingMode.IsVertical() ? mComputedMinHeight : mComputedMinWidth; }
   323   nscoord& ComputedMaxISize()
   324     { return mWritingMode.IsVertical() ? mComputedMaxHeight : mComputedMaxWidth; }
   325   nscoord& ComputedMinBSize()
   326     { return mWritingMode.IsVertical() ? mComputedMinWidth : mComputedMinHeight; }
   327   nscoord& ComputedMaxBSize()
   328     { return mWritingMode.IsVertical() ? mComputedMaxWidth : mComputedMaxHeight; }
   330   // XXX this will need to change when we make mComputedOffsets logical;
   331   // we won't be able to return a reference for the physical offsets
   332   const nsMargin& ComputedPhysicalOffsets() const { return mComputedOffsets; }
   333   nsMargin& ComputedPhysicalOffsets() { return mComputedOffsets; }
   335   LogicalMargin ComputedLogicalOffsets() const
   336     { return LogicalMargin(mWritingMode, mComputedOffsets); }
   338 private:
   339   // the available width in which to reflow the frame. The space
   340   // represents the amount of room for the frame's margin, border,
   341   // padding, and content area. The frame size you choose should fit
   342   // within the available width.
   343   nscoord              mAvailableWidth;
   345   // A value of NS_UNCONSTRAINEDSIZE for the available height means
   346   // you can choose whatever size you want. In galley mode the
   347   // available height is always NS_UNCONSTRAINEDSIZE, and only page
   348   // mode or multi-column layout involves a constrained height. The
   349   // element's the top border and padding, and content, must fit. If the
   350   // element is complete after reflow then its bottom border, padding
   351   // and margin (and similar for its complete ancestors) will need to
   352   // fit in this height.
   353   nscoord              mAvailableHeight;
   355   // The computed width specifies the frame's content area width, and it does
   356   // not apply to inline non-replaced elements
   357   //
   358   // For replaced inline frames, a value of NS_INTRINSICSIZE means you should
   359   // use your intrinsic width as the computed width
   360   //
   361   // For block-level frames, the computed width is based on the width of the
   362   // containing block, the margin/border/padding areas, and the min/max width.
   363   nscoord          mComputedWidth; 
   365   // The computed height specifies the frame's content height, and it does
   366   // not apply to inline non-replaced elements
   367   //
   368   // For replaced inline frames, a value of NS_INTRINSICSIZE means you should
   369   // use your intrinsic height as the computed height
   370   //
   371   // For non-replaced block-level frames in the flow and floated, a value of
   372   // NS_AUTOHEIGHT means you choose a height to shrink wrap around the normal
   373   // flow child frames. The height must be within the limit of the min/max
   374   // height if there is such a limit
   375   //
   376   // For replaced block-level frames, a value of NS_INTRINSICSIZE
   377   // means you use your intrinsic height as the computed height
   378   nscoord          mComputedHeight;
   380   // Computed values for 'left/top/right/bottom' offsets. Only applies to
   381   // 'positioned' elements. These are PHYSICAL coordinates (for now).
   382   nsMargin         mComputedOffsets;
   384   // Computed values for 'min-width/max-width' and 'min-height/max-height'
   385   // XXXldb The width ones here should go; they should be needed only
   386   // internally.
   387   nscoord          mComputedMinWidth, mComputedMaxWidth;
   388   nscoord          mComputedMinHeight, mComputedMaxHeight;
   390 public:
   391   // Cached pointers to the various style structs used during intialization
   392   const nsStyleDisplay*    mStyleDisplay;
   393   const nsStyleVisibility* mStyleVisibility;
   394   const nsStylePosition*   mStylePosition;
   395   const nsStyleBorder*     mStyleBorder;
   396   const nsStyleMargin*     mStyleMargin;
   397   const nsStylePadding*    mStylePadding;
   398   const nsStyleText*       mStyleText;
   400   bool IsFloating() const;
   402   uint8_t GetDisplay() const;
   404   // a frame (e.g. nsTableCellFrame) which may need to generate a special 
   405   // reflow for percent height calculations 
   406   nsIPercentHeightObserver* mPercentHeightObserver;
   408   // CSS margin collapsing sometimes requires us to reflow
   409   // optimistically assuming that margins collapse to see if clearance
   410   // is required. When we discover that clearance is required, we
   411   // store the frame in which clearance was discovered to the location
   412   // requested here.
   413   nsIFrame** mDiscoveredClearance;
   415   // This value keeps track of how deeply nested a given reflow state
   416   // is from the top of the frame tree.
   417   int16_t mReflowDepth;
   419   struct ReflowStateFlags {
   420     uint16_t mSpecialHeightReflow:1; // used by tables to communicate special reflow (in process) to handle
   421                                      // percent height frames inside cells which may not have computed heights
   422     uint16_t mNextInFlowUntouched:1; // nothing in the frame's next-in-flow (or its descendants)
   423                                      // is changing
   424     uint16_t mIsTopOfPage:1;         // Is the current context at the top of a
   425                                      // page?  When true, we force something
   426                                      // that's too tall for a page/column to
   427                                      // fit anyway to avoid infinite loops.
   428     uint16_t mHasClearance:1;        // Block has clearance
   429     uint16_t mAssumingHScrollbar:1;  // parent frame is an nsIScrollableFrame and it
   430                                      // is assuming a horizontal scrollbar
   431     uint16_t mAssumingVScrollbar:1;  // parent frame is an nsIScrollableFrame and it
   432                                      // is assuming a vertical scrollbar
   434     uint16_t mHResize:1;             // Is frame (a) not dirty and (b) a
   435                                      // different width than before?
   437     uint16_t mVResize:1;             // Is frame (a) not dirty and (b) a
   438                                      // different height than before or
   439                                      // (potentially) in a context where
   440                                      // percent heights have a different
   441                                      // basis?
   442     uint16_t mTableIsSplittable:1;   // tables are splittable, this should happen only inside a page
   443                                      // and never insider a column frame
   444     uint16_t mHeightDependsOnAncestorCell:1;   // Does frame height depend on
   445                                                // an ancestor table-cell?
   446     uint16_t mIsColumnBalancing:1;   // nsColumnSetFrame is balancing columns
   447     uint16_t mIsFlexContainerMeasuringHeight:1; // nsFlexContainerFrame is
   448                                                 // reflowing this child to
   449                                                 // measure its intrinsic height.
   450     uint16_t mDummyParentReflowState:1; // a "fake" reflow state made
   451                                         // in order to be the parent
   452                                         // of a real one
   453     uint16_t mMustReflowPlaceholders:1; // Should this frame reflow its place-
   454                                         // holder children? If the available
   455                                         // height of this frame didn't change,
   456                                         // but its in a paginated environment
   457                                         // (e.g. columns), it should always
   458                                         // reflow its placeholder children.
   459   } mFlags;
   461   // Note: The copy constructor is written by the compiler automatically. You
   462   // can use that and then override specific values if you want, or you can
   463   // call Init as desired...
   465   /**
   466    * Initialize a ROOT reflow state.
   467    *
   468    * @param aPresContext Must be equal to aFrame->PresContext().
   469    * @param aFrame The frame for whose reflow state is being constructed.
   470    * @param aRenderingContext The rendering context to be used for measurements.
   471    * @param aAvailableSpace See comments for availableHeight and availableWidth
   472    *        members.
   473    * @param aFlags A set of flags used for additional boolean parameters (see
   474    *        below).
   475    */
   476   nsHTMLReflowState(nsPresContext*           aPresContext,
   477                     nsIFrame*                aFrame,
   478                     nsRenderingContext*      aRenderingContext,
   479                     const nsSize&            aAvailableSpace,
   480                     uint32_t                 aFlags = 0);
   482   /**
   483    * Initialize a reflow state for a child frame's reflow. Some parts of the
   484    * state are copied from the parent's reflow state. The remainder is computed.
   485    *
   486    * @param aPresContext Must be equal to aFrame->PresContext().
   487    * @param aParentReflowState A reference to an nsHTMLReflowState object that
   488    *        is to be the parent of this object.
   489    * @param aFrame The frame for whose reflow state is being constructed.
   490    * @param aAvailableSpace See comments for availableHeight and availableWidth
   491    *        members.
   492    * @param aContainingBlockWidth An optional width, in app units, that is used
   493    *        by absolute positioning code to override default containing block
   494    *        width.
   495    * @param aContainingBlockHeight An optional height, in app units, that is
   496    *        used by absolute positioning code to override default containing
   497    *        block height.
   498    * @param aFlags A set of flags used for additional boolean parameters (see
   499    *        below).
   500    */
   501   nsHTMLReflowState(nsPresContext*           aPresContext,
   502                     const nsHTMLReflowState& aParentReflowState,
   503                     nsIFrame*                aFrame,
   504                     const nsSize&            aAvailableSpace,
   505                     nscoord                  aContainingBlockWidth = -1,
   506                     nscoord                  aContainingBlockHeight = -1,
   507                     uint32_t                 aFlags = 0);
   509   // Values for |aFlags| passed to constructor
   510   enum {
   511     // Indicates that the parent of this reflow state is "fake" (see
   512     // mDummyParentReflowState in mFlags).
   513     DUMMY_PARENT_REFLOW_STATE = (1<<0),
   515     // Indicates that the calling function will initialize the reflow state, and
   516     // that the constructor should not call Init().
   517     CALLER_WILL_INIT = (1<<1)
   518   };
   520   // This method initializes various data members. It is automatically
   521   // called by the various constructors
   522   void Init(nsPresContext* aPresContext,
   523             nscoord         aContainingBlockWidth = -1,
   524             nscoord         aContainingBlockHeight = -1,
   525             const nsMargin* aBorder = nullptr,
   526             const nsMargin* aPadding = nullptr);
   527   /**
   528    * Find the content width of the containing block of aReflowState
   529    */
   530   static nscoord
   531     GetContainingBlockContentWidth(const nsHTMLReflowState* aReflowState);
   533   /**
   534    * Calculate the used line-height property. The return value will be >= 0.
   535    */
   536   nscoord CalcLineHeight() const;
   538   /**
   539    * Same as CalcLineHeight() above, but doesn't need a reflow state.
   540    *
   541    * @param aBlockHeight The computed height of the content rect of the block
   542    *                     that the line should fill.
   543    *                     Only used with line-height:-moz-block-height.
   544    *                     NS_AUTOHEIGHT results in a normal line-height for
   545    *                     line-height:-moz-block-height.
   546    * @param aFontSizeInflation The result of the appropriate
   547    *                           nsLayoutUtils::FontSizeInflationFor call,
   548    *                           or 1.0 if during intrinsic size
   549    *                           calculation.
   550    */
   551   static nscoord CalcLineHeight(nsIContent* aContent,
   552                                 nsStyleContext* aStyleContext,
   553                                 nscoord aBlockHeight,
   554                                 float aFontSizeInflation);
   557   void ComputeContainingBlockRectangle(nsPresContext*          aPresContext,
   558                                        const nsHTMLReflowState* aContainingBlockRS,
   559                                        nscoord&                 aContainingBlockWidth,
   560                                        nscoord&                 aContainingBlockHeight);
   562   /**
   563    * Apply the mComputed(Min/Max)Width constraints to the content
   564    * size computed so far.
   565    */
   566   nscoord ApplyMinMaxWidth(nscoord aWidth) const {
   567     if (NS_UNCONSTRAINEDSIZE != ComputedMaxWidth()) {
   568       aWidth = std::min(aWidth, ComputedMaxWidth());
   569     }
   570     return std::max(aWidth, ComputedMinWidth());
   571   }
   573   /**
   574    * Apply the mComputed(Min/Max)Height constraints to the content
   575    * size computed so far.
   576    *
   577    * @param aHeight The height that we've computed an to which we want to apply
   578    *        min/max constraints.
   579    * @param aConsumed The amount of the computed height that was consumed by
   580    *        our prev-in-flows.
   581    */
   582   nscoord ApplyMinMaxHeight(nscoord aHeight, nscoord aConsumed = 0) const {
   583     aHeight += aConsumed;
   585     if (NS_UNCONSTRAINEDSIZE != ComputedMaxHeight()) {
   586       aHeight = std::min(aHeight, ComputedMaxHeight());
   587     }
   589     if (NS_UNCONSTRAINEDSIZE != ComputedMinHeight()) {
   590       aHeight = std::max(aHeight, ComputedMinHeight());
   591     }
   593     return aHeight - aConsumed;
   594   }
   596   bool ShouldReflowAllKids() const {
   597     // Note that we could make a stronger optimization for mVResize if
   598     // we use it in a ShouldReflowChild test that replaces the current
   599     // checks of NS_FRAME_IS_DIRTY | NS_FRAME_HAS_DIRTY_CHILDREN, if it
   600     // were tested there along with NS_FRAME_CONTAINS_RELATIVE_HEIGHT.
   601     // This would need to be combined with a slight change in which
   602     // frames NS_FRAME_CONTAINS_RELATIVE_HEIGHT is marked on.
   603     return (frame->GetStateBits() & NS_FRAME_IS_DIRTY) ||
   604            mFlags.mHResize ||
   605            (mFlags.mVResize && 
   606             (frame->GetStateBits() & NS_FRAME_CONTAINS_RELATIVE_HEIGHT));
   607   }
   609   // This method doesn't apply min/max computed widths to the value passed in.
   610   void SetComputedWidth(nscoord aComputedWidth);
   612   // This method doesn't apply min/max computed heights to the value passed in.
   613   void SetComputedHeight(nscoord aComputedHeight);
   615   void SetComputedHeightWithoutResettingResizeFlags(nscoord aComputedHeight) {
   616     // Viewport frames reset the computed height on a copy of their reflow
   617     // state when reflowing fixed-pos kids.  In that case we actually don't
   618     // want to mess with the resize flags, because comparing the frame's rect
   619     // to the munged computed width is pointless.
   620     ComputedHeight() = aComputedHeight;
   621   }
   623   void SetTruncated(const nsHTMLReflowMetrics& aMetrics, nsReflowStatus* aStatus) const;
   625   bool WillReflowAgainForClearance() const {
   626     return mDiscoveredClearance && *mDiscoveredClearance;
   627   }
   629   // Compute the offsets for a relative position element
   630   static void ComputeRelativeOffsets(uint8_t aCBDirection,
   631                                      nsIFrame* aFrame,
   632                                      nscoord aContainingBlockWidth,
   633                                      nscoord aContainingBlockHeight,
   634                                      nsMargin& aComputedOffsets);
   636   // If a relatively positioned element, adjust the position appropriately.
   637   static void ApplyRelativePositioning(nsIFrame* aFrame,
   638                                        const nsMargin& aComputedOffsets,
   639                                        nsPoint* aPosition);
   641   void ApplyRelativePositioning(nsPoint* aPosition) const {
   642     ApplyRelativePositioning(frame, ComputedPhysicalOffsets(), aPosition);
   643   }
   645 #ifdef DEBUG
   646   // Reflow trace methods.  Defined in nsFrame.cpp so they have access
   647   // to the display-reflow infrastructure.
   648   static void* DisplayInitConstraintsEnter(nsIFrame* aFrame,
   649                                            nsHTMLReflowState* aState,
   650                                            nscoord aCBWidth,
   651                                            nscoord aCBHeight,
   652                                            const nsMargin* aBorder,
   653                                            const nsMargin* aPadding);
   654   static void DisplayInitConstraintsExit(nsIFrame* aFrame,
   655                                          nsHTMLReflowState* aState,
   656                                          void* aValue);
   657   static void* DisplayInitFrameTypeEnter(nsIFrame* aFrame,
   658                                          nsHTMLReflowState* aState);
   659   static void DisplayInitFrameTypeExit(nsIFrame* aFrame,
   660                                        nsHTMLReflowState* aState,
   661                                        void* aValue);
   662 #endif
   664 protected:
   665   void InitFrameType(nsIAtom* aFrameType);
   666   void InitCBReflowState();
   667   void InitResizeFlags(nsPresContext* aPresContext, nsIAtom* aFrameType);
   669   void InitConstraints(nsPresContext* aPresContext,
   670                        nscoord         aContainingBlockWidth,
   671                        nscoord         aContainingBlockHeight,
   672                        const nsMargin* aBorder,
   673                        const nsMargin* aPadding,
   674                        nsIAtom*        aFrameType);
   676   // Returns the nearest containing block or block frame (whether or not
   677   // it is a containing block) for the specified frame.  Also returns
   678   // the left edge and width of the containing block's content area.
   679   // These are returned in the coordinate space of the containing block.
   680   nsIFrame* GetHypotheticalBoxContainer(nsIFrame* aFrame,
   681                                         nscoord& aCBLeftEdge,
   682                                         nscoord& aCBWidth);
   684   void CalculateHypotheticalBox(nsPresContext*    aPresContext,
   685                                 nsIFrame*         aPlaceholderFrame,
   686                                 nsIFrame*         aContainingBlock,
   687                                 nscoord           aBlockLeftContentEdge,
   688                                 nscoord           aBlockContentWidth,
   689                                 const nsHTMLReflowState* cbrs,
   690                                 nsHypotheticalBox& aHypotheticalBox,
   691                                 nsIAtom*          aFrameType);
   693   void InitAbsoluteConstraints(nsPresContext* aPresContext,
   694                                const nsHTMLReflowState* cbrs,
   695                                nscoord aContainingBlockWidth,
   696                                nscoord aContainingBlockHeight,
   697                                nsIAtom* aFrameType);
   699   // Calculates the computed values for the 'min-Width', 'max-Width',
   700   // 'min-Height', and 'max-Height' properties, and stores them in the assorted
   701   // data members
   702   void ComputeMinMaxValues(nscoord                  aContainingBlockWidth,
   703                            nscoord                  aContainingBlockHeight,
   704                            const nsHTMLReflowState* aContainingBlockRS);
   706   void CalculateHorizBorderPaddingMargin(nscoord aContainingBlockWidth,
   707                                          nscoord* aInsideBoxSizing,
   708                                          nscoord* aOutsideBoxSizing);
   710   void CalculateBlockSideMargins(nscoord aAvailWidth,
   711                                  nscoord aComputedWidth,
   712                                  nsIAtom* aFrameType);
   713 };
   715 #endif /* nsHTMLReflowState_h___ */

mercurial