layout/generic/nsColumnSetFrame.h

changeset 0
6474c204b198
     1.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     1.2 +++ b/layout/generic/nsColumnSetFrame.h	Wed Dec 31 06:09:35 2014 +0100
     1.3 @@ -0,0 +1,221 @@
     1.4 +/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
     1.5 +/* This Source Code Form is subject to the terms of the Mozilla Public
     1.6 + * License, v. 2.0. If a copy of the MPL was not distributed with this
     1.7 + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
     1.8 +
     1.9 +/* rendering object for css3 multi-column layout */
    1.10 +
    1.11 +#include "mozilla/Attributes.h"
    1.12 +#include "nsContainerFrame.h"
    1.13 +
    1.14 +class nsColumnSetFrame : public nsContainerFrame {
    1.15 +public:
    1.16 +  NS_DECL_FRAMEARENA_HELPERS
    1.17 +
    1.18 +  nsColumnSetFrame(nsStyleContext* aContext);
    1.19 +
    1.20 +  virtual nsresult SetInitialChildList(ChildListID     aListID,
    1.21 +                                       nsFrameList&    aChildList) MOZ_OVERRIDE;
    1.22 +
    1.23 +  virtual nsresult Reflow(nsPresContext* aPresContext,
    1.24 +                          nsHTMLReflowMetrics& aDesiredSize,
    1.25 +                          const nsHTMLReflowState& aReflowState,
    1.26 +                          nsReflowStatus& aStatus) MOZ_OVERRIDE;
    1.27 +
    1.28 +  virtual nsresult  AppendFrames(ChildListID     aListID,
    1.29 +                                 nsFrameList&    aFrameList) MOZ_OVERRIDE;
    1.30 +  virtual nsresult  InsertFrames(ChildListID     aListID,
    1.31 +                                 nsIFrame*       aPrevFrame,
    1.32 +                                 nsFrameList&    aFrameList) MOZ_OVERRIDE;
    1.33 +  virtual nsresult  RemoveFrame(ChildListID     aListID,
    1.34 +                                nsIFrame*       aOldFrame) MOZ_OVERRIDE;
    1.35 +
    1.36 +  virtual nscoord GetMinWidth(nsRenderingContext *aRenderingContext) MOZ_OVERRIDE;
    1.37 +  virtual nscoord GetPrefWidth(nsRenderingContext *aRenderingContext) MOZ_OVERRIDE;
    1.38 +
    1.39 +  /**
    1.40 +   * Retrieve the available height for content of this frame. The available content
    1.41 +   * height is the available height for the frame, minus borders and padding.
    1.42 +   */
    1.43 +  virtual nscoord GetAvailableContentHeight(const nsHTMLReflowState& aReflowState);
    1.44 +
    1.45 +  virtual nsIFrame* GetContentInsertionFrame() MOZ_OVERRIDE {
    1.46 +    nsIFrame* frame = GetFirstPrincipalChild();
    1.47 +
    1.48 +    // if no children return nullptr
    1.49 +    if (!frame)
    1.50 +      return nullptr;
    1.51 +
    1.52 +    return frame->GetContentInsertionFrame();
    1.53 +  }
    1.54 +
    1.55 +  virtual nsresult StealFrame(nsIFrame* aChild, bool aForceNormal) MOZ_OVERRIDE
    1.56 +  { // nsColumnSetFrame keeps overflow containers in main child list
    1.57 +    return nsContainerFrame::StealFrame(aChild, true);
    1.58 +  }
    1.59 +
    1.60 +  virtual bool IsFrameOfType(uint32_t aFlags) const MOZ_OVERRIDE
    1.61 +   {
    1.62 +     return nsContainerFrame::IsFrameOfType(aFlags &
    1.63 +              ~(nsIFrame::eCanContainOverflowContainers));
    1.64 +   }
    1.65 +
    1.66 +  virtual void BuildDisplayList(nsDisplayListBuilder*   aBuilder,
    1.67 +                                const nsRect&           aDirtyRect,
    1.68 +                                const nsDisplayListSet& aLists) MOZ_OVERRIDE;
    1.69 +
    1.70 +  virtual nsIAtom* GetType() const MOZ_OVERRIDE;
    1.71 +
    1.72 +  virtual void PaintColumnRule(nsRenderingContext* aCtx,
    1.73 +                               const nsRect&        aDirtyRect,
    1.74 +                               const nsPoint&       aPt);
    1.75 +
    1.76 +#ifdef DEBUG_FRAME_DUMP
    1.77 +  virtual nsresult GetFrameName(nsAString& aResult) const MOZ_OVERRIDE {
    1.78 +    return MakeFrameName(NS_LITERAL_STRING("ColumnSet"), aResult);
    1.79 +  }
    1.80 +#endif
    1.81 +
    1.82 +protected:
    1.83 +  nscoord        mLastBalanceHeight;
    1.84 +  nsReflowStatus mLastFrameStatus;
    1.85 +
    1.86 +  /**
    1.87 +   * These are the parameters that control the layout of columns.
    1.88 +   */
    1.89 +  struct ReflowConfig {
    1.90 +    // The number of columns that we want to balance across. If we're not
    1.91 +    // balancing, this will be set to INT32_MAX.
    1.92 +    int32_t mBalanceColCount;
    1.93 +
    1.94 +    // The width of each individual column.
    1.95 +    nscoord mColWidth;
    1.96 +
    1.97 +    // The amount of width that is expected to be left over after all the
    1.98 +    // columns and column gaps are laid out.
    1.99 +    nscoord mExpectedWidthLeftOver;
   1.100 +
   1.101 +    // The width of each column gap.
   1.102 +    nscoord mColGap;
   1.103 +
   1.104 +    // The maximum height of any individual column during a reflow iteration.
   1.105 +    // This parameter is set during each iteration of the binary search for
   1.106 +    // the best column height.
   1.107 +    nscoord mColMaxHeight;
   1.108 +
   1.109 +    // A boolean controlling whether or not we are balancing. This should be
   1.110 +    // equivalent to mBalanceColCount == INT32_MAX.
   1.111 +    bool mIsBalancing;
   1.112 +
   1.113 +    // The last known column height that was 'feasible'. A column height is
   1.114 +    // feasible if all child content fits within the specified height.
   1.115 +    nscoord mKnownFeasibleHeight;
   1.116 +
   1.117 +    // The last known height that was 'infeasible'. A column height is
   1.118 +    // infeasible if not all child content fits within the specified height.
   1.119 +    nscoord mKnownInfeasibleHeight;
   1.120 +
   1.121 +    // Height of the column set frame
   1.122 +    nscoord mComputedHeight;
   1.123 +
   1.124 +    // The height "consumed" by previous-in-flows.
   1.125 +    // The computed height should be equal to the height of the element (i.e.
   1.126 +    // the computed height itself) plus the consumed height.
   1.127 +    nscoord mConsumedHeight;
   1.128 +  };
   1.129 +
   1.130 +  /**
   1.131 +   * Some data that is better calculated during reflow
   1.132 +   */
   1.133 +  struct ColumnBalanceData {
   1.134 +    // The maximum "content height" of any column
   1.135 +    nscoord mMaxHeight;
   1.136 +    // The sum of the "content heights" for all columns
   1.137 +    nscoord mSumHeight;
   1.138 +    // The "content height" of the last column
   1.139 +    nscoord mLastHeight;
   1.140 +    // The maximum "content height" of all columns that overflowed
   1.141 +    // their available height
   1.142 +    nscoord mMaxOverflowingHeight;
   1.143 +    // This flag determines whether the last reflow of children exceeded the
   1.144 +    // computed height of the column set frame. If so, we set the height to
   1.145 +    // this maximum allowable height, and continue reflow without balancing.
   1.146 +    bool mHasExcessHeight;
   1.147 +
   1.148 +    void Reset() {
   1.149 +      mMaxHeight = mSumHeight = mLastHeight = mMaxOverflowingHeight = 0;
   1.150 +      mHasExcessHeight = false;
   1.151 +    }
   1.152 +  };
   1.153 +
   1.154 +  /**
   1.155 +   * Similar to nsBlockFrame::DrainOverflowLines. Locate any columns not
   1.156 +   * handled by our prev-in-flow, and any columns sitting on our own
   1.157 +   * overflow list, and put them in our primary child list for reflowing.
   1.158 +   */
   1.159 +  void DrainOverflowColumns();
   1.160 +
   1.161 +  bool ReflowColumns(nsHTMLReflowMetrics& aDesiredSize,
   1.162 +                     const nsHTMLReflowState& aReflowState,
   1.163 +                     nsReflowStatus& aReflowStatus,
   1.164 +                     ReflowConfig& aConfig,
   1.165 +                     bool aLastColumnUnbounded,
   1.166 +                     nsCollapsingMargin* aCarriedOutBottomMargin,
   1.167 +                     ColumnBalanceData& aColData);
   1.168 +
   1.169 +  /**
   1.170 +   * The basic reflow strategy is to call this function repeatedly to
   1.171 +   * obtain specific parameters that determine the layout of the
   1.172 +   * columns. This function will compute those parameters from the CSS
   1.173 +   * style. This function will also be responsible for implementing
   1.174 +   * the state machine that controls column balancing.
   1.175 +   */
   1.176 +  ReflowConfig ChooseColumnStrategy(const nsHTMLReflowState& aReflowState,
   1.177 +                                    bool aForceAuto, nscoord aFeasibleHeight,
   1.178 +                                    nscoord aInfeasibleHeight);
   1.179 +
   1.180 +  /**
   1.181 +   * Perform the binary search for the best balance height for this column set.
   1.182 +   *
   1.183 +   * @param aReflowState The input parameters for the current reflow iteration.
   1.184 +   * @param aPresContext The presentation context in which the current reflow
   1.185 +   *        iteration is occurring.
   1.186 +   * @param aConfig The ReflowConfig object associated with this column set
   1.187 +   *        frame, generated by ChooseColumnStrategy().
   1.188 +   * @param aColData A data structure used to keep track of data needed between
   1.189 +   *        successive iterations of the balancing process.
   1.190 +   * @param aDesiredSize The final output size of the column set frame (output
   1.191 +   *        of reflow procedure).
   1.192 +   * @param aOutMargin The bottom margin of the column set frame that may be
   1.193 +   *        carried out from reflow (and thus collapsed).
   1.194 +   * @param aUnboundedLastColumn A boolean value indicating that the last column
   1.195 +   *        can be of any height. Used during the first iteration of the
   1.196 +   *        balancing procedure to measure the height of all content in
   1.197 +   *        descendant frames of the column set.
   1.198 +   * @param aRunWasFeasible An input/output parameter indicating whether or not
   1.199 +   *        the last iteration of the balancing loop was a feasible height to
   1.200 +   *        fit all content from descendant frames.
   1.201 +   * @param aStatus A final reflow status of the column set frame, passed in as
   1.202 +   *        an output parameter.
   1.203 +   */
   1.204 +  void FindBestBalanceHeight(const nsHTMLReflowState& aReflowState,
   1.205 +                             nsPresContext* aPresContext,
   1.206 +                             ReflowConfig& aConfig,
   1.207 +                             ColumnBalanceData& aColData,
   1.208 +                             nsHTMLReflowMetrics& aDesiredSize,
   1.209 +                             nsCollapsingMargin& aOutMargin,
   1.210 +                             bool& aUnboundedLastColumn,
   1.211 +                             bool& aRunWasFeasible,
   1.212 +                             nsReflowStatus& aStatus);
   1.213 +  /**
   1.214 +   * Reflow column children. Returns true iff the content that was reflowed
   1.215 +   * fit into the mColMaxHeight.
   1.216 +   */
   1.217 +  bool ReflowChildren(nsHTMLReflowMetrics& aDesiredSize,
   1.218 +                        const nsHTMLReflowState& aReflowState,
   1.219 +                        nsReflowStatus& aStatus,
   1.220 +                        const ReflowConfig& aConfig,
   1.221 +                        bool aLastColumnUnbounded,
   1.222 +                        nsCollapsingMargin* aCarriedOutBottomMargin,
   1.223 +                        ColumnBalanceData& aColData);
   1.224 +};

mercurial