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

Changeset 269146 in webkit


Ignore:
Timestamp:
Oct 29, 2020, 7:21:34 AM (6 years ago)
Author:
Antti Koivisto
Message:

[LFC][Integration] RenderBlockFlow::positionForPointWithInlineChildren should use iterator
https://bugs.webkit.org/show_bug.cgi?id=218283

Reviewed by Zalan Bujtas.

Reduce InlineBox access and eliminate one ensureLineBoxes() call.

  • layout/integration/LayoutIntegrationLineIterator.h:

(WebCore::LayoutIntegration::PathLine::topWithLeading const):
(WebCore::LayoutIntegration::PathLine::bottomWithLeading const):
(WebCore::LayoutIntegration::PathLine::legacyRootInlineBox const):

  • layout/integration/LayoutIntegrationLineIteratorLegacyPath.h:

(WebCore::LayoutIntegration::LineIteratorLegacyPath::topWithLeading const):
(WebCore::LayoutIntegration::LineIteratorLegacyPath::bottomWithLeading const):
(WebCore::LayoutIntegration::LineIteratorLegacyPath::legacyRootInlineBox const):

  • layout/integration/LayoutIntegrationLineIteratorModernPath.h:

(WebCore::LayoutIntegration::LineIteratorModernPath::topWithLeading const):
(WebCore::LayoutIntegration::LineIteratorModernPath::bottomWithLeading const):
(WebCore::LayoutIntegration::LineIteratorModernPath::legacyRootInlineBox const):

  • layout/integration/LayoutIntegrationRunIteratorModernPath.h:

(WebCore::LayoutIntegration::RunIteratorModernPath::legacyInlineBox const):

  • rendering/RenderBlockFlow.cpp:

(WebCore::positionForRun):
(WebCore::RenderBlockFlow::positionForPointWithInlineChildren):
(WebCore::RenderBlockFlow::positionForBox const): Deleted.

  • rendering/RenderBlockFlow.h:
Location:
trunk/Source/WebCore
Files:
9 edited

Legend:

