layout/tables/nsTableFrame.h

Fri, 16 Jan 2015 04:50:19 +0100

author
Michael Schloh von Bennewitz <michael@schloh.com>
date
Fri, 16 Jan 2015 04:50:19 +0100
branch
TOR_BUG_9701
changeset 13
44a2da4a2ab2
permissions
-rw-r--r--

Replace accessor implementation with direct member state manipulation, by
request https://trac.torproject.org/projects/tor/ticket/9701#comment:32

     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/. */
     5 #ifndef nsTableFrame_h__
     6 #define nsTableFrame_h__
     8 #include "mozilla/Attributes.h"
     9 #include "celldata.h"
    10 #include "nscore.h"
    11 #include "nsContainerFrame.h"
    12 #include "nsStyleCoord.h"
    13 #include "nsStyleConsts.h"
    14 #include "nsTableColFrame.h"
    15 #include "nsTableColGroupFrame.h"
    16 #include "nsCellMap.h"
    17 #include "nsGkAtoms.h"
    18 #include "nsDisplayList.h"
    20 class nsTableCellFrame;
    21 class nsTableCellMap;
    22 class nsTableColFrame;
    23 class nsColGroupFrame;
    24 class nsTableRowGroupFrame;
    25 class nsTableRowFrame;
    26 class nsTableColGroupFrame;
    27 class nsITableLayoutStrategy;
    28 class nsStyleContext;
    30 struct nsTableReflowState;
    31 struct nsStylePosition;
    32 struct BCPropertyData;
    34 static inline bool IS_TABLE_CELL(nsIAtom* frameType) {
    35   return nsGkAtoms::tableCellFrame == frameType ||
    36     nsGkAtoms::bcTableCellFrame == frameType;
    37 }
    39 static inline bool FrameHasBorderOrBackground(nsIFrame* f) {
    40   return (f->StyleVisibility()->IsVisible() &&
    41           (!f->StyleBackground()->IsTransparent() ||
    42            f->StyleDisplay()->mAppearance ||
    43            f->StyleBorder()->HasBorder()));
    44 }
    46 class nsDisplayTableItem : public nsDisplayItem
    47 {
    48 public:
    49   nsDisplayTableItem(nsDisplayListBuilder* aBuilder, nsIFrame* aFrame) : 
    50       nsDisplayItem(aBuilder, aFrame),
    51       mPartHasFixedBackground(false) {}
    53   virtual bool IsVaryingRelativeToMovingFrame(nsDisplayListBuilder* aBuilder,
    54                                                 nsIFrame* aFrame) MOZ_OVERRIDE;
    55   // With collapsed borders, parts of the collapsed border can extend outside
    56   // the table part frames, so allow this display element to blow out to our
    57   // overflow rect. This is also useful for row frames that have spanning
    58   // cells extending outside them.
    59   virtual nsRect GetBounds(nsDisplayListBuilder* aBuilder, bool* aSnap) MOZ_OVERRIDE;
    61   void UpdateForFrameBackground(nsIFrame* aFrame);
    63 private:
    64   bool mPartHasFixedBackground;
    65 };
    67 class nsAutoPushCurrentTableItem
    68 {
    69 public:
    70   nsAutoPushCurrentTableItem() : mBuilder(nullptr) {}
    72   void Push(nsDisplayListBuilder* aBuilder, nsDisplayTableItem* aPushItem)
    73   {
    74     mBuilder = aBuilder;
    75     mOldCurrentItem = aBuilder->GetCurrentTableItem();
    76     aBuilder->SetCurrentTableItem(aPushItem);
    77 #ifdef DEBUG
    78     mPushedItem = aPushItem;
    79 #endif
    80   }
    81   ~nsAutoPushCurrentTableItem() {
    82     if (!mBuilder)
    83       return;
    84 #ifdef DEBUG
    85     NS_ASSERTION(mBuilder->GetCurrentTableItem() == mPushedItem,
    86                  "Someone messed with the current table item behind our back!");
    87 #endif
    88     mBuilder->SetCurrentTableItem(mOldCurrentItem);
    89   }
    91 private:
    92   nsDisplayListBuilder* mBuilder;
    93   nsDisplayTableItem*   mOldCurrentItem;
    94 #ifdef DEBUG
    95   nsDisplayTableItem*   mPushedItem;
    96 #endif
    97 };
    99 /* ============================================================================ */
   101 /**
   102   * nsTableFrame maps the inner portion of a table (everything except captions.)
   103   * Used as a pseudo-frame within nsTableOuterFrame, it may also be used
   104   * stand-alone as the top-level frame.
   105   *
   106   * The principal child list contains row group frames. There is also an
   107   * additional child list, kColGroupList, which contains the col group frames.
   108   */
   109 class nsTableFrame : public nsContainerFrame
   110 {
   111 public:
   112   NS_DECL_FRAMEARENA_HELPERS
   114   static void DestroyPositionedTablePartArray(void* aPropertyValue);
   115   NS_DECLARE_FRAME_PROPERTY(PositionedTablePartArray, DestroyPositionedTablePartArray)
   117   /** nsTableOuterFrame has intimate knowledge of the inner table frame */
   118   friend class nsTableOuterFrame;
   120   /** instantiate a new instance of nsTableRowFrame.
   121     * @param aPresShell the pres shell for this frame
   122     *
   123     * @return           the frame that was created
   124     */
   125   friend nsIFrame* NS_NewTableFrame(nsIPresShell* aPresShell, nsStyleContext* aContext);
   127   /** sets defaults for table-specific style.
   128     * @see nsIFrame::Init 
   129     */
   130   virtual void Init(nsIContent*      aContent,
   131                     nsIFrame*        aParent,
   132                     nsIFrame*        aPrevInFlow) MOZ_OVERRIDE;
   134   static float GetTwipsToPixels(nsPresContext* aPresContext);
   136   // Return true if aParentReflowState.frame or any of its ancestors within
   137   // the containing table have non-auto height. (e.g. pct or fixed height)
   138   static bool AncestorsHaveStyleHeight(const nsHTMLReflowState& aParentReflowState);
   140   // See if a special height reflow will occur due to having a pct height when
   141   // the pct height basis may not yet be valid.
   142   static void CheckRequestSpecialHeightReflow(const nsHTMLReflowState& aReflowState);
   144   // Notify the frame and its ancestors (up to the containing table) that a special
   145   // height reflow will occur. 
   146   static void RequestSpecialHeightReflow(const nsHTMLReflowState& aReflowState);
   148   static void RePositionViews(nsIFrame* aFrame);
   150   static bool PageBreakAfter(nsIFrame* aSourceFrame,
   151                                nsIFrame* aNextFrame);
   153   // Register a positioned table part with its nsTableFrame. These objects will
   154   // be visited by FixupPositionedTableParts after reflow is complete. (See that
   155   // function for more explanation.) Should be called during frame construction.
   156   static void RegisterPositionedTablePart(nsIFrame* aFrame);
   158   // Unregister a positioned table part with its nsTableFrame.
   159   static void UnregisterPositionedTablePart(nsIFrame* aFrame,
   160                                             nsIFrame* aDestructRoot);
   162   nsPoint GetFirstSectionOrigin(const nsHTMLReflowState& aReflowState) const;
   163   /*
   164    * Notification that aAttribute has changed for content inside a table (cell, row, etc)
   165    */
   166   void AttributeChangedFor(nsIFrame*       aFrame,
   167                            nsIContent*     aContent, 
   168                            nsIAtom*        aAttribute); 
   170   /** @see nsIFrame::DestroyFrom */
   171   virtual void DestroyFrom(nsIFrame* aDestructRoot) MOZ_OVERRIDE;
   173   /** @see nsIFrame::DidSetStyleContext */
   174   virtual void DidSetStyleContext(nsStyleContext* aOldStyleContext) MOZ_OVERRIDE;
   176   virtual nsresult AppendFrames(ChildListID     aListID,
   177                                 nsFrameList&    aFrameList) MOZ_OVERRIDE;
   178   virtual nsresult InsertFrames(ChildListID     aListID,
   179                                 nsIFrame*       aPrevFrame,
   180                                 nsFrameList&    aFrameList) MOZ_OVERRIDE;
   181   virtual nsresult RemoveFrame(ChildListID     aListID,
   182                                nsIFrame*       aOldFrame) MOZ_OVERRIDE;
   184   virtual nsMargin GetUsedBorder() const MOZ_OVERRIDE;
   185   virtual nsMargin GetUsedPadding() const MOZ_OVERRIDE;
   186   virtual nsMargin GetUsedMargin() const MOZ_OVERRIDE;
   188   // Get the offset from the border box to the area where the row groups fit
   189   nsMargin GetChildAreaOffset(const nsHTMLReflowState* aReflowState) const;
   191   /** helper method to find the table parent of any table frame object */
   192   static nsTableFrame* GetTableFrame(nsIFrame* aSourceFrame);
   194   /* Like GetTableFrame, but will return nullptr if we don't pass through
   195    * aMustPassThrough on the way to the table.
   196    */
   197   static nsTableFrame* GetTableFramePassingThrough(nsIFrame* aMustPassThrough,
   198                                                    nsIFrame* aSourceFrame);
   200   typedef void (* DisplayGenericTablePartTraversal)
   201       (nsDisplayListBuilder* aBuilder, nsFrame* aFrame,
   202        const nsRect& aDirtyRect, const nsDisplayListSet& aLists);
   203   static void GenericTraversal(nsDisplayListBuilder* aBuilder, nsFrame* aFrame,
   204                                const nsRect& aDirtyRect, const nsDisplayListSet& aLists);
   206   /**
   207    * Helper method to handle display common to table frames, rowgroup frames
   208    * and row frames. It creates a background display item for handling events
   209    * if necessary, an outline display item if necessary, and displays
   210    * all the the frame's children.
   211    * @param aDisplayItem the display item created for this part, or null
   212    * if this part's border/background painting is delegated to an ancestor
   213    * @param aTraversal a function that gets called to traverse the table
   214    * part's child frames and add their display list items to a
   215    * display list set.
   216    */
   217   static void DisplayGenericTablePart(nsDisplayListBuilder* aBuilder,
   218                                       nsFrame* aFrame,
   219                                       const nsRect& aDirtyRect,
   220                                       const nsDisplayListSet& aLists,
   221                                       nsDisplayTableItem* aDisplayItem,
   222                                       DisplayGenericTablePartTraversal aTraversal = GenericTraversal);
   224   // Return the closest sibling of aPriorChildFrame (including aPriroChildFrame)
   225   // of type aChildType.
   226   static nsIFrame* GetFrameAtOrBefore(nsIFrame*       aParentFrame,
   227                                       nsIFrame*       aPriorChildFrame,
   228                                       nsIAtom*        aChildType);
   229   bool IsAutoHeight();
   231   /** @return true if aDisplayType represents a rowgroup of any sort
   232     * (header, footer, or body)
   233     */
   234   bool IsRowGroup(int32_t aDisplayType) const;
   236   /** Initialize the table frame with a set of children.
   237     * @see nsIFrame::SetInitialChildList 
   238     */
   239   virtual nsresult SetInitialChildList(ChildListID     aListID,
   240                                        nsFrameList&    aChildList) MOZ_OVERRIDE;
   242   virtual const nsFrameList& GetChildList(ChildListID aListID) const MOZ_OVERRIDE;
   243   virtual void GetChildLists(nsTArray<ChildList>* aLists) const MOZ_OVERRIDE;
   245   virtual void BuildDisplayList(nsDisplayListBuilder*   aBuilder,
   246                                 const nsRect&           aDirtyRect,
   247                                 const nsDisplayListSet& aLists) MOZ_OVERRIDE;
   249   /**
   250    * Paint the background of the table and its parts (column groups,
   251    * columns, row groups, rows, and cells), and the table border, and all
   252    * internal borders if border-collapse is on.
   253    */
   254   void PaintTableBorderBackground(nsRenderingContext& aRenderingContext,
   255                                   const nsRect& aDirtyRect,
   256                                   nsPoint aPt, uint32_t aBGPaintFlags);
   258   /**
   259    * Determines if any table part has a background image that is currently not
   260    * decoded. Does not look into cell contents (ie only table parts).
   261    */
   262   static bool AnyTablePartHasUndecodedBackgroundImage(nsIFrame* aStart,
   263                                                       nsIFrame* aEnd);
   265   /** Get the outer half (i.e., the part outside the height and width of
   266    *  the table) of the largest segment (?) of border-collapsed border on
   267    *  the table on each side, or 0 for non border-collapsed tables.
   268    */
   269   nsMargin GetOuterBCBorder() const;
   271   /** Same as above, but only if it's included from the border-box width
   272    *  of the table.
   273    */
   274   nsMargin GetIncludedOuterBCBorder() const;
   276   /** Same as above, but only if it's excluded from the border-box width
   277    *  of the table.  This is the area that leaks out into the margin
   278    *  (or potentially past it, if there is no margin).
   279    */
   280   nsMargin GetExcludedOuterBCBorder() const;
   282   /**
   283    * In quirks mode, the size of the table background is reduced
   284    * by the outer BC border. Compute the reduction needed.
   285    */
   286   nsMargin GetDeflationForBackground(nsPresContext* aPresContext) const;
   288   /** Get width of table + colgroup + col collapse: elements that
   289    *  continue along the length of the whole left side.
   290    *  see nsTablePainter about continuous borders
   291    */
   292   nscoord GetContinuousLeftBCBorderWidth() const;
   293   void SetContinuousLeftBCBorderWidth(nscoord aValue);
   295   friend class nsDelayedCalcBCBorders;
   297   void AddBCDamageArea(const nsIntRect& aValue);
   298   bool BCRecalcNeeded(nsStyleContext* aOldStyleContext,
   299                         nsStyleContext* aNewStyleContext);
   300   void PaintBCBorders(nsRenderingContext& aRenderingContext,
   301                       const nsRect&        aDirtyRect);
   303   virtual void MarkIntrinsicWidthsDirty() MOZ_OVERRIDE;
   304   // For border-collapse tables, the caller must not add padding and
   305   // border to the results of these functions.
   306   virtual nscoord GetMinWidth(nsRenderingContext *aRenderingContext) MOZ_OVERRIDE;
   307   virtual nscoord GetPrefWidth(nsRenderingContext *aRenderingContext) MOZ_OVERRIDE;
   308   virtual IntrinsicWidthOffsetData
   309     IntrinsicWidthOffsets(nsRenderingContext* aRenderingContext) MOZ_OVERRIDE;
   311   virtual nsSize ComputeSize(nsRenderingContext *aRenderingContext,
   312                              nsSize aCBSize, nscoord aAvailableWidth,
   313                              nsSize aMargin, nsSize aBorder, nsSize aPadding,
   314                              uint32_t aFlags) MOZ_OVERRIDE;
   315   virtual nsSize ComputeAutoSize(nsRenderingContext *aRenderingContext,
   316                                  nsSize aCBSize, nscoord aAvailableWidth,
   317                                  nsSize aMargin, nsSize aBorder,
   318                                  nsSize aPadding, bool aShrinkWrap) MOZ_OVERRIDE;
   319   /**
   320    * A copy of nsFrame::ShrinkWidthToFit that calls a different
   321    * GetPrefWidth, since tables have two different ones.
   322    */
   323   nscoord TableShrinkWidthToFit(nsRenderingContext *aRenderingContext,
   324                                 nscoord aWidthInCB);
   326   // XXXldb REWRITE THIS COMMENT!
   327   /** inner tables are reflowed in two steps.
   328     * <pre>
   329     * if mFirstPassValid is false, this is our first time through since content was last changed
   330     *   set pass to 1
   331     *   do pass 1
   332     *     get min/max info for all cells in an infinite space
   333     *   do column balancing
   334     *   set mFirstPassValid to true
   335     *   do pass 2
   336     *     use column widths to Reflow cells
   337     * </pre>
   338     *
   339     * @see nsIFrame::Reflow
   340     */
   341   virtual nsresult Reflow(nsPresContext*          aPresContext,
   342                           nsHTMLReflowMetrics&     aDesiredSize,
   343                           const nsHTMLReflowState& aReflowState,
   344                           nsReflowStatus&          aStatus) MOZ_OVERRIDE;
   346   nsresult ReflowTable(nsHTMLReflowMetrics&     aDesiredSize,
   347                        const nsHTMLReflowState& aReflowState,
   348                        nscoord                  aAvailHeight,
   349                        nsIFrame*&               aLastChildReflowed,
   350                        nsReflowStatus&          aStatus);
   352   nsFrameList& GetColGroups();
   354   virtual nsIFrame* GetParentStyleContextFrame() const MOZ_OVERRIDE;
   356   /**
   357    * Get the "type" of the frame
   358    *
   359    * @see nsGkAtoms::tableFrame
   360    */
   361   virtual nsIAtom* GetType() const MOZ_OVERRIDE;
   363   virtual bool IsFrameOfType(uint32_t aFlags) const MOZ_OVERRIDE
   364   {
   365     if (aFlags & eSupportsCSSTransforms) {
   366       return false;
   367     }
   368     return nsContainerFrame::IsFrameOfType(aFlags);
   369   }
   371 #ifdef DEBUG_FRAME_DUMP
   372   /** @see nsIFrame::GetFrameName */
   373   virtual nsresult GetFrameName(nsAString& aResult) const MOZ_OVERRIDE;
   374 #endif
   376   /** return the width of the column at aColIndex    */
   377   int32_t GetColumnWidth(int32_t aColIndex);
   379   /** helper to get the cell spacing X style value */
   380   nscoord GetCellSpacingX();
   382   /** helper to get the cell spacing Y style value */
   383   nscoord GetCellSpacingY();
   385   virtual nscoord GetBaseline() const MOZ_OVERRIDE;
   386   /** return the row span of a cell, taking into account row span magic at the bottom
   387     * of a table. The row span equals the number of rows spanned by aCell starting at
   388     * aStartRowIndex, and can be smaller if aStartRowIndex is greater than the row
   389     * index in which aCell originates.
   390     *
   391     * @param aStartRowIndex the cell
   392     * @param aCell          the cell
   393     *
   394     * @return  the row span, correcting for row spans that extend beyond the bottom
   395     *          of the table.
   396     */
   397   int32_t  GetEffectiveRowSpan(int32_t                 aStartRowIndex,
   398                                const nsTableCellFrame& aCell) const;
   399   int32_t  GetEffectiveRowSpan(const nsTableCellFrame& aCell,
   400                                nsCellMap*              aCellMap = nullptr);
   402   /** return the col span of a cell, taking into account col span magic at the edge
   403     * of a table.
   404     *
   405     * @param aCell      the cell
   406     *
   407     * @return  the col span, correcting for col spans that extend beyond the edge
   408     *          of the table.
   409     */
   410   int32_t  GetEffectiveColSpan(const nsTableCellFrame& aCell,
   411                                nsCellMap*              aCellMap = nullptr) const;
   413   /** indicate whether the row has more than one cell that either originates
   414     * or is spanned from the rows above
   415     */
   416   bool HasMoreThanOneCell(int32_t aRowIndex) const;
   418   /** return the column frame associated with aColIndex
   419     * returns nullptr if the col frame has not yet been allocated, or if
   420     * aColIndex is out of range
   421     */
   422   nsTableColFrame* GetColFrame(int32_t aColIndex) const;
   424   /** Insert a col frame reference into the colframe cache and adapt the cellmap
   425     * @param aColFrame    - the column frame
   426     * @param aColIndex    - index where the column should be inserted into the
   427     *                       colframe cache
   428     */
   429   void InsertCol(nsTableColFrame& aColFrame,
   430                  int32_t          aColIndex);
   432   nsTableColGroupFrame* CreateAnonymousColGroupFrame(nsTableColGroupType aType);
   434   int32_t DestroyAnonymousColFrames(int32_t aNumFrames);
   436   // Append aNumColsToAdd anonymous col frames of type eColAnonymousCell to our
   437   // last eColGroupAnonymousCell colgroup.  If we have no such colgroup, then
   438   // create one.
   439   void AppendAnonymousColFrames(int32_t aNumColsToAdd);
   441   // Append aNumColsToAdd anonymous col frames of type aColType to
   442   // aColGroupFrame.  If aAddToTable is true, also call AddColsToTable on the
   443   // new cols.
   444   void AppendAnonymousColFrames(nsTableColGroupFrame* aColGroupFrame,
   445                                 int32_t               aNumColsToAdd,
   446                                 nsTableColType        aColType,
   447                                 bool                  aAddToTable);
   449   void MatchCellMapToColCache(nsTableCellMap* aCellMap);
   450   /** empty the column frame cache */
   451   void ClearColCache();
   453   void DidResizeColumns();
   455   void AppendCell(nsTableCellFrame& aCellFrame,
   456                   int32_t           aRowIndex);
   458   void InsertCells(nsTArray<nsTableCellFrame*>& aCellFrames,
   459                    int32_t                      aRowIndex,
   460                    int32_t                      aColIndexBefore);
   462   void RemoveCell(nsTableCellFrame* aCellFrame,
   463                   int32_t           aRowIndex);
   465   void AppendRows(nsTableRowGroupFrame*       aRowGroupFrame,
   466                   int32_t                     aRowIndex,
   467                   nsTArray<nsTableRowFrame*>& aRowFrames);
   469   int32_t InsertRows(nsTableRowGroupFrame*       aRowGroupFrame,
   470                      nsTArray<nsTableRowFrame*>& aFrames,
   471                      int32_t                     aRowIndex,
   472                      bool                        aConsiderSpans);
   474   void RemoveRows(nsTableRowFrame& aFirstRowFrame,
   475                   int32_t          aNumRowsToRemove,
   476                   bool             aConsiderSpans);
   478   /** Insert multiple rowgroups into the table cellmap handling
   479     * @param aRowGroups - iterator that iterates over the rowgroups to insert
   480     */
   481   void InsertRowGroups(const nsFrameList::Slice& aRowGroups);
   483   void InsertColGroups(int32_t                   aStartColIndex,
   484                        const nsFrameList::Slice& aColgroups);
   486   void RemoveCol(nsTableColGroupFrame* aColGroupFrame,
   487                  int32_t               aColIndex,
   488                  bool                  aRemoveFromCache,
   489                  bool                  aRemoveFromCellMap);
   491   bool ColumnHasCellSpacingBefore(int32_t aColIndex) const;
   493   bool HasPctCol() const;
   494   void SetHasPctCol(bool aValue);
   496   bool HasCellSpanningPctCol() const;
   497   void SetHasCellSpanningPctCol(bool aValue);
   499   /**
   500    * To be called on a frame by its parent after setting its size/position and
   501    * calling DidReflow (possibly via FinishReflowChild()).  This can also be
   502    * used for child frames which are not being reflowed but did have their size
   503    * or position changed.
   504    *
   505    * @param aFrame The frame to invalidate
   506    * @param aOrigRect The original rect of aFrame (before the change).
   507    * @param aOrigVisualOverflow The original overflow rect of aFrame.
   508    * @param aIsFirstReflow True if the size/position change is due to the
   509    *                       first reflow of aFrame.
   510    */
   511   static void InvalidateTableFrame(nsIFrame* aFrame,
   512                                    const nsRect& aOrigRect,
   513                                    const nsRect& aOrigVisualOverflow,
   514                                    bool aIsFirstReflow);
   516   virtual bool UpdateOverflow() MOZ_OVERRIDE;
   518 protected:
   520   /** protected constructor. 
   521     * @see NewFrame
   522     */
   523   nsTableFrame(nsStyleContext* aContext);
   525   /** destructor, responsible for mColumnLayoutData */
   526   virtual ~nsTableFrame();
   528   void InitChildReflowState(nsHTMLReflowState& aReflowState);
   530   virtual int GetLogicalSkipSides(const nsHTMLReflowState* aReflowState = nullptr) const MOZ_OVERRIDE;
   532 public:
   533   bool IsRowInserted() const;
   534   void   SetRowInserted(bool aValue);
   536 protected:
   538   // A helper function to reflow a header or footer with unconstrained height
   539   // to see if it should be made repeatable and also to determine its desired
   540   // height.
   541   nsresult SetupHeaderFooterChild(const nsTableReflowState& aReflowState,
   542                                   nsTableRowGroupFrame* aFrame,
   543                                   nscoord* aDesiredHeight);
   545   nsresult ReflowChildren(nsTableReflowState&  aReflowState,
   546                           nsReflowStatus&      aStatus,
   547                           nsIFrame*&           aLastChildReflowed,
   548                           nsOverflowAreas&     aOverflowAreas);
   550   // This calls the col group and column reflow methods, which do two things:
   551   //  (1) set all the dimensions to 0
   552   //  (2) notify the table about colgroups or columns with hidden visibility
   553   void ReflowColGroups(nsRenderingContext* aRenderingContext);
   555   /** return the width of the table taking into account visibility collapse
   556     * on columns and colgroups
   557     * @param aBorderPadding  the border and padding of the table
   558     */
   559   nscoord GetCollapsedWidth(nsMargin aBorderPadding);
   562   /** Adjust the table for visibility.collapse set on rowgroups, rows,
   563     * colgroups and cols
   564     * @param aDesiredSize    the metrics of the table
   565     * @param aBorderPadding  the border and padding of the table
   566     */
   567   void AdjustForCollapsingRowsCols(nsHTMLReflowMetrics& aDesiredSize,
   568                                    nsMargin             aBorderPadding);
   570   /** FixupPositionedTableParts is called at the end of table reflow to reflow
   571    *  the absolutely positioned descendants of positioned table parts. This is
   572    *  necessary because the dimensions of table parts may change after they've
   573    *  been reflowed (e.g. in AdjustForCollapsingRowsCols).
   574    */
   575   void FixupPositionedTableParts(nsPresContext*           aPresContext,
   576                                  nsHTMLReflowMetrics&     aDesiredSize,
   577                                  const nsHTMLReflowState& aReflowState);
   579   // Clears the list of positioned table parts.
   580   void ClearAllPositionedTableParts();
   582   nsITableLayoutStrategy* LayoutStrategy() const {
   583     return static_cast<nsTableFrame*>(FirstInFlow())->
   584       mTableLayoutStrategy;
   585   }
   587   // Helper for InsertFrames.
   588   void HomogenousInsertFrames(ChildListID     aListID,
   589                               nsIFrame*       aPrevFrame,
   590                               nsFrameList&    aFrameList);
   591 private:
   592   /* Handle a row that got inserted during reflow.  aNewHeight is the
   593      new height of the table after reflow. */
   594   void ProcessRowInserted(nscoord aNewHeight);
   596   // WIDTH AND HEIGHT CALCULATION
   598 public:
   600   // calculate the computed height of aFrame including its border and padding given 
   601   // its reflow state.
   602   nscoord CalcBorderBoxHeight(const nsHTMLReflowState& aReflowState);
   604 protected:
   606   // update the  desired height of this table taking into account the current
   607   // reflow state, the table attributes and the content driven rowgroup heights
   608   // this function can change the overflow area
   609   void CalcDesiredHeight(const nsHTMLReflowState& aReflowState, nsHTMLReflowMetrics& aDesiredSize);
   611   // The following is a helper for CalcDesiredHeight 
   613   void DistributeHeightToRows(const nsHTMLReflowState& aReflowState,
   614                               nscoord                  aAmount);
   616   void PlaceChild(nsTableReflowState&  aReflowState,
   617                   nsIFrame*            aKidFrame,
   618                   nsHTMLReflowMetrics& aKidDesiredSize,
   619                   const nsRect&        aOriginalKidRect,
   620                   const nsRect&        aOriginalKidVisualOverflow);
   621    void PlaceRepeatedFooter(nsTableReflowState& aReflowState,
   622                             nsTableRowGroupFrame *aTfoot,
   623                             nscoord aFooterHeight);
   625   nsIFrame* GetFirstBodyRowGroupFrame();
   626 public:
   627   typedef nsAutoTArray<nsTableRowGroupFrame*, 8> RowGroupArray;
   628   /**
   629    * Push all our child frames from the aRowGroups array, in order, starting
   630    * from the frame at aPushFrom to the end of the array. The frames are put on
   631    * our overflow list or moved directly to our next-in-flow if one exists.
   632    */
   633 protected:
   634   void PushChildren(const RowGroupArray& aRowGroups, int32_t aPushFrom);
   636 public:
   637   // put the children frames in the display order (e.g. thead before tbodies
   638   // before tfoot). This will handle calling GetRowGroupFrame() on the
   639   // children, and not append nulls, so the array is guaranteed to contain
   640   // nsTableRowGroupFrames.  If there are multiple theads or tfoots, all but
   641   // the first one are treated as tbodies instead.
   643   void OrderRowGroups(RowGroupArray& aChildren,
   644                       nsTableRowGroupFrame** aHead = nullptr,
   645                       nsTableRowGroupFrame** aFoot = nullptr) const;
   647   // Return the thead, if any
   648   nsTableRowGroupFrame* GetTHead() const;
   650   // Return the tfoot, if any
   651   nsTableRowGroupFrame* GetTFoot() const;
   653   // Returns true if there are any cells above the row at
   654   // aRowIndex and spanning into the row at aRowIndex, the number of
   655   // effective columns limits the search up to that column
   656   bool RowIsSpannedInto(int32_t aRowIndex, int32_t aNumEffCols);
   658   // Returns true if there is a cell originating in aRowIndex
   659   // which spans into the next row,  the number of effective
   660   // columns limits the search up to that column
   661   bool RowHasSpanningCells(int32_t aRowIndex, int32_t aNumEffCols);
   663 protected:
   665   bool HaveReflowedColGroups() const;
   666   void   SetHaveReflowedColGroups(bool aValue);
   668 public:
   669   bool IsBorderCollapse() const;
   671   bool NeedToCalcBCBorders() const;
   672   void SetNeedToCalcBCBorders(bool aValue);
   674   bool NeedToCollapse() const;
   675   void SetNeedToCollapse(bool aValue);
   677   bool HasZeroColSpans() const;
   678   void SetHasZeroColSpans(bool aValue);
   680   bool NeedColSpanExpansion() const;
   681   void SetNeedColSpanExpansion(bool aValue);
   683   /** The GeometryDirty bit is similar to the NS_FRAME_IS_DIRTY frame
   684     * state bit, which implies that all descendants are dirty.  The
   685     * GeometryDirty still implies that all the parts of the table are
   686     * dirty, but resizing optimizations should still apply to the
   687     * contents of the individual cells.
   688     */
   689   void SetGeometryDirty() { mBits.mGeometryDirty = true; }
   690   void ClearGeometryDirty() { mBits.mGeometryDirty = false; }
   691   bool IsGeometryDirty() const { return mBits.mGeometryDirty; }
   693   /** Get the cell map for this table frame.  It is not always mCellMap.
   694     * Only the firstInFlow has a legit cell map
   695     */
   696   nsTableCellMap* GetCellMap() const;
   698   /** Iterate over the row groups and adjust the row indices of all rows 
   699     * whose index is >= aRowIndex.  
   700     * @param aRowIndex   - start adjusting with this index
   701     * @param aAdjustment - shift the row index by this amount
   702     */
   703   void AdjustRowIndices(int32_t aRowIndex,
   704                         int32_t aAdjustment);
   706   /** Reset the rowindices of all rows as they might have changed due to 
   707     * rowgroup reordering, exclude new row group frames that show in the
   708     * reordering but are not yet inserted into the cellmap
   709     * @param aRowGroupsToExclude - an iterator that will produce the row groups
   710     *                              to exclude.
   711     */
   712   void ResetRowIndices(const nsFrameList::Slice& aRowGroupsToExclude);
   714   nsTArray<nsTableColFrame*>& GetColCache();
   717 protected:
   719   void SetBorderCollapse(bool aValue);
   721   BCPropertyData* GetBCProperty(bool aCreateIfNecessary = false) const;
   722   void SetFullBCDamageArea();
   723   void CalcBCBorders();
   725   void ExpandBCDamageArea(nsIntRect& aRect) const;
   727   void SetColumnDimensions(nscoord         aHeight,
   728                            const nsMargin& aReflowState);
   730   int32_t CollectRows(nsIFrame*                   aFrame,
   731                       nsTArray<nsTableRowFrame*>& aCollection);
   733 public: /* ----- Cell Map public methods ----- */
   735   int32_t GetStartRowIndex(nsTableRowGroupFrame* aRowGroupFrame);
   737   /** returns the number of rows in this table.
   738     */
   739   int32_t GetRowCount () const
   740   {
   741     return GetCellMap()->GetRowCount();
   742   }
   744   /** returns the number of columns in this table after redundant columns have been removed 
   745     */
   746   int32_t GetEffectiveColCount() const;
   748   /* return the col count including dead cols */
   749   int32_t GetColCount () const
   750   {
   751     return GetCellMap()->GetColCount();
   752   }
   754   // return the last col index which isn't of type eColAnonymousCell
   755   int32_t GetIndexOfLastRealCol();
   757   /** returns true if table-layout:auto  */
   758   bool IsAutoLayout();
   760 public:
   762 #ifdef DEBUG
   763   void Dump(bool            aDumpRows,
   764             bool            aDumpCols, 
   765             bool            aDumpCellMap);
   766 #endif
   768 protected:
   769   /**
   770    * Helper method for RemoveFrame.
   771    */
   772   void DoRemoveFrame(ChildListID aListID, nsIFrame* aOldFrame);
   773 #ifdef DEBUG
   774   void DumpRowGroup(nsIFrame* aChildFrame);
   775 #endif
   776   // DATA MEMBERS
   777   nsAutoTArray<nsTableColFrame*, 8> mColFrames;
   779   struct TableBits {
   780     uint32_t mHaveReflowedColGroups:1; // have the col groups gotten their initial reflow
   781     uint32_t mHasPctCol:1;             // does any cell or col have a pct width
   782     uint32_t mCellSpansPctCol:1;       // does any cell span a col with a pct width (or containing a cell with a pct width)
   783     uint32_t mIsBorderCollapse:1;      // border collapsing model vs. separate model
   784     uint32_t mRowInserted:1;
   785     uint32_t mNeedToCalcBCBorders:1;
   786     uint32_t mGeometryDirty:1;
   787     uint32_t mLeftContBCBorder:8;
   788     uint32_t mNeedToCollapse:1;    // rows, cols that have visibility:collapse need to be collapsed
   789     uint32_t mHasZeroColSpans:1;
   790     uint32_t mNeedColSpanExpansion:1;
   791     uint32_t mResizedColumns:1;        // have we resized columns since last reflow?
   792   } mBits;
   794   nsTableCellMap*         mCellMap;            // maintains the relationships between rows, cols, and cells
   795   nsITableLayoutStrategy* mTableLayoutStrategy;// the layout strategy for this frame
   796   nsFrameList             mColGroups;          // the list of colgroup frames
   797 };
   800 inline bool nsTableFrame::IsRowGroup(int32_t aDisplayType) const
   801 {
   802   return bool((NS_STYLE_DISPLAY_TABLE_HEADER_GROUP == aDisplayType) ||
   803                 (NS_STYLE_DISPLAY_TABLE_FOOTER_GROUP == aDisplayType) ||
   804                 (NS_STYLE_DISPLAY_TABLE_ROW_GROUP    == aDisplayType));
   805 }
   807 inline void nsTableFrame::SetHaveReflowedColGroups(bool aValue)
   808 {
   809   mBits.mHaveReflowedColGroups = aValue;
   810 }
   812 inline bool nsTableFrame::HaveReflowedColGroups() const
   813 {
   814   return (bool)mBits.mHaveReflowedColGroups;
   815 }
   817 inline bool nsTableFrame::HasPctCol() const
   818 {
   819   return (bool)mBits.mHasPctCol;
   820 }
   822 inline void nsTableFrame::SetHasPctCol(bool aValue)
   823 {
   824   mBits.mHasPctCol = (unsigned)aValue;
   825 }
   827 inline bool nsTableFrame::HasCellSpanningPctCol() const
   828 {
   829   return (bool)mBits.mCellSpansPctCol;
   830 }
   832 inline void nsTableFrame::SetHasCellSpanningPctCol(bool aValue)
   833 {
   834   mBits.mCellSpansPctCol = (unsigned)aValue;
   835 }
   837 inline bool nsTableFrame::IsRowInserted() const
   838 {
   839   return (bool)mBits.mRowInserted;
   840 }
   842 inline void nsTableFrame::SetRowInserted(bool aValue)
   843 {
   844   mBits.mRowInserted = (unsigned)aValue;
   845 }
   847 inline void nsTableFrame::SetNeedToCollapse(bool aValue)
   848 {
   849   static_cast<nsTableFrame*>(FirstInFlow())->mBits.mNeedToCollapse = (unsigned)aValue;
   850 }
   852 inline bool nsTableFrame::NeedToCollapse() const
   853 {
   854   return (bool) static_cast<nsTableFrame*>(FirstInFlow())->mBits.mNeedToCollapse;
   855 }
   857 inline void nsTableFrame::SetHasZeroColSpans(bool aValue)
   858 {
   859   mBits.mHasZeroColSpans = (unsigned)aValue;
   860 }
   862 inline bool nsTableFrame::HasZeroColSpans() const
   863 {
   864   return (bool)mBits.mHasZeroColSpans;
   865 }
   867 inline void nsTableFrame::SetNeedColSpanExpansion(bool aValue)
   868 {
   869   mBits.mNeedColSpanExpansion = (unsigned)aValue;
   870 }
   872 inline bool nsTableFrame::NeedColSpanExpansion() const
   873 {
   874   return (bool)mBits.mNeedColSpanExpansion;
   875 }
   878 inline nsFrameList& nsTableFrame::GetColGroups()
   879 {
   880   return static_cast<nsTableFrame*>(FirstInFlow())->mColGroups;
   881 }
   883 inline nsTArray<nsTableColFrame*>& nsTableFrame::GetColCache()
   884 {
   885   return mColFrames;
   886 }
   888 inline bool nsTableFrame::IsBorderCollapse() const
   889 {
   890   return (bool)mBits.mIsBorderCollapse;
   891 }
   893 inline void nsTableFrame::SetBorderCollapse(bool aValue) 
   894 {
   895   mBits.mIsBorderCollapse = aValue;
   896 }
   898 inline bool nsTableFrame::NeedToCalcBCBorders() const
   899 {
   900   return (bool)mBits.mNeedToCalcBCBorders;
   901 }
   903 inline void nsTableFrame::SetNeedToCalcBCBorders(bool aValue)
   904 {
   905   mBits.mNeedToCalcBCBorders = (unsigned)aValue;
   906 }
   908 inline nscoord
   909 nsTableFrame::GetContinuousLeftBCBorderWidth() const
   910 {
   911   int32_t aPixelsToTwips = nsPresContext::AppUnitsPerCSSPixel();
   912   return BC_BORDER_RIGHT_HALF_COORD(aPixelsToTwips, mBits.mLeftContBCBorder);
   913 }
   915 inline void nsTableFrame::SetContinuousLeftBCBorderWidth(nscoord aValue)
   916 {
   917   mBits.mLeftContBCBorder = (unsigned) aValue;
   918 }
   920 class nsTableIterator
   921 {
   922 public:
   923   nsTableIterator(nsIFrame& aSource);
   924   nsTableIterator(nsFrameList& aSource);
   925   nsIFrame* First();
   926   nsIFrame* Next();
   927   bool      IsLeftToRight();
   928   int32_t   Count();
   930 protected:
   931   void Init(nsIFrame* aFirstChild);
   932   bool      mLeftToRight;
   933   nsIFrame* mFirstListChild;
   934   nsIFrame* mFirstChild;
   935   nsIFrame* mCurrentChild;
   936   int32_t   mCount;
   937 };
   939 #define ABORT0() \
   940 {NS_ASSERTION(false, "CellIterator program error"); \
   941 return;}
   943 #define ABORT1(aReturn) \
   944 {NS_ASSERTION(false, "CellIterator program error"); \
   945 return aReturn;} 
   947 #endif

mercurial