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

Changeset 284678 in webkit


Ignore:
Timestamp:
Oct 22, 2021, 6:44:00 AM (5 years ago)
Author:
Alan Bujtas
Message:

[LFC][IFC] Add support for checking leading collapsible whitespace in InlineContentBreaker::processOverflowingContent
https://bugs.webkit.org/show_bug.cgi?id=232091

Reviewed by Antti Koivisto.

This patch ensures that the leading collapsible whitespace on the continuous run is taken
into account when checking if the otherwise overflowing content may fit the line.
e.g.
<span style="white-space: nowrap">no_wrap </span><span> yes_wrap</span>
The " yes_wrap" content has a collapsible leading whitespace here.
(This is also a preparation for fixing a regression and a WPT test.)

  • layout/formattingContexts/inline/InlineContentBreaker.cpp:

(WebCore::Layout::isVisuallyEmptyWhitespaceContent):
(WebCore::Layout::InlineContentBreaker::processOverflowingContent const):
(WebCore::Layout::InlineContentBreaker::ContinuousContent::append):
(WebCore::Layout::InlineContentBreaker::ContinuousContent::reset):

  • layout/formattingContexts/inline/InlineContentBreaker.h:

(WebCore::Layout::InlineContentBreaker::ContinuousContent::leadingCollapsibleWidth const):
(WebCore::Layout::InlineContentBreaker::ContinuousContent::trailingCollapsibleWidth const):
(WebCore::Layout::InlineContentBreaker::ContinuousContent::hasCollapsibleContent const):
(WebCore::Layout::InlineContentBreaker::ContinuousContent::isFullyCollapsible const):
(WebCore::Layout::InlineContentBreaker::ContinuousContent::collapsibleLogicalWidth const): Deleted.
(WebCore::Layout::InlineContentBreaker::ContinuousContent::nonCollapsibleLogicalWidth const): Deleted.
(WebCore::Layout::InlineContentBreaker::ContinuousContent::hasTrailingCollapsibleContent const): Deleted.

Location:
trunk/Source/WebCore
Files:
3 edited

Legend:

