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

Changeset 283392 in webkit


Ignore:
Timestamp:
Oct 1, 2021, 1:20:58 PM (5 years ago)
Author:
Alan Bujtas
Message:

REGRESSION(r283047): PerformanceTests/Layout/line-layout-simple.html regressed by ~10%
https://bugs.webkit.org/show_bug.cgi?id=231089

Reviewed by Antti Koivisto.

Let's just hold on to the applicable RenderStyle instead of constructing a dedicated Style structure.
Note that the expected style for line breaking is not necessarily the style of the inline item (e.g. in case of an atomic inline box, it's the parent inline box's style).

  • layout/formattingContexts/inline/InlineContentBreaker.cpp:

(WebCore::Layout::InlineContentBreaker::isWrappingAllowed):
(WebCore::Layout::InlineContentBreaker::shouldKeepEndOfLineWhitespace const):
(WebCore::Layout::InlineContentBreaker::processOverflowingContent const):
(WebCore::Layout::InlineContentBreaker::wordBreakBehavior const):
(WebCore::Layout::InlineContentBreaker::tryBreakingTextRun const):

  • layout/formattingContexts/inline/InlineContentBreaker.h:

(WebCore::Layout::InlineContentBreaker::ContinuousContent::Run::Run):
(WebCore::Layout::logicalWidth): Deleted.

Location:
trunk/Source/WebCore
Files:
3 edited

Legend:

