Changeset 272725 in webkit


Ignore:
Timestamp:
Feb 11, 2021, 6:56:18 AM (5 years ago)
Author:
Alan Bujtas
Message:

[LFC][IFC] Introduce dedicated logical rect getter for each inline level box type
https://bugs.webkit.org/show_bug.cgi?id=221725

Reviewed by Antti Koivisto.

This helps when different type of rects (margin vs. border) are returned for different type of boxes.

  • layout/inlineformatting/InlineFormattingContext.cpp:

(WebCore::Layout::InlineFormattingContext::computeGeometryForLineContent):

  • layout/inlineformatting/InlineLineBox.cpp:

(WebCore::Layout::LineBox::logicalRectForTextRun const):
(WebCore::Layout::LineBox::logicalRectForLineBreakBox const):
(WebCore::Layout::LineBox::logicalRectForInlineLevelBox const):
(WebCore::Layout::LineBox::logicalMarginRectForAtomicInlineLevelBox const):
(WebCore::Layout::LineBox::logicalRectForInlineBox const):
(WebCore::Layout::LineBox::logicalMarginRectForInlineLevelBox const): Deleted.

  • layout/inlineformatting/InlineLineBox.h:
  • layout/integration/LayoutIntegrationInlineContentBuilder.cpp:

(WebCore::LayoutIntegration::InlineContentBuilder::createDisplayNonRootInlineBoxes const):

  • layout/layouttree/LayoutTreeBuilder.cpp:

(WebCore::Layout::showInlineTreeAndRuns):

Location:
trunk/Source/WebCore
Files:
6 edited

Legend:

