Diff
Modified: trunk/Source/WebCore/ChangeLog (245811 => 245812)
--- trunk/Source/WebCore/ChangeLog 2019-05-28 14:51:16 UTC (rev 245811)
+++ trunk/Source/WebCore/ChangeLog 2019-05-28 15:36:04 UTC (rev 245812)
@@ -1,5 +1,27 @@
2019-05-28 Zalan Bujtas <[email protected]>
+ [LFC][IFC] Decouple line layout and processing inline runs.
+ https://bugs.webkit.org/show_bug.cgi?id=198282
+ <rdar://problem/51167954>
+
+ Reviewed by Antti Koivisto.
+
+ This is in preparation for using "createInlineRunsForLine" logic when computing preferred width.
+
+ * layout/inlineformatting/InlineFormattingContext.h:
+ * layout/inlineformatting/InlineFormattingContextLineLayout.cpp:
+ (WebCore::Layout::UncommittedContent::size const):
+ (WebCore::Layout::InlineFormattingContext::LineLayout::createInlineRunsForLine const):
+ (WebCore::Layout::InlineFormattingContext::LineLayout::layout const):
+ (WebCore::Layout::InlineFormattingContext::LineLayout::processInlineRuns const):
+ (WebCore::Layout::InlineFormattingContext::LineLayout::closeLine const): Deleted.
+ * layout/inlineformatting/InlineFormattingState.h:
+ (WebCore::Layout::InlineFormattingState::addInlineItem):
+ * layout/inlineformatting/InlineTextItem.cpp:
+ (WebCore::Layout::InlineTextItem::createAndAppendTextItems):
+
+2019-05-28 Zalan Bujtas <[email protected]>
+
[LFC][IFC] Move intrinsic width computation from InlineFormattingContext to LineLayout
https://bugs.webkit.org/show_bug.cgi?id=198258
Modified: trunk/Source/WebCore/layout/inlineformatting/InlineFormattingContext.h (245811 => 245812)
--- trunk/Source/WebCore/layout/inlineformatting/InlineFormattingContext.h 2019-05-28 14:51:16 UTC (rev 245811)
+++ trunk/Source/WebCore/layout/inlineformatting/InlineFormattingContext.h 2019-05-28 15:36:04 UTC (rev 245812)
@@ -59,7 +59,8 @@
private:
LayoutState& layoutState() const { return m_formattingContext.layoutState(); }
void initializeLine(Line&, LayoutUnit lineLogicalTop, LayoutUnit widthConstraint) const;
- void closeLine(Line&) const;
+ unsigned createInlineRunsForLine(Line&, unsigned firstInlineItemIndex) const;
+ void processInlineRuns(Line&) const;
void commitInlineItemToLine(Line&, const InlineItem&) const;
void handleFloat(Line&, const FloatingContext&, const InlineItem& floatBox) const;
void alignRuns(TextAlignMode, unsigned firstRunIndex, LayoutUnit availableWidth) const;
Modified: trunk/Source/WebCore/layout/inlineformatting/InlineFormattingContextLineLayout.cpp (245811 => 245812)
--- trunk/Source/WebCore/layout/inlineformatting/InlineFormattingContextLineLayout.cpp 2019-05-28 14:51:16 UTC (rev 245811)
+++ trunk/Source/WebCore/layout/inlineformatting/InlineFormattingContextLineLayout.cpp 2019-05-28 15:36:04 UTC (rev 245812)
@@ -336,6 +336,7 @@
Vector<InlineItem*> inlineItems() { return m_inlineItems; }
bool isEmpty() const { return m_inlineItems.isEmpty(); }
+ unsigned size() const { return m_inlineItems.size(); }
LayoutUnit width() const { return m_width; }
private:
@@ -398,65 +399,80 @@
line.reset({ lineLogicalLeft, lineLogicalTop }, availableWidth, mimimumLineHeight, baselineOffset);
}
-void InlineFormattingContext::LineLayout::layout(LayoutUnit widthConstraint) const
+unsigned InlineFormattingContext::LineLayout::createInlineRunsForLine(Line& line, unsigned startInlineItemIndex) const
{
auto floatingContext = FloatingContext { m_floatingState };
- Line line(layoutState());
- initializeLine(line, layoutState().displayBoxForLayoutBox(m_formattingRoot).contentBoxTop(), widthConstraint);
+ Optional<unsigned> lastCommittedIndex;
UncommittedContent uncommittedContent;
auto commitPendingContent = [&] {
+ if (uncommittedContent.isEmpty())
+ return;
+
+ lastCommittedIndex = lastCommittedIndex.valueOr(startInlineItemIndex) + uncommittedContent.size();
for (auto* uncommitted : uncommittedContent.inlineItems())
commitInlineItemToLine(line, *uncommitted);
uncommittedContent.reset();
};
- auto closeCurrentAndInitializeNewLine = [&] {
- closeLine(line);
- initializeLine(line, line.logicalBottom(), widthConstraint);
- };
-
LineBreaker lineBreaker(layoutState());
+ // Iterate through the inline content and place the inline boxes on the current line.
auto& inlineContent = m_formattingState.inlineItems();
- for (auto& inlineItem : inlineContent) {
- // Iterate through the inline content and try to put the inline boxes on the current line.
+ for (auto inlineItemIndex = startInlineItemIndex; inlineItemIndex < inlineContent.size(); ++inlineItemIndex) {
+ auto& inlineItem = inlineContent[inlineItemIndex];
if (inlineItem->isHardLineBreak()) {
+ uncommittedContent.add(*inlineItem);
commitPendingContent();
- commitInlineItemToLine(line, *inlineItem);
- closeCurrentAndInitializeNewLine();
- } else {
- auto availableWidth = line.availableWidth() - uncommittedContent.width();
- auto currentLogicalRight = line.contentLogicalRight() + uncommittedContent.width();
- // FIXME: Ensure LineContext::trimmableWidth includes uncommitted content if needed.
- auto breakingContext = lineBreaker.breakingContext(*inlineItem, { availableWidth, currentLogicalRight, line.trailingTrimmableWidth(), !line.hasContent() });
- if (breakingContext.isAtBreakingOpportunity)
- commitPendingContent();
+ return *lastCommittedIndex;
+ }
+ auto availableWidth = line.availableWidth() - uncommittedContent.width();
+ auto currentLogicalRight = line.contentLogicalRight() + uncommittedContent.width();
+ // FIXME: Ensure LineContext::trimmableWidth includes uncommitted content if needed.
+ auto breakingContext = lineBreaker.breakingContext(*inlineItem, { availableWidth, currentLogicalRight, line.trailingTrimmableWidth(), !line.hasContent() });
+ if (breakingContext.isAtBreakingOpportunity)
+ commitPendingContent();
- if (breakingContext.breakingBehavior == LineBreaker::BreakingBehavior::Break) {
- ASSERT_NOT_IMPLEMENTED_YET();
- continue;
- }
+ // Content does not fit the current line.
+ if (breakingContext.breakingBehavior == LineBreaker::BreakingBehavior::Wrap)
+ return *lastCommittedIndex;
- if (breakingContext.breakingBehavior == LineBreaker::BreakingBehavior::Wrap)
- closeCurrentAndInitializeNewLine();
+ // Partial content stays on the current line.
+ if (breakingContext.breakingBehavior == LineBreaker::BreakingBehavior::Break) {
+ ASSERT(inlineItem->isText());
- if (inlineItem->isFloat())
- handleFloat(line, floatingContext, *inlineItem);
- else {
- if (breakingContext.isAtBreakingOpportunity)
- commitInlineItemToLine(line, *inlineItem);
- else
- uncommittedContent.add(*inlineItem);
- }
+ ASSERT_NOT_IMPLEMENTED_YET();
+ return *lastCommittedIndex;
}
+
+ if (inlineItem->isFloat()) {
+ handleFloat(line, floatingContext, *inlineItem);
+ continue;
+ }
+
+ uncommittedContent.add(*inlineItem);
+ if (breakingContext.isAtBreakingOpportunity)
+ commitPendingContent();
}
- // Process remaining uncommitted content.
- if (!uncommittedContent.isEmpty()) {
- if (line.availableWidth() < uncommittedContent.width())
- closeCurrentAndInitializeNewLine();
- commitPendingContent();
+ commitPendingContent();
+ return *lastCommittedIndex;
+}
+
+void InlineFormattingContext::LineLayout::layout(LayoutUnit widthConstraint) const
+{
+ ASSERT(!m_formattingState.inlineItems().isEmpty());
+
+ Line line(layoutState());
+ initializeLine(line, layoutState().displayBoxForLayoutBox(m_formattingRoot).contentBoxTop(), widthConstraint);
+
+ unsigned startInlineItemIndex = 0;
+ while (true) {
+ auto nextInlineItemIndex = createInlineRunsForLine(line, startInlineItemIndex);
+ processInlineRuns(line);
+ if (nextInlineItemIndex == m_formattingState.inlineItems().size())
+ break;
+ startInlineItemIndex = nextInlineItemIndex;
+ initializeLine(line, line.logicalBottom(), widthConstraint);
}
- closeLine(line);
}
LayoutUnit InlineFormattingContext::LineLayout::computedIntrinsicWidth(LayoutUnit widthConstraint) const
@@ -487,7 +503,7 @@
return std::max(maximumLineWidth, lineLogicalRight - trimmableTrailingWidth);
}
-void InlineFormattingContext::LineLayout::closeLine(Line& line) const
+void InlineFormattingContext::LineLayout::processInlineRuns(Line& line) const
{
auto& lineItems = line.close();
if (lineItems.isEmpty()) {
Modified: trunk/Source/WebCore/layout/inlineformatting/InlineFormattingState.h (245811 => 245812)
--- trunk/Source/WebCore/layout/inlineformatting/InlineFormattingState.h 2019-05-28 14:51:16 UTC (rev 245811)
+++ trunk/Source/WebCore/layout/inlineformatting/InlineFormattingState.h 2019-05-28 15:36:04 UTC (rev 245812)
@@ -38,7 +38,7 @@
namespace Layout {
// Temp
-using InlineItems = ListHashSet<std::unique_ptr<InlineItem>>;
+using InlineItems = Vector<std::unique_ptr<InlineItem>>;
using InlineRuns = Vector<std::unique_ptr<Display::Run>>;
using LineBoxes = Vector<LineBox>;
// InlineFormattingState holds the state for a particular inline formatting context tree.
@@ -54,7 +54,7 @@
InlineRuns& inlineRuns() { return m_inlineRuns; }
LineBoxes& lineBoxes() { return m_lineBoxes; }
- void addInlineItem(std::unique_ptr<InlineItem>&& inlineItem) { m_inlineItems.add(WTFMove(inlineItem)); }
+ void addInlineItem(std::unique_ptr<InlineItem>&& inlineItem) { m_inlineItems.append(WTFMove(inlineItem)); }
void addInlineRun(std::unique_ptr<Display::Run>&& inlineRun) { m_inlineRuns.append(WTFMove(inlineRun)); }
void addLineBox(LineBox lineBox) { m_lineBoxes.append(lineBox); }
Modified: trunk/Source/WebCore/layout/inlineformatting/InlineTextItem.cpp (245811 => 245812)
--- trunk/Source/WebCore/layout/inlineformatting/InlineTextItem.cpp 2019-05-28 14:51:16 UTC (rev 245811)
+++ trunk/Source/WebCore/layout/inlineformatting/InlineTextItem.cpp 2019-05-28 15:36:04 UTC (rev 245812)
@@ -98,7 +98,7 @@
while (currentPosition < text.length()) {
// Soft linebreak?
if (isSoftLineBreak(text[currentPosition], preserveNewline)) {
- inlineContent.add(std::make_unique<InlineTextItem>(inlineBox, currentPosition, 1, true, false));
+ inlineContent.append(std::make_unique<InlineTextItem>(inlineBox, currentPosition, 1, true, false));
++currentPosition;
continue;
}
@@ -105,13 +105,13 @@
if (isWhitespaceCharacter(text[currentPosition], preserveNewline)) {
auto length = moveToNextNonWhitespacePosition(text, currentPosition, preserveNewline);
auto isCollapsed = collapseWhiteSpace && length > 1;
- inlineContent.add(std::make_unique<InlineTextItem>(inlineBox, currentPosition, length, true, isCollapsed));
+ inlineContent.append(std::make_unique<InlineTextItem>(inlineBox, currentPosition, length, true, isCollapsed));
currentPosition += length;
continue;
}
auto length = moveToNextBreakablePosition(currentPosition, lineBreakIterator, style);
- inlineContent.add(std::make_unique<InlineTextItem>(inlineBox, currentPosition, length, false, false));
+ inlineContent.append(std::make_unique<InlineTextItem>(inlineBox, currentPosition, length, false, false));
currentPosition += length;
}
}