Skip to content

Commit 6f868ef

Browse files
committedMay 15, 2023
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
1 parent d82335f commit 6f868ef

40 files changed

+204
-120
lines changed
 

‎layout/base/Baseline.h

+6
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,12 @@ enum class BaselineSharingGroup : uint8_t {
1919
Last = 1,
2020
};
2121

22+
// Layout context under which the baseline is being exported to.
23+
enum class BaselineExportContext : uint8_t {
24+
LineLayout = 0,
25+
Other = 1,
26+
};
27+
2228
class Baseline {
2329
public:
2430
/**

‎layout/base/nsLayoutUtils.cpp

+2-2
Original file line numberDiff line numberDiff line change
@@ -5963,8 +5963,8 @@ bool nsLayoutUtils::GetLastLineBaseline(WritingMode aWM, const nsIFrame* aFrame,
59635963
// `ColumnSetWrapperFrame` level, but this keeps it symmetric to
59645964
// `GetFirstLinePosition`.
59655965
if (aFrame->IsColumnSetFrame()) {
5966-
const auto baseline =
5967-
aFrame->GetNaturalBaselineBOffset(aWM, BaselineSharingGroup::Last);
5966+
const auto baseline = aFrame->GetNaturalBaselineBOffset(
5967+
aWM, BaselineSharingGroup::Last, BaselineExportContext::Other);
59685968
if (!baseline) {
59695969
return false;
59705970
}

‎layout/forms/nsCheckboxRadioFrame.cpp

+2-1
Original file line numberDiff line numberDiff line change
@@ -86,7 +86,8 @@ LogicalSize nsCheckboxRadioFrame::ComputeAutoSize(
8686
}
8787

8888
Maybe<nscoord> nsCheckboxRadioFrame::GetNaturalBaselineBOffset(
89-
WritingMode aWM, BaselineSharingGroup aBaselineGroup) const {
89+
WritingMode aWM, BaselineSharingGroup aBaselineGroup,
90+
BaselineExportContext) const {
9091
NS_ASSERTION(!IsSubtreeDirty(), "frame must not be dirty");
9192

9293
if (aBaselineGroup == BaselineSharingGroup::Last) {

‎layout/forms/nsCheckboxRadioFrame.h

+2-2
Original file line numberDiff line numberDiff line change
@@ -62,8 +62,8 @@ class nsCheckboxRadioFrame final : public nsAtomicContainerFrame,
6262
nsEventStatus* aEventStatus) override;
6363

6464
Maybe<nscoord> GetNaturalBaselineBOffset(
65-
mozilla::WritingMode aWM,
66-
BaselineSharingGroup aBaselineGroup) const override;
65+
mozilla::WritingMode aWM, BaselineSharingGroup aBaselineGroup,
66+
BaselineExportContext) const override;
6767

6868
/**
6969
* Respond to the request to resize and/or reflow

‎layout/forms/nsDateTimeControlFrame.cpp

+2-1
Original file line numberDiff line numberDiff line change
@@ -65,7 +65,8 @@ nscoord nsDateTimeControlFrame::GetPrefISize(gfxContext* aRenderingContext) {
6565
}
6666

6767
Maybe<nscoord> nsDateTimeControlFrame::GetNaturalBaselineBOffset(
68-
WritingMode aWM, BaselineSharingGroup aBaselineGroup) const {
68+
WritingMode aWM, BaselineSharingGroup aBaselineGroup,
69+
BaselineExportContext) const {
6970
return nsTextControlFrame::GetSingleLineTextControlBaseline(
7071
this, mFirstBaseline, aWM, aBaselineGroup);
7172
}

‎layout/forms/nsDateTimeControlFrame.h

+2-2
Original file line numberDiff line numberDiff line change
@@ -62,8 +62,8 @@ class nsDateTimeControlFrame final : public nsContainerFrame {
6262
nsReflowStatus& aStatus) override;
6363

6464
Maybe<nscoord> GetNaturalBaselineBOffset(
65-
mozilla::WritingMode aWM,
66-
BaselineSharingGroup aBaselineGroup) const override;
65+
mozilla::WritingMode aWM, BaselineSharingGroup aBaselineGroup,
66+
BaselineExportContext) const override;
6767

6868
nscoord mFirstBaseline = NS_INTRINSIC_ISIZE_UNKNOWN;
6969
};

‎layout/forms/nsFieldSetFrame.cpp

+4-2
Original file line numberDiff line numberDiff line change
@@ -851,7 +851,8 @@ nscoord nsFieldSetFrame::SynthesizeFallbackBaseline(
851851
}
852852

853853
Maybe<nscoord> nsFieldSetFrame::GetNaturalBaselineBOffset(
854-
WritingMode aWM, BaselineSharingGroup aBaselineGroup) const {
854+
WritingMode aWM, BaselineSharingGroup aBaselineGroup,
855+
BaselineExportContext aExportContext) const {
855856
if (StyleDisplay()->IsContainLayout()) {
856857
// If we are layout-contained, our child 'inner' should not
857858
// affect how we calculate our baseline.
@@ -862,7 +863,8 @@ Maybe<nscoord> nsFieldSetFrame::GetNaturalBaselineBOffset(
862863
return Nothing{};
863864
}
864865
MOZ_ASSERT(!inner->GetWritingMode().IsOrthogonalTo(aWM));
865-
const auto result = inner->GetNaturalBaselineBOffset(aWM, aBaselineGroup);
866+
const auto result =
867+
inner->GetNaturalBaselineBOffset(aWM, aBaselineGroup, aExportContext);
866868
if (!result) {
867869
return Nothing{};
868870
}

‎layout/forms/nsFieldSetFrame.h

+2-2
Original file line numberDiff line numberDiff line change
@@ -41,8 +41,8 @@ class nsFieldSetFrame final : public nsContainerFrame {
4141
BaselineSharingGroup aBaselineGroup) const override;
4242
BaselineSharingGroup GetDefaultBaselineSharingGroup() const override;
4343
Maybe<nscoord> GetNaturalBaselineBOffset(
44-
mozilla::WritingMode aWM,
45-
BaselineSharingGroup aBaselineGroup) const override;
44+
mozilla::WritingMode aWM, BaselineSharingGroup aBaselineGroup,
45+
BaselineExportContext aExportContext) const override;
4646

4747
virtual void BuildDisplayList(nsDisplayListBuilder* aBuilder,
4848
const nsDisplayListSet& aLists) override;

‎layout/forms/nsHTMLButtonControlFrame.cpp

+8-6
Original file line numberDiff line numberDiff line change
@@ -313,7 +313,8 @@ void nsHTMLButtonControlFrame::ReflowButtonContents(
313313
}
314314

315315
Maybe<nscoord> nsHTMLButtonControlFrame::GetNaturalBaselineBOffset(
316-
WritingMode aWM, BaselineSharingGroup aBaselineGroup) const {
316+
WritingMode aWM, BaselineSharingGroup aBaselineGroup,
317+
BaselineExportContext aExportContext) const {
317318
if (StyleDisplay()->IsContainLayout()) {
318319
return Nothing{};
319320
}
@@ -322,11 +323,12 @@ Maybe<nscoord> nsHTMLButtonControlFrame::GetNaturalBaselineBOffset(
322323
if (MOZ_UNLIKELY(inner->GetWritingMode().IsOrthogonalTo(aWM))) {
323324
return Nothing{};
324325
}
325-
auto result = inner->GetNaturalBaselineBOffset(aWM, aBaselineGroup)
326-
.valueOrFrom([inner, aWM, aBaselineGroup]() {
327-
return Baseline::SynthesizeBOffsetFromBorderBox(
328-
inner, aWM, aBaselineGroup);
329-
});
326+
auto result =
327+
inner->GetNaturalBaselineBOffset(aWM, aBaselineGroup, aExportContext)
328+
.valueOrFrom([inner, aWM, aBaselineGroup]() {
329+
return Baseline::SynthesizeBOffsetFromBorderBox(inner, aWM,
330+
aBaselineGroup);
331+
});
330332

331333
nscoord innerBStart = inner->BStart(aWM, GetSize());
332334
if (aBaselineGroup == BaselineSharingGroup::First) {

‎layout/forms/nsHTMLButtonControlFrame.h

+2-2
Original file line numberDiff line numberDiff line change
@@ -39,8 +39,8 @@ class nsHTMLButtonControlFrame : public nsContainerFrame,
3939
nsReflowStatus& aStatus) override;
4040

4141
Maybe<nscoord> GetNaturalBaselineBOffset(
42-
mozilla::WritingMode aWM,
43-
BaselineSharingGroup aBaselineGroup) const override;
42+
mozilla::WritingMode aWM, BaselineSharingGroup aBaselineGroup,
43+
BaselineExportContext aExportContext) const override;
4444

4545
virtual nsresult HandleEvent(nsPresContext* aPresContext,
4646
mozilla::WidgetGUIEvent* aEvent,

‎layout/forms/nsListControlFrame.cpp

+2-1
Original file line numberDiff line numberDiff line change
@@ -71,7 +71,8 @@ nsListControlFrame::nsListControlFrame(ComputedStyle* aStyle,
7171
nsListControlFrame::~nsListControlFrame() = default;
7272

7373
Maybe<nscoord> nsListControlFrame::GetNaturalBaselineBOffset(
74-
WritingMode aWM, BaselineSharingGroup aBaselineGroup) const {
74+
WritingMode aWM, BaselineSharingGroup aBaselineGroup,
75+
BaselineExportContext) const {
7576
// Unlike scroll frames which we inherit from, we don't export a baseline.
7677
return Nothing{};
7778
}

‎layout/forms/nsListControlFrame.h

+2-2
Original file line numberDiff line numberDiff line change
@@ -56,8 +56,8 @@ class nsListControlFrame final : public nsHTMLScrollFrame,
5656
NS_DECL_FRAMEARENA_HELPERS(nsListControlFrame)
5757

5858
Maybe<nscoord> GetNaturalBaselineBOffset(
59-
mozilla::WritingMode aWM,
60-
BaselineSharingGroup aBaselineGroup) const override;
59+
mozilla::WritingMode aWM, BaselineSharingGroup aBaselineGroup,
60+
BaselineExportContext) const override;
6161

6262
// nsIFrame
6363
nsresult HandleEvent(nsPresContext* aPresContext,

‎layout/forms/nsTextControlFrame.h

+2-2
Original file line numberDiff line numberDiff line change
@@ -78,8 +78,8 @@ class nsTextControlFrame : public nsContainerFrame,
7878
nsReflowStatus& aStatus) override;
7979

8080
Maybe<nscoord> GetNaturalBaselineBOffset(
81-
mozilla::WritingMode aWM,
82-
BaselineSharingGroup aBaselineGroup) const override {
81+
mozilla::WritingMode aWM, BaselineSharingGroup aBaselineGroup,
82+
BaselineExportContext) const override {
8383
if (!IsSingleLineTextControl()) {
8484
return Nothing{};
8585
}

‎layout/generic/BRFrame.cpp

+4-2
Original file line numberDiff line numberDiff line change
@@ -60,7 +60,8 @@ class BRFrame final : public nsIFrame {
6060
nscoord GetPrefISize(gfxContext* aRenderingContext) override;
6161

6262
Maybe<nscoord> GetNaturalBaselineBOffset(
63-
WritingMode aWM, BaselineSharingGroup aBaselineGroup) const override;
63+
WritingMode aWM, BaselineSharingGroup aBaselineGroup,
64+
BaselineExportContext) const override;
6465

6566
bool IsFrameOfType(uint32_t aFlags) const override {
6667
return nsIFrame::IsFrameOfType(
@@ -203,7 +204,8 @@ nscoord BRFrame::GetPrefISize(gfxContext* aRenderingContext) {
203204
}
204205

205206
Maybe<nscoord> BRFrame::GetNaturalBaselineBOffset(
206-
WritingMode aWM, BaselineSharingGroup aBaselineGroup) const {
207+
WritingMode aWM, BaselineSharingGroup aBaselineGroup,
208+
BaselineExportContext) const {
207209
if (aBaselineGroup == BaselineSharingGroup::Last) {
208210
return Nothing{};
209211
}

‎layout/generic/ColumnSetWrapperFrame.cpp

+10-5
Original file line numberDiff line numberDiff line change
@@ -235,7 +235,8 @@ nscoord ColumnSetWrapperFrame::GetPrefISize(gfxContext* aRenderingContext) {
235235
template <typename Iterator>
236236
Maybe<nscoord> ColumnSetWrapperFrame::GetBaselineBOffset(
237237
Iterator aStart, Iterator aEnd, WritingMode aWM,
238-
BaselineSharingGroup aBaselineGroup) const {
238+
BaselineSharingGroup aBaselineGroup,
239+
BaselineExportContext aExportContext) const {
239240
// Either forward iterator + first baseline, or reverse iterator + last
240241
// baseline
241242
MOZ_ASSERT((*aStart == PrincipalChildList().FirstChild() &&
@@ -251,7 +252,8 @@ Maybe<nscoord> ColumnSetWrapperFrame::GetBaselineBOffset(
251252
// baseline.
252253
for (auto itr = aStart; itr != aEnd; ++itr) {
253254
const nsIFrame* kid = *itr;
254-
auto kidBaseline = kid->GetNaturalBaselineBOffset(aWM, aBaselineGroup);
255+
auto kidBaseline =
256+
kid->GetNaturalBaselineBOffset(aWM, aBaselineGroup, aExportContext);
255257
if (!kidBaseline) {
256258
continue;
257259
}
@@ -270,13 +272,16 @@ Maybe<nscoord> ColumnSetWrapperFrame::GetBaselineBOffset(
270272
}
271273

272274
Maybe<nscoord> ColumnSetWrapperFrame::GetNaturalBaselineBOffset(
273-
WritingMode aWM, BaselineSharingGroup aBaselineGroup) const {
275+
WritingMode aWM, BaselineSharingGroup aBaselineGroup,
276+
BaselineExportContext aExportContext) const {
274277
if (aBaselineGroup == BaselineSharingGroup::First) {
275278
return GetBaselineBOffset(PrincipalChildList().cbegin(),
276-
PrincipalChildList().cend(), aWM, aBaselineGroup);
279+
PrincipalChildList().cend(), aWM, aBaselineGroup,
280+
aExportContext);
277281
}
278282
return GetBaselineBOffset(PrincipalChildList().crbegin(),
279-
PrincipalChildList().crend(), aWM, aBaselineGroup);
283+
PrincipalChildList().crend(), aWM, aBaselineGroup,
284+
aExportContext);
280285
}
281286

282287
#ifdef DEBUG

‎layout/generic/ColumnSetWrapperFrame.h

+4-2
Original file line numberDiff line numberDiff line change
@@ -60,7 +60,8 @@ class ColumnSetWrapperFrame final : public nsBlockFrame {
6060
nscoord GetPrefISize(gfxContext* aRenderingContext) override;
6161

6262
Maybe<nscoord> GetNaturalBaselineBOffset(
63-
WritingMode aWM, BaselineSharingGroup aBaselineGroup) const override;
63+
WritingMode aWM, BaselineSharingGroup aBaselineGroup,
64+
BaselineExportContext aExportContext) const override;
6465

6566
private:
6667
explicit ColumnSetWrapperFrame(ComputedStyle* aStyle,
@@ -78,7 +79,8 @@ class ColumnSetWrapperFrame final : public nsBlockFrame {
7879
template <typename Iterator>
7980
Maybe<nscoord> GetBaselineBOffset(Iterator aStart, Iterator aEnd,
8081
WritingMode aWM,
81-
BaselineSharingGroup aBaselineGroup) const;
82+
BaselineSharingGroup aBaselineGroup,
83+
BaselineExportContext aExportContext) const;
8284
};
8385

8486
} // namespace mozilla

‎layout/generic/nsBlockFrame.cpp

+64-41
Original file line numberDiff line numberDiff line change
@@ -603,54 +603,76 @@ nscoord nsBlockFrame::SynthesizeFallbackBaseline(
603603
return Baseline::SynthesizeBOffsetFromMarginBox(this, aWM, aBaselineGroup);
604604
}
605605

606+
template <typename LineIteratorType>
607+
Maybe<nscoord> nsBlockFrame::GetBaselineBOffset(
608+
LineIteratorType aStart, LineIteratorType aEnd, WritingMode aWM,
609+
BaselineSharingGroup aBaselineGroup,
610+
BaselineExportContext aExportContext) const {
611+
MOZ_ASSERT((std::is_same_v<LineIteratorType, ConstLineIterator> &&
612+
aBaselineGroup == BaselineSharingGroup::First) ||
613+
(std::is_same_v<LineIteratorType, ConstReverseLineIterator> &&
614+
aBaselineGroup == BaselineSharingGroup::Last),
615+
"Iterator direction must match baseline sharing group.");
616+
for (auto line = aStart; line != aEnd; ++line) {
617+
if (!line->IsBlock()) {
618+
// XXX Is this the right test? We have some bogus empty lines
619+
// floating around, but IsEmpty is perhaps too weak.
620+
if (line->BSize() != 0 || !line->IsEmpty()) {
621+
const auto ascent = line->BStart() + line->GetLogicalAscent();
622+
if (aBaselineGroup == BaselineSharingGroup::Last) {
623+
return Some(BSize(aWM) - ascent);
624+
}
625+
return Some(ascent);
626+
}
627+
continue;
628+
}
629+
nsIFrame* kid = line->mFirstChild;
630+
if (aWM.IsOrthogonalTo(kid->GetWritingMode())) {
631+
continue;
632+
}
633+
if (aExportContext == BaselineExportContext::LineLayout &&
634+
kid->IsTableWrapperFrame()) {
635+
// `<table>` in inline-block context does not export any baseline.
636+
continue;
637+
}
638+
const auto kidBaselineGroup =
639+
aExportContext == BaselineExportContext::LineLayout
640+
? kid->GetDefaultBaselineSharingGroup()
641+
: aBaselineGroup;
642+
const auto kidBaseline =
643+
kid->GetNaturalBaselineBOffset(aWM, kidBaselineGroup, aExportContext);
644+
if (!kidBaseline) {
645+
continue;
646+
}
647+
auto result = *kidBaseline;
648+
if (kidBaselineGroup == BaselineSharingGroup::Last) {
649+
result = kid->BSize(aWM) - result;
650+
}
651+
// Ignore relative positioning for baseline calculations.
652+
const nsSize& sz = line->mContainerSize;
653+
result += kid->GetLogicalNormalPosition(aWM, sz).B(aWM);
654+
if (aBaselineGroup == BaselineSharingGroup::Last) {
655+
return Some(BSize(aWM) - result);
656+
}
657+
return Some(result);
658+
}
659+
return Nothing{};
660+
}
661+
606662
Maybe<nscoord> nsBlockFrame::GetNaturalBaselineBOffset(
607-
WritingMode aWM, BaselineSharingGroup aBaselineGroup) const {
663+
WritingMode aWM, BaselineSharingGroup aBaselineGroup,
664+
BaselineExportContext aExportContext) const {
608665
if (StyleDisplay()->IsContainLayout()) {
609666
return Nothing{};
610667
}
611668

612669
if (aBaselineGroup == BaselineSharingGroup::First) {
613-
nscoord result;
614-
if (!nsLayoutUtils::GetFirstLineBaseline(aWM, this, &result)) {
615-
return Nothing{};
616-
}
617-
return Some(result);
670+
return GetBaselineBOffset(LinesBegin(), LinesEnd(), aWM, aBaselineGroup,
671+
aExportContext);
618672
}
619673

620-
for (ConstReverseLineIterator line = LinesRBegin(), line_end = LinesREnd();
621-
line != line_end; ++line) {
622-
if (line->IsBlock()) {
623-
nsIFrame* kid = line->mFirstChild;
624-
if (aWM.IsOrthogonalTo(kid->GetWritingMode())) {
625-
continue;
626-
}
627-
if (kid->IsTableWrapperFrame()) {
628-
// `<table>` in block display context does not export any baseline.
629-
continue;
630-
}
631-
const auto kidBaselineGroup = kid->GetDefaultBaselineSharingGroup();
632-
const auto kidBaseline =
633-
kid->GetNaturalBaselineBOffset(aWM, kidBaselineGroup);
634-
if (!kidBaseline) {
635-
continue;
636-
}
637-
auto result = *kidBaseline;
638-
if (kidBaselineGroup == BaselineSharingGroup::Last) {
639-
result = kid->BSize(aWM) - result;
640-
}
641-
// Ignore relative positioning for baseline calculations.
642-
const nsSize& sz = line->mContainerSize;
643-
result += kid->GetLogicalNormalPosition(aWM, sz).B(aWM);
644-
return Some(BSize(aWM) - result);
645-
} else {
646-
// XXX Is this the right test? We have some bogus empty lines
647-
// floating around, but IsEmpty is perhaps too weak.
648-
if (line->BSize() != 0 || !line->IsEmpty()) {
649-
return Some(BSize(aWM) - (line->BStart() + line->GetLogicalAscent()));
650-
}
651-
}
652-
}
653-
return Nothing{};
674+
return GetBaselineBOffset(LinesRBegin(), LinesREnd(), aWM, aBaselineGroup,
675+
aExportContext);
654676
}
655677

656678
nscoord nsBlockFrame::GetCaretBaseline() const {
@@ -1570,7 +1592,8 @@ void nsBlockFrame::Reflow(nsPresContext* aPresContext, ReflowOutput& aMetrics,
15701592
const auto baselineGroup = BaselineSharingGroup::First;
15711593
Maybe<nscoord> result;
15721594
if (MOZ_LIKELY(!wm.IsOrthogonalTo(marker->GetWritingMode()))) {
1573-
result = marker->GetNaturalBaselineBOffset(wm, baselineGroup);
1595+
result = marker->GetNaturalBaselineBOffset(
1596+
wm, baselineGroup, BaselineExportContext::LineLayout);
15741597
}
15751598
const auto markerBaseline = result.valueOrFrom([bbox, wm, marker]() {
15761599
return bbox.BSize(wm) + marker->GetLogicalUsedMargin(wm).BEnd(wm);

‎layout/generic/nsBlockFrame.h

+9-2
Original file line numberDiff line numberDiff line change
@@ -133,8 +133,8 @@ class nsBlockFrame : public nsContainerFrame {
133133
return BaselineSharingGroup::Last;
134134
}
135135
Maybe<nscoord> GetNaturalBaselineBOffset(
136-
mozilla::WritingMode aWM,
137-
BaselineSharingGroup aBaselineGroup) const override;
136+
mozilla::WritingMode aWM, BaselineSharingGroup aBaselineGroup,
137+
BaselineExportContext aExportContext) const override;
138138
nscoord GetCaretBaseline() const override;
139139
void DestroyFrom(nsIFrame* aDestructRoot,
140140
PostDestroyData& aPostDestroyData) override;
@@ -276,6 +276,13 @@ class nsBlockFrame : public nsContainerFrame {
276276
private:
277277
void CheckIntrinsicCacheAgainstShrinkWrapState();
278278

279+
template <typename LineIteratorType>
280+
Maybe<nscoord> GetBaselineBOffset(LineIteratorType aStart,
281+
LineIteratorType aEnd,
282+
mozilla::WritingMode aWM,
283+
BaselineSharingGroup aBaselineGroup,
284+
BaselineExportContext aExportContext) const;
285+
279286
public:
280287
nscoord GetMinISize(gfxContext* aRenderingContext) override;
281288
nscoord GetPrefISize(gfxContext* aRenderingContext) override;

0 commit comments

Comments
 (0)
Failed to load comments.