Title: [253480] trunk/Source/WebCore
Revision
253480
Author
[email protected]
Date
2019-12-13 09:10:37 -0800 (Fri, 13 Dec 2019)

Log Message

[LFC][IFC] Fix fast/text/simple-line-with-br.html
https://bugs.webkit.org/show_bug.cgi?id=205207
<rdar://problem/57913504>

Reviewed by Antti Koivisto.

Apply https://www.w3.org/TR/css-text-3/#white-space-property's matrix to end-of-the-line whitespace.
(Keep white-space: mormal no-wrap pre-wrap and pre-line content)

* layout/inlineformatting/InlineLineBreaker.cpp:
(WebCore::Layout::shouldKeepEndOfLineWhitespace):
(WebCore::Layout::LineBreaker::breakingContextForInlineContent):
(WebCore::Layout::LineBreaker::Content::isVisuallyEmptyWhitespaceContentOnly const):
(WebCore::Layout::isTrailingWhitespaceWithPreWrap): Deleted.
* layout/inlineformatting/InlineLineBreaker.h:
* layout/inlineformatting/InlineLineBuilder.cpp:
(WebCore::Layout::LineBuilder::InlineItemRun::isTrimmableWhitespace const):
* layout/inlineformatting/LineLayoutContext.cpp:
(WebCore::Layout::LineLayoutContext::placeInlineItem):

Modified Paths

Diff

Modified: trunk/Source/WebCore/ChangeLog (253479 => 253480)


--- trunk/Source/WebCore/ChangeLog	2019-12-13 17:01:05 UTC (rev 253479)
+++ trunk/Source/WebCore/ChangeLog	2019-12-13 17:10:37 UTC (rev 253480)
@@ -1,3 +1,25 @@
+2019-12-13  Zalan Bujtas  <[email protected]>
+
+        [LFC][IFC] Fix fast/text/simple-line-with-br.html
+        https://bugs.webkit.org/show_bug.cgi?id=205207
+        <rdar://problem/57913504>
+
+        Reviewed by Antti Koivisto.
+
+        Apply https://www.w3.org/TR/css-text-3/#white-space-property's matrix to end-of-the-line whitespace.
+        (Keep white-space: mormal no-wrap pre-wrap and pre-line content)
+
+        * layout/inlineformatting/InlineLineBreaker.cpp:
+        (WebCore::Layout::shouldKeepEndOfLineWhitespace):
+        (WebCore::Layout::LineBreaker::breakingContextForInlineContent):
+        (WebCore::Layout::LineBreaker::Content::isVisuallyEmptyWhitespaceContentOnly const):
+        (WebCore::Layout::isTrailingWhitespaceWithPreWrap): Deleted.
+        * layout/inlineformatting/InlineLineBreaker.h:
+        * layout/inlineformatting/InlineLineBuilder.cpp:
+        (WebCore::Layout::LineBuilder::InlineItemRun::isTrimmableWhitespace const):
+        * layout/inlineformatting/LineLayoutContext.cpp:
+        (WebCore::Layout::LineLayoutContext::placeInlineItem):
+
 2019-12-13  Chris Lord  <[email protected]>
 
         Implement OffscreenCanvas.convertToBlob

Modified: trunk/Source/WebCore/layout/inlineformatting/InlineLineBreaker.cpp (253479 => 253480)


--- trunk/Source/WebCore/layout/inlineformatting/InlineLineBreaker.cpp	2019-12-13 17:01:05 UTC (rev 253479)
+++ trunk/Source/WebCore/layout/inlineformatting/InlineLineBreaker.cpp	2019-12-13 17:10:37 UTC (rev 253480)
@@ -68,11 +68,14 @@
     return false;
 }
 
-static inline bool isTrailingWhitespaceWithPreWrap(const InlineItem& trailingInlineItem)
+static inline bool shouldKeepEndOfLineWhitespace(const LineBreaker::Content& candidateRuns)
 {
-    if (!trailingInlineItem.isText())
-        return false;
-    return trailingInlineItem.style().whiteSpace() == WhiteSpace::PreWrap && downcast<InlineTextItem>(trailingInlineItem).isWhitespace();
+    // 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.
+    // It might very well get trimmed when we close the line (normal/nowrap/pre-line).
+    // See https://www.w3.org/TR/css-text-3/#white-space-property
+    auto whitespace = candidateRuns.runs()[*candidateRuns.firstTextRunIndex()].inlineItem.style().whiteSpace();
+    return whitespace == WhiteSpace::Normal || whitespace == WhiteSpace::NoWrap || whitespace == WhiteSpace::PreWrap || whitespace == WhiteSpace::PreLine;
 }
 
 LineBreaker::BreakingContext LineBreaker::breakingContextForInlineContent(const Content& candidateRuns, const LineStatus& lineStatus)
@@ -95,6 +98,11 @@
         if (candidateRuns.width() <= lineStatus.availableWidth + lineStatus.trimmableWidth)
             return { BreakingContext::ContentWrappingRule::Keep, { } };
     }
