Diff
Modified: trunk/Source/WebCore/ChangeLog (284322 => 284323)
--- trunk/Source/WebCore/ChangeLog 2021-10-16 20:32:52 UTC (rev 284322)
+++ trunk/Source/WebCore/ChangeLog 2021-10-16 21:14:57 UTC (rev 284323)
@@ -1,5 +1,19 @@
2021-10-16 Alan Bujtas <za...@apple.com>
+ [LFC][IFC] Add "line spanning line box start items" to Line
+ https://bugs.webkit.org/show_bug.cgi?id=231551
+
+ Reviewed by Antti Koivisto.
+
+ This patch is in preparation for supporting box-decoration-break: clone, where the line spanning
+ inline boxes may take up space on the line (border/padding).
+ This patch moves the construction of the spanning inline boxes to an earlier step, from LineBox to Line.
+
+ * layout/formattingContexts/inline/InlineLineBuilder.cpp:
+ (WebCore::Layout::LineBuilder::initialize):
+
+2021-10-16 Alan Bujtas <za...@apple.com>
+
[LFC][IFC] Move overflowing content creation to LineBuilder::initialize
https://bugs.webkit.org/show_bug.cgi?id=231540
Modified: trunk/Source/WebCore/layout/formattingContexts/inline/InlineDisplayContentBuilder.cpp (284322 => 284323)
--- trunk/Source/WebCore/layout/formattingContexts/inline/InlineDisplayContentBuilder.cpp 2021-10-16 20:32:52 UTC (rev 284322)
+++ trunk/Source/WebCore/layout/formattingContexts/inline/InlineDisplayContentBuilder.cpp 2021-10-16 21:14:57 UTC (rev 284323)
@@ -78,8 +78,7 @@
return !lineIndex ? layoutBox.firstLineStyle() : layoutBox.style();
}();
- switch (lineRun.type()) {
- case InlineItem::Type::Text: {
+ if (lineRun.isText()) {
auto textRunRect = lineBox.logicalRectForTextRun(lineRun);
textRunRect.moveBy(lineBoxLogicalTopLeft);
@@ -110,9 +109,9 @@
, inkOverflow()
, lineRun.expansion()
, InlineDisplay::Box::Text { text->start, text->length, content, adjustedContentToRender(), text->needsHyphen } });
- break;
+ continue;
}
- case InlineItem::Type::SoftLineBreak: {
+ if (lineRun.isSoftLineBreak()) {
auto softLineBreakRunRect = lineBox.logicalRectForTextRun(lineRun);
softLineBreakRunRect.moveBy(lineBoxLogicalTopLeft);
@@ -127,7 +126,7 @@
, InlineDisplay::Box::Text { text->start, text->length, downcast<InlineTextBox>(layoutBox).content() } });
break;
}
- case InlineItem::Type::HardLineBreak: {
+ if (lineRun.isHardLineBreak()) {
// Only hard linebreaks have associated layout boxes.
auto lineBreakBoxRect = lineBox.logicalRectForLineBreakBox(layoutBox);
lineBreakBoxRect.moveBy(lineBoxLogicalTopLeft);
@@ -136,9 +135,9 @@
auto& boxGeometry = formattingState.boxGeometry(layoutBox);
boxGeometry.setLogicalTopLeft(toLayoutPoint(lineBreakBoxRect.topLeft()));
boxGeometry.setContentBoxHeight(toLayoutUnit(lineBreakBoxRect.height()));
- break;
+ continue;
}
- case InlineItem::Type::Box: {
+ if (lineRun.isBox()) {
ASSERT(layoutBox.isAtomicInlineLevelBox());
auto& boxGeometry = formattingState.boxGeometry(layoutBox);
auto logicalBorderBox = lineBox.logicalBorderBoxForAtomicInlineLevelBox(layoutBox, boxGeometry);
@@ -161,9 +160,9 @@
boxes[m_inlineBoxIndexMap.get(&parentInlineBox)].adjustInkOverflow(logicalBorderBox);
};
adjustParentInlineBoxInkOverflow();
- break;
+ continue;
}
- case InlineItem::Type::InlineBoxStart: {
+ if (lineRun.isInlineBoxStart()) {
// This inline box showed up first on this line.
auto& boxGeometry = formattingState.boxGeometry(layoutBox);
auto inlineBoxBorderBox = lineBox.logicalBorderBoxForInlineBox(layoutBox, boxGeometry);
@@ -185,12 +184,9 @@
boxGeometry.setContentBoxHeight(contentBoxHeight);
auto contentBoxWidth = logicalRect.width() - (boxGeometry.horizontalBorder() + boxGeometry.horizontalPadding().value_or(0_lu));
boxGeometry.setContentBoxWidth(contentBoxWidth);
- break;
+ continue;
}
- default:
- ASSERT(lineRun.isInlineBoxEnd() || lineRun.isWordBreakOpportunity());
- break;
- }
+ ASSERT(lineRun.isInlineBoxEnd() || lineRun.isWordBreakOpportunity() || lineRun.isLineSpanningInlineBoxStart());
}
}
Modified: trunk/Source/WebCore/layout/formattingContexts/inline/InlineItem.h (284322 => 284323)
--- trunk/Source/WebCore/layout/formattingContexts/inline/InlineItem.h 2021-10-16 20:32:52 UTC (rev 284322)
+++ trunk/Source/WebCore/layout/formattingContexts/inline/InlineItem.h 2021-10-16 21:14:57 UTC (rev 284323)
@@ -35,7 +35,16 @@
class InlineItem {
public:
- enum class Type : uint8_t { Text, HardLineBreak, SoftLineBreak, WordBreakOpportunity, Box, Float, InlineBoxStart, InlineBoxEnd };
+ enum class Type : uint8_t {
+ Text,
+ HardLineBreak,
+ SoftLineBreak,
+ WordBreakOpportunity,
+ Box,
+ InlineBoxStart,
+ InlineBoxEnd,
+ Float
+ };
InlineItem(const Box& layoutBox, Type);
Type type() const { return m_type; }
Modified: trunk/Source/WebCore/layout/formattingContexts/inline/InlineLine.cpp (284322 => 284323)
--- trunk/Source/WebCore/layout/formattingContexts/inline/InlineLine.cpp 2021-10-16 20:32:52 UTC (rev 284322)
+++ trunk/Source/WebCore/layout/formattingContexts/inline/InlineLine.cpp 2021-10-16 21:14:57 UTC (rev 284323)
@@ -50,12 +50,17 @@
{
}
-void Line::initialize()
+void Line::initialize(const Vector<InlineItem>& lineSpanningInlineBoxes)
{
m_nonSpanningInlineLevelBoxCount = 0;
m_contentLogicalWidth = { };
m_runs.clear();
resetTrailingContent();
+ auto appendLineSpanningInlineBoxes = [&] {
+ for (auto& inlineBoxStartItem : lineSpanningInlineBoxes)
+ m_runs.append({ inlineBoxStartItem });
+ };
+ appendLineSpanningInlineBoxes();
}
void Line::resetTrailingContent()
@@ -192,7 +197,7 @@
for (auto& run : WTF::makeReversedRange(m_runs)) {
if (!run.shouldTrailingWhitespaceHang())
break;
- auto visuallyCollapsibleInlineItem = run.isInlineBoxStart() || run.isInlineBoxEnd() || run.hasTrailingWhitespace();
+ auto visuallyCollapsibleInlineItem = run.isLineSpanningInlineBoxStart() || run.isInlineBoxStart() || run.isInlineBoxEnd() || run.hasTrailingWhitespace();
if (!visuallyCollapsibleInlineItem)
break;
ASSERT(!run.hasCollapsibleTrailingWhitespace());
@@ -280,7 +285,7 @@
// provided both spaces are within the same inline formatting context—is collapsed to have zero advance width.
if (run.isText())
return run.hasCollapsibleTrailingWhitespace();
- ASSERT(run.isInlineBoxStart() || run.isInlineBoxEnd() || run.isWordBreakOpportunity());
+ ASSERT(run.isLineSpanningInlineBoxStart() || run.isInlineBoxStart() || run.isInlineBoxEnd() || run.isWordBreakOpportunity());
}
// Leading whitespace.
return true;
@@ -445,7 +450,7 @@
// not produce a run since in ::appendText() we see it as a fully collapsible run.
for (auto index = *m_firstTrimmableRunIndex + 1; index < m_runs.size(); ++index) {
auto& run = m_runs[index];
- ASSERT(run.isWordBreakOpportunity() || run.isInlineBoxStart() || run.isInlineBoxEnd() || run.isLineBreak());
+ ASSERT(run.isWordBreakOpportunity() || run.isLineSpanningInlineBoxStart() || run.isInlineBoxStart() || run.isInlineBoxEnd() || run.isLineBreak());
run.moveHorizontally(-trimmableWidth);
}
if (!trimmableRun.textContent()->length) {
@@ -475,8 +480,27 @@
m_length += trailingWhitespace.length();
}
+inline static Line::Run::Type toLineRunType(InlineItem::Type inlineItemType)
+{
+ switch (inlineItemType) {
+ case InlineItem::Type::HardLineBreak:
+ return Line::Run::Type::HardLineBreak;
+ case InlineItem::Type::WordBreakOpportunity:
+ return Line::Run::Type::WordBreakOpportunity;
+ case InlineItem::Type::Box:
+ return Line::Run::Type::AtomicBox;
+ case InlineItem::Type::InlineBoxStart:
+ return Line::Run::Type::InlineBoxStart;
+ case InlineItem::Type::InlineBoxEnd:
+ return Line::Run::Type::InlineBoxEnd;
+ default:
+ RELEASE_ASSERT_NOT_REACHED();
+ }
+ return { };
+}
+
Line::Run::Run(const InlineItem& inlineItem, const RenderStyle& style, InlineLayoutUnit logicalLeft, InlineLayoutUnit logicalWidth)
- : m_type(inlineItem.type())
+ : m_type(toLineRunType(inlineItem.type()))
, m_layoutBox(&inlineItem.layoutBox())
, m_logicalLeft(logicalLeft)
, m_logicalWidth(logicalWidth)
@@ -485,14 +509,21 @@
}
Line::Run::Run(const InlineItem& zeroWidhtInlineItem, InlineLayoutUnit logicalLeft)
- : m_type(zeroWidhtInlineItem.type())
+ : m_type(toLineRunType(zeroWidhtInlineItem.type()))
, m_layoutBox(&zeroWidhtInlineItem.layoutBox())
, m_logicalLeft(logicalLeft)
{
}
+Line::Run::Run(const InlineItem& lineSpanningInlineBoxItem)
+ : m_type(Type::LineSpanningInlineBoxStart)
+ , m_layoutBox(&lineSpanningInlineBoxItem.layoutBox())
+{
+ ASSERT(lineSpanningInlineBoxItem.isInlineBoxStart());
+}
+
Line::Run::Run(const InlineSoftLineBreakItem& softLineBreakItem, InlineLayoutUnit logicalLeft)
- : m_type(softLineBreakItem.type())
+ : m_type(Type::SoftLineBreak)
, m_layoutBox(&softLineBreakItem.layoutBox())
, m_logicalLeft(logicalLeft)
, m_textContent({ softLineBreakItem.position(), 1 })
@@ -500,7 +531,7 @@
}
Line::Run::Run(const InlineTextItem& inlineTextItem, const RenderStyle& style, InlineLayoutUnit logicalLeft, InlineLayoutUnit logicalWidth)
- : m_type(InlineItem::Type::Text)
+ : m_type(Type::Text)
, m_layoutBox(&inlineTextItem.layoutBox())
, m_logicalLeft(logicalLeft)
, m_logicalWidth(logicalWidth)
Modified: trunk/Source/WebCore/layout/formattingContexts/inline/InlineLine.h (284322 => 284323)
--- trunk/Source/WebCore/layout/formattingContexts/inline/InlineLine.h 2021-10-16 20:32:52 UTC (rev 284322)
+++ trunk/Source/WebCore/layout/formattingContexts/inline/InlineLine.h 2021-10-16 21:14:57 UTC (rev 284323)
@@ -42,10 +42,12 @@
Line(const InlineFormattingContext&);
~Line();
- void initialize();
+ void initialize(const Vector<InlineItem>& lineSpanningInlineBoxes);
void append(const InlineItem&, const RenderStyle&, InlineLayoutUnit logicalWidth);
+ bool hasContent() const { return !m_runs.isEmpty() && !m_runs.last().isLineSpanningInlineBoxStart(); }
+
InlineLayoutUnit contentLogicalWidth() const { return m_contentLogicalWidth; }
InlineLayoutUnit contentLogicalRight() const { return m_runs.isEmpty() ? 0.0f : m_runs.last().logicalRight(); }
size_t nonSpanningInlineLevelBoxCount() const { return m_nonSpanningInlineLevelBoxCount; }
@@ -62,15 +64,26 @@
void applyRunExpansion(InlineLayoutUnit horizontalAvailableSpace);
struct Run {
- bool isText() const { return m_type == InlineItem::Type::Text; }
- bool isBox() const { return m_type == InlineItem::Type::Box; }
+ enum class Type : uint8_t {
+ Text,
+ HardLineBreak,
+ SoftLineBreak,
+ WordBreakOpportunity,
+ AtomicBox,
+ InlineBoxStart,
+ InlineBoxEnd,
+ LineSpanningInlineBoxStart
+ };
+
+ bool isText() const { return m_type == Type::Text; }
+ bool isBox() const { return m_type == Type::AtomicBox; }
bool isLineBreak() const { return isHardLineBreak() || isSoftLineBreak(); }
- bool isSoftLineBreak() const { return m_type == InlineItem::Type::SoftLineBreak; }
- bool isHardLineBreak() const { return m_type == InlineItem::Type::HardLineBreak; }
- bool isWordBreakOpportunity() const { return m_type == InlineItem::Type::WordBreakOpportunity; }
- bool isInlineBoxStart() const { return m_type == InlineItem::Type::InlineBoxStart; }
- bool isInlineBoxEnd() const { return m_type == InlineItem::Type::InlineBoxEnd; }
- auto type() const { return m_type; }
+ bool isSoftLineBreak() const { return m_type == Type::SoftLineBreak; }
+ bool isHardLineBreak() const { return m_type == Type::HardLineBreak; }
+ bool isWordBreakOpportunity() const { return m_type == Type::WordBreakOpportunity; }
+ bool isInlineBoxStart() const { return m_type == Type::InlineBoxStart; }
+ bool isLineSpanningInlineBoxStart() const { return m_type == Type::LineSpanningInlineBoxStart; }
+ bool isInlineBoxEnd() const { return m_type == Type::InlineBoxEnd; }
const Box& layoutBox() const { return *m_layoutBox; }
struct Text {
@@ -101,6 +114,7 @@
Run(const InlineSoftLineBreakItem&, InlineLayoutUnit logicalLeft);
Run(const InlineItem&, const RenderStyle&, InlineLayoutUnit logicalLeft, InlineLayoutUnit logicalWidth);
Run(const InlineItem&, InlineLayoutUnit logicalLeft);
+ Run(const InlineItem& lineSpanningInlineBoxItem);
void expand(const InlineTextItem&, InlineLayoutUnit logicalWidth);
void moveHorizontally(InlineLayoutUnit offset) { m_logicalLeft += offset; }
@@ -124,7 +138,7 @@
InlineLayoutUnit trailingLetterSpacing() const;
void removeTrailingLetterSpacing();
- InlineItem::Type m_type { InlineItem::Type::Text };
+ Type m_type { Type::Text };
const Box* m_layoutBox { nullptr };
InlineLayoutUnit m_logicalLeft { 0 };
InlineLayoutUnit m_logicalWidth { 0 };
Modified: trunk/Source/WebCore/layout/formattingContexts/inline/InlineLineBoxBuilder.cpp (284322 => 284323)
--- trunk/Source/WebCore/layout/formattingContexts/inline/InlineLineBoxBuilder.cpp 2021-10-16 20:32:52 UTC (rev 284322)
+++ trunk/Source/WebCore/layout/formattingContexts/inline/InlineLineBoxBuilder.cpp 2021-10-16 21:14:57 UTC (rev 284323)
@@ -254,43 +254,6 @@
return !lineIndex ? layoutBox.firstLineStyle() : layoutBox.style();
};
- auto createLineSpanningInlineBoxes = [&] {
- if (runs.isEmpty())
- return;
- // An inline box may not necessarily start on the current line:
- // <span id=outer>line break<br>this content's parent inline box('outer') <span id=inner>starts on the previous line</span></span>
- // We need to make sure that there's an InlineLevelBox for every inline box that's present on the current line.
- // In nesting case we need to create InlineLevelBoxes for the inline box ancestors.
- // We only have to do it on the first run as any subsequent inline content is either at the same/higher nesting level or
- // nested with a [inline box start] run.
- auto& firstRun = runs[0];
- auto& firstRunParentLayoutBox = firstRun.layoutBox().parent();
- // If the parent is the formatting root, we can stop here. This is root inline box content, there's no nesting inline box from the previous line(s)
- // unless the inline box closing is forced over to the current line.
- // e.g.
- // <span>normally the inline box closing forms a continuous content</span>
- // <span>unless it's forced to the next line<br></span>
- auto firstRunNeedsInlineBox = firstRun.isInlineBoxEnd();
- if (!firstRunNeedsInlineBox && isRootLayoutBox(firstRunParentLayoutBox))
- return;
- Vector<const Box*> layoutBoxesWithoutInlineBoxes;
- if (firstRunNeedsInlineBox)
- layoutBoxesWithoutInlineBoxes.append(&firstRun.layoutBox());
- auto* ancestor = &firstRunParentLayoutBox;
- while (!isRootLayoutBox(*ancestor)) {
- layoutBoxesWithoutInlineBoxes.append(ancestor);
- ancestor = &ancestor->parent();
- }
- // Construct the missing LineBox::InlineBoxes starting with the topmost layout box.
- for (auto* layoutBox : WTF::makeReversedRange(layoutBoxesWithoutInlineBoxes)) {
- auto inlineBox = InlineLevelBox::createInlineBox(*layoutBox, styleToUse(*layoutBox), rootInlineBox.logicalLeft(), rootInlineBox.logicalWidth(), InlineLevelBox::LineSpanningInlineBox::Yes);
- setInitialVerticalGeometryForInlineBox(inlineBox);
- updateCanUseSimplifiedAlignment(inlineBox);
- lineBox.addInlineLevelBox(WTFMove(inlineBox));
- }
- };
- createLineSpanningInlineBoxes();
-
auto lineHasContent = false;
for (auto& run : runs) {
auto& layoutBox = run.layoutBox();
@@ -299,6 +262,10 @@
ASSERT(!lineHasContent);
if (run.isText() || run.isBox() || run.isSoftLineBreak() || run.isHardLineBreak())
return true;
+ if (run.isLineSpanningInlineBoxStart())
+ return false;
+ if (run.isWordBreakOpportunity())
+ return false;
auto& inlineBoxGeometry = formattingContext().geometryForBox(layoutBox);
// Even negative horizontal margin makes the line "contentful".
if (run.isInlineBoxStart())
@@ -305,8 +272,6 @@
return inlineBoxGeometry.marginStart() || inlineBoxGeometry.borderLeft() || inlineBoxGeometry.paddingLeft().value_or(0_lu);
if (run.isInlineBoxEnd())
return inlineBoxGeometry.marginEnd() || inlineBoxGeometry.borderRight() || inlineBoxGeometry.paddingRight().value_or(0_lu);
- if (run.isWordBreakOpportunity())
- return false;
ASSERT_NOT_REACHED();
return true;
};
@@ -344,6 +309,13 @@
lineBox.addInlineLevelBox(WTFMove(atomicInlineLevelBox));
continue;
}
+ if (run.isLineSpanningInlineBoxStart()) {
+ auto inlineBox = InlineLevelBox::createInlineBox(layoutBox, style, logicalLeft, rootInlineBox.logicalWidth(), InlineLevelBox::LineSpanningInlineBox::Yes);
+ setInitialVerticalGeometryForInlineBox(inlineBox);
+ updateCanUseSimplifiedAlignment(inlineBox);
+ lineBox.addInlineLevelBox(WTFMove(inlineBox));
+ continue;
+ }
if (run.isInlineBoxStart()) {
// At this point we don't know yet how wide this inline box is. Let's assume it's as long as the line is
// and adjust it later if we come across an inlineBoxEnd run (see below).
Modified: trunk/Source/WebCore/layout/formattingContexts/inline/InlineLineBoxBuilder.h (284322 => 284323)
--- trunk/Source/WebCore/layout/formattingContexts/inline/InlineLineBoxBuilder.h 2021-10-16 20:32:52 UTC (rev 284322)
+++ trunk/Source/WebCore/layout/formattingContexts/inline/InlineLineBoxBuilder.h 2021-10-16 21:14:57 UTC (rev 284323)
@@ -60,8 +60,6 @@
const Box& rootBox() const { return formattingContext().root(); }
LayoutState& layoutState() const { return formattingContext().layoutState(); }
- bool isRootLayoutBox(const ContainerBox& containerBox) const { return &containerBox == &rootBox(); }
-
private:
const InlineFormattingContext& m_inlineFormattingContext;
};
Modified: trunk/Source/WebCore/layout/formattingContexts/inline/InlineLineBuilder.cpp (284322 => 284323)
--- trunk/Source/WebCore/layout/formattingContexts/inline/InlineLineBuilder.cpp 2021-10-16 20:32:52 UTC (rev 284322)
+++ trunk/Source/WebCore/layout/formattingContexts/inline/InlineLineBuilder.cpp 2021-10-16 21:14:57 UTC (rev 284323)
@@ -292,19 +292,50 @@
return { committedRange, m_line.contentLogicalWidth(), m_floats };
}
-void LineBuilder::initialize(const UsedConstraints& lineConstraints, bool isFirstLine, size_t leadingInlineTextItemIndex, size_t partialLeadingContentLength, std::optional<InlineLayoutUnit> overflowingLogicalWidth)
+void LineBuilder::initialize(const UsedConstraints& lineConstraints, bool isFirstLine, size_t leadingInlineItemIndex, size_t partialLeadingContentLength, std::optional<InlineLayoutUnit> overflowingLogicalWidth)
{
m_isFirstLine = isFirstLine;
m_floats.clear();
+ m_lineSpanningInlineBoxes.clear();
m_wrapOpportunityList.clear();
- m_line.initialize();
+ auto createLineSpanningInlineBoxes = [&] {
+ auto isRootLayoutBox = [&](auto& containerBox) {
+ return &containerBox == &root();
+ };
+ // An inline box may not necessarily start on the current line:
+ // <span>first line<br>second line<span>with some more embedding<br> forth line</span></span>
+ // We need to make sure that there's an [InlineBoxStart] for every inline box that's present on the current line.
+ // We only have to do it on the first run as any subsequent inline content is either at the same/higher nesting level.
+ auto& firstInlineItem = m_inlineItems[leadingInlineItemIndex];
+ // If the parent is the formatting root, we can stop here. This is root inline box content, there's no nesting inline box from the previous line(s)
+ // unless the inline box closing is forced over to the current line.
+ // e.g.
+ // <span>normally the inline box closing forms a continuous content</span>
+ // <span>unless it's forced to the next line<br></span>
+ auto firstInlineItemIsLineSpanning = firstInlineItem.isInlineBoxEnd();
+ if (!firstInlineItemIsLineSpanning && isRootLayoutBox(firstInlineItem.layoutBox().parent()))
+ return;
+ Vector<const Box*> spanningLayoutBoxList;
+ if (firstInlineItemIsLineSpanning)
+ spanningLayoutBoxList.append(&firstInlineItem.layoutBox());
+ auto* ancestor = &firstInlineItem.layoutBox().parent();
+ while (!isRootLayoutBox(*ancestor)) {
+ spanningLayoutBoxList.append(ancestor);
+ ancestor = &ancestor->parent();
+ }
+ for (auto* spanningInlineBox : WTF::makeReversedRange(spanningLayoutBoxList))
+ m_lineSpanningInlineBoxes.append({ *spanningInlineBox, InlineItem::Type::InlineBoxStart });
+ };
+ createLineSpanningInlineBoxes();
+ m_line.initialize(m_lineSpanningInlineBoxes);
+
m_lineLogicalRect = lineConstraints.logicalRect;
m_contentIsConstrainedByFloat = lineConstraints.isConstrainedByFloat;
if (partialLeadingContentLength) {
ASSERT(!isFirstLine);
- m_partialLeadingTextItem = downcast<InlineTextItem>(m_inlineItems[leadingInlineTextItemIndex]).right(partialLeadingContentLength, overflowingLogicalWidth);
+ m_partialLeadingTextItem = downcast<InlineTextItem>(m_inlineItems[leadingInlineItemIndex]).right(partialLeadingContentLength, overflowingLogicalWidth);
m_overflowingLogicalWidth = { };
} else {
m_partialLeadingTextItem = { };
@@ -386,7 +417,7 @@
if (runsExpandHorizontally)
m_line.applyRunExpansion(horizontalAvailableSpace);
auto lineEndsWithHyphen = false;
- if (!m_line.runs().isEmpty()) {
+ if (m_line.hasContent()) {
auto& lastTextContent = m_line.runs().last().textContent();
lineEndsWithHyphen = lastTextContent && lastTextContent->needsHyphen;
}
@@ -707,7 +738,7 @@
return std::isnan(availableWidthForContent) ? maxInlineLayoutUnit() : availableWidthForContent;
}();
// While the floats are not considered to be on the line, they make the line contentful for line breaking.
- auto lineHasContent = !m_line.runs().isEmpty() || m_contentIsConstrainedByFloat;
+ auto lineHasContent = m_line.hasContent() || m_contentIsConstrainedByFloat;
auto lineStatus = InlineContentBreaker::LineStatus { m_line.contentLogicalRight(), availableWidth, m_line.trimmableTrailingWidth(), m_line.trailingSoftHyphenWidth(), m_line.isTrailingRunFullyTrimmable(), lineHasContent, !m_wrapOpportunityList.isEmpty() };
auto result = inlineContentBreaker.processInlineContent(continuousInlineContent, lineStatus);
auto& candidateRuns = continuousInlineContent.runs();
@@ -721,7 +752,7 @@
auto& trailingRun = candidateRuns.last();
// FIXME: There must be a way to decide if the trailing run actually ended up on the line.
// Let's just deal with collapsed leading whitespace for now.
- if (!m_line.runs().isEmpty() && TextUtil::isWrappingAllowed(trailingRun.style))
+ if (m_line.hasContent() && TextUtil::isWrappingAllowed(trailingRun.style))
m_wrapOpportunityList.append(&trailingRun.inlineItem);
}
return { result.isEndOfLine, { candidateRuns.size(), false } };
@@ -826,7 +857,7 @@
ASSERT(!m_wrapOpportunityList.isEmpty());
// We might already have added floats. They shrink the available horizontal space for the line.
// Let's just reuse what the line has at this point.
- m_line.initialize();
+ m_line.initialize(m_lineSpanningInlineBoxes);
auto currentItemIndex = layoutRange.start;
if (m_partialLeadingTextItem) {
m_line.append(*m_partialLeadingTextItem, m_partialLeadingTextItem->style(), inlineItemWidth(*m_partialLeadingTextItem, { }));
Modified: trunk/Source/WebCore/layout/formattingContexts/inline/InlineLineBuilder.h (284322 => 284323)
--- trunk/Source/WebCore/layout/formattingContexts/inline/InlineLineBuilder.h 2021-10-16 20:32:52 UTC (rev 284322)
+++ trunk/Source/WebCore/layout/formattingContexts/inline/InlineLineBuilder.h 2021-10-16 21:14:57 UTC (rev 284323)
@@ -131,6 +131,7 @@
std::optional<InlineTextItem> m_partialLeadingTextItem;
std::optional<InlineLayoutUnit> m_overflowingLogicalWidth;
Vector<const InlineItem*> m_wrapOpportunityList;
+ Vector<InlineItem> m_lineSpanningInlineBoxes;
unsigned m_successiveHyphenatedLineCount { 0 };
bool m_contentIsConstrainedByFloat { false };
};