Bug 1863837 Part 10 - Improve ergonomics of TableReflowInput. r=layout-reviewers,emilio

- Better encapsulation.
- Add `AdvanceBCoord()` to adjust block-offset and available block-size at
  once.

This patch doesn't change behavior.

Differential Revision: https://phabricator.services.mozilla.com/D193149
This commit is contained in:
Ting-Yu Lin 2023-11-13 22:36:16 +00:00
parent 44d862821f
commit 67d9c2fb7b
2 changed files with 61 additions and 58 deletions

View File

@ -65,65 +65,76 @@ using mozilla::gfx::DrawTarget;
using mozilla::gfx::Float;
using mozilla::gfx::ToDeviceColor;
/********************************************************************************
** TableReflowInput **
********************************************************************************/
namespace mozilla {
struct TableReflowInput {
// the real reflow input
const ReflowInput& mReflowInput;
// The table's available size (in reflowInput's writing mode)
LogicalSize mAvailSize;
// Stationary inline-offset
nscoord mICoord;
// Running block-offset
nscoord mBCoord;
struct TableReflowInput final {
TableReflowInput(const ReflowInput& aReflowInput,
const LogicalSize& aAvailSize)
: mReflowInput(aReflowInput), mAvailSize(aAvailSize) {
: mReflowInput(aReflowInput),
mWM(aReflowInput.GetWritingMode()),
mAvailSize(aAvailSize) {
MOZ_ASSERT(mReflowInput.mFrame->IsTableFrame(),
"TableReflowInput should only be created for nsTableFrame");
nsTableFrame* table =
static_cast<nsTableFrame*>(mReflowInput.mFrame->FirstInFlow());
WritingMode wm = aReflowInput.GetWritingMode();
// XXX: We need to call ApplySkipSides() for borderPadding. Otherwise,
// mAvailSize will be wrong in a continuation.
LogicalMargin borderPadding = mReflowInput.ComputedLogicalBorderPadding(wm);
LogicalMargin borderPadding =
mReflowInput.ComputedLogicalBorderPadding(mWM);
mICoord = borderPadding.IStart(wm) + table->GetColSpacing(-1);
mBCoord = borderPadding.BStart(wm); // cellspacing added during reflow
mICoord = borderPadding.IStart(mWM) + table->GetColSpacing(-1);
mBCoord = borderPadding.BStart(mWM); // rowspacing added during reflow
// XXX do we actually need to check for unconstrained inline-size here?
if (NS_UNCONSTRAINEDSIZE != mAvailSize.ISize(wm)) {
if (NS_UNCONSTRAINEDSIZE != mAvailSize.ISize(mWM)) {
int32_t colCount = table->GetColCount();
mAvailSize.ISize(wm) -= borderPadding.IStartEnd(wm) +
table->GetColSpacing(-1) +
table->GetColSpacing(colCount);
mAvailSize.ISize(wm) = std::max(0, mAvailSize.ISize(wm));
mAvailSize.ISize(mWM) -= borderPadding.IStartEnd(mWM) +
table->GetColSpacing(-1) +
table->GetColSpacing(colCount);
mAvailSize.ISize(mWM) = std::max(0, mAvailSize.ISize(mWM));
}
if (NS_UNCONSTRAINEDSIZE != mAvailSize.BSize(wm)) {
mAvailSize.BSize(wm) -= borderPadding.BStartEnd(wm) +
table->GetRowSpacing(-1) +
table->GetRowSpacing(table->GetRowCount());
mAvailSize.BSize(wm) = std::max(0, mAvailSize.BSize(wm));
if (NS_UNCONSTRAINEDSIZE != mAvailSize.BSize(mWM)) {
mAvailSize.BSize(mWM) -= borderPadding.BStartEnd(mWM) +
table->GetRowSpacing(-1) +
table->GetRowSpacing(table->GetRowCount());
mAvailSize.BSize(mWM) = std::max(0, mAvailSize.BSize(mWM));
}
}
void ReduceAvailableBSizeBy(WritingMode aWM, nscoord aAmount) {
if (mAvailSize.BSize(aWM) == NS_UNCONSTRAINEDSIZE) {
// Advance to the next block-offset and reduce the available block-size.
void AdvanceBCoord(nscoord aAmount) {
mBCoord += aAmount;
ReduceAvailableBSizeBy(aAmount);
}
const LogicalSize& AvailableSize() const { return mAvailSize; }
// The real reflow input of the table frame.
const ReflowInput& mReflowInput;
// Stationary inline-offset, which won't change after the constructor.
nscoord mICoord = 0;
// Running block-offset, which will be adjusted as we reflow children.
nscoord mBCoord = 0;
private:
void ReduceAvailableBSizeBy(nscoord aAmount) {
if (mAvailSize.BSize(mWM) == NS_UNCONSTRAINEDSIZE) {
return;
}
mAvailSize.BSize(aWM) -= aAmount;
mAvailSize.BSize(aWM) = std::max(0, mAvailSize.BSize(aWM));
mAvailSize.BSize(mWM) -= aAmount;
mAvailSize.BSize(mWM) = std::max(0, mAvailSize.BSize(mWM));
}
// mReflowInput's (i.e. table frame's) writing-mode.
WritingMode mWM;
// The available size for children. The inline-size is stationary after the
// constructor, but the block-size will be adjusted as we reflow children.
LogicalSize mAvailSize;
};
struct TableBCData final {
@ -2522,11 +2533,7 @@ void nsTableFrame::PlaceChild(TableReflowInput& aReflowInput,
InvalidateTableFrame(aKidFrame, aOriginalKidRect, aOriginalKidInkOverflow,
isFirstReflow);
// Adjust the running block-offset
aReflowInput.mBCoord += aKidDesiredSize.BSize(wm);
// If our bsize is constrained, then update the available bsize
aReflowInput.ReduceAvailableBSizeBy(wm, aKidDesiredSize.BSize(wm));
aReflowInput.AdvanceBCoord(aKidDesiredSize.BSize(wm));
}
nsTableFrame::RowGroupArray nsTableFrame::OrderedRowGroups(
@ -2604,7 +2611,7 @@ nscoord nsTableFrame::SetupHeaderFooterChild(
LogicalSize(wm, presContext->GetPageSize()).BSize(wm);
// Reflow the child with unconstrained block-size.
LogicalSize availSize = aReflowInput.mAvailSize;
LogicalSize availSize = aReflowInput.AvailableSize();
availSize.BSize(wm) = NS_UNCONSTRAINEDSIZE;
const nsSize containerSize =
@ -2630,7 +2637,7 @@ void nsTableFrame::PlaceRepeatedFooter(TableReflowInput& aReflowInput,
nscoord aFooterBSize) {
nsPresContext* presContext = PresContext();
const WritingMode wm = GetWritingMode();
LogicalSize kidAvailSize = aReflowInput.mAvailSize;
LogicalSize kidAvailSize = aReflowInput.AvailableSize();
kidAvailSize.BSize(wm) = aFooterBSize;
const nsSize containerSize =
@ -2639,7 +2646,7 @@ void nsTableFrame::PlaceRepeatedFooter(TableReflowInput& aReflowInput,
kidAvailSize, Nothing(),
ReflowInput::InitFlag::CallerWillInit);
InitChildReflowInput(footerReflowInput);
aReflowInput.mBCoord += GetRowSpacing(GetRowCount());
aReflowInput.AdvanceBCoord(GetRowSpacing(GetRowCount()));
nsRect origTfootRect = aTfoot->GetRect();
nsRect origTfootInkOverflow = aTfoot->InkOverflowRect();
@ -2679,7 +2686,7 @@ void nsTableFrame::ReflowChildren(TableReflowInput& aReflowInput,
// frame. (This is indicated by the "mTableIsSplittable" flag.)
bool isPaginated =
presContext->IsPaginated() &&
NS_UNCONSTRAINEDSIZE != aReflowInput.mAvailSize.BSize(wm) &&
aReflowInput.mReflowInput.AvailableBSize() != NS_UNCONSTRAINEDSIZE &&
aReflowInput.mReflowInput.mFlags.mTableIsSplittable;
// Tables currently (though we ought to fix this) only fragment in
@ -2757,7 +2764,7 @@ void nsTableFrame::ReflowChildren(TableReflowInput& aReflowInput,
break;
}
LogicalSize kidAvailSize(aReflowInput.mAvailSize);
LogicalSize kidAvailSize = aReflowInput.AvailableSize();
allowRepeatedFooter = false;
if (isPaginated && (NS_UNCONSTRAINEDSIZE != kidAvailSize.BSize(wm))) {
if (kidFrame != thead && kidFrame != tfoot && tfoot &&
@ -2793,8 +2800,7 @@ void nsTableFrame::ReflowChildren(TableReflowInput& aReflowInput,
.BEnd(wm) > 0)) {
kidReflowInput.mFlags.mIsTopOfPage = false;
}
aReflowInput.mBCoord += rowSpacing;
aReflowInput.ReduceAvailableBSizeBy(wm, rowSpacing);
aReflowInput.AdvanceBCoord(rowSpacing);
// record the presence of a next in flow, it might get destroyed so we
// need to reorder the row group array
const bool reorder = kidFrame->GetNextInFlow();
@ -2932,7 +2938,7 @@ void nsTableFrame::ReflowChildren(TableReflowInput& aReflowInput,
break;
}
} else { // it isn't being reflowed
aReflowInput.mBCoord += rowSpacing;
aReflowInput.AdvanceBCoord(rowSpacing);
const LogicalRect kidRect =
kidFrame->GetLogicalNormalRect(wm, containerSize);
if (kidRect.BStart(wm) != aReflowInput.mBCoord) {
@ -2945,9 +2951,8 @@ void nsTableFrame::ReflowChildren(TableReflowInput& aReflowInput,
// invalidate the new position
kidFrame->InvalidateFrameSubtree();
}
aReflowInput.mBCoord += kidRect.BSize(wm);
aReflowInput.ReduceAvailableBSizeBy(wm, rowSpacing + kidRect.BSize(wm));
aReflowInput.AdvanceBCoord(kidRect.BSize(wm));
}
}

View File

@ -25,7 +25,6 @@ class nsTableColGroupFrame;
class nsITableLayoutStrategy;
namespace mozilla {
class LogicalMargin;
class PresShell;
class WritingMode;
@ -133,7 +132,6 @@ class nsTableFrame : public nsContainerFrame {
typedef mozilla::image::ImgDrawResult ImgDrawResult;
typedef mozilla::WritingMode WritingMode;
typedef mozilla::LogicalMargin LogicalMargin;
typedef mozilla::TableReflowInput TableReflowInput;
public:
NS_DECL_FRAMEARENA_HELPERS(nsTableFrame)
@ -576,11 +574,11 @@ class nsTableFrame : public nsContainerFrame {
// A helper function to reflow a header or footer with unconstrained
// block-size to see if it should be made repeatable.
// @return the desired block-size for a header or footer.
nscoord SetupHeaderFooterChild(const TableReflowInput& aReflowInput,
nscoord SetupHeaderFooterChild(const mozilla::TableReflowInput& aReflowInput,
nsTableRowGroupFrame* aFrame);
void ReflowChildren(TableReflowInput& aReflowInput, nsReflowStatus& aStatus,
nsIFrame*& aLastChildReflowed,
void ReflowChildren(mozilla::TableReflowInput& aReflowInput,
nsReflowStatus& aStatus, nsIFrame*& aLastChildReflowed,
mozilla::OverflowAreas& aOverflowAreas);
// This calls the col group and column reflow methods, which do two things:
@ -647,13 +645,13 @@ class nsTableFrame : public nsContainerFrame {
// The following is a helper for CalcDesiredBSize
void DistributeBSizeToRows(const ReflowInput& aReflowInput, nscoord aAmount);
void PlaceChild(TableReflowInput& aReflowInput, nsIFrame* aKidFrame,
void PlaceChild(mozilla::TableReflowInput& aReflowInput, nsIFrame* aKidFrame,
const ReflowInput& aKidReflowInput,
const mozilla::LogicalPoint& aKidPosition,
const nsSize& aContainerSize, ReflowOutput& aKidDesiredSize,
const nsRect& aOriginalKidRect,
const nsRect& aOriginalKidInkOverflow);
void PlaceRepeatedFooter(TableReflowInput& aReflowInput,
void PlaceRepeatedFooter(mozilla::TableReflowInput& aReflowInput,
nsTableRowGroupFrame* aTfoot, nscoord aFooterBSize);
public: