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

Changeset 245812 in webkit


Ignore:
Timestamp:
May 28, 2019, 8:36:04 AM (7 years ago)
Author:
Alan Bujtas
Message:

[LFC][IFC] Decouple line layout and processing inline runs.
​https://bugs.webkit.org/show_bug.cgi?id=198282
<rdar://problem/51167954>

Reviewed by Antti Koivisto.

This is in preparation for using "createInlineRunsForLine" logic when computing preferred width.

  • layout/inlineformatting/InlineFormattingContext.h:
  • layout/inlineformatting/InlineFormattingContextLineLayout.cpp:

(WebCore::Layout::UncommittedContent::size const):
(WebCore::Layout::InlineFormattingContext::LineLayout::createInlineRunsForLine const):
(WebCore::Layout::InlineFormattingContext::LineLayout::layout const):
(WebCore::Layout::InlineFormattingContext::LineLayout::processInlineRuns const):
(WebCore::Layout::InlineFormattingContext::LineLayout::closeLine const): Deleted.

  • layout/inlineformatting/InlineFormattingState.h:

(WebCore::Layout::InlineFormattingState::addInlineItem):

  • layout/inlineformatting/InlineTextItem.cpp:

(WebCore::Layout::InlineTextItem::createAndAppendTextItems):

Location:
trunk/Source/WebCore
Files:
5 edited

Legend:

