Changeset 247257 in webkit


Ignore:
Timestamp:
Jul 9, 2019 8:29:31 AM (5 years ago)
Author:
Alan Bujtas
Message:

[LFC][IFC] Remove InlineItem references from inline runs.
https://bugs.webkit.org/show_bug.cgi?id=199608
<rdar://problem/52812775>

Reviewed by Antti Koivisto.

Constructing the inline runs is where we stop using InlineItems in the process of processing the inline content.
InlineItems are redundant in the context of Display::Runs.
It also enables us to create temporary InlineItems to process split content.

  • layout/inlineformatting/InlineFormattingContextLineLayout.cpp:

(WebCore::Layout::InlineFormattingContext::LineLayout::createDisplayRuns const):

  • layout/inlineformatting/InlineFormattingContextQuirks.cpp:

(WebCore::Layout::InlineFormattingContext::Quirks::lineDescentNeedsCollapsing):

  • layout/inlineformatting/InlineLine.cpp:

(WebCore::Layout::Line::Content::Run::Run):
(WebCore::Layout::Line::isVisuallyEmpty const):
(WebCore::Layout::Line::close):
(WebCore::Layout::Line::removeTrailingTrimmableContent):
(WebCore::Layout::Line::trailingTrimmableWidth const):
(WebCore::Layout::Line::appendNonBreakableSpace):
(WebCore::Layout::Line::appendTextContent):
(WebCore::Layout::Line::appendNonReplacedInlineBox):
(WebCore::Layout::Line::appendHardLineBreak):

  • layout/inlineformatting/InlineLine.h:

(WebCore::Layout::Line::Content::Run::layoutBox const):
(WebCore::Layout::Line::Content::Run::logicalRect const):
(WebCore::Layout::Line::Content::Run::textContext const):
(WebCore::Layout::Line::Content::Run::type const):
(WebCore::Layout::Line::Content::Run::isText const):
(WebCore::Layout::Line::Content::Run::isBox const):
(WebCore::Layout::Line::Content::Run::isLineBreak const):
(WebCore::Layout::Line::Content::Run::isContainerStart const):
(WebCore::Layout::Line::Content::Run::isContainerEnd const):
(WebCore::Layout::Line::Content::Run::adjustLogicalTop):
(WebCore::Layout::Line::Content::Run::moveVertically):
(WebCore::Layout::Line::Content::Run::moveHorizontally):
(WebCore::Layout::Line::Content::Run::setTextIsCollapsed):

Location:
trunk/Source/WebCore
Files:
5 edited

Legend:

