mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-11-24 05:11:16 +00:00
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:
parent
a5b890bd77
commit
a1013c7313
@ -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;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user