Title: [286101] trunk/Source/WebCore
Revision
286101
Author
za...@apple.com
Date
2021-11-21 10:33:06 -0800 (Sun, 21 Nov 2021)

Log Message

[LFC][IFC] Cache measured width even if canUseSimplifiedTextMeasuring is false
https://bugs.webkit.org/show_bug.cgi?id=233404

Reviewed by Antti Koivisto.

Just because some content goes through the non-simplified text measuring codepath, it does not
necessary mean we can't cache the measured value on the inline item (actually, we can cache these values just fine in most cases).

This is in preparation for being able to cache bidi content measured widths.

* layout/formattingContexts/inline/InlineItemsBuilder.cpp:
(WebCore::Layout::canCacheMeasuredWidthOnInlineTextItem):
(WebCore::Layout::InlineItemsBuilder::handleTextContent):

Modified Paths

Diff

Modified: trunk/Source/WebCore/ChangeLog (286100 => 286101)


--- trunk/Source/WebCore/ChangeLog	2021-11-21 18:22:01 UTC (rev 286100)
+++ trunk/Source/WebCore/ChangeLog	2021-11-21 18:33:06 UTC (rev 286101)
@@ -1,3 +1,19 @@
+2021-11-21  Alan Bujtas  <za...@apple.com>
+
+        [LFC][IFC] Cache measured width even if canUseSimplifiedTextMeasuring is false
+        https://bugs.webkit.org/show_bug.cgi?id=233404
+
+        Reviewed by Antti Koivisto.
+
+        Just because some content goes through the non-simplified text measuring codepath, it does not
+        necessary mean we can't cache the measured value on the inline item (actually, we can cache these values just fine in most cases).
+
+        This is in preparation for being able to cache bidi content measured widths.
+
+        * layout/formattingContexts/inline/InlineItemsBuilder.cpp:
+        (WebCore::Layout::canCacheMeasuredWidthOnInlineTextItem):
+        (WebCore::Layout::InlineItemsBuilder::handleTextContent):
+
 2021-11-21  Ziran Sun  <z...@igalia.com>
 
         [css-grid] svg image as grid items should use the overriding logical width/height when defined to compute the logical height/width

Modified: trunk/Source/WebCore/layout/formattingContexts/inline/InlineItemsBuilder.cpp (286100 => 286101)


--- trunk/Source/WebCore/layout/formattingContexts/inline/InlineItemsBuilder.cpp	2021-11-21 18:22:01 UTC (rev 286100)
+++ trunk/Source/WebCore/layout/formattingContexts/inline/InlineItemsBuilder.cpp	2021-11-21 18:33:06 UTC (rev 286101)
@@ -349,12 +349,22 @@
     setBidiLevelForOpaqueInlineItems();
 }
 
-static inline bool canCacheMeasuredWidthOnInlineTextItem(const InlineTextBox& inlineTextBox)
+static inline bool canCacheMeasuredWidthOnInlineTextItem(const InlineTextBox& inlineTextBox, size_t start, size_t length, bool isWhitespace)
 {
-    // FIXME: Disable width caching for position dependent content only.
-    if (!inlineTextBox.canUseSimplifiedContentMeasuring())
+    // Do not cache when:
+    // 1. first-line style's unique font properties may produce non-matching width values.
+    // 2. position dependent content is present (preserved tab character atm).
+    if (inlineTextBox.style().fontCascade() != inlineTextBox.firstLineStyle().fontCascade())
         return false;
-    return inlineTextBox.style().fontCascade() == inlineTextBox.firstLineStyle().fontCascade();
+    if (!isWhitespace || !TextUtil::shouldPreserveSpacesAndTabs(inlineTextBox))
+        return true;
+    // FIXME: Currently we opt out of caching only when we see a preserved \t character (position dependent measured width).
+    auto textContent = inlineTextBox.content();
+    for (auto index = start; index < start + length; ++index) {
+        if (textContent[index] == tabCharacter)
+            return false;
+    }
+    return true;
 }
 
 void InlineItemsBuilder::handleTextContent(const InlineTextBox& inlineTextBox, InlineItems& inlineItems)
@@ -369,6 +379,7 @@
 
     auto& style = inlineTextBox.style();
     auto& fontCascade = style.fontCascade();