Unmodified
Added
Removed
  • trunk/Source/WebCore/ChangeLog

    r247256 r247257  
     12019-07-09  Zalan Bujtas  <zalan@apple.com>
     2
     3        [LFC][IFC] Remove InlineItem references from inline runs.
     4        https://bugs.webkit.org/show_bug.cgi?id=199608
     5        <rdar://problem/52812775>
     6
     7        Reviewed by Antti Koivisto.
     8
     9        Constructing the inline runs is where we stop using InlineItems in the process of processing the inline content.
     10        InlineItems are redundant in the context of Display::Runs.
     11        It also enables us to create temporary InlineItems to process split content. 
     12
     13        * layout/inlineformatting/InlineFormattingContextLineLayout.cpp:
     14        (WebCore::Layout::InlineFormattingContext::LineLayout::createDisplayRuns const):
     15        * layout/inlineformatting/InlineFormattingContextQuirks.cpp:
     16        (WebCore::Layout::InlineFormattingContext::Quirks::lineDescentNeedsCollapsing):
     17        * layout/inlineformatting/InlineLine.cpp:
     18        (WebCore::Layout::Line::Content::Run::Run):
     19        (WebCore::Layout::Line::isVisuallyEmpty const):
     20        (WebCore::Layout::Line::close):
     21        (WebCore::Layout::Line::removeTrailingTrimmableContent):
     22        (WebCore::Layout::Line::trailingTrimmableWidth const):
     23        (WebCore::Layout::Line::appendNonBreakableSpace):
     24        (WebCore::Layout::Line::appendTextContent):
     25        (WebCore::Layout::Line::appendNonReplacedInlineBox):
     26        (WebCore::Layout::Line::appendHardLineBreak):
     27        * layout/inlineformatting/InlineLine.h:
     28        (WebCore::Layout::Line::Content::Run::layoutBox const):
     29        (WebCore::Layout::Line::Content::Run::logicalRect const):
     30        (WebCore::Layout::Line::Content::Run::textContext const):
     31        (WebCore::Layout::Line::Content::Run::type const):
     32        (WebCore::Layout::Line::Content::Run::isText const):
     33        (WebCore::Layout::Line::Content::Run::isBox const):
     34        (WebCore::Layout::Line::Content::Run::isLineBreak const):
     35        (WebCore::Layout::Line::Content::Run::isContainerStart const):
     36        (WebCore::Layout::Line::Content::Run::isContainerEnd const):
     37        (WebCore::Layout::Line::Content::Run::adjustLogicalTop):
     38        (WebCore::Layout::Line::Content::Run::moveVertically):
     39        (WebCore::Layout::Line::Content::Run::moveHorizontally):
     40        (WebCore::Layout::Line::Content::Run::setTextIsCollapsed):
     41
    1422019-07-09  Antti Koivisto  <antti@apple.com>
    243
  • trunk/Source/WebCore/layout/inlineformatting/InlineFormattingContextLineLayout.cpp

    r247199 r247257  
    318318    for (unsigned index = 0; index < lineRuns.size(); ++index) {
    319319        auto& lineRun = lineRuns.at(index);
    320 
    321         auto& inlineItem = lineRun->inlineItem;
    322         auto& logicalRect = lineRun->logicalRect;
    323         auto& layoutBox = inlineItem.layoutBox();
     320        auto& logicalRect = lineRun->logicalRect();
     321        auto& layoutBox = lineRun->layoutBox();
    324322        auto& displayBox = layoutState().displayBoxForLayoutBox(layoutBox);
    325323
    326         if (inlineItem.isHardLineBreak()) {
     324        if (lineRun->isLineBreak()) {
    327325            displayBox.setTopLeft(logicalRect.topLeft());
    328326            displayBox.setContentBoxWidth(logicalRect.width());
     
    333331
    334332        // Inline level box (replaced or inline-block)
    335         if (inlineItem.isBox()) {
     333        if (lineRun->isBox()) {
    336334            auto topLeft = logicalRect.topLeft();
    337335            if (layoutBox.isInFlowPositioned())
     
    344342
    345343        // Inline level container start (<span>)
    346         if (inlineItem.isContainerStart()) {
     344        if (lineRun->isContainerStart()) {
    347345            displayBox.setTopLeft(logicalRect.topLeft());
    348346            lineBoxRect.expandHorizontally(logicalRect.width());
     
    351349
    352350        // Inline level container end (</span>)
    353         if (inlineItem.isContainerEnd()) {
     351        if (lineRun->isContainerEnd()) {
    354352            if (layoutBox.isInFlowPositioned()) {
    355353                auto inflowOffset = Geometry::inFlowPositionedPositionOffset(layoutState(), layoutBox);
     
    367365
    368366        // Text content. Try to join multiple text runs when possible.
    369         ASSERT(lineRun->textContext);       
     367        ASSERT(lineRun->isText());
     368        auto textContext = lineRun->textContext();   
    370369        const Line::Content::Run* previousLineRun = !index ? nullptr : lineRuns[index - 1].get();
    371         if (!lineRun->isCollapsed) {
    372             auto previousRunCanBeExtended = previousLineRun ? previousLineRun->canBeExtended : false;
    373             auto requiresNewRun = !index || !previousRunCanBeExtended || &layoutBox != &previousLineRun->inlineItem.layoutBox();
     370        if (!textContext->isCollapsed) {
     371            auto previousRunCanBeExtended = previousLineRun && previousLineRun->textContext() ? previousLineRun->textContext()->canBeExtended : false;
     372            auto requiresNewRun = !index || !previousRunCanBeExtended || &layoutBox != &previousLineRun->layoutBox();
    374373            if (requiresNewRun)
    375                 m_formattingState.addInlineRun(std::make_unique<Display::Run>(logicalRect, Display::Run::TextContext { lineRun->textContext->start, lineRun->textContext->length }));
     374                m_formattingState.addInlineRun(std::make_unique<Display::Run>(logicalRect, Display::Run::TextContext { textContext->start, textContext->length }));
    376375            else {
    377376                auto& lastDisplayRun = m_formattingState.inlineRuns().last();
    378377                lastDisplayRun->expandHorizontally(logicalRect.width());
    379                 lastDisplayRun->textContext()->expand(lineRun->textContext->length);
     378                lastDisplayRun->textContext()->expand(textContext->length);
    380379            }
    381380            lineBoxRect.expandHorizontally(logicalRect.width());
    382381        }
    383382        // FIXME take content breaking into account when part of the layout box is on the previous line.
    384         auto firstInlineRunForLayoutBox = !previousLineRun || &previousLineRun->inlineItem.layoutBox() != &layoutBox;
     383        auto firstInlineRunForLayoutBox = !previousLineRun || &previousLineRun->layoutBox() != &layoutBox;
    385384        if (firstInlineRunForLayoutBox) {
    386385            // Setup display box for the associated layout box.
    387386            displayBox.setTopLeft(logicalRect.topLeft());
    388             displayBox.setContentBoxWidth(lineRun->isCollapsed ? LayoutUnit() : logicalRect.width());
     387            displayBox.setContentBoxWidth(textContext->isCollapsed ? LayoutUnit() : logicalRect.width());
    389388            displayBox.setContentBoxHeight(logicalRect.height());
    390         } else if (!lineRun->isCollapsed) {
     389        } else if (!textContext->isCollapsed) {
    391390            // FIXME fix it for multirun/multiline.
    392391            displayBox.setContentBoxWidth(displayBox.contentBoxWidth() + logicalRect.width());
  • trunk/Source/WebCore/layout/inlineformatting/InlineFormattingContextQuirks.cpp

    r246634 r247257  
    4545
    4646    for (auto& run : lineContent.runs()) {
    47         auto& inlineItem = run->inlineItem;
    48         if (inlineItem.style().verticalAlign() != VerticalAlign::Baseline)
     47        auto& layoutBox = run->layoutBox();
     48        if (layoutBox.style().verticalAlign() != VerticalAlign::Baseline)
    4949            continue;
    5050
    51         switch (inlineItem.type()) {
     51        switch (run->type()) {
    5252        case InlineItem::Type::Text:
    53             if (!run->isCollapsed)
     53            if (!run->textContext() || !run->textContext()->isCollapsed)
    5454                return false;
    5555            break;
     
    5757            return false;
    5858        case InlineItem::Type::ContainerStart: {
    59             auto& displayBox = layoutState.displayBoxForLayoutBox(inlineItem.layoutBox());
     59            auto& displayBox = layoutState.displayBoxForLayoutBox(layoutBox);
    6060            if (displayBox.horizontalBorder() || (displayBox.horizontalPadding() && displayBox.horizontalPadding().value()))
    6161                return false;
     
    6565            break;
    6666        case InlineItem::Type::Box: {
    67             auto& layoutBox = inlineItem.layoutBox();
    6867            if (layoutBox.isInlineBlockBox() && layoutBox.establishesInlineFormattingContext()) {
    6968                auto& formattingState = downcast<InlineFormattingState>(layoutState.establishedFormattingState(layoutBox));
  • trunk/Source/WebCore/layout/inlineformatting/InlineLine.cpp

    r247153 r247257  
    3636WTF_MAKE_ISO_ALLOCATED_IMPL(Line);
    3737
    38 Line::Content::Run::Run(const InlineItem& inlineItem, const Display::Rect& logicalRect, TextContext textContext, bool isCollapsed, bool canBeExtended)
    39     : inlineItem(inlineItem)
    40     , logicalRect(logicalRect)
    41     , textContext(textContext)
    42     , isCollapsed(isCollapsed)
    43     , canBeExtended(canBeExtended)
     38Line::Content::Run::Run(const InlineItem& inlineItem, const Display::Rect& logicalRect)
     39    : m_layoutBox(inlineItem.layoutBox())
     40    , m_type(inlineItem.type())
     41    , m_logicalRect(logicalRect)
     42{
     43}
     44
     45Line::Content::Run::Run(const InlineItem& inlineItem, const TextContext& textContext, const Display::Rect& logicalRect)
     46    : m_layoutBox(inlineItem.layoutBox())
     47    , m_type(inlineItem.type())
     48    , m_logicalRect(logicalRect)
     49    , m_textContext(textContext)
    4450{
    4551}
     
    6975    // Return true for empty inline containers like <span></span>.
    7076    for (auto& run : m_content->runs()) {
    71         if (run->inlineItem.isContainerStart()) {
    72             if (!isInlineContainerConsideredEmpty(m_layoutState, run->inlineItem.layoutBox()))
     77        if (run->isContainerStart()) {
     78            if (!isInlineContainerConsideredEmpty(m_layoutState, run->layoutBox()))
    7379                return false;
    7480            continue;
    7581        }
    76         if (run->inlineItem.isContainerEnd())
     82        if (run->isContainerEnd())
    7783            continue;
    78         if (run->inlineItem.layoutBox().establishesFormattingContext()) {
    79             ASSERT(run->inlineItem.layoutBox().isInlineBlockBox());
    80             auto& displayBox = m_layoutState.displayBoxForLayoutBox(run->inlineItem.layoutBox());
     84        if (run->layoutBox().establishesFormattingContext()) {
     85            ASSERT(run->layoutBox().isInlineBlockBox());
     86            auto& displayBox = m_layoutState.displayBoxForLayoutBox(run->layoutBox());
    8187            if (!displayBox.width())
    8288                continue;
     
    8591            continue;
    8692        }
    87         if (!run->isCollapsed)
     93        if (!run->textContext() || !run->textContext()->isCollapsed)
    8894            return false;
    8995    }
     
    109115        for (auto& run : m_content->runs()) {
    110116            LayoutUnit logicalTop;
    111             auto& inlineItem = run->inlineItem;
    112             auto& layoutBox = inlineItem.layoutBox();
    113             auto verticalAlign = inlineItem.style().verticalAlign();
    114             auto ascent = inlineItem.style().fontMetrics().ascent();
     117            auto& layoutBox = run->layoutBox();
     118            auto verticalAlign = layoutBox.style().verticalAlign();
     119            auto ascent = layoutBox.style().fontMetrics().ascent();
    115120
    116121            switch (verticalAlign) {
    117122            case VerticalAlign::Baseline:
    118                 if (inlineItem.isLineBreak() || inlineItem.isText())
     123                if (run->isLineBreak() || run->isText())
    119124                    logicalTop = baselineOffset() - ascent;
    120                 else if (inlineItem.isContainerStart()) {
     125                else if (run->isContainerStart()) {
    121126                    auto& displayBox = m_layoutState.displayBoxForLayoutBox(layoutBox);
    122127                    logicalTop = baselineOffset() - ascent - displayBox.borderTop() - displayBox.paddingTop().valueOr(0);
     
    128133                    logicalTop = baselineOffset() - inlineBlockBaseline.ascent;
    129134                } else
    130                     logicalTop = baselineOffset() - run->logicalRect.height();
     135                    logicalTop = baselineOffset() - run->logicalRect().height();
    131136                break;
    132137            case VerticalAlign::Top:
     
    134139                break;
    135140            case VerticalAlign::Bottom:
    136                 logicalTop = logicalBottom() - run->logicalRect.height();
     141                logicalTop = logicalBottom() - run->logicalRect().height();
    137142                break;
    138143            default:
     
    140145                break;
    141146            }
    142             run->logicalRect.setTop(logicalTop);
     147            run->adjustLogicalTop(logicalTop);
    143148            // Convert runs from relative to the line top/left to the formatting root's border box top/left.
    144             run->logicalRect.moveVertically(this->logicalTop());
    145             run->logicalRect.moveHorizontally(this->logicalLeft());
     149            run->moveVertically(this->logicalTop());
     150            run->moveHorizontally(this->logicalLeft());
    146151        }
    147152    }
     
    157162    LayoutUnit trimmableWidth;
    158163    for (auto* trimmableRun : m_trimmableContent) {
    159         trimmableRun->isCollapsed = true;
    160         trimmableWidth += trimmableRun->logicalRect.width();
     164        ASSERT(trimmableRun->isText());
     165        trimmableRun->setTextIsCollapsed();
     166        trimmableWidth += trimmableRun->logicalRect().width();
    161167    }
    162168    m_contentLogicalWidth -= trimmableWidth;
     
    183189    LayoutUnit trimmableWidth;
    184190    for (auto* trimmableRun : m_trimmableContent) {
    185         ASSERT(!trimmableRun->isCollapsed);
    186         trimmableWidth += trimmableRun->logicalRect.width();
     191        ASSERT(!trimmableRun->textContext()->isCollapsed);
     192        trimmableWidth += trimmableRun->logicalRect().width();
    187193    }
    188194    return trimmableWidth;
     
    206212void Line::appendNonBreakableSpace(const InlineItem& inlineItem, const Display::Rect& logicalRect)
    207213{
    208     m_content->runs().append(std::make_unique<Content::Run>(inlineItem, logicalRect, Content::Run::TextContext { }, false, false));
     214    m_content->runs().append(std::make_unique<Content::Run>(inlineItem, logicalRect));
    209215    m_contentLogicalWidth += logicalRect.width();
    210216}
     
    251257        // Check if the last item is trimmable as well.
    252258        for (int index = runs.size() - 1; index >= 0; --index) {
    253             auto& inlineItem = runs[index]->inlineItem;
    254             if (inlineItem.isBox())
     259            auto& run = runs[index];
     260            if (run->isBox())
    255261                return false;
    256             if (inlineItem.isText())
    257                 return TextUtil::isTrimmableContent(inlineItem);
    258             ASSERT(inlineItem.isContainerStart() || inlineItem.isContainerEnd());
     262            if (run->isText())
     263                return run->textContext()->isWhitespace && run->layoutBox().style().collapseWhiteSpace();
     264            ASSERT(run->isContainerStart() || run->isContainerEnd());
    259265        }
    260266        return true;
     
    274280    }
    275281
    276     auto textContext = Content::Run::TextContext { inlineItem.start(), inlineItem.isCollapsed() ? 1 : inlineItem.length() };
    277     auto lineItem = std::make_unique<Content::Run>(inlineItem, logicalRect, textContext, isCompletelyCollapsed, canBeExtended);
     282    auto textContext = Content::Run::TextContext { inlineItem.start(), inlineItem.isCollapsed() ? 1 : inlineItem.length(), isCompletelyCollapsed, canBeExtended, inlineItem.isWhitespace() };
     283    auto lineItem = std::make_unique<Content::Run>(inlineItem, textContext, logicalRect);
    278284    if (isTrimmable && !isCompletelyCollapsed)
    279285        m_trimmableContent.add(lineItem.get());
     
    296302    }
    297303
    298     m_content->runs().append(std::make_unique<Content::Run>(inlineItem, logicalRect, Content::Run::TextContext { }, false, false));
     304    m_content->runs().append(std::make_unique<Content::Run>(inlineItem, logicalRect));
    299305    m_contentLogicalWidth += (logicalWidth + horizontalMargin.start + horizontalMargin.end);
    300306    m_trimmableContent.clear();
     
    316322        logicalRect.setHeight(logicalHeight());
    317323    }
    318     m_content->runs().append(std::make_unique<Content::Run>(inlineItem, logicalRect, Content::Run::TextContext { }, false, false));
     324    m_content->runs().append(std::make_unique<Content::Run>(inlineItem, logicalRect));
    319325}
    320326
  • trunk/Source/WebCore/layout/inlineformatting/InlineLine.h

    r246679 r247257  
    5858                unsigned start { 0 };
    5959                unsigned length { 0 };
     60                bool isCollapsed { false };
     61                bool isWhitespace { false };
     62                bool canBeExtended { false };
    6063            };
    61             Run(const InlineItem&, const Display::Rect&, TextContext, bool isCollapsed, bool canBeExtended);
     64            Run(const InlineItem&, const Display::Rect&);
     65            Run(const InlineItem&, const TextContext&, const Display::Rect&);
    6266
    63             const InlineItem& inlineItem;
    64             Display::Rect logicalRect;
    65             LayoutUnit baseline;
    66             Optional<TextContext> textContext;
    67             bool isCollapsed { false };
    68             bool canBeExtended { false };
     67            const Box& layoutBox() const { return m_layoutBox; }
     68            const Display::Rect& logicalRect() const { return m_logicalRect; }
     69            const Optional<TextContext> textContext() const { return m_textContext; }
     70            InlineItem::Type type() const { return m_type; }
     71
     72            bool isText() const { return m_type == InlineItem::Type::Text; }
     73            bool isBox() const { return m_type == InlineItem::Type::Box; }
     74            bool isLineBreak() const { return m_type == InlineItem::Type::HardLineBreak; }
     75            bool isContainerStart() const { return m_type == InlineItem::Type::ContainerStart; }
     76            bool isContainerEnd() const { return m_type == InlineItem::Type::ContainerEnd; }
     77
     78        private:
     79            friend class Line;
     80            void adjustLogicalTop(LayoutUnit logicalTop) { m_logicalRect.setTop(logicalTop); }
     81            void moveVertically(LayoutUnit offset) { m_logicalRect.moveVertically(offset); }
     82            void moveHorizontally(LayoutUnit offset) { m_logicalRect.moveHorizontally(offset); }
     83            void setTextIsCollapsed() { m_textContext->isCollapsed = true; }
     84
     85            const Box& m_layoutBox;
     86            const InlineItem::Type m_type;
     87            Display::Rect m_logicalRect;
     88            Optional<TextContext> m_textContext;
    6989        };
    7090        using Runs = Vector<std::unique_ptr<Run>>;
Note: See TracChangeset for help on using the changeset viewer.