Modified: trunk/Source/WebCore/ChangeLog (287441 => 287442)
--- trunk/Source/WebCore/ChangeLog 2021-12-26 06:10:32 UTC (rev 287441)
+++ trunk/Source/WebCore/ChangeLog 2021-12-26 06:16:27 UTC (rev 287442)
@@ -1,5 +1,30 @@
2021-12-25 Alan Bujtas <[email protected]>
+ [LFC][IFC] Turn InlineContentBreaker::ContinuousContent's leading/trailing member variables to std::optional<InlineLayoutUnit>
+ https://bugs.webkit.org/show_bug.cgi?id=234676
+
+ Reviewed by Antti Koivisto.
+
+ While an empty (logical width = 0) ContinuousContent takes up no space, it should not be mistaken for collapsed content
+ (i.e when m_logicalWidth(0) == m_trailingCollapsibleWidth(0), hasCollapsibleContent() should still return false)
+
+ * layout/formattingContexts/inline/InlineContentBreaker.cpp:
+ (WebCore::Layout::InlineContentBreaker::processOverflowingContent const):
+ (WebCore::Layout::InlineContentBreaker::tryBreakingOverflowingRun const):
+ (WebCore::Layout::InlineContentBreaker::tryBreakingPreviousNonOverflowingRuns const):
+ (WebCore::Layout::InlineContentBreaker::ContinuousContent::appendToRunList): Add a dedicated function to deal with append and logicalWidth.
+ (WebCore::Layout::InlineContentBreaker::ContinuousContent::resetTrailingWhitespace): Turn trailing whitespace into leading if applicable.
+ (WebCore::Layout::InlineContentBreaker::ContinuousContent::append): Add dedicated functions for each inline item types.
+ * layout/formattingContexts/inline/InlineContentBreaker.h:
+ (WebCore::Layout::InlineContentBreaker::ContinuousContent::leadingCollapsibleWidth const):
+ (WebCore::Layout::InlineContentBreaker::ContinuousContent::trailingCollapsibleWidth const):
+ (WebCore::Layout::InlineContentBreaker::ContinuousContent::hasCollapsibleContent const):
+ (WebCore::Layout::InlineContentBreaker::ContinuousContent::isFullyCollapsible const):
+ * layout/formattingContexts/inline/InlineLineBuilder.cpp:
+ (WebCore::Layout::LineCandidate::InlineContent::appendInlineItem):
+
+2021-12-25 Alan Bujtas <[email protected]>
+
[LFC][IFC] Remove redundant InlineContentBreaker::shouldKeepEndOfLineWhitespace
https://bugs.webkit.org/show_bug.cgi?id=234668
Modified: trunk/Source/WebCore/layout/formattingContexts/inline/InlineContentBreaker.cpp (287441 => 287442)
--- trunk/Source/WebCore/layout/formattingContexts/inline/InlineContentBreaker.cpp 2021-12-26 06:10:32 UTC (rev 287441)
+++ trunk/Source/WebCore/layout/formattingContexts/inline/InlineContentBreaker.cpp 2021-12-26 06:16:27 UTC (rev 287442)
@@ -163,9 +163,9 @@
// If this new content is fully collapsible, it should surely fit.
return InlineContentBreaker::Result { Result::Action::Keep };
} else {
- auto spaceRequired = continuousContent.logicalWidth() - continuousContent.trailingCollapsibleWidth();
+ auto spaceRequired = continuousContent.logicalWidth() - continuousContent.trailingCollapsibleWidth().value_or(0.f);
if (lineStatus.hasFullyCollapsibleTrailingContent || isVisuallyEmptyWhitespaceContent(continuousContent))
- spaceRequired -= continuousContent.leadingCollapsibleWidth();
+ spaceRequired -= continuousContent.leadingCollapsibleWidth().value_or(0.f);
if (spaceRequired <= lineStatus.availableWidth)
return InlineContentBreaker::Result { Result::Action::Keep };
}
@@ -513,8 +513,8 @@
if (!isWrappableRun(overflowingRun))
return { };
- auto avilableWidth = std::max(0.0f, lineStatus.availableWidth - nonOverflowingContentWidth);
- auto partialOverflowingRun = tryBreakingTextRun(runs, { overflowingRunIndex, true, lineStatus.contentLogicalRight + nonOverflowingContentWidth }, avilableWidth, lineStatus.hasWrapOpportunityAtPreviousPosition);
+ auto availableWidth = std::max(0.f, lineStatus.availableWidth - nonOverflowingContentWidth);
+ auto partialOverflowingRun = tryBreakingTextRun(runs, { overflowingRunIndex, true, lineStatus.contentLogicalRight + nonOverflowingContentWidth }, availableWidth, lineStatus.hasWrapOpportunityAtPreviousPosition);
if (!partialOverflowingRun)
return { };
if (partialOverflowingRun->length)
@@ -536,8 +536,8 @@
if (!isWrappableRun(run))
continue;
ASSERT(run.inlineItem.isText());
- auto avilableWidth = std::max(0.0f, lineStatus.availableWidth - previousContentWidth);
- if (auto partialRun = tryBreakingTextRun(runs, { index, false, lineStatus.contentLogicalRight + previousContentWidth }, avilableWidth, lineStatus.hasWrapOpportunityAtPreviousPosition)) {
+ auto availableWidth = std::max(0.f, lineStatus.availableWidth - previousContentWidth);
+ if (auto partialRun = tryBreakingTextRun(runs, { index, false, lineStatus.contentLogicalRight + previousContentWidth }, availableWidth, lineStatus.hasWrapOpportunityAtPreviousPosition)) {
// We know this run fits, so if breaking is allowed on the run, it should return a non-empty left-side
// since it's either at hyphen position or the entire run is returned.
ASSERT(partialRun->length);
@@ -679,26 +679,47 @@
return includeHyphenationIfAllowed({ });
}
-void InlineContentBreaker::ContinuousContent::append(const InlineItem& inlineItem, const RenderStyle& style, InlineLayoutUnit logicalWidth, std::optional<InlineLayoutUnit> collapsibleWidth)
+void InlineContentBreaker::ContinuousContent::appendToRunList(const InlineItem& inlineItem, const RenderStyle& style, InlineLayoutUnit logicalWidth)
{
- ASSERT(inlineItem.isText() || inlineItem.isBox() || inlineItem.isInlineBoxStart() || inlineItem.isInlineBoxEnd());
- auto isLeadingCollapsible = collapsibleWidth && (m_runs.isEmpty() || isFullyCollapsible());
m_runs.append({ inlineItem, style, logicalWidth });
m_logicalWidth = clampTo<InlineLayoutUnit>(m_logicalWidth + logicalWidth);
+}
+
+void InlineContentBreaker::ContinuousContent::resetTrailingWhitespace()
+{
+ if (!m_leadingCollapsibleWidth)
+ m_leadingCollapsibleWidth = m_trailingCollapsibleWidth;
+ m_trailingCollapsibleWidth = { };
+}
+
+void InlineContentBreaker::ContinuousContent::append(const InlineItem& inlineItem, const RenderStyle& style, InlineLayoutUnit logicalWidth)
+{
+ ASSERT(inlineItem.isBox() || inlineItem.isInlineBoxStart() || inlineItem.isInlineBoxEnd());
+ appendToRunList(inlineItem, style, logicalWidth);
+ if (inlineItem.isBox()) {
+ // Inline boxes (whitespace-> <span></span>) do not prevent the trailing content from getting collapsed/hung
+ // but atomic inline level boxes do.
+ resetTrailingWhitespace();
+ }
+}
+
+void InlineContentBreaker::ContinuousContent::append(const InlineTextItem& inlineTextItem, const RenderStyle& style, InlineLayoutUnit logicalWidth, std::optional<InlineLayoutUnit> collapsibleWidth)
+{
if (!collapsibleWidth) {
- if (inlineItem.isText() || inlineItem.isBox()) {
- // Inline boxes do not prevent the trailing content from getting collapsed.
- m_trailingCollapsibleWidth = { };
- }
+ appendToRunList(inlineTextItem, style, logicalWidth);
+ resetTrailingWhitespace();
return;
}
+
ASSERT(*collapsibleWidth <= logicalWidth);
+ auto isLeadingCollapsible = collapsibleWidth && (!this->logicalWidth() || isFullyCollapsible());
+ appendToRunList(inlineTextItem, style, logicalWidth);
if (isLeadingCollapsible) {
ASSERT(!m_trailingCollapsibleWidth);
- m_leadingCollapsibleWidth += *collapsibleWidth;
+ m_leadingCollapsibleWidth = m_leadingCollapsibleWidth.value_or(0.f) + *collapsibleWidth;
return;
}
- m_trailingCollapsibleWidth = *collapsibleWidth == logicalWidth ? m_trailingCollapsibleWidth + logicalWidth : *collapsibleWidth;
+ m_trailingCollapsibleWidth = *collapsibleWidth == logicalWidth ? m_trailingCollapsibleWidth.value_or(0.f) + logicalWidth : *collapsibleWidth;
}
void InlineContentBreaker::ContinuousContent::reset()
Modified: trunk/Source/WebCore/layout/formattingContexts/inline/InlineContentBreaker.h (287441 => 287442)
--- trunk/Source/WebCore/layout/formattingContexts/inline/InlineContentBreaker.h 2021-12-26 06:10:32 UTC (rev 287441)
+++ trunk/Source/WebCore/layout/formattingContexts/inline/InlineContentBreaker.h 2021-12-26 06:16:27 UTC (rev 287442)
@@ -35,6 +35,7 @@
namespace Layout {
class InlineItem;
+class InlineTextItem;
struct CandidateTextRunForBreaking;
class InlineContentBreaker {
@@ -80,12 +81,13 @@
// see https://drafts.csswg.org/css-text-3/#line-break-details
struct ContinuousContent {
InlineLayoutUnit logicalWidth() const { return m_logicalWidth; }
- InlineLayoutUnit leadingCollapsibleWidth() const { return m_leadingCollapsibleWidth; }
- InlineLayoutUnit trailingCollapsibleWidth() const { return m_trailingCollapsibleWidth; }
- bool hasCollapsibleContent() const { return trailingCollapsibleWidth() > 0 || leadingCollapsibleWidth() > 0; }
- bool isFullyCollapsible() const { return logicalWidth() == trailingCollapsibleWidth() + leadingCollapsibleWidth(); }
+ std::optional<InlineLayoutUnit> leadingCollapsibleWidth() const { return m_leadingCollapsibleWidth; }
+ std::optional<InlineLayoutUnit> trailingCollapsibleWidth() const { return m_trailingCollapsibleWidth; }
+ bool hasCollapsibleContent() const { return trailingCollapsibleWidth() || leadingCollapsibleWidth(); }
+ bool isFullyCollapsible() const;
- void append(const InlineItem&, const RenderStyle&, InlineLayoutUnit logicalWidth, std::optional<InlineLayoutUnit> collapsibleWidth = std::nullopt);
+ void append(const InlineItem&, const RenderStyle&, InlineLayoutUnit logicalWidth);
+ void append(const InlineTextItem&, const RenderStyle&, InlineLayoutUnit logicalWidth, std::optional<InlineLayoutUnit> collapsibleWidth);
void reset();
struct Run {
@@ -101,10 +103,13 @@
const RunList& runs() const { return m_runs; }
private:
+ void appendToRunList(const InlineItem&, const RenderStyle&, InlineLayoutUnit logicalWidth);
+ void resetTrailingWhitespace();
+
RunList m_runs;
InlineLayoutUnit m_logicalWidth { 0 };
- InlineLayoutUnit m_leadingCollapsibleWidth { 0 };
- InlineLayoutUnit m_trailingCollapsibleWidth { 0 };
+ std::optional<InlineLayoutUnit> m_leadingCollapsibleWidth { };
+ std::optional<InlineLayoutUnit> m_trailingCollapsibleWidth { };
};
struct LineStatus {
@@ -171,6 +176,16 @@
{
}
+inline bool InlineContentBreaker::ContinuousContent::isFullyCollapsible() const
+{
+ auto collapsibleWidth = std::optional<InlineLayoutUnit> { };
+ if (m_leadingCollapsibleWidth)
+ collapsibleWidth = *m_leadingCollapsibleWidth;
+ if (m_trailingCollapsibleWidth)
+ collapsibleWidth = collapsibleWidth.value_or(0.f) + *m_trailingCollapsibleWidth;
+ return collapsibleWidth && *collapsibleWidth == logicalWidth();
}
+
}
+}
#endif
Modified: trunk/Source/WebCore/layout/formattingContexts/inline/InlineLineBuilder.cpp (287441 => 287442)
--- trunk/Source/WebCore/layout/formattingContexts/inline/InlineLineBuilder.cpp 2021-12-26 06:10:32 UTC (rev 287441)
+++ trunk/Source/WebCore/layout/formattingContexts/inline/InlineLineBuilder.cpp 2021-12-26 06:16:27 UTC (rev 287442)
@@ -193,25 +193,33 @@
inline void LineCandidate::InlineContent::appendInlineItem(const InlineItem& inlineItem, const RenderStyle& style, InlineLayoutUnit logicalWidth)
{
ASSERT(inlineItem.isText() || inlineItem.isBox() || inlineItem.isInlineBoxStart() || inlineItem.isInlineBoxEnd());
- auto collapsibleWidth = [&]() -> std::optional<InlineLayoutUnit> {
- if (!inlineItem.isText())
- return { };
+ m_hasInlineLevelBox = m_hasInlineLevelBox || inlineItem.isBox() || inlineItem.isInlineBoxStart();
+
+ if (inlineItem.isBox() || inlineItem.isInlineBoxStart() || inlineItem.isInlineBoxEnd())
+ return m_continuousContent.append(inlineItem, style, logicalWidth);
+
+ if (inlineItem.isText()) {
auto& inlineTextItem = downcast<InlineTextItem>(inlineItem);
- if (inlineTextItem.isWhitespace() && !InlineTextItem::shouldPreserveSpacesAndTabs(inlineTextItem)) {
- // Fully collapsible trailing content.
- return logicalWidth;
- }
- // Check for partially collapsible content.
- if (m_ignoreTrailingLetterSpacing)
- return { };
- auto letterSpacing = style.letterSpacing();
- if (letterSpacing <= 0)
- return { };
- ASSERT(logicalWidth > letterSpacing);
- return letterSpacing;
- };
- m_continuousContent.append(inlineItem, style, logicalWidth, collapsibleWidth());
- m_hasInlineLevelBox = m_hasInlineLevelBox || inlineItem.isBox() || inlineItem.isInlineBoxStart();
+ auto isWhitespace = inlineTextItem.isWhitespace();
+
+ auto collapsibleWidth = [&]() -> std::optional<InlineLayoutUnit> {
+ if (isWhitespace && !InlineTextItem::shouldPreserveSpacesAndTabs(inlineTextItem)) {
+ // Fully collapsible trailing content.
+ return logicalWidth;
+ }
+ // Check for partially collapsible content.
+ if (m_ignoreTrailingLetterSpacing)
+ return { };
+ auto letterSpacing = style.letterSpacing();
+ if (letterSpacing <= 0)
+ return { };
+ ASSERT(logicalWidth > letterSpacing);
+ return letterSpacing;
+ };
+ m_continuousContent.append(inlineTextItem, style, logicalWidth, collapsibleWidth());
+ return;
+ }
+ ASSERT_NOT_REACHED();
}
inline void LineCandidate::InlineContent::reset()