Unmodified
Added
Removed
  • trunk/Source/WebCore/ChangeLog

    r245811 r245812  
     12019-05-28  Zalan Bujtas  <zalan@apple.com>
     2
     3        [LFC][IFC] Decouple line layout and processing inline runs.
     4        https://bugs.webkit.org/show_bug.cgi?id=198282
     5        <rdar://problem/51167954>
     6
     7        Reviewed by Antti Koivisto.
     8
     9        This is in preparation for using "createInlineRunsForLine" logic when computing preferred width.
     10
     11        * layout/inlineformatting/InlineFormattingContext.h:
     12        * layout/inlineformatting/InlineFormattingContextLineLayout.cpp:
     13        (WebCore::Layout::UncommittedContent::size const):
     14        (WebCore::Layout::InlineFormattingContext::LineLayout::createInlineRunsForLine const):
     15        (WebCore::Layout::InlineFormattingContext::LineLayout::layout const):
     16        (WebCore::Layout::InlineFormattingContext::LineLayout::processInlineRuns const):
     17        (WebCore::Layout::InlineFormattingContext::LineLayout::closeLine const): Deleted.
     18        * layout/inlineformatting/InlineFormattingState.h:
     19        (WebCore::Layout::InlineFormattingState::addInlineItem):
     20        * layout/inlineformatting/InlineTextItem.cpp:
     21        (WebCore::Layout::InlineTextItem::createAndAppendTextItems):
     22
    1232019-05-28  Zalan Bujtas  <zalan@apple.com>
    224
  • trunk/Source/WebCore/layout/inlineformatting/InlineFormattingContext.h

    r245811 r245812  
    6060        LayoutState& layoutState() const { return m_formattingContext.layoutState(); }
    6161        void initializeLine(Line&, LayoutUnit lineLogicalTop, LayoutUnit widthConstraint) const;
    62         void closeLine(Line&) const;
     62        unsigned createInlineRunsForLine(Line&, unsigned firstInlineItemIndex) const;
     63        void processInlineRuns(Line&) const;
    6364        void commitInlineItemToLine(Line&, const InlineItem&) const;
    6465        void handleFloat(Line&, const FloatingContext&, const InlineItem& floatBox) const;
  • trunk/Source/WebCore/layout/inlineformatting/InlineFormattingContextLineLayout.cpp

    r245811 r245812  
    337337    Vector<InlineItem*> inlineItems() { return m_inlineItems; }
    338338    bool isEmpty() const { return m_inlineItems.isEmpty(); }
     339    unsigned size() const { return m_inlineItems.size(); }
    339340    LayoutUnit width() const { return m_width; }
    340341
    … …  
    399400}
    400401
    401 void InlineFormattingContext::LineLayout::layout(LayoutUnit widthConstraint) const
     402unsigned InlineFormattingContext::LineLayout::createInlineRunsForLine(Line& line, unsigned startInlineItemIndex) const
    402403{
    403404    auto floatingContext = FloatingContext { m_floatingState };
    404     Line line(layoutState());
    405     initializeLine(line, layoutState().displayBoxForLayoutBox(m_formattingRoot).contentBoxTop(), widthConstraint);
     405    Optional<unsigned> lastCommittedIndex;
    406406
    407407    UncommittedContent uncommittedContent;
    408408    auto commitPendingContent = [&] {
     409        if (uncommittedContent.isEmpty())
     410            return;
     411
     412        lastCommittedIndex = lastCommittedIndex.valueOr(startInlineItemIndex) + uncommittedContent.size();
    409413        for (auto* uncommitted : uncommittedContent.inlineItems())
    410414            commitInlineItemToLine(line, *uncommitted);
    … …  
    412416    };
    413417
    414     auto closeCurrentAndInitializeNewLine = [&] {
    415         closeLine(line);
     418    LineBreaker lineBreaker(layoutState());
     419    // Iterate through the inline content and place the inline boxes on the current line.
     420    auto& inlineContent = m_formattingState.inlineItems();
     421    for (auto inlineItemIndex = startInlineItemIndex; inlineItemIndex < inlineContent.size(); ++inlineItemIndex) {
     422        auto& inlineItem = inlineContent[inlineItemIndex];
     423        if (inlineItem->isHardLineBreak()) {
     424            uncommittedContent.add(*inlineItem);
     425            commitPendingContent();
     426            return *lastCommittedIndex;
     427        }
     428        auto availableWidth = line.availableWidth() - uncommittedContent.width();
     429        auto currentLogicalRight = line.contentLogicalRight() + uncommittedContent.width();
     430        // FIXME: Ensure LineContext::trimmableWidth includes uncommitted content if needed.
     431        auto breakingContext = lineBreaker.breakingContext(*inlineItem, { availableWidth, currentLogicalRight, line.trailingTrimmableWidth(), !line.hasContent() });
     432        if (breakingContext.isAtBreakingOpportunity)
     433            commitPendingContent();
     434
     435        // Content does not fit the current line.
     436        if (breakingContext.breakingBehavior == LineBreaker::BreakingBehavior::Wrap)
     437            return *lastCommittedIndex;
     438
     439        // Partial content stays on the current line.
     440        if (breakingContext.breakingBehavior == LineBreaker::BreakingBehavior::Break) {
     441            ASSERT(inlineItem->isText());
     442
     443            ASSERT_NOT_IMPLEMENTED_YET();
     444            return *lastCommittedIndex;
     445        }
     446
     447        if (inlineItem->isFloat()) {
     448            handleFloat(line, floatingContext, *inlineItem);
     449            continue;
     450        }
     451
     452        uncommittedContent.add(*inlineItem);
     453        if (breakingContext.isAtBreakingOpportunity)
     454            commitPendingContent();
     455    }
     456    commitPendingContent();
     457    return *lastCommittedIndex;
     458}
     459
     460void InlineFormattingContext::LineLayout::layout(LayoutUnit widthConstraint) const
     461{
     462    ASSERT(!m_formattingState.inlineItems().isEmpty());
     463
     464    Line line(layoutState());
     465    initializeLine(line, layoutState().displayBoxForLayoutBox(m_formattingRoot).contentBoxTop(), widthConstraint);
     466
     467    unsigned startInlineItemIndex = 0;
     468    while (true) {
     469        auto nextInlineItemIndex = createInlineRunsForLine(line, startInlineItemIndex);
     470        processInlineRuns(line);
     471        if (nextInlineItemIndex == m_formattingState.inlineItems().size())
     472            break;
     473        startInlineItemIndex = nextInlineItemIndex;
    416474        initializeLine(line, line.logicalBottom(), widthConstraint);
    417     };
    418 
    419     LineBreaker lineBreaker(layoutState());
    420     auto& inlineContent = m_formattingState.inlineItems();
    421     for (auto& inlineItem : inlineContent) {
    422         // Iterate through the inline content and try to put the inline boxes on the current line.
    423         if (inlineItem->isHardLineBreak()) {
    424             commitPendingContent();
    425             commitInlineItemToLine(line, *inlineItem);
    426             closeCurrentAndInitializeNewLine();
    427         } else {
    428             auto availableWidth = line.availableWidth() - uncommittedContent.width();
    429             auto currentLogicalRight = line.contentLogicalRight() + uncommittedContent.width();
    430             // FIXME: Ensure LineContext::trimmableWidth includes uncommitted content if needed.
    431             auto breakingContext = lineBreaker.breakingContext(*inlineItem, { availableWidth, currentLogicalRight, line.trailingTrimmableWidth(), !line.hasContent() });
    432             if (breakingContext.isAtBreakingOpportunity)
    433                 commitPendingContent();
    434 
    435             if (breakingContext.breakingBehavior == LineBreaker::BreakingBehavior::Break) {
    436                 ASSERT_NOT_IMPLEMENTED_YET();
    437                 continue;
    438             }
    439 
    440             if (breakingContext.breakingBehavior == LineBreaker::BreakingBehavior::Wrap)
    441                 closeCurrentAndInitializeNewLine();
    442 
    443             if (inlineItem->isFloat())
    444                 handleFloat(line, floatingContext, *inlineItem);
    445             else {
    446                 if (breakingContext.isAtBreakingOpportunity)
    447                     commitInlineItemToLine(line, *inlineItem);
    448                 else
    449                     uncommittedContent.add(*inlineItem);
    450             }
    451         }
    452     }
    453     // Process remaining uncommitted content.
    454     if (!uncommittedContent.isEmpty()) {
    455         if (line.availableWidth() < uncommittedContent.width())
    456             closeCurrentAndInitializeNewLine();
    457         commitPendingContent();
    458     }
    459     closeLine(line);
     475    }
    460476}
    461477
    … …  
    488504}
    489505
    490 void InlineFormattingContext::LineLayout::closeLine(Line& line) const
     506void InlineFormattingContext::LineLayout::processInlineRuns(Line& line) const
    491507{
    492508    auto& lineItems = line.close();
  • trunk/Source/WebCore/layout/inlineformatting/InlineFormattingState.h

    r245776 r245812  
    3939
    4040// Temp
    41 using InlineItems = ListHashSet<std::unique_ptr<InlineItem>>;
     41using InlineItems = Vector<std::unique_ptr<InlineItem>>;
    4242using InlineRuns = Vector<std::unique_ptr<Display::Run>>;
    4343using LineBoxes = Vector<LineBox>;
    … …  
    5555    LineBoxes& lineBoxes() { return m_lineBoxes; }
    5656
    57     void addInlineItem(std::unique_ptr<InlineItem>&& inlineItem) { m_inlineItems.add(WTFMove(inlineItem)); }
     57    void addInlineItem(std::unique_ptr<InlineItem>&& inlineItem) { m_inlineItems.append(WTFMove(inlineItem)); }
    5858    void addInlineRun(std::unique_ptr<Display::Run>&& inlineRun) { m_inlineRuns.append(WTFMove(inlineRun)); }
    5959    void addLineBox(LineBox lineBox) { m_lineBoxes.append(lineBox); }
  • trunk/Source/WebCore/layout/inlineformatting/InlineTextItem.cpp

    r245776 r245812  
    9999        // Soft linebreak?
    100100        if (isSoftLineBreak(text[currentPosition], preserveNewline)) {
    101             inlineContent.add(std::make_unique<InlineTextItem>(inlineBox, currentPosition, 1, true, false));
     101            inlineContent.append(std::make_unique<InlineTextItem>(inlineBox, currentPosition, 1, true, false));
    102102            ++currentPosition;
    103103            continue;
    … …  
    106106            auto length = moveToNextNonWhitespacePosition(text, currentPosition, preserveNewline);
    107107            auto isCollapsed = collapseWhiteSpace && length > 1;
    108             inlineContent.add(std::make_unique<InlineTextItem>(inlineBox, currentPosition, length, true, isCollapsed));
     108            inlineContent.append(std::make_unique<InlineTextItem>(inlineBox, currentPosition, length, true, isCollapsed));
    109109            currentPosition += length;
    110110            continue;
    … …  
    112112
    113113        auto length = moveToNextBreakablePosition(currentPosition, lineBreakIterator, style);
    114         inlineContent.add(std::make_unique<InlineTextItem>(inlineBox, currentPosition, length, false, false));
     114        inlineContent.append(std::make_unique<InlineTextItem>(inlineBox, currentPosition, length, false, false));
    115115        currentPosition += length;
    116116    }
Note: See TracChangeset for help on using the changeset viewer.