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

Changeset 267494 in webkit


Ignore:
Timestamp:
Sep 23, 2020, 12:34:44 PM (6 years ago)
Author:
Alan Bujtas
Message:

[LFC][IFC] Precompute the collapsible trailing width for LineBreaker
https://bugs.webkit.org/show_bug.cgi?id=216881

Reviewed by Antti Koivisto.

Let's just compute the collapsible trailing width while adding inline content to LineCandidate instead of
reverse looping through the runs in LineBreaker.
This is also in preparation for reducing the number of RuntimeEnabledFeatures::layoutFormattingContextIntegrationEnabled calls.

  • layout/inlineformatting/InlineLineBreaker.cpp:

(WebCore::Layout::ContinuousContent::hasTrailingCollapsibleContent const):
(WebCore::Layout::ContinuousContent::isFullyCollapsible const):
(WebCore::Layout::LineBreaker::shouldKeepEndOfLineWhitespace const):
(WebCore::Layout::LineBreaker::shouldWrapInlineContent):
(WebCore::Layout::LineBreaker::tryWrappingInlineContent const):
(WebCore::Layout::ContinuousContent::ContinuousContent):
(WebCore::Layout::ContinuousContent::nonCollapsibleLogicalWidth const):
(WebCore::Layout::ContinuousContent::isTrailingContentFullyCollapsible const): Deleted.
(WebCore::Layout::ContinuousContent::TrailingCollapsibleContent::reset): Deleted.

  • layout/inlineformatting/InlineLineBreaker.h:
  • layout/inlineformatting/InlineLineBuilder.cpp:

(WebCore::Layout::LineCandidate::InlineContent::collapsibleTrailingWidth const):
(WebCore::Layout::LineCandidate::InlineContent::appendInlineItem):
(WebCore::Layout::LineCandidate::InlineContent::reset):
(WebCore::Layout::LineBuilder::handleFloatsAndInlineContent):

Location:
trunk/Source/WebCore
Files:
4 edited

Legend:

