Bug 1809568 - Part 2: Provide `GetNaturalBaselineBOffset` with baseline export context. r=emilio

Some baseline exports are context-sensitive. One example: In line-layout scenario,
the last baseline of a scroll container is always the margin-end. In other (e.g.
flex, grid) scenarios, it's the border-box clamped offset to the last line in the
container.
This enables the required 3 different behaviours for `inline-block` scroll containers
for 3 different `baseline-source` values:
- `auto`: Last baseline, margin-end
- `first`: Border-box clamped offset to the first line
- `last`: Border-box clamped offset to the last line

Differential Revision: https://phabricator.services.mozilla.com/D173886
This commit is contained in:
David Shin 2023-05-15 14:34:26 +00:00
Родитель 40fa43a69d
Коммит c4f2c2237b
40 изменённых файлов: 204 добавлений и 120 удалений

Просмотреть файл

@ -19,6 +19,12 @@ enum class BaselineSharingGroup : uint8_t {
Last = 1,
};
// Layout context under which the baseline is being exported to.
enum class BaselineExportContext : uint8_t {
LineLayout = 0,
Other = 1,
};
class Baseline {
public:
/**

Просмотреть файл

@ -5963,8 +5963,8 @@ bool nsLayoutUtils::GetLastLineBaseline(WritingMode aWM, const nsIFrame* aFrame,
// `ColumnSetWrapperFrame` level, but this keeps it symmetric to
// `GetFirstLinePosition`.
if (aFrame->IsColumnSetFrame()) {
const auto baseline =
aFrame->GetNaturalBaselineBOffset(aWM, BaselineSharingGroup::Last);
const auto baseline = aFrame->GetNaturalBaselineBOffset(
aWM, BaselineSharingGroup::Last, BaselineExportContext::Other);
if (!baseline) {
return false;
}

Просмотреть файл

@ -86,7 +86,8 @@ LogicalSize nsCheckboxRadioFrame::ComputeAutoSize(
}
Maybe<nscoord> nsCheckboxRadioFrame::GetNaturalBaselineBOffset(
WritingMode aWM, BaselineSharingGroup aBaselineGroup) const {
WritingMode aWM, BaselineSharingGroup aBaselineGroup,
BaselineExportContext) const {
NS_ASSERTION(!IsSubtreeDirty(), "frame must not be dirty");
if (aBaselineGroup == BaselineSharingGroup::Last) {

Просмотреть файл

@ -62,8 +62,8 @@ class nsCheckboxRadioFrame final : public nsAtomicContainerFrame,
nsEventStatus* aEventStatus) override;
Maybe<nscoord> GetNaturalBaselineBOffset(
mozilla::WritingMode aWM,
BaselineSharingGroup aBaselineGroup) const override;
mozilla::WritingMode aWM, BaselineSharingGroup aBaselineGroup,
BaselineExportContext) const override;
/**
* Respond to the request to resize and/or reflow

Просмотреть файл

@ -65,7 +65,8 @@ nscoord nsDateTimeControlFrame::GetPrefISize(gfxContext* aRenderingContext) {
}
Maybe<nscoord> nsDateTimeControlFrame::GetNaturalBaselineBOffset(
WritingMode aWM, BaselineSharingGroup aBaselineGroup) const {
WritingMode aWM, BaselineSharingGroup aBaselineGroup,
BaselineExportContext) const {
return nsTextControlFrame::GetSingleLineTextControlBaseline(
this, mFirstBaseline, aWM, aBaselineGroup);
}

Просмотреть файл

@ -62,8 +62,8 @@ class nsDateTimeControlFrame final : public nsContainerFrame {
nsReflowStatus& aStatus) override;
Maybe<nscoord> GetNaturalBaselineBOffset(
mozilla::WritingMode aWM,
BaselineSharingGroup aBaselineGroup) const override;
mozilla::WritingMode aWM, BaselineSharingGroup aBaselineGroup,
BaselineExportContext) const override;
nscoord mFirstBaseline = NS_INTRINSIC_ISIZE_UNKNOWN;
};

Просмотреть файл

@ -851,7 +851,8 @@ nscoord nsFieldSetFrame::SynthesizeFallbackBaseline(
}
Maybe<nscoord> nsFieldSetFrame::GetNaturalBaselineBOffset(
WritingMode aWM, BaselineSharingGroup aBaselineGroup) const {
WritingMode aWM, BaselineSharingGroup aBaselineGroup,
BaselineExportContext aExportContext) const {
if (StyleDisplay()->IsContainLayout()) {
// If we are layout-contained, our child 'inner' should not
// affect how we calculate our baseline.
@ -862,7 +863,8 @@ Maybe<nscoord> nsFieldSetFrame::GetNaturalBaselineBOffset(
return Nothing{};
}
MOZ_ASSERT(!inner->GetWritingMode().IsOrthogonalTo(aWM));
const auto result = inner->GetNaturalBaselineBOffset(aWM, aBaselineGroup);
const auto result =
inner->GetNaturalBaselineBOffset(aWM, aBaselineGroup, aExportContext);
if (!result) {
return Nothing{};
}

Просмотреть файл

@ -41,8 +41,8 @@ class nsFieldSetFrame final : public nsContainerFrame {
BaselineSharingGroup aBaselineGroup) const override;
BaselineSharingGroup GetDefaultBaselineSharingGroup() const override;
Maybe<nscoord> GetNaturalBaselineBOffset(
mozilla::WritingMode aWM,
BaselineSharingGroup aBaselineGroup) const override;
mozilla::WritingMode aWM, BaselineSharingGroup aBaselineGroup,
BaselineExportContext aExportContext) const override;
virtual void BuildDisplayList(nsDisplayListBuilder* aBuilder,
const nsDisplayListSet& aLists) override;

Просмотреть файл

@ -313,7 +313,8 @@ void nsHTMLButtonControlFrame::ReflowButtonContents(
}
Maybe<nscoord> nsHTMLButtonControlFrame::GetNaturalBaselineBOffset(
WritingMode aWM, BaselineSharingGroup aBaselineGroup) const {
WritingMode aWM, BaselineSharingGroup aBaselineGroup,
BaselineExportContext aExportContext) const {
if (StyleDisplay()->IsContainLayout()) {
return Nothing{};
}
@ -322,11 +323,12 @@ Maybe<nscoord> nsHTMLButtonControlFrame::GetNaturalBaselineBOffset(
if (MOZ_UNLIKELY(inner->GetWritingMode().IsOrthogonalTo(aWM))) {
return Nothing{};
}
auto result = inner->GetNaturalBaselineBOffset(aWM, aBaselineGroup)
.valueOrFrom([inner, aWM, aBaselineGroup]() {
return Baseline::SynthesizeBOffsetFromBorderBox(
inner, aWM, aBaselineGroup);
});
auto result =
inner->GetNaturalBaselineBOffset(aWM, aBaselineGroup, aExportContext)
.valueOrFrom([inner, aWM, aBaselineGroup]() {
return Baseline::SynthesizeBOffsetFromBorderBox(inner, aWM,
aBaselineGroup);
});
nscoord innerBStart = inner->BStart(aWM, GetSize());
if (aBaselineGroup == BaselineSharingGroup::First) {

Просмотреть файл

@ -39,8 +39,8 @@ class nsHTMLButtonControlFrame : public nsContainerFrame,
nsReflowStatus& aStatus) override;
Maybe<nscoord> GetNaturalBaselineBOffset(
mozilla::WritingMode aWM,
BaselineSharingGroup aBaselineGroup) const override;
mozilla::WritingMode aWM, BaselineSharingGroup aBaselineGroup,
BaselineExportContext aExportContext) const override;
virtual nsresult HandleEvent(nsPresContext* aPresContext,
mozilla::WidgetGUIEvent* aEvent,

Просмотреть файл

@ -71,7 +71,8 @@ nsListControlFrame::nsListControlFrame(ComputedStyle* aStyle,
nsListControlFrame::~nsListControlFrame() = default;
Maybe<nscoord> nsListControlFrame::GetNaturalBaselineBOffset(
WritingMode aWM, BaselineSharingGroup aBaselineGroup) const {
WritingMode aWM, BaselineSharingGroup aBaselineGroup,
BaselineExportContext) const {
// Unlike scroll frames which we inherit from, we don't export a baseline.
return Nothing{};
}

Просмотреть файл

@ -56,8 +56,8 @@ class nsListControlFrame final : public nsHTMLScrollFrame,
NS_DECL_FRAMEARENA_HELPERS(nsListControlFrame)
Maybe<nscoord> GetNaturalBaselineBOffset(
mozilla::WritingMode aWM,
BaselineSharingGroup aBaselineGroup) const override;
mozilla::WritingMode aWM, BaselineSharingGroup aBaselineGroup,
BaselineExportContext) const override;
// nsIFrame
nsresult HandleEvent(nsPresContext* aPresContext,

Просмотреть файл

@ -78,8 +78,8 @@ class nsTextControlFrame : public nsContainerFrame,
nsReflowStatus& aStatus) override;
Maybe<nscoord> GetNaturalBaselineBOffset(
mozilla::WritingMode aWM,
BaselineSharingGroup aBaselineGroup) const override {
mozilla::WritingMode aWM, BaselineSharingGroup aBaselineGroup,
BaselineExportContext) const override {
if (!IsSingleLineTextControl()) {
return Nothing{};
}

Просмотреть файл

@ -60,7 +60,8 @@ class BRFrame final : public nsIFrame {
nscoord GetPrefISize(gfxContext* aRenderingContext) override;
Maybe<nscoord> GetNaturalBaselineBOffset(
WritingMode aWM, BaselineSharingGroup aBaselineGroup) const override;
WritingMode aWM, BaselineSharingGroup aBaselineGroup,
BaselineExportContext) const override;
bool IsFrameOfType(uint32_t aFlags) const override {
return nsIFrame::IsFrameOfType(
@ -203,7 +204,8 @@ nscoord BRFrame::GetPrefISize(gfxContext* aRenderingContext) {
}
Maybe<nscoord> BRFrame::GetNaturalBaselineBOffset(
WritingMode aWM, BaselineSharingGroup aBaselineGroup) const {
WritingMode aWM, BaselineSharingGroup aBaselineGroup,
BaselineExportContext) const {
if (aBaselineGroup == BaselineSharingGroup::Last) {
return Nothing{};
}

Просмотреть файл

@ -235,7 +235,8 @@ nscoord ColumnSetWrapperFrame::GetPrefISize(gfxContext* aRenderingContext) {
template <typename Iterator>
Maybe<nscoord> ColumnSetWrapperFrame::GetBaselineBOffset(
Iterator aStart, Iterator aEnd, WritingMode aWM,
BaselineSharingGroup aBaselineGroup) const {
BaselineSharingGroup aBaselineGroup,
BaselineExportContext aExportContext) const {
// Either forward iterator + first baseline, or reverse iterator + last
// baseline
MOZ_ASSERT((*aStart == PrincipalChildList().FirstChild() &&
@ -251,7 +252,8 @@ Maybe<nscoord> ColumnSetWrapperFrame::GetBaselineBOffset(
// baseline.
for (auto itr = aStart; itr != aEnd; ++itr) {
const nsIFrame* kid = *itr;
auto kidBaseline = kid->GetNaturalBaselineBOffset(aWM, aBaselineGroup);
auto kidBaseline =
kid->GetNaturalBaselineBOffset(aWM, aBaselineGroup, aExportContext);
if (!kidBaseline) {
continue;
}
@ -270,13 +272,16 @@ Maybe<nscoord> ColumnSetWrapperFrame::GetBaselineBOffset(
}
Maybe<nscoord> ColumnSetWrapperFrame::GetNaturalBaselineBOffset(
WritingMode aWM, BaselineSharingGroup aBaselineGroup) const {
WritingMode aWM, BaselineSharingGroup aBaselineGroup,
BaselineExportContext aExportContext) const {
if (aBaselineGroup == BaselineSharingGroup::First) {
return GetBaselineBOffset(PrincipalChildList().cbegin(),
PrincipalChildList().cend(), aWM, aBaselineGroup);
PrincipalChildList().cend(), aWM, aBaselineGroup,
aExportContext);
}
return GetBaselineBOffset(PrincipalChildList().crbegin(),
PrincipalChildList().crend(), aWM, aBaselineGroup);
PrincipalChildList().crend(), aWM, aBaselineGroup,
aExportContext);
}
#ifdef DEBUG

Просмотреть файл

@ -60,7 +60,8 @@ class ColumnSetWrapperFrame final : public nsBlockFrame {
nscoord GetPrefISize(gfxContext* aRenderingContext) override;
Maybe<nscoord> GetNaturalBaselineBOffset(
WritingMode aWM, BaselineSharingGroup aBaselineGroup) const override;
WritingMode aWM, BaselineSharingGroup aBaselineGroup,
BaselineExportContext aExportContext) const override;
private:
explicit ColumnSetWrapperFrame(ComputedStyle* aStyle,
@ -78,7 +79,8 @@ class ColumnSetWrapperFrame final : public nsBlockFrame {
template <typename Iterator>
Maybe<nscoord> GetBaselineBOffset(Iterator aStart, Iterator aEnd,
WritingMode aWM,
BaselineSharingGroup aBaselineGroup) const;
BaselineSharingGroup aBaselineGroup,
BaselineExportContext aExportContext) const;
};
} // namespace mozilla

Просмотреть файл

@ -603,54 +603,76 @@ nscoord nsBlockFrame::SynthesizeFallbackBaseline(
return Baseline::SynthesizeBOffsetFromMarginBox(this, aWM, aBaselineGroup);
}
template <typename LineIteratorType>
Maybe<nscoord> nsBlockFrame::GetBaselineBOffset(
LineIteratorType aStart, LineIteratorType aEnd, WritingMode aWM,
BaselineSharingGroup aBaselineGroup,
BaselineExportContext aExportContext) const {
MOZ_ASSERT((std::is_same_v<LineIteratorType, ConstLineIterator> &&
aBaselineGroup == BaselineSharingGroup::First) ||
(std::is_same_v<LineIteratorType, ConstReverseLineIterator> &&
aBaselineGroup == BaselineSharingGroup::Last),
"Iterator direction must match baseline sharing group.");
for (auto line = aStart; line != aEnd; ++line) {
if (!line->IsBlock()) {
// XXX Is this the right test? We have some bogus empty lines
// floating around, but IsEmpty is perhaps too weak.
if (line->BSize() != 0 || !line->IsEmpty()) {
const auto ascent = line->BStart() + line->GetLogicalAscent();
if (aBaselineGroup == BaselineSharingGroup::Last) {
return Some(BSize(aWM) - ascent);
}
return Some(ascent);
}
continue;
}
nsIFrame* kid = line->mFirstChild;
if (aWM.IsOrthogonalTo(kid->GetWritingMode())) {
continue;
}
if (aExportContext == BaselineExportContext::LineLayout &&
kid->IsTableWrapperFrame()) {
// `<table>` in inline-block context does not export any baseline.
continue;
}
const auto kidBaselineGroup =
aExportContext == BaselineExportContext::LineLayout
? kid->GetDefaultBaselineSharingGroup()
: aBaselineGroup;
const auto kidBaseline =
kid->GetNaturalBaselineBOffset(aWM, kidBaselineGroup, aExportContext);
if (!kidBaseline) {
continue;
}
auto result = *kidBaseline;
if (kidBaselineGroup == BaselineSharingGroup::Last) {
result = kid->BSize(aWM) - result;
}
// Ignore relative positioning for baseline calculations.
const nsSize& sz = line->mContainerSize;
result += kid->GetLogicalNormalPosition(aWM, sz).B(aWM);
if (aBaselineGroup == BaselineSharingGroup::Last) {
return Some(BSize(aWM) - result);
}
return Some(result);
}
return Nothing{};
}
Maybe<nscoord> nsBlockFrame::GetNaturalBaselineBOffset(
WritingMode aWM, BaselineSharingGroup aBaselineGroup) const {
WritingMode aWM, BaselineSharingGroup aBaselineGroup,
BaselineExportContext aExportContext) const {
if (StyleDisplay()->IsContainLayout()) {
return Nothing{};
}
if (aBaselineGroup == BaselineSharingGroup::First) {
nscoord result;
if (!nsLayoutUtils::GetFirstLineBaseline(aWM, this, &result)) {
return Nothing{};
}
return Some(result);
return GetBaselineBOffset(LinesBegin(), LinesEnd(), aWM, aBaselineGroup,
aExportContext);
}
for (ConstReverseLineIterator line = LinesRBegin(), line_end = LinesREnd();
line != line_end; ++line) {
if (line->IsBlock()) {
nsIFrame* kid = line->mFirstChild;
if (aWM.IsOrthogonalTo(kid->GetWritingMode())) {
continue;
}
if (kid->IsTableWrapperFrame()) {
// `<table>` in block display context does not export any baseline.
continue;
}
const auto kidBaselineGroup = kid->GetDefaultBaselineSharingGroup();
const auto kidBaseline =
kid->GetNaturalBaselineBOffset(aWM, kidBaselineGroup);
if (!kidBaseline) {
continue;
}
auto result = *kidBaseline;
if (kidBaselineGroup == BaselineSharingGroup::Last) {
result = kid->BSize(aWM) - result;
}
// Ignore relative positioning for baseline calculations.
const nsSize& sz = line->mContainerSize;
result += kid->GetLogicalNormalPosition(aWM, sz).B(aWM);
return Some(BSize(aWM) - result);
} else {
// XXX Is this the right test? We have some bogus empty lines
// floating around, but IsEmpty is perhaps too weak.
if (line->BSize() != 0 || !line->IsEmpty()) {
return Some(BSize(aWM) - (line->BStart() + line->GetLogicalAscent()));
}
}
}
return Nothing{};
return GetBaselineBOffset(LinesRBegin(), LinesREnd(), aWM, aBaselineGroup,
aExportContext);
}
nscoord nsBlockFrame::GetCaretBaseline() const {
@ -1570,7 +1592,8 @@ void nsBlockFrame::Reflow(nsPresContext* aPresContext, ReflowOutput& aMetrics,
const auto baselineGroup = BaselineSharingGroup::First;
Maybe<nscoord> result;
if (MOZ_LIKELY(!wm.IsOrthogonalTo(marker->GetWritingMode()))) {
result = marker->GetNaturalBaselineBOffset(wm, baselineGroup);
result = marker->GetNaturalBaselineBOffset(
wm, baselineGroup, BaselineExportContext::LineLayout);
}
const auto markerBaseline = result.valueOrFrom([bbox, wm, marker]() {
return bbox.BSize(wm) + marker->GetLogicalUsedMargin(wm).BEnd(wm);

Просмотреть файл

@ -133,8 +133,8 @@ class nsBlockFrame : public nsContainerFrame {
return BaselineSharingGroup::Last;
}
Maybe<nscoord> GetNaturalBaselineBOffset(
mozilla::WritingMode aWM,
BaselineSharingGroup aBaselineGroup) const override;
mozilla::WritingMode aWM, BaselineSharingGroup aBaselineGroup,
BaselineExportContext aExportContext) const override;
nscoord GetCaretBaseline() const override;
void DestroyFrom(nsIFrame* aDestructRoot,
PostDestroyData& aPostDestroyData) override;
@ -276,6 +276,13 @@ class nsBlockFrame : public nsContainerFrame {
private:
void CheckIntrinsicCacheAgainstShrinkWrapState();
template <typename LineIteratorType>
Maybe<nscoord> GetBaselineBOffset(LineIteratorType aStart,
LineIteratorType aEnd,
mozilla::WritingMode aWM,
BaselineSharingGroup aBaselineGroup,
BaselineExportContext aExportContext) const;
public:
nscoord GetMinISize(gfxContext* aRenderingContext) override;
nscoord GetPrefISize(gfxContext* aRenderingContext) override;

Просмотреть файл

@ -1298,10 +1298,12 @@ void nsColumnSetFrame::AppendDirectlyOwnedAnonBoxes(
}
Maybe<nscoord> nsColumnSetFrame::GetNaturalBaselineBOffset(
WritingMode aWM, BaselineSharingGroup aBaselineGroup) const {
WritingMode aWM, BaselineSharingGroup aBaselineGroup,
BaselineExportContext aExportContext) const {
Maybe<nscoord> result;
for (const auto* kid : mFrames) {
auto kidBaseline = kid->GetNaturalBaselineBOffset(aWM, aBaselineGroup);
auto kidBaseline =
kid->GetNaturalBaselineBOffset(aWM, aBaselineGroup, aExportContext);
if (!kidBaseline) {
continue;
}

Просмотреть файл

@ -75,8 +75,8 @@ class nsColumnSetFrame final : public nsContainerFrame {
const nsPoint& aPt);
Maybe<nscoord> GetNaturalBaselineBOffset(
mozilla::WritingMode aWM,
BaselineSharingGroup aBaselineGroup) const override;
mozilla::WritingMode aWM, BaselineSharingGroup aBaselineGroup,
BaselineExportContext aExportContext) const override;
protected:
nscoord mLastBalanceBSize;

Просмотреть файл

@ -426,7 +426,8 @@ void nsFirstLetterFrame::DrainOverflowFrames(nsPresContext* aPresContext) {
}
Maybe<nscoord> nsFirstLetterFrame::GetNaturalBaselineBOffset(
WritingMode aWM, BaselineSharingGroup aBaselineGroup) const {
WritingMode aWM, BaselineSharingGroup aBaselineGroup,
BaselineExportContext) const {
if (aBaselineGroup == BaselineSharingGroup::Last) {
return Nothing{};
}

Просмотреть файл

@ -61,8 +61,8 @@ class nsFirstLetterFrame final : public nsContainerFrame {
virtual bool CanContinueTextRun() const override;
Maybe<nscoord> GetNaturalBaselineBOffset(
mozilla::WritingMode aWM,
BaselineSharingGroup aBaselineGroup) const override;
mozilla::WritingMode aWM, BaselineSharingGroup aBaselineGroup,
BaselineExportContext) const override;
virtual LogicalSides GetLogicalSkipSides() const override;
// override of nsFrame method

Просмотреть файл

@ -416,7 +416,8 @@ class nsFlexContainerFrame::FlexItem final {
// If the nsLayoutUtils getter fails, then ask the frame directly:
auto baselineGroup = aUseFirstBaseline ? BaselineSharingGroup::First
: BaselineSharingGroup::Last;
if (auto baseline = mFrame->GetNaturalBaselineBOffset(mWM, baselineGroup)) {
if (auto baseline = mFrame->GetNaturalBaselineBOffset(
mWM, baselineGroup, BaselineExportContext::Other)) {
// Offset for last baseline from `GetNaturalBaselineBOffset` originates
// from the frame's block end, so convert it back.
mAscent = baselineGroup == BaselineSharingGroup::First
@ -4636,7 +4637,8 @@ void nsFlexContainerFrame::Reflow(nsPresContext* aPresContext,
}
Maybe<nscoord> nsFlexContainerFrame::GetNaturalBaselineBOffset(
WritingMode aWM, BaselineSharingGroup aBaselineGroup) const {
WritingMode aWM, BaselineSharingGroup aBaselineGroup,
BaselineExportContext) const {
if (StyleDisplay()->IsContainLayout() ||
HasAnyStateBits(NS_STATE_FLEX_SYNTHESIZE_BASELINE)) {
return Nothing{};

Просмотреть файл

@ -166,8 +166,8 @@ class nsFlexContainerFrame final : public nsContainerFrame,
#endif
Maybe<nscoord> GetNaturalBaselineBOffset(
mozilla::WritingMode aWM,
BaselineSharingGroup aBaselineGroup) const override;
mozilla::WritingMode aWM, BaselineSharingGroup aBaselineGroup,
BaselineExportContext) const override;
// Unions the child overflow from our in-flow children.
void UnionInFlowChildOverflow(mozilla::OverflowAreas&);

Просмотреть файл

@ -1421,7 +1421,8 @@ nscoord nsHTMLScrollFrame::SynthesizeFallbackBaseline(
}
Maybe<nscoord> nsHTMLScrollFrame::GetNaturalBaselineBOffset(
WritingMode aWM, BaselineSharingGroup aBaselineGroup) const {
WritingMode aWM, BaselineSharingGroup aBaselineGroup,
BaselineExportContext aExportContext) const {
// Block containers that are scrollable always have a last baseline
// that are synthesized from block-end margin edge.
// Note(dshin): This behaviour is really only relevant to `inline-block`
@ -1429,7 +1430,8 @@ Maybe<nscoord> nsHTMLScrollFrame::GetNaturalBaselineBOffset(
// baselines are calculated through `GetFirstLineBaseline`, which does
// calculations of its own.
// https://drafts.csswg.org/css-align/#baseline-export
if (aBaselineGroup == BaselineSharingGroup::Last &&
if (aExportContext == BaselineExportContext::LineLayout &&
aBaselineGroup == BaselineSharingGroup::Last &&
mScrolledFrame->IsBlockFrameOrSubclass()) {
return Some(SynthesizeFallbackBaseline(aWM, aBaselineGroup));
}
@ -1439,7 +1441,8 @@ Maybe<nscoord> nsHTMLScrollFrame::GetNaturalBaselineBOffset(
}
// OK, here's where we defer to our scrolled frame.
return mScrolledFrame->GetNaturalBaselineBOffset(aWM, aBaselineGroup)
return mScrolledFrame
->GetNaturalBaselineBOffset(aWM, aBaselineGroup, aExportContext)
.map([this, aWM](nscoord aBaseline) {
// We have to add our border BStart thickness to whatever it returns, to
// produce an offset in our frame-rect's coordinate system. (We don't

Просмотреть файл

@ -130,8 +130,8 @@ class nsHTMLScrollFrame : public nsContainerFrame,
mozilla::WritingMode aWM,
BaselineSharingGroup aBaselineGroup) const override;
Maybe<nscoord> GetNaturalBaselineBOffset(
mozilla::WritingMode aWM,
BaselineSharingGroup aBaselineGroup) const override;
mozilla::WritingMode aWM, BaselineSharingGroup aBaselineGroup,
BaselineExportContext aExportContext) const override;
// Recomputes the scrollable overflow area we store in the helper to take
// children that are affected by perpsective set on the outer frame and scroll

Просмотреть файл

@ -9568,7 +9568,9 @@ nscoord nsGridContainerFrame::SynthesizeBaseline(
baseline = isOrthogonal ? grid->GetIBaseline(aGroup)
: grid->GetBBaseline(aGroup);
} else if (!isOrthogonal && aGridOrderItem.mIsInEdgeTrack) {
baseline = child->GetNaturalBaselineBOffset(childWM, aGroup)
baseline = child
->GetNaturalBaselineBOffset(childWM, aGroup,
BaselineExportContext::Other)
.valueOrFrom([aGroup, child, childWM]() {
return Baseline::SynthesizeBOffsetFromBorderBox(
child, childWM, aGroup);

Просмотреть файл

@ -131,8 +131,8 @@ class nsGridContainerFrame final : public nsContainerFrame,
const nsDisplayListSet& aLists) override;
Maybe<nscoord> GetNaturalBaselineBOffset(
mozilla::WritingMode aWM,
BaselineSharingGroup aBaselineGroup) const override {
mozilla::WritingMode aWM, BaselineSharingGroup aBaselineGroup,
BaselineExportContext) const override {
if (StyleDisplay()->IsContainLayout() ||
HasAnyStateBits(NS_STATE_GRID_SYNTHESIZE_BASELINE)) {
return Nothing{};

Просмотреть файл

@ -2086,13 +2086,15 @@ nscoord nsIFrame::SynthesizeFallbackBaseline(
}
nscoord nsIFrame::GetLogicalBaseline(WritingMode aWM) const {
return GetLogicalBaseline(aWM, GetDefaultBaselineSharingGroup());
return GetLogicalBaseline(aWM, GetDefaultBaselineSharingGroup(),
BaselineExportContext::LineLayout);
}
nscoord nsIFrame::GetLogicalBaseline(
WritingMode aWM, BaselineSharingGroup aBaselineGroup) const {
WritingMode aWM, BaselineSharingGroup aBaselineGroup,
BaselineExportContext aExportContext) const {
const auto result =
GetNaturalBaselineBOffset(aWM, aBaselineGroup)
GetNaturalBaselineBOffset(aWM, aBaselineGroup, aExportContext)
.valueOrFrom([this, aWM, aBaselineGroup]() {
return SynthesizeFallbackBaseline(aWM, aBaselineGroup);
});

Просмотреть файл

@ -519,6 +519,7 @@ class nsIFrame : public nsQueryFrame {
public:
using AlignmentContext = mozilla::AlignmentContext;
using BaselineSharingGroup = mozilla::BaselineSharingGroup;
using BaselineExportContext = mozilla::BaselineExportContext;
template <typename T>
using Maybe = mozilla::Maybe<T>;
template <typename T, typename E>
@ -1528,14 +1529,19 @@ class nsIFrame : public nsQueryFrame {
/**
* `GetNaturalBaselineBOffset`, but determines the baseline sharing group
* through `GetDefaultBaselineSharingGroup` (If not specified), and never
* fails, returning a synthesized baseline through
* through `GetDefaultBaselineSharingGroup` (If not specified), assuming line
* layout context, and never fails, returning a synthesized baseline through
* `SynthesizeFallbackBaseline`. Unlike `GetNaturalBaselineBOffset`, Result is
* always relative to the block start of the frame.
*/
nscoord GetLogicalBaseline(mozilla::WritingMode aWM) const;
/**
* Same as the above, but with baseline sharing group & export
* context specified.
*/
nscoord GetLogicalBaseline(mozilla::WritingMode aWM,
BaselineSharingGroup aBaselineGroup) const;
BaselineSharingGroup aBaselineGroup,
BaselineExportContext aExportContext) const;
/**
* Return true if the frame has a first(last) inline-axis baseline per
@ -1543,14 +1549,21 @@ class nsIFrame : public nsQueryFrame {
* the relevant block-axis border-box edge (Start for
* BaselineSharingGroup::First, end for BaselineSharingGroup::Last), where
* a positive value points towards the content-box.
* Some frames can export different baselines depending if it's in a line
* layout context or any other context (e.g. Flex, grid).
* https://drafts.csswg.org/css-align-3/#baseline-export
* @note The returned value is only valid when reflow is not needed.
* @note You should only call this on frames with a WM that's parallel to aWM.
* @note We're approaching `nsLayoutUtils::Get(First|Last)LineBaseline` ==
* `GetNaturalBaselineBOffset(aWM, (First|Last), Other)`. Grid relies on
* baseline synthesis behaviour in `nsLayoutUtils` implementations (bug
* 1609403), which blocks its removal.
* @param aWM the writing-mode of the alignment context.
* @return the baseline offset, if one exists
*/
virtual Maybe<nscoord> GetNaturalBaselineBOffset(
mozilla::WritingMode aWM, BaselineSharingGroup aBaselineGroup) const {
mozilla::WritingMode aWM, BaselineSharingGroup aBaselineGroup,
BaselineExportContext aExportContext) const {
return Nothing{};
}
@ -1657,7 +1670,8 @@ class nsIFrame : public nsQueryFrame {
public:
/**
* Get the suitable baseline sharing group for this element.
* Get the suitable baseline sharing group for this element, assuming line
* layout.
*/
virtual BaselineSharingGroup GetDefaultBaselineSharingGroup() const {
return BaselineSharingGroup::First;

Просмотреть файл

@ -841,7 +841,8 @@ LogicalSides nsInlineFrame::GetLogicalSkipSides() const {
}
Maybe<nscoord> nsInlineFrame::GetNaturalBaselineBOffset(
WritingMode aWM, BaselineSharingGroup aBaselineGroup) const {
WritingMode aWM, BaselineSharingGroup aBaselineGroup,
BaselineExportContext) const {
if (aBaselineGroup == BaselineSharingGroup::Last) {
return Nothing{};
}

Просмотреть файл

@ -97,8 +97,8 @@ class nsInlineFrame : public nsContainerFrame {
virtual void PullOverflowsFromPrevInFlow() override;
Maybe<nscoord> GetNaturalBaselineBOffset(
mozilla::WritingMode aWM,
BaselineSharingGroup aBaselineGroup) const override;
mozilla::WritingMode aWM, BaselineSharingGroup aBaselineGroup,
BaselineExportContext) const override;
virtual bool DrainSelfOverflowList() override;
/**

Просмотреть файл

@ -262,7 +262,8 @@ nsIFrame::SizeComputationResult nsRubyBaseContainerFrame::ComputeSize(
}
Maybe<nscoord> nsRubyBaseContainerFrame::GetNaturalBaselineBOffset(
WritingMode aWM, BaselineSharingGroup aBaselineGroup) const {
WritingMode aWM, BaselineSharingGroup aBaselineGroup,
BaselineExportContext) const {
if (aBaselineGroup == BaselineSharingGroup::Last) {
return Nothing{};
}

Просмотреть файл

@ -47,8 +47,8 @@ class nsRubyBaseContainerFrame final : public nsContainerFrame {
nsReflowStatus& aStatus) override;
Maybe<nscoord> GetNaturalBaselineBOffset(
mozilla::WritingMode aWM,
BaselineSharingGroup aBaselineGroup) const override;
mozilla::WritingMode aWM, BaselineSharingGroup aBaselineGroup,
BaselineExportContext) const override;
#ifdef DEBUG_FRAME_DUMP
virtual nsresult GetFrameName(nsAString& aResult) const override;

Просмотреть файл

@ -10058,7 +10058,8 @@ bool nsTextFrame::IsAtEndOfLine() const {
}
Maybe<nscoord> nsTextFrame::GetNaturalBaselineBOffset(
WritingMode aWM, BaselineSharingGroup aBaselineGroup) const {
WritingMode aWM, BaselineSharingGroup aBaselineGroup,
BaselineExportContext) const {
if (aBaselineGroup == BaselineSharingGroup::Last) {
return Nothing{};
}

Просмотреть файл

@ -367,8 +367,8 @@ class nsTextFrame : public nsIFrame {
bool IsEmpty() final;
bool IsSelfEmpty() final { return IsEmpty(); }
Maybe<nscoord> GetNaturalBaselineBOffset(
mozilla::WritingMode aWM,
BaselineSharingGroup aBaselineGroup) const override;
mozilla::WritingMode aWM, BaselineSharingGroup aBaselineGroup,
BaselineExportContext) const override;
bool HasSignificantTerminalNewline() const final;

Просмотреть файл

@ -3541,7 +3541,8 @@ nscoord nsTableFrame::SynthesizeFallbackBaseline(
/* virtual */
Maybe<nscoord> nsTableFrame::GetNaturalBaselineBOffset(
WritingMode aWM, BaselineSharingGroup aBaselineGroup) const {
WritingMode aWM, BaselineSharingGroup aBaselineGroup,
BaselineExportContext) const {
if (StyleDisplay()->IsContainLayout()) {
return Nothing{};
}

Просмотреть файл

@ -439,8 +439,8 @@ class nsTableFrame : public nsContainerFrame {
mozilla::WritingMode aWM,
BaselineSharingGroup aBaselineGroup) const override;
Maybe<nscoord> GetNaturalBaselineBOffset(
mozilla::WritingMode aWM,
BaselineSharingGroup aBaselineGroup) const override;
mozilla::WritingMode aWM, BaselineSharingGroup aBaselineGroup,
BaselineExportContext) const override;
/** return the row span of a cell, taking into account row span magic at the
* bottom of a table. The row span equals the number of rows spanned by aCell

Просмотреть файл

@ -41,7 +41,8 @@ nscoord nsTableWrapperFrame::SynthesizeFallbackBaseline(
}
Maybe<nscoord> nsTableWrapperFrame::GetNaturalBaselineBOffset(
WritingMode aWM, BaselineSharingGroup aBaselineGroup) const {
WritingMode aWM, BaselineSharingGroup aBaselineGroup,
BaselineExportContext aExportContext) const {
// Baseline is determined by row
// (https://drafts.csswg.org/css-align-3/#baseline-export). If the row
// direction is going to be orthogonal to the parent's writing mode, the
@ -52,7 +53,8 @@ Maybe<nscoord> nsTableWrapperFrame::GetNaturalBaselineBOffset(
return Nothing{};
}
auto* innerTable = InnerTableFrame();
return innerTable->GetNaturalBaselineBOffset(aWM, aBaselineGroup)
return innerTable
->GetNaturalBaselineBOffset(aWM, aBaselineGroup, aExportContext)
.map([this, aWM, aBaselineGroup, innerTable](nscoord aBaseline) {
auto bStart = innerTable->BStart(aWM, mRect.Size());
if (aBaselineGroup == BaselineSharingGroup::First) {

Просмотреть файл

@ -68,8 +68,8 @@ class nsTableWrapperFrame : public nsContainerFrame {
mozilla::WritingMode aWM,
BaselineSharingGroup aBaselineGroup) const override;
Maybe<nscoord> GetNaturalBaselineBOffset(
mozilla::WritingMode aWM,
BaselineSharingGroup aBaselineGroup) const override;
mozilla::WritingMode aWM, BaselineSharingGroup aBaselineGroup,
BaselineExportContext aExportContext) const override;
virtual nscoord GetMinISize(gfxContext* aRenderingContext) override;
virtual nscoord GetPrefISize(gfxContext* aRenderingContext) override;