Skip to content

Commit 8306b84

Browse files
committed
[LFC][IFC] Move horizontal space tracking from Line to LineBuilder
https://bugs.webkit.org/show_bug.cgi?id=219185 Reviewed by Antti Koivisto. Let's move the available horizontal space tracking from Line to LineBuilder. Since the LineBuilder decides what to put on the line the Line object does not need to know how much available space there is. This is also in preparation for adding float support on (vertically) stretchy lines where the horizontal available space may vary depending on how much the inline level boxes stretch the line vertically. * layout/inlineformatting/InlineLine.cpp: (WebCore::Layout::Line::initialize): (WebCore::Layout::Line::removeCollapsibleContent): (WebCore::Layout::Line::applyRunExpansion): (WebCore::Layout::Line::removeTrailingTrimmableContent): (WebCore::Layout::Line::visuallyCollapsePreWrapOverflowContent): (WebCore::Layout::Line::moveLogicalLeft): (WebCore::Layout::Line::moveLogicalRight): Deleted. * layout/inlineformatting/InlineLine.h: (WebCore::Layout::Line::contentLogicalWidth const): (WebCore::Layout::Line::horizontalConstraint const): Deleted. (WebCore::Layout::Line::availableWidth const): Deleted. * layout/inlineformatting/InlineLineBuilder.cpp: (WebCore::Layout::LineBuilder::layoutInlineContent): (WebCore::Layout::LineBuilder::initialize): (WebCore::Layout::LineBuilder::placeInlineContent): (WebCore::Layout::LineBuilder::close): (WebCore::Layout::LineBuilder::commitFloats): (WebCore::Layout::LineBuilder::handleFloatsAndInlineContent): (WebCore::Layout::LineBuilder::rebuildLine): (WebCore::Layout::LineBuilder::rebuildLineForTrailingSoftHyphen): * layout/inlineformatting/InlineLineBuilder.h: (WebCore::Layout::LineBuilder::availableWidth const): Canonical link: https://commits.webkit.org/231823@main git-svn-id: https://svn.webkit.org/repository/webkit/trunk@270114 268f45cc-cd09-0410-ab3c-d52691b4dbfc
1 parent b67b6c2 commit 8306b84

5 files changed

Lines changed: 69 additions & 41 deletions

File tree

Source/WebCore/ChangeLog

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,39 @@
1+
2020-11-20 Zalan Bujtas <zalan@apple.com>
2+
3+
[LFC][IFC] Move horizontal space tracking from Line to LineBuilder
4+
https://bugs.webkit.org/show_bug.cgi?id=219185
5+
6+
Reviewed by Antti Koivisto.
7+
8+
Let's move the available horizontal space tracking from Line to LineBuilder. Since the LineBuilder decides what to put on the line
9+
the Line object does not need to know how much available space there is.
10+
This is also in preparation for adding float support on (vertically) stretchy lines where the horizontal available space may vary
11+
depending on how much the inline level boxes stretch the line vertically.
12+
13+
* layout/inlineformatting/InlineLine.cpp:
14+
(WebCore::Layout::Line::initialize):
15+
(WebCore::Layout::Line::removeCollapsibleContent):
16+
(WebCore::Layout::Line::applyRunExpansion):
17+
(WebCore::Layout::Line::removeTrailingTrimmableContent):
18+
(WebCore::Layout::Line::visuallyCollapsePreWrapOverflowContent):
19+
(WebCore::Layout::Line::moveLogicalLeft):
20+
(WebCore::Layout::Line::moveLogicalRight): Deleted.
21+
* layout/inlineformatting/InlineLine.h:
22+
(WebCore::Layout::Line::contentLogicalWidth const):
23+
(WebCore::Layout::Line::horizontalConstraint const): Deleted.
24+
(WebCore::Layout::Line::availableWidth const): Deleted.
25+
* layout/inlineformatting/InlineLineBuilder.cpp:
26+
(WebCore::Layout::LineBuilder::layoutInlineContent):
27+
(WebCore::Layout::LineBuilder::initialize):
28+
(WebCore::Layout::LineBuilder::placeInlineContent):
29+
(WebCore::Layout::LineBuilder::close):
30+
(WebCore::Layout::LineBuilder::commitFloats):
31+
(WebCore::Layout::LineBuilder::handleFloatsAndInlineContent):
32+
(WebCore::Layout::LineBuilder::rebuildLine):
33+
(WebCore::Layout::LineBuilder::rebuildLineForTrailingSoftHyphen):
34+
* layout/inlineformatting/InlineLineBuilder.h:
35+
(WebCore::Layout::LineBuilder::availableWidth const):
36+
137
2020-11-20 Antti Koivisto <antti@apple.com>
238

