⚠ Archived content — this site is no longer maintained.   Current WebKit documentation is at docs.webkit.org.

Changeset 286101 in webkit


Ignore:
Timestamp:
Nov 21, 2021, 10:33:06 AM (5 years ago)
Author:
Alan Bujtas
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):

Location:
trunk/Source/WebCore
Files:
2 edited

Legend:

Unmodified
Added
Removed
  • trunk/Source/WebCore/ChangeLog

    r286100 r286101  
     12021-11-21  Alan Bujtas  <zalan@apple.com>
     2
     3        [LFC][IFC] Cache measured width even if canUseSimplifiedTextMeasuring is false
     4        https://bugs.webkit.org/show_bug.cgi?id=233404
     5
     6        Reviewed by Antti Koivisto.
     7
     8        Just because some content goes through the non-simplified text measuring codepath, it does not
     9        necessary mean we can't cache the measured value on the inline item (actually, we can cache these values just fine in most cases).
     10
     11        This is in preparation for being able to cache bidi content measured widths.
     12
     13        * layout/formattingContexts/inline/InlineItemsBuilder.cpp:
     14        (WebCore::Layout::canCacheMeasuredWidthOnInlineTextItem):
     15        (WebCore::Layout::InlineItemsBuilder::handleTextContent):
     16
    1172021-11-21  Ziran Sun  <zsun@igalia.com>
    218
  • trunk/Source/WebCore/layout/formattingContexts/inline/InlineItemsBuilder.cpp

    r286099 r286101  
    350350}
    351351
    352 static inline bool canCacheMeasuredWidthOnInlineTextItem(const InlineTextBox& inlineTextBox)
    353 {
    354     // FIXME: Disable width caching for position dependent content only.
    355     if (!inlineTextBox.canUseSimplifiedContentMeasuring())
     352static inline bool canCacheMeasuredWidthOnInlineTextItem(const InlineTextBox& inlineTextBox, size_t start, size_t length, bool isWhitespace)
     353{
     354    // Do not cache when:
     355    // 1. first-line style's unique font properties may produce non-matching width values.
     356    // 2. position dependent content is present (preserved tab character atm).
     357    if (inlineTextBox.style().fontCascade() != inlineTextBox.firstLineStyle().fontCascade())
    356358        return false;
    357     return inlineTextBox.style().fontCascade() == inlineTextBox.firstLineStyle().fontCascade();
     359    if (!isWhitespace || !TextUtil::shouldPreserveSpacesAndTabs(inlineTextBox))
     360        return true;
     361    // FIXME: Currently we opt out of caching only when we see a preserved \t character (position dependent measured width).
     362    auto textContent = inlineTextBox.content();
     363    for (auto index = start; index < start + length; ++index) {
     364        if (textContent[index] == tabCharacter)
     365            return false;
     366    }
     367    return true;
    358368}
    359369
     
    370380    auto& style = inlineTextBox.style();
    371381    auto& fontCascade = style.fontCascade();
     382    auto whiteSpaceWidth = std::optional<InlineLayoutUnit> { fontCascade.spaceWidth() };
    372383    auto shouldPreserveSpacesAndTabs = TextUtil::shouldPreserveSpacesAndTabs(inlineTextBox);
    373384    auto whitespaceContentIsTreatedAsSingleSpace = !shouldPreserveSpacesAndTabs;
     
    376387    auto lineBreakIterator = LazyLineBreakIterator { text, style.computedLocale(), TextUtil::lineBreakIteratorMode(style.lineBreak()) };
    377388    unsigned currentPosition = 0;
    378 
    379     auto textWidth = [&](auto startPosition, auto length) -> std::optional<InlineLayoutUnit> {
    380         // Delay content measuring until after bidi split.
    381         if (hasSeenBidiContent() || !canCacheMeasuredWidthOnInlineTextItem(inlineTextBox))
    382             return { };
    383         return TextUtil::width(inlineTextBox, fontCascade, startPosition, startPosition + length, { });
    384     };
    385389
    386390    while (currentPosition < contentLength) {
     
    404408            ASSERT(whitespaceContent->length);
    405409            auto appendWhitespaceItem = [&] (auto startPosition, auto itemLength) {
    406                 auto simpleSingleWhitespaceContent = inlineTextBox.canUseSimplifiedContentMeasuring() && (itemLength == 1 || whitespaceContentIsTreatedAsSingleSpace);
    407                 auto width = simpleSingleWhitespaceContent ? std::make_optional(InlineLayoutUnit { fontCascade.spaceWidth() }) : textWidth(startPosition, itemLength);
     410                auto width = [&]() -> std::optional<InlineLayoutUnit> {
     411                    if (!canCacheMeasuredWidthOnInlineTextItem(inlineTextBox, startPosition, itemLength, true))
     412                        return { };
     413                    if (whitespaceContentIsTreatedAsSingleSpace || (itemLength == 1 && inlineTextBox.canUseSimplifiedContentMeasuring()))
     414                        return whiteSpaceWidth;
     415                    return TextUtil::width(inlineTextBox, fontCascade, startPosition, startPosition + itemLength, { });
     416                }();
    408417                inlineItems.append(InlineTextItem::createWhitespaceItem(inlineTextBox, startPosition, itemLength, UBIDI_DEFAULT_LTR, whitespaceContent->isWordSeparator, width));
    409418            };
     
    438447            }
    439448            ASSERT_IMPLIES(style.hyphens() == Hyphens::None, !hasTrailingSoftHyphen);
    440             auto inlineItemLength = endPosition - startPosition;
    441             inlineItems.append(InlineTextItem::createNonWhitespaceItem(inlineTextBox, startPosition, inlineItemLength, UBIDI_DEFAULT_LTR, hasTrailingSoftHyphen, textWidth(startPosition, inlineItemLength)));
     449            auto length = endPosition - startPosition;
     450            auto textWidth = [&]() -> std::optional<InlineLayoutUnit> {
     451                // Delay non-whitespace content measuring until after bidi split.
     452                if (hasSeenBidiContent() || !canCacheMeasuredWidthOnInlineTextItem(inlineTextBox, startPosition, length, false))
     453                    return { };
     454                return TextUtil::width(inlineTextBox, fontCascade, startPosition, endPosition, { });
     455            }();
     456            inlineItems.append(InlineTextItem::createNonWhitespaceItem(inlineTextBox, startPosition, length, UBIDI_DEFAULT_LTR, hasTrailingSoftHyphen, textWidth));
    442457            currentPosition = endPosition;
    443 
    444458            return true;
    445459        };
Note: See TracChangeset for help on using the changeset viewer.