/src/mozilla-central/layout/generic/ReflowInput.h
Line | Count | Source (jump to first uncovered line) |
1 | | /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ |
2 | | /* vim: set ts=8 sts=2 et sw=2 tw=80: */ |
3 | | /* This Source Code Form is subject to the terms of the Mozilla Public |
4 | | * License, v. 2.0. If a copy of the MPL was not distributed with this |
5 | | * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ |
6 | | |
7 | | /* struct containing the input to nsIFrame::Reflow */ |
8 | | |
9 | | #ifndef mozilla_ReflowInput_h |
10 | | #define mozilla_ReflowInput_h |
11 | | |
12 | | #include "nsMargin.h" |
13 | | #include "nsStyleCoord.h" |
14 | | #include "nsIFrame.h" |
15 | | #include "mozilla/Assertions.h" |
16 | | #include <algorithm> |
17 | | |
18 | | class gfxContext; |
19 | | class nsFloatManager; |
20 | | struct nsHypotheticalPosition; |
21 | | class nsIPercentBSizeObserver; |
22 | | class nsLineLayout; |
23 | | class nsPlaceholderFrame; |
24 | | class nsPresContext; |
25 | | |
26 | | /** |
27 | | * @return aValue clamped to [aMinValue, aMaxValue]. |
28 | | * |
29 | | * @note This function needs to handle aMinValue > aMaxValue. In that case, |
30 | | * aMinValue is returned. |
31 | | * @see http://www.w3.org/TR/CSS21/visudet.html#min-max-widths |
32 | | * @see http://www.w3.org/TR/CSS21/visudet.html#min-max-heights |
33 | | */ |
34 | | template <class NumericType> |
35 | | NumericType |
36 | | NS_CSS_MINMAX(NumericType aValue, NumericType aMinValue, NumericType aMaxValue) |
37 | | { |
38 | | NumericType result = aValue; |
39 | | if (aMaxValue < result) |
40 | | result = aMaxValue; |
41 | | if (aMinValue > result) |
42 | | result = aMinValue; |
43 | | return result; |
44 | | } |
45 | | |
46 | | /** |
47 | | * CSS Frame type. Included as part of the reflow state. |
48 | | */ |
49 | | typedef uint32_t nsCSSFrameType; |
50 | | |
51 | 0 | #define NS_CSS_FRAME_TYPE_UNKNOWN 0 |
52 | 0 | #define NS_CSS_FRAME_TYPE_INLINE 1 |
53 | 0 | #define NS_CSS_FRAME_TYPE_BLOCK 2 /* block-level in normal flow */ |
54 | 0 | #define NS_CSS_FRAME_TYPE_FLOATING 3 |
55 | 0 | #define NS_CSS_FRAME_TYPE_ABSOLUTE 4 |
56 | 0 | #define NS_CSS_FRAME_TYPE_INTERNAL_TABLE 5 /* row group frame, row frame, cell frame, ... */ |
57 | | |
58 | | /** |
59 | | * Bit-flag that indicates whether the element is replaced. Applies to inline, |
60 | | * block-level, floating, and absolutely positioned elements |
61 | | */ |
62 | 0 | #define NS_CSS_FRAME_TYPE_REPLACED 0x08000 |
63 | | |
64 | | /** |
65 | | * Bit-flag that indicates that the element is replaced and contains a block |
66 | | * (eg some form controls). Applies to inline, block-level, floating, and |
67 | | * absolutely positioned elements. Mutually exclusive with |
68 | | * NS_CSS_FRAME_TYPE_REPLACED. |
69 | | */ |
70 | 0 | #define NS_CSS_FRAME_TYPE_REPLACED_CONTAINS_BLOCK 0x10000 |
71 | | |
72 | | /** |
73 | | * Helper macros for telling whether items are replaced |
74 | | */ |
75 | | #define NS_FRAME_IS_REPLACED_NOBLOCK(_ft) \ |
76 | 0 | (NS_CSS_FRAME_TYPE_REPLACED == ((_ft) & NS_CSS_FRAME_TYPE_REPLACED)) |
77 | | |
78 | | #define NS_FRAME_IS_REPLACED(_ft) \ |
79 | 0 | (NS_FRAME_IS_REPLACED_NOBLOCK(_ft) || \ |
80 | 0 | NS_FRAME_IS_REPLACED_CONTAINS_BLOCK(_ft)) |
81 | | |
82 | | #define NS_FRAME_REPLACED(_ft) \ |
83 | 0 | (NS_CSS_FRAME_TYPE_REPLACED | (_ft)) |
84 | | |
85 | | #define NS_FRAME_IS_REPLACED_CONTAINS_BLOCK(_ft) \ |
86 | 0 | (NS_CSS_FRAME_TYPE_REPLACED_CONTAINS_BLOCK == \ |
87 | 0 | ((_ft) & NS_CSS_FRAME_TYPE_REPLACED_CONTAINS_BLOCK)) |
88 | | |
89 | | #define NS_FRAME_REPLACED_CONTAINS_BLOCK(_ft) \ |
90 | 0 | (NS_CSS_FRAME_TYPE_REPLACED_CONTAINS_BLOCK | (_ft)) |
91 | | |
92 | | /** |
93 | | * A macro to extract the type. Masks off the 'replaced' bit-flag |
94 | | */ |
95 | | #define NS_FRAME_GET_TYPE(_ft) \ |
96 | 0 | ((_ft) & ~(NS_CSS_FRAME_TYPE_REPLACED | \ |
97 | 0 | NS_CSS_FRAME_TYPE_REPLACED_CONTAINS_BLOCK)) |
98 | | |
99 | | namespace mozilla { |
100 | | |
101 | | // A base class of ReflowInput that computes only the padding, |
102 | | // border, and margin, since those values are needed more often. |
103 | | struct SizeComputationInput { |
104 | | public: |
105 | | typedef mozilla::WritingMode WritingMode; |
106 | | typedef mozilla::LogicalMargin LogicalMargin; |
107 | | |
108 | | // The frame being reflowed. |
109 | | nsIFrame* mFrame; |
110 | | |
111 | | // Rendering context to use for measurement. |
112 | | gfxContext* mRenderingContext; |
113 | | |
114 | 0 | const nsMargin& ComputedPhysicalMargin() const { return mComputedMargin; } |
115 | | const nsMargin& ComputedPhysicalBorderPadding() const { return mComputedBorderPadding; } |
116 | | const nsMargin& ComputedPhysicalPadding() const { return mComputedPadding; } |
117 | | |
118 | | // We may need to eliminate the (few) users of these writable-reference accessors |
119 | | // as part of migrating to logical coordinates. |
120 | | nsMargin& ComputedPhysicalMargin() { return mComputedMargin; } |
121 | | nsMargin& ComputedPhysicalBorderPadding() { return mComputedBorderPadding; } |
122 | | nsMargin& ComputedPhysicalPadding() { return mComputedPadding; } |
123 | | |
124 | | const LogicalMargin ComputedLogicalMargin() const |
125 | 0 | { return LogicalMargin(mWritingMode, mComputedMargin); } |
126 | | const LogicalMargin ComputedLogicalBorderPadding() const |
127 | | { return LogicalMargin(mWritingMode, mComputedBorderPadding); } |
128 | | const LogicalMargin ComputedLogicalPadding() const |
129 | 0 | { return LogicalMargin(mWritingMode, mComputedPadding); } |
130 | | |
131 | | void SetComputedLogicalMargin(mozilla::WritingMode aWM, |
132 | | const LogicalMargin& aMargin) |
133 | 0 | { mComputedMargin = aMargin.GetPhysicalMargin(aWM); } |
134 | | void SetComputedLogicalMargin(const LogicalMargin& aMargin) |
135 | 0 | { SetComputedLogicalMargin(mWritingMode, aMargin); } |
136 | | |
137 | | void SetComputedLogicalBorderPadding(mozilla::WritingMode aWM, |
138 | | const LogicalMargin& aMargin) |
139 | 0 | { mComputedBorderPadding = aMargin.GetPhysicalMargin(aWM); } |
140 | | void SetComputedLogicalBorderPadding(const LogicalMargin& aMargin) |
141 | 0 | { SetComputedLogicalBorderPadding(mWritingMode, aMargin); } |
142 | | |
143 | | void SetComputedLogicalPadding(mozilla::WritingMode aWM, |
144 | | const LogicalMargin& aMargin) |
145 | 0 | { mComputedPadding = aMargin.GetPhysicalMargin(aWM); } |
146 | | void SetComputedLogicalPadding(const LogicalMargin& aMargin) |
147 | | { SetComputedLogicalPadding(mWritingMode, aMargin); } |
148 | | |
149 | 0 | WritingMode GetWritingMode() const { return mWritingMode; } |
150 | | |
151 | | protected: |
152 | | // cached copy of the frame's writing-mode, for logical coordinates |
153 | | WritingMode mWritingMode; |
154 | | |
155 | | // These are PHYSICAL coordinates (for now). |
156 | | // Will probably become logical in due course. |
157 | | |
158 | | // Computed margin values |
159 | | nsMargin mComputedMargin; |
160 | | |
161 | | // Cached copy of the border + padding values |
162 | | nsMargin mComputedBorderPadding; |
163 | | |
164 | | // Computed padding values |
165 | | nsMargin mComputedPadding; |
166 | | |
167 | | public: |
168 | | // Callers using this constructor must call InitOffsets on their own. |
169 | | SizeComputationInput(nsIFrame *aFrame, gfxContext *aRenderingContext) |
170 | | : mFrame(aFrame) |
171 | | , mRenderingContext(aRenderingContext) |
172 | | , mWritingMode(aFrame->GetWritingMode()) |
173 | 0 | { |
174 | 0 | } |
175 | | |
176 | | SizeComputationInput(nsIFrame *aFrame, gfxContext *aRenderingContext, |
177 | | mozilla::WritingMode aContainingBlockWritingMode, |
178 | | nscoord aContainingBlockISize); |
179 | | |
180 | | struct ReflowInputFlags { |
181 | 0 | ReflowInputFlags() { memset(this, 0, sizeof(*this)); } |
182 | | bool mSpecialBSizeReflow : 1; // used by tables to communicate special reflow (in process) to handle |
183 | | // percent bsize frames inside cells which may not have computed bsizes |
184 | | bool mNextInFlowUntouched : 1; // nothing in the frame's next-in-flow (or its descendants) |
185 | | // is changing |
186 | | bool mIsTopOfPage : 1; // Is the current context at the top of a |
187 | | // page? When true, we force something |
188 | | // that's too tall for a page/column to |
189 | | // fit anyway to avoid infinite loops. |
190 | | bool mAssumingHScrollbar : 1; // parent frame is an nsIScrollableFrame and it |
191 | | // is assuming a horizontal scrollbar |
192 | | bool mAssumingVScrollbar : 1; // parent frame is an nsIScrollableFrame and it |
193 | | // is assuming a vertical scrollbar |
194 | | |
195 | | bool mIsIResize : 1; // Is frame (a) not dirty and (b) a |
196 | | // different inline-size than before? |
197 | | |
198 | | bool mIsBResize : 1; // Is frame (a) not dirty and (b) a |
199 | | // different block-size than before or |
200 | | // (potentially) in a context where |
201 | | // percent block-sizes have a different |
202 | | // basis? |
203 | | bool mTableIsSplittable : 1; // tables are splittable, this should happen only inside a page |
204 | | // and never insider a column frame |
205 | | bool mHeightDependsOnAncestorCell : 1; // Does frame height depend on |
206 | | // an ancestor table-cell? |
207 | | bool mIsColumnBalancing : 1; // nsColumnSetFrame is balancing columns |
208 | | bool mIsFlexContainerMeasuringBSize : 1; // nsFlexContainerFrame is |
209 | | // reflowing this child to |
210 | | // measure its intrinsic BSize. |
211 | | bool mDummyParentReflowInput : 1; // a "fake" reflow state made |
212 | | // in order to be the parent |
213 | | // of a real one |
214 | | bool mMustReflowPlaceholders : 1; // Should this frame reflow its place- |
215 | | // holder children? If the available |
216 | | // height of this frame didn't change, |
217 | | // but its in a paginated environment |
218 | | // (e.g. columns), it should always |
219 | | // reflow its placeholder children. |
220 | | bool mShrinkWrap : 1; // stores the COMPUTE_SIZE_SHRINK_WRAP ctor flag |
221 | | bool mUseAutoBSize : 1; // stores the COMPUTE_SIZE_USE_AUTO_BSIZE ctor flag |
222 | | bool mStaticPosIsCBOrigin : 1; // the STATIC_POS_IS_CB_ORIGIN ctor flag |
223 | | bool mIClampMarginBoxMinSize : 1; // the I_CLAMP_MARGIN_BOX_MIN_SIZE ctor flag |
224 | | bool mBClampMarginBoxMinSize : 1; // the B_CLAMP_MARGIN_BOX_MIN_SIZE ctor flag |
225 | | bool mApplyAutoMinSize : 1; // the I_APPLY_AUTO_MIN_SIZE ctor flag |
226 | | |
227 | | // If set, the following two flags indicate that: |
228 | | // (1) this frame is absolutely-positioned (or fixed-positioned). |
229 | | // (2) this frame's static position depends on the CSS Box Alignment. |
230 | | // (3) we do need to compute the static position, because the frame's |
231 | | // {Inline and/or Block} offsets actually depend on it. |
232 | | // When these bits are set, the offset values (IStart/IEnd, BStart/BEnd) |
233 | | // represent the "start" edge of the frame's CSS Box Alignment container |
234 | | // area, in that axis -- and these offsets need to be further-resolved |
235 | | // (with CSS Box Alignment) after we know the OOF frame's size. |
236 | | // NOTE: The "I" and "B" (for "Inline" and "Block") refer the axes of the |
237 | | // *containing block's writing-mode*, NOT mFrame's own writing-mode. This |
238 | | // is purely for convenience, since that's the writing-mode we're dealing |
239 | | // with when we set & react to these bits. |
240 | | bool mIOffsetsNeedCSSAlign : 1; |
241 | | bool mBOffsetsNeedCSSAlign : 1; |
242 | | }; |
243 | | |
244 | | #ifdef DEBUG |
245 | | // Reflow trace methods. Defined in nsFrame.cpp so they have access |
246 | | // to the display-reflow infrastructure. |
247 | | static void* DisplayInitOffsetsEnter( |
248 | | nsIFrame* aFrame, |
249 | | SizeComputationInput* aState, |
250 | | nscoord aPercentBasis, |
251 | | WritingMode aCBWritingMode, |
252 | | const nsMargin* aBorder, |
253 | | const nsMargin* aPadding); |
254 | | static void DisplayInitOffsetsExit(nsIFrame* aFrame, |
255 | | SizeComputationInput* aState, |
256 | | void* aValue); |
257 | | #endif |
258 | | |
259 | | private: |
260 | | /** |
261 | | * Computes margin values from the specified margin style information, and |
262 | | * fills in the mComputedMargin member. |
263 | | * |
264 | | * @param aWM Writing mode of the containing block |
265 | | * @param aPercentBasis |
266 | | * Inline size of the containing block (in its own writing mode), to use |
267 | | * for resolving percentage margin values in the inline and block axes. |
268 | | * @return true if the margin is dependent on the containing block size. |
269 | | */ |
270 | | bool ComputeMargin(mozilla::WritingMode aWM, |
271 | | nscoord aPercentBasis); |
272 | | |
273 | | /** |
274 | | * Computes padding values from the specified padding style information, and |
275 | | * fills in the mComputedPadding member. |
276 | | * |
277 | | * @param aWM Writing mode of the containing block |
278 | | * @param aPercentBasis |
279 | | * Inline size of the containing block (in its own writing mode), to use |
280 | | * for resolving percentage padding values in the inline and block axes. |
281 | | * @return true if the padding is dependent on the containing block size. |
282 | | */ |
283 | | bool ComputePadding(mozilla::WritingMode aWM, |
284 | | nscoord aPercentBasis, |
285 | | mozilla::LayoutFrameType aFrameType); |
286 | | |
287 | | protected: |
288 | | void InitOffsets(mozilla::WritingMode aWM, |
289 | | nscoord aPercentBasis, |
290 | | mozilla::LayoutFrameType aFrameType, |
291 | | ReflowInputFlags aFlags, |
292 | | const nsMargin* aBorder = nullptr, |
293 | | const nsMargin* aPadding = nullptr, |
294 | | const nsStyleDisplay* aDisplay = nullptr); |
295 | | |
296 | | /* |
297 | | * Convert nsStyleCoord to nscoord when percentages depend on the |
298 | | * inline size of the containing block, and enumerated values are for |
299 | | * inline size, min-inline-size, or max-inline-size. Does not handle |
300 | | * auto inline sizes. |
301 | | */ |
302 | | inline nscoord ComputeISizeValue(nscoord aContainingBlockISize, |
303 | | nscoord aContentEdgeToBoxSizing, |
304 | | nscoord aBoxSizingToMarginEdge, |
305 | | const nsStyleCoord& aCoord) const; |
306 | | // same as previous, but using mComputedBorderPadding, mComputedPadding, |
307 | | // and mComputedMargin |
308 | | nscoord ComputeISizeValue(nscoord aContainingBlockISize, |
309 | | mozilla::StyleBoxSizing aBoxSizing, |
310 | | const nsStyleCoord& aCoord) const; |
311 | | |
312 | | nscoord ComputeBSizeValue(nscoord aContainingBlockBSize, |
313 | | mozilla::StyleBoxSizing aBoxSizing, |
314 | | const nsStyleCoord& aCoord) const; |
315 | | }; |
316 | | |
317 | | /** |
318 | | * State passed to a frame during reflow or intrinsic size calculation. |
319 | | * |
320 | | * XXX Refactor so only a base class (nsSizingState?) is used for intrinsic |
321 | | * size calculation. |
322 | | * |
323 | | * @see nsIFrame#Reflow() |
324 | | */ |
325 | | struct ReflowInput : public SizeComputationInput { |
326 | | // the reflow states are linked together. this is the pointer to the |
327 | | // parent's reflow state |
328 | | const ReflowInput* mParentReflowInput; |
329 | | |
330 | | // A non-owning pointer to the float manager associated with this area, |
331 | | // which points to the object owned by nsAutoFloatManager::mNew. |
332 | | nsFloatManager* mFloatManager; |
333 | | |
334 | | // LineLayout object (only for inline reflow; set to nullptr otherwise) |
335 | | nsLineLayout* mLineLayout; |
336 | | |
337 | | // The appropriate reflow state for the containing block (for |
338 | | // percentage widths, etc.) of this reflow state's frame. |
339 | | const ReflowInput* mCBReflowInput; |
340 | | |
341 | | // The type of frame, from css's perspective. This value is |
342 | | // initialized by the Init method below. |
343 | | MOZ_INIT_OUTSIDE_CTOR |
344 | | nsCSSFrameType mFrameType; |
345 | | |
346 | | // The amount the in-flow position of the block is moving vertically relative |
347 | | // to its previous in-flow position (i.e. the amount the line containing the |
348 | | // block is moving). |
349 | | // This should be zero for anything which is not a block outside, and it |
350 | | // should be zero for anything which has a non-block parent. |
351 | | // The intended use of this value is to allow the accurate determination |
352 | | // of the potential impact of a float |
353 | | // This takes on an arbitrary value the first time a block is reflowed |
354 | | nscoord mBlockDelta; |
355 | | |
356 | | // If an ReflowInput finds itself initialized with an unconstrained |
357 | | // inline-size, it will look up its parentReflowInput chain for a state |
358 | | // with an orthogonal writing mode and a non-NS_UNCONSTRAINEDSIZE value for |
359 | | // orthogonal limit; when it finds such a reflow-state, it will use its |
360 | | // orthogonal-limit value to constrain inline-size. |
361 | | // This is initialized to NS_UNCONSTRAINEDSIZE (so it will be ignored), |
362 | | // but reset to a suitable value for the reflow root by nsPresShell. |
363 | | nscoord mOrthogonalLimit; |
364 | | |
365 | | // Accessors for the private fields below. Forcing all callers to use these |
366 | | // will allow us to introduce logical-coordinate versions and gradually |
367 | | // change clients from physical to logical as needed; and potentially switch |
368 | | // the internal fields from physical to logical coordinates in due course, |
369 | | // while maintaining compatibility with not-yet-updated code. |
370 | | nscoord AvailableWidth() const { return mAvailableWidth; } |
371 | 0 | nscoord AvailableHeight() const { return mAvailableHeight; } |
372 | | nscoord ComputedWidth() const { return mComputedWidth; } |
373 | | nscoord ComputedHeight() const { return mComputedHeight; } |
374 | | nscoord ComputedMinWidth() const { return mComputedMinWidth; } |
375 | | nscoord ComputedMaxWidth() const { return mComputedMaxWidth; } |
376 | | nscoord ComputedMinHeight() const { return mComputedMinHeight; } |
377 | | nscoord ComputedMaxHeight() const { return mComputedMaxHeight; } |
378 | | |
379 | | nscoord& AvailableWidth() { return mAvailableWidth; } |
380 | | nscoord& AvailableHeight() { return mAvailableHeight; } |
381 | | nscoord& ComputedWidth() { return mComputedWidth; } |
382 | | nscoord& ComputedHeight() { return mComputedHeight; } |
383 | 0 | nscoord& ComputedMinWidth() { return mComputedMinWidth; } |
384 | 0 | nscoord& ComputedMaxWidth() { return mComputedMaxWidth; } |
385 | 0 | nscoord& ComputedMinHeight() { return mComputedMinHeight; } |
386 | 0 | nscoord& ComputedMaxHeight() { return mComputedMaxHeight; } |
387 | | |
388 | | // ISize and BSize are logical-coordinate dimensions: |
389 | | // ISize is the size in the writing mode's inline direction (which equates to |
390 | | // width in horizontal writing modes, height in vertical ones), and BSize is |
391 | | // the size in the block-progression direction. |
392 | | nscoord AvailableISize() const |
393 | 0 | { return mWritingMode.IsVertical() ? mAvailableHeight : mAvailableWidth; } |
394 | | nscoord AvailableBSize() const |
395 | 0 | { return mWritingMode.IsVertical() ? mAvailableWidth : mAvailableHeight; } |
396 | | nscoord ComputedISize() const |
397 | 0 | { return mWritingMode.IsVertical() ? mComputedHeight : mComputedWidth; } |
398 | | nscoord ComputedBSize() const |
399 | 0 | { return mWritingMode.IsVertical() ? mComputedWidth : mComputedHeight; } |
400 | | nscoord ComputedMinISize() const |
401 | 0 | { return mWritingMode.IsVertical() ? mComputedMinHeight : mComputedMinWidth; } |
402 | | nscoord ComputedMaxISize() const |
403 | 0 | { return mWritingMode.IsVertical() ? mComputedMaxHeight : mComputedMaxWidth; } |
404 | | nscoord ComputedMinBSize() const |
405 | 0 | { return mWritingMode.IsVertical() ? mComputedMinWidth : mComputedMinHeight; } |
406 | | nscoord ComputedMaxBSize() const |
407 | 0 | { return mWritingMode.IsVertical() ? mComputedMaxWidth : mComputedMaxHeight; } |
408 | | |
409 | | nscoord& AvailableISize() |
410 | 0 | { return mWritingMode.IsVertical() ? mAvailableHeight : mAvailableWidth; } |
411 | | nscoord& AvailableBSize() |
412 | 0 | { return mWritingMode.IsVertical() ? mAvailableWidth : mAvailableHeight; } |
413 | | nscoord& ComputedISize() |
414 | 0 | { return mWritingMode.IsVertical() ? mComputedHeight : mComputedWidth; } |
415 | | nscoord& ComputedBSize() |
416 | 0 | { return mWritingMode.IsVertical() ? mComputedWidth : mComputedHeight; } |
417 | | nscoord& ComputedMinISize() |
418 | 0 | { return mWritingMode.IsVertical() ? mComputedMinHeight : mComputedMinWidth; } |
419 | | nscoord& ComputedMaxISize() |
420 | 0 | { return mWritingMode.IsVertical() ? mComputedMaxHeight : mComputedMaxWidth; } |
421 | | nscoord& ComputedMinBSize() |
422 | 0 | { return mWritingMode.IsVertical() ? mComputedMinWidth : mComputedMinHeight; } |
423 | | nscoord& ComputedMaxBSize() |
424 | 0 | { return mWritingMode.IsVertical() ? mComputedMaxWidth : mComputedMaxHeight; } |
425 | | |
426 | 0 | mozilla::LogicalSize AvailableSize() const { |
427 | 0 | return mozilla::LogicalSize(mWritingMode, |
428 | 0 | AvailableISize(), AvailableBSize()); |
429 | 0 | } |
430 | 0 | mozilla::LogicalSize ComputedSize() const { |
431 | 0 | return mozilla::LogicalSize(mWritingMode, |
432 | 0 | ComputedISize(), ComputedBSize()); |
433 | 0 | } |
434 | 0 | mozilla::LogicalSize ComputedMinSize() const { |
435 | 0 | return mozilla::LogicalSize(mWritingMode, |
436 | 0 | ComputedMinISize(), ComputedMinBSize()); |
437 | 0 | } |
438 | 0 | mozilla::LogicalSize ComputedMaxSize() const { |
439 | 0 | return mozilla::LogicalSize(mWritingMode, |
440 | 0 | ComputedMaxISize(), ComputedMaxBSize()); |
441 | 0 | } |
442 | | |
443 | | mozilla::LogicalSize AvailableSize(mozilla::WritingMode aWM) const |
444 | 0 | { return AvailableSize().ConvertTo(aWM, mWritingMode); } |
445 | | mozilla::LogicalSize ComputedSize(mozilla::WritingMode aWM) const |
446 | 0 | { return ComputedSize().ConvertTo(aWM, mWritingMode); } |
447 | | mozilla::LogicalSize ComputedMinSize(mozilla::WritingMode aWM) const |
448 | 0 | { return ComputedMinSize().ConvertTo(aWM, mWritingMode); } |
449 | | mozilla::LogicalSize ComputedMaxSize(mozilla::WritingMode aWM) const |
450 | 0 | { return ComputedMaxSize().ConvertTo(aWM, mWritingMode); } |
451 | | |
452 | | mozilla::LogicalSize ComputedSizeWithPadding() const { |
453 | | mozilla::WritingMode wm = GetWritingMode(); |
454 | | return mozilla::LogicalSize(wm, |
455 | | ComputedISize() + |
456 | | ComputedLogicalPadding().IStartEnd(wm), |
457 | | ComputedBSize() + |
458 | | ComputedLogicalPadding().BStartEnd(wm)); |
459 | | } |
460 | | |
461 | | mozilla::LogicalSize ComputedSizeWithPadding(mozilla::WritingMode aWM) const { |
462 | | return ComputedSizeWithPadding().ConvertTo(aWM, GetWritingMode()); |
463 | | } |
464 | | |
465 | | mozilla::LogicalSize ComputedSizeWithBorderPadding() const { |
466 | | mozilla::WritingMode wm = GetWritingMode(); |
467 | | return mozilla::LogicalSize(wm, |
468 | | ComputedISize() + |
469 | | ComputedLogicalBorderPadding().IStartEnd(wm), |
470 | | ComputedBSize() + |
471 | | ComputedLogicalBorderPadding().BStartEnd(wm)); |
472 | | } |
473 | | |
474 | | mozilla::LogicalSize |
475 | | ComputedSizeWithBorderPadding(mozilla::WritingMode aWM) const { |
476 | | return ComputedSizeWithBorderPadding().ConvertTo(aWM, GetWritingMode()); |
477 | | } |
478 | | |
479 | | mozilla::LogicalSize |
480 | | ComputedSizeWithMarginBorderPadding() const { |
481 | | mozilla::WritingMode wm = GetWritingMode(); |
482 | | return mozilla::LogicalSize(wm, |
483 | | ComputedISize() + |
484 | | ComputedLogicalMargin().IStartEnd(wm) + |
485 | | ComputedLogicalBorderPadding().IStartEnd(wm), |
486 | | ComputedBSize() + |
487 | | ComputedLogicalMargin().BStartEnd(wm) + |
488 | | ComputedLogicalBorderPadding().BStartEnd(wm)); |
489 | | } |
490 | | |
491 | | mozilla::LogicalSize |
492 | | ComputedSizeWithMarginBorderPadding(mozilla::WritingMode aWM) const { |
493 | | return ComputedSizeWithMarginBorderPadding().ConvertTo(aWM, |
494 | | GetWritingMode()); |
495 | | } |
496 | | |
497 | | nsSize |
498 | | ComputedPhysicalSize() const { |
499 | | return nsSize(ComputedWidth(), ComputedHeight()); |
500 | | } |
501 | | |
502 | | // XXX this will need to change when we make mComputedOffsets logical; |
503 | | // we won't be able to return a reference for the physical offsets |
504 | | const nsMargin& ComputedPhysicalOffsets() const { return mComputedOffsets; } |
505 | | nsMargin& ComputedPhysicalOffsets() { return mComputedOffsets; } |
506 | | |
507 | | const LogicalMargin ComputedLogicalOffsets() const |
508 | 0 | { return LogicalMargin(mWritingMode, mComputedOffsets); } |
509 | | |
510 | | void SetComputedLogicalOffsets(const LogicalMargin& aOffsets) |
511 | 0 | { mComputedOffsets = aOffsets.GetPhysicalMargin(mWritingMode); } |
512 | | |
513 | | // Return the state's computed size including border-padding, with |
514 | | // unconstrained dimensions replaced by zero. |
515 | 0 | nsSize ComputedSizeAsContainerIfConstrained() const { |
516 | 0 | const nscoord wd = ComputedWidth(); |
517 | 0 | const nscoord ht = ComputedHeight(); |
518 | 0 | return nsSize(wd == NS_UNCONSTRAINEDSIZE |
519 | 0 | ? 0 : wd + ComputedPhysicalBorderPadding().LeftRight(), |
520 | 0 | ht == NS_UNCONSTRAINEDSIZE |
521 | 0 | ? 0 : ht + ComputedPhysicalBorderPadding().TopBottom()); |
522 | 0 | } |
523 | | |
524 | | private: |
525 | | // the available width in which to reflow the frame. The space |
526 | | // represents the amount of room for the frame's margin, border, |
527 | | // padding, and content area. The frame size you choose should fit |
528 | | // within the available width. |
529 | | nscoord mAvailableWidth; |
530 | | |
531 | | // A value of NS_UNCONSTRAINEDSIZE for the available height means |
532 | | // you can choose whatever size you want. In galley mode the |
533 | | // available height is always NS_UNCONSTRAINEDSIZE, and only page |
534 | | // mode or multi-column layout involves a constrained height. The |
535 | | // element's the top border and padding, and content, must fit. If the |
536 | | // element is complete after reflow then its bottom border, padding |
537 | | // and margin (and similar for its complete ancestors) will need to |
538 | | // fit in this height. |
539 | | nscoord mAvailableHeight; |
540 | | |
541 | | // The computed width specifies the frame's content area width, and it does |
542 | | // not apply to inline non-replaced elements |
543 | | // |
544 | | // For replaced inline frames, a value of NS_INTRINSICSIZE means you should |
545 | | // use your intrinsic width as the computed width |
546 | | // |
547 | | // For block-level frames, the computed width is based on the width of the |
548 | | // containing block, the margin/border/padding areas, and the min/max width. |
549 | | MOZ_INIT_OUTSIDE_CTOR |
550 | | nscoord mComputedWidth; |
551 | | |
552 | | // The computed height specifies the frame's content height, and it does |
553 | | // not apply to inline non-replaced elements |
554 | | // |
555 | | // For replaced inline frames, a value of NS_INTRINSICSIZE means you should |
556 | | // use your intrinsic height as the computed height |
557 | | // |
558 | | // For non-replaced block-level frames in the flow and floated, a value of |
559 | | // NS_AUTOHEIGHT means you choose a height to shrink wrap around the normal |
560 | | // flow child frames. The height must be within the limit of the min/max |
561 | | // height if there is such a limit |
562 | | // |
563 | | // For replaced block-level frames, a value of NS_INTRINSICSIZE |
564 | | // means you use your intrinsic height as the computed height |
565 | | MOZ_INIT_OUTSIDE_CTOR |
566 | | nscoord mComputedHeight; |
567 | | |
568 | | // Computed values for 'left/top/right/bottom' offsets. Only applies to |
569 | | // 'positioned' elements. These are PHYSICAL coordinates (for now). |
570 | | nsMargin mComputedOffsets; |
571 | | |
572 | | // Computed values for 'min-width/max-width' and 'min-height/max-height' |
573 | | // XXXldb The width ones here should go; they should be needed only |
574 | | // internally. |
575 | | MOZ_INIT_OUTSIDE_CTOR |
576 | | nscoord mComputedMinWidth, mComputedMaxWidth; |
577 | | MOZ_INIT_OUTSIDE_CTOR |
578 | | nscoord mComputedMinHeight, mComputedMaxHeight; |
579 | | |
580 | | public: |
581 | | // Our saved containing block dimensions. |
582 | | MOZ_INIT_OUTSIDE_CTOR |
583 | | LogicalSize mContainingBlockSize; |
584 | | |
585 | | // Cached pointers to the various style structs used during intialization |
586 | | MOZ_INIT_OUTSIDE_CTOR |
587 | | const nsStyleDisplay* mStyleDisplay; |
588 | | MOZ_INIT_OUTSIDE_CTOR |
589 | | const nsStyleVisibility* mStyleVisibility; |
590 | | MOZ_INIT_OUTSIDE_CTOR |
591 | | const nsStylePosition* mStylePosition; |
592 | | MOZ_INIT_OUTSIDE_CTOR |
593 | | const nsStyleBorder* mStyleBorder; |
594 | | MOZ_INIT_OUTSIDE_CTOR |
595 | | const nsStyleMargin* mStyleMargin; |
596 | | MOZ_INIT_OUTSIDE_CTOR |
597 | | const nsStylePadding* mStylePadding; |
598 | | MOZ_INIT_OUTSIDE_CTOR |
599 | | const nsStyleText* mStyleText; |
600 | | |
601 | | bool IsFloating() const; |
602 | | |
603 | | mozilla::StyleDisplay GetDisplay() const; |
604 | | |
605 | | // a frame (e.g. nsTableCellFrame) which may need to generate a special |
606 | | // reflow for percent bsize calculations |
607 | | nsIPercentBSizeObserver* mPercentBSizeObserver; |
608 | | |
609 | | // CSS margin collapsing sometimes requires us to reflow |
610 | | // optimistically assuming that margins collapse to see if clearance |
611 | | // is required. When we discover that clearance is required, we |
612 | | // store the frame in which clearance was discovered to the location |
613 | | // requested here. |
614 | | nsIFrame** mDiscoveredClearance; |
615 | | |
616 | | ReflowInputFlags mFlags; |
617 | | |
618 | | // This value keeps track of how deeply nested a given reflow state |
619 | | // is from the top of the frame tree. |
620 | | int16_t mReflowDepth; |
621 | | |
622 | | // Logical and physical accessors for the resize flags. All users should go |
623 | | // via these accessors, so that in due course we can change the storage from |
624 | | // physical to logical. |
625 | | bool IsHResize() const { |
626 | | return mWritingMode.IsVertical() ? mFlags.mIsBResize : mFlags.mIsIResize; |
627 | | } |
628 | | bool IsVResize() const { |
629 | | return mWritingMode.IsVertical() ? mFlags.mIsIResize : mFlags.mIsBResize; |
630 | | } |
631 | 0 | bool IsIResize() const { |
632 | 0 | return mFlags.mIsIResize; |
633 | 0 | } |
634 | 0 | bool IsBResize() const { |
635 | 0 | return mFlags.mIsBResize; |
636 | 0 | } |
637 | 0 | bool IsBResizeForWM(mozilla::WritingMode aWM) const { |
638 | 0 | return aWM.IsOrthogonalTo(mWritingMode) ? mFlags.mIsIResize |
639 | 0 | : mFlags.mIsBResize; |
640 | 0 | } |
641 | | void SetHResize(bool aValue) { |
642 | | if (mWritingMode.IsVertical()) { |
643 | | mFlags.mIsBResize = aValue; |
644 | | } else { |
645 | | mFlags.mIsIResize = aValue; |
646 | | } |
647 | | } |
648 | | void SetVResize(bool aValue) { |
649 | | if (mWritingMode.IsVertical()) { |
650 | | mFlags.mIsIResize = aValue; |
651 | | } else { |
652 | | mFlags.mIsBResize = aValue; |
653 | | } |
654 | | } |
655 | 0 | void SetIResize(bool aValue) { |
656 | 0 | mFlags.mIsIResize = aValue; |
657 | 0 | } |
658 | | void SetBResize(bool aValue) { |
659 | | mFlags.mIsBResize = aValue; |
660 | | } |
661 | | |
662 | | // Note: The copy constructor is written by the compiler automatically. You |
663 | | // can use that and then override specific values if you want, or you can |
664 | | // call Init as desired... |
665 | | |
666 | | /** |
667 | | * Initialize a ROOT reflow state. |
668 | | * |
669 | | * @param aPresContext Must be equal to aFrame->PresContext(). |
670 | | * @param aFrame The frame for whose reflow state is being constructed. |
671 | | * @param aRenderingContext The rendering context to be used for measurements. |
672 | | * @param aAvailableSpace See comments for availableHeight and availableWidth |
673 | | * members. |
674 | | * @param aFlags A set of flags used for additional boolean parameters (see |
675 | | * below). |
676 | | */ |
677 | | ReflowInput(nsPresContext* aPresContext, |
678 | | nsIFrame* aFrame, |
679 | | gfxContext* aRenderingContext, |
680 | | const mozilla::LogicalSize& aAvailableSpace, |
681 | | uint32_t aFlags = 0); |
682 | | |
683 | | /** |
684 | | * Initialize a reflow state for a child frame's reflow. Some parts of the |
685 | | * state are copied from the parent's reflow state. The remainder is computed. |
686 | | * |
687 | | * @param aPresContext Must be equal to aFrame->PresContext(). |
688 | | * @param aParentReflowInput A reference to an ReflowInput object that |
689 | | * is to be the parent of this object. |
690 | | * @param aFrame The frame for whose reflow state is being constructed. |
691 | | * @param aAvailableSpace See comments for availableHeight and availableWidth |
692 | | * members. |
693 | | * @param aContainingBlockSize An optional size, in app units, specifying |
694 | | * the containing block size to use instead of the default which is |
695 | | * to use the aAvailableSpace. |
696 | | * @param aFlags A set of flags used for additional boolean parameters (see |
697 | | * below). |
698 | | */ |
699 | | ReflowInput(nsPresContext* aPresContext, |
700 | | const ReflowInput& aParentReflowInput, |
701 | | nsIFrame* aFrame, |
702 | | const mozilla::LogicalSize& aAvailableSpace, |
703 | | const mozilla::LogicalSize* aContainingBlockSize = nullptr, |
704 | | uint32_t aFlags = 0); |
705 | | |
706 | | // Values for |aFlags| passed to constructor |
707 | | enum { |
708 | | // Indicates that the parent of this reflow state is "fake" (see |
709 | | // mDummyParentReflowInput in mFlags). |
710 | | DUMMY_PARENT_REFLOW_STATE = (1<<0), |
711 | | |
712 | | // Indicates that the calling function will initialize the reflow state, and |
713 | | // that the constructor should not call Init(). |
714 | | CALLER_WILL_INIT = (1<<1), |
715 | | |
716 | | // The caller wants shrink-wrap behavior (i.e. ComputeSizeFlags::eShrinkWrap |
717 | | // will be passed to ComputeSize()). |
718 | | COMPUTE_SIZE_SHRINK_WRAP = (1<<2), |
719 | | |
720 | | // The caller wants 'auto' bsize behavior (ComputeSizeFlags::eUseAutoBSize |
721 | | // will be be passed to ComputeSize()). |
722 | | COMPUTE_SIZE_USE_AUTO_BSIZE = (1<<3), |
723 | | |
724 | | // The caller wants the abs.pos. static-position resolved at the origin of |
725 | | // the containing block, i.e. at LogicalPoint(0, 0). (Note that this |
726 | | // doesn't necessarily mean that (0, 0) is the *correct* static position |
727 | | // for the frame in question.) |
728 | | STATIC_POS_IS_CB_ORIGIN = (1<<4), |
729 | | |
730 | | // Pass ComputeSizeFlags::eIClampMarginBoxMinSize to ComputeSize(). |
731 | | I_CLAMP_MARGIN_BOX_MIN_SIZE = (1<<5), |
732 | | |
733 | | // Pass ComputeSizeFlags::eBClampMarginBoxMinSize to ComputeSize(). |
734 | | B_CLAMP_MARGIN_BOX_MIN_SIZE = (1<<6), |
735 | | |
736 | | // Pass ComputeSizeFlags::eIApplyAutoMinSize to ComputeSize(). |
737 | | I_APPLY_AUTO_MIN_SIZE = (1<<7), |
738 | | }; |
739 | | |
740 | | // This method initializes various data members. It is automatically |
741 | | // called by the various constructors |
742 | | void Init(nsPresContext* aPresContext, |
743 | | const mozilla::LogicalSize* aContainingBlockSize = nullptr, |
744 | | const nsMargin* aBorder = nullptr, |
745 | | const nsMargin* aPadding = nullptr); |
746 | | |
747 | | /** |
748 | | * Find the content isize of our containing block for the given writing mode, |
749 | | * which need not be the same as the reflow state's mode. |
750 | | */ |
751 | | nscoord GetContainingBlockContentISize(mozilla::WritingMode aWritingMode) const; |
752 | | |
753 | | /** |
754 | | * Calculate the used line-height property. The return value will be >= 0. |
755 | | */ |
756 | | nscoord CalcLineHeight() const; |
757 | | |
758 | | /** |
759 | | * Same as CalcLineHeight() above, but doesn't need a reflow state. |
760 | | * |
761 | | * @param aBlockBSize The computed block size of the content rect of the block |
762 | | * that the line should fill. |
763 | | * Only used with line-height:-moz-block-height. |
764 | | * NS_AUTOHEIGHT results in a normal line-height for |
765 | | * line-height:-moz-block-height. |
766 | | * @param aFontSizeInflation The result of the appropriate |
767 | | * nsLayoutUtils::FontSizeInflationFor call, |
768 | | * or 1.0 if during intrinsic size |
769 | | * calculation. |
770 | | */ |
771 | | static nscoord CalcLineHeight(nsIContent* aContent, |
772 | | ComputedStyle* aComputedStyle, |
773 | | nsPresContext* aPresContext, |
774 | | nscoord aBlockBSize, |
775 | | float aFontSizeInflation); |
776 | | |
777 | | |
778 | | mozilla::LogicalSize ComputeContainingBlockRectangle( |
779 | | nsPresContext* aPresContext, |
780 | | const ReflowInput* aContainingBlockRI) const; |
781 | | |
782 | | /** |
783 | | * Apply the mComputed(Min/Max)Width constraints to the content |
784 | | * size computed so far. |
785 | | */ |
786 | | nscoord ApplyMinMaxWidth(nscoord aWidth) const { |
787 | | if (NS_UNCONSTRAINEDSIZE != ComputedMaxWidth()) { |
788 | | aWidth = std::min(aWidth, ComputedMaxWidth()); |
789 | | } |
790 | | return std::max(aWidth, ComputedMinWidth()); |
791 | | } |
792 | | |
793 | | /** |
794 | | * Apply the mComputed(Min/Max)ISize constraints to the content |
795 | | * size computed so far. |
796 | | */ |
797 | | nscoord ApplyMinMaxISize(nscoord aISize) const { |
798 | | if (NS_UNCONSTRAINEDSIZE != ComputedMaxISize()) { |
799 | | aISize = std::min(aISize, ComputedMaxISize()); |
800 | | } |
801 | | return std::max(aISize, ComputedMinISize()); |
802 | | } |
803 | | |
804 | | /** |
805 | | * Apply the mComputed(Min/Max)Height constraints to the content |
806 | | * size computed so far. |
807 | | * |
808 | | * @param aHeight The height that we've computed an to which we want to apply |
809 | | * min/max constraints. |
810 | | * @param aConsumed The amount of the computed height that was consumed by |
811 | | * our prev-in-flows. |
812 | | */ |
813 | | nscoord ApplyMinMaxHeight(nscoord aHeight, nscoord aConsumed = 0) const { |
814 | | aHeight += aConsumed; |
815 | | |
816 | | if (NS_UNCONSTRAINEDSIZE != ComputedMaxHeight()) { |
817 | | aHeight = std::min(aHeight, ComputedMaxHeight()); |
818 | | } |
819 | | |
820 | | if (NS_UNCONSTRAINEDSIZE != ComputedMinHeight()) { |
821 | | aHeight = std::max(aHeight, ComputedMinHeight()); |
822 | | } |
823 | | |
824 | | return aHeight - aConsumed; |
825 | | } |
826 | | |
827 | | /** |
828 | | * Apply the mComputed(Min/Max)BSize constraints to the content |
829 | | * size computed so far. |
830 | | * |
831 | | * @param aBSize The block-size that we've computed an to which we want to apply |
832 | | * min/max constraints. |
833 | | * @param aConsumed The amount of the computed block-size that was consumed by |
834 | | * our prev-in-flows. |
835 | | */ |
836 | | nscoord ApplyMinMaxBSize(nscoord aBSize, nscoord aConsumed = 0) const { |
837 | | aBSize += aConsumed; |
838 | | |
839 | | if (NS_UNCONSTRAINEDSIZE != ComputedMaxBSize()) { |
840 | | aBSize = std::min(aBSize, ComputedMaxBSize()); |
841 | | } |
842 | | |
843 | | if (NS_UNCONSTRAINEDSIZE != ComputedMinBSize()) { |
844 | | aBSize = std::max(aBSize, ComputedMinBSize()); |
845 | | } |
846 | | |
847 | | return aBSize - aConsumed; |
848 | | } |
849 | | |
850 | | bool ShouldReflowAllKids() const { |
851 | | // Note that we could make a stronger optimization for IsBResize if |
852 | | // we use it in a ShouldReflowChild test that replaces the current |
853 | | // checks of NS_FRAME_IS_DIRTY | NS_FRAME_HAS_DIRTY_CHILDREN, if it |
854 | | // were tested there along with NS_FRAME_CONTAINS_RELATIVE_BSIZE. |
855 | | // This would need to be combined with a slight change in which |
856 | | // frames NS_FRAME_CONTAINS_RELATIVE_BSIZE is marked on. |
857 | | return (mFrame->GetStateBits() & NS_FRAME_IS_DIRTY) || |
858 | | IsIResize() || |
859 | | (IsBResize() && |
860 | | (mFrame->GetStateBits() & NS_FRAME_CONTAINS_RELATIVE_BSIZE)); |
861 | | } |
862 | | |
863 | | // This method doesn't apply min/max computed widths to the value passed in. |
864 | | void SetComputedWidth(nscoord aComputedWidth); |
865 | | |
866 | | // This method doesn't apply min/max computed heights to the value passed in. |
867 | | void SetComputedHeight(nscoord aComputedHeight); |
868 | | |
869 | | void SetComputedISize(nscoord aComputedISize) { |
870 | | if (mWritingMode.IsVertical()) { |
871 | | SetComputedHeight(aComputedISize); |
872 | | } else { |
873 | | SetComputedWidth(aComputedISize); |
874 | | } |
875 | | } |
876 | | |
877 | | void SetComputedBSize(nscoord aComputedBSize) { |
878 | | if (mWritingMode.IsVertical()) { |
879 | | SetComputedWidth(aComputedBSize); |
880 | | } else { |
881 | | SetComputedHeight(aComputedBSize); |
882 | | } |
883 | | } |
884 | | |
885 | | void SetComputedBSizeWithoutResettingResizeFlags(nscoord aComputedBSize) { |
886 | | // Viewport frames reset the computed block size on a copy of their reflow |
887 | | // state when reflowing fixed-pos kids. In that case we actually don't |
888 | | // want to mess with the resize flags, because comparing the frame's rect |
889 | | // to the munged computed isize is pointless. |
890 | | ComputedBSize() = aComputedBSize; |
891 | | } |
892 | | |
893 | | void SetTruncated(const ReflowOutput& aMetrics, nsReflowStatus* aStatus) const; |
894 | | |
895 | | bool WillReflowAgainForClearance() const { |
896 | | return mDiscoveredClearance && *mDiscoveredClearance; |
897 | | } |
898 | | |
899 | | // Compute the offsets for a relative position element |
900 | | static void ComputeRelativeOffsets(mozilla::WritingMode aWM, |
901 | | nsIFrame* aFrame, |
902 | | const mozilla::LogicalSize& aCBSize, |
903 | | nsMargin& aComputedOffsets); |
904 | | |
905 | | // If a relatively positioned element, adjust the position appropriately. |
906 | | static void ApplyRelativePositioning(nsIFrame* aFrame, |
907 | | const nsMargin& aComputedOffsets, |
908 | | nsPoint* aPosition); |
909 | | |
910 | | void ApplyRelativePositioning(nsPoint* aPosition) const { |
911 | | ApplyRelativePositioning(mFrame, ComputedPhysicalOffsets(), aPosition); |
912 | | } |
913 | | |
914 | | static void |
915 | | ApplyRelativePositioning(nsIFrame* aFrame, |
916 | | mozilla::WritingMode aWritingMode, |
917 | | const mozilla::LogicalMargin& aComputedOffsets, |
918 | | mozilla::LogicalPoint* aPosition, |
919 | 0 | const nsSize& aContainerSize) { |
920 | 0 | // Subtract the size of the frame from the container size that we |
921 | 0 | // use for converting between the logical and physical origins of |
922 | 0 | // the frame. This accounts for the fact that logical origins in RTL |
923 | 0 | // coordinate systems are at the top right of the frame instead of |
924 | 0 | // the top left. |
925 | 0 | nsSize frameSize = aFrame->GetSize(); |
926 | 0 | nsPoint pos = aPosition->GetPhysicalPoint(aWritingMode, |
927 | 0 | aContainerSize - frameSize); |
928 | 0 | ApplyRelativePositioning(aFrame, |
929 | 0 | aComputedOffsets.GetPhysicalMargin(aWritingMode), |
930 | 0 | &pos); |
931 | 0 | *aPosition = mozilla::LogicalPoint(aWritingMode, pos, |
932 | 0 | aContainerSize - frameSize); |
933 | 0 | } |
934 | | |
935 | | void ApplyRelativePositioning(mozilla::LogicalPoint* aPosition, |
936 | | const nsSize& aContainerSize) const { |
937 | | ApplyRelativePositioning(mFrame, mWritingMode, |
938 | | ComputedLogicalOffsets(), aPosition, |
939 | | aContainerSize); |
940 | | } |
941 | | |
942 | | #ifdef DEBUG |
943 | | // Reflow trace methods. Defined in nsFrame.cpp so they have access |
944 | | // to the display-reflow infrastructure. |
945 | | static void* DisplayInitConstraintsEnter(nsIFrame* aFrame, |
946 | | ReflowInput* aState, |
947 | | nscoord aCBISize, |
948 | | nscoord aCBBSize, |
949 | | const nsMargin* aBorder, |
950 | | const nsMargin* aPadding); |
951 | | static void DisplayInitConstraintsExit(nsIFrame* aFrame, |
952 | | ReflowInput* aState, |
953 | | void* aValue); |
954 | | static void* DisplayInitFrameTypeEnter(nsIFrame* aFrame, |
955 | | ReflowInput* aState); |
956 | | static void DisplayInitFrameTypeExit(nsIFrame* aFrame, |
957 | | ReflowInput* aState, |
958 | | void* aValue); |
959 | | #endif |
960 | | |
961 | | protected: |
962 | | void InitFrameType(LayoutFrameType aFrameType); |
963 | | void InitCBReflowInput(); |
964 | | void InitResizeFlags(nsPresContext* aPresContext, |
965 | | mozilla::LayoutFrameType aFrameType); |
966 | | |
967 | | void InitConstraints(nsPresContext* aPresContext, |
968 | | const mozilla::LogicalSize& aContainingBlockSize, |
969 | | const nsMargin* aBorder, |
970 | | const nsMargin* aPadding, |
971 | | mozilla::LayoutFrameType aFrameType); |
972 | | |
973 | | // Returns the nearest containing block or block frame (whether or not |
974 | | // it is a containing block) for the specified frame. Also returns |
975 | | // the inline-start edge and logical size of the containing block's |
976 | | // content area. |
977 | | // These are returned in the coordinate space of the containing block. |
978 | | nsIFrame* GetHypotheticalBoxContainer(nsIFrame* aFrame, |
979 | | nscoord& aCBIStartEdge, |
980 | | mozilla::LogicalSize& aCBSize) const; |
981 | | |
982 | | // Calculate a "hypothetical box" position where the placeholder frame |
983 | | // (for a position:fixed/absolute element) would have been placed if it were |
984 | | // positioned statically. The hypothetical box position will have a writing |
985 | | // mode with the same block direction as the absolute containing block |
986 | | // (aReflowInput->frame), though it may differ in inline direction. |
987 | | void CalculateHypotheticalPosition(nsPresContext* aPresContext, |
988 | | nsPlaceholderFrame* aPlaceholderFrame, |
989 | | const ReflowInput* aReflowInput, |
990 | | nsHypotheticalPosition& aHypotheticalPos, |
991 | | mozilla::LayoutFrameType aFrameType) const; |
992 | | |
993 | | void InitAbsoluteConstraints(nsPresContext* aPresContext, |
994 | | const ReflowInput* aReflowInput, |
995 | | const mozilla::LogicalSize& aContainingBlockSize, |
996 | | mozilla::LayoutFrameType aFrameType); |
997 | | |
998 | | // Calculates the computed values for the 'min-Width', 'max-Width', |
999 | | // 'min-Height', and 'max-Height' properties, and stores them in the assorted |
1000 | | // data members |
1001 | | void ComputeMinMaxValues(const mozilla::LogicalSize& aContainingBlockSize); |
1002 | | |
1003 | | // aInsideBoxSizing returns the part of the padding, border, and margin |
1004 | | // in the aAxis dimension that goes inside the edge given by box-sizing; |
1005 | | // aOutsideBoxSizing returns the rest. |
1006 | | void CalculateBorderPaddingMargin(mozilla::LogicalAxis aAxis, |
1007 | | nscoord aContainingBlockSize, |
1008 | | nscoord* aInsideBoxSizing, |
1009 | | nscoord* aOutsideBoxSizing) const; |
1010 | | |
1011 | | void CalculateBlockSideMargins(LayoutFrameType aFrameType); |
1012 | | }; |
1013 | | |
1014 | | } // namespace mozilla |
1015 | | |
1016 | | #endif // mozilla_ReflowInput_h |