layout/tables/nsCellMap.h

Tue, 06 Jan 2015 21:39:09 +0100

author
Michael Schloh von Bennewitz <michael@schloh.com>
date
Tue, 06 Jan 2015 21:39:09 +0100
branch
TOR_BUG_9701
changeset 8
97036ab72558
permissions
-rw-r--r--

Conditionally force memory storage according to privacy.thirdparty.isolate;
This solves Tor bug #9701, complying with disk avoidance documented in
https://www.torproject.org/projects/torbrowser/design/#disk-avoidance.

     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 nsCellMap_h__
     6 #define nsCellMap_h__
     8 #include "nscore.h"
     9 #include "celldata.h"
    10 #include "nsTArray.h"
    11 #include "nsTArray.h"
    12 #include "nsCOMPtr.h"
    13 #include "nsAlgorithm.h"
    14 #include "nsAutoPtr.h"
    15 #include <algorithm>
    17 #undef DEBUG_TABLE_CELLMAP
    19 class nsTableColFrame;
    20 class nsTableCellFrame;
    21 class nsTableRowFrame;
    22 class nsTableRowGroupFrame;
    23 class nsTableFrame;
    24 class nsCellMap;
    25 class nsPresContext;
    26 class nsCellMapColumnIterator;
    27 struct nsIntRect;
    29 struct nsColInfo
    30 {
    31   int32_t mNumCellsOrig; // number of cells originating in the col
    32   int32_t mNumCellsSpan; // number of cells spanning into the col via colspans (not rowspans)
    34   nsColInfo();
    35   nsColInfo(int32_t aNumCellsOrig,
    36             int32_t aNumCellsSpan);
    37 };
    39 enum Corner
    40 {
    41   eTopLeft     = 0,
    42   eTopRight    = 1,
    43   eBottomRight = 2,
    44   eBottomLeft  = 3
    45 };
    47 struct BCInfo
    48 {
    49   nsTArray<BCData> mRightBorders;
    50   nsTArray<BCData> mBottomBorders;
    51   BCData           mLowerRightCorner;
    52 };
    54 class nsTableCellMap
    55 {
    56 public:
    57   nsTableCellMap(nsTableFrame&   aTableFrame,
    58                  bool            aBorderCollapse);
    60   /** destructor
    61     * NOT VIRTUAL BECAUSE THIS CLASS SHOULD **NEVER** BE SUBCLASSED
    62     */
    63   ~nsTableCellMap();
    65   void RemoveGroupCellMap(nsTableRowGroupFrame* aRowGroup);
    67   void InsertGroupCellMap(nsTableRowGroupFrame*  aNewRowGroup,
    68                           nsTableRowGroupFrame*& aPrevRowGroup);
    70   /**
    71    * Get the nsCellMap for the given row group.  If aStartHint is non-null,
    72    * will start looking with that cellmap and only fall back to starting at the
    73    * beginning of the list if that doesn't find us the right nsCellMap.
    74    * Otherwise, just start at the beginning.
    75    *
    76    * aRowGroup must not be null.
    77    */
    78   nsCellMap* GetMapFor(const nsTableRowGroupFrame* aRowGroup,
    79                        nsCellMap* aStartHint) const;
    81   /** synchronize the cellmaps with the rowgroups again **/
    82   void Synchronize(nsTableFrame* aTableFrame);
    84   nsTableCellFrame* GetCellFrame(int32_t   aRowIndex,
    85                                  int32_t   aColIndex,
    86                                  CellData& aData,
    87                                  bool      aUseRowIfOverlap) const;
    89   /** return the CellData for the cell at (aRowIndex, aColIndex) */
    90   CellData* GetDataAt(int32_t aRowIndex,
    91                       int32_t aColIndex) const;
    93   // this function creates a col if needed
    94   nsColInfo* GetColInfoAt(int32_t aColIndex);
    96   /** append the cellFrame at the end of the row at aRowIndex and return the col index
    97     */
    98   CellData* AppendCell(nsTableCellFrame&     aCellFrame,
    99                        int32_t               aRowIndex,
   100                        bool                  aRebuildIfNecessary,
   101                        nsIntRect&            aDamageArea);
   103   void InsertCells(nsTArray<nsTableCellFrame*>& aCellFrames,
   104                    int32_t                      aRowIndex,
   105                    int32_t                      aColIndexBefore,
   106                    nsIntRect&                   aDamageArea);
   108   void RemoveCell(nsTableCellFrame* aCellFrame,
   109                   int32_t           aRowIndex,
   110                   nsIntRect&        aDamageArea);
   111   /** Remove the previously gathered column information */
   112   void ClearCols();
   113   void InsertRows(nsTableRowGroupFrame*       aRowGroup,
   114                   nsTArray<nsTableRowFrame*>& aRows,
   115                   int32_t                     aFirstRowIndex,
   116                   bool                        aConsiderSpans,
   117                   nsIntRect&                  aDamageArea);
   119   void RemoveRows(int32_t         aFirstRowIndex,
   120                   int32_t         aNumRowsToRemove,
   121                   bool            aConsiderSpans,
   122                   nsIntRect&      aDamageArea);
   124   int32_t GetNumCellsOriginatingInRow(int32_t aRowIndex) const;
   125   int32_t GetNumCellsOriginatingInCol(int32_t aColIndex) const;
   127   /** indicate whether the row has more than one cell that either originates
   128     * or is spanned from the rows above
   129     */
   130   bool HasMoreThanOneCell(int32_t aRowIndex) const;
   132   int32_t GetEffectiveRowSpan(int32_t aRowIndex,
   133                               int32_t aColIndex) const;
   134   int32_t GetEffectiveColSpan(int32_t aRowIndex,
   135                               int32_t aColIndex) const;
   137   /** return the total number of columns in the table represented by this CellMap */
   138   int32_t GetColCount() const;
   140   /** return the actual number of rows in the table represented by this CellMap */
   141   int32_t GetRowCount() const;
   143   nsTableCellFrame* GetCellInfoAt(int32_t  aRowX,
   144                                   int32_t  aColX,
   145                                   bool*  aOriginates = nullptr,
   146                                   int32_t* aColSpan = nullptr) const;
   148   /**
   149    * Returns the index at the given row and column coordinates.
   150    *
   151    * @see  nsITableLayout::GetIndexByRowAndColumn()
   152    *
   153    * @param aRow     [in] the row coordinate
   154    * @param aColumn  [in] the column coordinate
   155    * @returns             the index for the cell
   156    */
   157   int32_t GetIndexByRowAndColumn(int32_t aRow, int32_t aColumn) const;
   159   /**
   160    * Retrieves the row and column coordinates for the given index.
   161    *
   162    * @see  nsITableLayout::GetRowAndColumnByIndex()
   163    *
   164    * @param aIndex  [in] the index for which coordinates are to be retrieved
   165    * @param aRow    [out] the row coordinate to be returned
   166    * @param aColumn [out] the column coordinate to be returned
   167    */
   168   void GetRowAndColumnByIndex(int32_t aIndex,
   169                               int32_t *aRow, int32_t *aColumn) const;
   171   void AddColsAtEnd(uint32_t aNumCols);
   172   void RemoveColsAtEnd();
   174   bool RowIsSpannedInto(int32_t aRowIndex, int32_t aNumEffCols) const;
   175   bool RowHasSpanningCells(int32_t aRowIndex, int32_t aNumEffCols) const;
   176   void RebuildConsideringCells(nsCellMap*                   aCellMap,
   177                                nsTArray<nsTableCellFrame*>* aCellFrames,
   178                                int32_t                      aRowIndex,
   179                                int32_t                      aColIndex,
   180                                bool                         aInsert,
   181                                nsIntRect&                   aDamageArea);
   183 protected:
   184   /**
   185    * Rebuild due to rows being inserted or deleted with cells spanning
   186    * into or out of the rows.  This function can only handle insertion
   187    * or deletion but NOT both.  So either aRowsToInsert must be null
   188    * or aNumRowsToRemove must be 0.
   189    *
   190    * // XXXbz are both allowed to happen?  That'd be a no-op...
   191    */
   192   void RebuildConsideringRows(nsCellMap*                  aCellMap,
   193                               int32_t                     aStartRowIndex,
   194                               nsTArray<nsTableRowFrame*>* aRowsToInsert,
   195                               int32_t                     aNumRowsToRemove,
   196                               nsIntRect&                  aDamageArea);
   198 public:
   199   void ExpandZeroColSpans();
   201   void ResetTopStart(uint8_t    aSide,
   202                      nsCellMap& aCellMap,
   203                      uint32_t   aYPos,
   204                      uint32_t   aXPos,
   205                      bool       aIsLowerRight = false);
   207   void SetBCBorderEdge(mozilla::css::Side aEdge,
   208                        nsCellMap&    aCellMap,
   209                        uint32_t      aCellMapStart,
   210                        uint32_t      aYPos,
   211                        uint32_t      aXPos,
   212                        uint32_t      aLength,
   213                        BCBorderOwner aOwner,
   214                        nscoord       aSize,
   215                        bool          aChanged);
   217   void SetBCBorderCorner(::Corner    aCorner,
   218                          nsCellMap&  aCellMap,
   219                          uint32_t    aCellMapStart,
   220                          uint32_t    aYPos,
   221                          uint32_t    aXPos,
   222                          mozilla::css::Side aOwner,
   223                          nscoord     aSubSize,
   224                          bool        aBevel,
   225                          bool        aIsBottomRight = false);
   227   /** dump a representation of the cell map to stdout for debugging */
   228 #ifdef DEBUG
   229   void Dump(char* aString = nullptr) const;
   230 #endif
   232 protected:
   233   BCData* GetRightMostBorder(int32_t aRowIndex);
   234   BCData* GetBottomMostBorder(int32_t aColIndex);
   236   friend class nsCellMap;
   237   friend class BCMapCellIterator;
   238   friend class BCPaintBorderIterator;
   239   friend class nsCellMapColumnIterator;
   241 /** Insert a row group cellmap after aPrevMap, if aPrefMap is null insert it
   242   * at the beginning, the ordering of the cellmap corresponds to the ordering of
   243   * rowgroups once OrderRowGroups has been called
   244   */
   245   void InsertGroupCellMap(nsCellMap* aPrevMap,
   246                           nsCellMap& aNewMap);
   247   void DeleteRightBottomBorders();
   249   nsTableFrame&               mTableFrame;
   250   nsAutoTArray<nsColInfo, 8>  mCols;
   251   nsCellMap*                  mFirstMap;
   252   // border collapsing info
   253   BCInfo*                     mBCInfo;
   254 };
   256 /** nsCellMap is a support class for nsTablePart.
   257   * It maintains an Rows x Columns grid onto which the cells of the table are mapped.
   258   * This makes processing of rowspan and colspan attributes much easier.
   259   * Each cell is represented by a CellData object.
   260   *
   261   * @see CellData
   262   * @see nsTableFrame::AddCellToMap
   263   * @see nsTableFrame::GrowCellMap
   264   * @see nsTableFrame::BuildCellIntoMap
   265   *
   266   * mRows is an array of rows.  Each row is an array of cells.  a cell
   267   * can be null.
   268   */
   269 class nsCellMap
   270 {
   271 public:
   272   /** constructor
   273     * @param aRowGroupFrame the row group frame this is a cellmap for
   274     * @param aIsBC whether the table is doing border-collapse
   275     */
   276   nsCellMap(nsTableRowGroupFrame* aRowGroupFrame, bool aIsBC);
   278   /** destructor
   279     * NOT VIRTUAL BECAUSE THIS CLASS SHOULD **NEVER** BE SUBCLASSED
   280     */
   281   ~nsCellMap();
   283   static void Init();
   284   static void Shutdown();
   286   nsCellMap* GetNextSibling() const;
   287   void SetNextSibling(nsCellMap* aSibling);
   289   nsTableRowGroupFrame* GetRowGroup() const;
   291   nsTableCellFrame* GetCellFrame(int32_t   aRowIndex,
   292                                  int32_t   aColIndex,
   293                                  CellData& aData,
   294                                  bool      aUseRowSpanIfOverlap) const;
   296   /**
   297    * Returns highest cell index within the cell map.
   298    *
   299    * @param  aColCount  [in] the number of columns in the table
   300    */
   301   int32_t GetHighestIndex(int32_t aColCount);
   303   /**
   304    * Returns the index of the given row and column coordinates.
   305    *
   306    * @see  nsITableLayout::GetIndexByRowAndColumn()
   307    *
   308    * @param aColCount    [in] the number of columns in the table
   309    * @param aRow         [in] the row coordinate
   310    * @param aColumn      [in] the column coordinate
   311    */
   312   int32_t GetIndexByRowAndColumn(int32_t aColCount,
   313                                  int32_t aRow, int32_t aColumn) const;
   315   /**
   316    * Get the row and column coordinates at the given index.
   317    *
   318    * @see  nsITableLayout::GetRowAndColumnByIndex()
   319    *
   320    * @param aColCount  [in] the number of columns in the table
   321    * @param aIndex     [in] the index for which coordinates are to be retrieved
   322    * @param aRow       [out] the row coordinate to be returned
   323    * @param aColumn    [out] the column coordinate to be returned
   324    */
   325   void GetRowAndColumnByIndex(int32_t aColCount, int32_t aIndex,
   326                               int32_t *aRow, int32_t *aColumn) const;
   328   /** append the cellFrame at an empty or dead cell or finally at the end of
   329     * the row at aRowIndex and return a pointer to the celldata entry in the
   330     * cellmap
   331     *
   332     * @param aMap               - reference to the table cell map
   333     * @param aCellFrame         - a pointer to the cellframe which will be appended
   334     *                             to the row
   335     * @param aRowIndex          - to this row the celldata entry will be added
   336     * @param aRebuildIfNecessay - if a cell spans into a row below it might be
   337     *                             necesserary to rebuild the cellmap as this rowspan
   338     *                             might overlap another cell.
   339     * @param aDamageArea        - area in cellmap coordinates which have been updated.
   340     * @param aColToBeginSearch  - if not null contains the column number where
   341     *                             the search for a empty or dead cell in the
   342     *                             row should start
   343     * @return                   - a pointer to the celldata entry inserted into
   344     *                             the cellmap
   345     */
   346   CellData* AppendCell(nsTableCellMap&   aMap,
   347                        nsTableCellFrame* aCellFrame,
   348                        int32_t           aRowIndex,
   349                        bool              aRebuildIfNecessary,
   350                        int32_t           aRgFirstRowIndex,
   351                        nsIntRect&        aDamageArea,
   352                        int32_t*          aBeginSearchAtCol = nullptr);
   354   /** Function to be called when a cell is added at a location which is spanned
   355     * to by a zero colspan.  We handle this situation by collapsing the zero
   356     * colspan, since there is really no good way to deal with it (trying to
   357     * increase the number of columns to hold the new cell would just mean the
   358     * zero colspan needs to expand).
   360     * @param aMap      - reference to the table cell map
   361     * @param aOrigData - zero colspanned cell that will be collapsed
   362     * @param aRowIndex - row where the first collision appears
   363     * @param aColIndex - column where the first collision appears
   364     **/
   365   void CollapseZeroColSpan(nsTableCellMap& aMap,
   366                            CellData*       aOrigData,
   367                            int32_t         aRowIndex,
   368                            int32_t         aColIndex);
   370   void InsertCells(nsTableCellMap&              aMap,
   371                    nsTArray<nsTableCellFrame*>& aCellFrames,
   372                    int32_t                      aRowIndex,
   373                    int32_t                      aColIndexBefore,
   374                    int32_t                      aRgFirstRowIndex,
   375                    nsIntRect&                   aDamageArea);
   377   void RemoveCell(nsTableCellMap&   aMap,
   378                   nsTableCellFrame* aCellFrame,
   379                   int32_t           aRowIndex,
   380                   int32_t           aRgFirstRowIndex,
   381                   nsIntRect&        aDamageArea);
   383   void InsertRows(nsTableCellMap&             aMap,
   384                   nsTArray<nsTableRowFrame*>& aRows,
   385                   int32_t                     aFirstRowIndex,
   386                   bool                        aConsiderSpans,
   387                   int32_t                     aRgFirstRowIndex,
   388                   nsIntRect&                  aDamageArea);
   390   void RemoveRows(nsTableCellMap& aMap,
   391                   int32_t         aFirstRowIndex,
   392                   int32_t         aNumRowsToRemove,
   393                   bool            aConsiderSpans,
   394                   int32_t         aRgFirstRowIndex,
   395                   nsIntRect&      aDamageArea);
   397   int32_t GetNumCellsOriginatingInRow(int32_t aRowIndex) const;
   398   int32_t GetNumCellsOriginatingInCol(int32_t aColIndex) const;
   400   /** return the number of rows in the table represented by this CellMap */
   401   int32_t GetRowCount(bool aConsiderDeadRowSpanRows = false) const;
   403   nsTableCellFrame* GetCellInfoAt(const nsTableCellMap& aMap,
   404                                   int32_t          aRowX,
   405                                   int32_t          aColX,
   406                                   bool*          aOriginates = nullptr,
   407                                   int32_t*         aColSpan = nullptr) const;
   409   bool RowIsSpannedInto(int32_t aRowIndex,
   410                           int32_t aNumEffCols) const;
   412   bool RowHasSpanningCells(int32_t aRowIndex,
   413                              int32_t aNumEffCols) const;
   415   void ExpandZeroColSpans(nsTableCellMap& aMap);
   417   /** indicate whether the row has more than one cell that either originates
   418    * or is spanned from the rows above
   419    */
   420   bool HasMoreThanOneCell(int32_t aRowIndex) const;
   422   /* Get the rowspan for a cell starting at aRowIndex and aColIndex.
   423    * If aGetEffective is true the size will not exceed the last content based
   424    * row. Cells can have a specified rowspan that extends below the last
   425    * content based row. This is legitimate considering incr. reflow where the
   426    * content rows will arive later.
   427    */
   428   int32_t GetRowSpan(int32_t aRowIndex,
   429                      int32_t aColIndex,
   430                      bool    aGetEffective) const;
   432   int32_t GetEffectiveColSpan(const nsTableCellMap& aMap,
   433                               int32_t     aRowIndex,
   434                               int32_t     aColIndex,
   435                               bool&     aIsZeroColSpan) const;
   437   typedef nsTArray<CellData*> CellDataArray;
   439   /** dump a representation of the cell map to stdout for debugging */
   440 #ifdef DEBUG
   441   void Dump(bool aIsBorderCollapse) const;
   442 #endif
   444 protected:
   445   friend class nsTableCellMap;
   446   friend class BCMapCellIterator;
   447   friend class BCPaintBorderIterator;
   448   friend class nsTableFrame;
   449   friend class nsCellMapColumnIterator;
   451   /**
   452    * Increase the number of rows in this cellmap by aNumRows.  Put the
   453    * new rows at aRowIndex.  If aRowIndex is -1, put them at the end.
   454    */
   455   bool Grow(nsTableCellMap& aMap,
   456               int32_t         aNumRows,
   457               int32_t         aRowIndex = -1);
   459   void GrowRow(CellDataArray& aRow,
   460                int32_t        aNumCols);
   462   /** assign aCellData to the cell at (aRow,aColumn) */
   463   void SetDataAt(nsTableCellMap& aMap,
   464                  CellData&       aCellData,
   465                  int32_t         aMapRowIndex,
   466                  int32_t         aColIndex);
   468   CellData* GetDataAt(int32_t         aMapRowIndex,
   469                       int32_t         aColIndex) const;
   471   int32_t GetNumCellsIn(int32_t aColIndex) const;
   473   void ExpandWithRows(nsTableCellMap&             aMap,
   474                       nsTArray<nsTableRowFrame*>& aRowFrames,
   475                       int32_t                     aStartRowIndex,
   476                       int32_t                     aRgFirstRowIndex,
   477                       nsIntRect&                  aDamageArea);
   479   void ExpandWithCells(nsTableCellMap&              aMap,
   480                        nsTArray<nsTableCellFrame*>& aCellFrames,
   481                        int32_t                      aRowIndex,
   482                        int32_t                      aColIndex,
   483                        int32_t                      aRowSpan,
   484                        bool                         aRowSpanIsZero,
   485                        int32_t                      aRgFirstRowIndex,
   486                        nsIntRect&                   aDamageArea);
   488   void ShrinkWithoutRows(nsTableCellMap& aMap,
   489                          int32_t         aFirstRowIndex,
   490                          int32_t         aNumRowsToRemove,
   491                          int32_t         aRgFirstRowIndex,
   492                          nsIntRect&      aDamageArea);
   494   void ShrinkWithoutCell(nsTableCellMap&   aMap,
   495                          nsTableCellFrame& aCellFrame,
   496                          int32_t           aRowIndex,
   497                          int32_t           aColIndex,
   498                          int32_t           aRgFirstRowIndex,
   499                          nsIntRect&        aDamageArea);
   501   /**
   502    * Rebuild due to rows being inserted or deleted with cells spanning
   503    * into or out of the rows.  This function can only handle insertion
   504    * or deletion but NOT both.  So either aRowsToInsert must be null
   505    * or aNumRowsToRemove must be 0.
   506    *
   507    * // XXXbz are both allowed to happen?  That'd be a no-op...
   508    */
   509   void RebuildConsideringRows(nsTableCellMap&             aMap,
   510                               int32_t                     aStartRowIndex,
   511                               nsTArray<nsTableRowFrame*>* aRowsToInsert,
   512                               int32_t                     aNumRowsToRemove);
   514   void RebuildConsideringCells(nsTableCellMap&              aMap,
   515                                int32_t                      aNumOrigCols,
   516                                nsTArray<nsTableCellFrame*>* aCellFrames,
   517                                int32_t                      aRowIndex,
   518                                int32_t                      aColIndex,
   519                                bool                         aInsert);
   521   bool CellsSpanOut(nsTArray<nsTableRowFrame*>& aNewRows) const;
   523   /** If a cell spans out of the area defined by aStartRowIndex, aEndRowIndex
   524     * and aStartColIndex, aEndColIndex the cellmap changes are more severe so
   525     * the corresponding routines needs to be called. This is also necessary if
   526     * cells outside spans into this region.
   527     * @aStartRowIndex       - y start index
   528     * @aEndRowIndex         - y end index
   529     * @param aStartColIndex - x start index
   530     * @param aEndColIndex   - x end index
   531     * @return               - true if a cell span crosses the border of the
   532                               region
   533     */
   534   bool CellsSpanInOrOut(int32_t aStartRowIndex,
   535                           int32_t aEndRowIndex,
   536                           int32_t aStartColIndex,
   537                           int32_t aEndColIndex) const;
   539   void ExpandForZeroSpan(nsTableCellFrame* aCellFrame,
   540                          int32_t           aNumColsInTable);
   542   bool CreateEmptyRow(int32_t aRowIndex,
   543                         int32_t aNumCols);
   545   int32_t GetRowSpanForNewCell(nsTableCellFrame* aCellFrameToAdd,
   546                                int32_t           aRowIndex,
   547                                bool&           aIsZeroRowSpan) const;
   549   int32_t GetColSpanForNewCell(nsTableCellFrame& aCellFrameToAdd,
   550                                bool&           aIsZeroColSpan) const;
   552   // Destroy a CellData struct.  This will handle the case of aData
   553   // actually being a BCCellData properly.
   554   void DestroyCellData(CellData* aData);
   555   // Allocate a CellData struct.  This will handle needing to create a
   556   // BCCellData properly.
   557   // @param aOrigCell the originating cell to pass to the celldata constructor
   558   CellData* AllocCellData(nsTableCellFrame* aOrigCell);
   560   /** an array containing, for each row, the CellDatas for the cells
   561     * in that row.  It can be larger than mContentRowCount due to row spans
   562     * extending beyond the table */
   563   // XXXbz once we have auto TArrays, we should probably use them here.
   564   nsTArray<CellDataArray> mRows;
   566   /** the number of rows in the table (content) which is not indentical to the
   567     * number of rows in the cell map due to row spans extending beyond the end
   568     * of thetable (dead rows) or empty tr tags
   569     */
   570   int32_t mContentRowCount;
   572   // the row group that corresponds to this map
   573   nsTableRowGroupFrame* mRowGroupFrame;
   575   // the next row group cell map
   576   nsCellMap* mNextSibling;
   578   // Whether this is a BC cellmap or not
   579   bool mIsBC;
   581   // Prescontext to deallocate and allocate celldata
   582   nsRefPtr<nsPresContext> mPresContext;
   583 };
   585 /**
   586  * A class for iterating the cells in a given column.  Must be given a
   587  * non-null nsTableCellMap and a column number valid for that cellmap.
   588  */
   589 class nsCellMapColumnIterator
   590 {
   591 public:
   592   nsCellMapColumnIterator(const nsTableCellMap* aMap, int32_t aCol) :
   593     mMap(aMap), mCurMap(aMap->mFirstMap), mCurMapStart(0),
   594     mCurMapRow(0), mCol(aCol), mFoundCells(0)
   595   {
   596     NS_PRECONDITION(aMap, "Must have map");
   597     NS_PRECONDITION(mCol < aMap->GetColCount(), "Invalid column");
   598     mOrigCells = aMap->GetNumCellsOriginatingInCol(mCol);
   599     if (mCurMap) {
   600       mCurMapContentRowCount = mCurMap->GetRowCount();
   601       uint32_t rowArrayLength = mCurMap->mRows.Length();
   602       mCurMapRelevantRowCount = std::min(mCurMapContentRowCount, rowArrayLength);
   603       if (mCurMapRelevantRowCount == 0 && mOrigCells > 0) {
   604         // This row group is useless; advance!
   605         AdvanceRowGroup();
   606       }
   607     }
   608 #ifdef DEBUG
   609     else {
   610       NS_ASSERTION(mOrigCells == 0, "Why no rowgroups?");
   611     }
   612 #endif
   613   }
   615   nsTableCellFrame* GetNextFrame(int32_t* aRow, int32_t* aColSpan);
   617 private:
   618   void AdvanceRowGroup();
   620   // Advance the row; aIncrement is considered to be a cell's rowspan,
   621   // so if 0 is passed in we'll advance to the next rowgroup.
   622   void IncrementRow(int32_t aIncrement);
   624   const nsTableCellMap* mMap;
   625   const nsCellMap* mCurMap;
   627   // mCurMapStart is the row in the entire nsTableCellMap where
   628   // mCurMap starts.  This is used to compute row indices to pass to
   629   // nsTableCellMap::GetDataAt, so must be a _content_ row index.
   630   uint32_t mCurMapStart;
   632   // In steady-state mCurMapRow is the row in our current nsCellMap
   633   // that we'll use the next time GetNextFrame() is called.  Due to
   634   // the way we skip over rowspans, the entry in mCurMapRow and mCol
   635   // is either null, dead, originating, or a colspan.  In particular,
   636   // it cannot be a rowspan or overlap entry.
   637   uint32_t mCurMapRow;
   638   const int32_t mCol;
   639   uint32_t mOrigCells;
   640   uint32_t mFoundCells;
   642   // The number of content rows in mCurMap.  This may be bigger than the number
   643   // of "relevant" rows, or it might be smaller.
   644   uint32_t mCurMapContentRowCount;
   646   // The number of "relevant" rows in mCurMap.  That is, the number of rows
   647   // which might have an originating cell in them.  Once mCurMapRow reaches
   648   // mCurMapRelevantRowCount, we should move to the next map.
   649   uint32_t mCurMapRelevantRowCount;
   650 };
   653 /* ----- inline methods ----- */
   654 inline int32_t nsTableCellMap::GetColCount() const
   655 {
   656   return mCols.Length();
   657 }
   659 inline nsCellMap* nsCellMap::GetNextSibling() const
   660 {
   661   return mNextSibling;
   662 }
   664 inline void nsCellMap::SetNextSibling(nsCellMap* aSibling)
   665 {
   666   mNextSibling = aSibling;
   667 }
   669 inline nsTableRowGroupFrame* nsCellMap::GetRowGroup() const
   670 {
   671   return mRowGroupFrame;
   672 }
   674 inline int32_t nsCellMap::GetRowCount(bool aConsiderDeadRowSpanRows) const
   675 {
   676   int32_t rowCount = (aConsiderDeadRowSpanRows) ? mRows.Length() : mContentRowCount;
   677   return rowCount;
   678 }
   680 // nsColInfo
   682 inline nsColInfo::nsColInfo()
   683  :mNumCellsOrig(0), mNumCellsSpan(0)
   684 {}
   686 inline nsColInfo::nsColInfo(int32_t aNumCellsOrig,
   687                             int32_t aNumCellsSpan)
   688  :mNumCellsOrig(aNumCellsOrig), mNumCellsSpan(aNumCellsSpan)
   689 {}
   692 #endif

mercurial