- Revision
- 251633
- Author
- za...@apple.com
- Date
- 2019-10-26 05:53:00 -0700 (Sat, 26 Oct 2019)
Log Message
[LFC][IFC] Completely collapsed runs should not have advance width
https://bugs.webkit.org/show_bug.cgi?id=203457
<rdar://problem/56645024>
Reviewed by Antti Koivisto.
Let's reset the advance width for completely collapsed runs (any a collapsible space immediatelly following another
collapsible space).
https://drafts.csswg.org/css-text-3/#white-space-phase-1
* layout/inlineformatting/InlineFormattingContext.cpp:
(WebCore::Layout::InlineFormattingContext::setDisplayBoxesForLine):
* layout/inlineformatting/InlineFormattingContextQuirks.cpp:
(WebCore::Layout::InlineFormattingContext::Quirks::lineDescentNeedsCollapsing const):
* layout/inlineformatting/InlineLine.cpp:
(WebCore::Layout::Line::Run::canBeExtended const):
(WebCore::Layout::Line::isVisuallyEmpty const):
(WebCore::Layout::Line::removeTrailingTrimmableContent):
(WebCore::Layout::Line::trailingTrimmableWidth const):
(WebCore::Layout::Line::appendTextContent):
* layout/inlineformatting/InlineLine.h:
(WebCore::Layout::Line::Run::expand):
(WebCore::Layout::Line::Run::isCollapsedToZeroAdvanceWidth const):
(WebCore::Layout::Line::Run::setCollapsesToZeroAdvanceWidth):
(WebCore::Layout::Line::Run::isVisuallyEmpty const): Deleted.
(WebCore::Layout::Line::Run::setVisuallyIsEmpty): Deleted.
Modified Paths
Diff
Modified: trunk/Source/WebCore/ChangeLog (251632 => 251633)
--- trunk/Source/WebCore/ChangeLog 2019-10-26 12:47:05 UTC (rev 251632)
+++ trunk/Source/WebCore/ChangeLog 2019-10-26 12:53:00 UTC (rev 251633)
@@ -1,3 +1,32 @@
+2019-10-26 Zalan Bujtas <za...@apple.com>
+
+ [LFC][IFC] Completely collapsed runs should not have advance width
+ https://bugs.webkit.org/show_bug.cgi?id=203457
+ <rdar://problem/56645024>
+
+ Reviewed by Antti Koivisto.
+
+ Let's reset the advance width for completely collapsed runs (any a collapsible space immediatelly following another
+ collapsible space).
+ https://drafts.csswg.org/css-text-3/#white-space-phase-1
+
+ * layout/inlineformatting/InlineFormattingContext.cpp:
+ (WebCore::Layout::InlineFormattingContext::setDisplayBoxesForLine):
+ * layout/inlineformatting/InlineFormattingContextQuirks.cpp:
+ (WebCore::Layout::InlineFormattingContext::Quirks::lineDescentNeedsCollapsing const):
+ * layout/inlineformatting/InlineLine.cpp:
+ (WebCore::Layout::Line::Run::canBeExtended const):
+ (WebCore::Layout::Line::isVisuallyEmpty const):
+ (WebCore::Layout::Line::removeTrailingTrimmableContent):
+ (WebCore::Layout::Line::trailingTrimmableWidth const):
+ (WebCore::Layout::Line::appendTextContent):
+ * layout/inlineformatting/InlineLine.h:
+ (WebCore::Layout::Line::Run::expand):
+ (WebCore::Layout::Line::Run::isCollapsedToZeroAdvanceWidth const):
+ (WebCore::Layout::Line::Run::setCollapsesToZeroAdvanceWidth):
+ (WebCore::Layout::Line::Run::isVisuallyEmpty const): Deleted.
+ (WebCore::Layout::Line::Run::setVisuallyIsEmpty): Deleted.
+
2019-10-26 Antti Koivisto <an...@apple.com>
Build cascade in PropertyCascade constructor
Modified: trunk/Source/WebCore/layout/inlineformatting/InlineFormattingContext.cpp (251632 => 251633)
--- trunk/Source/WebCore/layout/inlineformatting/InlineFormattingContext.cpp 2019-10-26 12:47:05 UTC (rev 251632)
+++ trunk/Source/WebCore/layout/inlineformatting/InlineFormattingContext.cpp 2019-10-26 12:53:00 UTC (rev 251633)
@@ -435,8 +435,8 @@
// Inline level containers (<span>) don't generate inline runs.
if (lineRun->isContainerStart() || lineRun->isContainerEnd())
continue;
- // Collapsed line runs don't generate display runs.
- if (lineRun->isVisuallyEmpty())
+ // Completely collapsed line runs don't generate display runs.
+ if (lineRun->isCollapsedToZeroAdvanceWidth())
continue;
formattingState.addInlineRun(lineRun->displayRun(), currentLine);
}
@@ -490,15 +490,14 @@
const Line::Run* previousLineRun = !index ? nullptr : lineRuns[index - 1].get();
// FIXME take content breaking into account when part of the layout box is on the previous line.
auto firstInlineRunForLayoutBox = !previousLineRun || &previousLineRun->layoutBox() != &layoutBox;
- auto logicalWidth = lineRun->isVisuallyEmpty() ? LayoutUnit() : logicalRect.width();
if (firstInlineRunForLayoutBox) {
// Setup display box for the associated layout box.
displayBox.setTopLeft(logicalRect.topLeft());
- displayBox.setContentBoxWidth(logicalWidth);
+ displayBox.setContentBoxWidth(logicalRect.width());
displayBox.setContentBoxHeight(logicalRect.height());
} else {
// FIXME fix it for multirun/multiline.
- displayBox.setContentBoxWidth(displayBox.contentBoxWidth() + logicalWidth);
+ displayBox.setContentBoxWidth(displayBox.contentBoxWidth() + logicalRect.width());
}
continue;
}
Modified: trunk/Source/WebCore/layout/inlineformatting/InlineFormattingContextQuirks.cpp (251632 => 251633)
--- trunk/Source/WebCore/layout/inlineformatting/InlineFormattingContextQuirks.cpp 2019-10-26 12:47:05 UTC (rev 251632)
+++ trunk/Source/WebCore/layout/inlineformatting/InlineFormattingContextQuirks.cpp 2019-10-26 12:53:00 UTC (rev 251633)
@@ -50,7 +50,7 @@
if (run->isForcedLineBreak())
return false;
if (run->isText()) {
- if (!run->isVisuallyEmpty())
+ if (!run->isCollapsedToZeroAdvanceWidth())
return false;
continue;
}
Modified: trunk/Source/WebCore/layout/inlineformatting/InlineLine.cpp (251632 => 251633)
--- trunk/Source/WebCore/layout/inlineformatting/InlineLine.cpp 2019-10-26 12:47:05 UTC (rev 251632)
+++ trunk/Source/WebCore/layout/inlineformatting/InlineLine.cpp 2019-10-26 12:53:00 UTC (rev 251633)
@@ -55,7 +55,7 @@
if (!isText())
return false;
// Non-collapsed text runs can be merged into one continuous run.
- if (isVisuallyEmpty())
+ if (isCollapsedToZeroAdvanceWidth())
return false;
return !isCollapsed();
}
@@ -120,7 +120,7 @@
return false;
continue;
}
- if (!run->isText() || !run->isVisuallyEmpty())
+ if (!run->isText() || !run->isCollapsedToZeroAdvanceWidth())
return false;
}
return true;
@@ -272,8 +272,9 @@
LayoutUnit trimmableWidth;
for (auto* trimmableRun : m_trimmableContent) {
ASSERT(trimmableRun->isText());
- trimmableRun->setVisuallyIsEmpty();
+ // FIXME: We might need to be able to differentiate between trimmed and collapsed runs.
trimmableWidth += trimmableRun->logicalRect().width();
+ trimmableRun->setCollapsesToZeroAdvanceWidth();
}
m_lineBox.shrinkHorizontally(trimmableWidth);
}
@@ -296,10 +297,8 @@
LayoutUnit Line::trailingTrimmableWidth() const
{
LayoutUnit trimmableWidth;
- for (auto* trimmableRun : m_trimmableContent) {
- ASSERT(!trimmableRun->isVisuallyEmpty());
+ for (auto* trimmableRun : m_trimmableContent)
trimmableWidth += trimmableRun->logicalRect().width();
- }
return trimmableWidth;
}
@@ -366,11 +365,13 @@
auto& run = m_runList[i];
if (run->isBox())
return false;
- // When the previous text run is collapsed, this collapsible run collapses completely.
+ // https://drafts.csswg.org/css-text-3/#white-space-phase-1
+ // Any collapsible space immediately following another collapsible space—even one outside the boundary of the inline containing that space,
+ // provided both spaces are within the same inline formatting context—is collapsed to have zero advance width.
+ // : "<span> </span> " <- the trailing whitespace collapses completely.
+ // Not that when the inline container has preserve whitespace style, "<span style="white-space: pre"> </span> " <- this whitespace stays around.
if (run->isText())
return run->isCollapsed();
- // Collapsing works across inline containers: "<span> </span> " <- the trailing whitespace collapses completely.
- // Not that when the inline container has preserve whitespace style, "<span style="white-space: pre"> </span> " <- this whitespace stays around.
ASSERT(run->isContainerStart() || run->isContainerEnd());
}
return true;
@@ -388,20 +389,18 @@
auto contentStart = inlineItem.start();
auto contentLength = collapseRun ? 1 : inlineItem.length();
auto textContent = inlineItem.layoutBox().textContent().substring(contentStart, contentLength);
- auto lineItem = makeUnique<Run>(inlineItem, Display::Run { inlineItem.style(), logicalRect, Display::Run::TextContext { contentStart, contentLength, textContent } });
+ auto lineRun = makeUnique<Run>(inlineItem, Display::Run { inlineItem.style(), logicalRect, Display::Run::TextContext { contentStart, contentLength, textContent } });
- auto isVisuallyEmpty = willCollapseCompletely();
- if (collapseRun)
- lineItem->setIsCollapsed();
- if (isVisuallyEmpty)
- lineItem->setVisuallyIsEmpty();
- else if (isTrimmable)
- m_trimmableContent.add(lineItem.get());
+ auto collapsesToZeroAdvanceWidth = willCollapseCompletely();
+ if (collapsesToZeroAdvanceWidth)
+ lineRun->setCollapsesToZeroAdvanceWidth();
+ else if (collapseRun)
+ lineRun->setIsCollapsed();
+ if (isTrimmable)
+ m_trimmableContent.add(lineRun.get());
- m_runList.append(WTFMove(lineItem));
- // Collapsed line items don't contribute to the line width.
- if (!isVisuallyEmpty)
- m_lineBox.expandHorizontally(logicalWidth);
+ m_lineBox.expandHorizontally(lineRun->logicalRect().width());
+ m_runList.append(WTFMove(lineRun));
}
void Line::appendNonReplacedInlineBox(const InlineItem& inlineItem, LayoutUnit logicalWidth)
Modified: trunk/Source/WebCore/layout/inlineformatting/InlineLine.h (251632 => 251633)
--- trunk/Source/WebCore/layout/inlineformatting/InlineLine.h 2019-10-26 12:47:05 UTC (rev 251632)
+++ trunk/Source/WebCore/layout/inlineformatting/InlineLine.h 2019-10-26 12:53:00 UTC (rev 251633)
@@ -73,7 +73,7 @@
const Box& layoutBox() const { return m_inlineItem.layoutBox(); }
const Display::Rect& logicalRect() const { return m_displayRun.logicalRect(); }
- bool isVisuallyEmpty() const { return m_isVisuallyEmpty; }
+ bool isCollapsedToZeroAdvanceWidth() const;
bool isCollapsed() const { return m_isCollapsed; }
bool isText() const { return m_inlineItem.isText() && !isForcedLineBreak(); }
@@ -90,8 +90,8 @@
void expand(const Run&);
- void setVisuallyIsEmpty() { m_isVisuallyEmpty = true; }
void setIsCollapsed() { m_isCollapsed = true; }
+ void setCollapsesToZeroAdvanceWidth();
bool isWhitespace() const;
bool canBeExtended() const;
@@ -99,7 +99,7 @@
const InlineItem& m_inlineItem;
Display::Run m_displayRun;
bool m_isCollapsed { false };
- bool m_isVisuallyEmpty { false };
+ bool m_collapsedToZeroAdvanceWidth { false };
};
using RunList = Vector<std::unique_ptr<Run>>;
RunList close();
@@ -154,6 +154,7 @@
{
ASSERT(isText());
ASSERT(other.isText());
+ ASSERT(!isCollapsedToZeroAdvanceWidth());
auto& otherDisplayRun = other.displayRun();
m_displayRun.expandHorizontally(otherDisplayRun.logicalWidth());
@@ -160,6 +161,19 @@
m_displayRun.textContext()->expand(*otherDisplayRun.textContext());
}
+inline bool Line::Run::isCollapsedToZeroAdvanceWidth() const
+{
+ ASSERT(!m_collapsedToZeroAdvanceWidth || !m_displayRun.logicalWidth());
+ return m_collapsedToZeroAdvanceWidth;
}
+
+inline void Line::Run::setCollapsesToZeroAdvanceWidth()
+{
+ m_collapsedToZeroAdvanceWidth = true;
+ m_isCollapsed = true;
+ m_displayRun.setLogicalWidth({ });
}
+
+}
+}
#endif