Title: [284112] trunk/Source/WebCore
Revision
284112
Author
[email protected]
Date
2021-10-13 11:02:22 -0700 (Wed, 13 Oct 2021)

Log Message

[LFC][Integration] Move text box logical order cache to the caller
https://bugs.webkit.org/show_bug.cgi?id=231669

Reviewed by Alan Bujtas.

Don't maintain this rarely used cache internally in the iterator. Instead move it to the caller.

Also make the code non-legacy specific so it will work with future IFC BiDi.

* dom/Position.cpp:
(WebCore::Position::upstream const):
(WebCore::Position::downstream const):
(WebCore::searchAheadForBetterMatch):
* editing/CompositeEditCommand.cpp:
(WebCore::CompositeEditCommand::deleteInsignificantText):
* editing/TextIterator.cpp:
(WebCore::TextIterator::advance):
(WebCore::TextIterator::handleTextNode):
(WebCore::TextIterator::handleTextRun):
(WebCore::TextIterator::revertToRemainingTextRun):
(WebCore::TextIterator::handleTextNodeFirstLetter):
* editing/TextIterator.h:
* layout/integration/InlineIteratorBoxLegacyPath.h:
(WebCore::InlineIterator::BoxLegacyPath::traverseNextTextBox):
(WebCore::InlineIterator::BoxLegacyPath::traverseNextTextBoxInTextOrder): Deleted.
* layout/integration/InlineIteratorBoxModernPath.h:
(WebCore::InlineIterator::BoxModernPath::traverseNextTextBoxInTextOrder): Deleted.
* layout/integration/InlineIteratorTextBox.cpp:
(WebCore::InlineIterator::firstTextBoxInLogicalOrderFor):
(WebCore::InlineIterator::nextTextBoxInLogicalOrder):

Traverse using free functions instead of members.

(WebCore::InlineIterator::TextBox::nextTextBoxInTextOrder const): Deleted.
(WebCore::InlineIterator::TextBoxIterator::traverseNextTextBoxInTextOrder): Deleted.
(WebCore::InlineIterator::firstTextBoxInTextOrderFor): Deleted.
* layout/integration/InlineIteratorTextBox.h:
* rendering/LegacyInlineTextBox.h:
(WebCore::LegacyInlineTextBox::compareByStart): Deleted.
* rendering/RenderText.cpp:
(WebCore::containsOffset):

Modified Paths

Diff

Modified: trunk/Source/WebCore/ChangeLog (284111 => 284112)


--- trunk/Source/WebCore/ChangeLog	2021-10-13 18:02:14 UTC (rev 284111)
+++ trunk/Source/WebCore/ChangeLog	2021-10-13 18:02:22 UTC (rev 284112)
@@ -1,5 +1,49 @@
 2021-10-13  Antti Koivisto  <[email protected]>
 