Unmodified
Added
Removed
  • trunk/Source/WebCore/ChangeLog

    r272724 r272725  
     12021-02-11  Zalan Bujtas  <zalan@apple.com>
     2
     3        [LFC][IFC] Introduce dedicated logical rect getter for each inline level box type
     4        https://bugs.webkit.org/show_bug.cgi?id=221725
     5
     6        Reviewed by Antti Koivisto.
     7
     8        This helps when different type of rects (margin vs. border) are returned for different type of boxes.
     9
     10        * layout/inlineformatting/InlineFormattingContext.cpp:
     11        (WebCore::Layout::InlineFormattingContext::computeGeometryForLineContent):
     12        * layout/inlineformatting/InlineLineBox.cpp:
     13        (WebCore::Layout::LineBox::logicalRectForTextRun const):
     14        (WebCore::Layout::LineBox::logicalRectForLineBreakBox const):
     15        (WebCore::Layout::LineBox::logicalRectForInlineLevelBox const):
     16        (WebCore::Layout::LineBox::logicalMarginRectForAtomicInlineLevelBox const):
     17        (WebCore::Layout::LineBox::logicalRectForInlineBox const):
     18        (WebCore::Layout::LineBox::logicalMarginRectForInlineLevelBox const): Deleted.
     19        * layout/inlineformatting/InlineLineBox.h:
     20        * layout/integration/LayoutIntegrationInlineContentBuilder.cpp:
     21        (WebCore::LayoutIntegration::InlineContentBuilder::createDisplayNonRootInlineBoxes const):
     22        * layout/layouttree/LayoutTreeBuilder.cpp:
     23        (WebCore::Layout::showInlineTreeAndRuns):
     24
    1252021-02-11  Zalan Bujtas  <zalan@apple.com>
    226
  • trunk/Source/WebCore/layout/inlineformatting/InlineFormattingContext.cpp

    r272724 r272725  
    465465            for (auto* layoutBox : layoutBoxList) {
    466466                auto& boxGeometry = formattingState.boxGeometry(*layoutBox);
    467                 auto inlineBoxLogicalHeight = LayoutUnit::fromFloatCeil(lineBox.logicalMarginRectForInlineLevelBox(*layoutBox, boxGeometry).height());
     467                auto inlineBoxLogicalHeight = LayoutUnit::fromFloatCeil(lineBox.logicalRectForInlineBox(*layoutBox, boxGeometry).height());
    468468                boxGeometry.setContentBoxHeight(inlineBoxLogicalHeight);
    469469                boxGeometry.setContentBoxWidth({ });
     
    491491            }
    492492            if (lineRun.isLineBreak()) {
    493                 auto lineBreakBoxRect = lineBox.logicalRectForTextRun(lineRun);
    494                 formattingState.addLineRun({ lineIndex, layoutBox, lineBreakBoxRect, lineRun.expansion(), lineRun.textContent() });
    495 
    496493                if (layoutBox.isLineBreakBox()) {
    497494                    // Only hard linebreaks have associated layout boxes.
     495                    auto lineBreakBoxRect = lineBox.logicalRectForLineBreakBox(layoutBox);
     496                    formattingState.addLineRun({ lineIndex, layoutBox, lineBreakBoxRect, lineRun.expansion(), { } });
     497
    498498                    auto& boxGeometry = formattingState.boxGeometry(layoutBox);
    499499                    lineBreakBoxRect.moveBy(lineBoxLogicalRect.topLeft());
    500500                    boxGeometry.setLogicalTopLeft(toLayoutPoint(lineBreakBoxRect.topLeft()));
    501501                    boxGeometry.setContentBoxHeight(toLayoutUnit(lineBreakBoxRect.height()));
    502                 }
     502                } else
     503                    formattingState.addLineRun({ lineIndex, layoutBox, lineBox.logicalRectForTextRun(lineRun), lineRun.expansion(), lineRun.textContent() });
    503504                continue;
    504505            }
    505506            if (lineRun.isBox()) {
    506507                ASSERT(layoutBox.isAtomicInlineLevelBox());
     508                auto logicalMarginRect = lineBox.logicalMarginRectForAtomicInlineLevelBox(layoutBox);
     509                formattingState.addLineRun({ lineIndex, layoutBox, logicalMarginRect, lineRun.expansion(), { } });
     510
     511                auto borderBoxLogicalTopLeft = logicalMarginRect.topLeft();
    507512                auto& boxGeometry = formattingState.boxGeometry(layoutBox);
    508                 auto logicalMarginRect = lineBox.logicalMarginRectForInlineLevelBox(layoutBox, boxGeometry);
    509                 formattingState.addLineRun({ lineIndex, layoutBox, logicalMarginRect, lineRun.expansion(), { } });
    510 
    511                 auto borderBoxLogicalTopLeft = logicalMarginRect.topLeft();
    512513                borderBoxLogicalTopLeft.move(std::max(0_lu, boxGeometry.marginStart()), std::max(0_lu, boxGeometry.marginBefore()));
    513514                // Note that inline boxes are relative to the line and their top position can be negative.
     
    526527            if (lineRun.isInlineBoxStart()) {
    527528                auto& boxGeometry = formattingState.boxGeometry(layoutBox);
    528                 auto inlineBoxLogicalRect = lineBox.logicalMarginRectForInlineLevelBox(layoutBox, boxGeometry);
     529                auto inlineBoxLogicalRect = lineBox.logicalRectForInlineBox(layoutBox, boxGeometry);
    529530                formattingState.addLineRun({ lineIndex, layoutBox, inlineBoxLogicalRect, lineRun.expansion(), { } });
    530531                inlineBoxStartSet.add(&layoutBox);
     
    534535            if (lineRun.isInlineBoxEnd()) {
    535536                inlineBoxEndSet.add(&layoutBox);
    536                 auto inlineBoxLogicalRect = lineBox.logicalMarginRectForInlineLevelBox(layoutBox, formattingState.boxGeometry(layoutBox));
     537                auto inlineBoxLogicalRect = lineBox.logicalRectForInlineBox(layoutBox, formattingState.boxGeometry(layoutBox));
    537538                enclosingTopAndBottom.bottom = std::max(enclosingTopAndBottom.bottom, inlineBoxLogicalRect.bottom());
    538539                continue;
     
    555556            auto& boxGeometry = formattingState.boxGeometry(layoutBox);
    556557            // Inline boxes may or may not be wrapped and have runs on multiple lines (e.g. <span>first line<br>second line<br>third line</span>)
    557             auto inlineBoxMarginRect = lineBox.logicalMarginRectForInlineLevelBox(layoutBox, boxGeometry);
     558            auto inlineBoxMarginRect = lineBox.logicalRectForInlineBox(layoutBox, boxGeometry);
    558559            auto inlineBoxSize = LayoutSize { LayoutUnit::fromFloatCeil(inlineBoxMarginRect.width()), LayoutUnit::fromFloatCeil(inlineBoxMarginRect.height()) };
    559560            auto logicalRect = Rect { LayoutPoint { inlineBoxMarginRect.topLeft() }, inlineBoxSize };
  • trunk/Source/WebCore/layout/inlineformatting/InlineLineBox.cpp

    r272724 r272725  
    107107InlineRect LineBox::logicalRectForTextRun(const Line::Run& run) const
    108108{
    109     ASSERT(run.isText() || run.isLineBreak());
     109    ASSERT(run.isText() || run.isSoftLineBreak());
    110110    auto* parentInlineBox = &inlineLevelBoxForLayoutBox(run.layoutBox().parent());
    111111    ASSERT(parentInlineBox->isInlineBox());
     
    122122}
    123123
    124 InlineRect LineBox::logicalMarginRectForInlineLevelBox(const Box& layoutBox, const BoxGeometry& boxGeometry) const
     124InlineRect LineBox::logicalRectForLineBreakBox(const Box& layoutBox) const
    125125{
    126     auto logicalRect = [&] {
    127         auto* inlineBox = &inlineLevelBoxForLayoutBox(layoutBox);
    128         auto inlineBoxLogicalRect = inlineBox->logicalRect();
    129         if (inlineBox->hasLineBoxRelativeAlignment())
    130             return inlineBoxLogicalRect;
     126    ASSERT(layoutBox.isLineBreakBox());
     127    return logicalRectForInlineLevelBox(layoutBox);
     128}
    131129
    132         if (&layoutBox.parent() == &m_rootInlineBox->layoutBox()) {
    133             inlineBoxLogicalRect.moveVertically(m_rootInlineBox->logicalTop());
    134             return inlineBoxLogicalRect;
    135         }
     130InlineRect LineBox::logicalRectForInlineLevelBox(const Box& layoutBox) const
     131{
     132    ASSERT(layoutBox.isInlineLevelBox() || layoutBox.isLineBreakBox());
     133    // Inline level boxes are relative to their parent unless the vertical alignment makes them relative to the line box (e.g. top, bottom).
     134    auto* inlineBox = &inlineLevelBoxForLayoutBox(layoutBox);
     135    auto inlineBoxLogicalRect = inlineBox->logicalRect();
     136    if (inlineBox->hasLineBoxRelativeAlignment())
     137        return inlineBoxLogicalRect;
    136138
    137         auto inlineBoxAbsolutelogicalTop = inlineBoxLogicalRect.top();
    138         while (inlineBox != m_rootInlineBox.get() && !inlineBox->hasLineBoxRelativeAlignment()) {
    139             inlineBox = &inlineLevelBoxForLayoutBox(inlineBox->layoutBox().parent());
    140             ASSERT(inlineBox->isInlineBox());
    141             inlineBoxAbsolutelogicalTop += inlineBox->logicalTop();
    142         }
    143         return InlineRect { inlineBoxAbsolutelogicalTop, inlineBoxLogicalRect.left(), inlineBoxLogicalRect.width(), inlineBoxLogicalRect.height() };
    144     }();
    145     if (!layoutBox.isInlineBox())
    146         return logicalRect;
     139    // Fast path for inline level boxes on the root inline box (e.g <div><img></div>).
     140    if (&layoutBox.parent() == &m_rootInlineBox->layoutBox()) {
     141        inlineBoxLogicalRect.moveVertically(m_rootInlineBox->logicalTop());
     142        return inlineBoxLogicalRect;
     143    }
    147144
     145    // e.g <div><span><img></span></div>
     146    auto inlineBoxAbsolutelogicalTop = inlineBoxLogicalRect.top();
     147    while (inlineBox != m_rootInlineBox.get() && !inlineBox->hasLineBoxRelativeAlignment()) {
     148        inlineBox = &inlineLevelBoxForLayoutBox(inlineBox->layoutBox().parent());
     149        ASSERT(inlineBox->isInlineBox());
     150        inlineBoxAbsolutelogicalTop += inlineBox->logicalTop();
     151    }
     152    return InlineRect { inlineBoxAbsolutelogicalTop, inlineBoxLogicalRect.left(), inlineBoxLogicalRect.width(), inlineBoxLogicalRect.height() };
     153}
     154
     155InlineRect LineBox::logicalMarginRectForAtomicInlineLevelBox(const Box& layoutBox) const
     156{
     157    ASSERT(layoutBox.isAtomicInlineLevelBox());
     158    return logicalRectForInlineLevelBox(layoutBox);
     159}
     160
     161InlineRect LineBox::logicalRectForInlineBox(const Box& layoutBox, const BoxGeometry& boxGeometry) const
     162{
     163    auto logicalRect = logicalRectForInlineLevelBox(layoutBox);
    148164    // This logical rect is as tall as the "text" content is. Let's adjust with vertical border and padding -vertical margin is ignored.
    149165    auto verticalBorderAndPadding = boxGeometry.verticalBorder() + boxGeometry.verticalPadding().valueOr(0_lu);
  • trunk/Source/WebCore/layout/inlineformatting/InlineLineBox.h

    r272701 r272725  
    151151
    152152    InlineRect logicalRectForTextRun(const Line::Run&) const;
     153    InlineRect logicalRectForLineBreakBox(const Box&) const;
     154    InlineRect logicalMarginRectForAtomicInlineLevelBox(const Box&) const;
    153155    InlineRect logicalRectForRootInlineBox() const { return m_rootInlineBox->logicalRect(); }
    154     InlineRect logicalMarginRectForInlineLevelBox(const Box&, const BoxGeometry&) const;
     156    InlineRect logicalRectForInlineBox(const Box&, const BoxGeometry&) const;
    155157
    156158    const InlineLevelBox& rootInlineBox() const { return *m_rootInlineBox; }
     
    172174
    173175    InlineLevelBox& inlineLevelBoxForLayoutBox(const Box& layoutBox) { return *m_inlineLevelBoxRectMap.get(&layoutBox); }
     176    InlineRect logicalRectForInlineLevelBox(const Box& layoutBox) const;
    174177
    175178    void setHasContent(bool hasContent) { m_hasContent = hasContent; }
  • trunk/Source/WebCore/layout/integration/LayoutIntegrationInlineContentBuilder.cpp

    r272602 r272725  
    342342            auto& layoutBox = inlineLevelBox->layoutBox();
    343343            auto& boxGeometry = m_layoutState.geometryForBox(layoutBox);
    344             auto inlineBoxRect = lineBox.logicalMarginRectForInlineLevelBox(layoutBox, boxGeometry);
     344            auto inlineBoxRect = lineBox.logicalRectForInlineBox(layoutBox, boxGeometry);
    345345            inlineBoxRect.moveBy(lineBoxLogicalRect.topLeft());
    346346
  • trunk/Source/WebCore/layout/layouttree/LayoutTreeBuilder.cpp

    r270932 r272725  
    407407            addSpacing();
    408408            stream << "    ";
    409             if (inlineLevelBox.isRootInlineBox())
     409            auto logicalRect = InlineRect { };
     410            auto& layoutBox = inlineLevelBox.layoutBox();
     411            if (inlineLevelBox.isRootInlineBox()) {
    410412                stream << "Root inline box";
    411             else if (inlineLevelBox.isAtomicInlineLevelBox())
     413                logicalRect = lineBox.logicalRectForRootInlineBox();
     414            } else if (inlineLevelBox.isAtomicInlineLevelBox()) {
    412415                stream << "Atomic inline level box";
    413             else if (inlineLevelBox.isLineBreakBox())
     416                logicalRect = lineBox.logicalMarginRectForAtomicInlineLevelBox(layoutBox);
     417            } else if (inlineLevelBox.isLineBreakBox()) {
    414418                stream << "Line break box";
    415             else if (inlineLevelBox.isInlineBox())
    416                 stream << "Generic inline box";
    417             else
     419                logicalRect = lineBox.logicalRectForLineBreakBox(layoutBox);
     420            } else if (inlineLevelBox.isInlineBox()) {
     421                stream << "Inline box";
     422                logicalRect = lineBox.logicalRectForInlineBox(layoutBox, layoutState.geometryForBox(layoutBox));
     423            } else
    418424                stream << "Generic inline level box";
    419             auto& layoutBox = inlineLevelBox.layoutBox();
    420             auto logicalRect = lineBox.logicalMarginRectForInlineLevelBox(layoutBox, layoutState.geometryForBox(layoutBox));
    421425            stream
    422426                << " at (" << logicalRect.left() << "," << logicalRect.top() << ")"
Note: See TracChangeset for help on using the changeset viewer.