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

Changeset 272124 in webkit


Ignore:
Timestamp:
Jan 31, 2021, 9:16:58 AM (6 years ago)
Author:
Alan Bujtas
Message:

[LFC][IFC] TrailingTextContent should be able to tell if even the first run in the set does not fit
​https://bugs.webkit.org/show_bug.cgi?id=221185

Reviewed by Antti Koivisto.

There are 3 distinct cases here that we should be able to encode with the return value of processOverflowingTextContent.

  1. We did not find any breakable run in the set -> return value is nullopt
  2. We did find a breakable run but even the first run does not fit at all -> TrailingTextContent::runIndex is nullopt
  3. We did find a breakable run and we can fit the first run (either fully or partially) -> TrailingTextContent::runIndex is 0.

Make TrailingTextContent::runIndex optional so that we can tell the difference between #2 and #3.

  • layout/inlineformatting/InlineContentBreaker.cpp:

(WebCore::Layout::InlineContentBreaker::processOverflowingContent const):
(WebCore::Layout::InlineContentBreaker::processOverflowingTextContent const):

Location:
trunk/Source/WebCore
Files:
2 edited

Legend:

Unmodified
Added
Removed
  • trunk/Source/WebCore/ChangeLog

    r272123 r272124  
     12021-01-31  Zalan Bujtas  <zalan@apple.com>
     2
     3        [LFC][IFC] TrailingTextContent should be able to tell if even the first run in the set does not fit
     4        https://bugs.webkit.org/show_bug.cgi?id=221185
     5
     6        Reviewed by Antti Koivisto.
     7
     8        There are 3 distinct cases here that we should be able to encode with the return value of processOverflowingTextContent.
     9
     10        1. We did not find any breakable run in the set -> return value is nullopt
     11        2. We did find a breakable run but even the first run does not fit at all -> TrailingTextContent::runIndex is nullopt
     12        3. We did find a breakable run and we can fit the first run (either fully or partially) -> TrailingTextContent::runIndex is 0.
     13
     14        Make TrailingTextContent::runIndex optional so that we can tell the difference between #2 and #3.
     15
     16        * layout/inlineformatting/InlineContentBreaker.cpp:
     17        (WebCore::Layout::InlineContentBreaker::processOverflowingContent const):
     18        (WebCore::Layout::InlineContentBreaker::processOverflowingTextContent const):
     19
    1202021-01-30  Sam Weinig  <weinig@apple.com>
    221
  • trunk/Source/WebCore/layout/inlineformatting/InlineContentBreaker.cpp

    r271562 r272124  
    161161
    162162struct TrailingTextContent {
    163     size_t runIndex { 0 };
    164     bool hasOverflow { false }; // Trailing content still overflows the line.
     163    Optional<size_t> runIndex; // In some cases when the first run is breakable but it does not fit, there's not trailing run index.
     164    bool hasOverflow { false }; // Trailing content overflows the available space.
    165165    Optional<InlineContentBreaker::PartialRun> partialRun;
    166166};
    … …  
    196196    if (isTextContent(continuousContent)) {
    197197        if (auto trailingContent = processOverflowingTextContent(continuousContent, lineStatus)) {
    198             if (!trailingContent->runIndex && trailingContent->hasOverflow) {
    199                 // We tried to break the content but the available space can't even accommodate the first character.
    200                 // 1. Wrap the content over to the next line when we've got content on the line already.
    201                 // 2. Keep the first character on the empty line (or keep the whole run if it has only one character/completely empty).
     198            if (trailingContent->hasOverflow) {
     199                if (!trailingContent->runIndex.hasValue()) {
     200                    // We tried to break the content but the available space can't even accommodate the first character.
     201                    // 1. Wrap the content over to the next line when we've got content on the line already.
     202                    // 2. Keep the first character on the empty line (or keep the whole run if it has only one character/completely empty).
     203                    if (lineStatus.hasContent)
     204                        return { Result::Action::Wrap, IsEndOfLine::Yes };
     205                    auto leadingTextRunIndex = *firstTextRunIndex(continuousContent);
     206                    auto& inlineTextItem = downcast<InlineTextItem>(continuousContent.runs()[leadingTextRunIndex].inlineItem);
     207                    if (inlineTextItem.length() <= 1)
     208                        return Result { Result::Action::Keep, IsEndOfLine::Yes };
     209                    auto firstCharacterWidth = TextUtil::width(inlineTextItem, inlineTextItem.start(), inlineTextItem.start() + 1, lineStatus.contentLogicalRight);
     210                    auto firstCharacterRun = PartialRun { 1, firstCharacterWidth };
     211                    return { Result::Action::Break, IsEndOfLine::Yes, Result::PartialTrailingContent { leadingTextRunIndex, firstCharacterRun } };
     212                }
     213                // We managed to break a run with overflow. Should not keep this on the line unless it's the only content.
    202214                if (lineStatus.hasContent)
    203215                    return { Result::Action::Wrap, IsEndOfLine::Yes };
    204                 auto leadingTextRunIndex = *firstTextRunIndex(continuousContent);
    205                 auto& inlineTextItem = downcast<InlineTextItem>(continuousContent.runs()[leadingTextRunIndex].inlineItem);
    206                 if (inlineTextItem.length() <= 1)
    207                     return Result { Result::Action::Keep, IsEndOfLine::Yes };
    208                 auto firstCharacterWidth = TextUtil::width(inlineTextItem, inlineTextItem.start(), inlineTextItem.start() + 1, lineStatus.contentLogicalRight);
    209                 auto firstCharacterRun = PartialRun { 1, firstCharacterWidth };
    210                 return { Result::Action::Break, IsEndOfLine::Yes, Result::PartialTrailingContent { leadingTextRunIndex, firstCharacterRun } };
    211             }
    212             auto trailingPartialContent = Result::PartialTrailingContent { trailingContent->runIndex, trailingContent->partialRun };
    213             return { Result::Action::Break, IsEndOfLine::Yes, trailingPartialContent };
    214         }
     216            }
     217            auto trailingPartialContent = Result::PartialTrailingContent { *trailingContent->runIndex, trailingContent->partialRun };
     218            return { Result::Action::Break, IsEndOfLine::Yes, trailingPartialContent };        }
    215219    }
    216220    // If we are not allowed to break this overflowing content, we still need to decide whether keep it or wrap it to the next line.
    … …  
    282286                if (partialRun->length)
    283287                    return TrailingTextContent { index, false, partialRun };
    284                 if (index) {
    285                     // When the content is wrapped at the run boundary, the trailing run is the previous run.
    286                     auto trailingCandidateIndex = index - 1;
    287                     // Try not break content at inline box boundary
    288                     // e.g. <span>fits</span><span>overflows</span>
    289                     // when the text "overflows" completely overflows, let's not wrap the content at '<span>'.
    290                     auto isAtInlineBox = runs[trailingCandidateIndex].inlineItem.isInlineBoxStart();
    291                     if (isAtInlineBox) {
    292                         if (!trailingCandidateIndex) {
    293                             // This content starts at an inline box and clearly does not fit.
    294                             // Let's wrap this content over to the next line
    295                             // e.g <span>this_content_does_not_fit</span>
    296                             return TrailingTextContent { 0, true, { } };
    297                         }
    298                         --trailingCandidateIndex;
    299                     }
     288                // When the breaking position is at the beginning of the run, the trailing run is the previous one.
     289                if (!index) {
     290                    // Sometimes we can't accommodate even the very first character.
     291                    // Note that this is different from when there's no breakable run in this set.
     292                    return TrailingTextContent { { }, true, { } };
     293                }
     294                auto trailingCandidateIndex = index - 1;
     295                // Try not break content at inline box boundary
     296                // e.g. <span>fits</span><span>overflows</span>
     297                // when the text "overflows" completely overflows, let's break the content right before the '<span>'.
     298                auto isAtInlineBox = runs[trailingCandidateIndex].inlineItem.isInlineBoxStart();
     299                if (!isAtInlineBox)
    300300                    return TrailingTextContent { trailingCandidateIndex, false, { } };
    301                 }
    302                 // Sometimes we can't accommodate even the very first character.
    303                 return TrailingTextContent { 0, true, { } };
    304             }
    305             // If this run is not breakable, we need to check if any previous run is breakable.
     301                // Let's return the run right before the inline box start, or return nothing if we are at the beginning of the set.
     302                // e.g. <span>this_is_breakable</span> vs. some_breakable_content<span>and_more</span>
     303                if (trailingCandidateIndex)
     304                    return TrailingTextContent { trailingCandidateIndex - 1, false, { } };
     305                // This content starts with an inline box and clearly does not fit.
     306                return TrailingTextContent { { }, true, { } };
     307            }
     308            // If this run is not breakable, we need to check if any previous or next runs are breakable.
    306309            break;
    307310        }
Note: See TracChangeset for help on using the changeset viewer.