+    if (candidateRuns.isVisuallyEmptyWhitespaceContentOnly() && shouldKeepEndOfLineWhitespace(candidateRuns)) {
+        // This overflowing content apparently falls into the remove/hang end-of-line-spaces catergory.
+        // see https://www.w3.org/TR/css-text-3/#white-space-property matrix
+        return { BreakingContext::ContentWrappingRule::Keep, { } };
+    }
 
     if (candidateRuns.hasTextContentOnly()) {
         auto& runs = candidateRuns.runs();
@@ -117,10 +125,6 @@
         }
         // If we are not allowed to break this content, we still need to decide whether keep it or push it to the next line.
         auto contentShouldOverflow = lineStatus.lineIsEmpty || !isTextContentWrappingAllowed(runs[0].inlineItem.style());
-        // FIXME: white-space: pre-wrap needs clarification. According to CSS Text Module Level 3, content wrapping is as 'normal' but apparently
-        // we need to keep the overlapping whitespace on the line (and hang it I'd assume).
-        if (isTrailingWhitespaceWithPreWrap(runs.last().inlineItem))
-            contentShouldOverflow = true;
         return { contentShouldOverflow ? BreakingContext::ContentWrappingRule::Keep : BreakingContext::ContentWrappingRule::Push, { } };
     }
     // First non-text inline content always stays on line.
@@ -385,6 +389,21 @@
     return false;
 }
 
+bool LineBreaker::Content::isVisuallyEmptyWhitespaceContentOnly() const
+{
+    // [<span></span> ] [<span> </span>] [ <span style="padding: 0px;"></span>] are all considered visually empty whitespace content.
+    // [<span style="border: 1px solid red"></span> ] while this is whitespace content only, it is not considered visually empty.
+    // Due to commit boundary rules, we just need to check the first non-typeless inline item (can't have both [img] and [text])
+    for (auto& run : m_continousRuns) {
+        auto& inlineItem = run.inlineItem;
+        // FIXME: check for padding border etc.
+        if (inlineItem.isContainerStart() || inlineItem.isContainerEnd())
+            continue;
+        return inlineItem.isText() && downcast<InlineTextItem>(inlineItem).isWhitespace();
+    }
+    return false;
+}
+
 Optional<unsigned> LineBreaker::Content::firstTextRunIndex() const
 {
     for (size_t index = 0; index < m_continousRuns.size(); ++index) {

Modified: trunk/Source/WebCore/layout/inlineformatting/InlineLineBreaker.h (253479 => 253480)


--- trunk/Source/WebCore/layout/inlineformatting/InlineLineBreaker.h	2019-12-13 17:01:05 UTC (rev 253479)
+++ trunk/Source/WebCore/layout/inlineformatting/InlineLineBreaker.h	2019-12-13 17:10:37 UTC (rev 253480)
@@ -79,6 +79,7 @@
         const RunList& runs() const { return m_continousRuns; }
         bool isEmpty() const { return m_continousRuns.isEmpty(); }
         bool hasTextContentOnly() const;
+        bool isVisuallyEmptyWhitespaceContentOnly() const;
         bool hasNonContentRunsOnly() const;
         unsigned size() const { return m_continousRuns.size(); }
         InlineLayoutUnit width() const { return m_width; }

Modified: trunk/Source/WebCore/layout/inlineformatting/InlineLineBuilder.cpp (253479 => 253480)


--- trunk/Source/WebCore/layout/inlineformatting/InlineLineBuilder.cpp	2019-12-13 17:01:05 UTC (rev 253479)
+++ trunk/Source/WebCore/layout/inlineformatting/InlineLineBuilder.cpp	2019-12-13 17:10:37 UTC (rev 253480)
@@ -804,6 +804,8 @@
 
 bool LineBuilder::InlineItemRun::isTrimmableWhitespace() const
 {
+    // Return true if the "end-of-line spaces" can be removed.
+    // See https://www.w3.org/TR/css-text-3/#white-space-property matrix.
     if (!isWhitespace())
         return false;
     return !TextUtil::shouldPreserveTrailingWhitespace(style());

Modified: trunk/Source/WebCore/layout/inlineformatting/LineLayoutContext.cpp (253479 => 253480)


--- trunk/Source/WebCore/layout/inlineformatting/LineLayoutContext.cpp	2019-12-13 17:01:05 UTC (rev 253479)
+++ trunk/Source/WebCore/layout/inlineformatting/LineLayoutContext.cpp	2019-12-13 17:10:37 UTC (rev 253480)
@@ -174,7 +174,9 @@
     }
     // Line breaks are also special.
     if (inlineItem.isLineBreak()) {
-        auto isEndOfLine = !m_uncommittedContent.isEmpty() ? processUncommittedContent(line) : IsEndOfLine::No;
+        auto isEndOfLine = IsEndOfLine::No;
+        if (!m_uncommittedContent.isEmpty())
+            isEndOfLine = processUncommittedContent(line);
         // When the uncommitted content fits(or the line is empty), add the line break to this line as well.
         if (isEndOfLine == IsEndOfLine::No) {
             m_uncommittedContent.append(inlineItem, itemLogicalWidth);
_______________________________________________
webkit-changes mailing list
[email protected]
https://lists.webkit.org/mailman/listinfo/webkit-changes

Reply via email to