+        [LFC][Integration] Move text box logical order cache to the caller
+        https://bugs.webkit.org/show_bug.cgi?id=231669
+
+        Reviewed by Alan Bujtas.
+
+        Don't maintain this rarely used cache internally in the iterator. Instead move it to the caller.
+
+        Also make the code non-legacy specific so it will work with future IFC BiDi.
+
+        * dom/Position.cpp:
+        (WebCore::Position::upstream const):
+        (WebCore::Position::downstream const):
+        (WebCore::searchAheadForBetterMatch):
+        * editing/CompositeEditCommand.cpp:
+        (WebCore::CompositeEditCommand::deleteInsignificantText):
+        * editing/TextIterator.cpp:
+        (WebCore::TextIterator::advance):
+        (WebCore::TextIterator::handleTextNode):
+        (WebCore::TextIterator::handleTextRun):
+        (WebCore::TextIterator::revertToRemainingTextRun):
+        (WebCore::TextIterator::handleTextNodeFirstLetter):
+        * editing/TextIterator.h:
+        * layout/integration/InlineIteratorBoxLegacyPath.h:
+        (WebCore::InlineIterator::BoxLegacyPath::traverseNextTextBox):
+        (WebCore::InlineIterator::BoxLegacyPath::traverseNextTextBoxInTextOrder): Deleted.
+        * layout/integration/InlineIteratorBoxModernPath.h:
+        (WebCore::InlineIterator::BoxModernPath::traverseNextTextBoxInTextOrder): Deleted.
+        * layout/integration/InlineIteratorTextBox.cpp:
+        (WebCore::InlineIterator::firstTextBoxInLogicalOrderFor):
+        (WebCore::InlineIterator::nextTextBoxInLogicalOrder):
+
+        Traverse using free functions instead of members.
+
+        (WebCore::InlineIterator::TextBox::nextTextBoxInTextOrder const): Deleted.
+        (WebCore::InlineIterator::TextBoxIterator::traverseNextTextBoxInTextOrder): Deleted.
+        (WebCore::InlineIterator::firstTextBoxInTextOrderFor): Deleted.
+        * layout/integration/InlineIteratorTextBox.h:
+        * rendering/LegacyInlineTextBox.h:
+        (WebCore::LegacyInlineTextBox::compareByStart): Deleted.
+        * rendering/RenderText.cpp:
+        (WebCore::containsOffset):
+
+2021-10-13  Antti Koivisto  <[email protected]>
+
         [LFC][Integration] Add concept of integration root and stop using InitialContainingBlock
         https://bugs.webkit.org/show_bug.cgi?id=231662
 

Modified: trunk/Source/WebCore/dom/Position.cpp (284111 => 284112)


--- trunk/Source/WebCore/dom/Position.cpp	2021-10-13 18:02:14 UTC (rev 284111)
+++ trunk/Source/WebCore/dom/Position.cpp	2021-10-13 18:02:22 UTC (rev 284112)
@@ -740,7 +740,7 @@
         if (is<RenderText>(*renderer)) {
             auto& textRenderer = downcast<RenderText>(*renderer);
 
-            auto firstTextRun = InlineIterator::firstTextBoxInTextOrderFor(textRenderer);
+            auto [firstTextRun, orderCache] = InlineIterator::firstTextBoxInLogicalOrderFor(textRenderer);
             if (!firstTextRun)
                 continue;
 
@@ -758,7 +758,7 @@
                 if (textOffset > run->start() && textOffset <= run->end())
                     return currentPosition;
 
-                auto nextRun = run->nextTextBoxInTextOrder();
+                auto nextRun = InlineIterator::nextTextBoxInLogicalOrder(run, orderCache);
                 if (textOffset == run->end() + 1 && nextRun && run->line() != nextRun->line())
                     return currentPosition;
 
@@ -847,7 +847,7 @@
         if (is<RenderText>(*renderer)) {
             auto& textRenderer = downcast<RenderText>(*renderer);
 
-            auto firstTextRun = InlineIterator::firstTextBoxInTextOrderFor(textRenderer);
+            auto [firstTextRun, orderCache] = InlineIterator::firstTextBoxInLogicalOrderFor(textRenderer);
             if (!firstTextRun)
                 continue;
 
@@ -864,7 +864,7 @@
                 if (textOffset >= run->start() && textOffset < run->end())
                     return currentPosition;
 
-                auto nextRun = run->nextTextBoxInTextOrder();
+                auto nextRun = InlineIterator::nextTextBoxInLogicalOrder(run, orderCache);
                 if (textOffset == run->end() && nextRun && run->line() != nextRun->line())
                     return currentPosition;
 
@@ -1173,7 +1173,7 @@
         if (isNonTextLeafChild(*next))
             return { };
         if (is<RenderText>(*next)) {
-            if (auto run = InlineIterator::firstTextBoxInTextOrderFor(downcast<RenderText>(*next)))
+            if (auto [run, orderCache] = InlineIterator::firstTextBoxInLogicalOrderFor(downcast<RenderText>(*next)); run)
                 return run;
         }
     }

Modified: trunk/Source/WebCore/editing/CompositeEditCommand.cpp (284111 => 284112)


--- trunk/Source/WebCore/editing/CompositeEditCommand.cpp	2021-10-13 18:02:14 UTC (rev 284111)
+++ trunk/Source/WebCore/editing/CompositeEditCommand.cpp	2021-10-13 18:02:22 UTC (rev 284112)
@@ -1016,7 +1016,7 @@
         if (!textRenderer)
             return;
 
-        auto run = InlineIterator::firstTextBoxInTextOrderFor(*textRenderer);
+        auto [run, orderCache] = InlineIterator::firstTextBoxInLogicalOrderFor(*textRenderer);
         if (!run) {
             wholeTextNodeIsEmpty = true;
             return;
@@ -1051,7 +1051,7 @@
 
             previousRun = run;
             if (run)
-                run.traverseNextTextBoxInTextOrder();
+                run = InlineIterator::nextTextBoxInLogicalOrder(run, orderCache);
         }
     };
     determineRemovalMode();

