nsTableRowFrame.h 15 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443
  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 nsTableRowFrame_h__
  6. #define nsTableRowFrame_h__
  7. #include "mozilla/Attributes.h"
  8. #include "nscore.h"
  9. #include "nsContainerFrame.h"
  10. #include "nsTableRowGroupFrame.h"
  11. #include "mozilla/WritingModes.h"
  12. class nsTableCellFrame;
  13. namespace mozilla {
  14. struct TableCellReflowInput;
  15. } // namespace mozilla
  16. /**
  17. * nsTableRowFrame is the frame that maps table rows
  18. * (HTML tag TR). This class cannot be reused
  19. * outside of an nsTableRowGroupFrame. It assumes that its parent is an nsTableRowGroupFrame,
  20. * and its children are nsTableCellFrames.
  21. *
  22. * @see nsTableFrame
  23. * @see nsTableRowGroupFrame
  24. * @see nsTableCellFrame
  25. */
  26. class nsTableRowFrame : public nsContainerFrame
  27. {
  28. using TableCellReflowInput = mozilla::TableCellReflowInput;
  29. public:
  30. NS_DECL_QUERYFRAME_TARGET(nsTableRowFrame)
  31. NS_DECL_QUERYFRAME
  32. NS_DECL_FRAMEARENA_HELPERS
  33. virtual ~nsTableRowFrame();
  34. virtual void Init(nsIContent* aContent,
  35. nsContainerFrame* aParent,
  36. nsIFrame* aPrevInFlow) override;
  37. virtual void DestroyFrom(nsIFrame* aDestructRoot) override;
  38. /** @see nsIFrame::DidSetStyleContext */
  39. virtual void DidSetStyleContext(nsStyleContext* aOldStyleContext) override;
  40. virtual void AppendFrames(ChildListID aListID,
  41. nsFrameList& aFrameList) override;
  42. virtual void InsertFrames(ChildListID aListID,
  43. nsIFrame* aPrevFrame,
  44. nsFrameList& aFrameList) override;
  45. virtual void RemoveFrame(ChildListID aListID,
  46. nsIFrame* aOldFrame) override;
  47. /** instantiate a new instance of nsTableRowFrame.
  48. * @param aPresShell the pres shell for this frame
  49. *
  50. * @return the frame that was created
  51. */
  52. friend nsTableRowFrame* NS_NewTableRowFrame(nsIPresShell* aPresShell,
  53. nsStyleContext* aContext);
  54. nsTableRowGroupFrame* GetTableRowGroupFrame() const
  55. {
  56. nsIFrame* parent = GetParent();
  57. MOZ_ASSERT(parent && parent->GetType() == nsGkAtoms::tableRowGroupFrame);
  58. return static_cast<nsTableRowGroupFrame*>(parent);
  59. }
  60. nsTableFrame* GetTableFrame() const
  61. {
  62. return GetTableRowGroupFrame()->GetTableFrame();
  63. }
  64. virtual nsMargin GetUsedMargin() const override;
  65. virtual nsMargin GetUsedBorder() const override;
  66. virtual nsMargin GetUsedPadding() const override;
  67. virtual void BuildDisplayList(nsDisplayListBuilder* aBuilder,
  68. const nsDisplayListSet& aLists) override;
  69. void PaintCellBackgroundsForFrame(nsIFrame* aFrame,
  70. nsDisplayListBuilder* aBuilder,
  71. const nsDisplayListSet& aLists,
  72. const nsPoint& aOffset = nsPoint());
  73. // Implemented in nsTableCellFrame.h, because it needs to know about the
  74. // nsTableCellFrame class, but we can't include nsTableCellFrame.h here.
  75. inline nsTableCellFrame* GetFirstCell() const;
  76. /** calls Reflow for all of its child cells.
  77. * Cells with rowspan=1 are all set to the same height and stacked horizontally.
  78. * <P> Cells are not split unless absolutely necessary.
  79. * <P> Cells are resized in nsTableFrame::BalanceColumnWidths
  80. * and nsTableFrame::ShrinkWrapChildren
  81. *
  82. * @param aDesiredSize width set to width of the sum of the cells, height set to
  83. * height of cells with rowspan=1.
  84. *
  85. * @see nsIFrame::Reflow
  86. * @see nsTableFrame::BalanceColumnWidths
  87. * @see nsTableFrame::ShrinkWrapChildren
  88. */
  89. virtual void Reflow(nsPresContext* aPresContext,
  90. ReflowOutput& aDesiredSize,
  91. const ReflowInput& aReflowInput,
  92. nsReflowStatus& aStatus) override;
  93. void DidResize();
  94. /**
  95. * Get the "type" of the frame
  96. *
  97. * @see nsGkAtoms::tableRowFrame
  98. */
  99. virtual nsIAtom* GetType() const override;
  100. #ifdef DEBUG_FRAME_DUMP
  101. virtual nsresult GetFrameName(nsAString& aResult) const override;
  102. #endif
  103. virtual mozilla::WritingMode GetWritingMode() const override
  104. { return GetTableFrame()->GetWritingMode(); }
  105. void UpdateBSize(nscoord aBSize,
  106. nscoord aAscent,
  107. nscoord aDescent,
  108. nsTableFrame* aTableFrame = nullptr,
  109. nsTableCellFrame* aCellFrame = nullptr);
  110. void ResetBSize(nscoord aRowStyleBSize);
  111. // calculate the bsize, considering content bsize of the
  112. // cells and the style bsize of the row and cells, excluding pct bsizes
  113. nscoord CalcBSize(const ReflowInput& aReflowInput);
  114. // Support for cells with 'vertical-align: baseline'.
  115. /**
  116. * returns the max-ascent amongst all the cells that have
  117. * 'vertical-align: baseline', *including* cells with rowspans.
  118. * returns 0 if we don't have any cell with 'vertical-align: baseline'
  119. */
  120. nscoord GetMaxCellAscent() const;
  121. /* return the row ascent
  122. */
  123. nscoord GetRowBaseline(mozilla::WritingMode aWritingMode);
  124. /** returns the ordinal position of this row in its table */
  125. virtual int32_t GetRowIndex() const;
  126. /** set this row's starting row index */
  127. void SetRowIndex (int aRowIndex);
  128. /** used by row group frame code */
  129. nscoord ReflowCellFrame(nsPresContext* aPresContext,
  130. const ReflowInput& aReflowInput,
  131. bool aIsTopOfPage,
  132. nsTableCellFrame* aCellFrame,
  133. nscoord aAvailableBSize,
  134. nsReflowStatus& aStatus);
  135. /**
  136. * Collapse the row if required, apply col and colgroup visibility: collapse
  137. * info to the cells in the row.
  138. * @return the amount to shift bstart-wards all following rows
  139. * @param aRowOffset - shift the row bstart-wards by this amount
  140. * @param aISize - new isize of the row
  141. * @param aCollapseGroup - parent rowgroup is collapsed so this row needs
  142. * to be collapsed
  143. * @param aDidCollapse - the row has been collapsed
  144. */
  145. nscoord CollapseRowIfNecessary(nscoord aRowOffset,
  146. nscoord aISize,
  147. bool aCollapseGroup,
  148. bool& aDidCollapse);
  149. /**
  150. * Insert a cell frame after the last cell frame that has a col index
  151. * that is less than aColIndex. If no such cell frame is found the
  152. * frame to insert is prepended to the child list.
  153. * @param aFrame the cell frame to insert
  154. * @param aColIndex the col index
  155. */
  156. void InsertCellFrame(nsTableCellFrame* aFrame,
  157. int32_t aColIndex);
  158. nsresult CalculateCellActualBSize(nsTableCellFrame* aCellFrame,
  159. nscoord& aDesiredBSize,
  160. mozilla::WritingMode aWM);
  161. bool IsFirstInserted() const;
  162. void SetFirstInserted(bool aValue);
  163. nscoord GetContentBSize() const;
  164. void SetContentBSize(nscoord aTwipValue);
  165. bool HasStyleBSize() const;
  166. bool HasFixedBSize() const;
  167. void SetHasFixedBSize(bool aValue);
  168. bool HasPctBSize() const;
  169. void SetHasPctBSize(bool aValue);
  170. nscoord GetFixedBSize() const;
  171. void SetFixedBSize(nscoord aValue);
  172. float GetPctBSize() const;
  173. void SetPctBSize(float aPctValue,
  174. bool aForce = false);
  175. nscoord GetInitialBSize(nscoord aBasis = 0) const;
  176. nsTableRowFrame* GetNextRow() const;
  177. bool HasUnpaginatedBSize();
  178. void SetHasUnpaginatedBSize(bool aValue);
  179. nscoord GetUnpaginatedBSize();
  180. void SetUnpaginatedBSize(nsPresContext* aPresContext, nscoord aValue);
  181. nscoord GetBStartBCBorderWidth() const { return mBStartBorderWidth; }
  182. nscoord GetBEndBCBorderWidth() const { return mBEndBorderWidth; }
  183. void SetBStartBCBorderWidth(BCPixelSize aWidth) { mBStartBorderWidth = aWidth; }
  184. void SetBEndBCBorderWidth(BCPixelSize aWidth) { mBEndBorderWidth = aWidth; }
  185. mozilla::LogicalMargin GetBCBorderWidth(mozilla::WritingMode aWM);
  186. /**
  187. * Gets inner border widths before collapsing with cell borders
  188. * Caller must get block-end border from next row or from table
  189. * GetContinuousBCBorderWidth will not overwrite that border
  190. * see nsTablePainter about continuous borders
  191. */
  192. void GetContinuousBCBorderWidth(mozilla::WritingMode aWM,
  193. mozilla::LogicalMargin& aBorder);
  194. /**
  195. * @returns outer block-start bc border == prev row's block-end inner
  196. */
  197. nscoord GetOuterBStartContBCBorderWidth();
  198. /**
  199. * Sets full border widths before collapsing with cell borders
  200. * @param aForSide - side to set; only accepts iend, istart, and bstart
  201. */
  202. void SetContinuousBCBorderWidth(mozilla::LogicalSide aForSide,
  203. BCPixelSize aPixelValue);
  204. virtual bool IsFrameOfType(uint32_t aFlags) const override
  205. {
  206. return nsContainerFrame::IsFrameOfType(aFlags & ~(nsIFrame::eTablePart));
  207. }
  208. virtual void InvalidateFrame(uint32_t aDisplayItemKey = 0) override;
  209. virtual void InvalidateFrameWithRect(const nsRect& aRect, uint32_t aDisplayItemKey = 0) override;
  210. virtual void InvalidateFrameForRemoval() override { InvalidateFrameSubtree(); }
  211. #ifdef ACCESSIBILITY
  212. virtual mozilla::a11y::AccType AccessibleType() override;
  213. #endif
  214. protected:
  215. /** protected constructor.
  216. * @see NewFrame
  217. */
  218. explicit nsTableRowFrame(nsStyleContext *aContext);
  219. void InitChildReflowInput(nsPresContext& aPresContext,
  220. const mozilla::LogicalSize& aAvailSize,
  221. bool aBorderCollapse,
  222. TableCellReflowInput& aReflowInput);
  223. virtual LogicalSides GetLogicalSkipSides(const ReflowInput* aReflowInput = nullptr) const override;
  224. // row-specific methods
  225. nscoord ComputeCellXOffset(const ReflowInput& aState,
  226. nsIFrame* aKidFrame,
  227. const nsMargin& aKidMargin) const;
  228. /**
  229. * Called for incremental/dirty and resize reflows. If aDirtyOnly is true then
  230. * only reflow dirty cells.
  231. */
  232. void ReflowChildren(nsPresContext* aPresContext,
  233. ReflowOutput& aDesiredSize,
  234. const ReflowInput& aReflowInput,
  235. nsTableFrame& aTableFrame,
  236. nsReflowStatus& aStatus);
  237. private:
  238. struct RowBits {
  239. unsigned mRowIndex:29;
  240. unsigned mHasFixedBSize:1; // set if the dominating style bsize on the row or any cell is pixel based
  241. unsigned mHasPctBSize:1; // set if the dominating style bsize on the row or any cell is pct based
  242. unsigned mFirstInserted:1; // if true, then it was the bstart-most newly inserted row
  243. } mBits;
  244. // the desired bsize based on the content of the tallest cell in the row
  245. nscoord mContentBSize;
  246. // the bsize based on a style percentage bsize on either the row or any cell
  247. // if mHasPctBSize is set
  248. nscoord mStylePctBSize;
  249. // the bsize based on a style pixel bsize on the row or any
  250. // cell if mHasFixedBSize is set
  251. nscoord mStyleFixedBSize;
  252. // max-ascent and max-descent amongst all cells that have 'vertical-align: baseline'
  253. nscoord mMaxCellAscent; // does include cells with rowspan > 1
  254. nscoord mMaxCellDescent; // does *not* include cells with rowspan > 1
  255. // border widths in pixels in the collapsing border model of the *inner*
  256. // half of the border only
  257. BCPixelSize mBStartBorderWidth;
  258. BCPixelSize mBEndBorderWidth;
  259. BCPixelSize mIEndContBorderWidth;
  260. BCPixelSize mBStartContBorderWidth;
  261. BCPixelSize mIStartContBorderWidth;
  262. /**
  263. * Sets the NS_ROW_HAS_CELL_WITH_STYLE_BSIZE bit to indicate whether
  264. * this row has any cells that have non-auto-bsize. (Row-spanning
  265. * cells are ignored.)
  266. */
  267. void InitHasCellWithStyleBSize(nsTableFrame* aTableFrame);
  268. };
  269. inline int32_t nsTableRowFrame::GetRowIndex() const
  270. {
  271. return int32_t(mBits.mRowIndex);
  272. }
  273. inline void nsTableRowFrame::SetRowIndex (int aRowIndex)
  274. {
  275. mBits.mRowIndex = aRowIndex;
  276. }
  277. inline bool nsTableRowFrame::IsFirstInserted() const
  278. {
  279. return bool(mBits.mFirstInserted);
  280. }
  281. inline void nsTableRowFrame::SetFirstInserted(bool aValue)
  282. {
  283. mBits.mFirstInserted = aValue;
  284. }
  285. inline bool nsTableRowFrame::HasStyleBSize() const
  286. {
  287. return (bool)mBits.mHasFixedBSize || (bool)mBits.mHasPctBSize;
  288. }
  289. inline bool nsTableRowFrame::HasFixedBSize() const
  290. {
  291. return (bool)mBits.mHasFixedBSize;
  292. }
  293. inline void nsTableRowFrame::SetHasFixedBSize(bool aValue)
  294. {
  295. mBits.mHasFixedBSize = aValue;
  296. }
  297. inline bool nsTableRowFrame::HasPctBSize() const
  298. {
  299. return (bool)mBits.mHasPctBSize;
  300. }
  301. inline void nsTableRowFrame::SetHasPctBSize(bool aValue)
  302. {
  303. mBits.mHasPctBSize = aValue;
  304. }
  305. inline nscoord nsTableRowFrame::GetContentBSize() const
  306. {
  307. return mContentBSize;
  308. }
  309. inline void nsTableRowFrame::SetContentBSize(nscoord aValue)
  310. {
  311. mContentBSize = aValue;
  312. }
  313. inline nscoord nsTableRowFrame::GetFixedBSize() const
  314. {
  315. if (mBits.mHasFixedBSize) {
  316. return mStyleFixedBSize;
  317. }
  318. return 0;
  319. }
  320. inline float nsTableRowFrame::GetPctBSize() const
  321. {
  322. if (mBits.mHasPctBSize) {
  323. return (float)mStylePctBSize / 100.0f;
  324. }
  325. return 0.0f;
  326. }
  327. inline bool nsTableRowFrame::HasUnpaginatedBSize()
  328. {
  329. return HasAnyStateBits(NS_TABLE_ROW_HAS_UNPAGINATED_BSIZE);
  330. }
  331. inline void nsTableRowFrame::SetHasUnpaginatedBSize(bool aValue)
  332. {
  333. if (aValue) {
  334. AddStateBits(NS_TABLE_ROW_HAS_UNPAGINATED_BSIZE);
  335. } else {
  336. RemoveStateBits(NS_TABLE_ROW_HAS_UNPAGINATED_BSIZE);
  337. }
  338. }
  339. inline mozilla::LogicalMargin
  340. nsTableRowFrame::GetBCBorderWidth(mozilla::WritingMode aWM)
  341. {
  342. return mozilla::LogicalMargin(
  343. aWM, nsPresContext::CSSPixelsToAppUnits(mBStartBorderWidth), 0,
  344. nsPresContext::CSSPixelsToAppUnits(mBEndBorderWidth), 0);
  345. }
  346. inline void
  347. nsTableRowFrame::GetContinuousBCBorderWidth(mozilla::WritingMode aWM,
  348. mozilla::LogicalMargin& aBorder)
  349. {
  350. int32_t aPixelsToTwips = nsPresContext::AppUnitsPerCSSPixel();
  351. aBorder.IEnd(aWM) = BC_BORDER_START_HALF_COORD(aPixelsToTwips,
  352. mIStartContBorderWidth);
  353. aBorder.BStart(aWM) = BC_BORDER_END_HALF_COORD(aPixelsToTwips,
  354. mBStartContBorderWidth);
  355. aBorder.IStart(aWM) = BC_BORDER_END_HALF_COORD(aPixelsToTwips,
  356. mIEndContBorderWidth);
  357. }
  358. inline nscoord nsTableRowFrame::GetOuterBStartContBCBorderWidth()
  359. {
  360. int32_t aPixelsToTwips = nsPresContext::AppUnitsPerCSSPixel();
  361. return BC_BORDER_START_HALF_COORD(aPixelsToTwips, mBStartContBorderWidth);
  362. }
  363. #endif