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.

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

mercurial