Title: [287525] trunk/Source/WebCore
Revision
287525
Author
[email protected]
Date
2022-01-02 16:49:30 -0800 (Sun, 02 Jan 2022)

Log Message

[LFC][IFC] Add ASSERT(middle >= left && middle < right) to TextUtil::breakWord
https://bugs.webkit.org/show_bug.cgi?id=234801

Reviewed by Antti Koivisto.

Before adding support for surrogate pairs, the implicit integral flooring guaranteed that
(left + right) / 2 always produced a middle point where left >= middle and middle < right.
With introducing surrogate pair support, the middle point may end up being equal to the right position.
(when the (left + right) / 2 falls right in the middle of a surrogate pair, we advance the index
to the _end_ of the pair (and later we adjust it by calling U16_SET_CP_START)).

In this patch, we revert this behavior back so that the middle point is always < right.
We also make sure that left/right/middle are all fall on cluster boundary by calling nextUserPerceivedCharacterIndex.
This patch is also in preparation for introducing grapheme cluster support.

* layout/formattingContexts/inline/text/TextUtil.cpp:
(WebCore::Layout::TextUtil::breakWord):

Modified Paths

Diff

Modified: trunk/Source/WebCore/ChangeLog (287524 => 287525)


--- trunk/Source/WebCore/ChangeLog	2022-01-02 23:42:27 UTC (rev 287524)
+++ trunk/Source/WebCore/ChangeLog	2022-01-03 00:49:30 UTC (rev 287525)
@@ -1,3 +1,23 @@
+2022-01-02  Alan Bujtas  <[email protected]>
+
+        [LFC][IFC] Add ASSERT(middle >= left && middle < right) to TextUtil::breakWord
+        https://bugs.webkit.org/show_bug.cgi?id=234801
+
+        Reviewed by Antti Koivisto.
+
+        Before adding support for surrogate pairs, the implicit integral flooring guaranteed that
+        (left + right) / 2 always produced a middle point where left >= middle and middle < right.
+        With introducing surrogate pair support, the middle point may end up being equal to the right position.
+        (when the (left + right) / 2 falls right in the middle of a surrogate pair, we advance the index
+        to the _end_ of the pair (and later we adjust it by calling U16_SET_CP_START)).
+
+        In this patch, we revert this behavior back so that the middle point is always < right.
+        We also make sure that left/right/middle are all fall on cluster boundary by calling nextUserPerceivedCharacterIndex.
+        This patch is also in preparation for introducing grapheme cluster support.
+
+        * layout/formattingContexts/inline/text/TextUtil.cpp:
+        (WebCore::Layout::TextUtil::breakWord):
+
 2022-01-02  Antoine Quint  <[email protected]>
 
         [Web Animations] getKeyframes() should handle multiple keyframes for the same offset

Modified: trunk/Source/WebCore/layout/formattingContexts/inline/text/TextUtil.cpp (287524 => 287525)


--- trunk/Source/WebCore/layout/formattingContexts/inline/text/TextUtil.cpp	2022-01-02 23:42:27 UTC (rev 287524)
+++ trunk/Source/WebCore/layout/formattingContexts/inline/text/TextUtil.cpp	2022-01-03 00:49:30 UTC (rev 287525)
@@ -151,13 +151,20 @@
     ASSERT(length);
 
     auto text = inlineTextBox.content();
-    auto surrogatePairAwareIndex = [&] (auto index) {
-        // We should never break in the middle of a surrogate pair. They are considered one joint entity.
-        auto offset = index + 1;
-        U16_SET_CP_LIMIT(text, 0, offset, text.length());
+    auto userPerceivedCharacterBoundaryAlignedIndex = [&] (auto index) {
+        if (text.is8Bit())
+            return index;
+        auto alignedStartIndex = index;
+        U16_SET_CP_START(text, startPosition, alignedStartIndex);
+        ASSERT(alignedStartIndex >= startPosition);
+        return alignedStartIndex;
+    };
 
-        // Returns the index at trail.
-        return offset - 1;
+    auto nextUserPerceivedCharacterIndex = [&] (auto index) {
+        if (text.is8Bit())
+            return index + 1;
+        U16_FWD_1(text, index, length);
+        return index;
     };
 
     auto left = startPosition;
@@ -165,22 +172,21 @@
     // Adjust the range so that we can pick a reasonable midpoint.
     auto averageCharacterWidth = InlineLayoutUnit { textWidth / length };
     unsigned offset = toLayoutUnit(2 * availableWidth / averageCharacterWidth).toUnsigned();
-    auto right = surrogatePairAwareIndex(std::min<unsigned>(left + offset, (startPosition + length - 1)));
+    auto right = userPerceivedCharacterBoundaryAlignedIndex(std::min<unsigned>(left + offset, (startPosition + length - 1)));
     // Preserve the left width for the final split position so that we don't need to remeasure the left side again.
     auto leftSideWidth = InlineLayoutUnit { 0 };
     while (left < right) {
-        auto middle = surrogatePairAwareIndex((left + right) / 2);
-        auto width = TextUtil::width(inlineTextBox, fontCascade, startPosition, middle + 1, contentLogicalLeft);
+        auto middle = userPerceivedCharacterBoundaryAlignedIndex((left + right) / 2);
+        ASSERT(middle >= left && middle < right);
+        auto endOfMiddleCharacter = nextUserPerceivedCharacterIndex(middle);
+        auto width = TextUtil::width(inlineTextBox, fontCascade, startPosition, endOfMiddleCharacter, contentLogicalLeft);
         if (width < availableWidth) {
-            left = middle + 1;
+            left = endOfMiddleCharacter;
             leftSideWidth = width;
-        } else if (width > availableWidth) {
-            // When the substring does not fit, the right side is supposed to be the start of the surrogate pair if applicable, unless startPosition falls between surrogate pair.
+        } else if (width > availableWidth)
             right = middle;
-            U16_SET_CP_START(text, 0, right);
-            ASSERT(right >= startPosition);
-        } else {
-            right = middle + 1;
+        else {
+            right = endOfMiddleCharacter;
             leftSideWidth = width;
             break;
         }
_______________________________________________
webkit-changes mailing list
[email protected]
https://lists.webkit.org/mailman/listinfo/webkit-changes

Reply via email to