Modified: trunk/Source/WebCore/ChangeLog (283484 => 283485)
--- trunk/Source/WebCore/ChangeLog 2021-10-03 23:09:02 UTC (rev 283484)
+++ trunk/Source/WebCore/ChangeLog 2021-10-04 01:07:25 UTC (rev 283485)
@@ -1,3 +1,27 @@
+2021-10-03 Alan Bujtas <[email protected]>
+
+ [LFC][IFC] HangingTrailingContent should cache width/length
+ https://bugs.webkit.org/show_bug.cgi?id=231128
+
+ Reviewed by Antti Koivisto.
+
+ Compute the length of the hanging trailing whitespace sequence.
+ This is in preparation for fixing imported/w3c/web-platform-tests/css/css-text/white-space/textarea-pre-wrap-014.html
+
+ * layout/formattingContexts/inline/InlineLine.cpp:
+ (WebCore::Layout::Line::Line):
+ (WebCore::Layout::Line::initialize):
+ (WebCore::Layout::Line::resetTrailingContent):
+ (WebCore::Layout::Line::appendTextContent):
+ (WebCore::Layout::Line::appendNonReplacedInlineLevelBox):
+ (WebCore::Layout::Line::HangingTrailingContent::add):
+ (WebCore::Layout::Line::HangingTrailingContent::HangingTrailingContent): Deleted.
+ (WebCore::Layout::Line::HangingTrailingContent::width const): Deleted.
+ * layout/formattingContexts/inline/InlineLine.h:
+ (WebCore::Layout::Line::HangingTrailingContent::length const):
+ (WebCore::Layout::Line::HangingTrailingContent::width const):
+ (WebCore::Layout::Line::HangingTrailingContent::reset):
+
2021-10-03 Sam Weinig <[email protected]>
WebXRSession's m_environmentBlendMode and m_interactionMode are never initialized
Modified: trunk/Source/WebCore/layout/formattingContexts/inline/InlineLine.cpp (283484 => 283485)
--- trunk/Source/WebCore/layout/formattingContexts/inline/InlineLine.cpp 2021-10-03 23:09:02 UTC (rev 283484)
+++ trunk/Source/WebCore/layout/formattingContexts/inline/InlineLine.cpp 2021-10-04 01:07:25 UTC (rev 283485)
@@ -43,7 +43,6 @@
Line::Line(const InlineFormattingContext& inlineFormattingContext)
: m_inlineFormattingContext(inlineFormattingContext)
, m_trimmableTrailingContent(m_runs)
- , m_hangingTrailingContent(m_runs)
{
}
@@ -56,8 +55,14 @@
m_nonSpanningInlineLevelBoxCount = 0;
m_contentLogicalWidth = { };
m_runs.clear();
+ resetTrailingContent();
+}
+
+void Line::resetTrailingContent()
+{
+ m_trimmableTrailingContent.reset();
+ m_hangingTrailingContent.reset();
m_trailingSoftHyphenWidth = { };
- m_trimmableTrailingContent.reset();
}
void Line::removeCollapsibleContent(InlineLayoutUnit horizontalAvailableSpace)
@@ -197,6 +202,8 @@
if (overflowWidth <= 0)
break;
}
+ // FIXME: Add support for incremental reset, where the hanging whitespace partially overflows.
+ m_hangingTrailingContent.reset();
m_contentLogicalWidth -= trimmedContentWidth;
}
@@ -303,22 +310,31 @@
// Do not let negative letter spacing make the content shorter than it already is.
m_contentLogicalWidth += std::max(0.0f, logicalWidth);
}
- // Set the trailing trimmable content.
- if (inlineTextItem.isWhitespace() && !InlineTextItem::shouldPreserveSpacesAndTabs(inlineTextItem)) {
- m_trimmableTrailingContent.addFullyTrimmableContent(m_runs.size() - 1, contentLogicalWidth() - oldContentLogicalWidth);
- return;
+
+ // Handle trailing content, specifically whitespace and letter spacing.
+ auto lastRunIndex = m_runs.size() - 1;
+ if (inlineTextItem.isWhitespace()) {
+ if (InlineTextItem::shouldPreserveSpacesAndTabs(inlineTextItem)) {
+ m_trimmableTrailingContent.reset();
+ if (m_runs[lastRunIndex].shouldTrailingWhitespaceHang())
+ m_hangingTrailingContent.add(inlineTextItem, logicalWidth);
+ } else {
+ m_hangingTrailingContent.reset();
+ m_trimmableTrailingContent.addFullyTrimmableContent(lastRunIndex, contentLogicalWidth() - oldContentLogicalWidth);
+ }
+ m_trailingSoftHyphenWidth = { };
+ } else {
+ resetTrailingContent();
+ if (style.letterSpacing() > 0 && !formattingContext().layoutState().shouldIgnoreTrailingLetterSpacing())
+ m_trimmableTrailingContent.addPartiallyTrimmableContent(lastRunIndex, style.letterSpacing());
+ if (inlineTextItem.hasTrailingSoftHyphen())
+ m_trailingSoftHyphenWidth = style.fontCascade().width(TextRun { StringView { style.hyphenString() } });
}
- // Any non-whitespace, no-trimmable content resets the existing trimmable.
- m_trimmableTrailingContent.reset();
- if (!formattingContext().layoutState().shouldIgnoreTrailingLetterSpacing() && !inlineTextItem.isWhitespace() && style.letterSpacing() > 0)
- m_trimmableTrailingContent.addPartiallyTrimmableContent(m_runs.size() - 1, style.letterSpacing());
- m_trailingSoftHyphenWidth = inlineTextItem.hasTrailingSoftHyphen() ? std::make_optional(style.fontCascade().width(TextRun { StringView { style.hyphenString() } })) : std::nullopt;
}
void Line::appendNonReplacedInlineLevelBox(const InlineItem& inlineItem, const RenderStyle& style, InlineLayoutUnit marginBoxLogicalWidth)
{
- m_trimmableTrailingContent.reset();
- m_trailingSoftHyphenWidth = { };
+ resetTrailingContent();
m_contentLogicalWidth += marginBoxLogicalWidth;
++m_nonSpanningInlineLevelBoxCount;
auto marginStart = formattingContext().geometryForBox(inlineItem.layoutBox()).marginStart();
@@ -443,27 +459,14 @@
return remove();
}
-Line::HangingTrailingContent::HangingTrailingContent(const RunList& runs)
- : m_runs(runs)
+void Line::HangingTrailingContent::add(const InlineTextItem& trailingWhitespace, InlineLayoutUnit logicalWidth)
{
-}
-
-InlineLayoutUnit Line::HangingTrailingContent::width() const
-{
// When a glyph at the start or end edge of a line hangs, it is not considered when measuring the line’s contents for fit, alignment, or justification.
// Depending on the line’s alignment/justification, this can result in the mark being placed outside the line box.
// https://drafts.csswg.org/css-text-3/#hanging
- auto hangingWidth = InlineLayoutUnit { };
- for (auto& run : WTF::makeReversedRange(m_runs)) {
- if (run.isBox() || run.isLineBreak())
- break;
- if (run.isInlineBoxStart() || run.isInlineBoxEnd())
- continue;
- if (!run.hasTrailingWhitespace() || !run.shouldTrailingWhitespaceHang())
- break;
- hangingWidth += run.trailingWhitespaceWidth();
- }
- return hangingWidth;
+ ASSERT(trailingWhitespace.isWhitespace());
+ m_width += logicalWidth;
+ m_length += trailingWhitespace.length();
}
Line::Run::Run(const InlineItem& inlineItem, const RenderStyle& style, InlineLayoutUnit logicalLeft, InlineLayoutUnit logicalWidth)
Modified: trunk/Source/WebCore/layout/formattingContexts/inline/InlineLine.h (283484 => 283485)
--- trunk/Source/WebCore/layout/formattingContexts/inline/InlineLine.h 2021-10-03 23:09:02 UTC (rev 283484)
+++ trunk/Source/WebCore/layout/formattingContexts/inline/InlineLine.h 2021-10-04 01:07:25 UTC (rev 283485)
@@ -156,6 +156,8 @@
void removeTrailingTrimmableContent();
void visuallyCollapseHangingOverflow(InlineLayoutUnit horizontalAvailableSpace);
+ void resetTrailingContent();
+
const InlineFormattingContext& formattingContext() const;
struct TrimmableTrailingContent {
@@ -182,12 +184,15 @@
};
struct HangingTrailingContent {
- HangingTrailingContent(const RunList&);
+ void add(const InlineTextItem& trailingWhitespace, InlineLayoutUnit logicalWidth);
+ void reset();
- InlineLayoutUnit width() const;
+ size_t length() const { return m_length; }
+ InlineLayoutUnit width() const { return m_width; }
private:
- const RunList& m_runs;
+ size_t m_length { 0 };
+ InlineLayoutUnit m_width { 0 };
};
const InlineFormattingContext& m_inlineFormattingContext;
@@ -207,6 +212,12 @@
m_partiallyTrimmableWidth = { };
}
+inline void Line::HangingTrailingContent::reset()
+{
+ m_width = { };
+ m_length = { };
+}
+
inline Line::Run::TrailingWhitespace Line::Run::trailingWhitespaceType(const InlineTextItem& inlineTextItem) const
{
if (!inlineTextItem.isWhitespace())