Unmodified
Added
Removed
  • trunk/Source/WebCore/ChangeLog

    r269145 r269146  
     12020-10-29  Antti Koivisto  <antti@apple.com>
     2
     3        [LFC][Integration] RenderBlockFlow::positionForPointWithInlineChildren should use iterator
     4        https://bugs.webkit.org/show_bug.cgi?id=218283
     5
     6        Reviewed by Zalan Bujtas.
     7
     8        Reduce InlineBox access and eliminate one ensureLineBoxes() call.
     9
     10        * layout/integration/LayoutIntegrationLineIterator.h:
     11        (WebCore::LayoutIntegration::PathLine::topWithLeading const):
     12        (WebCore::LayoutIntegration::PathLine::bottomWithLeading const):
     13        (WebCore::LayoutIntegration::PathLine::legacyRootInlineBox const):
     14        * layout/integration/LayoutIntegrationLineIteratorLegacyPath.h:
     15        (WebCore::LayoutIntegration::LineIteratorLegacyPath::topWithLeading const):
     16        (WebCore::LayoutIntegration::LineIteratorLegacyPath::bottomWithLeading const):
     17        (WebCore::LayoutIntegration::LineIteratorLegacyPath::legacyRootInlineBox const):
     18        * layout/integration/LayoutIntegrationLineIteratorModernPath.h:
     19        (WebCore::LayoutIntegration::LineIteratorModernPath::topWithLeading const):
     20        (WebCore::LayoutIntegration::LineIteratorModernPath::bottomWithLeading const):
     21        (WebCore::LayoutIntegration::LineIteratorModernPath::legacyRootInlineBox const):
     22        * layout/integration/LayoutIntegrationRunIteratorModernPath.h:
     23        (WebCore::LayoutIntegration::RunIteratorModernPath::legacyInlineBox const):
     24        * rendering/RenderBlockFlow.cpp:
     25        (WebCore::positionForRun):
     26        (WebCore::RenderBlockFlow::positionForPointWithInlineChildren):
     27        (WebCore::RenderBlockFlow::positionForBox const): Deleted.
     28        * rendering/RenderBlockFlow.h:
     29
    1302020-10-29  Zalan Bujtas  <zalan@apple.com>
    231
  • trunk/Source/WebCore/layout/integration/LayoutIntegrationLineIterator.h

    r269041 r269146  
    5656    LayoutUnit selectionTopForHitTesting() const;
    5757    LayoutUnit selectionBottom() const;
     58    LayoutUnit topWithLeading() const;
     59    LayoutUnit bottomWithLeading() const;
    5860
    5961    float y() const;
     
    6567
    6668    const RenderBlockFlow& containingBlock() const;
     69    const RootInlineBox* legacyRootInlineBox() const;
    6770
    6871protected:
     
    129132{
    130133    return WTF::switchOn(m_pathVariant, [](const auto& path) {
    131         return path.top();
     134        return path.bottom();
    132135    });
    133136}
     
    151154    return WTF::switchOn(m_pathVariant, [](const auto& path) {
    152155        return path.selectionBottom();
     156    });
     157}
     158
     159inline LayoutUnit PathLine::topWithLeading() const
     160{
     161    return WTF::switchOn(m_pathVariant, [](const auto& path) {
     162        return path.topWithLeading();
     163    });
     164}
     165
     166inline LayoutUnit PathLine::bottomWithLeading() const
     167{
     168    return WTF::switchOn(m_pathVariant, [](const auto& path) {
     169        return path.bottomWithLeading();
    153170    });
    154171}
     
    182199}
    183200
    184 }
    185 }
    186 
     201inline const RootInlineBox* PathLine::legacyRootInlineBox() const
     202{
     203    return WTF::switchOn(m_pathVariant, [](const auto& path) {
     204        return path.legacyRootInlineBox();
     205    });
     206}
     207
     208}
     209}
     210
  • trunk/Source/WebCore/layout/integration/LayoutIntegrationLineIteratorLegacyPath.h

    r269041 r269146  
    5050    LayoutUnit selectionTopForHitTesting() const { return m_rootInlineBox->selectionTop(RootInlineBox::ForHitTesting::Yes); }
    5151    LayoutUnit selectionBottom() const { return m_rootInlineBox->selectionBottom(); }
     52    LayoutUnit topWithLeading() const { return m_rootInlineBox->lineTopWithLeading(); }
     53    LayoutUnit bottomWithLeading() const { return m_rootInlineBox->lineBottomWithLeading(); }
    5254
    5355    float y() const { return m_rootInlineBox->y(); }
     
    5658
    5759    const RenderBlockFlow& containingBlock() const { return m_rootInlineBox->blockFlow(); }
     60    const RootInlineBox* legacyRootInlineBox() const { return m_rootInlineBox; }
    5861
    5962    void traverseNext()
  • trunk/Source/WebCore/layout/integration/LayoutIntegrationLineIteratorModernPath.h

    r269041 r269146  
    5252    LayoutUnit top() const { return LayoutUnit::fromFloatRound(line().rect().y()); }
    5353    LayoutUnit bottom() const { return LayoutUnit::fromFloatRound(line().rect().maxY()); }
     54    // FIXME: What should these really be?
    5455    LayoutUnit selectionTop() const { return top(); }
    5556    LayoutUnit selectionTopForHitTesting() const { return top(); }
    5657    LayoutUnit selectionBottom() const { return bottom(); }
     58    LayoutUnit topWithLeading() const { return top(); }
     59    LayoutUnit bottomWithLeading() const { return bottom(); }
    5760
    5861    float y() const { return top(); }
     
    6164
    6265    const RenderBlockFlow& containingBlock() const { return m_inlineContent->containingBlock(); }
     66    const RootInlineBox* legacyRootInlineBox() const { return nullptr; }
    6367
    6468    void traverseNext()
  • trunk/Source/WebCore/layout/integration/LayoutIntegrationRunIteratorModernPath.h

    r268817 r269146  
    171171    InlineBox* legacyInlineBox() const
    172172    {
    173         ASSERT_NOT_REACHED();
    174173        return nullptr;
    175174    }
  • trunk/Source/WebCore/rendering/RenderBlockFlow.cpp

    r269145 r269146  
    33073307}
    33083308
    3309 Position RenderBlockFlow::positionForBox(InlineBox *box, bool start) const
    3310 {
    3311     if (!box)
     3309static Position positionForRun(const RenderBlockFlow& flow, LayoutIntegration::RunIterator run, bool start)
     3310{
     3311    if (!run)
    33123312        return Position();
    33133313
    3314     if (!box->renderer().nonPseudoNode())
    3315         return makeDeprecatedLegacyPosition(nonPseudoElement(), start ? caretMinOffset() : caretMaxOffset());
    3316 
    3317     if (!is<InlineTextBox>(*box))
    3318         return makeDeprecatedLegacyPosition(box->renderer().nonPseudoNode(), start ? box->renderer().caretMinOffset() : box->renderer().caretMaxOffset());
    3319 
    3320     auto& textBox = downcast<InlineTextBox>(*box);
    3321     return makeDeprecatedLegacyPosition(textBox.renderer().nonPseudoNode(), start ? textBox.start() : textBox.start() + textBox.len());
     3314    if (!run->renderer().nonPseudoNode())
     3315        return makeDeprecatedLegacyPosition(flow.nonPseudoElement(), start ? flow.caretMinOffset() : flow.caretMaxOffset());
     3316
     3317    if (!is<LayoutIntegration::TextRunIterator>(run))
     3318        return makeDeprecatedLegacyPosition(run->renderer().nonPseudoNode(), start ? run->renderer().caretMinOffset() : run->renderer().caretMaxOffset());
     3319
     3320    auto& textRun = downcast<LayoutIntegration::TextRunIterator>(run);
     3321    return makeDeprecatedLegacyPosition(textRun->renderer().nonPseudoNode(), start ? textRun->localStartOffset() : textRun->localEndOffset());
    33223322}
    33233323
     
    33913391    ASSERT(childrenInline());
    33923392
    3393     ensureLineBoxes();
    3394 
    3395     if (!firstRootBox())
     3393    auto firstLine = LayoutIntegration::firstLineFor(*this);
     3394
     3395    if (!firstLine)
    33963396        return createVisiblePosition(0, Affinity::Downstream);
    33973397
     
    34003400
    34013401    // look for the closest line box in the root box which is at the passed-in y coordinate
    3402     InlineBox* closestBox = 0;
    3403     RootInlineBox* firstRootBoxWithChildren = 0;
    3404     RootInlineBox* lastRootBoxWithChildren = 0;
    3405     for (RootInlineBox* root = firstRootBox(); root; root = root->nextRootBox()) {
    3406         if (fragment && root->containingFragment() != fragment)
     3402    LayoutIntegration::RunIterator closestRun;
     3403    LayoutIntegration::LineIterator firstLineWithChildren;
     3404    LayoutIntegration::LineIterator lastLineWithChildren;
     3405    for (auto line = firstLine; line; line.traverseNext()) {
     3406        if (fragment && line->legacyRootInlineBox() && line->legacyRootInlineBox()->containingFragment() != fragment)
    34073407            continue;
    34083408
    3409         if (!root->firstLeafDescendant())
     3409        if (!line.firstRun())
    34103410            continue;
    3411         if (!firstRootBoxWithChildren)
    3412             firstRootBoxWithChildren = root;
    3413 
    3414         if (!linesAreFlipped && root->isFirstAfterPageBreak() && (pointInLogicalContents.y() < root->lineTopWithLeading()
    3415             || (blocksAreFlipped && pointInLogicalContents.y() == root->lineTopWithLeading())))
     3411        if (!firstLineWithChildren)
     3412            firstLineWithChildren = line;
     3413
     3414        if (!linesAreFlipped && line->legacyRootInlineBox() && line->legacyRootInlineBox()->isFirstAfterPageBreak()
     3415            && (pointInLogicalContents.y() < line->topWithLeading() || (blocksAreFlipped && pointInLogicalContents.y() == line->topWithLeading())))
    34163416            break;
    34173417
    3418         lastRootBoxWithChildren = root;
     3418        lastLineWithChildren = line;
    34193419
    34203420        // check if this root line box is located at this y coordinate
    3421         if (pointInLogicalContents.y() < root->selectionBottom() || (blocksAreFlipped && pointInLogicalContents.y() == root->selectionBottom())) {
     3421        if (pointInLogicalContents.y() < line->selectionBottom() || (blocksAreFlipped && pointInLogicalContents.y() == line->selectionBottom())) {
    34223422            if (linesAreFlipped) {
    3423                 RootInlineBox* nextRootBoxWithChildren = root->nextRootBox();
    3424                 while (nextRootBoxWithChildren && !nextRootBoxWithChildren->firstLeafDescendant())
    3425                     nextRootBoxWithChildren = nextRootBoxWithChildren->nextRootBox();
    3426 
    3427                 if (nextRootBoxWithChildren && nextRootBoxWithChildren->isFirstAfterPageBreak() && (pointInLogicalContents.y() > nextRootBoxWithChildren->lineTopWithLeading()
    3428                     || (!blocksAreFlipped && pointInLogicalContents.y() == nextRootBoxWithChildren->lineTopWithLeading())))
     3423                auto nextLineWithChildren = line.next();
     3424                while (nextLineWithChildren && !nextLineWithChildren.firstRun())
     3425                    nextLineWithChildren.traverseNext();
     3426
     3427                if (nextLineWithChildren && nextLineWithChildren->legacyRootInlineBox() && nextLineWithChildren->legacyRootInlineBox()->isFirstAfterPageBreak()
     3428                    && (pointInLogicalContents.y() > nextLineWithChildren->topWithLeading() || (!blocksAreFlipped && pointInLogicalContents.y() == nextLineWithChildren->topWithLeading())))
    34293429                    continue;
    34303430            }
    3431             if (auto closestRun = LayoutIntegration::LineIterator(root).closestRunForLogicalLeftPosition(pointInLogicalContents.x()))
    3432                 closestBox = closestRun->legacyInlineBox();
    3433             if (closestBox)
     3431            closestRun = line.closestRunForLogicalLeftPosition(pointInLogicalContents.x());
     3432            if (closestRun)
    34343433                break;
    34353434        }
     
    34383437    bool moveCaretToBoundary = frame().editor().behavior().shouldMoveCaretToHorizontalBoundaryWhenPastTopOrBottom();
    34393438
    3440     if (!moveCaretToBoundary && !closestBox && lastRootBoxWithChildren) {
     3439    if (!moveCaretToBoundary && !closestRun && lastLineWithChildren) {
    34413440        // y coordinate is below last root line box, pretend we hit it
    3442         auto closestRun = LayoutIntegration::LineIterator(lastRootBoxWithChildren).closestRunForLogicalLeftPosition(pointInLogicalContents.x());
    3443         closestBox = closestRun ? closestRun->legacyInlineBox() : nullptr;
    3444     }
    3445 
    3446     if (closestBox) {
     3441        closestRun = lastLineWithChildren.closestRunForLogicalLeftPosition(pointInLogicalContents.x());
     3442    }
     3443
     3444    if (closestRun) {
    34473445        if (moveCaretToBoundary) {
    3448             LayoutUnit firstRootBoxWithChildrenTop = std::min(firstRootBoxWithChildren->selectionTop(RootInlineBox::ForHitTesting::Yes), LayoutUnit(firstRootBoxWithChildren->logicalTop()));
    3449             if (pointInLogicalContents.y() < firstRootBoxWithChildrenTop
    3450                 || (blocksAreFlipped && pointInLogicalContents.y() == firstRootBoxWithChildrenTop)) {
    3451                 InlineBox* box = firstRootBoxWithChildren->firstLeafDescendant();
    3452                 if (box->isLineBreak()) {
    3453                     if (InlineBox* newBox = box->nextLeafOnLineIgnoringLineBreak())
    3454                         box = newBox;
     3446            LayoutUnit firstLineWithChildrenTop = std::min(firstLineWithChildren->selectionTopForHitTesting(), LayoutUnit(firstLineWithChildren->top()));
     3447            if (pointInLogicalContents.y() < firstLineWithChildrenTop
     3448                || (blocksAreFlipped && pointInLogicalContents.y() == firstLineWithChildrenTop)) {
     3449                auto run = firstLineWithChildren.firstRun();
     3450                if (run->isLineBreak()) {
     3451                    if (auto next = run.nextOnLineIgnoringLineBreak())
     3452                        run = next;
    34553453                }
    34563454                // y coordinate is above first root line box, so return the start of the first
    3457                 return positionForBox(box, true);
     3455                return positionForRun(*this, run, true);
    34583456            }
    34593457        }
    34603458
    34613459        // pass the box a top position that is inside it
    3462         LayoutPoint point(pointInLogicalContents.x(), closestBox->root().blockDirectionPointInLine());
     3460        LayoutPoint point(pointInLogicalContents.x(), closestRun.line()->blockDirectionPointInLine());
    34633461        if (!isHorizontalWritingMode())
    34643462            point = point.transposedPoint();
    3465         if (closestBox->renderer().isReplaced())
    3466             return positionForPointRespectingEditingBoundaries(*this, downcast<RenderBox>(closestBox->renderer()), point);
    3467         return closestBox->renderer().positionForPoint(point, nullptr);
    3468     }
    3469 
    3470     if (lastRootBoxWithChildren) {
     3463        if (closestRun->renderer().isReplaced())
     3464            return positionForPointRespectingEditingBoundaries(*this, const_cast<RenderBox&>(downcast<RenderBox>(closestRun->renderer())), point);
     3465        return const_cast<RenderObject&>(closestRun->renderer()).positionForPoint(point, nullptr);
     3466    }
     3467
     3468    if (lastLineWithChildren) {
    34713469        // We hit this case for Mac behavior when the Y coordinate is below the last box.
    34723470        ASSERT(moveCaretToBoundary);
    3473         InlineBox* logicallyLastBox;
    3474         if (lastRootBoxWithChildren->getLogicalEndBoxWithNode(logicallyLastBox))
    3475             return positionForBox(logicallyLastBox, false);
     3471        if (auto logicallyLastRun = lastLineWithChildren.logicalEndRunWithNode())
     3472            return positionForRun(*this, logicallyLastRun, false);
    34763473    }
    34773474
     
    34843481Position RenderBlockFlow::positionForPoint(const LayoutPoint& point)
    34853482{
    3486     // FIXME: This forces Complex Line Layout.
    34873483    return positionForPoint(point, nullptr).deepEquivalent();
    34883484}
  • trunk/Source/WebCore/rendering/RenderBlockFlow.h

    r268994 r269146  
    528528        LayoutUnit& lastLogicalTop, LayoutUnit& lastLogicalLeft, LayoutUnit& lastLogicalRight, const LogicalSelectionOffsetCaches&, const PaintInfo*) override;
    529529   
    530     Position positionForBox(InlineBox*, bool start = true) const;
    531530    VisiblePosition positionForPointWithInlineChildren(const LayoutPoint& pointInLogicalContents, const RenderFragmentContainer*) override;
    532531    void addFocusRingRectsForInlineChildren(Vector<LayoutRect>& rects, const LayoutPoint& additionalOffset, const RenderLayerModelObject*) override;
  • trunk/Source/WebCore/rendering/RootInlineBox.cpp

    r269064 r269146  
    751751}
    752752
    753 int RootInlineBox::blockDirectionPointInLine() const
    754 {
    755     return !blockFlow().style().isFlippedBlocksWritingMode() ? std::max(lineTop(), selectionTop()) : std::min(lineBottom(), selectionBottom());
    756 }
    757 
    758753RenderBlockFlow& RootInlineBox::blockFlow() const
    759754{
  • trunk/Source/WebCore/rendering/RootInlineBox.h

    r269064 r269146  
    8080    LayoutUnit selectionTopAdjustedForPrecedingBlock() const;
    8181    LayoutUnit selectionHeightAdjustedForPrecedingBlock() const { return std::max<LayoutUnit>(0, selectionBottom() - selectionTopAdjustedForPrecedingBlock()); }
    82 
    83     int blockDirectionPointInLine() const;
    8482
    8583    LayoutUnit alignBoxesInBlockDirection(LayoutUnit heightOfBlock, GlyphOverflowAndFallbackFontsMap&, VerticalPositionCache&);
Note: See TracChangeset for help on using the changeset viewer.