- Revision
- 267494
- Author
- [email protected]
- Date
- 2020-09-23 12:34:44 -0700 (Wed, 23 Sep 2020)
Log Message
[LFC][IFC] Precompute the collapsible trailing width for LineBreaker
https://bugs.webkit.org/show_bug.cgi?id=216881
Reviewed by Antti Koivisto.
Let's just compute the collapsible trailing width while adding inline content to LineCandidate instead of
reverse looping through the runs in LineBreaker.
This is also in preparation for reducing the number of RuntimeEnabledFeatures::layoutFormattingContextIntegrationEnabled calls.
* layout/inlineformatting/InlineLineBreaker.cpp:
(WebCore::Layout::ContinuousContent::hasTrailingCollapsibleContent const):
(WebCore::Layout::ContinuousContent::isFullyCollapsible const):
(WebCore::Layout::LineBreaker::shouldKeepEndOfLineWhitespace const):
(WebCore::Layout::LineBreaker::shouldWrapInlineContent):
(WebCore::Layout::LineBreaker::tryWrappingInlineContent const):
(WebCore::Layout::ContinuousContent::ContinuousContent):
(WebCore::Layout::ContinuousContent::nonCollapsibleLogicalWidth const):
(WebCore::Layout::ContinuousContent::isTrailingContentFullyCollapsible const): Deleted.
(WebCore::Layout::ContinuousContent::TrailingCollapsibleContent::reset): Deleted.
* layout/inlineformatting/InlineLineBreaker.h:
* layout/inlineformatting/InlineLineBuilder.cpp:
(WebCore::Layout::LineCandidate::InlineContent::collapsibleTrailingWidth const):
(WebCore::Layout::LineCandidate::InlineContent::appendInlineItem):
(WebCore::Layout::LineCandidate::InlineContent::reset):
(WebCore::Layout::LineBuilder::handleFloatsAndInlineContent):
Modified Paths
Diff
Modified: trunk/Source/WebCore/ChangeLog (267493 => 267494)
--- trunk/Source/WebCore/ChangeLog 2020-09-23 19:17:20 UTC (rev 267493)
+++ trunk/Source/WebCore/ChangeLog 2020-09-23 19:34:44 UTC (rev 267494)
@@ -1,3 +1,31 @@
+2020-09-23 Zalan Bujtas <[email protected]>
+
+ [LFC][IFC] Precompute the collapsible trailing width for LineBreaker
+ https://bugs.webkit.org/show_bug.cgi?id=216881
+
+ Reviewed by Antti Koivisto.
+
+ Let's just compute the collapsible trailing width while adding inline content to LineCandidate instead of
+ reverse looping through the runs in LineBreaker.
+ This is also in preparation for reducing the number of RuntimeEnabledFeatures::layoutFormattingContextIntegrationEnabled calls.
+
+ * layout/inlineformatting/InlineLineBreaker.cpp:
+ (WebCore::Layout::ContinuousContent::hasTrailingCollapsibleContent const):
+ (WebCore::Layout::ContinuousContent::isFullyCollapsible const):
+ (WebCore::Layout::LineBreaker::shouldKeepEndOfLineWhitespace const):
+ (WebCore::Layout::LineBreaker::shouldWrapInlineContent):
+ (WebCore::Layout::LineBreaker::tryWrappingInlineContent const):
+ (WebCore::Layout::ContinuousContent::ContinuousContent):
+ (WebCore::Layout::ContinuousContent::nonCollapsibleLogicalWidth const):
+ (WebCore::Layout::ContinuousContent::isTrailingContentFullyCollapsible const): Deleted.
+ (WebCore::Layout::ContinuousContent::TrailingCollapsibleContent::reset): Deleted.
+ * layout/inlineformatting/InlineLineBreaker.h:
+ * layout/inlineformatting/InlineLineBuilder.cpp:
+ (WebCore::Layout::LineCandidate::InlineContent::collapsibleTrailingWidth const):
+ (WebCore::Layout::LineCandidate::InlineContent::appendInlineItem):
+ (WebCore::Layout::LineCandidate::InlineContent::reset):
+ (WebCore::Layout::LineBuilder::handleFloatsAndInlineContent):
+
2020-09-23 Peng Liu <[email protected]>
[Media in GPU Process] Implement caption support in video fullscreen and PiP
Modified: trunk/Source/WebCore/layout/inlineformatting/InlineLineBreaker.cpp (267493 => 267494)
--- trunk/Source/WebCore/layout/inlineformatting/InlineLineBreaker.cpp 2020-09-23 19:17:20 UTC (rev 267493)
+++ trunk/Source/WebCore/layout/inlineformatting/InlineLineBreaker.cpp 2020-09-23 19:34:44 UTC (rev 267494)
@@ -32,7 +32,6 @@
#include "Hyphenation.h"
#include "InlineItem.h"
#include "InlineTextItem.h"
-#include "RuntimeEnabledFeatures.h"
#include "TextUtil.h"
namespace WebCore {
@@ -72,10 +71,10 @@
bool hasNonContentRunsOnly() const;
InlineLayoutUnit logicalWidth() const { return m_candidateContent.logicalWidth; }
InlineLayoutUnit logicalLeft() const { return m_candidateContent.logicalLeft; }
- InlineLayoutUnit nonCollapsibleLogicalWidth() const { return logicalWidth() - m_trailingCollapsibleContent.width; }
+ InlineLayoutUnit nonCollapsibleLogicalWidth() const;
- bool hasTrailingCollapsibleContent() const { return !!m_trailingCollapsibleContent.width; }
- bool isTrailingContentFullyCollapsible() const { return m_trailingCollapsibleContent.isFullyCollapsible; }
+ bool hasTrailingCollapsibleContent() const { return !!m_candidateContent.collapsibleTrailingWidth; }
+ bool isFullyCollapsible() const { return !nonCollapsibleLogicalWidth(); }
Optional<size_t> firstTextRunIndex() const;
Optional<size_t> lastContentRunIndex() const;
@@ -82,13 +81,6 @@
private:
const LineBreaker::CandidateContent& m_candidateContent;
- struct TrailingCollapsibleContent {
- void reset();
-
- bool isFullyCollapsible { false };
- InlineLayoutUnit width { 0 };
- };
- TrailingCollapsibleContent m_trailingCollapsibleContent;
};
struct WrappedTextContent {
@@ -107,8 +99,8 @@
bool LineBreaker::shouldKeepEndOfLineWhitespace(const ContinuousContent& continuousContent) const
{
- // Grab the style and check for white-space property to decided whether we should let this whitespace content overflow the current line.
- // Note that the "keep" in the context means we let the whitespace content sit on the current line.
+ // Grab the style and check for white-space property to decide whether we should let this whitespace content overflow the current line.
+ // Note that the "keep" in this context means we let the whitespace content sit on the current line.
// It might very well get collapsed when we close the line (normal/nowrap/pre-line).
// See https://www.w3.org/TR/css-text-3/#white-space-property
auto whitespace = continuousContent.runs()[*continuousContent.firstTextRunIndex()].inlineItem.style().whiteSpace();
@@ -121,7 +113,7 @@
if (candidateContent.logicalWidth <= lineStatus.availableWidth)
return Result { Result::Action::Keep };
#if USE_FLOAT_AS_INLINE_LAYOUT_UNIT
- // Preferred width computation sums up floats while line breaker substracts them. This can lead to epsilon-scale differences.
+ // Preferred width computation sums up floats while line breaker subtracts them. This can lead to epsilon-scale differences.
if (WTF::areEssentiallyEqual(candidateContent.logicalWidth, lineStatus.availableWidth))
return Result { Result::Action::Keep };
#endif
@@ -162,7 +154,7 @@
if (continuousContent.nonCollapsibleLogicalWidth() <= lineStatus.availableWidth)
return { Result::Action::Keep, IsEndOfLine };
// Now check if we can trim the line too.
- if (lineStatus.lineHasFullyCollapsibleTrailingRun && continuousContent.isTrailingContentFullyCollapsible()) {
+ if (lineStatus.lineHasFullyCollapsibleTrailingRun && continuousContent.isFullyCollapsible()) {
// If this new content is fully collapsible, it should surely fit.
return { Result::Action::Keep, IsEndOfLine };
}
@@ -355,37 +347,14 @@
ContinuousContent::ContinuousContent(const LineBreaker::CandidateContent& candidateContent)
: m_candidateContent(candidateContent)
{
- // Figure out the trailing collapsible state.
- for (auto& run : WTF::makeReversedRange(runs())) {
- auto& inlineItem = run.inlineItem;
- if (inlineItem.isBox()) {
- // We did reach a non-collapsible content. We have all the trailing whitespace now.
- break;
- }
- if (inlineItem.isText()) {
- auto& inlineTextItem = downcast<InlineTextItem>(inlineItem);
- auto isFullyCollapsible = [&] {
- return inlineTextItem.isWhitespace() && !TextUtil::shouldPreserveTrailingWhitespace(inlineTextItem.style());
- };
- if (isFullyCollapsible()) {
- m_trailingCollapsibleContent.width += run.logicalWidth;
- m_trailingCollapsibleContent.isFullyCollapsible = true;
- // Let's see if we've got more trailing whitespace content.
- continue;
- }
- if (!RuntimeEnabledFeatures::sharedFeatures().layoutFormattingContextIntegrationEnabled()) {
- // A run with trailing letter spacing is partially collapsible.
- if (auto collapsibleWidth = inlineTextItem.style().letterSpacing()) {
- m_trailingCollapsibleContent.width += collapsibleWidth;
- m_trailingCollapsibleContent.isFullyCollapsible = false;
- }
- }
- // End of whitespace content.
- break;
- }
- }
}
+InlineLayoutUnit ContinuousContent::nonCollapsibleLogicalWidth() const
+{
+ ASSERT(logicalWidth() >= m_candidateContent.collapsibleTrailingWidth);
+ return logicalWidth() - m_candidateContent.collapsibleTrailingWidth;
+}
+
bool ContinuousContent::hasTextContentOnly() const
{
// <span>text</span> is considered a text run even with the [container start][container end] inline items.
@@ -446,12 +415,6 @@
return true;
}
-void ContinuousContent::TrailingCollapsibleContent::reset()
-{
- isFullyCollapsible = false;
- width = 0_lu;
}
-
}
-}
#endif
Modified: trunk/Source/WebCore/layout/inlineformatting/InlineLineBreaker.h (267493 => 267494)
--- trunk/Source/WebCore/layout/inlineformatting/InlineLineBreaker.h 2020-09-23 19:17:20 UTC (rev 267493)
+++ trunk/Source/WebCore/layout/inlineformatting/InlineLineBreaker.h 2020-09-23 19:34:44 UTC (rev 267494)
@@ -76,10 +76,21 @@
};
using RunList = Vector<Run, 3>;
+ // This struct represents the amount of content committed to line breaking at a time e.g.
+ // <div>text content <span>span1</span>between<span>span2</span></div>
+ // [text][ ][content][ ][container start][span1][container end][between][container start][span2][container end]
+ // candidate content at a time:
+ // 1. [text]
+ // 2. [ ]
+ // 3. [content]
+ // 4. [ ]
+ // 5. [container start][span1][container end][between][container start][span2][container end]
+ // see https://drafts.csswg.org/css-text-3/#line-break-details
struct CandidateContent {
const RunList& runs;
InlineLayoutUnit logicalLeft { 0 };
InlineLayoutUnit logicalWidth { 0 };
+ InlineLayoutUnit collapsibleTrailingWidth { 0 };
};
struct LineStatus {
InlineLayoutUnit availableWidth { 0 };
@@ -92,15 +103,6 @@
void setHyphenationDisabled() { n_hyphenationIsDisabled = true; }
private:
- // This struct represents the amount of content committed to line breaking at a time e.g.
- // text content <span>span1</span>between<span>span2</span>
- // [text][ ][content][ ][container start][span1][container end][between][container start][span2][container end]
- // -> content chunks ->
- // [text]
- // [ ]
- // [content]
- // [container start][span1][container end][between][container start][span2][container end]
- // see https://drafts.csswg.org/css-text-3/#line-break-details
Optional<WrappedTextContent> wrapTextContent(const ContinuousContent&, const LineStatus&) const;
Result tryWrappingInlineContent(const CandidateContent&, const LineStatus&) const;
Optional<PartialRun> tryBreakingTextRun(const Run& overflowRun, InlineLayoutUnit logicalLeft, InlineLayoutUnit availableWidth) const;
Modified: trunk/Source/WebCore/layout/inlineformatting/InlineLineBuilder.cpp (267493 => 267494)
--- trunk/Source/WebCore/layout/inlineformatting/InlineLineBuilder.cpp 2020-09-23 19:17:20 UTC (rev 267493)
+++ trunk/Source/WebCore/layout/inlineformatting/InlineLineBuilder.cpp 2020-09-23 19:34:44 UTC (rev 267494)
@@ -182,6 +182,7 @@
struct InlineContent {
const LineBreaker::RunList& runs() const { return m_inlineRuns; }
InlineLayoutUnit logicalWidth() const { return m_LogicalWidth; }
+ InlineLayoutUnit collapsibleTrailingWidth() const { return m_collapsibleTrailingWidth; }
const InlineItem* trailingLineBreak() const { return m_trailingLineBreak; }
void appendInlineItem(const InlineItem&, InlineLayoutUnit logicalWidth);
@@ -192,6 +193,7 @@
void setTrailingLineBreak(const InlineItem& lineBreakItem) { m_trailingLineBreak = &lineBreakItem; }
InlineLayoutUnit m_LogicalWidth { 0 };
+ InlineLayoutUnit m_collapsibleTrailingWidth { 0 };
LineBreaker::RunList m_inlineRuns;
const InlineItem* m_trailingLineBreak { nullptr };
};
@@ -223,11 +225,41 @@
{
m_LogicalWidth += logicalWidth;
m_inlineRuns.append({ inlineItem, logicalWidth });
+
+ auto isFullyCollapsible = [&] {
+ if (inlineItem.isBox())
+ return false;
+ if (inlineItem.isText()) {
+ auto& inlineTextItem = downcast<InlineTextItem>(inlineItem);
+ return inlineTextItem.isWhitespace() && !TextUtil::shouldPreserveTrailingWhitespace(inlineTextItem.style());
+ }
+ return true;
+ };
+ if (isFullyCollapsible()) {
+ m_collapsibleTrailingWidth += logicalWidth;
+ return;
+ }
+
+ auto partiallyCollapsibleTrailingWidth = [&]() -> InlineLayoutUnit {
+ if (RuntimeEnabledFeatures::sharedFeatures().layoutFormattingContextIntegrationEnabled())
+ return { };
+ if (!inlineItem.isText())
+ return { };
+ if (auto letterSpacing = inlineItem.style().letterSpacing(); letterSpacing > 0)
+ return letterSpacing;
+ return { };
+ };
+ if (auto collapsibleTrailingWidth = partiallyCollapsibleTrailingWidth()) {
+ m_collapsibleTrailingWidth = collapsibleTrailingWidth;
+ return;
+ }
+ m_collapsibleTrailingWidth = { };
}
inline void LineCandidate::InlineContent::reset()
{
m_LogicalWidth = { };
+ m_collapsibleTrailingWidth = { };
m_inlineRuns.clear();
m_trailingLineBreak = { };
}
@@ -553,8 +585,8 @@
auto availableWidth = m_line.availableWidth() - floatContent.intrusiveWidth();
auto isLineConsideredEmpty = m_line.isVisuallyEmpty() && !m_contentIsConstrainedByFloat;
auto lineStatus = LineBreaker::LineStatus { availableWidth, m_line.trimmableTrailingWidth(), m_line.isTrailingRunFullyTrimmable(), isLineConsideredEmpty };
- auto candidateInlineContentLogicalLeft = m_line.contentLogicalWidth();
- auto result = lineBreaker.shouldWrapInlineContent({ candidateRuns, candidateInlineContentLogicalLeft, candidateInlineContent.logicalWidth() }, lineStatus);
+ auto contentLogicalLeft = m_line.contentLogicalWidth();
+ auto result = lineBreaker.shouldWrapInlineContent({ candidateRuns, contentLogicalLeft, candidateInlineContent.logicalWidth(), candidateInlineContent.collapsibleTrailingWidth() }, lineStatus);
if (result.lastWrapOpportunityItem)
m_lastWrapOpportunityItem = result.lastWrapOpportunityItem;
if (result.action == LineBreaker::Result::Action::Keep) {