Wed, 31 Dec 2014 06:09:35 +0100
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 /* rendering object for css3 multi-column layout */
8 #include "mozilla/Attributes.h"
9 #include "nsContainerFrame.h"
11 class nsColumnSetFrame : public nsContainerFrame {
12 public:
13 NS_DECL_FRAMEARENA_HELPERS
15 nsColumnSetFrame(nsStyleContext* aContext);
17 virtual nsresult SetInitialChildList(ChildListID aListID,
18 nsFrameList& aChildList) MOZ_OVERRIDE;
20 virtual nsresult Reflow(nsPresContext* aPresContext,
21 nsHTMLReflowMetrics& aDesiredSize,
22 const nsHTMLReflowState& aReflowState,
23 nsReflowStatus& aStatus) MOZ_OVERRIDE;
25 virtual nsresult AppendFrames(ChildListID aListID,
26 nsFrameList& aFrameList) MOZ_OVERRIDE;
27 virtual nsresult InsertFrames(ChildListID aListID,
28 nsIFrame* aPrevFrame,
29 nsFrameList& aFrameList) MOZ_OVERRIDE;
30 virtual nsresult RemoveFrame(ChildListID aListID,
31 nsIFrame* aOldFrame) MOZ_OVERRIDE;
33 virtual nscoord GetMinWidth(nsRenderingContext *aRenderingContext) MOZ_OVERRIDE;
34 virtual nscoord GetPrefWidth(nsRenderingContext *aRenderingContext) MOZ_OVERRIDE;
36 /**
37 * Retrieve the available height for content of this frame. The available content
38 * height is the available height for the frame, minus borders and padding.
39 */
40 virtual nscoord GetAvailableContentHeight(const nsHTMLReflowState& aReflowState);
42 virtual nsIFrame* GetContentInsertionFrame() MOZ_OVERRIDE {
43 nsIFrame* frame = GetFirstPrincipalChild();
45 // if no children return nullptr
46 if (!frame)
47 return nullptr;
49 return frame->GetContentInsertionFrame();
50 }
52 virtual nsresult StealFrame(nsIFrame* aChild, bool aForceNormal) MOZ_OVERRIDE
53 { // nsColumnSetFrame keeps overflow containers in main child list
54 return nsContainerFrame::StealFrame(aChild, true);
55 }
57 virtual bool IsFrameOfType(uint32_t aFlags) const MOZ_OVERRIDE
58 {
59 return nsContainerFrame::IsFrameOfType(aFlags &
60 ~(nsIFrame::eCanContainOverflowContainers));
61 }
63 virtual void BuildDisplayList(nsDisplayListBuilder* aBuilder,
64 const nsRect& aDirtyRect,
65 const nsDisplayListSet& aLists) MOZ_OVERRIDE;
67 virtual nsIAtom* GetType() const MOZ_OVERRIDE;
69 virtual void PaintColumnRule(nsRenderingContext* aCtx,
70 const nsRect& aDirtyRect,
71 const nsPoint& aPt);
73 #ifdef DEBUG_FRAME_DUMP
74 virtual nsresult GetFrameName(nsAString& aResult) const MOZ_OVERRIDE {
75 return MakeFrameName(NS_LITERAL_STRING("ColumnSet"), aResult);
76 }
77 #endif
79 protected:
80 nscoord mLastBalanceHeight;
81 nsReflowStatus mLastFrameStatus;
83 /**
84 * These are the parameters that control the layout of columns.
85 */
86 struct ReflowConfig {
87 // The number of columns that we want to balance across. If we're not
88 // balancing, this will be set to INT32_MAX.
89 int32_t mBalanceColCount;
91 // The width of each individual column.
92 nscoord mColWidth;
94 // The amount of width that is expected to be left over after all the
95 // columns and column gaps are laid out.
96 nscoord mExpectedWidthLeftOver;
98 // The width of each column gap.
99 nscoord mColGap;
101 // The maximum height of any individual column during a reflow iteration.
102 // This parameter is set during each iteration of the binary search for
103 // the best column height.
104 nscoord mColMaxHeight;
106 // A boolean controlling whether or not we are balancing. This should be
107 // equivalent to mBalanceColCount == INT32_MAX.
108 bool mIsBalancing;
110 // The last known column height that was 'feasible'. A column height is
111 // feasible if all child content fits within the specified height.
112 nscoord mKnownFeasibleHeight;
114 // The last known height that was 'infeasible'. A column height is
115 // infeasible if not all child content fits within the specified height.
116 nscoord mKnownInfeasibleHeight;
118 // Height of the column set frame
119 nscoord mComputedHeight;
121 // The height "consumed" by previous-in-flows.
122 // The computed height should be equal to the height of the element (i.e.
123 // the computed height itself) plus the consumed height.
124 nscoord mConsumedHeight;
125 };
127 /**
128 * Some data that is better calculated during reflow
129 */
130 struct ColumnBalanceData {
131 // The maximum "content height" of any column
132 nscoord mMaxHeight;
133 // The sum of the "content heights" for all columns
134 nscoord mSumHeight;
135 // The "content height" of the last column
136 nscoord mLastHeight;
137 // The maximum "content height" of all columns that overflowed
138 // their available height
139 nscoord mMaxOverflowingHeight;
140 // This flag determines whether the last reflow of children exceeded the
141 // computed height of the column set frame. If so, we set the height to
142 // this maximum allowable height, and continue reflow without balancing.
143 bool mHasExcessHeight;
145 void Reset() {
146 mMaxHeight = mSumHeight = mLastHeight = mMaxOverflowingHeight = 0;
147 mHasExcessHeight = false;
148 }
149 };
151 /**
152 * Similar to nsBlockFrame::DrainOverflowLines. Locate any columns not
153 * handled by our prev-in-flow, and any columns sitting on our own
154 * overflow list, and put them in our primary child list for reflowing.
155 */
156 void DrainOverflowColumns();
158 bool ReflowColumns(nsHTMLReflowMetrics& aDesiredSize,
159 const nsHTMLReflowState& aReflowState,
160 nsReflowStatus& aReflowStatus,
161 ReflowConfig& aConfig,
162 bool aLastColumnUnbounded,
163 nsCollapsingMargin* aCarriedOutBottomMargin,
164 ColumnBalanceData& aColData);
166 /**
167 * The basic reflow strategy is to call this function repeatedly to
168 * obtain specific parameters that determine the layout of the
169 * columns. This function will compute those parameters from the CSS
170 * style. This function will also be responsible for implementing
171 * the state machine that controls column balancing.
172 */
173 ReflowConfig ChooseColumnStrategy(const nsHTMLReflowState& aReflowState,
174 bool aForceAuto, nscoord aFeasibleHeight,
175 nscoord aInfeasibleHeight);
177 /**
178 * Perform the binary search for the best balance height for this column set.
179 *
180 * @param aReflowState The input parameters for the current reflow iteration.
181 * @param aPresContext The presentation context in which the current reflow
182 * iteration is occurring.
183 * @param aConfig The ReflowConfig object associated with this column set
184 * frame, generated by ChooseColumnStrategy().
185 * @param aColData A data structure used to keep track of data needed between
186 * successive iterations of the balancing process.
187 * @param aDesiredSize The final output size of the column set frame (output
188 * of reflow procedure).
189 * @param aOutMargin The bottom margin of the column set frame that may be
190 * carried out from reflow (and thus collapsed).
191 * @param aUnboundedLastColumn A boolean value indicating that the last column
192 * can be of any height. Used during the first iteration of the
193 * balancing procedure to measure the height of all content in
194 * descendant frames of the column set.
195 * @param aRunWasFeasible An input/output parameter indicating whether or not
196 * the last iteration of the balancing loop was a feasible height to
197 * fit all content from descendant frames.
198 * @param aStatus A final reflow status of the column set frame, passed in as
199 * an output parameter.
200 */
201 void FindBestBalanceHeight(const nsHTMLReflowState& aReflowState,
202 nsPresContext* aPresContext,
203 ReflowConfig& aConfig,
204 ColumnBalanceData& aColData,
205 nsHTMLReflowMetrics& aDesiredSize,
206 nsCollapsingMargin& aOutMargin,
207 bool& aUnboundedLastColumn,
208 bool& aRunWasFeasible,
209 nsReflowStatus& aStatus);
210 /**
211 * Reflow column children. Returns true iff the content that was reflowed
212 * fit into the mColMaxHeight.
213 */
214 bool ReflowChildren(nsHTMLReflowMetrics& aDesiredSize,
215 const nsHTMLReflowState& aReflowState,
216 nsReflowStatus& aStatus,
217 const ReflowConfig& aConfig,
218 bool aLastColumnUnbounded,
219 nsCollapsingMargin* aCarriedOutBottomMargin,
220 ColumnBalanceData& aColData);
221 };