tor-browser

The Tor Browser
git clone https://git.dasho.dev/tor-browser.git
Log | Files | Refs | README | LICENSE

nsColumnSetFrame.h (8175B)


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