Title: [253468] trunk/Source/WebCore
Revision
253468
Author
[email protected]
Date
2019-12-13 05:47:50 -0800 (Fri, 13 Dec 2019)

Log Message

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

Reviewed by Antti Koivisto.

Use LazyLineBreakIterator to find out if 2 (visually)adjacent non-whitespace inline items are
on a soft breaking opportunity.

* layout/inlineformatting/InlineLineBreaker.cpp:
(WebCore::Layout::endsWithBreakingOpportunity):
(WebCore::Layout::LineBreaker::Content::isAtContentBoundary):
* layout/inlineformatting/InlineTextItem.cpp:
(WebCore::Layout::moveToNextBreakablePosition):
* layout/inlineformatting/text/TextUtil.cpp:
(WebCore::Layout::TextUtil::findNextBreakablePosition):
* layout/inlineformatting/text/TextUtil.h:

Modified Paths

Diff

Modified: trunk/Source/WebCore/ChangeLog (253467 => 253468)


--- trunk/Source/WebCore/ChangeLog	2019-12-13 10:54:33 UTC (rev 253467)
+++ trunk/Source/WebCore/ChangeLog	2019-12-13 13:47:50 UTC (rev 253468)
@@ -1,3 +1,23 @@
+2019-12-13  Zalan Bujtas  <[email protected]>
+
+        [LFC][IFC] Fix fast/text/simple-line-with-multiple-renderers.html
+        https://bugs.webkit.org/show_bug.cgi?id=205193
+        <rdar://problem/57900709>
+
+        Reviewed by Antti Koivisto.
+
+        Use LazyLineBreakIterator to find out if 2 (visually)adjacent non-whitespace inline items are
+        on a soft breaking opportunity.
+
+        * layout/inlineformatting/InlineLineBreaker.cpp:
+        (WebCore::Layout::endsWithBreakingOpportunity):
+        (WebCore::Layout::LineBreaker::Content::isAtContentBoundary):
+        * layout/inlineformatting/InlineTextItem.cpp:
+        (WebCore::Layout::moveToNextBreakablePosition):
+        * layout/inlineformatting/text/TextUtil.cpp:
+        (WebCore::Layout::TextUtil::findNextBreakablePosition):
+        * layout/inlineformatting/text/TextUtil.h:
+
 2019-12-13  Carlos Garcia Campos  <[email protected]>
 
         Uninitialized variables in RenderLayer

Modified: trunk/Source/WebCore/layout/inlineformatting/InlineLineBreaker.cpp (253467 => 253468)


--- trunk/Source/WebCore/layout/inlineformatting/InlineLineBreaker.cpp	2019-12-13 10:54:33 UTC (rev 253467)
+++ trunk/Source/WebCore/layout/inlineformatting/InlineLineBreaker.cpp	2019-12-13 13:47:50 UTC (rev 253468)
@@ -223,6 +223,30 @@
     return LeftSide { hyphenLocation, trailingPartialRunWidthWithHyphen, true };
 }
 