Modified: trunk/Source/WebCore/editing/TextIterator.cpp (284111 => 284112)


--- trunk/Source/WebCore/editing/TextIterator.cpp	2021-10-13 18:02:14 UTC (rev 284111)
+++ trunk/Source/WebCore/editing/TextIterator.cpp	2021-10-13 18:02:22 UTC (rev 284112)
@@ -438,12 +438,9 @@
         return;
     }
 
-    if (!m_textRun && m_remainingTextRun) {
-        m_textRun = m_remainingTextRun;
-        m_remainingTextRun = { };
-        m_firstLetterText = { };
-        m_offset = 0;
-    }
+    if (!m_textRun && m_remainingTextRun)
+        revertToRemainingTextRun();
+
     // handle remembered text box
     if (m_textRun) {
         handleTextRun();
@@ -581,7 +578,7 @@
         return true;
     }
 
-    m_textRun = InlineIterator::firstTextBoxInTextOrderFor(renderer);
+    std::tie(m_textRun, m_textRunLogicalOrderCache) = InlineIterator::firstTextBoxInLogicalOrderFor(renderer);
 
     bool shouldHandleFirstLetter = !m_handledFirstLetter && is<RenderTextFragment>(renderer) && !m_offset;
     if (shouldHandleFirstLetter)
@@ -608,7 +605,7 @@
         return;
     }
 
-    auto firstTextRun = InlineIterator::firstTextBoxInTextOrderFor(renderer);
+    auto [firstTextRun, orderCache] = InlineIterator::firstTextBoxInLogicalOrderFor(renderer);
 
     String rendererText = renderer.text();
     unsigned start = m_offset;
@@ -633,8 +630,7 @@
         unsigned runEnd = std::min(textRunEnd, end);
         
         // Determine what the next text run will be, but don't advance yet
-        auto nextTextRun = m_textRun;
-        nextTextRun.traverseNextTextBoxInTextOrder();
+        auto nextTextRun = InlineIterator::nextTextBoxInLogicalOrder(m_textRun, m_textRunLogicalOrderCache);
 
         if (runStart < runEnd) {
             auto isNewlineOrTab = [&](UChar character) {
@@ -677,14 +673,22 @@
         m_textRun = nextTextRun;
     }
     if (!m_textRun && m_remainingTextRun) {
-        m_textRun = m_remainingTextRun;
-        m_remainingTextRun = { };
-        m_firstLetterText = { };
-        m_offset = 0;
+        revertToRemainingTextRun();
         handleTextRun();
     }
 }
 
+void TextIterator::revertToRemainingTextRun()
+{
+    ASSERT(!m_textRun && m_remainingTextRun);
+
+    m_textRun = m_remainingTextRun;
+    m_textRunLogicalOrderCache = std::exchange(m_remainingTextRunLogicalOrderCache, { });
+    m_remainingTextRun = { };
+    m_firstLetterText = { };
+    m_offset = 0;
+}
+
 static inline RenderText* firstRenderTextInFirstLetter(RenderBoxModelObject* firstLetter)
 {
     if (!firstLetter)
@@ -702,7 +706,8 @@
         if (auto* firstLetterText = firstRenderTextInFirstLetter(firstLetter)) {
             m_handledFirstLetter = true;
             m_remainingTextRun = m_textRun;
-            m_textRun = InlineIterator::firstTextBoxInTextOrderFor(*firstLetterText);
+            m_remainingTextRunLogicalOrderCache = std::exchange(m_textRunLogicalOrderCache, { });
+            std::tie(m_textRun, m_textRunLogicalOrderCache) = InlineIterator::firstTextBoxInLogicalOrderFor(*firstLetterText);
             m_firstLetterText = firstLetterText;
         }
     }

