Bug 1874684 - Part 20: Tag stack classes with MOZ_STACK_CLASS. r=allstarschh
[gecko.git] / layout / generic / nsColumnSetFrame.h
blob20df72a07def215370b258ae7928527e7903ddc3
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/. */
7 #ifndef nsColumnSetFrame_h___
8 #define nsColumnSetFrame_h___
10 /* rendering object for css3 multi-column layout */
12 #include "mozilla/Attributes.h"
13 #include "nsContainerFrame.h"
15 class nsCSSBorderRenderer;
17 /**
18 * nsColumnSetFrame implements CSS multi-column layout.
19 * @note nsColumnSetFrame keeps true overflow containers in the normal flow
20 * child lists (i.e. the principal and overflow lists).
22 class nsColumnSetFrame final : public nsContainerFrame {
23 public:
24 NS_DECL_FRAMEARENA_HELPERS(nsColumnSetFrame)
26 explicit nsColumnSetFrame(ComputedStyle* aStyle, nsPresContext* aPresContext);
28 void Reflow(nsPresContext* aPresContext, ReflowOutput& aDesiredSize,
29 const ReflowInput& aReflowInput,
30 nsReflowStatus& aStatus) override;
32 #ifdef DEBUG
33 void SetInitialChildList(ChildListID aListID,
34 nsFrameList&& aChildList) override;
35 void AppendFrames(ChildListID aListID, nsFrameList&& aFrameList) override;
36 void InsertFrames(ChildListID aListID, nsIFrame* aPrevFrame,
37 const nsLineList::iterator* aPrevFrameLine,
38 nsFrameList&& aFrameList) override;
39 void RemoveFrame(DestroyContext&, ChildListID, nsIFrame*) override;
40 #endif
42 nscoord GetMinISize(gfxContext* aRenderingContext) override;
43 nscoord GetPrefISize(gfxContext* aRenderingContext) override;
45 nsContainerFrame* GetContentInsertionFrame() override {
46 nsIFrame* frame = PrincipalChildList().FirstChild();
48 // if no children return nullptr
49 if (!frame) return nullptr;
51 return frame->GetContentInsertionFrame();
54 void BuildDisplayList(nsDisplayListBuilder* aBuilder,
55 const nsDisplayListSet& aLists) override;
57 /**
58 * Similar to nsBlockFrame::DrainOverflowLines. Locate any columns not
59 * handled by our prev-in-flow, and any columns sitting on our own
60 * overflow list, and put them in our primary child list for reflowing.
62 void DrainOverflowColumns();
64 // Return the column-content frame.
65 void AppendDirectlyOwnedAnonBoxes(nsTArray<OwnedAnonBox>& aResult) override;
67 #ifdef DEBUG_FRAME_DUMP
68 nsresult GetFrameName(nsAString& aResult) const override {
69 return MakeFrameName(u"ColumnSet"_ns, aResult);
71 #endif
73 void CreateBorderRenderers(nsTArray<nsCSSBorderRenderer>& aBorderRenderers,
74 gfxContext* aCtx, const nsRect& aDirtyRect,
75 const nsPoint& aPt);
77 Maybe<nscoord> GetNaturalBaselineBOffset(
78 mozilla::WritingMode aWM, BaselineSharingGroup aBaselineGroup,
79 BaselineExportContext aExportContext) const override;
81 protected:
82 nscoord mLastBalanceBSize;
83 nsReflowStatus mLastFrameStatus;
85 /**
86 * These are the parameters that control the layout of columns.
88 struct ReflowConfig {
89 // The optimal number of columns that we want to use. This is computed from
90 // column-count, column-width, available inline-size, etc.
91 int32_t mUsedColCount = INT32_MAX;
93 // The inline-size of each individual column.
94 nscoord mColISize = NS_UNCONSTRAINEDSIZE;
96 // The amount of inline-size that is expected to be left over after all the
97 // columns and column gaps are laid out.
98 nscoord mExpectedISizeLeftOver = 0;
100 // The width (inline-size) of each column gap.
101 nscoord mColGap = NS_UNCONSTRAINEDSIZE;
103 // The available block-size of each individual column. This parameter is set
104 // during each iteration of the binary search for the best column
105 // block-size.
106 nscoord mColBSize = NS_UNCONSTRAINEDSIZE;
108 // A boolean controlling whether or not we are balancing.
109 bool mIsBalancing = false;
111 // A boolean controlling whether or not we are forced to fill columns
112 // sequentially.
113 bool mForceAuto = false;
115 // A boolean indicates whether or not we are in the last attempt to reflow
116 // columns. We set it to true at the end of FindBestBalanceBSize().
117 bool mIsLastBalancingReflow = false;
119 // The last known column block-size that was 'feasible'. A column bSize is
120 // feasible if all child content fits within the specified bSize.
121 nscoord mKnownFeasibleBSize = NS_UNCONSTRAINEDSIZE;
123 // The last known block-size that was 'infeasible'. A column bSize is
124 // infeasible if not all child content fits within the specified bSize.
125 nscoord mKnownInfeasibleBSize = 0;
128 // Collect various block-size data calculated in ReflowChildren(), which are
129 // mainly used for column balancing. This is the output of ReflowChildren()
130 // and ReflowColumns().
131 struct ColumnBalanceData {
132 // The maximum "content block-size" of any column
133 nscoord mMaxBSize = 0;
135 // The sum of the "content block-size" for all columns
136 nscoord mSumBSize = 0;
138 // The "content block-size" of the last column
139 nscoord mLastBSize = 0;
141 // The maximum "content block-size" of all columns that overflowed
142 // their available block-size
143 nscoord mMaxOverflowingBSize = 0;
145 // The number of columns (starting from 1 because we have at least one
146 // column). It can be less than ReflowConfig::mUsedColCount.
147 int32_t mColCount = 1;
149 // This flag indicates the content that was reflowed fits into the
150 // mColMaxBSize in ReflowConfig.
151 bool mFeasible = false;
154 ColumnBalanceData ReflowColumns(ReflowOutput& aDesiredSize,
155 const ReflowInput& aReflowInput,
156 nsReflowStatus& aStatus,
157 const ReflowConfig& aConfig,
158 bool aUnboundedLastColumn);
161 * The basic reflow strategy is to call this function repeatedly to
162 * obtain specific parameters that determine the layout of the
163 * columns. This function will compute those parameters from the CSS
164 * style. This function will also be responsible for implementing
165 * the state machine that controls column balancing.
167 ReflowConfig ChooseColumnStrategy(const ReflowInput& aReflowInput,
168 bool aForceAuto) const;
171 * Perform the binary search for the best balance block-size for this column
172 * set.
174 * @param aReflowInput The input parameters for the current reflow iteration.
175 * @param aPresContext The presentation context in which the current reflow
176 * iteration is occurring.
177 * @param aConfig The ReflowConfig object associated with this column set
178 * frame, generated by ChooseColumnStrategy().
179 * @param aColData A data structure used to keep track of data needed between
180 * successive iterations of the balancing process.
181 * @param aDesiredSize The final output size of the column set frame (output
182 * of reflow procedure).
183 * @param aUnboundedLastColumn A boolean value indicating that the last column
184 * can be of any block-size. Used during the first iteration of the
185 * balancing procedure to measure the block-size of all content in
186 * descendant frames of the column set.
187 * @param aStatus A final reflow status of the column set frame, passed in as
188 * an output parameter.
190 void FindBestBalanceBSize(const ReflowInput& aReflowInput,
191 nsPresContext* aPresContext, ReflowConfig& aConfig,
192 ColumnBalanceData aColData,
193 ReflowOutput& aDesiredSize,
194 bool aUnboundedLastColumn, nsReflowStatus& aStatus);
196 void ForEachColumnRule(
197 const std::function<void(const nsRect& lineRect)>& aSetLineRect,
198 const nsPoint& aPt) const;
201 #endif // nsColumnSetFrame_h___