Unmodified
Added
Removed
  • trunk/Source/WebCore/ChangeLog

    r283390 r283392  
     12021-10-01  Alan Bujtas  <zalan@apple.com>
     2
     3        REGRESSION(r283047): PerformanceTests/Layout/line-layout-simple.html regressed by ~10%
     4        https://bugs.webkit.org/show_bug.cgi?id=231089
     5
     6        Reviewed by Antti Koivisto.
     7
     8        Let's just hold on to the applicable RenderStyle instead of constructing a dedicated Style structure.
     9        Note that the expected style for line breaking is not necessarily the style of the inline item (e.g. in case of an atomic inline box, it's the parent inline box's style).
     10
     11        * layout/formattingContexts/inline/InlineContentBreaker.cpp:
     12        (WebCore::Layout::InlineContentBreaker::isWrappingAllowed):
     13        (WebCore::Layout::InlineContentBreaker::shouldKeepEndOfLineWhitespace const):
     14        (WebCore::Layout::InlineContentBreaker::processOverflowingContent const):
     15        (WebCore::Layout::InlineContentBreaker::wordBreakBehavior const):
     16        (WebCore::Layout::InlineContentBreaker::tryBreakingTextRun const):
     17        * layout/formattingContexts/inline/InlineContentBreaker.h:
     18        (WebCore::Layout::InlineContentBreaker::ContinuousContent::Run::Run):
     19        (WebCore::Layout::logicalWidth): Deleted.
     20
    1212021-10-01  Alan Bujtas  <zalan@apple.com>
    222
  • trunk/Source/WebCore/layout/formattingContexts/inline/InlineContentBreaker.cpp

    r283080 r283392  
    116116{
    117117    // Do not try to wrap overflown 'pre' and 'no-wrap' content to next line.
    118     return run.style.whiteSpace != WhiteSpace::Pre && run.style.whiteSpace != WhiteSpace::NoWrap;
     118    return run.style.whiteSpace() != WhiteSpace::Pre && run.style.whiteSpace() != WhiteSpace::NoWrap;
    119119}
    120120
     
    125125    // It might very well get collapsed when we close the line (normal/nowrap/pre-line).
    126126    // See https://www.w3.org/TR/css-text-3/#white-space-property
    127     auto whitespace = continuousContent.runs()[*firstTextRunIndex(continuousContent)].style.whiteSpace;
     127    auto whitespace = continuousContent.runs()[*firstTextRunIndex(continuousContent)].style.whiteSpace();
    128128    return whitespace == WhiteSpace::Normal || whitespace == WhiteSpace::NoWrap || whitespace == WhiteSpace::PreWrap || whitespace == WhiteSpace::PreLine;
    129129}
     
    234234                    return Result { Result::Action::Keep, IsEndOfLine::Yes };
    235235
    236                 auto firstCodePointWidth = TextUtil::width(inlineTextItem, leadingTextRun.style.fontCascade, inlineTextItem.start(), inlineTextItem.start() + firstCodePointLength, lineStatus.contentLogicalRight);
     236                auto firstCodePointWidth = TextUtil::width(inlineTextItem, leadingTextRun.style.fontCascade(), inlineTextItem.start(), inlineTextItem.start() + firstCodePointLength, lineStatus.contentLogicalRight);
    237237                return Result { Result::Action::Break, IsEndOfLine::Yes, Result::PartialTrailingContent { leadingTextRunIndex, PartialRun { firstCodePointLength, firstCodePointWidth } } };
    238238            }
     
    406406}
    407407
    408 OptionSet<InlineContentBreaker::WordBreakRule> InlineContentBreaker::wordBreakBehavior(const ContinuousContent::Run::Style& style, bool hasWrapOpportunityAtPreviousPosition) const
     408OptionSet<InlineContentBreaker::WordBreakRule> InlineContentBreaker::wordBreakBehavior(const RenderStyle& style, bool hasWrapOpportunityAtPreviousPosition) const
    409409{
    410410    // Disregard any prohibition against line breaks mandated by the word-break property.
    411411    // The different wrapping opportunities must not be prioritized.
    412412    // Note hyphenation is not applied.
    413     if (style.lineBreak == LineBreak::Anywhere)
     413    if (style.lineBreak() == LineBreak::Anywhere)
    414414        return { WordBreakRule::AtArbitraryPosition };
    415415
    416416    auto includeHyphenationIfAllowed = [&](std::optional<InlineContentBreaker::WordBreakRule> wordBreakRule) -> OptionSet<InlineContentBreaker::WordBreakRule> {
    417         auto hyphenationIsAllowed = !n_hyphenationIsDisabled && style.hyphens == Hyphens::Auto && canHyphenate(style.locale);
     417        auto hyphenationIsAllowed = !n_hyphenationIsDisabled && style.hyphens() == Hyphens::Auto && canHyphenate(style.computedLocale());
    418418        if (hyphenationIsAllowed) {
    419419            if (wordBreakRule)
     
    426426    };
    427427    // Breaking is allowed within “words”.
    428     if (style.wordBreak == WordBreak::BreakAll)
     428    if (style.wordBreak() == WordBreak::BreakAll)
    429429        return includeHyphenationIfAllowed(WordBreakRule::AtArbitraryPosition);
    430430    // For compatibility with legacy content, the word-break property also supports a deprecated break-word keyword.
    431431    // When specified, this has the same effect as word-break: normal and overflow-wrap: anywhere, regardless of the actual value of the overflow-wrap property.
    432     if (style.wordBreak == WordBreak::BreakWord && !hasWrapOpportunityAtPreviousPosition)
     432    if (style.wordBreak() == WordBreak::BreakWord && !hasWrapOpportunityAtPreviousPosition)
    433433        return includeHyphenationIfAllowed(WordBreakRule::AtArbitraryPosition);
    434434    // OverflowWrap::BreakWord/Anywhere An otherwise unbreakable sequence of characters may be broken at an arbitrary point if there are no otherwise-acceptable break points in the line.
    435435    // Note that this applies to content where CSS properties (e.g. WordBreak::KeepAll) make it unbreakable.
    436     if ((style.overflowWrap == OverflowWrap::BreakWord || style.overflowWrap == OverflowWrap::Anywhere) && !hasWrapOpportunityAtPreviousPosition)
     436    if ((style.overflowWrap() == OverflowWrap::BreakWord || style.overflowWrap() == OverflowWrap::Anywhere) && !hasWrapOpportunityAtPreviousPosition)
    437437        return includeHyphenationIfAllowed(WordBreakRule::AtArbitraryPosition);
    438438    // Breaking is forbidden within “words”.
    439     if (style.wordBreak == WordBreak::KeepAll)
     439    if (style.wordBreak() == WordBreak::KeepAll)
    440440        return { };
    441441    return includeHyphenationIfAllowed({ });
     
    453453        return { };
    454454
     455    auto& fontCascade = style.fontCascade();
    455456    if (breakRules.contains(WordBreakRule::AtHyphenationOpportunities)) {
    456457        auto tryBreakingAtHyphenationOpportunity = [&]() -> std::optional<PartialRun> {
     
    463464            }
    464465            auto runLength = inlineTextItem.length();
    465             auto limitBefore = style.hyphenationLimitBefore.value_or(0);
    466             auto limitAfter = style.hyphenationLimitAfter.value_or(0);
     466            unsigned limitBefore = style.hyphenationLimitBefore() == RenderStyle::initialHyphenationLimitBefore() ? 0 : style.hyphenationLimitBefore();
     467            unsigned limitAfter = style.hyphenationLimitAfter() == RenderStyle::initialHyphenationLimitAfter() ? 0 : style.hyphenationLimitAfter();
    467468            // Check if this run can accommodate the before/after limits at all before start measuring text.
    468469            if (limitBefore >= runLength || limitAfter >= runLength || limitBefore + limitAfter > runLength)
     
    470471
    471472            unsigned leftSideLength = runLength;
    472             auto hyphenWidth = InlineLayoutUnit { style.fontCascade.width(TextRun { StringView { style.hyphenString } }) };
     473            auto hyphenWidth = InlineLayoutUnit { fontCascade.width(TextRun { StringView { style.hyphenString() } }) };
    473474            if (!availableSpaceIsInfinite) {
    474475                auto availableWidthExcludingHyphen = *availableWidth - hyphenWidth;
    475                 if (availableWidthExcludingHyphen <= 0 || !enoughWidthForHyphenation(availableWidthExcludingHyphen, style.fontCascade.pixelSize()))
     476                if (availableWidthExcludingHyphen <= 0 || !enoughWidthForHyphenation(availableWidthExcludingHyphen, fontCascade.pixelSize()))
    476477                    return { };
    477                 leftSideLength = TextUtil::midWordBreak(inlineTextItem, overflowingRun.style.fontCascade, overflowingRun.logicalWidth, availableWidthExcludingHyphen, logicalLeft).length;
     478                leftSideLength = TextUtil::midWordBreak(inlineTextItem, fontCascade, overflowingRun.logicalWidth, availableWidthExcludingHyphen, logicalLeft).length;
    478479            }
    479480            if (leftSideLength < limitBefore)
     
    481482            // Adjust before index to accommodate the limit-after value (it's the last potential hyphen location in this run).
    482483            auto hyphenBefore = std::min(leftSideLength, runLength - limitAfter) + 1;
    483             unsigned hyphenLocation = lastHyphenLocation(StringView(inlineTextItem.inlineTextBox().content()).substring(inlineTextItem.start(), inlineTextItem.length()), hyphenBefore, style.locale);
     484            unsigned hyphenLocation = lastHyphenLocation(StringView(inlineTextItem.inlineTextBox().content()).substring(inlineTextItem.start(), inlineTextItem.length()), hyphenBefore, style.computedLocale());
    484485            if (!hyphenLocation || hyphenLocation < limitBefore)
    485486                return { };
    486487            // hyphenLocation is relative to the start of this InlineItemText.
    487488            ASSERT(inlineTextItem.start() + hyphenLocation < inlineTextItem.end());
    488             auto trailingPartialRunWidthWithHyphen = TextUtil::width(inlineTextItem, overflowingRun.style.fontCascade, inlineTextItem.start(), inlineTextItem.start() + hyphenLocation, logicalLeft);
     489            auto trailingPartialRunWidthWithHyphen = TextUtil::width(inlineTextItem, fontCascade, inlineTextItem.start(), inlineTextItem.start() + hyphenLocation, logicalLeft);
    489490            return PartialRun { hyphenLocation, trailingPartialRunWidthWithHyphen, hyphenWidth };
    490491        };
     
    502503                // When the run can be split at arbitrary position let's just return the entire run when it is intended to fit on the line.
    503504                ASSERT(inlineTextItem.length());
    504                 auto trailingPartialRunWidth = TextUtil::width(inlineTextItem, overflowingRun.style.fontCascade, logicalLeft);
     505                auto trailingPartialRunWidth = TextUtil::width(inlineTextItem, fontCascade, logicalLeft);
    505506                return { inlineTextItem.length(), trailingPartialRunWidth };
    506507            }
     
    509510                return { };
    510511            }
    511             auto midWordBreak = TextUtil::midWordBreak(inlineTextItem, overflowingRun.style.fontCascade, overflowingRun.logicalWidth, *availableWidth, logicalLeft);
     512            auto midWordBreak = TextUtil::midWordBreak(inlineTextItem, fontCascade, overflowingRun.logicalWidth, *availableWidth, logicalLeft);
    512513            return { midWordBreak.length, midWordBreak.logicalWidth };
    513514        };
  • trunk/Source/WebCore/layout/formattingContexts/inline/InlineContentBreaker.h

    r283055 r283392  
    9292
    9393            const InlineItem& inlineItem;
    94             struct Style {
    95                 WhiteSpace whiteSpace { WhiteSpace::Normal };
    96                 LineBreak lineBreak { LineBreak::Auto };
    97                 WordBreak wordBreak { WordBreak::Normal };
    98                 OverflowWrap overflowWrap { OverflowWrap::Normal };
    99                 Hyphens hyphens { Hyphens::None };
    100                 std::optional<unsigned> hyphenationLimitBefore;
    101                 std::optional<unsigned> hyphenationLimitAfter;
    102                 const FontCascade& fontCascade;
    103                 const AtomString& hyphenString;
    104                 const AtomString& locale;
    105             };
    106             Style style;
     94            const RenderStyle& style;
    10795            InlineLayoutUnit logicalWidth { 0 };
    10896        };
     
    139127        AtHyphenationOpportunities = 1 << 1
    140128    };
    141     OptionSet<WordBreakRule> wordBreakBehavior(const ContinuousContent::Run::Style&, bool hasWrapOpportunityAtPreviousPosition) const;
     129    OptionSet<WordBreakRule> wordBreakBehavior(const RenderStyle&, bool hasWrapOpportunityAtPreviousPosition) const;
    142130    bool shouldKeepEndOfLineWhitespace(const ContinuousContent&) const;
    143131
     
    147135inline InlineContentBreaker::ContinuousContent::Run::Run(const InlineItem& inlineItem, const RenderStyle& style, InlineLayoutUnit logicalWidth)
    148136    : inlineItem(inlineItem)
    149     , style({ style.whiteSpace()
    150         , style.lineBreak()
    151         , style.wordBreak()
    152         , style.overflowWrap()
    153         , style.hyphens()
    154         , style.hyphenationLimitBefore() != style.initialHyphenationLimitBefore() ? std::make_optional(style.hyphenationLimitBefore()) : std::nullopt
    155         , style.hyphenationLimitAfter() != style.initialHyphenationLimitAfter() ? std::make_optional(style.hyphenationLimitAfter()) : std::nullopt
    156         , style.fontCascade()
    157         , (style.hyphens() == Hyphens::None ? nullAtom() : style.hyphenString())
    158         , style.fontDescription().computedLocale() })
     137    , style(style)
    159138    , logicalWidth(logicalWidth)
    160139{
Note: See TracChangeset for help on using the changeset viewer.