339
[LFC][Integration] Take alignment offset into account when computing line iterator logicalLeft

Source/WebCore/layout/inlineformatting/InlineLine.cpp

Lines changed: 9 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -56,9 +56,8 @@ Line::~Line()
5656
{
5757
}
5858

59-
void Line::initialize(InlineLayoutUnit horizontalConstraint)
59+
void Line::initialize()
6060
{
61-
m_horizontalConstraint = horizontalConstraint;
6261
m_contentLogicalWidth = { };
6362
m_runs.clear();
6463
m_trailingSoftHyphenWidth = { };
@@ -67,13 +66,13 @@ void Line::initialize(InlineLayoutUnit horizontalConstraint)
6766
m_isConsideredEmptyBeforeTrimmableTrailingContent = { };
6867
}
6968

70-
void Line::removeCollapsibleContent()
69+
void Line::removeCollapsibleContent(InlineLayoutUnit extraHorizontalSpace)
7170
{
7271
removeTrailingTrimmableContent();
73-
visuallyCollapsePreWrapOverflowContent();
72+
visuallyCollapsePreWrapOverflowContent(extraHorizontalSpace);
7473
}
7574

76-
void Line::applyRunExpansion()
75+
void Line::applyRunExpansion(InlineLayoutUnit extraHorizontalSpace)
7776
{
7877
ASSERT(formattingContext().root().style().textAlign() == TextAlignMode::Justify);
7978
// Text is justified according to the method specified by the text-justify property,
@@ -97,10 +96,10 @@ void Line::applyRunExpansion()
9796
lastRunWithContent->setExpansionBehavior(leadingExpansion | ForbidRightExpansion);
9897
}
9998
// Anything to distribute?
100-
if (!expansionOpportunityCount || !availableWidth())
99+
if (!expansionOpportunityCount || !extraHorizontalSpace)
101100
return;
102101
// Distribute the extra space.
103-
auto expansionToDistribute = availableWidth() / expansionOpportunityCount;
102+
auto expansionToDistribute = extraHorizontalSpace / expansionOpportunityCount;
104103
auto accumulatedExpansion = InlineLayoutUnit { };
105104
for (auto& run : m_runs) {
106105
// Expand and move runs by the accumulated expansion.
@@ -116,7 +115,6 @@ void Line::applyRunExpansion()
116115
}
117116
// Content grows as runs expand.
118117
m_contentLogicalWidth += accumulatedExpansion;
119-
ASSERT(m_contentLogicalWidth == m_horizontalConstraint);
120118
}
121119

122120
void Line::removeTrailingTrimmableContent()
@@ -133,7 +131,7 @@ void Line::removeTrailingTrimmableContent()
133131
|| textAlign == TextAlignMode::End;
134132
}();
135133

136-
if (m_runs.last().isLineBreak() && availableWidth() >= 0 && !isTextAlignRight) {
134+
if (m_runs.last().isLineBreak() && !isTextAlignRight) {
137135
m_trimmableTrailingContent.reset();
138136
return;
139137
}
@@ -155,13 +153,13 @@ void Line::removeTrailingTrimmableContent()
155153
}
156154
}
157155

158-
void Line::visuallyCollapsePreWrapOverflowContent()
156+
void Line::visuallyCollapsePreWrapOverflowContent(InlineLayoutUnit extraHorizontalSpace)
159157
{
160158
ASSERT(m_trimmableTrailingContent.isEmpty());
161159
// If white-space is set to pre-wrap, the UA must
162160
// ...
163161
// It may also visually collapse the character advance widths of any that would otherwise overflow.
164-
auto overflowWidth = -availableWidth();
162+
auto overflowWidth = -extraHorizontalSpace;
165163
if (overflowWidth <= 0)
166164
return;
167165
// Let's just find the trailing pre-wrap whitespace content for now (e.g check if there are multiple trailing runs with
@@ -200,13 +198,6 @@ void Line::moveLogicalLeft(InlineLayoutUnit delta)
200198
return;
201199
ASSERT(delta > 0);
202200
m_lineLogicalLeft += delta;
203-
m_horizontalConstraint -= delta;
204-
}
205-
206-
void Line::moveLogicalRight(InlineLayoutUnit delta)
207-
{
208-
ASSERT(delta > 0);
209-
m_horizontalConstraint -= delta;
210201
}
211202