Modified: trunk/Source/WebCore/editing/TextIterator.h (284111 => 284112)


--- trunk/Source/WebCore/editing/TextIterator.h	2021-10-13 18:02:14 UTC (rev 284111)
+++ trunk/Source/WebCore/editing/TextIterator.h	2021-10-13 18:02:22 UTC (rev 284112)
@@ -120,6 +120,7 @@
     void handleTextNodeFirstLetter(RenderTextFragment&);
     void emitCharacter(UChar, Node& characterNode, Node* offsetBaseNode, int textStartOffset, int textEndOffset);
     void emitText(Text& textNode, RenderText&, int textStartOffset, int textEndOffset);
+    void revertToRemainingTextRun();
 
     Node* baseNodeForEmittingNewLine() const;
 
@@ -150,9 +151,11 @@
     // Used when there is still some pending text from the current node; when these are false and null, we go back to normal iterating.
     Node* m_nodeForAdditionalNewline { nullptr };
     InlineIterator::TextBoxIterator m_textRun;
+    InlineIterator::LogicalOrderCache m_textRunLogicalOrderCache;
 
     // Used when iterating over :first-letter text to save pointer to remaining text box.
     InlineIterator::TextBoxIterator m_remainingTextRun;
+    InlineIterator::LogicalOrderCache m_remainingTextRunLogicalOrderCache;
 
     // Used to point to RenderText object for :first-letter.
     RenderText* m_firstLetterText { nullptr };

Modified: trunk/Source/WebCore/layout/integration/InlineIteratorBoxLegacyPath.h (284111 => 284112)


--- trunk/Source/WebCore/layout/integration/InlineIteratorBoxLegacyPath.h	2021-10-13 18:02:14 UTC (rev 284111)
+++ trunk/Source/WebCore/layout/integration/InlineIteratorBoxLegacyPath.h	2021-10-13 18:02:22 UTC (rev 284112)
@@ -87,15 +87,6 @@
     }
 
     void traverseNextTextBox() { m_inlineBox = inlineTextBox()->nextTextBox(); }
-    void traverseNextTextBoxInTextOrder()
-    {
-        if (!m_logicalOrderCache.isEmpty()) {
-            traverseNextInlineBoxInCacheOrder();
-            ASSERT(!m_inlineBox || is<LegacyInlineTextBox>(m_inlineBox));
-            return;
-        }
-        traverseNextTextBox();
-    }
 
     void traverseNextOnLine()
     {

Modified: trunk/Source/WebCore/layout/integration/InlineIteratorBoxModernPath.h (284111 => 284112)


--- trunk/Source/WebCore/layout/integration/InlineIteratorBoxModernPath.h	2021-10-13 18:02:14 UTC (rev 284111)
+++ trunk/Source/WebCore/layout/integration/InlineIteratorBoxModernPath.h	2021-10-13 18:02:22 UTC (rev 284112)
@@ -136,12 +136,6 @@
         ASSERT(atEnd() || box().text());
     }
 
-    void traverseNextTextBoxInTextOrder()
-    {
-        // FIXME: No RTL in LFC.
-        traverseNextTextBox();
-    }
-
     void traverseNextOnLine()
     {
         ASSERT(!atEnd());

Modified: trunk/Source/WebCore/layout/integration/InlineIteratorTextBox.cpp (284111 => 284112)


--- trunk/Source/WebCore/layout/integration/InlineIteratorTextBox.cpp	2021-10-13 18:02:14 UTC (rev 284111)
+++ trunk/Source/WebCore/layout/integration/InlineIteratorTextBox.cpp	2021-10-13 18:02:22 UTC (rev 284112)
@@ -38,11 +38,6 @@
     return TextBoxIterator(*this).traverseNextTextBox();
 }
 
