1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 1.2 +++ b/layout/generic/nsHTMLReflowState.h Wed Dec 31 06:09:35 2014 +0100 1.3 @@ -0,0 +1,716 @@ 1.4 +/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ 1.5 +/* This Source Code Form is subject to the terms of the Mozilla Public 1.6 + * License, v. 2.0. If a copy of the MPL was not distributed with this 1.7 + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ 1.8 + 1.9 +/* struct containing the input to nsIFrame::Reflow */ 1.10 + 1.11 +#ifndef nsHTMLReflowState_h___ 1.12 +#define nsHTMLReflowState_h___ 1.13 + 1.14 +#include "nsMargin.h" 1.15 +#include "nsStyleCoord.h" 1.16 +#include "nsIFrame.h" 1.17 +#include "mozilla/Assertions.h" 1.18 +#include <algorithm> 1.19 + 1.20 +class nsPresContext; 1.21 +class nsRenderingContext; 1.22 +class nsFloatManager; 1.23 +class nsLineLayout; 1.24 +class nsIPercentHeightObserver; 1.25 +struct nsHypotheticalBox; 1.26 + 1.27 +/** 1.28 + * @return aValue clamped to [aMinValue, aMaxValue]. 1.29 + * 1.30 + * @note This function needs to handle aMinValue > aMaxValue. In that case, 1.31 + * aMinValue is returned. 1.32 + * @see http://www.w3.org/TR/CSS21/visudet.html#min-max-widths 1.33 + * @see http://www.w3.org/TR/CSS21/visudet.html#min-max-heights 1.34 + */ 1.35 +template <class NumericType> 1.36 +NumericType 1.37 +NS_CSS_MINMAX(NumericType aValue, NumericType aMinValue, NumericType aMaxValue) 1.38 +{ 1.39 + NumericType result = aValue; 1.40 + if (aMaxValue < result) 1.41 + result = aMaxValue; 1.42 + if (aMinValue > result) 1.43 + result = aMinValue; 1.44 + return result; 1.45 +} 1.46 + 1.47 +/** 1.48 + * CSS Frame type. Included as part of the reflow state. 1.49 + */ 1.50 +typedef uint32_t nsCSSFrameType; 1.51 + 1.52 +#define NS_CSS_FRAME_TYPE_UNKNOWN 0 1.53 +#define NS_CSS_FRAME_TYPE_INLINE 1 1.54 +#define NS_CSS_FRAME_TYPE_BLOCK 2 /* block-level in normal flow */ 1.55 +#define NS_CSS_FRAME_TYPE_FLOATING 3 1.56 +#define NS_CSS_FRAME_TYPE_ABSOLUTE 4 1.57 +#define NS_CSS_FRAME_TYPE_INTERNAL_TABLE 5 /* row group frame, row frame, cell frame, ... */ 1.58 + 1.59 +/** 1.60 + * Bit-flag that indicates whether the element is replaced. Applies to inline, 1.61 + * block-level, floating, and absolutely positioned elements 1.62 + */ 1.63 +#define NS_CSS_FRAME_TYPE_REPLACED 0x08000 1.64 + 1.65 +/** 1.66 + * Bit-flag that indicates that the element is replaced and contains a block 1.67 + * (eg some form controls). Applies to inline, block-level, floating, and 1.68 + * absolutely positioned elements. Mutually exclusive with 1.69 + * NS_CSS_FRAME_TYPE_REPLACED. 1.70 + */ 1.71 +#define NS_CSS_FRAME_TYPE_REPLACED_CONTAINS_BLOCK 0x10000 1.72 + 1.73 +/** 1.74 + * Helper macros for telling whether items are replaced 1.75 + */ 1.76 +#define NS_FRAME_IS_REPLACED_NOBLOCK(_ft) \ 1.77 + (NS_CSS_FRAME_TYPE_REPLACED == ((_ft) & NS_CSS_FRAME_TYPE_REPLACED)) 1.78 + 1.79 +#define NS_FRAME_IS_REPLACED(_ft) \ 1.80 + (NS_FRAME_IS_REPLACED_NOBLOCK(_ft) || \ 1.81 + NS_FRAME_IS_REPLACED_CONTAINS_BLOCK(_ft)) 1.82 + 1.83 +#define NS_FRAME_REPLACED(_ft) \ 1.84 + (NS_CSS_FRAME_TYPE_REPLACED | (_ft)) 1.85 + 1.86 +#define NS_FRAME_IS_REPLACED_CONTAINS_BLOCK(_ft) \ 1.87 + (NS_CSS_FRAME_TYPE_REPLACED_CONTAINS_BLOCK == \ 1.88 + ((_ft) & NS_CSS_FRAME_TYPE_REPLACED_CONTAINS_BLOCK)) 1.89 + 1.90 +#define NS_FRAME_REPLACED_CONTAINS_BLOCK(_ft) \ 1.91 + (NS_CSS_FRAME_TYPE_REPLACED_CONTAINS_BLOCK | (_ft)) 1.92 + 1.93 +/** 1.94 + * A macro to extract the type. Masks off the 'replaced' bit-flag 1.95 + */ 1.96 +#define NS_FRAME_GET_TYPE(_ft) \ 1.97 + ((_ft) & ~(NS_CSS_FRAME_TYPE_REPLACED | \ 1.98 + NS_CSS_FRAME_TYPE_REPLACED_CONTAINS_BLOCK)) 1.99 + 1.100 +// A base class of nsHTMLReflowState that computes only the padding, 1.101 +// border, and margin, since those values are needed more often. 1.102 +struct nsCSSOffsetState { 1.103 +public: 1.104 + typedef mozilla::WritingMode WritingMode; 1.105 + typedef mozilla::LogicalMargin LogicalMargin; 1.106 + 1.107 + // the frame being reflowed 1.108 + nsIFrame* frame; 1.109 + 1.110 + // rendering context to use for measurement 1.111 + nsRenderingContext* rendContext; 1.112 + 1.113 + const nsMargin& ComputedPhysicalMargin() const { return mComputedMargin; } 1.114 + const nsMargin& ComputedPhysicalBorderPadding() const { return mComputedBorderPadding; } 1.115 + const nsMargin& ComputedPhysicalPadding() const { return mComputedPadding; } 1.116 + 1.117 + // We may need to eliminate the (few) users of these writable-reference accessors 1.118 + // as part of migrating to logical coordinates. 1.119 + nsMargin& ComputedPhysicalMargin() { return mComputedMargin; } 1.120 + nsMargin& ComputedPhysicalBorderPadding() { return mComputedBorderPadding; } 1.121 + nsMargin& ComputedPhysicalPadding() { return mComputedPadding; } 1.122 + 1.123 + LogicalMargin ComputedLogicalMargin() const 1.124 + { return LogicalMargin(mWritingMode, mComputedMargin); } 1.125 + LogicalMargin ComputedLogicalBorderPadding() const 1.126 + { return LogicalMargin(mWritingMode, mComputedBorderPadding); } 1.127 + LogicalMargin ComputedLogicalPadding() const 1.128 + { return LogicalMargin(mWritingMode, mComputedPadding); } 1.129 + 1.130 + WritingMode GetWritingMode() const { return mWritingMode; } 1.131 + 1.132 +protected: 1.133 + // cached copy of the frame's writing-mode, for logical coordinates 1.134 + WritingMode mWritingMode; 1.135 + 1.136 + // These are PHYSICAL coordinates (for now). 1.137 + // Will probably become logical in due course. 1.138 + 1.139 + // Computed margin values 1.140 + nsMargin mComputedMargin; 1.141 + 1.142 + // Cached copy of the border + padding values 1.143 + nsMargin mComputedBorderPadding; 1.144 + 1.145 + // Computed padding values 1.146 + nsMargin mComputedPadding; 1.147 + 1.148 +public: 1.149 + // Callers using this constructor must call InitOffsets on their own. 1.150 + nsCSSOffsetState(nsIFrame *aFrame, nsRenderingContext *aRenderingContext) 1.151 + : frame(aFrame) 1.152 + , rendContext(aRenderingContext) 1.153 + , mWritingMode(aFrame->GetWritingMode()) 1.154 + { 1.155 + } 1.156 + 1.157 + nsCSSOffsetState(nsIFrame *aFrame, nsRenderingContext *aRenderingContext, 1.158 + nscoord aContainingBlockWidth); 1.159 + 1.160 +#ifdef DEBUG 1.161 + // Reflow trace methods. Defined in nsFrame.cpp so they have access 1.162 + // to the display-reflow infrastructure. 1.163 + static void* DisplayInitOffsetsEnter(nsIFrame* aFrame, 1.164 + nsCSSOffsetState* aState, 1.165 + nscoord aHorizontalPercentBasis, 1.166 + nscoord aVerticalPercentBasis, 1.167 + const nsMargin* aBorder, 1.168 + const nsMargin* aPadding); 1.169 + static void DisplayInitOffsetsExit(nsIFrame* aFrame, 1.170 + nsCSSOffsetState* aState, 1.171 + void* aValue); 1.172 +#endif 1.173 + 1.174 +private: 1.175 + /** 1.176 + * Computes margin values from the specified margin style information, and 1.177 + * fills in the mComputedMargin member. 1.178 + * 1.179 + * @param aHorizontalPercentBasis 1.180 + * Length to use for resolving percentage margin values in the horizontal 1.181 + * axis. Usually the containing block width. 1.182 + * @param aVerticalPercentBasis 1.183 + * Length to use for resolving percentage margin values in the vertical 1.184 + * axis. Usually the containing block width, per CSS21 sec 8.3, but may 1.185 + * be the containing block *height*, e.g. in CSS3 Flexbox and Grid. 1.186 + * @return true if the margin is dependent on the containing block size. 1.187 + */ 1.188 + bool ComputeMargin(nscoord aHorizontalPercentBasis, 1.189 + nscoord aVerticalPercentBasis); 1.190 + 1.191 + /** 1.192 + * Computes padding values from the specified padding style information, and 1.193 + * fills in the mComputedPadding member. 1.194 + * 1.195 + * @param aHorizontalPercentBasis 1.196 + * Length to use for resolving percentage padding values in the horizontal 1.197 + * axis. Usually the containing block width. 1.198 + * @param aVerticalPercentBasis 1.199 + * Length to use for resolving percentage padding values in the vertical 1.200 + * axis. Usually the containing block width, per CSS21 sec 8.4, but may 1.201 + * be the containing block *height* in e.g. CSS3 Flexbox and Grid. 1.202 + * @return true if the padding is dependent on the containing block size. 1.203 + */ 1.204 + bool ComputePadding(nscoord aHorizontalPercentBasis, 1.205 + nscoord aVerticalPercentBasis, nsIAtom* aFrameType); 1.206 + 1.207 +protected: 1.208 + 1.209 + void InitOffsets(nscoord aHorizontalPercentBasis, 1.210 + nscoord aVerticalPercentBasis, 1.211 + nsIAtom* aFrameType, 1.212 + const nsMargin *aBorder = nullptr, 1.213 + const nsMargin *aPadding = nullptr); 1.214 + 1.215 + /* 1.216 + * Convert nsStyleCoord to nscoord when percentages depend on the 1.217 + * containing block width, and enumerated values are for width, 1.218 + * min-width, or max-width. Does not handle auto widths. 1.219 + */ 1.220 + inline nscoord ComputeWidthValue(nscoord aContainingBlockWidth, 1.221 + nscoord aContentEdgeToBoxSizing, 1.222 + nscoord aBoxSizingToMarginEdge, 1.223 + const nsStyleCoord& aCoord); 1.224 + // same as previous, but using mComputedBorderPadding, mComputedPadding, 1.225 + // and mComputedMargin 1.226 + nscoord ComputeWidthValue(nscoord aContainingBlockWidth, 1.227 + uint8_t aBoxSizing, 1.228 + const nsStyleCoord& aCoord); 1.229 + 1.230 + nscoord ComputeHeightValue(nscoord aContainingBlockHeight, 1.231 + uint8_t aBoxSizing, 1.232 + const nsStyleCoord& aCoord); 1.233 +}; 1.234 + 1.235 +/** 1.236 + * State passed to a frame during reflow or intrinsic size calculation. 1.237 + * 1.238 + * XXX Refactor so only a base class (nsSizingState?) is used for intrinsic 1.239 + * size calculation. 1.240 + * 1.241 + * @see nsIFrame#Reflow() 1.242 + */ 1.243 +struct nsHTMLReflowState : public nsCSSOffsetState { 1.244 + // the reflow states are linked together. this is the pointer to the 1.245 + // parent's reflow state 1.246 + const nsHTMLReflowState* parentReflowState; 1.247 + 1.248 + // pointer to the float manager associated with this area 1.249 + nsFloatManager* mFloatManager; 1.250 + 1.251 + // LineLayout object (only for inline reflow; set to nullptr otherwise) 1.252 + nsLineLayout* mLineLayout; 1.253 + 1.254 + // The appropriate reflow state for the containing block (for 1.255 + // percentage widths, etc.) of this reflow state's frame. 1.256 + const nsHTMLReflowState *mCBReflowState; 1.257 + 1.258 + // The type of frame, from css's perspective. This value is 1.259 + // initialized by the Init method below. 1.260 + nsCSSFrameType mFrameType; 1.261 + 1.262 + // The amount the in-flow position of the block is moving vertically relative 1.263 + // to its previous in-flow position (i.e. the amount the line containing the 1.264 + // block is moving). 1.265 + // This should be zero for anything which is not a block outside, and it 1.266 + // should be zero for anything which has a non-block parent. 1.267 + // The intended use of this value is to allow the accurate determination 1.268 + // of the potential impact of a float 1.269 + // This takes on an arbitrary value the first time a block is reflowed 1.270 + nscoord mBlockDelta; 1.271 + 1.272 + // Accessors for the private fields below. Forcing all callers to use these 1.273 + // will allow us to introduce logical-coordinate versions and gradually 1.274 + // change clients from physical to logical as needed; and potentially switch 1.275 + // the internal fields from physical to logical coordinates in due course, 1.276 + // while maintaining compatibility with not-yet-updated code. 1.277 + nscoord AvailableWidth() const { return mAvailableWidth; } 1.278 + nscoord AvailableHeight() const { return mAvailableHeight; } 1.279 + nscoord ComputedWidth() const { return mComputedWidth; } 1.280 + nscoord ComputedHeight() const { return mComputedHeight; } 1.281 + nscoord ComputedMinWidth() const { return mComputedMinWidth; } 1.282 + nscoord ComputedMaxWidth() const { return mComputedMaxWidth; } 1.283 + nscoord ComputedMinHeight() const { return mComputedMinHeight; } 1.284 + nscoord ComputedMaxHeight() const { return mComputedMaxHeight; } 1.285 + 1.286 + nscoord& AvailableWidth() { return mAvailableWidth; } 1.287 + nscoord& AvailableHeight() { return mAvailableHeight; } 1.288 + nscoord& ComputedWidth() { return mComputedWidth; } 1.289 + nscoord& ComputedHeight() { return mComputedHeight; } 1.290 + nscoord& ComputedMinWidth() { return mComputedMinWidth; } 1.291 + nscoord& ComputedMaxWidth() { return mComputedMaxWidth; } 1.292 + nscoord& ComputedMinHeight() { return mComputedMinHeight; } 1.293 + nscoord& ComputedMaxHeight() { return mComputedMaxHeight; } 1.294 + 1.295 + // ISize and BSize are logical-coordinate dimensions: 1.296 + // ISize is the size in the writing mode's inline direction (which equates to 1.297 + // width in horizontal writing modes, height in vertical ones), and BSize is 1.298 + // the size in the block-progression direction. 1.299 + nscoord AvailableISize() const 1.300 + { return mWritingMode.IsVertical() ? mAvailableHeight : mAvailableWidth; } 1.301 + nscoord AvailableBSize() const 1.302 + { return mWritingMode.IsVertical() ? mAvailableWidth : mAvailableHeight; } 1.303 + nscoord ComputedISize() const 1.304 + { return mWritingMode.IsVertical() ? mComputedHeight : mComputedWidth; } 1.305 + nscoord ComputedBSize() const 1.306 + { return mWritingMode.IsVertical() ? mComputedWidth : mComputedHeight; } 1.307 + nscoord ComputedMinISize() const 1.308 + { return mWritingMode.IsVertical() ? mComputedMinHeight : mComputedMinWidth; } 1.309 + nscoord ComputedMaxISize() const 1.310 + { return mWritingMode.IsVertical() ? mComputedMaxHeight : mComputedMaxWidth; } 1.311 + nscoord ComputedMinBSize() const 1.312 + { return mWritingMode.IsVertical() ? mComputedMinWidth : mComputedMinHeight; } 1.313 + nscoord ComputedMaxBSize() const 1.314 + { return mWritingMode.IsVertical() ? mComputedMaxWidth : mComputedMaxHeight; } 1.315 + 1.316 + nscoord& AvailableISize() 1.317 + { return mWritingMode.IsVertical() ? mAvailableHeight : mAvailableWidth; } 1.318 + nscoord& AvailableBSize() 1.319 + { return mWritingMode.IsVertical() ? mAvailableWidth : mAvailableHeight; } 1.320 + nscoord& ComputedISize() 1.321 + { return mWritingMode.IsVertical() ? mComputedHeight : mComputedWidth; } 1.322 + nscoord& ComputedBSize() 1.323 + { return mWritingMode.IsVertical() ? mComputedWidth : mComputedHeight; } 1.324 + nscoord& ComputedMinISize() 1.325 + { return mWritingMode.IsVertical() ? mComputedMinHeight : mComputedMinWidth; } 1.326 + nscoord& ComputedMaxISize() 1.327 + { return mWritingMode.IsVertical() ? mComputedMaxHeight : mComputedMaxWidth; } 1.328 + nscoord& ComputedMinBSize() 1.329 + { return mWritingMode.IsVertical() ? mComputedMinWidth : mComputedMinHeight; } 1.330 + nscoord& ComputedMaxBSize() 1.331 + { return mWritingMode.IsVertical() ? mComputedMaxWidth : mComputedMaxHeight; } 1.332 + 1.333 + // XXX this will need to change when we make mComputedOffsets logical; 1.334 + // we won't be able to return a reference for the physical offsets 1.335 + const nsMargin& ComputedPhysicalOffsets() const { return mComputedOffsets; } 1.336 + nsMargin& ComputedPhysicalOffsets() { return mComputedOffsets; } 1.337 + 1.338 + LogicalMargin ComputedLogicalOffsets() const 1.339 + { return LogicalMargin(mWritingMode, mComputedOffsets); } 1.340 + 1.341 +private: 1.342 + // the available width in which to reflow the frame. The space 1.343 + // represents the amount of room for the frame's margin, border, 1.344 + // padding, and content area. The frame size you choose should fit 1.345 + // within the available width. 1.346 + nscoord mAvailableWidth; 1.347 + 1.348 + // A value of NS_UNCONSTRAINEDSIZE for the available height means 1.349 + // you can choose whatever size you want. In galley mode the 1.350 + // available height is always NS_UNCONSTRAINEDSIZE, and only page 1.351 + // mode or multi-column layout involves a constrained height. The 1.352 + // element's the top border and padding, and content, must fit. If the 1.353 + // element is complete after reflow then its bottom border, padding 1.354 + // and margin (and similar for its complete ancestors) will need to 1.355 + // fit in this height. 1.356 + nscoord mAvailableHeight; 1.357 + 1.358 + // The computed width specifies the frame's content area width, and it does 1.359 + // not apply to inline non-replaced elements 1.360 + // 1.361 + // For replaced inline frames, a value of NS_INTRINSICSIZE means you should 1.362 + // use your intrinsic width as the computed width 1.363 + // 1.364 + // For block-level frames, the computed width is based on the width of the 1.365 + // containing block, the margin/border/padding areas, and the min/max width. 1.366 + nscoord mComputedWidth; 1.367 + 1.368 + // The computed height specifies the frame's content height, and it does 1.369 + // not apply to inline non-replaced elements 1.370 + // 1.371 + // For replaced inline frames, a value of NS_INTRINSICSIZE means you should 1.372 + // use your intrinsic height as the computed height 1.373 + // 1.374 + // For non-replaced block-level frames in the flow and floated, a value of 1.375 + // NS_AUTOHEIGHT means you choose a height to shrink wrap around the normal 1.376 + // flow child frames. The height must be within the limit of the min/max 1.377 + // height if there is such a limit 1.378 + // 1.379 + // For replaced block-level frames, a value of NS_INTRINSICSIZE 1.380 + // means you use your intrinsic height as the computed height 1.381 + nscoord mComputedHeight; 1.382 + 1.383 + // Computed values for 'left/top/right/bottom' offsets. Only applies to 1.384 + // 'positioned' elements. These are PHYSICAL coordinates (for now). 1.385 + nsMargin mComputedOffsets; 1.386 + 1.387 + // Computed values for 'min-width/max-width' and 'min-height/max-height' 1.388 + // XXXldb The width ones here should go; they should be needed only 1.389 + // internally. 1.390 + nscoord mComputedMinWidth, mComputedMaxWidth; 1.391 + nscoord mComputedMinHeight, mComputedMaxHeight; 1.392 + 1.393 +public: 1.394 + // Cached pointers to the various style structs used during intialization 1.395 + const nsStyleDisplay* mStyleDisplay; 1.396 + const nsStyleVisibility* mStyleVisibility; 1.397 + const nsStylePosition* mStylePosition; 1.398 + const nsStyleBorder* mStyleBorder; 1.399 + const nsStyleMargin* mStyleMargin; 1.400 + const nsStylePadding* mStylePadding; 1.401 + const nsStyleText* mStyleText; 1.402 + 1.403 + bool IsFloating() const; 1.404 + 1.405 + uint8_t GetDisplay() const; 1.406 + 1.407 + // a frame (e.g. nsTableCellFrame) which may need to generate a special 1.408 + // reflow for percent height calculations 1.409 + nsIPercentHeightObserver* mPercentHeightObserver; 1.410 + 1.411 + // CSS margin collapsing sometimes requires us to reflow 1.412 + // optimistically assuming that margins collapse to see if clearance 1.413 + // is required. When we discover that clearance is required, we 1.414 + // store the frame in which clearance was discovered to the location 1.415 + // requested here. 1.416 + nsIFrame** mDiscoveredClearance; 1.417 + 1.418 + // This value keeps track of how deeply nested a given reflow state 1.419 + // is from the top of the frame tree. 1.420 + int16_t mReflowDepth; 1.421 + 1.422 + struct ReflowStateFlags { 1.423 + uint16_t mSpecialHeightReflow:1; // used by tables to communicate special reflow (in process) to handle 1.424 + // percent height frames inside cells which may not have computed heights 1.425 + uint16_t mNextInFlowUntouched:1; // nothing in the frame's next-in-flow (or its descendants) 1.426 + // is changing 1.427 + uint16_t mIsTopOfPage:1; // Is the current context at the top of a 1.428 + // page? When true, we force something 1.429 + // that's too tall for a page/column to 1.430 + // fit anyway to avoid infinite loops. 1.431 + uint16_t mHasClearance:1; // Block has clearance 1.432 + uint16_t mAssumingHScrollbar:1; // parent frame is an nsIScrollableFrame and it 1.433 + // is assuming a horizontal scrollbar 1.434 + uint16_t mAssumingVScrollbar:1; // parent frame is an nsIScrollableFrame and it 1.435 + // is assuming a vertical scrollbar 1.436 + 1.437 + uint16_t mHResize:1; // Is frame (a) not dirty and (b) a 1.438 + // different width than before? 1.439 + 1.440 + uint16_t mVResize:1; // Is frame (a) not dirty and (b) a 1.441 + // different height than before or 1.442 + // (potentially) in a context where 1.443 + // percent heights have a different 1.444 + // basis? 1.445 + uint16_t mTableIsSplittable:1; // tables are splittable, this should happen only inside a page 1.446 + // and never insider a column frame 1.447 + uint16_t mHeightDependsOnAncestorCell:1; // Does frame height depend on 1.448 + // an ancestor table-cell? 1.449 + uint16_t mIsColumnBalancing:1; // nsColumnSetFrame is balancing columns 1.450 + uint16_t mIsFlexContainerMeasuringHeight:1; // nsFlexContainerFrame is 1.451 + // reflowing this child to 1.452 + // measure its intrinsic height. 1.453 + uint16_t mDummyParentReflowState:1; // a "fake" reflow state made 1.454 + // in order to be the parent 1.455 + // of a real one 1.456 + uint16_t mMustReflowPlaceholders:1; // Should this frame reflow its place- 1.457 + // holder children? If the available 1.458 + // height of this frame didn't change, 1.459 + // but its in a paginated environment 1.460 + // (e.g. columns), it should always 1.461 + // reflow its placeholder children. 1.462 + } mFlags; 1.463 + 1.464 + // Note: The copy constructor is written by the compiler automatically. You 1.465 + // can use that and then override specific values if you want, or you can 1.466 + // call Init as desired... 1.467 + 1.468 + /** 1.469 + * Initialize a ROOT reflow state. 1.470 + * 1.471 + * @param aPresContext Must be equal to aFrame->PresContext(). 1.472 + * @param aFrame The frame for whose reflow state is being constructed. 1.473 + * @param aRenderingContext The rendering context to be used for measurements. 1.474 + * @param aAvailableSpace See comments for availableHeight and availableWidth 1.475 + * members. 1.476 + * @param aFlags A set of flags used for additional boolean parameters (see 1.477 + * below). 1.478 + */ 1.479 + nsHTMLReflowState(nsPresContext* aPresContext, 1.480 + nsIFrame* aFrame, 1.481 + nsRenderingContext* aRenderingContext, 1.482 + const nsSize& aAvailableSpace, 1.483 + uint32_t aFlags = 0); 1.484 + 1.485 + /** 1.486 + * Initialize a reflow state for a child frame's reflow. Some parts of the 1.487 + * state are copied from the parent's reflow state. The remainder is computed. 1.488 + * 1.489 + * @param aPresContext Must be equal to aFrame->PresContext(). 1.490 + * @param aParentReflowState A reference to an nsHTMLReflowState object that 1.491 + * is to be the parent of this object. 1.492 + * @param aFrame The frame for whose reflow state is being constructed. 1.493 + * @param aAvailableSpace See comments for availableHeight and availableWidth 1.494 + * members. 1.495 + * @param aContainingBlockWidth An optional width, in app units, that is used 1.496 + * by absolute positioning code to override default containing block 1.497 + * width. 1.498 + * @param aContainingBlockHeight An optional height, in app units, that is 1.499 + * used by absolute positioning code to override default containing 1.500 + * block height. 1.501 + * @param aFlags A set of flags used for additional boolean parameters (see 1.502 + * below). 1.503 + */ 1.504 + nsHTMLReflowState(nsPresContext* aPresContext, 1.505 + const nsHTMLReflowState& aParentReflowState, 1.506 + nsIFrame* aFrame, 1.507 + const nsSize& aAvailableSpace, 1.508 + nscoord aContainingBlockWidth = -1, 1.509 + nscoord aContainingBlockHeight = -1, 1.510 + uint32_t aFlags = 0); 1.511 + 1.512 + // Values for |aFlags| passed to constructor 1.513 + enum { 1.514 + // Indicates that the parent of this reflow state is "fake" (see 1.515 + // mDummyParentReflowState in mFlags). 1.516 + DUMMY_PARENT_REFLOW_STATE = (1<<0), 1.517 + 1.518 + // Indicates that the calling function will initialize the reflow state, and 1.519 + // that the constructor should not call Init(). 1.520 + CALLER_WILL_INIT = (1<<1) 1.521 + }; 1.522 + 1.523 + // This method initializes various data members. It is automatically 1.524 + // called by the various constructors 1.525 + void Init(nsPresContext* aPresContext, 1.526 + nscoord aContainingBlockWidth = -1, 1.527 + nscoord aContainingBlockHeight = -1, 1.528 + const nsMargin* aBorder = nullptr, 1.529 + const nsMargin* aPadding = nullptr); 1.530 + /** 1.531 + * Find the content width of the containing block of aReflowState 1.532 + */ 1.533 + static nscoord 1.534 + GetContainingBlockContentWidth(const nsHTMLReflowState* aReflowState); 1.535 + 1.536 + /** 1.537 + * Calculate the used line-height property. The return value will be >= 0. 1.538 + */ 1.539 + nscoord CalcLineHeight() const; 1.540 + 1.541 + /** 1.542 + * Same as CalcLineHeight() above, but doesn't need a reflow state. 1.543 + * 1.544 + * @param aBlockHeight The computed height of the content rect of the block 1.545 + * that the line should fill. 1.546 + * Only used with line-height:-moz-block-height. 1.547 + * NS_AUTOHEIGHT results in a normal line-height for 1.548 + * line-height:-moz-block-height. 1.549 + * @param aFontSizeInflation The result of the appropriate 1.550 + * nsLayoutUtils::FontSizeInflationFor call, 1.551 + * or 1.0 if during intrinsic size 1.552 + * calculation. 1.553 + */ 1.554 + static nscoord CalcLineHeight(nsIContent* aContent, 1.555 + nsStyleContext* aStyleContext, 1.556 + nscoord aBlockHeight, 1.557 + float aFontSizeInflation); 1.558 + 1.559 + 1.560 + void ComputeContainingBlockRectangle(nsPresContext* aPresContext, 1.561 + const nsHTMLReflowState* aContainingBlockRS, 1.562 + nscoord& aContainingBlockWidth, 1.563 + nscoord& aContainingBlockHeight); 1.564 + 1.565 + /** 1.566 + * Apply the mComputed(Min/Max)Width constraints to the content 1.567 + * size computed so far. 1.568 + */ 1.569 + nscoord ApplyMinMaxWidth(nscoord aWidth) const { 1.570 + if (NS_UNCONSTRAINEDSIZE != ComputedMaxWidth()) { 1.571 + aWidth = std::min(aWidth, ComputedMaxWidth()); 1.572 + } 1.573 + return std::max(aWidth, ComputedMinWidth()); 1.574 + } 1.575 + 1.576 + /** 1.577 + * Apply the mComputed(Min/Max)Height constraints to the content 1.578 + * size computed so far. 1.579 + * 1.580 + * @param aHeight The height that we've computed an to which we want to apply 1.581 + * min/max constraints. 1.582 + * @param aConsumed The amount of the computed height that was consumed by 1.583 + * our prev-in-flows. 1.584 + */ 1.585 + nscoord ApplyMinMaxHeight(nscoord aHeight, nscoord aConsumed = 0) const { 1.586 + aHeight += aConsumed; 1.587 + 1.588 + if (NS_UNCONSTRAINEDSIZE != ComputedMaxHeight()) { 1.589 + aHeight = std::min(aHeight, ComputedMaxHeight()); 1.590 + } 1.591 + 1.592 + if (NS_UNCONSTRAINEDSIZE != ComputedMinHeight()) { 1.593 + aHeight = std::max(aHeight, ComputedMinHeight()); 1.594 + } 1.595 + 1.596 + return aHeight - aConsumed; 1.597 + } 1.598 + 1.599 + bool ShouldReflowAllKids() const { 1.600 + // Note that we could make a stronger optimization for mVResize if 1.601 + // we use it in a ShouldReflowChild test that replaces the current 1.602 + // checks of NS_FRAME_IS_DIRTY | NS_FRAME_HAS_DIRTY_CHILDREN, if it 1.603 + // were tested there along with NS_FRAME_CONTAINS_RELATIVE_HEIGHT. 1.604 + // This would need to be combined with a slight change in which 1.605 + // frames NS_FRAME_CONTAINS_RELATIVE_HEIGHT is marked on. 1.606 + return (frame->GetStateBits() & NS_FRAME_IS_DIRTY) || 1.607 + mFlags.mHResize || 1.608 + (mFlags.mVResize && 1.609 + (frame->GetStateBits() & NS_FRAME_CONTAINS_RELATIVE_HEIGHT)); 1.610 + } 1.611 + 1.612 + // This method doesn't apply min/max computed widths to the value passed in. 1.613 + void SetComputedWidth(nscoord aComputedWidth); 1.614 + 1.615 + // This method doesn't apply min/max computed heights to the value passed in. 1.616 + void SetComputedHeight(nscoord aComputedHeight); 1.617 + 1.618 + void SetComputedHeightWithoutResettingResizeFlags(nscoord aComputedHeight) { 1.619 + // Viewport frames reset the computed height on a copy of their reflow 1.620 + // state when reflowing fixed-pos kids. In that case we actually don't 1.621 + // want to mess with the resize flags, because comparing the frame's rect 1.622 + // to the munged computed width is pointless. 1.623 + ComputedHeight() = aComputedHeight; 1.624 + } 1.625 + 1.626 + void SetTruncated(const nsHTMLReflowMetrics& aMetrics, nsReflowStatus* aStatus) const; 1.627 + 1.628 + bool WillReflowAgainForClearance() const { 1.629 + return mDiscoveredClearance && *mDiscoveredClearance; 1.630 + } 1.631 + 1.632 + // Compute the offsets for a relative position element 1.633 + static void ComputeRelativeOffsets(uint8_t aCBDirection, 1.634 + nsIFrame* aFrame, 1.635 + nscoord aContainingBlockWidth, 1.636 + nscoord aContainingBlockHeight, 1.637 + nsMargin& aComputedOffsets); 1.638 + 1.639 + // If a relatively positioned element, adjust the position appropriately. 1.640 + static void ApplyRelativePositioning(nsIFrame* aFrame, 1.641 + const nsMargin& aComputedOffsets, 1.642 + nsPoint* aPosition); 1.643 + 1.644 + void ApplyRelativePositioning(nsPoint* aPosition) const { 1.645 + ApplyRelativePositioning(frame, ComputedPhysicalOffsets(), aPosition); 1.646 + } 1.647 + 1.648 +#ifdef DEBUG 1.649 + // Reflow trace methods. Defined in nsFrame.cpp so they have access 1.650 + // to the display-reflow infrastructure. 1.651 + static void* DisplayInitConstraintsEnter(nsIFrame* aFrame, 1.652 + nsHTMLReflowState* aState, 1.653 + nscoord aCBWidth, 1.654 + nscoord aCBHeight, 1.655 + const nsMargin* aBorder, 1.656 + const nsMargin* aPadding); 1.657 + static void DisplayInitConstraintsExit(nsIFrame* aFrame, 1.658 + nsHTMLReflowState* aState, 1.659 + void* aValue); 1.660 + static void* DisplayInitFrameTypeEnter(nsIFrame* aFrame, 1.661 + nsHTMLReflowState* aState); 1.662 + static void DisplayInitFrameTypeExit(nsIFrame* aFrame, 1.663 + nsHTMLReflowState* aState, 1.664 + void* aValue); 1.665 +#endif 1.666 + 1.667 +protected: 1.668 + void InitFrameType(nsIAtom* aFrameType); 1.669 + void InitCBReflowState(); 1.670 + void InitResizeFlags(nsPresContext* aPresContext, nsIAtom* aFrameType); 1.671 + 1.672 + void InitConstraints(nsPresContext* aPresContext, 1.673 + nscoord aContainingBlockWidth, 1.674 + nscoord aContainingBlockHeight, 1.675 + const nsMargin* aBorder, 1.676 + const nsMargin* aPadding, 1.677 + nsIAtom* aFrameType); 1.678 + 1.679 + // Returns the nearest containing block or block frame (whether or not 1.680 + // it is a containing block) for the specified frame. Also returns 1.681 + // the left edge and width of the containing block's content area. 1.682 + // These are returned in the coordinate space of the containing block. 1.683 + nsIFrame* GetHypotheticalBoxContainer(nsIFrame* aFrame, 1.684 + nscoord& aCBLeftEdge, 1.685 + nscoord& aCBWidth); 1.686 + 1.687 + void CalculateHypotheticalBox(nsPresContext* aPresContext, 1.688 + nsIFrame* aPlaceholderFrame, 1.689 + nsIFrame* aContainingBlock, 1.690 + nscoord aBlockLeftContentEdge, 1.691 + nscoord aBlockContentWidth, 1.692 + const nsHTMLReflowState* cbrs, 1.693 + nsHypotheticalBox& aHypotheticalBox, 1.694 + nsIAtom* aFrameType); 1.695 + 1.696 + void InitAbsoluteConstraints(nsPresContext* aPresContext, 1.697 + const nsHTMLReflowState* cbrs, 1.698 + nscoord aContainingBlockWidth, 1.699 + nscoord aContainingBlockHeight, 1.700 + nsIAtom* aFrameType); 1.701 + 1.702 + // Calculates the computed values for the 'min-Width', 'max-Width', 1.703 + // 'min-Height', and 'max-Height' properties, and stores them in the assorted 1.704 + // data members 1.705 + void ComputeMinMaxValues(nscoord aContainingBlockWidth, 1.706 + nscoord aContainingBlockHeight, 1.707 + const nsHTMLReflowState* aContainingBlockRS); 1.708 + 1.709 + void CalculateHorizBorderPaddingMargin(nscoord aContainingBlockWidth, 1.710 + nscoord* aInsideBoxSizing, 1.711 + nscoord* aOutsideBoxSizing); 1.712 + 1.713 + void CalculateBlockSideMargins(nscoord aAvailWidth, 1.714 + nscoord aComputedWidth, 1.715 + nsIAtom* aFrameType); 1.716 +}; 1.717 + 1.718 +#endif /* nsHTMLReflowState_h___ */ 1.719 +