+static bool endsWithBreakingOpportunity(const InlineTextItem& previousTextItem, const InlineTextItem& nextInlineTextItem)
+{
+    ASSERT(!previousTextItem.isWhitespace());
+    ASSERT(!nextInlineTextItem.isWhitespace());
+    // When both these non-whitespace runs belong to the same layout box, it's guaranteed that
+    // they are split at a soft breaking opportunity. See InlineTextItem::moveToNextBreakablePosition.
+    if (&previousTextItem.layoutBox() == &nextInlineTextItem.layoutBox())
+        return true;
+    // Now we need to collect at least 3 adjacent characters to be able to make a descision whether the previous text item ends with breaking opportunity.
+    // [ex-][ample] <- second to last[x] last[-] current[a]
+    // We need at least 1 character in the current inline text item and 2 more from previous inline items.
+    auto previousContent = previousTextItem.layoutBox().textContext()->content;
+    auto lineBreakIterator = LazyLineBreakIterator { nextInlineTextItem.layoutBox().textContext()->content };
+    auto previousContentLength = previousContent.length();
+    // FIXME: We should look into the entire uncommitted content for more text context.
+    UChar lastCharacter = previousContentLength ? previousContent[previousContentLength - 1] : 0;
+    UChar secondToLastCharacter = previousContentLength > 1 ? previousContent[previousContentLength - 2] : 0;
+    lineBreakIterator.setPriorContext(lastCharacter, secondToLastCharacter);
+    // Now check if we can break right at the inline item boundary.
+    // With the [ex-ample], findNextBreakablePosition should return the startPosition (0).
+    // FIXME: Check if there's a more correct way of finding breaking opportunities.
+    return !TextUtil::findNextBreakablePosition(lineBreakIterator, 0, nextInlineTextItem.style());
+}
+
 bool LineBreaker::Content::isAtContentBoundary(const InlineItem& inlineItem, const Content& content)
 {
     // https://drafts.csswg.org/css-text-3/#line-break-details
@@ -269,12 +293,7 @@
             auto& previousInlineTextItem = downcast<InlineTextItem>(*lastUncomittedContent);
             if (previousInlineTextItem.isWhitespace())
                 return true;
-            // When both these non-whitespace runs belong to the same layout box, it's guaranteed that
-            // they are split at a soft breaking opportunity. See InlineTextItem::moveToNextBreakablePosition.
-            if (&inlineItem.layoutBox() == &lastUncomittedContent->layoutBox())
-                return true;
-            // FIXME: check if <span>text-</span><span>text</span> should be handled here as well.
-            return false;
+            return endsWithBreakingOpportunity(previousInlineTextItem, downcast<InlineTextItem>(inlineItem));
         }
         // <img>text -> the inline box is on a commit boundary.
         if (lastUncomittedContent->isBox())

Modified: trunk/Source/WebCore/layout/inlineformatting/InlineTextItem.cpp (253467 => 253468)


--- trunk/Source/WebCore/layout/inlineformatting/InlineTextItem.cpp	2019-12-13 10:54:33 UTC (rev 253467)
+++ trunk/Source/WebCore/layout/inlineformatting/InlineTextItem.cpp	2019-12-13 13:47:50 UTC (rev 253468)
@@ -28,9 +28,9 @@
 
 #if ENABLE(LAYOUT_FORMATTING_CONTEXT)
 
-#include "BreakLines.h"
 #include "FontCascade.h"
 #include "InlineSoftLineBreakItem.h"
