Modified: trunk/Source/WebCore/layout/inlineformatting/InlineFormattingContext.cpp (254836 => 254837)
--- trunk/Source/WebCore/layout/inlineformatting/InlineFormattingContext.cpp 2020-01-20 21:21:18 UTC (rev 254836)
+++ trunk/Source/WebCore/layout/inlineformatting/InlineFormattingContext.cpp 2020-01-20 23:32:51 UTC (rev 254837)
@@ -85,22 +85,22 @@
}
collectInlineContentIfNeeded();
- lineLayout(horizontalConstraints, verticalConstraints);
+
+ auto& inlineItems = formattingState().inlineItems();
+ lineLayout(inlineItems, { 0, inlineItems.size() }, horizontalConstraints, verticalConstraints);
LOG_WITH_STREAM(FormattingContextLayout, stream << "[End] -> inline formatting context -> formatting root(" << &root() << ")");
}
-void InlineFormattingContext::lineLayout(const HorizontalConstraints& horizontalConstraints, const VerticalConstraints& verticalConstraints)
+void InlineFormattingContext::lineLayout(InlineItems& inlineItems, LineLayoutContext::InlineItemRange layoutRange, const HorizontalConstraints& horizontalConstraints, const VerticalConstraints& verticalConstraints)
{
- auto& inlineItems = formattingState().inlineItems();
auto lineLogicalTop = verticalConstraints.logicalTop;
- unsigned leadingInlineItemIndex = 0;
Optional<unsigned> partialLeadingContentLength;
auto lineBuilder = LineBuilder { *this, root().style().textAlign(), LineBuilder::IntrinsicSizing::No };
auto lineLayoutContext = LineLayoutContext { *this, root(), inlineItems };
- while (leadingInlineItemIndex < inlineItems.size()) {
+ while (!layoutRange.isEmpty()) {
lineBuilder.initialize(constraintsForLine(horizontalConstraints, lineLogicalTop));
- auto lineContent = lineLayoutContext.layoutLine(lineBuilder, leadingInlineItemIndex, partialLeadingContentLength);
+ auto lineContent = lineLayoutContext.layoutLine(lineBuilder, layoutRange, partialLeadingContentLength);
setDisplayBoxesForLine(lineContent, horizontalConstraints);
partialLeadingContentLength = { };
@@ -108,12 +108,12 @@
lineLogicalTop = lineContent.lineBox.logicalBottom();
// When the trailing content is partial, we need to reuse the last InlinItem.
if (lineContent.partialContent) {
- leadingInlineItemIndex = *lineContent.trailingInlineItemIndex;
+ layoutRange.start = *lineContent.trailingInlineItemIndex;
// Turn previous line's overflow content length into the next line's leading content partial length.
// "sp<->litcontent" -> overflow length: 10 -> leading partial content length: 10.
partialLeadingContentLength = lineContent.partialContent->overflowContentLength;
} else
- leadingInlineItemIndex = *lineContent.trailingInlineItemIndex + 1;
+ layoutRange.start = *lineContent.trailingInlineItemIndex + 1;
continue;
}
// Floats prevented us placing any content on the line.
@@ -233,16 +233,16 @@
InlineLayoutUnit InlineFormattingContext::computedIntrinsicWidthForConstraint(const HorizontalConstraints& horizontalConstraints) const
{
auto& inlineItems = formattingState().inlineItems();
- InlineLayoutUnit maximumLineWidth = 0;
- unsigned leadingInlineItemIndex = 0;
+ auto maximumLineWidth = InlineLayoutUnit { };
auto lineBuilder = LineBuilder { *this, root().style().textAlign(), LineBuilder::IntrinsicSizing::Yes };
auto lineLayoutContext = LineLayoutContext { *this, root(), inlineItems };
- while (leadingInlineItemIndex < inlineItems.size()) {
+ auto layoutRange = LineLayoutContext::InlineItemRange { 0 , inlineItems.size() };
+ while (!layoutRange.isEmpty()) {
// Only the horiztonal available width is constrained when computing intrinsic width.
lineBuilder.initialize(LineBuilder::Constraints { { }, horizontalConstraints.logicalWidth, false, { } });
- auto lineContent = lineLayoutContext.layoutLine(lineBuilder, leadingInlineItemIndex, { });
+ auto lineContent = lineLayoutContext.layoutLine(lineBuilder, layoutRange , { });
- leadingInlineItemIndex = *lineContent.trailingInlineItemIndex + 1;
+ layoutRange.start = *lineContent.trailingInlineItemIndex + 1;
InlineLayoutUnit floatsWidth = 0;
for (auto& floatItem : lineContent.floats)
floatsWidth += geometryForBox(floatItem->layoutBox()).marginBoxWidth();
Modified: trunk/Source/WebCore/layout/inlineformatting/LineLayoutContext.cpp (254836 => 254837)
--- trunk/Source/WebCore/layout/inlineformatting/LineLayoutContext.cpp 2020-01-20 21:21:18 UTC (rev 254836)
+++ trunk/Source/WebCore/layout/inlineformatting/LineLayoutContext.cpp 2020-01-20 23:32:51 UTC (rev 254837)
@@ -105,7 +105,7 @@
return true;
}
-static inline size_t nextWrapOpportunity(const InlineItems& inlineContent, unsigned startIndex)
+static inline size_t nextWrapOpportunity(const InlineItems& inlineContent, size_t startIndex, const LineLayoutContext::InlineItemRange layoutRange)
{
// 1. Find the start candidate by skipping leading non-content items e.g <span><span>start : skip "<span><span>"
// 2. Find the end candidate by skipping non-content items inbetween e.g. <span><span>start</span>end: skip "</span>"
@@ -115,12 +115,11 @@
// [ex-][container start][container end][float][ample] (ex-<span></span><div style="float:left"></div>ample) : wrap index is at [ex-].
// [ex][container start][amp-][container start][le] (ex<span>amp-<span>ample) : wrap index is at [amp-].
// [ex-][container start][line break][ample] (ex-<span><br>ample) : wrap index is after [br].
- unsigned inlineItemCount = inlineContent.size();
auto isAtLineBreak = false;
auto inlineItemIndexWithContent = [&] (auto index) {
// Break at the first text/box/line break inline item.
- for (; index < inlineItemCount; ++index) {
+ for (; index < layoutRange.end; ++index) {
auto& inlineItem = inlineContent[index];
if (inlineItem.isText() || inlineItem.isBox())
return index;
@@ -129,7 +128,7 @@
return index;
}
}
- return inlineItemCount;
+ return layoutRange.end;
};
// Start at the first inline item with content.
@@ -140,11 +139,11 @@
return startContentIndex + 1;
}
- while (startContentIndex < inlineItemCount) {
+ while (startContentIndex < layoutRange.end) {
// 1. Find the next inline item with content.
// 2. Check if there's a soft wrap opportunity between the start and the next inline item.
auto nextContentIndex = inlineItemIndexWithContent(startContentIndex + 1);
- if (nextContentIndex == inlineItemCount)
+ if (nextContentIndex == layoutRange.end)
return nextContentIndex;
if (isAtLineBreak) {
// We always stop at line breaks. The wrap position is after the line break.
@@ -169,7 +168,7 @@
}
startContentIndex = nextContentIndex;
}
- return inlineItemCount;
+ return layoutRange.end;
}
struct LineCandidateContent {
@@ -253,7 +252,7 @@
{
}
-LineLayoutContext::LineContent LineLayoutContext::layoutLine(LineBuilder& line, unsigned leadingInlineItemIndex, Optional<unsigned> partialLeadingContentLength)
+LineLayoutContext::LineContent LineLayoutContext::layoutLine(LineBuilder& line, const InlineItemRange layoutRange, Optional<unsigned> partialLeadingContentLength)
{
auto reset = [&] {
ASSERT(m_floats.isEmpty());
@@ -262,15 +261,15 @@
};
reset();
auto lineBreaker = LineBreaker { };
- auto currentItemIndex = leadingInlineItemIndex;
+ auto currentItemIndex = layoutRange.start;
unsigned committedInlineItemCount = 0;
auto candidateContent = LineCandidateContent { };
- while (currentItemIndex < m_inlineItems.size()) {
+ while (currentItemIndex < layoutRange.end) {
// 1. Collect the set of runs that we can commit to the line as one entity e.g. <span>text_and_span_start_span_end</span>.
// 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.
- nextContentForLine(candidateContent, currentItemIndex, partialLeadingContentLength, line.lineBox().logicalWidth());
+ nextContentForLine(candidateContent, currentItemIndex, layoutRange, partialLeadingContentLength, line.lineBox().logicalWidth());
if (candidateContent.hasIntrusiveFloats()) {
// Add floats first because they shrink the available horizontal space for the rest of the content.
auto result = tryAddingFloatItems(line, candidateContent.floats());
@@ -277,7 +276,7 @@
committedInlineItemCount += result.committedCount;
if (result.isEndOfLine == LineBreaker::IsEndOfLine::Yes) {
// Floats take up all the horizontal space.
- return close(line, leadingInlineItemIndex, committedInlineItemCount, { });
+ return close(line, layoutRange, committedInlineItemCount, { });
}
}
if (!candidateContent.inlineRuns().isEmpty()) {
@@ -287,25 +286,25 @@
ASSERT(!result.committedCount);
ASSERT(result.isEndOfLine == LineBreaker::IsEndOfLine::Yes);
// An earlier line wrapping opportunity turned out to be the final breaking position.
- rebuildLineForRevert(line, *result.revertTo, leadingInlineItemIndex);
+ rebuildLineForRevert(line, *result.revertTo, layoutRange);
}
committedInlineItemCount += result.committedCount;
if (result.isEndOfLine == LineBreaker::IsEndOfLine::Yes) {
// We can't place any more items on the current line.
- return close(line, leadingInlineItemIndex, committedInlineItemCount, result.partialContent);
+ return close(line, layoutRange, committedInlineItemCount, result.partialContent);
}
} else if (auto* trailingLineBreak = candidateContent.trailingLineBreak()) {
line.append(*trailingLineBreak, 0);
- return close(line, leadingInlineItemIndex, ++committedInlineItemCount, { });
+ return close(line, layoutRange, ++committedInlineItemCount, { });
}
- currentItemIndex = leadingInlineItemIndex + committedInlineItemCount;
+ currentItemIndex = layoutRange.start + committedInlineItemCount;
partialLeadingContentLength = { };
}
// Looks like we've run out of runs.
- return close(line, leadingInlineItemIndex, committedInlineItemCount, { });
+ return close(line, layoutRange, committedInlineItemCount, { });
}
-LineLayoutContext::LineContent LineLayoutContext::close(LineBuilder& line, unsigned leadingInlineItemIndex, unsigned committedInlineItemCount, Optional<LineContent::PartialContent> partialContent)
+LineLayoutContext::LineContent LineLayoutContext::close(LineBuilder& line, const InlineItemRange layoutRange, unsigned committedInlineItemCount, Optional<LineContent::PartialContent> partialContent)
{
ASSERT(committedInlineItemCount || line.hasIntrusiveFloat());
if (!committedInlineItemCount)
@@ -317,14 +316,15 @@
else
m_successiveHyphenatedLineCount = 0;
- auto trailingInlineItemIndex = leadingInlineItemIndex + committedInlineItemCount - 1;
+ auto trailingInlineItemIndex = layoutRange.start + committedInlineItemCount - 1;
+ ASSERT(trailingInlineItemIndex < layoutRange.end);
auto isLastLineWithInlineContent = [&] {
- if (trailingInlineItemIndex == m_inlineItems.size() - 1)
+ if (trailingInlineItemIndex == layoutRange.end - 1)
return LineBuilder::IsLastLineWithInlineContent::Yes;
if (partialContent)
return LineBuilder::IsLastLineWithInlineContent::No;
// Omit floats to see if this is the last line with inline content.
- for (auto i = m_inlineItems.size(); i--;) {
+ for (auto i = layoutRange.end; i--;) {
if (!m_inlineItems[i].isFloat())
return i == trailingInlineItemIndex ? LineBuilder::IsLastLineWithInlineContent::Yes : LineBuilder::IsLastLineWithInlineContent::No;
}
@@ -335,28 +335,28 @@
return LineContent { trailingInlineItemIndex, partialContent, WTFMove(m_floats), line.close(isLastLineWithInlineContent), line.lineBox() };
}
-void LineLayoutContext::nextContentForLine(LineCandidateContent& candidateContent, unsigned inlineItemIndex, Optional<unsigned> partialLeadingContentLength, InlineLayoutUnit currentLogicalRight)
+void LineLayoutContext::nextContentForLine(LineCandidateContent& candidateContent, unsigned currentInlineItemIndex, const InlineItemRange layoutRange, Optional<unsigned> partialLeadingContentLength, InlineLayoutUnit currentLogicalRight)
{
- ASSERT(inlineItemIndex < m_inlineItems.size());
+ ASSERT(currentInlineItemIndex < layoutRange.end);
candidateContent.reset();
// 1. Simply add any overflow content from the previous line to the candidate content. It's always a text content.
// 2. Find the next soft wrap position or explicit line break.
// 3. Collect floats between the inline content.
- auto softWrapOpportunityIndex = nextWrapOpportunity(m_inlineItems, inlineItemIndex);
- // softWrapOpportunityIndex == m_inlineItems.size() means we don't have any wrap opportunity in this content.
- ASSERT(softWrapOpportunityIndex <= m_inlineItems.size());
+ auto softWrapOpportunityIndex = nextWrapOpportunity(m_inlineItems, currentInlineItemIndex, layoutRange);
+ // softWrapOpportunityIndex == layoutRange.end means we don't have any wrap opportunity in this content.
+ ASSERT(softWrapOpportunityIndex <= layoutRange.end);
if (partialLeadingContentLength) {
// Handle leading partial content first (split text from the previous line).
// Construct a partial leading inline item.
- m_partialLeadingTextItem = downcast<InlineTextItem>(m_inlineItems[inlineItemIndex]).right(*partialLeadingContentLength);
+ m_partialLeadingTextItem = downcast<InlineTextItem>(m_inlineItems[currentInlineItemIndex]).right(*partialLeadingContentLength);
auto itemWidth = inlineItemWidth(*m_partialLeadingTextItem, currentLogicalRight);
candidateContent.appendInlineContent(*m_partialLeadingTextItem, itemWidth);
currentLogicalRight += itemWidth;
- ++inlineItemIndex;
+ ++currentInlineItemIndex;
}
- for (auto index = inlineItemIndex; index < softWrapOpportunityIndex; ++index) {
+ for (auto index = currentInlineItemIndex; index < softWrapOpportunityIndex; ++index) {
auto& inlineItem = m_inlineItems[index];
if (inlineItem.isText() || inlineItem.isContainerStart() || inlineItem.isContainerEnd()) {
auto inlineItenmWidth = inlineItemWidth(inlineItem, currentLogicalRight);
@@ -478,11 +478,11 @@
}
}
-void LineLayoutContext::rebuildLineForRevert(LineBuilder& line, const InlineItem& revertTo, unsigned leadingInlineItemIndex)
+void LineLayoutContext::rebuildLineForRevert(LineBuilder& line, const InlineItem& revertTo, const InlineItemRange layoutRange)
{
// This is the rare case when the line needs to be reverted to an earlier position.
line.resetContent();
- auto inlineItemIndex = leadingInlineItemIndex;
+ auto inlineItemIndex = layoutRange.start;
InlineLayoutUnit logicalRight = { };
if (m_partialLeadingTextItem) {
auto logicalWidth = inlineItemWidth(*m_partialLeadingTextItem, logicalRight);
@@ -493,7 +493,7 @@
++inlineItemIndex;
}
- for (; inlineItemIndex < m_inlineItems.size(); ++inlineItemIndex) {
+ for (; inlineItemIndex < layoutRange.end; ++inlineItemIndex) {
auto& inlineItem = m_inlineItems[inlineItemIndex];
auto logicalWidth = inlineItemWidth(inlineItem, logicalRight);
line.append(inlineItem, logicalWidth);
Modified: trunk/Source/WebCore/layout/inlineformatting/LineLayoutContext.h (254836 => 254837)
--- trunk/Source/WebCore/layout/inlineformatting/LineLayoutContext.h 2020-01-20 21:21:18 UTC (rev 254836)
+++ trunk/Source/WebCore/layout/inlineformatting/LineLayoutContext.h 2020-01-20 23:32:51 UTC (rev 254837)
@@ -50,11 +50,16 @@
const LineBuilder::RunList runList;
const Display::LineBox lineBox;
};
- LineContent layoutLine(LineBuilder&, unsigned leadingInlineItemIndex, Optional<unsigned> partialLeadingContentLength);
+ struct InlineItemRange {
+ bool isEmpty() const { return start == end; }
+ size_t start { 0 };
+ size_t end { 0 };
+ };
+ LineContent layoutLine(LineBuilder&, const InlineItemRange, Optional<unsigned> partialLeadingContentLength);
using FloatList = Vector<const InlineItem*>;
private:
- void nextContentForLine(LineCandidateContent&, unsigned inlineItemIndex, Optional<unsigned> overflowLength, InlineLayoutUnit currentLogicalRight);
+ void nextContentForLine(LineCandidateContent&, unsigned inlineItemIndex, const InlineItemRange layoutRange, Optional<unsigned> overflowLength, InlineLayoutUnit currentLogicalRight);
struct Result {
LineBreaker::IsEndOfLine isEndOfLine { LineBreaker::IsEndOfLine::No };
size_t committedCount { 0 };
@@ -63,9 +68,9 @@
};
Result tryAddingFloatItems(LineBuilder&, const FloatList&);
Result tryAddingInlineItems(LineBreaker&, LineBuilder&, const LineCandidateContent&);
- void rebuildLineForRevert(LineBuilder&, const InlineItem& revertTo, unsigned leadingInlineItemIndex);
+ void rebuildLineForRevert(LineBuilder&, const InlineItem& revertTo, const InlineItemRange layoutRange);
void commitPartialContent(LineBuilder&, const LineBreaker::RunList&, const LineBreaker::Result::PartialTrailingContent&);
- LineContent close(LineBuilder&, unsigned leadingInlineItemIndex, unsigned committedInlineItemCount, Optional<LineContent::PartialContent>);
+ LineContent close(LineBuilder&, const InlineItemRange layoutRange, unsigned committedInlineItemCount, Optional<LineContent::PartialContent>);
InlineLayoutUnit inlineItemWidth(const InlineItem&, InlineLayoutUnit contentLogicalLeft) const;