-TextBoxIterator TextBox::nextTextBoxInTextOrder() const
-{
-    return TextBoxIterator(*this).traverseNextTextBoxInTextOrder();
-}
-
 LayoutRect TextBox::selectionRect(unsigned rangeStart, unsigned rangeEnd) const
 {
     auto [clampedStart, clampedEnd] = selectableRange().clamp(rangeStart, rangeEnd);
@@ -94,14 +89,6 @@
     return *this;
 }
 
-TextBoxIterator& TextBoxIterator::traverseNextTextBoxInTextOrder()
-{
-    WTF::switchOn(m_box.m_pathVariant, [](auto& path) {
-        path.traverseNextTextBoxInTextOrder();
-    });
-    return *this;
-}
-
 TextBoxIterator firstTextBoxFor(const RenderText& text)
 {
 #if ENABLE(LAYOUT_FORMATTING_CONTEXT)
@@ -112,20 +99,41 @@
     return { BoxLegacyPath { text.firstTextBox() } };
 }
 
-TextBoxIterator firstTextBoxInTextOrderFor(const RenderText& text)
+std::pair<TextBoxIterator, LogicalOrderCache> firstTextBoxInLogicalOrderFor(const RenderText& text)
 {
-    if (text.firstTextBox() && text.containsReversedText()) {
-        Vector<const LegacyInlineBox*> sortedTextBoxes;
-        for (auto* textBox = text.firstTextBox(); textBox; textBox = textBox->nextTextBox())
-            sortedTextBoxes.append(textBox);
-        std::sort(sortedTextBoxes.begin(), sortedTextBoxes.end(), [](auto* a, auto* b) {
-            return LegacyInlineTextBox::compareByStart(downcast<LegacyInlineTextBox>(a), downcast<LegacyInlineTextBox>(b));
-        });
-        auto* first = sortedTextBoxes[0];
-        return { BoxLegacyPath { first, WTFMove(sortedTextBoxes), 0 } };
+    if (!text.containsReversedText())
+        return { firstTextBoxFor(text), nullptr };
+
+    auto cache = WTF::makeUnique<LogicalOrderCacheData>();
+    for (auto textBox : textBoxesFor(text))
+        cache->boxes.append(textBox);
+
+    if (cache->boxes.isEmpty())
+        return { TextBoxIterator { }, nullptr };
+
+    std::sort(cache->boxes.begin(), cache->boxes.end(), [&](auto& a, auto& b) {
+        return a->start() < b->start();
+    });
+
+    return { cache->boxes[0], WTFMove(cache) };
+}
+
+TextBoxIterator nextTextBoxInLogicalOrder(const TextBoxIterator& textBox, LogicalOrderCache& cache)
+{
+    if (!cache)
+        return textBox->nextTextBox();
+
+    if (cache->index == cache->boxes.size() || cache->boxes[cache->index] != textBox) {
+        cache->index = cache->boxes.find(textBox);
+        ASSERT(cache->index != notFound);
     }
 
-    return firstTextBoxFor(text);
+    cache->index++;
+
+    if (cache->index < cache->boxes.size())
+        return cache->boxes[cache->index];
+
+    return { };
 }
 
 TextBoxIterator textBoxFor(const LegacyInlineTextBox* legacyInlineTextBox)

Modified: trunk/Source/WebCore/layout/integration/InlineIteratorTextBox.h (284111 => 284112)


--- trunk/Source/WebCore/layout/integration/InlineIteratorTextBox.h	2021-10-13 18:02:14 UTC (rev 284111)
+++ trunk/Source/WebCore/layout/integration/InlineIteratorTextBox.h	2021-10-13 18:02:22 UTC (rev 284112)
@@ -32,6 +32,9 @@
 
 namespace InlineIterator {
 
+struct LogicalOrderCacheData;
+using LogicalOrderCache = std::unique_ptr<LogicalOrderCacheData>;
+
 class TextBox : public Box {
 public:
     TextBox(PathVariant&&);
@@ -60,7 +63,6 @@
     const LegacyInlineTextBox* legacyInlineBox() const { return downcast<LegacyInlineTextBox>(Box::legacyInlineBox()); }
 
     TextBoxIterator nextTextBox() const;
-    TextBoxIterator nextTextBoxInTextOrder() const;
 };
 
 class TextBoxIterator : public LeafBoxIterator {
@@ -75,7 +77,6 @@
     const TextBox* operator->() const { return &get(); }
 
     TextBoxIterator& traverseNextTextBox();
-    TextBoxIterator& traverseNextTextBoxInTextOrder();
 
 private:
     BoxIterator& traverseNextOnLine() = delete;
@@ -103,7 +104,6 @@
 };
 
 TextBoxIterator firstTextBoxFor(const RenderText&);
-TextBoxIterator firstTextBoxInTextOrderFor(const RenderText&);
 TextBoxIterator textBoxFor(const LegacyInlineTextBox*);
 #if ENABLE(LAYOUT_FORMATTING_CONTEXT)
 TextBoxIterator textBoxFor(const LayoutIntegration::InlineContent&, const InlineDisplay::Box&);
@@ -111,6 +111,15 @@
 #endif
 TextBoxRange textBoxesFor(const RenderText&);
 
+struct LogicalOrderCacheData {
+    WTF_MAKE_STRUCT_FAST_ALLOCATED;
+    
+    Vector<TextBoxIterator> boxes;
+    size_t index { 0 };
+};
+std::pair<TextBoxIterator, LogicalOrderCache> firstTextBoxInLogicalOrderFor(const RenderText&);
+TextBoxIterator nextTextBoxInLogicalOrder(const TextBoxIterator&, LogicalOrderCache&);
+
 inline bool TextBox::hasHyphen() const
 {
     return WTF::switchOn(m_pathVariant, [](auto& path) {

Modified: trunk/Source/WebCore/rendering/LegacyInlineTextBox.h (284111 => 284112)


--- trunk/Source/WebCore/rendering/LegacyInlineTextBox.h	2021-10-13 18:02:14 UTC (rev 284111)
+++ trunk/Source/WebCore/rendering/LegacyInlineTextBox.h	2021-10-13 18:02:22 UTC (rev 284112)
@@ -88,8 +88,6 @@
     using LegacyInlineBox::forceLeftExpansion;
     using LegacyInlineBox::setForceLeftExpansion;
 
-    static inline bool compareByStart(const LegacyInlineTextBox* first, const LegacyInlineTextBox* second) { return first->start() < second->start(); }
-
     LayoutUnit baselinePosition(FontBaseline) const final;
     LayoutUnit lineHeight() const final;
 

Modified: trunk/Source/WebCore/rendering/RenderText.cpp (284111 => 284112)


--- trunk/Source/WebCore/rendering/RenderText.cpp	2021-10-13 18:02:14 UTC (rev 284111)
+++ trunk/Source/WebCore/rendering/RenderText.cpp	2021-10-13 18:02:22 UTC (rev 284112)
@@ -1712,7 +1712,7 @@
 enum class OffsetType { Character, Caret };
 static bool containsOffset(const RenderText& text, unsigned offset, OffsetType type)
 {
-    for (auto box = InlineIterator::firstTextBoxInTextOrderFor(text); box; box.traverseNextTextBoxInTextOrder()) {
+    for (auto [box, orderCache] = InlineIterator::firstTextBoxInLogicalOrderFor(text); box; box = InlineIterator::nextTextBoxInLogicalOrder(box, orderCache)) {
         auto start = box->start();
         if (offset < start)
             return false;
_______________________________________________
webkit-changes mailing list
[email protected]
https://lists.webkit.org/mailman/listinfo/webkit-changes

Reply via email to