+#include "TextUtil.h"
 
 namespace WebCore {
 namespace Layout {
@@ -48,33 +48,12 @@
     return nextNonWhiteSpacePosition - startPosition;
 }
 
-static unsigned moveToNextBreakablePosition(unsigned startPosition, LazyLineBreakIterator lineBreakIterator, const RenderStyle& style)
+static unsigned moveToNextBreakablePosition(unsigned startPosition, LazyLineBreakIterator& lineBreakIterator, const RenderStyle& style)
 {
-    auto findNextBreakablePosition = [&](auto startPosition) {
-        auto keepAllWordsForCJK = style.wordBreak() == WordBreak::KeepAll;
-        auto breakNBSP = style.autoWrap() && style.nbspMode() == NBSPMode::Space;
-
-        if (keepAllWordsForCJK) {
-            if (breakNBSP)
-                return nextBreakablePositionKeepingAllWords(lineBreakIterator, startPosition);
-            return nextBreakablePositionKeepingAllWordsIgnoringNBSP(lineBreakIterator, startPosition);
-        }
-
-        if (lineBreakIterator.mode() == LineBreakIteratorMode::Default) {
-            if (breakNBSP)
-                return WebCore::nextBreakablePosition(lineBreakIterator, startPosition);
-            return nextBreakablePositionIgnoringNBSP(lineBreakIterator, startPosition);
-        }
-
-        if (breakNBSP)
-            return nextBreakablePositionWithoutShortcut(lineBreakIterator, startPosition);
-        return nextBreakablePositionIgnoringNBSPWithoutShortcut(lineBreakIterator, startPosition);
-    };
-
     auto textLength = lineBreakIterator.stringView().length();
     auto startPositionForNextBreakablePosition = startPosition;
     while (startPositionForNextBreakablePosition < textLength) {
-        auto nextBreakablePosition = findNextBreakablePosition(startPositionForNextBreakablePosition);
+        auto nextBreakablePosition = TextUtil::findNextBreakablePosition(lineBreakIterator, startPositionForNextBreakablePosition, style);
         // Oftentimes the next breakable position comes back as the start position (most notably hyphens).
         if (nextBreakablePosition != startPosition)
             return nextBreakablePosition - startPosition;

Modified: trunk/Source/WebCore/layout/inlineformatting/text/TextUtil.cpp (253467 => 253468)


--- trunk/Source/WebCore/layout/inlineformatting/text/TextUtil.cpp	2019-12-13 10:54:33 UTC (rev 253467)
+++ trunk/Source/WebCore/layout/inlineformatting/text/TextUtil.cpp	2019-12-13 13:47:50 UTC (rev 253468)
@@ -28,6 +28,7 @@
 
 #if ENABLE(LAYOUT_FORMATTING_CONTEXT)
 
+#include "BreakLines.h"
 #include "FontCascade.h"
 #include "InlineTextItem.h"
 #include "RenderStyle.h"
@@ -133,6 +134,28 @@
     return whitespace == WhiteSpace::Pre || whitespace == WhiteSpace::PreWrap;
 }
 
+unsigned TextUtil::findNextBreakablePosition(LazyLineBreakIterator& lineBreakIterator, unsigned startPosition, const RenderStyle& style)
+{
+    auto keepAllWordsForCJK = style.wordBreak() == WordBreak::KeepAll;
+    auto breakNBSP = style.autoWrap() && style.nbspMode() == NBSPMode::Space;
+
+    if (keepAllWordsForCJK) {
+        if (breakNBSP)
+            return nextBreakablePositionKeepingAllWords(lineBreakIterator, startPosition);
+        return nextBreakablePositionKeepingAllWordsIgnoringNBSP(lineBreakIterator, startPosition);
+    }
+
+    if (lineBreakIterator.mode() == LineBreakIteratorMode::Default) {
+        if (breakNBSP)
+            return WebCore::nextBreakablePosition(lineBreakIterator, startPosition);
+        return nextBreakablePositionIgnoringNBSP(lineBreakIterator, startPosition);
+    }
+
+    if (breakNBSP)
+        return nextBreakablePositionWithoutShortcut(lineBreakIterator, startPosition);
+    return nextBreakablePositionIgnoringNBSPWithoutShortcut(lineBreakIterator, startPosition);
 }
+
 }
+}
 #endif

Modified: trunk/Source/WebCore/layout/inlineformatting/text/TextUtil.h (253467 => 253468)


--- trunk/Source/WebCore/layout/inlineformatting/text/TextUtil.h	2019-12-13 10:54:33 UTC (rev 253467)
+++ trunk/Source/WebCore/layout/inlineformatting/text/TextUtil.h	2019-12-13 13:47:50 UTC (rev 253468)
@@ -28,6 +28,7 @@
 #if ENABLE(LAYOUT_FORMATTING_CONTEXT)
 
 #include "InlineItem.h"
+#include <wtf/text/TextBreakIterator.h>
 
 namespace WebCore {
 
@@ -46,6 +47,7 @@
     };
     static SplitData split(const Box&, unsigned startPosition, unsigned length, InlineLayoutUnit textWidth, InlineLayoutUnit availableWidth, InlineLayoutUnit contentLogicalLeft);
     static bool shouldPreserveTrailingWhitespace(const RenderStyle&);
+    static unsigned findNextBreakablePosition(LazyLineBreakIterator&, unsigned startPosition, const RenderStyle&);
 
 private:
     static InlineLayoutUnit fixedPitchWidth(const StringView&, const RenderStyle&, unsigned from, unsigned to, InlineLayoutUnit contentLogicalLeft);
_______________________________________________
webkit-changes mailing list
[email protected]
https://lists.webkit.org/mailman/listinfo/webkit-changes

Reply via email to