layout/tables/nsCellMap.h

changeset 0
6474c204b198
     1.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     1.2 +++ b/layout/tables/nsCellMap.h	Wed Dec 31 06:09:35 2014 +0100
     1.3 @@ -0,0 +1,692 @@
     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 +#ifndef nsCellMap_h__
     1.9 +#define nsCellMap_h__
    1.10 +
    1.11 +#include "nscore.h"
    1.12 +#include "celldata.h"
    1.13 +#include "nsTArray.h"
    1.14 +#include "nsTArray.h"
    1.15 +#include "nsCOMPtr.h"
    1.16 +#include "nsAlgorithm.h"
    1.17 +#include "nsAutoPtr.h"
    1.18 +#include <algorithm>
    1.19 +
    1.20 +#undef DEBUG_TABLE_CELLMAP
    1.21 +
    1.22 +class nsTableColFrame;
    1.23 +class nsTableCellFrame;
    1.24 +class nsTableRowFrame;
    1.25 +class nsTableRowGroupFrame;
    1.26 +class nsTableFrame;
    1.27 +class nsCellMap;
    1.28 +class nsPresContext;
    1.29 +class nsCellMapColumnIterator;
    1.30 +struct nsIntRect;
    1.31 +
    1.32 +struct nsColInfo
    1.33 +{
    1.34 +  int32_t mNumCellsOrig; // number of cells originating in the col
    1.35 +  int32_t mNumCellsSpan; // number of cells spanning into the col via colspans (not rowspans)
    1.36 +
    1.37 +  nsColInfo();
    1.38 +  nsColInfo(int32_t aNumCellsOrig,
    1.39 +            int32_t aNumCellsSpan);
    1.40 +};
    1.41 +
    1.42 +enum Corner
    1.43 +{
    1.44 +  eTopLeft     = 0,
    1.45 +  eTopRight    = 1,
    1.46 +  eBottomRight = 2,
    1.47 +  eBottomLeft  = 3
    1.48 +};
    1.49 +
    1.50 +struct BCInfo
    1.51 +{
    1.52 +  nsTArray<BCData> mRightBorders;
    1.53 +  nsTArray<BCData> mBottomBorders;
    1.54 +  BCData           mLowerRightCorner;
    1.55 +};
    1.56 +
    1.57 +class nsTableCellMap
    1.58 +{
    1.59 +public:
    1.60 +  nsTableCellMap(nsTableFrame&   aTableFrame,
    1.61 +                 bool            aBorderCollapse);
    1.62 +
    1.63 +  /** destructor
    1.64 +    * NOT VIRTUAL BECAUSE THIS CLASS SHOULD **NEVER** BE SUBCLASSED
    1.65 +    */
    1.66 +  ~nsTableCellMap();
    1.67 +
    1.68 +  void RemoveGroupCellMap(nsTableRowGroupFrame* aRowGroup);
    1.69 +
    1.70 +  void InsertGroupCellMap(nsTableRowGroupFrame*  aNewRowGroup,
    1.71 +                          nsTableRowGroupFrame*& aPrevRowGroup);
    1.72 +
    1.73 +  /**
    1.74 +   * Get the nsCellMap for the given row group.  If aStartHint is non-null,
    1.75 +   * will start looking with that cellmap and only fall back to starting at the
    1.76 +   * beginning of the list if that doesn't find us the right nsCellMap.
    1.77 +   * Otherwise, just start at the beginning.
    1.78 +   *
    1.79 +   * aRowGroup must not be null.
    1.80 +   */
    1.81 +  nsCellMap* GetMapFor(const nsTableRowGroupFrame* aRowGroup,
    1.82 +                       nsCellMap* aStartHint) const;
    1.83 +
    1.84 +  /** synchronize the cellmaps with the rowgroups again **/
    1.85 +  void Synchronize(nsTableFrame* aTableFrame);
    1.86 +
    1.87 +  nsTableCellFrame* GetCellFrame(int32_t   aRowIndex,
    1.88 +                                 int32_t   aColIndex,
    1.89 +                                 CellData& aData,
    1.90 +                                 bool      aUseRowIfOverlap) const;
    1.91 +
    1.92 +  /** return the CellData for the cell at (aRowIndex, aColIndex) */
    1.93 +  CellData* GetDataAt(int32_t aRowIndex,
    1.94 +                      int32_t aColIndex) const;
    1.95 +
    1.96 +  // this function creates a col if needed
    1.97 +  nsColInfo* GetColInfoAt(int32_t aColIndex);
    1.98 +
    1.99 +  /** append the cellFrame at the end of the row at aRowIndex and return the col index
   1.100 +    */
   1.101 +  CellData* AppendCell(nsTableCellFrame&     aCellFrame,
   1.102 +                       int32_t               aRowIndex,
   1.103 +                       bool                  aRebuildIfNecessary,
   1.104 +                       nsIntRect&            aDamageArea);
   1.105 +
   1.106 +  void InsertCells(nsTArray<nsTableCellFrame*>& aCellFrames,
   1.107 +                   int32_t                      aRowIndex,
   1.108 +                   int32_t                      aColIndexBefore,
   1.109 +                   nsIntRect&                   aDamageArea);
   1.110 +
   1.111 +  void RemoveCell(nsTableCellFrame* aCellFrame,
   1.112 +                  int32_t           aRowIndex,
   1.113 +                  nsIntRect&        aDamageArea);
   1.114 +  /** Remove the previously gathered column information */
   1.115 +  void ClearCols();
   1.116 +  void InsertRows(nsTableRowGroupFrame*       aRowGroup,
   1.117 +                  nsTArray<nsTableRowFrame*>& aRows,
   1.118 +                  int32_t                     aFirstRowIndex,
   1.119 +                  bool                        aConsiderSpans,
   1.120 +                  nsIntRect&                  aDamageArea);
   1.121 +
   1.122 +  void RemoveRows(int32_t         aFirstRowIndex,
   1.123 +                  int32_t         aNumRowsToRemove,
   1.124 +                  bool            aConsiderSpans,
   1.125 +                  nsIntRect&      aDamageArea);
   1.126 +
   1.127 +  int32_t GetNumCellsOriginatingInRow(int32_t aRowIndex) const;
   1.128 +  int32_t GetNumCellsOriginatingInCol(int32_t aColIndex) const;
   1.129 +
   1.130 +  /** indicate whether the row has more than one cell that either originates
   1.131 +    * or is spanned from the rows above
   1.132 +    */
   1.133 +  bool HasMoreThanOneCell(int32_t aRowIndex) const;
   1.134 +
   1.135 +  int32_t GetEffectiveRowSpan(int32_t aRowIndex,
   1.136 +                              int32_t aColIndex) const;
   1.137 +  int32_t GetEffectiveColSpan(int32_t aRowIndex,
   1.138 +                              int32_t aColIndex) const;
   1.139 +
   1.140 +  /** return the total number of columns in the table represented by this CellMap */
   1.141 +  int32_t GetColCount() const;
   1.142 +
   1.143 +  /** return the actual number of rows in the table represented by this CellMap */
   1.144 +  int32_t GetRowCount() const;
   1.145 +
   1.146 +  nsTableCellFrame* GetCellInfoAt(int32_t  aRowX,
   1.147 +                                  int32_t  aColX,
   1.148 +                                  bool*  aOriginates = nullptr,
   1.149 +                                  int32_t* aColSpan = nullptr) const;
   1.150 +
   1.151 +  /**
   1.152 +   * Returns the index at the given row and column coordinates.
   1.153 +   *
   1.154 +   * @see  nsITableLayout::GetIndexByRowAndColumn()
   1.155 +   *
   1.156 +   * @param aRow     [in] the row coordinate
   1.157 +   * @param aColumn  [in] the column coordinate
   1.158 +   * @returns             the index for the cell
   1.159 +   */
   1.160 +  int32_t GetIndexByRowAndColumn(int32_t aRow, int32_t aColumn) const;
   1.161 +
   1.162 +  /**
   1.163 +   * Retrieves the row and column coordinates for the given index.
   1.164 +   *
   1.165 +   * @see  nsITableLayout::GetRowAndColumnByIndex()
   1.166 +   *
   1.167 +   * @param aIndex  [in] the index for which coordinates are to be retrieved
   1.168 +   * @param aRow    [out] the row coordinate to be returned
   1.169 +   * @param aColumn [out] the column coordinate to be returned
   1.170 +   */
   1.171 +  void GetRowAndColumnByIndex(int32_t aIndex,
   1.172 +                              int32_t *aRow, int32_t *aColumn) const;
   1.173 +
   1.174 +  void AddColsAtEnd(uint32_t aNumCols);
   1.175 +  void RemoveColsAtEnd();
   1.176 +
   1.177 +  bool RowIsSpannedInto(int32_t aRowIndex, int32_t aNumEffCols) const;
   1.178 +  bool RowHasSpanningCells(int32_t aRowIndex, int32_t aNumEffCols) const;
   1.179 +  void RebuildConsideringCells(nsCellMap*                   aCellMap,
   1.180 +                               nsTArray<nsTableCellFrame*>* aCellFrames,
   1.181 +                               int32_t                      aRowIndex,
   1.182 +                               int32_t                      aColIndex,
   1.183 +                               bool                         aInsert,
   1.184 +                               nsIntRect&                   aDamageArea);
   1.185 +
   1.186 +protected:
   1.187 +  /**
   1.188 +   * Rebuild due to rows being inserted or deleted with cells spanning
   1.189 +   * into or out of the rows.  This function can only handle insertion
   1.190 +   * or deletion but NOT both.  So either aRowsToInsert must be null
   1.191 +   * or aNumRowsToRemove must be 0.
   1.192 +   *
   1.193 +   * // XXXbz are both allowed to happen?  That'd be a no-op...
   1.194 +   */
   1.195 +  void RebuildConsideringRows(nsCellMap*                  aCellMap,
   1.196 +                              int32_t                     aStartRowIndex,
   1.197 +                              nsTArray<nsTableRowFrame*>* aRowsToInsert,
   1.198 +                              int32_t                     aNumRowsToRemove,
   1.199 +                              nsIntRect&                  aDamageArea);
   1.200 +
   1.201 +public:
   1.202 +  void ExpandZeroColSpans();
   1.203 +
   1.204 +  void ResetTopStart(uint8_t    aSide,
   1.205 +                     nsCellMap& aCellMap,
   1.206 +                     uint32_t   aYPos,
   1.207 +                     uint32_t   aXPos,
   1.208 +                     bool       aIsLowerRight = false);
   1.209 +
   1.210 +  void SetBCBorderEdge(mozilla::css::Side aEdge,
   1.211 +                       nsCellMap&    aCellMap,
   1.212 +                       uint32_t      aCellMapStart,
   1.213 +                       uint32_t      aYPos,
   1.214 +                       uint32_t      aXPos,
   1.215 +                       uint32_t      aLength,
   1.216 +                       BCBorderOwner aOwner,
   1.217 +                       nscoord       aSize,
   1.218 +                       bool          aChanged);
   1.219 +
   1.220 +  void SetBCBorderCorner(::Corner    aCorner,
   1.221 +                         nsCellMap&  aCellMap,
   1.222 +                         uint32_t    aCellMapStart,
   1.223 +                         uint32_t    aYPos,
   1.224 +                         uint32_t    aXPos,
   1.225 +                         mozilla::css::Side aOwner,
   1.226 +                         nscoord     aSubSize,
   1.227 +                         bool        aBevel,
   1.228 +                         bool        aIsBottomRight = false);
   1.229 +
   1.230 +  /** dump a representation of the cell map to stdout for debugging */
   1.231 +#ifdef DEBUG
   1.232 +  void Dump(char* aString = nullptr) const;
   1.233 +#endif
   1.234 +
   1.235 +protected:
   1.236 +  BCData* GetRightMostBorder(int32_t aRowIndex);
   1.237 +  BCData* GetBottomMostBorder(int32_t aColIndex);
   1.238 +
   1.239 +  friend class nsCellMap;
   1.240 +  friend class BCMapCellIterator;
   1.241 +  friend class BCPaintBorderIterator;
   1.242 +  friend class nsCellMapColumnIterator;
   1.243 +
   1.244 +/** Insert a row group cellmap after aPrevMap, if aPrefMap is null insert it
   1.245 +  * at the beginning, the ordering of the cellmap corresponds to the ordering of
   1.246 +  * rowgroups once OrderRowGroups has been called
   1.247 +  */
   1.248 +  void InsertGroupCellMap(nsCellMap* aPrevMap,
   1.249 +                          nsCellMap& aNewMap);
   1.250 +  void DeleteRightBottomBorders();
   1.251 +
   1.252 +  nsTableFrame&               mTableFrame;
   1.253 +  nsAutoTArray<nsColInfo, 8>  mCols;
   1.254 +  nsCellMap*                  mFirstMap;
   1.255 +  // border collapsing info
   1.256 +  BCInfo*                     mBCInfo;
   1.257 +};
   1.258 +
   1.259 +/** nsCellMap is a support class for nsTablePart.
   1.260 +  * It maintains an Rows x Columns grid onto which the cells of the table are mapped.
   1.261 +  * This makes processing of rowspan and colspan attributes much easier.
   1.262 +  * Each cell is represented by a CellData object.
   1.263 +  *
   1.264 +  * @see CellData
   1.265 +  * @see nsTableFrame::AddCellToMap
   1.266 +  * @see nsTableFrame::GrowCellMap
   1.267 +  * @see nsTableFrame::BuildCellIntoMap
   1.268 +  *
   1.269 +  * mRows is an array of rows.  Each row is an array of cells.  a cell
   1.270 +  * can be null.
   1.271 +  */
   1.272 +class nsCellMap
   1.273 +{
   1.274 +public:
   1.275 +  /** constructor
   1.276 +    * @param aRowGroupFrame the row group frame this is a cellmap for
   1.277 +    * @param aIsBC whether the table is doing border-collapse
   1.278 +    */
   1.279 +  nsCellMap(nsTableRowGroupFrame* aRowGroupFrame, bool aIsBC);
   1.280 +
   1.281 +  /** destructor
   1.282 +    * NOT VIRTUAL BECAUSE THIS CLASS SHOULD **NEVER** BE SUBCLASSED
   1.283 +    */
   1.284 +  ~nsCellMap();
   1.285 +
   1.286 +  static void Init();
   1.287 +  static void Shutdown();
   1.288 +
   1.289 +  nsCellMap* GetNextSibling() const;
   1.290 +  void SetNextSibling(nsCellMap* aSibling);
   1.291 +
   1.292 +  nsTableRowGroupFrame* GetRowGroup() const;
   1.293 +
   1.294 +  nsTableCellFrame* GetCellFrame(int32_t   aRowIndex,
   1.295 +                                 int32_t   aColIndex,
   1.296 +                                 CellData& aData,
   1.297 +                                 bool      aUseRowSpanIfOverlap) const;
   1.298 +
   1.299 +  /**
   1.300 +   * Returns highest cell index within the cell map.
   1.301 +   *
   1.302 +   * @param  aColCount  [in] the number of columns in the table
   1.303 +   */
   1.304 +  int32_t GetHighestIndex(int32_t aColCount);
   1.305 +
   1.306 +  /**
   1.307 +   * Returns the index of the given row and column coordinates.
   1.308 +   *
   1.309 +   * @see  nsITableLayout::GetIndexByRowAndColumn()
   1.310 +   *
   1.311 +   * @param aColCount    [in] the number of columns in the table
   1.312 +   * @param aRow         [in] the row coordinate
   1.313 +   * @param aColumn      [in] the column coordinate
   1.314 +   */
   1.315 +  int32_t GetIndexByRowAndColumn(int32_t aColCount,
   1.316 +                                 int32_t aRow, int32_t aColumn) const;
   1.317 +
   1.318 +  /**
   1.319 +   * Get the row and column coordinates at the given index.
   1.320 +   *
   1.321 +   * @see  nsITableLayout::GetRowAndColumnByIndex()
   1.322 +   *
   1.323 +   * @param aColCount  [in] the number of columns in the table
   1.324 +   * @param aIndex     [in] the index for which coordinates are to be retrieved
   1.325 +   * @param aRow       [out] the row coordinate to be returned
   1.326 +   * @param aColumn    [out] the column coordinate to be returned
   1.327 +   */
   1.328 +  void GetRowAndColumnByIndex(int32_t aColCount, int32_t aIndex,
   1.329 +                              int32_t *aRow, int32_t *aColumn) const;
   1.330 +
   1.331 +  /** append the cellFrame at an empty or dead cell or finally at the end of
   1.332 +    * the row at aRowIndex and return a pointer to the celldata entry in the
   1.333 +    * cellmap
   1.334 +    *
   1.335 +    * @param aMap               - reference to the table cell map
   1.336 +    * @param aCellFrame         - a pointer to the cellframe which will be appended
   1.337 +    *                             to the row
   1.338 +    * @param aRowIndex          - to this row the celldata entry will be added
   1.339 +    * @param aRebuildIfNecessay - if a cell spans into a row below it might be
   1.340 +    *                             necesserary to rebuild the cellmap as this rowspan
   1.341 +    *                             might overlap another cell.
   1.342 +    * @param aDamageArea        - area in cellmap coordinates which have been updated.
   1.343 +    * @param aColToBeginSearch  - if not null contains the column number where
   1.344 +    *                             the search for a empty or dead cell in the
   1.345 +    *                             row should start
   1.346 +    * @return                   - a pointer to the celldata entry inserted into
   1.347 +    *                             the cellmap
   1.348 +    */
   1.349 +  CellData* AppendCell(nsTableCellMap&   aMap,
   1.350 +                       nsTableCellFrame* aCellFrame,
   1.351 +                       int32_t           aRowIndex,
   1.352 +                       bool              aRebuildIfNecessary,
   1.353 +                       int32_t           aRgFirstRowIndex,
   1.354 +                       nsIntRect&        aDamageArea,
   1.355 +                       int32_t*          aBeginSearchAtCol = nullptr);
   1.356 +
   1.357 +  /** Function to be called when a cell is added at a location which is spanned
   1.358 +    * to by a zero colspan.  We handle this situation by collapsing the zero
   1.359 +    * colspan, since there is really no good way to deal with it (trying to
   1.360 +    * increase the number of columns to hold the new cell would just mean the
   1.361 +    * zero colspan needs to expand).
   1.362 +
   1.363 +    * @param aMap      - reference to the table cell map
   1.364 +    * @param aOrigData - zero colspanned cell that will be collapsed
   1.365 +    * @param aRowIndex - row where the first collision appears
   1.366 +    * @param aColIndex - column where the first collision appears
   1.367 +    **/
   1.368 +  void CollapseZeroColSpan(nsTableCellMap& aMap,
   1.369 +                           CellData*       aOrigData,
   1.370 +                           int32_t         aRowIndex,
   1.371 +                           int32_t         aColIndex);
   1.372 +
   1.373 +  void InsertCells(nsTableCellMap&              aMap,
   1.374 +                   nsTArray<nsTableCellFrame*>& aCellFrames,
   1.375 +                   int32_t                      aRowIndex,
   1.376 +                   int32_t                      aColIndexBefore,
   1.377 +                   int32_t                      aRgFirstRowIndex,
   1.378 +                   nsIntRect&                   aDamageArea);
   1.379 +
   1.380 +  void RemoveCell(nsTableCellMap&   aMap,
   1.381 +                  nsTableCellFrame* aCellFrame,
   1.382 +                  int32_t           aRowIndex,
   1.383 +                  int32_t           aRgFirstRowIndex,
   1.384 +                  nsIntRect&        aDamageArea);
   1.385 +
   1.386 +  void InsertRows(nsTableCellMap&             aMap,
   1.387 +                  nsTArray<nsTableRowFrame*>& aRows,
   1.388 +                  int32_t                     aFirstRowIndex,
   1.389 +                  bool                        aConsiderSpans,
   1.390 +                  int32_t                     aRgFirstRowIndex,
   1.391 +                  nsIntRect&                  aDamageArea);
   1.392 +
   1.393 +  void RemoveRows(nsTableCellMap& aMap,
   1.394 +                  int32_t         aFirstRowIndex,
   1.395 +                  int32_t         aNumRowsToRemove,
   1.396 +                  bool            aConsiderSpans,
   1.397 +                  int32_t         aRgFirstRowIndex,
   1.398 +                  nsIntRect&      aDamageArea);
   1.399 +
   1.400 +  int32_t GetNumCellsOriginatingInRow(int32_t aRowIndex) const;
   1.401 +  int32_t GetNumCellsOriginatingInCol(int32_t aColIndex) const;
   1.402 +
   1.403 +  /** return the number of rows in the table represented by this CellMap */
   1.404 +  int32_t GetRowCount(bool aConsiderDeadRowSpanRows = false) const;
   1.405 +
   1.406 +  nsTableCellFrame* GetCellInfoAt(const nsTableCellMap& aMap,
   1.407 +                                  int32_t          aRowX,
   1.408 +                                  int32_t          aColX,
   1.409 +                                  bool*          aOriginates = nullptr,
   1.410 +                                  int32_t*         aColSpan = nullptr) const;
   1.411 +
   1.412 +  bool RowIsSpannedInto(int32_t aRowIndex,
   1.413 +                          int32_t aNumEffCols) const;
   1.414 +
   1.415 +  bool RowHasSpanningCells(int32_t aRowIndex,
   1.416 +                             int32_t aNumEffCols) const;
   1.417 +
   1.418 +  void ExpandZeroColSpans(nsTableCellMap& aMap);
   1.419 +
   1.420 +  /** indicate whether the row has more than one cell that either originates
   1.421 +   * or is spanned from the rows above
   1.422 +   */
   1.423 +  bool HasMoreThanOneCell(int32_t aRowIndex) const;
   1.424 +
   1.425 +  /* Get the rowspan for a cell starting at aRowIndex and aColIndex.
   1.426 +   * If aGetEffective is true the size will not exceed the last content based
   1.427 +   * row. Cells can have a specified rowspan that extends below the last
   1.428 +   * content based row. This is legitimate considering incr. reflow where the
   1.429 +   * content rows will arive later.
   1.430 +   */
   1.431 +  int32_t GetRowSpan(int32_t aRowIndex,
   1.432 +                     int32_t aColIndex,
   1.433 +                     bool    aGetEffective) const;
   1.434 +
   1.435 +  int32_t GetEffectiveColSpan(const nsTableCellMap& aMap,
   1.436 +                              int32_t     aRowIndex,
   1.437 +                              int32_t     aColIndex,
   1.438 +                              bool&     aIsZeroColSpan) const;
   1.439 +
   1.440 +  typedef nsTArray<CellData*> CellDataArray;
   1.441 +
   1.442 +  /** dump a representation of the cell map to stdout for debugging */
   1.443 +#ifdef DEBUG
   1.444 +  void Dump(bool aIsBorderCollapse) const;
   1.445 +#endif
   1.446 +
   1.447 +protected:
   1.448 +  friend class nsTableCellMap;
   1.449 +  friend class BCMapCellIterator;
   1.450 +  friend class BCPaintBorderIterator;
   1.451 +  friend class nsTableFrame;
   1.452 +  friend class nsCellMapColumnIterator;
   1.453 +
   1.454 +  /**
   1.455 +   * Increase the number of rows in this cellmap by aNumRows.  Put the
   1.456 +   * new rows at aRowIndex.  If aRowIndex is -1, put them at the end.
   1.457 +   */
   1.458 +  bool Grow(nsTableCellMap& aMap,
   1.459 +              int32_t         aNumRows,
   1.460 +              int32_t         aRowIndex = -1);
   1.461 +
   1.462 +  void GrowRow(CellDataArray& aRow,
   1.463 +               int32_t        aNumCols);
   1.464 +
   1.465 +  /** assign aCellData to the cell at (aRow,aColumn) */
   1.466 +  void SetDataAt(nsTableCellMap& aMap,
   1.467 +                 CellData&       aCellData,
   1.468 +                 int32_t         aMapRowIndex,
   1.469 +                 int32_t         aColIndex);
   1.470 +
   1.471 +  CellData* GetDataAt(int32_t         aMapRowIndex,
   1.472 +                      int32_t         aColIndex) const;
   1.473 +
   1.474 +  int32_t GetNumCellsIn(int32_t aColIndex) const;
   1.475 +
   1.476 +  void ExpandWithRows(nsTableCellMap&             aMap,
   1.477 +                      nsTArray<nsTableRowFrame*>& aRowFrames,
   1.478 +                      int32_t                     aStartRowIndex,
   1.479 +                      int32_t                     aRgFirstRowIndex,
   1.480 +                      nsIntRect&                  aDamageArea);
   1.481 +
   1.482 +  void ExpandWithCells(nsTableCellMap&              aMap,
   1.483 +                       nsTArray<nsTableCellFrame*>& aCellFrames,
   1.484 +                       int32_t                      aRowIndex,
   1.485 +                       int32_t                      aColIndex,
   1.486 +                       int32_t                      aRowSpan,
   1.487 +                       bool                         aRowSpanIsZero,
   1.488 +                       int32_t                      aRgFirstRowIndex,
   1.489 +                       nsIntRect&                   aDamageArea);
   1.490 +
   1.491 +  void ShrinkWithoutRows(nsTableCellMap& aMap,
   1.492 +                         int32_t         aFirstRowIndex,
   1.493 +                         int32_t         aNumRowsToRemove,
   1.494 +                         int32_t         aRgFirstRowIndex,
   1.495 +                         nsIntRect&      aDamageArea);
   1.496 +
   1.497 +  void ShrinkWithoutCell(nsTableCellMap&   aMap,
   1.498 +                         nsTableCellFrame& aCellFrame,
   1.499 +                         int32_t           aRowIndex,
   1.500 +                         int32_t           aColIndex,
   1.501 +                         int32_t           aRgFirstRowIndex,
   1.502 +                         nsIntRect&        aDamageArea);
   1.503 +
   1.504 +  /**
   1.505 +   * Rebuild due to rows being inserted or deleted with cells spanning
   1.506 +   * into or out of the rows.  This function can only handle insertion
   1.507 +   * or deletion but NOT both.  So either aRowsToInsert must be null
   1.508 +   * or aNumRowsToRemove must be 0.
   1.509 +   *
   1.510 +   * // XXXbz are both allowed to happen?  That'd be a no-op...
   1.511 +   */
   1.512 +  void RebuildConsideringRows(nsTableCellMap&             aMap,
   1.513 +                              int32_t                     aStartRowIndex,
   1.514 +                              nsTArray<nsTableRowFrame*>* aRowsToInsert,
   1.515 +                              int32_t                     aNumRowsToRemove);
   1.516 +
   1.517 +  void RebuildConsideringCells(nsTableCellMap&              aMap,
   1.518 +                               int32_t                      aNumOrigCols,
   1.519 +                               nsTArray<nsTableCellFrame*>* aCellFrames,
   1.520 +                               int32_t                      aRowIndex,
   1.521 +                               int32_t                      aColIndex,
   1.522 +                               bool                         aInsert);
   1.523 +
   1.524 +  bool CellsSpanOut(nsTArray<nsTableRowFrame*>& aNewRows) const;
   1.525 +
   1.526 +  /** If a cell spans out of the area defined by aStartRowIndex, aEndRowIndex
   1.527 +    * and aStartColIndex, aEndColIndex the cellmap changes are more severe so
   1.528 +    * the corresponding routines needs to be called. This is also necessary if
   1.529 +    * cells outside spans into this region.
   1.530 +    * @aStartRowIndex       - y start index
   1.531 +    * @aEndRowIndex         - y end index
   1.532 +    * @param aStartColIndex - x start index
   1.533 +    * @param aEndColIndex   - x end index
   1.534 +    * @return               - true if a cell span crosses the border of the
   1.535 +                              region
   1.536 +    */
   1.537 +  bool CellsSpanInOrOut(int32_t aStartRowIndex,
   1.538 +                          int32_t aEndRowIndex,
   1.539 +                          int32_t aStartColIndex,
   1.540 +                          int32_t aEndColIndex) const;
   1.541 +
   1.542 +  void ExpandForZeroSpan(nsTableCellFrame* aCellFrame,
   1.543 +                         int32_t           aNumColsInTable);
   1.544 +
   1.545 +  bool CreateEmptyRow(int32_t aRowIndex,
   1.546 +                        int32_t aNumCols);
   1.547 +
   1.548 +  int32_t GetRowSpanForNewCell(nsTableCellFrame* aCellFrameToAdd,
   1.549 +                               int32_t           aRowIndex,
   1.550 +                               bool&           aIsZeroRowSpan) const;
   1.551 +
   1.552 +  int32_t GetColSpanForNewCell(nsTableCellFrame& aCellFrameToAdd,
   1.553 +                               bool&           aIsZeroColSpan) const;
   1.554 +
   1.555 +  // Destroy a CellData struct.  This will handle the case of aData
   1.556 +  // actually being a BCCellData properly.
   1.557 +  void DestroyCellData(CellData* aData);
   1.558 +  // Allocate a CellData struct.  This will handle needing to create a
   1.559 +  // BCCellData properly.
   1.560 +  // @param aOrigCell the originating cell to pass to the celldata constructor
   1.561 +  CellData* AllocCellData(nsTableCellFrame* aOrigCell);
   1.562 +
   1.563 +  /** an array containing, for each row, the CellDatas for the cells
   1.564 +    * in that row.  It can be larger than mContentRowCount due to row spans
   1.565 +    * extending beyond the table */
   1.566 +  // XXXbz once we have auto TArrays, we should probably use them here.
   1.567 +  nsTArray<CellDataArray> mRows;
   1.568 +
   1.569 +  /** the number of rows in the table (content) which is not indentical to the
   1.570 +    * number of rows in the cell map due to row spans extending beyond the end
   1.571 +    * of thetable (dead rows) or empty tr tags
   1.572 +    */
   1.573 +  int32_t mContentRowCount;
   1.574 +
   1.575 +  // the row group that corresponds to this map
   1.576 +  nsTableRowGroupFrame* mRowGroupFrame;
   1.577 +
   1.578 +  // the next row group cell map
   1.579 +  nsCellMap* mNextSibling;
   1.580 +
   1.581 +  // Whether this is a BC cellmap or not
   1.582 +  bool mIsBC;
   1.583 +
   1.584 +  // Prescontext to deallocate and allocate celldata
   1.585 +  nsRefPtr<nsPresContext> mPresContext;
   1.586 +};
   1.587 +
   1.588 +/**
   1.589 + * A class for iterating the cells in a given column.  Must be given a
   1.590 + * non-null nsTableCellMap and a column number valid for that cellmap.
   1.591 + */
   1.592 +class nsCellMapColumnIterator
   1.593 +{
   1.594 +public:
   1.595 +  nsCellMapColumnIterator(const nsTableCellMap* aMap, int32_t aCol) :
   1.596 +    mMap(aMap), mCurMap(aMap->mFirstMap), mCurMapStart(0),
   1.597 +    mCurMapRow(0), mCol(aCol), mFoundCells(0)
   1.598 +  {
   1.599 +    NS_PRECONDITION(aMap, "Must have map");
   1.600 +    NS_PRECONDITION(mCol < aMap->GetColCount(), "Invalid column");
   1.601 +    mOrigCells = aMap->GetNumCellsOriginatingInCol(mCol);
   1.602 +    if (mCurMap) {
   1.603 +      mCurMapContentRowCount = mCurMap->GetRowCount();
   1.604 +      uint32_t rowArrayLength = mCurMap->mRows.Length();
   1.605 +      mCurMapRelevantRowCount = std::min(mCurMapContentRowCount, rowArrayLength);
   1.606 +      if (mCurMapRelevantRowCount == 0 && mOrigCells > 0) {
   1.607 +        // This row group is useless; advance!
   1.608 +        AdvanceRowGroup();
   1.609 +      }
   1.610 +    }
   1.611 +#ifdef DEBUG
   1.612 +    else {
   1.613 +      NS_ASSERTION(mOrigCells == 0, "Why no rowgroups?");
   1.614 +    }
   1.615 +#endif
   1.616 +  }
   1.617 +
   1.618 +  nsTableCellFrame* GetNextFrame(int32_t* aRow, int32_t* aColSpan);
   1.619 +
   1.620 +private:
   1.621 +  void AdvanceRowGroup();
   1.622 +
   1.623 +  // Advance the row; aIncrement is considered to be a cell's rowspan,
   1.624 +  // so if 0 is passed in we'll advance to the next rowgroup.
   1.625 +  void IncrementRow(int32_t aIncrement);
   1.626 +
   1.627 +  const nsTableCellMap* mMap;
   1.628 +  const nsCellMap* mCurMap;
   1.629 +
   1.630 +  // mCurMapStart is the row in the entire nsTableCellMap where
   1.631 +  // mCurMap starts.  This is used to compute row indices to pass to
   1.632 +  // nsTableCellMap::GetDataAt, so must be a _content_ row index.
   1.633 +  uint32_t mCurMapStart;
   1.634 +
   1.635 +  // In steady-state mCurMapRow is the row in our current nsCellMap
   1.636 +  // that we'll use the next time GetNextFrame() is called.  Due to
   1.637 +  // the way we skip over rowspans, the entry in mCurMapRow and mCol
   1.638 +  // is either null, dead, originating, or a colspan.  In particular,
   1.639 +  // it cannot be a rowspan or overlap entry.
   1.640 +  uint32_t mCurMapRow;
   1.641 +  const int32_t mCol;
   1.642 +  uint32_t mOrigCells;
   1.643 +  uint32_t mFoundCells;
   1.644 +
   1.645 +  // The number of content rows in mCurMap.  This may be bigger than the number
   1.646 +  // of "relevant" rows, or it might be smaller.
   1.647 +  uint32_t mCurMapContentRowCount;
   1.648 +
   1.649 +  // The number of "relevant" rows in mCurMap.  That is, the number of rows
   1.650 +  // which might have an originating cell in them.  Once mCurMapRow reaches
   1.651 +  // mCurMapRelevantRowCount, we should move to the next map.
   1.652 +  uint32_t mCurMapRelevantRowCount;
   1.653 +};
   1.654 +
   1.655 +
   1.656 +/* ----- inline methods ----- */
   1.657 +inline int32_t nsTableCellMap::GetColCount() const
   1.658 +{
   1.659 +  return mCols.Length();
   1.660 +}
   1.661 +
   1.662 +inline nsCellMap* nsCellMap::GetNextSibling() const
   1.663 +{
   1.664 +  return mNextSibling;
   1.665 +}
   1.666 +
   1.667 +inline void nsCellMap::SetNextSibling(nsCellMap* aSibling)
   1.668 +{
   1.669 +  mNextSibling = aSibling;
   1.670 +}
   1.671 +
   1.672 +inline nsTableRowGroupFrame* nsCellMap::GetRowGroup() const
   1.673 +{
   1.674 +  return mRowGroupFrame;
   1.675 +}
   1.676 +
   1.677 +inline int32_t nsCellMap::GetRowCount(bool aConsiderDeadRowSpanRows) const
   1.678 +{
   1.679 +  int32_t rowCount = (aConsiderDeadRowSpanRows) ? mRows.Length() : mContentRowCount;
   1.680 +  return rowCount;
   1.681 +}
   1.682 +
   1.683 +// nsColInfo
   1.684 +
   1.685 +inline nsColInfo::nsColInfo()
   1.686 + :mNumCellsOrig(0), mNumCellsSpan(0)
   1.687 +{}
   1.688 +
   1.689 +inline nsColInfo::nsColInfo(int32_t aNumCellsOrig,
   1.690 +                            int32_t aNumCellsSpan)
   1.691 + :mNumCellsOrig(aNumCellsOrig), mNumCellsSpan(aNumCellsSpan)
   1.692 +{}
   1.693 +
   1.694 +
   1.695 +#endif

mercurial