[LFC][IFC] Move overflowing content creation to LineBuilder::initialize
https://bugs.webkit.org/show_bug.cgi?id=231540
Reviewed by Antti Koivisto.
LineBuilder::initialize is going to handle all overflowing content initialization.
This is in preparation for adding spanning inline box items to the line (to support box-decoration-break: clone).
* layout/formattingContexts/inline/InlineLineBuilder.cpp:
(WebCore::Layout::LineBuilder::layoutInlineContent):
(WebCore::Layout::LineBuilder::computedIntrinsicWidth):
(WebCore::Layout::LineBuilder::initialize):
(WebCore::Layout::LineBuilder::placeInlineContent):
(WebCore::Layout::LineBuilder::candidateContentForLine):
* layout/formattingContexts/inline/InlineLineBuilder.h:
* layout/formattingContexts/inline/InlineTextItem.h:
(WebCore::Layout::InlineTextItem::right const):
git-svn-id: http://svn.webkit.org/repository/webkit/trunk@284317 268f45cc-cd09-0410-ab3c-d52691b4dbfc
diff --git a/Source/WebCore/ChangeLog b/Source/WebCore/ChangeLog
index b296f86..57e9f61 100644
--- a/Source/WebCore/ChangeLog
+++ b/Source/WebCore/ChangeLog
@@ -1,3 +1,23 @@
+2021-10-16 Alan Bujtas <zalan@apple.com>
+
+ [LFC][IFC] Move overflowing content creation to LineBuilder::initialize
+ https://bugs.webkit.org/show_bug.cgi?id=231540
+
+ Reviewed by Antti Koivisto.
+
+ LineBuilder::initialize is going to handle all overflowing content initialization.
+ This is in preparation for adding spanning inline box items to the line (to support box-decoration-break: clone).
+
+ * layout/formattingContexts/inline/InlineLineBuilder.cpp:
+ (WebCore::Layout::LineBuilder::layoutInlineContent):
+ (WebCore::Layout::LineBuilder::computedIntrinsicWidth):
+ (WebCore::Layout::LineBuilder::initialize):
+ (WebCore::Layout::LineBuilder::placeInlineContent):
+ (WebCore::Layout::LineBuilder::candidateContentForLine):
+ * layout/formattingContexts/inline/InlineLineBuilder.h:
+ * layout/formattingContexts/inline/InlineTextItem.h:
+ (WebCore::Layout::InlineTextItem::right const):
+
2021-10-16 Antti Koivisto <antti@apple.com>
Use inline iterator for SVG reverse BiDI reordering
diff --git a/Source/WebCore/layout/formattingContexts/inline/InlineLineBuilder.cpp b/Source/WebCore/layout/formattingContexts/inline/InlineLineBuilder.cpp
index 0affd76..5548cbb 100644
--- a/Source/WebCore/layout/formattingContexts/inline/InlineLineBuilder.cpp
+++ b/Source/WebCore/layout/formattingContexts/inline/InlineLineBuilder.cpp
@@ -266,11 +266,11 @@
{
}
-LineBuilder::LineContent LineBuilder::layoutInlineContent(const InlineItemRange& needsLayoutRange, size_t partialLeadingContentLength, std::optional<InlineLayoutUnit> overflowLogicalWidth, const InlineRect& initialLineLogicalRect, bool isFirstLine)
+LineBuilder::LineContent LineBuilder::layoutInlineContent(const InlineItemRange& needsLayoutRange, size_t partialLeadingContentLength, std::optional<InlineLayoutUnit> overflowingLogicalWidth, const InlineRect& initialLineLogicalRect, bool isFirstLine)
{
- initialize(initialConstraintsForLine(initialLineLogicalRect, isFirstLine), isFirstLine);
+ initialize(initialConstraintsForLine(initialLineLogicalRect, isFirstLine), isFirstLine, needsLayoutRange.start, partialLeadingContentLength, overflowingLogicalWidth);
- auto committedContent = placeInlineContent(needsLayoutRange, partialLeadingContentLength, overflowLogicalWidth);
+ auto committedContent = placeInlineContent(needsLayoutRange);
auto committedRange = close(needsLayoutRange, committedContent);
auto isLastLine = isLastLineWithInlineContent(committedRange, needsLayoutRange.end, committedContent.partialTrailingContentLength);
@@ -286,25 +286,33 @@
LineBuilder::IntrinsicContent LineBuilder::computedIntrinsicWidth(const InlineItemRange& needsLayoutRange, InlineLayoutUnit availableWidth)
{
- initialize({ { { }, { availableWidth, maxInlineLayoutUnit() } }, false }, false);
- auto committedContent = placeInlineContent(needsLayoutRange, { }, { });
+ initialize({ { { }, { availableWidth, maxInlineLayoutUnit() } }, false }, false, { }, { }, { });
+ auto committedContent = placeInlineContent(needsLayoutRange);
auto committedRange = close(needsLayoutRange, committedContent);
return { committedRange, m_line.contentLogicalWidth(), m_floats };
}
-void LineBuilder::initialize(const UsedConstraints& lineConstraints, bool isFirstLine)
+void LineBuilder::initialize(const UsedConstraints& lineConstraints, bool isFirstLine, size_t leadingInlineTextItemIndex, size_t partialLeadingContentLength, std::optional<InlineLayoutUnit> overflowingLogicalWidth)
{
m_isFirstLine = isFirstLine;
m_floats.clear();
- m_partialLeadingTextItem = { };
m_wrapOpportunityList.clear();
m_line.initialize();
m_lineLogicalRect = lineConstraints.logicalRect;
m_contentIsConstrainedByFloat = lineConstraints.isConstrainedByFloat;
+
+ if (partialLeadingContentLength) {
+ ASSERT(!isFirstLine);
+ m_partialLeadingTextItem = downcast<InlineTextItem>(m_inlineItems[leadingInlineTextItemIndex]).right(partialLeadingContentLength, overflowingLogicalWidth);
+ m_overflowingLogicalWidth = { };
+ } else {
+ m_partialLeadingTextItem = { };
+ m_overflowingLogicalWidth = overflowingLogicalWidth;
+ }
}
-LineBuilder::CommittedContent LineBuilder::placeInlineContent(const InlineItemRange& needsLayoutRange, size_t partialLeadingContentLength, std::optional<InlineLayoutUnit> leadingLogicalWidth)
+LineBuilder::CommittedContent LineBuilder::placeInlineContent(const InlineItemRange& needsLayoutRange)
{
auto lineCandidate = LineCandidate { layoutState().shouldIgnoreTrailingLetterSpacing() };
auto inlineContentBreaker = InlineContentBreaker { };
@@ -316,7 +324,7 @@
// 2. Apply floats and shrink the available horizontal space e.g. <span>intru_<div style="float: left"></div>sive_float</span>.
// 3. Check if the content fits the line and commit the content accordingly (full, partial or not commit at all).
// 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.
- candidateContentForLine(lineCandidate, currentItemIndex, needsLayoutRange, partialLeadingContentLength, std::exchange(leadingLogicalWidth, std::nullopt), m_line.contentLogicalRight());
+ candidateContentForLine(lineCandidate, currentItemIndex, needsLayoutRange, m_line.contentLogicalRight());
// Now check if we can put this content on the current line.
auto result = Result { };
if (lineCandidate.floatItem) {
@@ -355,7 +363,6 @@
return { committedInlineItemCount, result.partialTrailingContentLength, result.overflowLogicalWidth };
}
currentItemIndex = needsLayoutRange.start + committedInlineItemCount + m_floats.size();
- partialLeadingContentLength = { };
}
// Looks like we've run out of runs.
return { committedInlineItemCount, { } };
@@ -471,7 +478,7 @@
return UsedConstraints { { initialLineLogicalRect.top(), lineLogicalLeft, lineLogicalRight - lineLogicalLeft, initialLineLogicalRect.height() }, lineIsConstrainedByFloat };
}
-void LineBuilder::candidateContentForLine(LineCandidate& lineCandidate, size_t currentInlineItemIndex, const InlineItemRange& layoutRange, size_t partialLeadingContentLength, std::optional<InlineLayoutUnit> leadingLogicalWidth, InlineLayoutUnit currentLogicalRight)
+void LineBuilder::candidateContentForLine(LineCandidate& lineCandidate, size_t currentInlineItemIndex, const InlineItemRange& layoutRange, InlineLayoutUnit currentLogicalRight)
{
ASSERT(currentInlineItemIndex < layoutRange.end);
lineCandidate.reset();
@@ -482,12 +489,11 @@
// softWrapOpportunityIndex == layoutRange.end means we don't have any wrap opportunity in this content.
ASSERT(softWrapOpportunityIndex <= layoutRange.end);
- if (partialLeadingContentLength) {
- ASSERT(!m_isFirstLine);
+ auto isLineStart = currentInlineItemIndex == layoutRange.start;
+ if (isLineStart && m_partialLeadingTextItem) {
+ ASSERT(!m_overflowingLogicalWidth);
// Handle leading partial content first (overflowing text from the previous line).
- // Construct a partial leading inline item.
- m_partialLeadingTextItem = downcast<InlineTextItem>(m_inlineItems[currentInlineItemIndex]).right(partialLeadingContentLength);
- auto itemWidth = leadingLogicalWidth ? *std::exchange(leadingLogicalWidth, std::nullopt) : inlineItemWidth(*m_partialLeadingTextItem, currentLogicalRight);
+ auto itemWidth = inlineItemWidth(*m_partialLeadingTextItem, currentLogicalRight);
lineCandidate.inlineContent.appendInlineItem(*m_partialLeadingTextItem, m_partialLeadingTextItem->style(), itemWidth);
currentLogicalRight += itemWidth;
++currentInlineItemIndex;
@@ -505,8 +511,7 @@
continue;
}
if (inlineItem.isText() || inlineItem.isInlineBoxStart() || inlineItem.isInlineBoxEnd()) {
- ASSERT(!leadingLogicalWidth || inlineItem.isText());
- auto logicalWidth = leadingLogicalWidth ? *std::exchange(leadingLogicalWidth, std::nullopt) : inlineItemWidth(inlineItem, currentLogicalRight);
+ auto logicalWidth = m_overflowingLogicalWidth ? *std::exchange(m_overflowingLogicalWidth, std::nullopt) : inlineItemWidth(inlineItem, currentLogicalRight);
lineCandidate.inlineContent.appendInlineItem(inlineItem, style, logicalWidth);
currentLogicalRight += logicalWidth;
if (is<InlineTextItem>(inlineItem) && downcast<InlineTextItem>(inlineItem).isWordSeparator()) {
diff --git a/Source/WebCore/layout/formattingContexts/inline/InlineLineBuilder.h b/Source/WebCore/layout/formattingContexts/inline/InlineLineBuilder.h
index 3bbb53f..17dd742 100644
--- a/Source/WebCore/layout/formattingContexts/inline/InlineLineBuilder.h
+++ b/Source/WebCore/layout/formattingContexts/inline/InlineLineBuilder.h
@@ -63,7 +63,7 @@
size_t nonSpanningInlineLevelBoxCount { 0 };
const Line::RunList& runs;
};
- LineContent layoutInlineContent(const InlineItemRange&, size_t partialLeadingContentLength, std::optional<InlineLayoutUnit> leadingLogicalWidth, const InlineRect& initialLineLogicalRect, bool isFirstLine);
+ LineContent layoutInlineContent(const InlineItemRange&, size_t partialLeadingContentLength, std::optional<InlineLayoutUnit> overflowingLogicalWidth, const InlineRect& initialLineLogicalRect, bool isFirstLine);
struct IntrinsicContent {
InlineItemRange inlineItemRange;
@@ -73,7 +73,7 @@
IntrinsicContent computedIntrinsicWidth(const InlineItemRange&, InlineLayoutUnit availableWidth);
private:
- void candidateContentForLine(LineCandidate&, size_t inlineItemIndex, const InlineItemRange& needsLayoutRange, size_t overflowLength, std::optional<InlineLayoutUnit> leadingLogicalWidth, InlineLayoutUnit currentLogicalRight);
+ void candidateContentForLine(LineCandidate&, size_t inlineItemIndex, const InlineItemRange& needsLayoutRange, InlineLayoutUnit currentLogicalRight);
size_t nextWrapOpportunity(size_t startIndex, const LineBuilder::InlineItemRange& layoutRange) const;
struct Result {
@@ -98,13 +98,13 @@
size_t rebuildLine(const InlineItemRange& needsLayoutRange, const InlineItem& lastInlineItemToAdd);
size_t rebuildLineForTrailingSoftHyphen(const InlineItemRange& layoutRange);
void commitPartialContent(const InlineContentBreaker::ContinuousContent::RunList&, const InlineContentBreaker::Result::PartialTrailingContent&);
- void initialize(const UsedConstraints&, bool isFirstLine);
+ void initialize(const UsedConstraints&, bool isFirstLine, size_t leadingInlineTextItemIndex, size_t partialLeadingContentLength, std::optional<InlineLayoutUnit> overflowingLogicalWidth);
struct CommittedContent {
size_t inlineItemCount { 0 };
size_t partialTrailingContentLength { 0 };
std::optional<InlineLayoutUnit> overflowLogicalWidth { };
};
- CommittedContent placeInlineContent(const InlineItemRange&, size_t partialLeadingContentLength, std::optional<InlineLayoutUnit> overflowLogicalWidth);
+ CommittedContent placeInlineContent(const InlineItemRange&);
InlineItemRange close(const InlineItemRange& needsLayoutRange, const CommittedContent&);
InlineLayoutUnit inlineItemWidth(const InlineItem&, InlineLayoutUnit contentLogicalLeft) const;
@@ -129,6 +129,7 @@
const InlineItems& m_inlineItems;
FloatList m_floats;
std::optional<InlineTextItem> m_partialLeadingTextItem;
+ std::optional<InlineLayoutUnit> m_overflowingLogicalWidth;
Vector<const InlineItem*> m_wrapOpportunityList;
unsigned m_successiveHyphenatedLineCount { 0 };
bool m_contentIsConstrainedByFloat { false };
diff --git a/Source/WebCore/layout/formattingContexts/inline/InlineTextItem.h b/Source/WebCore/layout/formattingContexts/inline/InlineTextItem.h
index 95cc717..978e51f 100644
--- a/Source/WebCore/layout/formattingContexts/inline/InlineTextItem.h
+++ b/Source/WebCore/layout/formattingContexts/inline/InlineTextItem.h
@@ -52,7 +52,7 @@
const InlineTextBox& inlineTextBox() const { return downcast<InlineTextBox>(layoutBox()); }
InlineTextItem left(unsigned length) const;
- InlineTextItem right(unsigned length) const;
+ InlineTextItem right(unsigned length, std::optional<InlineLayoutUnit> width) const;
static bool shouldPreserveSpacesAndTabs(const InlineTextItem&);
@@ -108,12 +108,12 @@
return { inlineTextBox(), start(), length, false, isWordSeparator(), std::nullopt, m_textItemType };
}
-inline InlineTextItem InlineTextItem::right(unsigned length) const
+inline InlineTextItem InlineTextItem::right(unsigned length, std::optional<InlineLayoutUnit> width) const
{
RELEASE_ASSERT(length <= this->length());
ASSERT(m_textItemType != TextItemType::Undefined);
ASSERT(length);
- return { inlineTextBox(), end() - length, length, hasTrailingSoftHyphen(), isWordSeparator(), std::nullopt, m_textItemType };
+ return { inlineTextBox(), end() - length, length, hasTrailingSoftHyphen(), isWordSeparator(), width, m_textItemType };
}
}