- Revision
- 287437
- Author
- [email protected]
- Date
- 2021-12-25 07:36:13 -0800 (Sat, 25 Dec 2021)
Log Message
[LFC][IFC] InlineContentBreaker should know about the hanging content width
https://bugs.webkit.org/show_bug.cgi?id=234662
Reviewed by Antti Koivisto.
Pass in the trailing hanging content width to InlineContentBreaker as this specific type
of content (e.g. pre-wrap whitespace) should be ignored when checking for content fit.
(Note that we already ignore it through the shouldKeepEndOfLineWhitespace() call in
InlineContentBreaker::processOverflowingContent, but this patch is in preparation for making hanging content logic
more inline with the spec. -and also removing shouldKeepEndOfLineWhitespace needs some more changes.)
* layout/formattingContexts/inline/InlineContentBreaker.cpp:
(WebCore::Layout::InlineContentBreaker::processOverflowingContent const):
* layout/formattingContexts/inline/InlineContentBreaker.h:
* layout/formattingContexts/inline/InlineLine.h:
(WebCore::Layout::Line::hangingTrailingContentWidth const):
(WebCore::Layout::Line::hangingWhitespaceWidth const): Deleted.
* layout/formattingContexts/inline/InlineLineBuilder.cpp:
(WebCore::Layout::LineBuilder::layoutInlineContent):
(WebCore::Layout::LineBuilder::handleInlineContent):
Modified Paths
Diff
Modified: trunk/Source/WebCore/ChangeLog (287436 => 287437)
--- trunk/Source/WebCore/ChangeLog 2021-12-25 10:13:53 UTC (rev 287436)
+++ trunk/Source/WebCore/ChangeLog 2021-12-25 15:36:13 UTC (rev 287437)
@@ -1,3 +1,27 @@
+2021-12-25 Alan Bujtas <[email protected]>
+
+ [LFC][IFC] InlineContentBreaker should know about the hanging content width
+ https://bugs.webkit.org/show_bug.cgi?id=234662
+
+ Reviewed by Antti Koivisto.
+
+ Pass in the trailing hanging content width to InlineContentBreaker as this specific type
+ of content (e.g. pre-wrap whitespace) should be ignored when checking for content fit.
+
+ (Note that we already ignore it through the shouldKeepEndOfLineWhitespace() call in
+ InlineContentBreaker::processOverflowingContent, but this patch is in preparation for making hanging content logic
+ more inline with the spec. -and also removing shouldKeepEndOfLineWhitespace needs some more changes.)
+
+ * layout/formattingContexts/inline/InlineContentBreaker.cpp:
+ (WebCore::Layout::InlineContentBreaker::processOverflowingContent const):
+ * layout/formattingContexts/inline/InlineContentBreaker.h:
+ * layout/formattingContexts/inline/InlineLine.h:
+ (WebCore::Layout::Line::hangingTrailingContentWidth const):
+ (WebCore::Layout::Line::hangingWhitespaceWidth const): Deleted.
+ * layout/formattingContexts/inline/InlineLineBuilder.cpp:
+ (WebCore::Layout::LineBuilder::layoutInlineContent):
+ (WebCore::Layout::LineBuilder::handleInlineContent):
+
2021-12-24 Tim Nguyen <[email protected]>
Unreviewed, remove -webkit-svg-shadow from CSSProperties.json
Modified: trunk/Source/WebCore/layout/formattingContexts/inline/InlineContentBreaker.cpp (287436 => 287437)
--- trunk/Source/WebCore/layout/formattingContexts/inline/InlineContentBreaker.cpp 2021-12-25 10:13:53 UTC (rev 287436)
+++ trunk/Source/WebCore/layout/formattingContexts/inline/InlineContentBreaker.cpp 2021-12-25 15:36:13 UTC (rev 287437)
@@ -166,29 +166,39 @@
ASSERT(!continuousContent.runs().isEmpty());
ASSERT(continuousContent.logicalWidth() > lineStatus.availableWidth);
- if (continuousContent.hasCollapsibleContent()) {
- if (lineStatus.hasFullyCollapsibleTrailingContent && continuousContent.isFullyCollapsible()) {
- // If this new content is fully collapsible, it should surely fit.
- return { Result::Action::Keep, IsEndOfLine::No };
+ auto checkForTrailingContentFit = [&]() -> std::optional<InlineContentBreaker::Result> {
+ if (continuousContent.hasCollapsibleContent()) {
+ // Check if the content fits if we collapsed it.
+ if (continuousContent.isFullyCollapsible()) {
+ if (lineStatus.hasFullyCollapsibleTrailingContent || lineStatus.availableWidth >= 0) {
+ // If this new content is fully collapsible, it should surely fit.
+ return InlineContentBreaker::Result { Result::Action::Keep, IsEndOfLine::No };
+ }
+ }
+ auto spaceRequired = continuousContent.logicalWidth() - continuousContent.trailingCollapsibleWidth();
+ if (lineStatus.hasFullyCollapsibleTrailingContent)
+ spaceRequired -= continuousContent.leadingCollapsibleWidth();
+ if (spaceRequired <= lineStatus.availableWidth)
+ return InlineContentBreaker::Result { Result::Action::Keep, IsEndOfLine::No };
}
- // Check if the content fits if we collapsed it.
- auto spaceRequired = continuousContent.logicalWidth() - continuousContent.trailingCollapsibleWidth();
- if (lineStatus.hasFullyCollapsibleTrailingContent)
- spaceRequired -= continuousContent.leadingCollapsibleWidth();
- if (spaceRequired <= lineStatus.availableWidth)
- return { Result::Action::Keep, IsEndOfLine::No };
- } else if (lineStatus.collapsibleWidth && isNonContentRunsOnly(continuousContent)) {
- // Let's see if the non-content runs fit when the line has trailing collapsible content.
- // "text content <span style="padding: 1px"></span>" <- the <span></span> runs could fit after collapsing the trailing whitespace.
- if (continuousContent.logicalWidth() <= lineStatus.availableWidth + lineStatus.collapsibleWidth)
- return { Result::Action::Keep };
- }
- if (isVisuallyEmptyWhitespaceContent(continuousContent) && shouldKeepEndOfLineWhitespace(continuousContent)) {
- // This overflowing content apparently falls into the remove/hang end-of-line-spaces category.
- // see https://www.w3.org/TR/css-text-3/#white-space-property matrix
- return { Result::Action::Keep };
- }
+ auto canIgnoreNonContentTrailingRuns = lineStatus.collapsibleOrHangingWidth && isNonContentRunsOnly(continuousContent);
+ if (canIgnoreNonContentTrailingRuns) {
+ // Let's see if the non-content runs fit when the line has trailing collapsible/hanging content.
+ // "text content <span style="padding: 1px"></span>" <- the <span></span> runs could fit after collapsing the trailing whitespace.
+ if (continuousContent.logicalWidth() <= lineStatus.availableWidth + lineStatus.collapsibleOrHangingWidth)
+ return InlineContentBreaker::Result { Result::Action::Keep };
+ }
+ if (isVisuallyEmptyWhitespaceContent(continuousContent) && shouldKeepEndOfLineWhitespace(continuousContent)) {
+ // This overflowing content apparently falls into the remove/hang end-of-line-spaces category.
+ // see https://www.w3.org/TR/css-text-3/#white-space-property matrix
+ return InlineContentBreaker::Result { Result::Action::Keep };
+ }
+ return { };
+ };
+ if (auto result = checkForTrailingContentFit())
+ return *result;
+
size_t overflowingRunIndex = 0;
if (hasTextRun(continuousContent)) {
auto tryBreakingContentWithText = [&]() -> std::optional<Result> {
Modified: trunk/Source/WebCore/layout/formattingContexts/inline/InlineContentBreaker.h (287436 => 287437)
--- trunk/Source/WebCore/layout/formattingContexts/inline/InlineContentBreaker.h 2021-12-25 10:13:53 UTC (rev 287436)
+++ trunk/Source/WebCore/layout/formattingContexts/inline/InlineContentBreaker.h 2021-12-25 15:36:13 UTC (rev 287437)
@@ -110,7 +110,8 @@
struct LineStatus {
InlineLayoutUnit contentLogicalRight { 0 };
InlineLayoutUnit availableWidth { 0 };
- InlineLayoutUnit collapsibleWidth { 0 };
+ // Both of these types of trailing content may be ignored when checking for content fit.
+ InlineLayoutUnit collapsibleOrHangingWidth { 0 };
std::optional<InlineLayoutUnit> trailingSoftHyphenWidth;
bool hasFullyCollapsibleTrailingContent { false };
bool hasContent { false };
Modified: trunk/Source/WebCore/layout/formattingContexts/inline/InlineLine.h (287436 => 287437)
--- trunk/Source/WebCore/layout/formattingContexts/inline/InlineLine.h 2021-12-25 10:13:53 UTC (rev 287436)
+++ trunk/Source/WebCore/layout/formattingContexts/inline/InlineLine.h 2021-12-25 15:36:13 UTC (rev 287437)
@@ -58,7 +58,7 @@
InlineLayoutUnit trimmableTrailingWidth() const { return m_trimmableTrailingContent.width(); }
bool isTrailingRunFullyTrimmable() const { return m_trimmableTrailingContent.isTrailingRunFullyTrimmable(); }
- InlineLayoutUnit hangingWhitespaceWidth() const { return m_hangingTrailingContent.width(); }
+ InlineLayoutUnit hangingTrailingContentWidth() const { return m_hangingTrailingContent.width(); }
std::optional<InlineLayoutUnit> trailingSoftHyphenWidth() const { return m_trailingSoftHyphenWidth; }
void addTrailingHyphen(InlineLayoutUnit hyphenLogicalWidth);
Modified: trunk/Source/WebCore/layout/formattingContexts/inline/InlineLineBuilder.cpp (287436 => 287437)
--- trunk/Source/WebCore/layout/formattingContexts/inline/InlineLineBuilder.cpp 2021-12-25 10:13:53 UTC (rev 287436)
+++ trunk/Source/WebCore/layout/formattingContexts/inline/InlineLineBuilder.cpp 2021-12-25 15:36:13 UTC (rev 287437)
@@ -341,7 +341,7 @@
, m_lineLogicalRect.topLeft()
, m_lineLogicalRect.width()
, m_line.contentLogicalWidth()
- , m_line.hangingWhitespaceWidth()
+ , m_line.hangingTrailingContentWidth()
, isLastLine
, m_line.nonSpanningInlineLevelBoxCount()
, computedVisualOrder()
@@ -860,7 +860,21 @@
// While the floats are not considered to be on the line, they make the line contentful for line breaking.
auto availableWidthForNewContent = availableWidth(inlineContent, m_line, lineLogicalRectForCandidateContent.width());
auto lineHasContent = m_line.hasContent() || m_contentIsConstrainedByFloat;
- auto lineStatus = InlineContentBreaker::LineStatus { m_line.contentLogicalRight(), availableWidthForNewContent, m_line.trimmableTrailingWidth(), m_line.trailingSoftHyphenWidth(), m_line.isTrailingRunFullyTrimmable(), lineHasContent, !m_wrapOpportunityList.isEmpty() };
+ auto trailingContentWidthToIgnore = [&] {
+ if (auto trimmableWidth = m_line.trimmableTrailingWidth()) {
+ ASSERT(!m_line.hangingTrailingContentWidth());
+ return trimmableWidth;
+ }
+ return m_line.hangingTrailingContentWidth();
+ };
+ auto lineStatus = InlineContentBreaker::LineStatus { m_line.contentLogicalRight()
+ , availableWidthForNewContent
+ , trailingContentWidthToIgnore()
+ , m_line.trailingSoftHyphenWidth()
+ , m_line.isTrailingRunFullyTrimmable()
+ , lineHasContent
+ , !m_wrapOpportunityList.isEmpty()
+ };
auto result = inlineContentBreaker.processInlineContent(continuousInlineContent, lineStatus);
auto& candidateRuns = continuousInlineContent.runs();
if (result.action == InlineContentBreaker::Result::Action::Keep) {