Unmodified
Added
Removed
  • trunk/Source/WebCore/ChangeLog

    r284677 r284678  
     12021-10-22  Alan Bujtas  <zalan@apple.com>
     2
     3        [LFC][IFC] Add support for checking leading collapsible whitespace in InlineContentBreaker::processOverflowingContent
     4        https://bugs.webkit.org/show_bug.cgi?id=232091
     5
     6        Reviewed by Antti Koivisto.
     7
     8        This patch ensures that the leading collapsible whitespace on the continuous run is taken
     9        into account when checking if the otherwise overflowing content may fit the line.
     10        e.g.
     11        <span style="white-space: nowrap">no_wrap </span><span> yes_wrap</span>
     12        The " yes_wrap" content has a collapsible leading whitespace here.
     13        (This is also a preparation for fixing a regression and a WPT test.)
     14
     15        * layout/formattingContexts/inline/InlineContentBreaker.cpp:
     16        (WebCore::Layout::isVisuallyEmptyWhitespaceContent):
     17        (WebCore::Layout::InlineContentBreaker::processOverflowingContent const):
     18        (WebCore::Layout::InlineContentBreaker::ContinuousContent::append):
     19        (WebCore::Layout::InlineContentBreaker::ContinuousContent::reset):
     20        * layout/formattingContexts/inline/InlineContentBreaker.h:
     21        (WebCore::Layout::InlineContentBreaker::ContinuousContent::leadingCollapsibleWidth const):
     22        (WebCore::Layout::InlineContentBreaker::ContinuousContent::trailingCollapsibleWidth const):
     23        (WebCore::Layout::InlineContentBreaker::ContinuousContent::hasCollapsibleContent const):
     24        (WebCore::Layout::InlineContentBreaker::ContinuousContent::isFullyCollapsible const):
     25        (WebCore::Layout::InlineContentBreaker::ContinuousContent::collapsibleLogicalWidth const): Deleted.
     26        (WebCore::Layout::InlineContentBreaker::ContinuousContent::nonCollapsibleLogicalWidth const): Deleted.
     27        (WebCore::Layout::InlineContentBreaker::ContinuousContent::hasTrailingCollapsibleContent const): Deleted.
     28
    1292021-10-22  Alan Bujtas  <zalan@apple.com>
    230
  • trunk/Source/WebCore/layout/formattingContexts/inline/InlineContentBreaker.cpp

    r284530 r284678  
    9898    // [<span></span> ] [<span> </span>] [ <span style="padding: 0px;"></span>] are all considered visually empty whitespace content.
    9999    // [<span style="border: 1px solid red"></span> ] while this is whitespace content only, it is not considered visually empty.
    100     // Due to commit boundary rules, we just need to check the first non-typeless inline item (can't have both [img] and [text])
     100    ASSERT(!continuousContent.runs().isEmpty());
     101    auto hasWhitespace = false;
    101102    for (auto& run : continuousContent.runs()) {
    102103        auto& inlineItem = run.inlineItem;
    103         // FIXME: check for padding border etc.
     104        // FIXME: check if visual decoration makes a difference here e.g. padding border.
    104105        if (inlineItem.isInlineBoxStart() || inlineItem.isInlineBoxEnd())
    105106            continue;
    106         return inlineItem.isText() && downcast<InlineTextItem>(inlineItem).isWhitespace();
    107     }
    108     return false;
     107        auto isWhitespace = inlineItem.isText() && downcast<InlineTextItem>(inlineItem).isWhitespace();
     108        if (!isWhitespace)
     109            return false;
     110        hasWhitespace = true;
     111    }
     112    return hasWhitespace;
    109113}
    110114
     
    174178
    175179    ASSERT(continuousContent.logicalWidth() > lineStatus.availableWidth);
    176     if (continuousContent.hasTrailingCollapsibleContent()) {
    177         ASSERT(hasTrailingTextContent(overflowContent));
    178         // First check if the content fits without the trailing collapsible part.
    179         if (continuousContent.nonCollapsibleLogicalWidth() <= lineStatus.availableWidth)
    180             return { Result::Action::Keep, IsEndOfLine::No };
    181         // Now check if we can trim the line too.
    182         if (lineStatus.hasFullyCollapsibleTrailingRun && continuousContent.isFullyCollapsible()) {
     180    if (continuousContent.hasCollapsibleContent()) {
     181        if (lineStatus.hasFullyCollapsibleTrailingContent && continuousContent.isFullyCollapsible()) {
    183182            // If this new content is fully collapsible, it should surely fit.
    184183            return { Result::Action::Keep, IsEndOfLine::No };
    185184        }
     185        // Check if the content fits if we collapsed it.
     186        auto spaceRequired = continuousContent.logicalWidth() - continuousContent.trailingCollapsibleWidth();
     187        if (lineStatus.hasFullyCollapsibleTrailingContent)
     188            spaceRequired -= continuousContent.leadingCollapsibleWidth();
     189        if (spaceRequired <= lineStatus.availableWidth)
     190            return { Result::Action::Keep, IsEndOfLine::No };
    186191    } else if (lineStatus.collapsibleWidth && isNonContentRunsOnly(continuousContent)) {
    187192        // Let's see if the non-content runs fit when the line has trailing collapsible content.
     
    650655{
    651656    ASSERT(inlineItem.isText() || inlineItem.isBox() || inlineItem.isInlineBoxStart() || inlineItem.isInlineBoxEnd());
     657    auto isLeadingCollapsible = collapsibleWidth && (m_runs.isEmpty() || isFullyCollapsible());
    652658    m_runs.append({ inlineItem, style, logicalWidth });
    653659    m_logicalWidth = clampTo<InlineLayoutUnit>(m_logicalWidth + logicalWidth);
     
    655661        if (inlineItem.isText() || inlineItem.isBox()) {
    656662            // Inline boxes do not prevent the trailing content from getting collapsed.
    657             m_collapsibleLogicalWidth = { };
     663            m_trailingCollapsibleWidth = { };
    658664        }
    659665        return;
    660666    }
    661667    ASSERT(*collapsibleWidth <= logicalWidth);
    662     if (*collapsibleWidth == logicalWidth) {
    663         // Fully collapsible run.
    664         m_collapsibleLogicalWidth += logicalWidth;
     668    if (isLeadingCollapsible) {
     669        ASSERT(!m_trailingCollapsibleWidth);
     670        m_leadingCollapsibleWidth += *collapsibleWidth;
    665671        return;
    666672    }
    667     // Partially collapsible run.
    668     m_collapsibleLogicalWidth = *collapsibleWidth;
     673    m_trailingCollapsibleWidth = *collapsibleWidth == logicalWidth ? m_trailingCollapsibleWidth + logicalWidth : *collapsibleWidth;
    669674}
    670675
     
    672677{
    673678    m_logicalWidth = { };
    674     m_collapsibleLogicalWidth = { };
     679    m_leadingCollapsibleWidth = { };
     680    m_trailingCollapsibleWidth = { };
    675681    m_runs.clear();
    676682}
  • trunk/Source/WebCore/layout/formattingContexts/inline/InlineContentBreaker.h

    r284188 r284678  
    7878    struct ContinuousContent {
    7979        InlineLayoutUnit logicalWidth() const { return m_logicalWidth; }
    80         InlineLayoutUnit collapsibleLogicalWidth() const { return m_collapsibleLogicalWidth; }
    81         InlineLayoutUnit nonCollapsibleLogicalWidth() const { return logicalWidth() - collapsibleLogicalWidth(); }
    82         bool hasTrailingCollapsibleContent() const { return !!collapsibleLogicalWidth(); }
    83         bool isFullyCollapsible() const { return logicalWidth() == collapsibleLogicalWidth(); }
     80        InlineLayoutUnit leadingCollapsibleWidth() const { return m_leadingCollapsibleWidth; }
     81        InlineLayoutUnit trailingCollapsibleWidth() const { return m_trailingCollapsibleWidth; }
     82        bool hasCollapsibleContent() const { return trailingCollapsibleWidth() > 0 || leadingCollapsibleWidth() > 0; }
     83        bool isFullyCollapsible() const { return logicalWidth() == trailingCollapsibleWidth() + leadingCollapsibleWidth(); }
    8484
    85         void append(const InlineItem&, const RenderStyle&, InlineLayoutUnit logicalWidth, std::optional<InlineLayoutUnit> collapsibleWidth);
     85        void append(const InlineItem&, const RenderStyle&, InlineLayoutUnit logicalWidth, std::optional<InlineLayoutUnit> collapsibleWidth = std::nullopt);
    8686        void reset();
    8787
     
    101101        RunList m_runs;
    102102        InlineLayoutUnit m_logicalWidth { 0 };
    103         InlineLayoutUnit m_collapsibleLogicalWidth { 0 };
     103        InlineLayoutUnit m_leadingCollapsibleWidth { 0 };
     104        InlineLayoutUnit m_trailingCollapsibleWidth { 0 };
    104105    };
    105106
     
    109110        InlineLayoutUnit collapsibleWidth { 0 };
    110111        std::optional<InlineLayoutUnit> trailingSoftHyphenWidth;
    111         bool hasFullyCollapsibleTrailingRun { false };
     112        bool hasFullyCollapsibleTrailingContent { false };
    112113        bool hasContent { false };
    113114        bool hasWrapOpportunityAtPreviousPosition { false };
Note: See TracChangeset for help on using the changeset viewer.