Coverage Report

Created: 2018-09-25 14:53

/src/mozilla-central/layout/generic/nsColumnSetFrame.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
#ifndef nsColumnSetFrame_h___
8
#define nsColumnSetFrame_h___
9
10
/* rendering object for css3 multi-column layout */
11
12
#include "mozilla/Attributes.h"
13
#include "nsContainerFrame.h"
14
#include "nsIFrameInlines.h" // for methods used by IS_TRUE_OVERFLOW_CONTAINER
15
16
/**
17
 * nsColumnSetFrame implements CSS multi-column layout.
18
 * @note nsColumnSetFrame keeps true overflow containers in the normal flow
19
 * child lists (i.e. the principal and overflow lists).
20
 */
21
class nsColumnSetFrame final : public nsContainerFrame
22
{
23
public:
24
  NS_DECL_FRAMEARENA_HELPERS(nsColumnSetFrame)
25
26
  explicit nsColumnSetFrame(ComputedStyle* aStyle);
27
28
  virtual void Reflow(nsPresContext* aPresContext,
29
                      ReflowOutput& aDesiredSize,
30
                      const ReflowInput& aReflowInput,
31
                      nsReflowStatus& aStatus) override;
32
33
#ifdef DEBUG
34
  virtual void SetInitialChildList(ChildListID     aListID,
35
                                   nsFrameList&    aChildList) override;
36
  virtual void AppendFrames(ChildListID     aListID,
37
                            nsFrameList&    aFrameList) override;
38
  virtual void InsertFrames(ChildListID     aListID,
39
                            nsIFrame*       aPrevFrame,
40
                            nsFrameList&    aFrameList) override;
41
  virtual void RemoveFrame(ChildListID     aListID,
42
                           nsIFrame*       aOldFrame) override;
43
#endif
44
45
  virtual nscoord GetMinISize(gfxContext *aRenderingContext) override;
46
  virtual nscoord GetPrefISize(gfxContext *aRenderingContext) override;
47
48
  /**
49
   * Retrieve the available height for content of this frame. The available content
50
   * height is the available height for the frame, minus borders and padding.
51
   */
52
  virtual nscoord GetAvailableContentBSize(const ReflowInput& aReflowInput);
53
54
0
  virtual nsContainerFrame* GetContentInsertionFrame() override {
55
0
    nsIFrame* frame = PrincipalChildList().FirstChild();
56
0
57
0
    // if no children return nullptr
58
0
    if (!frame)
59
0
      return nullptr;
60
0
61
0
    return frame->GetContentInsertionFrame();
62
0
  }
63
64
  virtual bool IsFrameOfType(uint32_t aFlags) const override
65
0
   {
66
0
     return nsContainerFrame::IsFrameOfType(aFlags &
67
0
              ~(nsIFrame::eCanContainOverflowContainers));
68
0
   }
69
70
  virtual void BuildDisplayList(nsDisplayListBuilder*   aBuilder,
71
                                const nsDisplayListSet& aLists) override;
72
73
  /**
74
   * Similar to nsBlockFrame::DrainOverflowLines. Locate any columns not
75
   * handled by our prev-in-flow, and any columns sitting on our own
76
   * overflow list, and put them in our primary child list for reflowing.
77
   */
78
  void DrainOverflowColumns();
79
80
  // Return the column-content frame.
81
  void AppendDirectlyOwnedAnonBoxes(nsTArray<OwnedAnonBox>& aResult) override;
82
83
#ifdef DEBUG_FRAME_DUMP
84
  virtual nsresult GetFrameName(nsAString& aResult) const override {
85
    return MakeFrameName(NS_LITERAL_STRING("ColumnSet"), aResult);
86
  }
87
#endif
88
89
  nsRect CalculateColumnRuleBounds(const nsPoint& aOffset);
90
  void CreateBorderRenderers(nsTArray<nsCSSBorderRenderer>& aBorderRenderers,
91
                             gfxContext* aCtx,
92
                             const nsRect& aDirtyRect,
93
                             const nsPoint& aPt);
94
95
protected:
96
  nscoord        mLastBalanceBSize;
97
  nsReflowStatus mLastFrameStatus;
98
99
  /**
100
   * These are the parameters that control the layout of columns.
101
   */
102
  struct ReflowConfig {
103
    // The number of columns that we want to balance across. If we're not
104
    // balancing, this will be set to INT32_MAX.
105
    int32_t mBalanceColCount;
106
107
    // The inline-size of each individual column.
108
    nscoord mColISize;
109
110
    // The amount of inline-size that is expected to be left over after all the
111
    // columns and column gaps are laid out.
112
    nscoord mExpectedISizeLeftOver;
113
114
    // The width (inline-size) of each column gap.
115
    nscoord mColGap;
116
117
    // The maximum bSize of any individual column during a reflow iteration.
118
    // This parameter is set during each iteration of the binary search for
119
    // the best column block-size.
120
    nscoord mColMaxBSize;
121
122
    // A boolean controlling whether or not we are balancing. This should be
123
    // equivalent to mBalanceColCount == INT32_MAX.
124
    bool mIsBalancing;
125
126
    // The last known column block-size that was 'feasible'. A column bSize is
127
    // feasible if all child content fits within the specified bSize.
128
    nscoord mKnownFeasibleBSize;
129
130
    // The last known block-size that was 'infeasible'. A column bSize is
131
    // infeasible if not all child content fits within the specified bSize.
132
    nscoord mKnownInfeasibleBSize;
133
134
    // block-size of the column set frame
135
    nscoord mComputedBSize;
136
137
    // The block-size "consumed" by previous-in-flows.
138
    // The computed block-size should be equal to the block-size of the element
139
    // (i.e. the computed block-size itself) plus the consumed block-size.
140
    nscoord mConsumedBSize;
141
  };
142
143
  /**
144
   * Some data that is better calculated during reflow
145
   */
146
  struct ColumnBalanceData {
147
    // The maximum "content block-size" of any column
148
    nscoord mMaxBSize;
149
    // The sum of the "content block-size" for all columns
150
    nscoord mSumBSize;
151
    // The "content block-size" of the last column
152
    nscoord mLastBSize;
153
    // The maximum "content block-size" of all columns that overflowed
154
    // their available block-size
155
    nscoord mMaxOverflowingBSize;
156
    // This flag determines whether the last reflow of children exceeded the
157
    // computed block-size of the column set frame. If so, we set the bSize to
158
    // this maximum allowable bSize, and continue reflow without balancing.
159
    bool mHasExcessBSize;
160
161
0
    void Reset() {
162
0
      mMaxBSize = mSumBSize = mLastBSize = mMaxOverflowingBSize = 0;
163
0
      mHasExcessBSize = false;
164
0
    }
165
  };
166
167
  bool ReflowColumns(ReflowOutput& aDesiredSize,
168
                     const ReflowInput& aReflowInput,
169
                     nsReflowStatus& aReflowStatus,
170
                     ReflowConfig& aConfig,
171
                     bool aLastColumnUnbounded,
172
                     nsCollapsingMargin* aCarriedOutBEndMargin,
173
                     ColumnBalanceData& aColData);
174
175
  /**
176
   * The basic reflow strategy is to call this function repeatedly to
177
   * obtain specific parameters that determine the layout of the
178
   * columns. This function will compute those parameters from the CSS
179
   * style. This function will also be responsible for implementing
180
   * the state machine that controls column balancing.
181
   */
182
  ReflowConfig ChooseColumnStrategy(const ReflowInput& aReflowInput,
183
                                    bool aForceAuto, nscoord aFeasibleBSize,
184
                                    nscoord aInfeasibleBSize);
185
186
  /**
187
   * Perform the binary search for the best balance height for this column set.
188
   *
189
   * @param aReflowInput The input parameters for the current reflow iteration.
190
   * @param aPresContext The presentation context in which the current reflow
191
   *        iteration is occurring.
192
   * @param aConfig The ReflowConfig object associated with this column set
193
   *        frame, generated by ChooseColumnStrategy().
194
   * @param aColData A data structure used to keep track of data needed between
195
   *        successive iterations of the balancing process.
196
   * @param aDesiredSize The final output size of the column set frame (output
197
   *        of reflow procedure).
198
   * @param aOutMargin The bottom margin of the column set frame that may be
199
   *        carried out from reflow (and thus collapsed).
200
   * @param aUnboundedLastColumn A boolean value indicating that the last column
201
   *        can be of any height. Used during the first iteration of the
202
   *        balancing procedure to measure the height of all content in
203
   *        descendant frames of the column set.
204
   * @param aRunWasFeasible An input/output parameter indicating whether or not
205
   *        the last iteration of the balancing loop was a feasible height to
206
   *        fit all content from descendant frames.
207
   * @param aStatus A final reflow status of the column set frame, passed in as
208
   *        an output parameter.
209
   */
210
  void FindBestBalanceBSize(const ReflowInput& aReflowInput,
211
                            nsPresContext* aPresContext,
212
                            ReflowConfig& aConfig,
213
                            ColumnBalanceData& aColData,
214
                            ReflowOutput& aDesiredSize,
215
                            nsCollapsingMargin& aOutMargin,
216
                            bool& aUnboundedLastColumn,
217
                            bool& aRunWasFeasible,
218
                            nsReflowStatus& aStatus);
219
  /**
220
   * Reflow column children. Returns true iff the content that was reflowed
221
   * fit into the mColMaxBSize.
222
   */
223
  bool ReflowChildren(ReflowOutput& aDesiredSize,
224
                        const ReflowInput& aReflowInput,
225
                        nsReflowStatus& aStatus,
226
                        const ReflowConfig& aConfig,
227
                        bool aLastColumnUnbounded,
228
                        nsCollapsingMargin* aCarriedOutBEndMargin,
229
                        ColumnBalanceData& aColData);
230
231
  void ForEachColumnRule(const std::function<void(const nsRect& lineRect)>& aSetLineRect,
232
                         const nsPoint& aPt);
233
234
  static nscoord ClampUsedColumnWidth(const nsStyleCoord& aColumnWidth);
235
};
236
237
#endif // nsColumnSetFrame_h___