Bug 1678767 Part 2 - Convert nsTableRowGroupFrame::SplitRowGroup() to logical coordinates. r=dshin

Differential Revision: https://phabricator.services.mozilla.com/D191368
This commit is contained in:
Ting-Yu Lin 2023-10-23 18:38:00 +00:00
parent a5b890bd77
commit a1013c7313

View File

@ -1059,18 +1059,20 @@ void nsTableRowGroupFrame::SplitRowGroup(nsPresContext* aPresContext,
MOZ_ASSERT(aPresContext->IsPaginated(), MOZ_ASSERT(aPresContext->IsPaginated(),
"SplitRowGroup currently supports only paged media"); "SplitRowGroup currently supports only paged media");
const WritingMode wm = aReflowInput.GetWritingMode();
nsTableRowFrame* prevRowFrame = nullptr; nsTableRowFrame* prevRowFrame = nullptr;
aDesiredSize.Height() = 0; aDesiredSize.BSize(wm) = 0;
aDesiredSize.SetOverflowAreasToDesiredBounds(); aDesiredSize.SetOverflowAreasToDesiredBounds();
const nscoord availWidth = aReflowInput.AvailableWidth(); const nscoord availISize = aReflowInput.AvailableISize();
const nscoord availHeight = aReflowInput.AvailableHeight(); const nscoord availBSize = aReflowInput.AvailableBSize();
const nsSize containerSize =
aReflowInput.ComputedSizeAsContainerIfConstrained();
const bool borderCollapse = aTableFrame->IsBorderCollapse(); const bool borderCollapse = aTableFrame->IsBorderCollapse();
// get the page height const nscoord pageBSize =
nscoord pageHeight = aPresContext->GetPageSize().height; LogicalSize(wm, aPresContext->GetPageSize()).BSize(wm);
NS_ASSERTION(pageHeight != NS_UNCONSTRAINEDSIZE, NS_ASSERTION(pageBSize != NS_UNCONSTRAINEDSIZE,
"The table shouldn't be split when there should be space"); "The table shouldn't be split when there should be space");
bool isTopOfPage = aReflowInput.mFlags.mIsTopOfPage; bool isTopOfPage = aReflowInput.mFlags.mIsTopOfPage;
@ -1086,23 +1088,25 @@ void nsTableRowGroupFrame::SplitRowGroup(nsPresContext* aPresContext,
rowFrame = rowFrame->GetNextRow()) { rowFrame = rowFrame->GetNextRow()) {
bool rowIsOnPage = true; bool rowIsOnPage = true;
nscoord cellSpacingB = aTableFrame->GetRowSpacing(rowFrame->GetRowIndex()); nscoord cellSpacingB = aTableFrame->GetRowSpacing(rowFrame->GetRowIndex());
nsRect rowRect = rowFrame->GetNormalRect(); const LogicalRect rowRect =
rowFrame->GetLogicalNormalRect(wm, containerSize);
// See if the row fits on this page // See if the row fits on this page
if (rowRect.YMost() > availHeight) { if (rowRect.BEnd(wm) > availBSize) {
nsTableRowFrame* contRow = nullptr; nsTableRowFrame* contRow = nullptr;
// Reflow the row in the availabe space and have it split if it is the 1st // Reflow the row in the availabe space and have it split if it is the 1st
// row (on the page) or there is at least 5% of the current page available // row (on the page) or there is at least 5% of the current page available
// XXX this 5% should be made a preference // XXX this 5% should be made a preference
if (!prevRowFrame || if (!prevRowFrame ||
(availHeight - aDesiredSize.Height() > pageHeight / 20)) { (availBSize - aDesiredSize.BSize(wm) > pageBSize / 20)) {
nsSize availSize(availWidth, std::max(availHeight - rowRect.y, 0)); LogicalSize availSize(wm, availISize,
// don't let the available height exceed what CalculateRowHeights set std::max(availBSize - rowRect.BStart(wm), 0));
// for it // Don't let the available block-size exceed what CalculateRowBSizes set
availSize.height = std::min(availSize.height, rowRect.height); // for it.
availSize.BSize(wm) = std::min(availSize.BSize(wm), rowRect.BSize(wm));
ReflowInput rowReflowInput( ReflowInput rowReflowInput(
aPresContext, aReflowInput, rowFrame, aPresContext, aReflowInput, rowFrame,
LogicalSize(rowFrame->GetWritingMode(), availSize), Nothing(), availSize.ConvertTo(rowFrame->GetWritingMode(), wm), Nothing(),
ReflowInput::InitFlag::CallerWillInit); ReflowInput::InitFlag::CallerWillInit);
InitChildReflowInput(*aPresContext, borderCollapse, rowReflowInput); InitChildReflowInput(*aPresContext, borderCollapse, rowReflowInput);
@ -1113,12 +1117,19 @@ void nsTableRowGroupFrame::SplitRowGroup(nsPresContext* aPresContext,
nsRect oldRowRect = rowFrame->GetRect(); nsRect oldRowRect = rowFrame->GetRect();
nsRect oldRowInkOverflow = rowFrame->InkOverflowRect(); nsRect oldRowInkOverflow = rowFrame->InkOverflowRect();
// Reflow the cell with the constrained height. A cell with rowspan >1 // Reflow the cell with the constrained bsize. A cell with rowspan >1
// will get this reflow later during SplitSpanningCells. // will get this reflow later during SplitSpanningCells.
ReflowChild(rowFrame, aPresContext, rowMetrics, rowReflowInput, 0, 0, //
ReflowChildFlags::NoMoveFrame, aStatus); // Note: We just pass dummy aPos and aContainerSize since we are not
rowFrame->SetSize(nsSize(rowMetrics.Width(), rowMetrics.Height())); // moving the row frame.
rowFrame->DidReflow(aPresContext, nullptr); const LogicalPoint dummyPos(wm);
const nsSize dummyContainerSize;
ReflowChild(rowFrame, aPresContext, rowMetrics, rowReflowInput, wm,
dummyPos, dummyContainerSize, ReflowChildFlags::NoMoveFrame,
aStatus);
FinishReflowChild(rowFrame, aPresContext, rowMetrics, &rowReflowInput,
wm, dummyPos, dummyContainerSize,
ReflowChildFlags::NoMoveFrame);
rowFrame->DidResize(); rowFrame->DidResize();
if (!aRowForcedPageBreak && !aStatus.IsFullyComplete() && if (!aRowForcedPageBreak && !aStatus.IsFullyComplete() &&
@ -1133,32 +1144,32 @@ void nsTableRowGroupFrame::SplitRowGroup(nsPresContext* aPresContext,
if (aStatus.IsIncomplete()) { if (aStatus.IsIncomplete()) {
// The row frame is incomplete and all of the rowspan 1 cells' block // The row frame is incomplete and all of the rowspan 1 cells' block
// frames split // frames split
if ((rowMetrics.Height() <= rowReflowInput.AvailableHeight()) || if ((rowMetrics.BSize(wm) <= rowReflowInput.AvailableBSize()) ||
isTopOfPage) { isTopOfPage) {
// The row stays on this page because either it split ok or we're on // The row stays on this page because either it split ok or we're on
// the top of page. If top of page and the height exceeded the avail // the top of page. If top of page and the block-size exceeded the
// height, then there will be data loss // avail block-size, then there will be data loss.
NS_ASSERTION( NS_ASSERTION(
rowMetrics.Height() <= rowReflowInput.AvailableHeight(), rowMetrics.BSize(wm) <= rowReflowInput.AvailableBSize(),
"data loss - incomplete row needed more height than available, " "Data loss - incomplete row needed more block-size than "
"on top of page"); "available, on top of page!");
contRow = CreateContinuingRowFrame(rowFrame); contRow = CreateContinuingRowFrame(rowFrame);
aDesiredSize.Height() += rowMetrics.Height(); aDesiredSize.BSize(wm) += rowMetrics.BSize(wm);
if (prevRowFrame) { if (prevRowFrame) {
aDesiredSize.Height() += cellSpacingB; aDesiredSize.BSize(wm) += cellSpacingB;
} }
} else { } else {
// Put the row on the next page to give it more height // Put the row on the next page to give it more block-size.
rowIsOnPage = false; rowIsOnPage = false;
} }
} else { } else {
// The row frame is complete because either (1) its minimum height is // The row frame is complete because either (1) its minimum block-size
// greater than the available height we gave it, or (2) it may have // is greater than the available block-size we gave it, or (2) it may
// been given a larger height through style than its content, or (3) // have been given a larger block-size through style than its content,
// it contains a rowspan >1 cell which hasn't been reflowed with a // or (3) it contains a rowspan >1 cell which hasn't been reflowed
// constrained height yet (we will find out when SplitSpanningCells is // with a constrained block-size yet (we will find out when
// called below) // SplitSpanningCells is called below)
if (rowMetrics.Height() > availSize.height || if (rowMetrics.BSize(wm) > availSize.BSize(wm) ||
(aStatus.IsInlineBreakBefore() && !aRowForcedPageBreak)) { (aStatus.IsInlineBreakBefore() && !aRowForcedPageBreak)) {
// cases (1) and (2) // cases (1) and (2)
if (isTopOfPage) { if (isTopOfPage) {
@ -1169,27 +1180,27 @@ void nsTableRowGroupFrame::SplitRowGroup(nsPresContext* aPresContext,
aStatus.Reset(); aStatus.Reset();
aStatus.SetIncomplete(); aStatus.SetIncomplete();
} }
aDesiredSize.Height() += rowMetrics.Height(); aDesiredSize.BSize(wm) += rowMetrics.BSize(wm);
if (prevRowFrame) aDesiredSize.Height() += cellSpacingB; if (prevRowFrame) {
aDesiredSize.BSize(wm) += cellSpacingB;
}
NS_WARNING( NS_WARNING(
"data loss - complete row needed more height than available, " "Data loss - complete row needed more block-size than "
"on top of page"); "available, on top of page");
} else { } else {
// We're not on top of the page, so put the row on the next page // We're not on top of the page, so put the row on the next page
// to give it more height // to give it more block-size.
rowIsOnPage = false; rowIsOnPage = false;
} }
} }
} }
} // if (!prevRowFrame || (availHeight - aDesiredSize.Height() > } else {
// pageHeight / 20)) // Put the row on the next page to give it more block-size.
else {
// put the row on the next page to give it more height
rowIsOnPage = false; rowIsOnPage = false;
} }
nsTableRowFrame* lastRowThisPage = rowFrame; nsTableRowFrame* lastRowThisPage = rowFrame;
nscoord spanningRowBottom = availHeight; nscoord spanningRowBEnd = availBSize;
if (!rowIsOnPage) { if (!rowIsOnPage) {
NS_ASSERTION(!contRow, NS_ASSERTION(!contRow,
"We should not have created a continuation if none of " "We should not have created a continuation if none of "
@ -1199,18 +1210,19 @@ void nsTableRowGroupFrame::SplitRowGroup(nsPresContext* aPresContext,
aStatus.SetInlineLineBreakBeforeAndReset(); aStatus.SetInlineLineBreakBeforeAndReset();
break; break;
} }
spanningRowBottom = prevRowFrame->GetNormalRect().YMost(); spanningRowBEnd =
prevRowFrame->GetLogicalNormalRect(wm, containerSize).BEnd(wm);
lastRowThisPage = prevRowFrame; lastRowThisPage = prevRowFrame;
aStatus.Reset(); aStatus.Reset();
aStatus.SetIncomplete(); aStatus.SetIncomplete();
} }
// reflow the cells with rowspan >1 that occur on the page
// reflow the cells with rowspan >1 that occur on the page
nsTableRowFrame* firstTruncatedRow; nsTableRowFrame* firstTruncatedRow;
nscoord bMost; nscoord bMost;
SplitSpanningCells(*aPresContext, aReflowInput, *aTableFrame, SplitSpanningCells(*aPresContext, aReflowInput, *aTableFrame,
*firstRowThisPage, *lastRowThisPage, *firstRowThisPage, *lastRowThisPage,
aReflowInput.mFlags.mIsTopOfPage, spanningRowBottom, aReflowInput.mFlags.mIsTopOfPage, spanningRowBEnd,
contRow, firstTruncatedRow, bMost); contRow, firstTruncatedRow, bMost);
if (firstTruncatedRow) { if (firstTruncatedRow) {
// A rowspan >1 cell did not fit (and could not split) in the space we // A rowspan >1 cell did not fit (and could not split) in the space we
@ -1221,17 +1233,18 @@ void nsTableRowGroupFrame::SplitRowGroup(nsPresContext* aPresContext,
} else { } else {
// We can't push children, so let our parent reflow us again with // We can't push children, so let our parent reflow us again with
// more space // more space
aDesiredSize.Height() = rowRect.YMost(); aDesiredSize.BSize(wm) = rowRect.BEnd(wm);
aStatus.Reset(); aStatus.Reset();
UndoContinuedRow(aPresContext, contRow); UndoContinuedRow(aPresContext, contRow);
contRow = nullptr; contRow = nullptr;
} }
} else { // (firstTruncatedRow != firstRowThisPage) } else {
// Try to put firstTruncateRow on the next page // Try to put firstTruncateRow on the next page
nsTableRowFrame* rowBefore = nsTableRowFrame* rowBefore =
::GetRowBefore(*firstRowThisPage, *firstTruncatedRow); ::GetRowBefore(*firstRowThisPage, *firstTruncatedRow);
nscoord oldSpanningRowBottom = spanningRowBottom; const nscoord oldSpanningRowBEnd = spanningRowBEnd;
spanningRowBottom = rowBefore->GetNormalRect().YMost(); spanningRowBEnd =
rowBefore->GetLogicalNormalRect(wm, containerSize).BEnd(wm);
UndoContinuedRow(aPresContext, contRow); UndoContinuedRow(aPresContext, contRow);
contRow = nullptr; contRow = nullptr;
@ -1244,8 +1257,8 @@ void nsTableRowGroupFrame::SplitRowGroup(nsPresContext* aPresContext,
// page // page
SplitSpanningCells( SplitSpanningCells(
*aPresContext, aReflowInput, *aTableFrame, *firstRowThisPage, *aPresContext, aReflowInput, *aTableFrame, *firstRowThisPage,
*rowBefore, aReflowInput.mFlags.mIsTopOfPage, spanningRowBottom, *rowBefore, aReflowInput.mFlags.mIsTopOfPage, spanningRowBEnd,
contRow, firstTruncatedRow, aDesiredSize.Height()); contRow, firstTruncatedRow, aDesiredSize.BSize(wm));
if (firstTruncatedRow) { if (firstTruncatedRow) {
if (aReflowInput.mFlags.mIsTopOfPage) { if (aReflowInput.mFlags.mIsTopOfPage) {
// We were better off with the 1st call to SplitSpanningCells, do // We were better off with the 1st call to SplitSpanningCells, do
@ -1253,25 +1266,24 @@ void nsTableRowGroupFrame::SplitRowGroup(nsPresContext* aPresContext,
UndoContinuedRow(aPresContext, contRow); UndoContinuedRow(aPresContext, contRow);
contRow = nullptr; contRow = nullptr;
lastRowThisPage = oldLastRowThisPage; lastRowThisPage = oldLastRowThisPage;
spanningRowBottom = oldSpanningRowBottom; spanningRowBEnd = oldSpanningRowBEnd;
SplitSpanningCells(*aPresContext, aReflowInput, *aTableFrame, SplitSpanningCells(*aPresContext, aReflowInput, *aTableFrame,
*firstRowThisPage, *lastRowThisPage, *firstRowThisPage, *lastRowThisPage,
aReflowInput.mFlags.mIsTopOfPage, aReflowInput.mFlags.mIsTopOfPage,
spanningRowBottom, contRow, firstTruncatedRow, spanningRowBEnd, contRow, firstTruncatedRow,
aDesiredSize.Height()); aDesiredSize.BSize(wm));
NS_WARNING("data loss in a row spanned cell"); NS_WARNING("data loss in a row spanned cell");
} else { } else {
// Let our parent reflow us again with more space // Let our parent reflow us again with more space
aDesiredSize.Height() = rowRect.YMost(); aDesiredSize.BSize(wm) = rowRect.BEnd(wm);
aStatus.Reset(); aStatus.Reset();
UndoContinuedRow(aPresContext, contRow); UndoContinuedRow(aPresContext, contRow);
contRow = nullptr; contRow = nullptr;
} }
} }
} // if (firstTruncatedRow == firstRowThisPage) }
} // if (firstTruncatedRow) } else {
else { aDesiredSize.BSize(wm) = std::max(aDesiredSize.BSize(wm), bMost);
aDesiredSize.Height() = std::max(aDesiredSize.Height(), bMost);
if (contRow) { if (contRow) {
aStatus.Reset(); aStatus.Reset();
aStatus.SetIncomplete(); aStatus.SetIncomplete();
@ -1293,8 +1305,8 @@ void nsTableRowGroupFrame::SplitRowGroup(nsPresContext* aPresContext,
} }
} }
break; break;
} // if (rowRect.YMost() > availHeight) }
aDesiredSize.Height() = rowRect.YMost(); aDesiredSize.BSize(wm) = rowRect.BEnd(wm);
prevRowFrame = rowFrame; prevRowFrame = rowFrame;
// see if there is a page break after the row // see if there is a page break after the row
nsTableRowFrame* nextRow = rowFrame->GetNextRow(); nsTableRowFrame* nextRow = rowFrame->GetNextRow();
@ -1304,9 +1316,9 @@ void nsTableRowGroupFrame::SplitRowGroup(nsPresContext* aPresContext,
aStatus.SetIncomplete(); aStatus.SetIncomplete();
break; break;
} }
// after the 1st row that has a height, we can't be on top // After the 1st row that has a block-size, we can't be on top of the page
// of the page anymore. // anymore.
isTopOfPage = isTopOfPage && rowRect.YMost() == 0; isTopOfPage = isTopOfPage && rowRect.BEnd(wm) == 0;
} }
} }