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__
8 #include "mozilla/Attributes.h"
10 #include "nsContainerFrame.h"
11 #include "nsTableRowGroupFrame.h"
12 #include "mozilla/WritingModes.h"
14 class nsTableCellFrame
;
17 struct TableCellReflowInput
;
18 } // namespace mozilla
21 * nsTableRowFrame is the frame that maps table rows
22 * (HTML tag TR). This class cannot be reused
23 * outside of an nsTableRowGroupFrame. It assumes that its parent is an
24 * nsTableRowGroupFrame, and its children are nsTableCellFrames.
27 * @see nsTableRowGroupFrame
28 * @see nsTableCellFrame
30 class nsTableRowFrame
: public nsContainerFrame
{
31 using TableCellReflowInput
= mozilla::TableCellReflowInput
;
35 NS_DECL_FRAMEARENA_HELPERS(nsTableRowFrame
)
37 virtual ~nsTableRowFrame();
39 virtual void Init(nsIContent
* aContent
, nsContainerFrame
* aParent
,
40 nsIFrame
* aPrevInFlow
) override
;
42 virtual void DestroyFrom(nsIFrame
* aDestructRoot
,
43 PostDestroyData
& aPostDestroyData
) override
;
45 /** @see nsIFrame::DidSetComputedStyle */
46 virtual void DidSetComputedStyle(ComputedStyle
* aOldComputedStyle
) override
;
48 virtual void AppendFrames(ChildListID aListID
,
49 nsFrameList
& aFrameList
) override
;
50 virtual void InsertFrames(ChildListID aListID
, nsIFrame
* aPrevFrame
,
51 const nsLineList::iterator
* aPrevFrameLine
,
52 nsFrameList
& aFrameList
) override
;
53 virtual void RemoveFrame(ChildListID aListID
, nsIFrame
* aOldFrame
) override
;
55 /** instantiate a new instance of nsTableRowFrame.
56 * @param aPresShell the pres shell for this frame
58 * @return the frame that was created
60 friend nsTableRowFrame
* NS_NewTableRowFrame(mozilla::PresShell
* aPresShell
,
61 ComputedStyle
* aStyle
);
63 nsTableRowGroupFrame
* GetTableRowGroupFrame() const {
64 nsIFrame
* parent
= GetParent();
65 MOZ_ASSERT(parent
&& parent
->IsTableRowGroupFrame());
66 return static_cast<nsTableRowGroupFrame
*>(parent
);
69 nsTableFrame
* GetTableFrame() const {
70 return GetTableRowGroupFrame()->GetTableFrame();
73 virtual nsMargin
GetUsedMargin() const override
;
74 virtual nsMargin
GetUsedBorder() const override
;
75 virtual nsMargin
GetUsedPadding() const override
;
77 virtual void BuildDisplayList(nsDisplayListBuilder
* aBuilder
,
78 const nsDisplayListSet
& aLists
) override
;
80 void PaintCellBackgroundsForFrame(nsIFrame
* aFrame
,
81 nsDisplayListBuilder
* aBuilder
,
82 const nsDisplayListSet
& aLists
,
83 const nsPoint
& aOffset
= nsPoint());
85 // Implemented in nsTableCellFrame.h, because it needs to know about the
86 // nsTableCellFrame class, but we can't include nsTableCellFrame.h here.
87 inline nsTableCellFrame
* GetFirstCell() const;
89 /** calls Reflow for all of its child cells.
91 * Cells with rowspan=1 are all set to the same height and stacked
94 * Cells are not split unless absolutely necessary.
96 * Cells are resized in nsTableFrame::BalanceColumnWidths and
97 * nsTableFrame::ShrinkWrapChildren
99 * @param aDesiredSize width set to width of the sum of the cells,
100 * height set to height of cells with rowspan=1.
102 * @see nsIFrame::Reflow
103 * @see nsTableFrame::BalanceColumnWidths
104 * @see nsTableFrame::ShrinkWrapChildren
106 virtual void Reflow(nsPresContext
* aPresContext
, ReflowOutput
& aDesiredSize
,
107 const ReflowInput
& aReflowInput
,
108 nsReflowStatus
& aStatus
) override
;
112 #ifdef DEBUG_FRAME_DUMP
113 virtual nsresult
GetFrameName(nsAString
& aResult
) const override
;
116 void UpdateBSize(nscoord aBSize
, nscoord aAscent
, nscoord aDescent
,
117 nsTableFrame
* aTableFrame
= nullptr,
118 nsTableCellFrame
* aCellFrame
= nullptr);
120 void ResetBSize(nscoord aRowStyleBSize
);
122 // calculate the bsize, considering content bsize of the
123 // cells and the style bsize of the row and cells, excluding pct bsizes
124 nscoord
CalcBSize(const ReflowInput
& aReflowInput
);
126 // Support for cells with 'vertical-align: baseline'.
129 * returns the max-ascent amongst all the cells that have
130 * 'vertical-align: baseline', *including* cells with rowspans.
131 * returns 0 if we don't have any cell with 'vertical-align: baseline'
133 nscoord
GetMaxCellAscent() const;
135 /* return the row ascent
137 nscoord
GetRowBaseline(mozilla::WritingMode aWritingMode
);
139 /** returns the ordinal position of this row in its table */
140 virtual int32_t GetRowIndex() const;
142 /** set this row's starting row index */
143 void SetRowIndex(int aRowIndex
);
145 // See nsTableFrame.h
146 int32_t GetAdjustmentForStoredIndex(int32_t aStoredIndex
) const;
148 // See nsTableFrame.h
149 void AddDeletedRowIndex();
151 /** used by row group frame code */
152 nscoord
ReflowCellFrame(nsPresContext
* aPresContext
,
153 const ReflowInput
& aReflowInput
, bool aIsTopOfPage
,
154 nsTableCellFrame
* aCellFrame
, nscoord aAvailableBSize
,
155 nsReflowStatus
& aStatus
);
157 * Collapse the row if required, apply col and colgroup visibility: collapse
158 * info to the cells in the row.
159 * @return the amount to shift bstart-wards all following rows
160 * @param aRowOffset - shift the row bstart-wards by this amount
161 * @param aISize - new isize of the row
162 * @param aCollapseGroup - parent rowgroup is collapsed so this row needs
164 * @param aDidCollapse - the row has been collapsed
166 nscoord
CollapseRowIfNecessary(nscoord aRowOffset
, nscoord aISize
,
167 bool aCollapseGroup
, bool& aDidCollapse
);
170 * Insert a cell frame after the last cell frame that has a col index
171 * that is less than aColIndex. If no such cell frame is found the
172 * frame to insert is prepended to the child list.
173 * @param aFrame the cell frame to insert
174 * @param aColIndex the col index
176 void InsertCellFrame(nsTableCellFrame
* aFrame
, int32_t aColIndex
);
178 nsresult
CalculateCellActualBSize(nsTableCellFrame
* aCellFrame
,
179 nscoord
& aDesiredBSize
,
180 mozilla::WritingMode aWM
);
182 bool IsFirstInserted() const;
183 void SetFirstInserted(bool aValue
);
185 nscoord
GetContentBSize() const;
186 void SetContentBSize(nscoord aTwipValue
);
188 bool HasStyleBSize() const;
190 bool HasFixedBSize() const;
191 void SetHasFixedBSize(bool aValue
);
193 bool HasPctBSize() const;
194 void SetHasPctBSize(bool aValue
);
196 nscoord
GetFixedBSize() const;
197 void SetFixedBSize(nscoord aValue
);
199 float GetPctBSize() const;
200 void SetPctBSize(float aPctValue
, bool aForce
= false);
202 nscoord
GetInitialBSize(nscoord aBasis
= 0) const;
204 nsTableRowFrame
* GetNextRow() const;
206 bool HasUnpaginatedBSize();
207 void SetHasUnpaginatedBSize(bool aValue
);
208 nscoord
GetUnpaginatedBSize();
209 void SetUnpaginatedBSize(nsPresContext
* aPresContext
, nscoord aValue
);
211 BCPixelSize
GetBStartBCBorderWidth() const { return mBStartBorderWidth
; }
212 BCPixelSize
GetBEndBCBorderWidth() const { return mBEndBorderWidth
; }
213 void SetBStartBCBorderWidth(BCPixelSize aWidth
) {
214 mBStartBorderWidth
= aWidth
;
216 void SetBEndBCBorderWidth(BCPixelSize aWidth
) { mBEndBorderWidth
= aWidth
; }
217 mozilla::LogicalMargin
GetBCBorderWidth(mozilla::WritingMode aWM
);
220 * Gets inner border widths before collapsing with cell borders
221 * Caller must get block-end border from next row or from table
222 * GetContinuousBCBorderWidth will not overwrite that border
223 * see nsTablePainter about continuous borders
225 void GetContinuousBCBorderWidth(mozilla::WritingMode aWM
,
226 mozilla::LogicalMargin
& aBorder
);
229 * @returns outer block-start bc border == prev row's block-end inner
231 nscoord
GetOuterBStartContBCBorderWidth();
233 * Sets full border widths before collapsing with cell borders
234 * @param aForSide - side to set; only accepts iend, istart, and bstart
236 void SetContinuousBCBorderWidth(mozilla::LogicalSide aForSide
,
237 BCPixelSize aPixelValue
);
239 virtual bool IsFrameOfType(uint32_t aFlags
) const override
{
240 if (aFlags
& eSupportsContainLayoutAndPaint
) {
244 return nsContainerFrame::IsFrameOfType(aFlags
& ~(nsIFrame::eTablePart
));
247 virtual void InvalidateFrame(uint32_t aDisplayItemKey
= 0,
248 bool aRebuildDisplayItems
= true) override
;
249 virtual void InvalidateFrameWithRect(
250 const nsRect
& aRect
, uint32_t aDisplayItemKey
= 0,
251 bool aRebuildDisplayItems
= true) override
;
252 virtual void InvalidateFrameForRemoval() override
{
253 InvalidateFrameSubtree();
257 virtual mozilla::a11y::AccType
AccessibleType() override
;
261 /** protected constructor.
264 explicit nsTableRowFrame(ComputedStyle
* aStyle
, nsPresContext
* aPresContext
,
265 ClassID aID
= kClassID
);
267 void InitChildReflowInput(nsPresContext
& aPresContext
,
268 const mozilla::LogicalSize
& aAvailSize
,
269 bool aBorderCollapse
,
270 TableCellReflowInput
& aReflowInput
);
272 virtual LogicalSides
GetLogicalSkipSides(
273 const ReflowInput
* aReflowInput
= nullptr) const override
;
275 // row-specific methods
277 nscoord
ComputeCellXOffset(const ReflowInput
& aState
, nsIFrame
* aKidFrame
,
278 const nsMargin
& aKidMargin
) const;
280 * Called for incremental/dirty and resize reflows. If aDirtyOnly is true then
281 * only reflow dirty cells.
283 void ReflowChildren(nsPresContext
* aPresContext
, ReflowOutput
& aDesiredSize
,
284 const ReflowInput
& aReflowInput
,
285 nsTableFrame
& aTableFrame
, nsReflowStatus
& aStatus
);
289 unsigned mRowIndex
: 29;
290 unsigned mHasFixedBSize
: 1; // set if the dominating style bsize on the
291 // row or any cell is pixel based
292 unsigned mHasPctBSize
: 1; // set if the dominating style bsize on the row
293 // or any cell is pct based
294 unsigned mFirstInserted
: 1; // if true, then it was the bstart-most newly
298 // the desired bsize based on the content of the tallest cell in the row
299 nscoord mContentBSize
;
300 // the bsize based on a style percentage bsize on either the row or any cell
301 // if mHasPctBSize is set
302 nscoord mStylePctBSize
;
303 // the bsize based on a style pixel bsize on the row or any
304 // cell if mHasFixedBSize is set
305 nscoord mStyleFixedBSize
;
307 // max-ascent and max-descent amongst all cells that have
308 // 'vertical-align: baseline'
309 nscoord mMaxCellAscent
; // does include cells with rowspan > 1
310 nscoord mMaxCellDescent
; // does *not* include cells with rowspan > 1
312 // border widths in pixels in the collapsing border model of the *inner*
313 // half of the border only
314 BCPixelSize mBStartBorderWidth
;
315 BCPixelSize mBEndBorderWidth
;
316 BCPixelSize mIEndContBorderWidth
;
317 BCPixelSize mBStartContBorderWidth
;
318 BCPixelSize mIStartContBorderWidth
;
321 * Sets the NS_ROW_HAS_CELL_WITH_STYLE_BSIZE bit to indicate whether
322 * this row has any cells that have non-auto-bsize. (Row-spanning
323 * cells are ignored.)
325 void InitHasCellWithStyleBSize(nsTableFrame
* aTableFrame
);
328 inline int32_t nsTableRowFrame::GetAdjustmentForStoredIndex(
329 int32_t aStoredIndex
) const {
330 nsTableRowGroupFrame
* parentFrame
= GetTableRowGroupFrame();
331 return parentFrame
->GetAdjustmentForStoredIndex(aStoredIndex
);
334 inline void nsTableRowFrame::AddDeletedRowIndex() {
335 nsTableRowGroupFrame
* parentFrame
= GetTableRowGroupFrame();
336 parentFrame
->AddDeletedRowIndex(int32_t(mBits
.mRowIndex
));
339 inline int32_t nsTableRowFrame::GetRowIndex() const {
340 int32_t storedRowIndex
= int32_t(mBits
.mRowIndex
);
341 int32_t rowIndexAdjustment
= GetAdjustmentForStoredIndex(storedRowIndex
);
342 return (storedRowIndex
- rowIndexAdjustment
);
345 inline void nsTableRowFrame::SetRowIndex(int aRowIndex
) {
346 // Note: Setting the index of a row (as in the case of adding new rows) should
347 // be preceded by a call to nsTableFrame::RecalculateRowIndices()
348 // so as to correctly clear mDeletedRowIndexRanges.
350 GetTableRowGroupFrame()->GetTableFrame()->IsDeletedRowIndexRangesEmpty(),
351 "mDeletedRowIndexRanges should be empty here!");
352 mBits
.mRowIndex
= aRowIndex
;
355 inline bool nsTableRowFrame::IsFirstInserted() const {
356 return bool(mBits
.mFirstInserted
);
359 inline void nsTableRowFrame::SetFirstInserted(bool aValue
) {
360 mBits
.mFirstInserted
= aValue
;
363 inline bool nsTableRowFrame::HasStyleBSize() const {
364 return (bool)mBits
.mHasFixedBSize
|| (bool)mBits
.mHasPctBSize
;
367 inline bool nsTableRowFrame::HasFixedBSize() const {
368 return (bool)mBits
.mHasFixedBSize
;
371 inline void nsTableRowFrame::SetHasFixedBSize(bool aValue
) {
372 mBits
.mHasFixedBSize
= aValue
;
375 inline bool nsTableRowFrame::HasPctBSize() const {
376 return (bool)mBits
.mHasPctBSize
;
379 inline void nsTableRowFrame::SetHasPctBSize(bool aValue
) {
380 mBits
.mHasPctBSize
= aValue
;
383 inline nscoord
nsTableRowFrame::GetContentBSize() const {
384 return mContentBSize
;
387 inline void nsTableRowFrame::SetContentBSize(nscoord aValue
) {
388 mContentBSize
= aValue
;
391 inline nscoord
nsTableRowFrame::GetFixedBSize() const {
392 if (mBits
.mHasFixedBSize
) {
393 return mStyleFixedBSize
;
398 inline float nsTableRowFrame::GetPctBSize() const {
399 if (mBits
.mHasPctBSize
) {
400 return (float)mStylePctBSize
/ 100.0f
;
405 inline bool nsTableRowFrame::HasUnpaginatedBSize() {
406 return HasAnyStateBits(NS_TABLE_ROW_HAS_UNPAGINATED_BSIZE
);
409 inline void nsTableRowFrame::SetHasUnpaginatedBSize(bool aValue
) {
411 AddStateBits(NS_TABLE_ROW_HAS_UNPAGINATED_BSIZE
);
413 RemoveStateBits(NS_TABLE_ROW_HAS_UNPAGINATED_BSIZE
);
417 inline mozilla::LogicalMargin
nsTableRowFrame::GetBCBorderWidth(
418 mozilla::WritingMode aWM
) {
419 nsPresContext
* presContext
= PresContext();
420 return mozilla::LogicalMargin(
421 aWM
, presContext
->DevPixelsToAppUnits(mBStartBorderWidth
), 0,
422 presContext
->DevPixelsToAppUnits(mBEndBorderWidth
), 0);
425 inline void nsTableRowFrame::GetContinuousBCBorderWidth(
426 mozilla::WritingMode aWM
, mozilla::LogicalMargin
& aBorder
) {
427 int32_t d2a
= PresContext()->AppUnitsPerDevPixel();
428 aBorder
.IEnd(aWM
) = BC_BORDER_START_HALF_COORD(d2a
, mIStartContBorderWidth
);
429 aBorder
.BStart(aWM
) = BC_BORDER_END_HALF_COORD(d2a
, mBStartContBorderWidth
);
430 aBorder
.IStart(aWM
) = BC_BORDER_END_HALF_COORD(d2a
, mIEndContBorderWidth
);
433 inline nscoord
nsTableRowFrame::GetOuterBStartContBCBorderWidth() {
434 int32_t aPixelsToTwips
= mozilla::AppUnitsPerCSSPixel();
435 return BC_BORDER_START_HALF_COORD(aPixelsToTwips
, mBStartContBorderWidth
);