+    auto whiteSpaceWidth = std::optional<InlineLayoutUnit> { fontCascade.spaceWidth() };
     auto shouldPreserveSpacesAndTabs = TextUtil::shouldPreserveSpacesAndTabs(inlineTextBox);
     auto whitespaceContentIsTreatedAsSingleSpace = !shouldPreserveSpacesAndTabs;
     auto shouldPreserveNewline = TextUtil::shouldPreserveNewline(inlineTextBox);
@@ -376,13 +387,6 @@
     auto lineBreakIterator = LazyLineBreakIterator { text, style.computedLocale(), TextUtil::lineBreakIteratorMode(style.lineBreak()) };
     unsigned currentPosition = 0;
 
-    auto textWidth = [&](auto startPosition, auto length) -> std::optional<InlineLayoutUnit> {
-        // Delay content measuring until after bidi split.
-        if (hasSeenBidiContent() || !canCacheMeasuredWidthOnInlineTextItem(inlineTextBox))
-            return { };
-        return TextUtil::width(inlineTextBox, fontCascade, startPosition, startPosition + length, { });
-    };
-
     while (currentPosition < contentLength) {
         auto handleSegmentBreak = [&] {
             // Segment breaks with preserve new line style (white-space: pre, pre-wrap, break-spaces and pre-line) compute to forced line break.
@@ -403,8 +407,13 @@
 
             ASSERT(whitespaceContent->length);
             auto appendWhitespaceItem = [&] (auto startPosition, auto itemLength) {
-                auto simpleSingleWhitespaceContent = inlineTextBox.canUseSimplifiedContentMeasuring() && (itemLength == 1 || whitespaceContentIsTreatedAsSingleSpace);
-                auto width = simpleSingleWhitespaceContent ? std::make_optional(InlineLayoutUnit { fontCascade.spaceWidth() }) : textWidth(startPosition, itemLength);
+                auto width = [&]() -> std::optional<InlineLayoutUnit> {
+                    if (!canCacheMeasuredWidthOnInlineTextItem(inlineTextBox, startPosition, itemLength, true))
+                        return { };
+                    if (whitespaceContentIsTreatedAsSingleSpace || (itemLength == 1 && inlineTextBox.canUseSimplifiedContentMeasuring()))
+                        return whiteSpaceWidth;
+                    return TextUtil::width(inlineTextBox, fontCascade, startPosition, startPosition + itemLength, { });
+                }();
                 inlineItems.append(InlineTextItem::createWhitespaceItem(inlineTextBox, startPosition, itemLength, UBIDI_DEFAULT_LTR, whitespaceContent->isWordSeparator, width));
             };
             if (style.whiteSpace() == WhiteSpace::BreakSpaces) {
@@ -437,10 +446,15 @@
                 hasTrailingSoftHyphen = text[endPosition - 1] == softHyphen;
             }
             ASSERT_IMPLIES(style.hyphens() == Hyphens::None, !hasTrailingSoftHyphen);
-            auto inlineItemLength = endPosition - startPosition;
-            inlineItems.append(InlineTextItem::createNonWhitespaceItem(inlineTextBox, startPosition, inlineItemLength, UBIDI_DEFAULT_LTR, hasTrailingSoftHyphen, textWidth(startPosition, inlineItemLength)));
+            auto length = endPosition - startPosition;
+            auto textWidth = [&]() -> std::optional<InlineLayoutUnit> {
+                // Delay non-whitespace content measuring until after bidi split.
+                if (hasSeenBidiContent() || !canCacheMeasuredWidthOnInlineTextItem(inlineTextBox, startPosition, length, false))
+                    return { };
+                return TextUtil::width(inlineTextBox, fontCascade, startPosition, endPosition, { });
+            }();
+            inlineItems.append(InlineTextItem::createNonWhitespaceItem(inlineTextBox, startPosition, length, UBIDI_DEFAULT_LTR, hasTrailingSoftHyphen, textWidth));
             currentPosition = endPosition;
-
             return true;
         };
         if (handleNonWhitespace())
_______________________________________________
webkit-changes mailing list
webkit-changes@lists.webkit.org
https://lists.webkit.org/mailman/listinfo/webkit-changes

Reply via email to