Unmodified
Added
Removed
  • trunk/Source/WebCore/ChangeLog

    r267491 r267494  
     12020-09-23  Zalan Bujtas  <zalan@apple.com>
     2
     3        [LFC][IFC] Precompute the collapsible trailing width for LineBreaker
     4        https://bugs.webkit.org/show_bug.cgi?id=216881
     5
     6        Reviewed by Antti Koivisto.
     7
     8        Let's just compute the collapsible trailing width while adding inline content to LineCandidate instead of
     9        reverse looping through the runs in LineBreaker.
     10        This is also in preparation for reducing the number of RuntimeEnabledFeatures::layoutFormattingContextIntegrationEnabled calls.
     11
     12        * layout/inlineformatting/InlineLineBreaker.cpp:
     13        (WebCore::Layout::ContinuousContent::hasTrailingCollapsibleContent const):
     14        (WebCore::Layout::ContinuousContent::isFullyCollapsible const):
     15        (WebCore::Layout::LineBreaker::shouldKeepEndOfLineWhitespace const):
     16        (WebCore::Layout::LineBreaker::shouldWrapInlineContent):
     17        (WebCore::Layout::LineBreaker::tryWrappingInlineContent const):
     18        (WebCore::Layout::ContinuousContent::ContinuousContent):
     19        (WebCore::Layout::ContinuousContent::nonCollapsibleLogicalWidth const):
     20        (WebCore::Layout::ContinuousContent::isTrailingContentFullyCollapsible const): Deleted.
     21        (WebCore::Layout::ContinuousContent::TrailingCollapsibleContent::reset): Deleted.
     22        * layout/inlineformatting/InlineLineBreaker.h:
     23        * layout/inlineformatting/InlineLineBuilder.cpp:
     24        (WebCore::Layout::LineCandidate::InlineContent::collapsibleTrailingWidth const):
     25        (WebCore::Layout::LineCandidate::InlineContent::appendInlineItem):
     26        (WebCore::Layout::LineCandidate::InlineContent::reset):
     27        (WebCore::Layout::LineBuilder::handleFloatsAndInlineContent):
     28
    1292020-09-23  Peng Liu  <peng.liu6@apple.com>
    230
  • trunk/Source/WebCore/layout/inlineformatting/InlineLineBreaker.cpp

    r267404 r267494  
    3333#include "InlineItem.h"
    3434#include "InlineTextItem.h"
    35 #include "RuntimeEnabledFeatures.h"
    3635#include "TextUtil.h"
    3736
     
    7372    InlineLayoutUnit logicalWidth() const { return m_candidateContent.logicalWidth; }
    7473    InlineLayoutUnit logicalLeft() const { return m_candidateContent.logicalLeft; }
    75     InlineLayoutUnit nonCollapsibleLogicalWidth() const { return logicalWidth() - m_trailingCollapsibleContent.width; }
    76 
    77     bool hasTrailingCollapsibleContent() const { return !!m_trailingCollapsibleContent.width; }
    78     bool isTrailingContentFullyCollapsible() const { return m_trailingCollapsibleContent.isFullyCollapsible; }
     74    InlineLayoutUnit nonCollapsibleLogicalWidth() const;
     75
     76    bool hasTrailingCollapsibleContent() const { return !!m_candidateContent.collapsibleTrailingWidth; }
     77    bool isFullyCollapsible() const { return !nonCollapsibleLogicalWidth(); }
    7978
    8079    Optional<size_t> firstTextRunIndex() const;
     
    8382private:
    8483    const LineBreaker::CandidateContent& m_candidateContent;
    85     struct TrailingCollapsibleContent {
    86         void reset();
    87 
    88         bool isFullyCollapsible { false };
    89         InlineLayoutUnit width { 0 };
    90     };
    91     TrailingCollapsibleContent m_trailingCollapsibleContent;
    9284};
    9385
     
    108100bool LineBreaker::shouldKeepEndOfLineWhitespace(const ContinuousContent& continuousContent) const
    109101{
    110     // Grab the style and check for white-space property to decided whether we should let this whitespace content overflow the current line.
    111     // Note that the "keep" in the context means we let the whitespace content sit on the current line.
     102    // Grab the style and check for white-space property to decide whether we should let this whitespace content overflow the current line.
     103    // Note that the "keep" in this context means we let the whitespace content sit on the current line.
    112104    // It might very well get collapsed when we close the line (normal/nowrap/pre-line).
    113105    // See https://www.w3.org/TR/css-text-3/#white-space-property
     
    122114            return Result { Result::Action::Keep };
    123115#if USE_FLOAT_AS_INLINE_LAYOUT_UNIT
    124         // Preferred width computation sums up floats while line breaker substracts them. This can lead to epsilon-scale differences.
     116        // Preferred width computation sums up floats while line breaker subtracts them. This can lead to epsilon-scale differences.
    125117        if (WTF::areEssentiallyEqual(candidateContent.logicalWidth, lineStatus.availableWidth))
    126118            return Result { Result::Action::Keep };
     
    163155            return { Result::Action::Keep, IsEndOfLine };
    164156        // Now check if we can trim the line too.
    165         if (lineStatus.lineHasFullyCollapsibleTrailingRun && continuousContent.isTrailingContentFullyCollapsible()) {
     157        if (lineStatus.lineHasFullyCollapsibleTrailingRun && continuousContent.isFullyCollapsible()) {
    166158            // If this new content is fully collapsible, it should surely fit.
    167159            return { Result::Action::Keep, IsEndOfLine };
     
    356348    : m_candidateContent(candidateContent)
    357349{
    358     // Figure out the trailing collapsible state.
    359     for (auto& run : WTF::makeReversedRange(runs())) {
    360         auto& inlineItem = run.inlineItem;
    361         if (inlineItem.isBox()) {
    362             // We did reach a non-collapsible content. We have all the trailing whitespace now.
    363             break;
    364         }
    365         if (inlineItem.isText()) {
    366             auto& inlineTextItem = downcast<InlineTextItem>(inlineItem);
    367             auto isFullyCollapsible = [&] {
    368                 return inlineTextItem.isWhitespace() && !TextUtil::shouldPreserveTrailingWhitespace(inlineTextItem.style());
    369             };
    370             if (isFullyCollapsible()) {
    371                 m_trailingCollapsibleContent.width += run.logicalWidth;
    372                 m_trailingCollapsibleContent.isFullyCollapsible = true;
    373                 // Let's see if we've got more trailing whitespace content.
    374                 continue;
    375             }
    376             if (!RuntimeEnabledFeatures::sharedFeatures().layoutFormattingContextIntegrationEnabled()) {
    377                 // A run with trailing letter spacing is partially collapsible.
    378                 if (auto collapsibleWidth = inlineTextItem.style().letterSpacing()) {
    379                     m_trailingCollapsibleContent.width += collapsibleWidth;
    380                     m_trailingCollapsibleContent.isFullyCollapsible = false;
    381                 }
    382             }
    383             // End of whitespace content.
    384             break;
    385         }
    386     }
     350}
     351
     352InlineLayoutUnit ContinuousContent::nonCollapsibleLogicalWidth() const
     353{
     354    ASSERT(logicalWidth() >= m_candidateContent.collapsibleTrailingWidth);
     355    return logicalWidth() - m_candidateContent.collapsibleTrailingWidth;
    387356}
    388357
     
    447416}
    448417
    449 void ContinuousContent::TrailingCollapsibleContent::reset()
    450 {
    451     isFullyCollapsible = false;
    452     width = 0_lu;
    453 }
    454 
    455418}
    456419}
  • trunk/Source/WebCore/layout/inlineformatting/InlineLineBreaker.h

    r267404 r267494  
    7777    using RunList = Vector<Run, 3>;
    7878
     79    // This struct represents the amount of content committed to line breaking at a time e.g.
     80    // <div>text content <span>span1</span>between<span>span2</span></div>
     81    // [text][ ][content][ ][container start][span1][container end][between][container start][span2][container end]
     82    // candidate content at a time:
     83    // 1. [text]
     84    // 2. [ ]
     85    // 3. [content]
     86    // 4. [ ]
     87    // 5. [container start][span1][container end][between][container start][span2][container end]
     88    // see https://drafts.csswg.org/css-text-3/#line-break-details
    7989    struct CandidateContent {
    8090        const RunList& runs;
    8191        InlineLayoutUnit logicalLeft { 0 };
    8292        InlineLayoutUnit logicalWidth { 0 };
     93        InlineLayoutUnit collapsibleTrailingWidth { 0 };
    8394    };
    8495    struct LineStatus {
     
    93104
    94105private:
    95     // This struct represents the amount of content committed to line breaking at a time e.g.
    96     // text content <span>span1</span>between<span>span2</span>
    97     // [text][ ][content][ ][container start][span1][container end][between][container start][span2][container end]
    98     // -> content chunks ->
    99     // [text]
    100     // [ ]
    101     // [content]
    102     // [container start][span1][container end][between][container start][span2][container end]
    103     // see https://drafts.csswg.org/css-text-3/#line-break-details
    104106    Optional<WrappedTextContent> wrapTextContent(const ContinuousContent&, const LineStatus&) const;
    105107    Result tryWrappingInlineContent(const CandidateContent&, const LineStatus&) const;
  • trunk/Source/WebCore/layout/inlineformatting/InlineLineBuilder.cpp

    r267461 r267494  
    183183        const LineBreaker::RunList& runs() const { return m_inlineRuns; }
    184184        InlineLayoutUnit logicalWidth() const { return m_LogicalWidth; }
     185        InlineLayoutUnit collapsibleTrailingWidth() const { return m_collapsibleTrailingWidth; }
    185186        const InlineItem* trailingLineBreak() const { return m_trailingLineBreak; }
    186187
     
    193194
    194195        InlineLayoutUnit m_LogicalWidth { 0 };
     196        InlineLayoutUnit m_collapsibleTrailingWidth { 0 };
    195197        LineBreaker::RunList m_inlineRuns;
    196198        const InlineItem* m_trailingLineBreak { nullptr };
     
    224226    m_LogicalWidth += logicalWidth;
    225227    m_inlineRuns.append({ inlineItem, logicalWidth });
     228
     229    auto isFullyCollapsible = [&] {
     230        if (inlineItem.isBox())
     231            return false;
     232        if (inlineItem.isText()) {
     233            auto& inlineTextItem = downcast<InlineTextItem>(inlineItem);
     234            return inlineTextItem.isWhitespace() && !TextUtil::shouldPreserveTrailingWhitespace(inlineTextItem.style());
     235        }
     236        return true;
     237    };
     238    if (isFullyCollapsible()) {
     239        m_collapsibleTrailingWidth += logicalWidth;
     240        return;
     241    }
     242
     243    auto partiallyCollapsibleTrailingWidth = [&]() -> InlineLayoutUnit {
     244        if (RuntimeEnabledFeatures::sharedFeatures().layoutFormattingContextIntegrationEnabled())
     245            return { };
     246        if (!inlineItem.isText())
     247            return { };
     248        if (auto letterSpacing = inlineItem.style().letterSpacing(); letterSpacing > 0)
     249            return letterSpacing;
     250        return { };
     251    };
     252    if (auto collapsibleTrailingWidth = partiallyCollapsibleTrailingWidth()) {
     253        m_collapsibleTrailingWidth = collapsibleTrailingWidth;
     254        return;
     255    }
     256    m_collapsibleTrailingWidth = { };
    226257}
    227258
     
    229260{
    230261    m_LogicalWidth = { };
     262    m_collapsibleTrailingWidth = { };
    231263    m_inlineRuns.clear();
    232264    m_trailingLineBreak = { };
     
    554586    auto isLineConsideredEmpty = m_line.isVisuallyEmpty() && !m_contentIsConstrainedByFloat;
    555587    auto lineStatus = LineBreaker::LineStatus { availableWidth, m_line.trimmableTrailingWidth(), m_line.isTrailingRunFullyTrimmable(), isLineConsideredEmpty };
    556     auto candidateInlineContentLogicalLeft = m_line.contentLogicalWidth();
    557     auto result = lineBreaker.shouldWrapInlineContent({ candidateRuns, candidateInlineContentLogicalLeft, candidateInlineContent.logicalWidth() }, lineStatus);
     588    auto contentLogicalLeft = m_line.contentLogicalWidth();
     589    auto result = lineBreaker.shouldWrapInlineContent({ candidateRuns, contentLogicalLeft, candidateInlineContent.logicalWidth(), candidateInlineContent.collapsibleTrailingWidth() }, lineStatus);
    558590    if (result.lastWrapOpportunityItem)
    559591        m_lastWrapOpportunityItem = result.lastWrapOpportunityItem;
Note: See TracChangeset for help on using the changeset viewer.