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 #ifndef nsColumnSetFrame_h___
7 #define nsColumnSetFrame_h___
9 /* rendering object for css3 multi-column layout */
11 #include "mozilla/Attributes.h"
12 #include "nsContainerFrame.h"
13 #include "nsIFrameInlines.h" // for methods used by IS_TRUE_OVERFLOW_CONTAINER
15 class nsColumnSetFrame MOZ_FINAL
: public nsContainerFrame
{
17 NS_DECL_FRAMEARENA_HELPERS
19 explicit nsColumnSetFrame(nsStyleContext
* aContext
);
21 virtual void Reflow(nsPresContext
* aPresContext
,
22 nsHTMLReflowMetrics
& aDesiredSize
,
23 const nsHTMLReflowState
& aReflowState
,
24 nsReflowStatus
& aStatus
) MOZ_OVERRIDE
;
27 virtual void SetInitialChildList(ChildListID aListID
,
28 nsFrameList
& aChildList
) MOZ_OVERRIDE
;
29 virtual void AppendFrames(ChildListID aListID
,
30 nsFrameList
& aFrameList
) MOZ_OVERRIDE
;
31 virtual void InsertFrames(ChildListID aListID
,
33 nsFrameList
& aFrameList
) MOZ_OVERRIDE
;
34 virtual void RemoveFrame(ChildListID aListID
,
35 nsIFrame
* aOldFrame
) MOZ_OVERRIDE
;
38 virtual nscoord
GetMinISize(nsRenderingContext
*aRenderingContext
) MOZ_OVERRIDE
;
39 virtual nscoord
GetPrefISize(nsRenderingContext
*aRenderingContext
) MOZ_OVERRIDE
;
42 * Retrieve the available height for content of this frame. The available content
43 * height is the available height for the frame, minus borders and padding.
45 virtual nscoord
GetAvailableContentHeight(const nsHTMLReflowState
& aReflowState
);
47 virtual nsContainerFrame
* GetContentInsertionFrame() MOZ_OVERRIDE
{
48 nsIFrame
* frame
= GetFirstPrincipalChild();
50 // if no children return nullptr
54 return frame
->GetContentInsertionFrame();
57 virtual nsresult
StealFrame(nsIFrame
* aChild
, bool aForceNormal
) MOZ_OVERRIDE
59 // nsColumnSetFrame keeps true overflow containers in the normal flow
60 // child lists (i.e. the principal and overflow lists).
61 return nsContainerFrame::StealFrame(aChild
,
62 IS_TRUE_OVERFLOW_CONTAINER(aChild
));
65 virtual bool IsFrameOfType(uint32_t aFlags
) const MOZ_OVERRIDE
67 return nsContainerFrame::IsFrameOfType(aFlags
&
68 ~(nsIFrame::eCanContainOverflowContainers
));
71 virtual void BuildDisplayList(nsDisplayListBuilder
* aBuilder
,
72 const nsRect
& aDirtyRect
,
73 const nsDisplayListSet
& aLists
) MOZ_OVERRIDE
;
75 virtual nsIAtom
* GetType() const MOZ_OVERRIDE
;
77 virtual void PaintColumnRule(nsRenderingContext
* aCtx
,
78 const nsRect
& aDirtyRect
,
82 * Similar to nsBlockFrame::DrainOverflowLines. Locate any columns not
83 * handled by our prev-in-flow, and any columns sitting on our own
84 * overflow list, and put them in our primary child list for reflowing.
86 void DrainOverflowColumns();
88 #ifdef DEBUG_FRAME_DUMP
89 virtual nsresult
GetFrameName(nsAString
& aResult
) const MOZ_OVERRIDE
{
90 return MakeFrameName(NS_LITERAL_STRING("ColumnSet"), aResult
);
95 nscoord mLastBalanceHeight
;
96 nsReflowStatus mLastFrameStatus
;
99 * These are the parameters that control the layout of columns.
101 struct ReflowConfig
{
102 // The number of columns that we want to balance across. If we're not
103 // balancing, this will be set to INT32_MAX.
104 int32_t mBalanceColCount
;
106 // The width of each individual column.
109 // The amount of width that is expected to be left over after all the
110 // columns and column gaps are laid out.
111 nscoord mExpectedWidthLeftOver
;
113 // The width of each column gap.
116 // The maximum height of any individual column during a reflow iteration.
117 // This parameter is set during each iteration of the binary search for
118 // the best column height.
119 nscoord mColMaxHeight
;
121 // A boolean controlling whether or not we are balancing. This should be
122 // equivalent to mBalanceColCount == INT32_MAX.
125 // The last known column height that was 'feasible'. A column height is
126 // feasible if all child content fits within the specified height.
127 nscoord mKnownFeasibleHeight
;
129 // The last known height that was 'infeasible'. A column height is
130 // infeasible if not all child content fits within the specified height.
131 nscoord mKnownInfeasibleHeight
;
133 // Height of the column set frame
134 nscoord mComputedHeight
;
136 // The height "consumed" by previous-in-flows.
137 // The computed height should be equal to the height of the element (i.e.
138 // the computed height itself) plus the consumed height.
139 nscoord mConsumedHeight
;
143 * Some data that is better calculated during reflow
145 struct ColumnBalanceData
{
146 // The maximum "content height" of any column
148 // The sum of the "content heights" for all columns
150 // The "content height" of the last column
152 // The maximum "content height" of all columns that overflowed
153 // their available height
154 nscoord mMaxOverflowingHeight
;
155 // This flag determines whether the last reflow of children exceeded the
156 // computed height of the column set frame. If so, we set the height to
157 // this maximum allowable height, and continue reflow without balancing.
158 bool mHasExcessHeight
;
161 mMaxHeight
= mSumHeight
= mLastHeight
= mMaxOverflowingHeight
= 0;
162 mHasExcessHeight
= false;
166 bool ReflowColumns(nsHTMLReflowMetrics
& aDesiredSize
,
167 const nsHTMLReflowState
& aReflowState
,
168 nsReflowStatus
& aReflowStatus
,
169 ReflowConfig
& aConfig
,
170 bool aLastColumnUnbounded
,
171 nsCollapsingMargin
* aCarriedOutBottomMargin
,
172 ColumnBalanceData
& aColData
);
175 * The basic reflow strategy is to call this function repeatedly to
176 * obtain specific parameters that determine the layout of the
177 * columns. This function will compute those parameters from the CSS
178 * style. This function will also be responsible for implementing
179 * the state machine that controls column balancing.
181 ReflowConfig
ChooseColumnStrategy(const nsHTMLReflowState
& aReflowState
,
182 bool aForceAuto
, nscoord aFeasibleHeight
,
183 nscoord aInfeasibleHeight
);
186 * Perform the binary search for the best balance height for this column set.
188 * @param aReflowState The input parameters for the current reflow iteration.
189 * @param aPresContext The presentation context in which the current reflow
190 * iteration is occurring.
191 * @param aConfig The ReflowConfig object associated with this column set
192 * frame, generated by ChooseColumnStrategy().
193 * @param aColData A data structure used to keep track of data needed between
194 * successive iterations of the balancing process.
195 * @param aDesiredSize The final output size of the column set frame (output
196 * of reflow procedure).
197 * @param aOutMargin The bottom margin of the column set frame that may be
198 * carried out from reflow (and thus collapsed).
199 * @param aUnboundedLastColumn A boolean value indicating that the last column
200 * can be of any height. Used during the first iteration of the
201 * balancing procedure to measure the height of all content in
202 * descendant frames of the column set.
203 * @param aRunWasFeasible An input/output parameter indicating whether or not
204 * the last iteration of the balancing loop was a feasible height to
205 * fit all content from descendant frames.
206 * @param aStatus A final reflow status of the column set frame, passed in as
207 * an output parameter.
209 void FindBestBalanceHeight(const nsHTMLReflowState
& aReflowState
,
210 nsPresContext
* aPresContext
,
211 ReflowConfig
& aConfig
,
212 ColumnBalanceData
& aColData
,
213 nsHTMLReflowMetrics
& aDesiredSize
,
214 nsCollapsingMargin
& aOutMargin
,
215 bool& aUnboundedLastColumn
,
216 bool& aRunWasFeasible
,
217 nsReflowStatus
& aStatus
);
219 * Reflow column children. Returns true iff the content that was reflowed
220 * fit into the mColMaxHeight.
222 bool ReflowChildren(nsHTMLReflowMetrics
& aDesiredSize
,
223 const nsHTMLReflowState
& aReflowState
,
224 nsReflowStatus
& aStatus
,
225 const ReflowConfig
& aConfig
,
226 bool aLastColumnUnbounded
,
227 nsCollapsingMargin
* aCarriedOutBottomMargin
,
228 ColumnBalanceData
& aColData
);
231 #endif // nsColumnSetFrame_h___