212203
void Line::append(const InlineItem& inlineItem, InlineLayoutUnit logicalWidth)

Source/WebCore/layout/inlineformatting/InlineLine.h

Lines changed: 4 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -42,7 +42,7 @@ class Line {
4242
Line(const InlineFormattingContext&);
4343
~Line();
4444

45-
void initialize(InlineLayoutUnit horizontalConstraint);
45+
void initialize();
4646

4747
void append(const InlineItem&, InlineLayoutUnit logicalWidth);
4848

@@ -52,9 +52,7 @@ class Line {
5252
// <span style="padding: 10px"></span> is not considered empty.
5353
bool isConsideredEmpty() const { return m_isConsideredEmpty; }
5454

55-
InlineLayoutUnit horizontalConstraint() const { return m_horizontalConstraint; }
5655
InlineLayoutUnit contentLogicalWidth() const { return m_contentLogicalWidth; }
57-
InlineLayoutUnit availableWidth() const { return horizontalConstraint() - contentLogicalWidth(); }
5856

5957
InlineLayoutUnit trimmableTrailingWidth() const { return m_trimmableTrailingContent.width(); }
6058
bool isTrailingRunFullyTrimmable() const { return m_trimmableTrailingContent.isTrailingRunFullyTrimmable(); }
@@ -63,10 +61,9 @@ class Line {
6361
void addTrailingHyphen(InlineLayoutUnit hyphenLogicalWidth);
6462

6563
void moveLogicalLeft(InlineLayoutUnit);
66-
void moveLogicalRight(InlineLayoutUnit);
6764

68-
void removeCollapsibleContent();
69-
void applyRunExpansion();
65+
void removeCollapsibleContent(InlineLayoutUnit extraHorizontalSpace);
66+
void applyRunExpansion(InlineLayoutUnit extraHorizontalSpace);
7067

7168
struct Run {
7269
bool isText() const { return m_type == InlineItem::Type::Text; }
@@ -150,7 +147,7 @@ class Line {
150147
void appendWordBreakOpportunity(const InlineItem&);
151148

152149
void removeTrailingTrimmableContent();
153-
void visuallyCollapsePreWrapOverflowContent();
150+
void visuallyCollapsePreWrapOverflowContent(InlineLayoutUnit extraHorizontalSpace);
154151

155152
bool isRunConsideredEmpty(const Run&) const;
156153
const InlineFormattingContext& formattingContext() const;
@@ -182,7 +179,6 @@ class Line {
182179
RunList m_runs;
183180
TrimmableTrailingContent m_trimmableTrailingContent;
184181
InlineLayoutUnit m_lineLogicalLeft { 0 };
185-
InlineLayoutUnit m_horizontalConstraint { 0 };
186182
InlineLayoutUnit m_contentLogicalWidth { 0 };
187183
Optional<InlineLayoutUnit> m_trailingSoftHyphenWidth { 0 };
188184
bool m_isConsideredEmpty { true };

Source/WebCore/layout/inlineformatting/InlineLineBuilder.cpp

Lines changed: 16 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -262,19 +262,19 @@ LineBuilder::LineBuilder(const InlineFormattingContext& inlineFormattingContext,
262262
{
263263
}
264264

265-
LineBuilder::LineContent LineBuilder::layoutInlineContent(const InlineItemRange& needsLayoutRange, size_t partialLeadingContentLength, const InlineRect& lineLogicalConstraints, bool isFirstLine)
265+
LineBuilder::LineContent LineBuilder::layoutInlineContent(const InlineItemRange& needsLayoutRange, size_t partialLeadingContentLength, const InlineRect& initialConstraintsForLine, bool isFirstLine)
266266
{
267-
auto usedConstraints = constraintsForLine(lineLogicalConstraints, isFirstLine);
267+
auto usedConstraints = constraintsForLine(initialConstraintsForLine, isFirstLine);
268268
initialize(usedConstraints);
269269

270270
auto committedContent = placeInlineContent(needsLayoutRange, partialLeadingContentLength);
271271
auto committedRange = close(needsLayoutRange, committedContent);
272272

273-
auto lineLogicalTopLeft = InlineLayoutPoint { usedConstraints.logicalLeft, lineLogicalConstraints.top() };
273+
auto lineLogicalTopLeft = InlineLayoutPoint { usedConstraints.logicalLeft, initialConstraintsForLine.top() };
274274
auto isLastLine = isLastLineWithInlineContent(committedRange, needsLayoutRange.end, committedContent.partialTrailingContentLength);
275275
return LineContent { committedRange, committedContent.partialTrailingContentLength, m_floats, m_contentIsConstrainedByFloat
276276
, lineLogicalTopLeft
277-
, m_line.horizontalConstraint()
277+
, m_horizontalSpaceForLine
278278
, m_line.contentLogicalWidth()
279279
, m_line.isConsideredEmpty()
280280
, isLastLine
@@ -295,8 +295,9 @@ void LineBuilder::initialize(const UsedConstraints& lineConstraints)
295295
m_partialLeadingTextItem = { };
296296
m_wrapOpportunityList.clear();
297297

298-
m_line.initialize(lineConstraints.availableLogicalWidth);
298+
m_line.initialize();
299299
m_contentIsConstrainedByFloat = lineConstraints.isConstrainedByFloat;
300+
m_horizontalSpaceForLine = lineConstraints.logicalWidth;
300301
}
301302

302303
LineBuilder::CommittedContent LineBuilder::placeInlineContent(const InlineItemRange& needsLayoutRange, size_t partialLeadingContentLength)
@@ -311,7 +312,7 @@ LineBuilder::CommittedContent LineBuilder::placeInlineContent(const InlineItemRa
311312
// 2. Apply floats and shrink the available horizontal space e.g. <span>intru_<div style="float: left"></div>sive_float</span>.
312313
// 3. Check if the content fits the line and commit the content accordingly (full, partial or not commit at all).
313314
// 4. Return if we are at the end of the line either by not being able to fit more content or because of an explicit line break.
314-
nextContentForLine(lineCandidate, currentItemIndex, needsLayoutRange, partialLeadingContentLength, m_line.availableWidth() + m_line.trimmableTrailingWidth(), m_line.contentLogicalWidth());
315+
nextContentForLine(lineCandidate, currentItemIndex, needsLayoutRange, partialLeadingContentLength, availableWidth() + m_line.trimmableTrailingWidth(), m_line.contentLogicalWidth());
315316
// Now check if we can put this content on the current line.
316317
auto result = handleFloatsAndInlineContent(inlineContentBreaker, needsLayoutRange, lineCandidate);
317318
committedInlineItemCount = result.committedCount.isRevert ? result.committedCount.value : committedInlineItemCount + result.committedCount.value;
@@ -354,11 +355,11 @@ LineBuilder::InlineItemRange LineBuilder::close(const InlineItemRange& needsLayo
354355
// Line is empty, we only managed to place float boxes.
355356
return lineRange;
356357
}
357-
m_line.removeCollapsibleContent();
358+
m_line.removeCollapsibleContent(availableWidth());
358359
auto horizontalAlignment = root().style().textAlign();
359360
auto runsExpandHorizontally = horizontalAlignment == TextAlignMode::Justify && !isLastLineWithInlineContent(lineRange, needsLayoutRange.end, committedContent.partialTrailingContentLength);
360361
if (runsExpandHorizontally)
361-
m_line.applyRunExpansion();
362+
m_line.applyRunExpansion(availableWidth());
362363
auto lineEndsWithHyphen = false;
363364
if (!m_line.isConsideredEmpty()) {
364365
ASSERT(!m_line.runs().isEmpty());
@@ -571,10 +572,12 @@ void LineBuilder::commitFloats(const LineCandidate& lineCandidate, CommitIntrusi
571572
}
572573
}
573574
if (leftIntrusiveFloatsWidth || rightIntrusiveFloatsWidth) {
574-
if (leftIntrusiveFloatsWidth)
575+
if (leftIntrusiveFloatsWidth) {
575576
m_line.moveLogicalLeft(leftIntrusiveFloatsWidth);
577+
m_horizontalSpaceForLine -= leftIntrusiveFloatsWidth;
578+
}
576579
if (rightIntrusiveFloatsWidth)
577-
m_line.moveLogicalRight(rightIntrusiveFloatsWidth);
580+
m_horizontalSpaceForLine -= rightIntrusiveFloatsWidth;
578581
}
579582
}
580583

@@ -596,7 +599,7 @@ LineBuilder::Result LineBuilder::handleFloatsAndInlineContent(InlineContentBreak
596599

597600
auto& floatContent = lineCandidate.floatContent;
598601
// Check if this new content fits.
599-
auto availableWidth = m_line.availableWidth() - floatContent.intrusiveWidth();
602+
auto availableWidth = this->availableWidth() - floatContent.intrusiveWidth();
600603
auto isLineConsideredEmpty = m_line.isConsideredEmpty() && !m_contentIsConstrainedByFloat;
601604
auto lineStatus = InlineContentBreaker::LineStatus { availableWidth, m_line.trimmableTrailingWidth(), m_line.trailingSoftHyphenWidth(), m_line.isTrailingRunFullyTrimmable(), isLineConsideredEmpty };
602605
auto result = inlineContentBreaker.processInlineContent(continuousInlineContent, lineStatus);
@@ -685,7 +688,7 @@ size_t LineBuilder::rebuildLine(const InlineItemRange& layoutRange, const Inline
685688
ASSERT(!m_wrapOpportunityList.isEmpty());
686689
// We might already have added intrusive floats. They shrink the avilable horizontal space for the line.
687690
// Let's just reuse what the line has at this point.
688-
m_line.initialize(m_line.horizontalConstraint());
691+
m_line.initialize();
689692
auto currentItemIndex = layoutRange.start;
690693
if (m_partialLeadingTextItem) {
691694
m_line.append(*m_partialLeadingTextItem, inlineItemWidth(*m_partialLeadingTextItem, { }));
@@ -713,7 +716,7 @@ size_t LineBuilder::rebuildLineForTrailingSoftHyphen(const InlineItemRange& layo
713716
auto committedCount = rebuildLine(layoutRange, softWrapOpportunityItem);
714717
auto trailingSoftHyphenWidth = m_line.trailingSoftHyphenWidth();
715718
// Check if the trailing hyphen now fits the line (or we don't need hyhen anymore).
716-
if (!trailingSoftHyphenWidth || trailingSoftHyphenWidth <= m_line.availableWidth()) {
719+
if (!trailingSoftHyphenWidth || trailingSoftHyphenWidth <= availableWidth()) {
717720
if (trailingSoftHyphenWidth)
718721
m_line.addTrailingHyphen(*trailingSoftHyphenWidth);
719722
return committedCount;

Source/WebCore/layout/inlineformatting/InlineLineBuilder.h

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -64,7 +64,7 @@ class LineBuilder {
6464
bool isLastLineWithInlineContent { true };
6565
const Line::RunList& runs;
6666
};
67-
LineContent layoutInlineContent(const InlineItemRange&, size_t partialLeadingContentLength, const InlineRect& initialLineConstraints, bool isFirstLine);
67+
LineContent layoutInlineContent(const InlineItemRange&, size_t partialLeadingContentLength, const InlineRect& initialConstraintsForLine, bool isFirstLine);
6868

6969
struct IntrinsicContent {
7070
InlineItemRange inlineItemRange;
@@ -88,7 +88,7 @@ class LineBuilder {
8888
enum class CommitIntrusiveFloatsOnly { No, Yes };
8989
struct UsedConstraints {
9090
InlineLayoutUnit logicalLeft { 0 };
91-
InlineLayoutUnit availableLogicalWidth { 0 };
91+
InlineLayoutUnit logicalWidth { 0 };
9292
bool isConstrainedByFloat { false };
9393
};
9494
UsedConstraints constraintsForLine(const InlineRect& initialLineConstraints, bool isFirstLine);
@@ -107,6 +107,7 @@ class LineBuilder {
107107

108108
InlineLayoutUnit inlineItemWidth(const InlineItem&, InlineLayoutUnit contentLogicalLeft) const;
109109
bool isLastLineWithInlineContent(const InlineItemRange& lineRange, size_t lastInlineItemIndex, bool hasPartialTrailingContent) const;
110+
InlineLayoutUnit availableWidth() const { return m_horizontalSpaceForLine - m_line.contentLogicalWidth(); }
110111

111112
const InlineFormattingContext& formattingContext() const { return m_inlineFormattingContext; }
112113
const ContainerBox& root() const { return m_formattingContextRoot; }
@@ -116,6 +117,7 @@ class LineBuilder {
116117
const FloatingContext& m_floatingContext;
117118
const ContainerBox& m_formattingContextRoot;
118119
Line m_line;
120+
InlineLayoutUnit m_horizontalSpaceForLine { 0 };
119121
const InlineItems& m_inlineItems;
120122
LineContent::FloatList m_floats;
121123
Optional<InlineTextItem> m_partialLeadingTextItem;

0 commit comments

Comments
 (0)