nsCellMap.h 25 KB

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