зеркало из https://github.com/mozilla/gecko-dev.git
Bug 1778931 Part 1 - Create a float's ReflowInput in FlowAndPlaceFloat() and pass it into ReflowFloat(). r=dholbert
There is some advantage to creating the float's ReflowInput in FlowAndPlaceFloat(). 1. ReflowFloat() doesn't need to output the float's margin and offset via the output arguments. FlowAndPlaceFloat() can get them from the local ReflowInput directly. 2. Since we are going to reflow the float, we have to create a ReflowInput anyway. FloatMarginISize() can take the ReflowInput and be simplified. No need to waste time to create a separate SizeComputationInput. Also, delete the comment "Pass floatRS so the frame hierarchy can be used (redoFloatRS has the same hierarchy)" because I believe it is obsolete. This patch also lays the foundation for other improvements in the later patches. Differential Revision: https://phabricator.services.mozilla.com/D151455
This commit is contained in:
Родитель
fd92081aec
Коммит
82c88e59cb
|
@ -648,28 +648,12 @@ bool BlockReflowState::CanPlaceFloat(
|
|||
// NS_UNCONSTRAINEDSIZE, we're dealing with an orthogonal block that
|
||||
// has block-size:auto, and we'll need to actually reflow it to find out
|
||||
// how much inline-size it will occupy in the containing block's mode.
|
||||
static nscoord FloatMarginISize(const ReflowInput& aCBReflowInput,
|
||||
nscoord aFloatAvailableISize, nsIFrame* aFloat,
|
||||
const SizeComputationInput& aFloatSizingInput) {
|
||||
AutoMaybeDisableFontInflation an(aFloat);
|
||||
WritingMode wm = aFloatSizingInput.GetWritingMode();
|
||||
|
||||
auto floatSize = aFloat->ComputeSize(
|
||||
aCBReflowInput.mRenderingContext, wm, aCBReflowInput.ComputedSize(wm),
|
||||
aFloatAvailableISize,
|
||||
aFloatSizingInput.ComputedLogicalMargin(wm).Size(wm),
|
||||
aFloatSizingInput.ComputedLogicalBorderPadding(wm).Size(wm), {},
|
||||
ComputeSizeFlag::ShrinkWrap);
|
||||
|
||||
WritingMode cbwm = aCBReflowInput.GetWritingMode();
|
||||
nscoord floatISize = floatSize.mLogicalSize.ConvertTo(cbwm, wm).ISize(cbwm);
|
||||
if (floatISize == NS_UNCONSTRAINEDSIZE) {
|
||||
static nscoord FloatMarginISize(WritingMode aCBWM,
|
||||
const ReflowInput& aFloatRI) {
|
||||
if (aFloatRI.ComputedSize(aCBWM).ISize(aCBWM) == NS_UNCONSTRAINEDSIZE) {
|
||||
return NS_UNCONSTRAINEDSIZE; // reflow is needed to get the true size
|
||||
}
|
||||
|
||||
return floatISize +
|
||||
aFloatSizingInput.ComputedLogicalMargin(cbwm).IStartEnd(cbwm) +
|
||||
aFloatSizingInput.ComputedLogicalBorderPadding(cbwm).IStartEnd(cbwm);
|
||||
return aFloatRI.ComputedSizeWithMarginBorderPadding(aCBWM).ISize(aCBWM);
|
||||
}
|
||||
|
||||
// A frame property that stores the last shape source / margin / etc. if there's
|
||||
|
@ -753,14 +737,12 @@ BlockReflowState::PlaceFloatResult BlockReflowState::FlowAndPlaceFloat(
|
|||
}
|
||||
|
||||
LogicalSize availSize = ComputeAvailableSizeForFloat();
|
||||
SizeComputationInput sizingInput(aFloat, mReflowInput.mRenderingContext, wm,
|
||||
mReflowInput.ComputedISize());
|
||||
const WritingMode floatWM = aFloat->GetWritingMode();
|
||||
Maybe<ReflowInput> floatRI(std::in_place, mPresContext, mReflowInput, aFloat,
|
||||
availSize.ConvertTo(floatWM, wm));
|
||||
|
||||
nscoord floatMarginISize =
|
||||
FloatMarginISize(mReflowInput, availSize.ISize(wm), aFloat, sizingInput);
|
||||
|
||||
LogicalMargin floatMargin(wm); // computed margin
|
||||
LogicalMargin floatOffsets(wm);
|
||||
nscoord floatMarginISize = FloatMarginISize(wm, *floatRI);
|
||||
LogicalMargin floatMargin = floatRI->ComputedLogicalMargin(wm);
|
||||
nsReflowStatus reflowStatus;
|
||||
|
||||
// If it's a floating first-letter, we need to reflow it before we
|
||||
|
@ -772,8 +754,8 @@ BlockReflowState::PlaceFloatResult BlockReflowState::FlowAndPlaceFloat(
|
|||
bool earlyFloatReflow =
|
||||
aFloat->IsLetterFrame() || floatMarginISize == NS_UNCONSTRAINEDSIZE;
|
||||
if (earlyFloatReflow) {
|
||||
mBlock->ReflowFloat(*this, availSize, aFloat, floatMargin, floatOffsets,
|
||||
false, reflowStatus);
|
||||
mBlock->ReflowFloat(*this, *floatRI, availSize, aFloat, false,
|
||||
reflowStatus);
|
||||
floatMarginISize = aFloat->ISize(wm) + floatMargin.IStartEnd(wm);
|
||||
NS_ASSERTION(reflowStatus.IsComplete(),
|
||||
"letter frames and orthogonal floats with auto block-size "
|
||||
|
@ -853,9 +835,16 @@ BlockReflowState::PlaceFloatResult BlockReflowState::FlowAndPlaceFloat(
|
|||
// Reflow the float after computing its vertical position so it knows
|
||||
// where to break.
|
||||
if (!earlyFloatReflow) {
|
||||
const LogicalSize oldAvailSize = availSize;
|
||||
availSize = ComputeAvailableSizeForFloat();
|
||||
if (oldAvailSize != availSize) {
|
||||
floatRI.reset();
|
||||
floatRI.emplace(mPresContext, mReflowInput, aFloat,
|
||||
availSize.ConvertTo(floatWM, wm));
|
||||
}
|
||||
bool pushedDown = mBCoord != restoreBCoord.SavedValue();
|
||||
mBlock->ReflowFloat(*this, ComputeAvailableSizeForFloat(), aFloat,
|
||||
floatMargin, floatOffsets, pushedDown, reflowStatus);
|
||||
mBlock->ReflowFloat(*this, *floatRI, availSize, aFloat, pushedDown,
|
||||
reflowStatus);
|
||||
}
|
||||
if (aFloat->GetPrevInFlow()) {
|
||||
floatMargin.BStart(wm) = 0;
|
||||
|
@ -892,6 +881,7 @@ BlockReflowState::PlaceFloatResult BlockReflowState::FlowAndPlaceFloat(
|
|||
floatMargin.BStart(wm) + floatPos.B(wm));
|
||||
|
||||
// If float is relatively positioned, factor that in as well
|
||||
const LogicalMargin floatOffsets = floatRI->ComputedLogicalOffsets(wm);
|
||||
ReflowInput::ApplyRelativePositioning(aFloat, wm, floatOffsets, &origin,
|
||||
ContainerSize());
|
||||
|
||||
|
|
|
@ -327,6 +327,12 @@ struct ReflowInput : public SizeComputationInput {
|
|||
return mComputedMaxSize.BSize(mWritingMode);
|
||||
}
|
||||
|
||||
// WARNING: In general, adjusting available inline-size or block-size is not
|
||||
// safe because ReflowInput has members whose values depend on the available
|
||||
// size passing through the constructor. For example,
|
||||
// CalculateBlockSideMargins() is called during initialization, and uses
|
||||
// AvailableSize(). Make sure your use case doesn't lead to stale member
|
||||
// values in ReflowInput!
|
||||
void SetAvailableISize(nscoord aAvailableISize) {
|
||||
mAvailableSize.ISize(mWritingMode) = aAvailableISize;
|
||||
}
|
||||
|
|
|
@ -6617,11 +6617,9 @@ const nsStyleText* nsBlockFrame::StyleTextForLineLayout() {
|
|||
return StyleText();
|
||||
}
|
||||
|
||||
void nsBlockFrame::ReflowFloat(BlockReflowState& aState,
|
||||
void nsBlockFrame::ReflowFloat(BlockReflowState& aState, ReflowInput& aFloatRI,
|
||||
const LogicalSize& aAvailableSize,
|
||||
nsIFrame* aFloat, LogicalMargin& aFloatMargin,
|
||||
LogicalMargin& aFloatOffsets,
|
||||
bool aFloatPushedDown,
|
||||
nsIFrame* aFloat, bool aFloatPushedDown,
|
||||
nsReflowStatus& aReflowStatus) {
|
||||
MOZ_ASSERT(aReflowStatus.IsEmpty(),
|
||||
"Caller should pass a fresh reflow status!");
|
||||
|
@ -6630,16 +6628,13 @@ void nsBlockFrame::ReflowFloat(BlockReflowState& aState,
|
|||
|
||||
WritingMode wm = aState.mReflowInput.GetWritingMode();
|
||||
|
||||
ReflowInput floatRS(aState.mPresContext, aState.mReflowInput, aFloat,
|
||||
aAvailableSize.ConvertTo(aFloat->GetWritingMode(), wm));
|
||||
|
||||
// Normally the mIsTopOfPage state is copied from the parent reflow
|
||||
// input. However, when reflowing a float, if we've placed other
|
||||
// floats that force this float *down* or *narrower*, we should unset
|
||||
// the mIsTopOfPage state.
|
||||
if (floatRS.mFlags.mIsTopOfPage &&
|
||||
if (aFloatRI.mFlags.mIsTopOfPage &&
|
||||
(aFloatPushedDown || aAvailableSize.ISize(wm) != aState.ContentISize())) {
|
||||
floatRS.mFlags.mIsTopOfPage = false;
|
||||
aFloatRI.mFlags.mIsTopOfPage = false;
|
||||
}
|
||||
|
||||
// Setup a block reflow context to reflow the float.
|
||||
|
@ -6649,14 +6644,14 @@ void nsBlockFrame::ReflowFloat(BlockReflowState& aState,
|
|||
do {
|
||||
nsCollapsingMargin margin;
|
||||
bool mayNeedRetry = false;
|
||||
floatRS.mDiscoveredClearance = nullptr;
|
||||
aFloatRI.mDiscoveredClearance = nullptr;
|
||||
// Only first in flow gets a block-start margin.
|
||||
if (!aFloat->GetPrevInFlow()) {
|
||||
brc.ComputeCollapsedBStartMargin(floatRS, &margin, clearanceFrame,
|
||||
brc.ComputeCollapsedBStartMargin(aFloatRI, &margin, clearanceFrame,
|
||||
&mayNeedRetry);
|
||||
|
||||
if (mayNeedRetry && !clearanceFrame) {
|
||||
floatRS.mDiscoveredClearance = &clearanceFrame;
|
||||
aFloatRI.mDiscoveredClearance = &clearanceFrame;
|
||||
// We don't need to push the float manager state because the the block
|
||||
// has its own float manager that will be destroyed and recreated
|
||||
}
|
||||
|
@ -6665,7 +6660,7 @@ void nsBlockFrame::ReflowFloat(BlockReflowState& aState,
|
|||
// When reflowing a float, aSpace argument doesn't matter because we pass
|
||||
// nullptr to aLine and we don't call nsBlockReflowContext::PlaceBlock()
|
||||
// later.
|
||||
brc.ReflowBlock(LogicalRect(wm), true, margin, 0, nullptr, floatRS,
|
||||
brc.ReflowBlock(LogicalRect(wm), true, margin, 0, nullptr, aFloatRI,
|
||||
aReflowStatus, aState);
|
||||
} while (clearanceFrame);
|
||||
|
||||
|
@ -6678,7 +6673,7 @@ void nsBlockFrame::ReflowFloat(BlockReflowState& aState,
|
|||
}
|
||||
}
|
||||
|
||||
if (!aReflowStatus.IsFullyComplete() && ShouldAvoidBreakInside(floatRS)) {
|
||||
if (!aReflowStatus.IsFullyComplete() && ShouldAvoidBreakInside(aFloatRI)) {
|
||||
aReflowStatus.SetInlineLineBreakBeforeAndReset();
|
||||
} else if (aReflowStatus.IsIncomplete() &&
|
||||
aAvailableSize.BSize(wm) == NS_UNCONSTRAINEDSIZE) {
|
||||
|
@ -6691,12 +6686,6 @@ void nsBlockFrame::ReflowFloat(BlockReflowState& aState,
|
|||
aState.mReflowStatus.SetNextInFlowNeedsReflow();
|
||||
}
|
||||
|
||||
// Capture the margin and offsets information for the caller
|
||||
aFloatMargin =
|
||||
// float margins don't collapse
|
||||
floatRS.ComputedLogicalMargin(wm);
|
||||
aFloatOffsets = floatRS.ComputedLogicalOffsets(wm);
|
||||
|
||||
const ReflowOutput& metrics = brc.GetMetrics();
|
||||
|
||||
// Set the rect, make sure the view is properly sized and positioned,
|
||||
|
@ -6712,9 +6701,7 @@ void nsBlockFrame::ReflowFloat(BlockReflowState& aState,
|
|||
aState.mPresContext, aFloat, aFloat->GetView(), metrics.InkOverflow(),
|
||||
ReflowChildFlags::NoMoveView);
|
||||
}
|
||||
// Pass floatRS so the frame hierarchy can be used (redoFloatRS has the same
|
||||
// hierarchy)
|
||||
aFloat->DidReflow(aState.mPresContext, &floatRS);
|
||||
aFloat->DidReflow(aState.mPresContext, &aFloatRI);
|
||||
}
|
||||
|
||||
StyleClear nsBlockFrame::FindTrailingClear() {
|
||||
|
|
|
@ -785,11 +785,9 @@ class nsBlockFrame : public nsContainerFrame {
|
|||
// floats.
|
||||
// @param aReflowStatus an incomplete status indicates the float should be
|
||||
// split but only if the available block-size is constrained.
|
||||
void ReflowFloat(BlockReflowState& aState,
|
||||
void ReflowFloat(BlockReflowState& aState, ReflowInput& aFloatRI,
|
||||
const mozilla::LogicalSize& aAvailableSize, nsIFrame* aFloat,
|
||||
mozilla::LogicalMargin& aFloatMargin,
|
||||
mozilla::LogicalMargin& aFloatOffsets, bool aFloatPushedDown,
|
||||
nsReflowStatus& aReflowStatus);
|
||||
bool aFloatPushedDown, nsReflowStatus& aReflowStatus);
|
||||
|
||||
//----------------------------------------
|
||||
// Methods for pushing/pulling lines/frames
|
||||
|
|
Загрузка…
Ссылка в новой задаче