Changeset 284315 in webkit


Ignore:
Timestamp:
Oct 16, 2021 5:39:37 AM (3 years ago)
Author:
Antti Koivisto
Message:

Use inline iterator for SVG reverse BiDI reordering
https://bugs.webkit.org/show_bug.cgi?id=231858

Reviewed by Alan Bujtas.

Share code.

  • layout/integration/InlineIteratorLogicalOrderTraversal.cpp:

(WebCore::InlineIterator::makeLineLogicalOrderCache):
(WebCore::InlineIterator::nextLeafOnLineInLogicalOrder):
(WebCore::InlineIterator::previousLeafOnLineInLogicalOrder):

No need to test for the cache, it is always there.

  • layout/integration/InlineIteratorLogicalOrderTraversal.h:

(WebCore::InlineIterator::leafBoxesInLogicalOrder):

Make template and move to header.

  • rendering/LegacyInlineFlowBox.cpp:

(WebCore::LegacyInlineFlowBox::collectLeafBoxesInLogicalOrder const): Deleted.

Not needed anymore.

  • rendering/LegacyInlineFlowBox.h:
  • rendering/svg/SVGRootInlineBox.cpp:

(WebCore::SVGRootInlineBox::computePerCharacterLayoutInformation):
(WebCore::reverseInlineBoxRangeAndValueListsIfNeeded):
(WebCore::SVGRootInlineBox::reorderValueListsToLogicalOrder):
(WebCore::SVGRootInlineBox::reorderValueLists): Deleted.

Call the generic version.

  • rendering/svg/SVGRootInlineBox.h:
Location:
trunk/Source/WebCore
Files:
7 edited

Legend:

Unmodified
Added
Removed
  • trunk/Source/WebCore/ChangeLog

    r284314 r284315  
     12021-10-16  Antti Koivisto  <antti@apple.com>
     2
     3        Use inline iterator for SVG reverse BiDI reordering
     4        https://bugs.webkit.org/show_bug.cgi?id=231858
     5
     6        Reviewed by Alan Bujtas.
     7
     8        Share code.
     9
     10        * layout/integration/InlineIteratorLogicalOrderTraversal.cpp:
     11        (WebCore::InlineIterator::makeLineLogicalOrderCache):
     12        (WebCore::InlineIterator::nextLeafOnLineInLogicalOrder):
     13        (WebCore::InlineIterator::previousLeafOnLineInLogicalOrder):
     14
     15        No need to test for the cache, it is always there.
     16
     17        * layout/integration/InlineIteratorLogicalOrderTraversal.h:
     18        (WebCore::InlineIterator::leafBoxesInLogicalOrder):
     19
     20        Make template and move to header.
     21
     22        * rendering/LegacyInlineFlowBox.cpp:
     23        (WebCore::LegacyInlineFlowBox::collectLeafBoxesInLogicalOrder const): Deleted.
     24
     25        Not needed anymore.
     26
     27        * rendering/LegacyInlineFlowBox.h:
     28        * rendering/svg/SVGRootInlineBox.cpp:
     29        (WebCore::SVGRootInlineBox::computePerCharacterLayoutInformation):
     30        (WebCore::reverseInlineBoxRangeAndValueListsIfNeeded):
     31        (WebCore::SVGRootInlineBox::reorderValueListsToLogicalOrder):
     32        (WebCore::SVGRootInlineBox::reorderValueLists): Deleted.
     33
     34        Call the generic version.
     35
     36        * rendering/svg/SVGRootInlineBox.h:
     37
    1382021-10-16  Simon Fraser  <simon.fraser@apple.com>
    239
  • trunk/Source/WebCore/layout/integration/InlineIteratorLogicalOrderTraversal.cpp

    r284269 r284315  
    9393{
    9494    auto cache = WTF::makeUnique<LineLogicalOrderCacheData>();
     95
    9596    cache->line = line;
    96 
    97     auto& boxes = cache->boxes;
    98 
    99     unsigned char minLevel = 128;
    100     unsigned char maxLevel = 0;
    101 
    102     for (auto box = line->firstRun(); box; box = box.traverseNextOnLine()) {
    103         minLevel = std::min(minLevel, box->bidiLevel());
    104         maxLevel = std::max(maxLevel, box->bidiLevel());
    105         boxes.append(box);
    106     }
    107 
    108     if (!maxLevel)
    109         return cache;
    110 
    111     if (line->containingBlock().style().rtlOrdering() == Order::Visual)
    112         return cache;
    113 
    114     // Reverse of reordering of the line (L2 according to Bidi spec):
    115     // L2. From the highest level found in the text to the lowest odd level on each line,
    116     // reverse any contiguous sequence of characters that are at that level or higher.
    117 
    118     // Reversing the reordering of the line is only done up to the lowest odd level.
    119     if (!(minLevel % 2))
    120         ++minLevel;
    121 
    122     auto end = boxes.end();
    123     for (; minLevel <= maxLevel; ++minLevel) {
    124         auto box = boxes.begin();
    125         while (box < end) {
    126             while (box < end && (*box)->bidiLevel() < minLevel)
    127                 ++box;
    128 
    129             auto first = box;
    130             while (box < end && (*box)->bidiLevel() >= minLevel)
    131                 ++box;
    132 
    133             auto last = box;
    134             std::reverse(first, last);
    135         }
    136     }
     97    cache->boxes = leafBoxesInLogicalOrder(line, [](auto first, auto last) {
     98        std::reverse(first, last);
     99    });
    137100
    138101    return cache;
     
    179142    updateLineLogicalOrderCacheIfNeeded(box, cache);
    180143
    181     if (!cache)
    182         return box->nextOnLine();
    183 
    184144    cache->index++;
    185145
     
    193153{
    194154    updateLineLogicalOrderCacheIfNeeded(box, cache);
    195 
    196     if (!cache)
    197         return box->previousOnLine();
    198155
    199156    if (!cache->index)
  • trunk/Source/WebCore/layout/integration/InlineIteratorLogicalOrderTraversal.h

    r284269 r284315  
    6060LeafBoxIterator lastLeafOnLineInLogicalOrderWithNode(const LineIterator&, LineLogicalOrderCache&);
    6161
     62template<typename ReverseFunction>
     63Vector<LeafBoxIterator> leafBoxesInLogicalOrder(const LineIterator& line, ReverseFunction&& reverseFunction)
     64{
     65    Vector<LeafBoxIterator> boxes;
     66
     67    unsigned char minLevel = 128;
     68    unsigned char maxLevel = 0;
     69
     70    for (auto box = line->firstRun(); box; box = box.traverseNextOnLine()) {
     71        minLevel = std::min(minLevel, box->bidiLevel());
     72        maxLevel = std::max(maxLevel, box->bidiLevel());
     73        boxes.append(box);
     74    }
     75
     76    if (line->containingBlock().style().rtlOrdering() == Order::Visual)
     77        return boxes;
     78
     79    // Reverse of reordering of the line (L2 according to Bidi spec):
     80    // L2. From the highest level found in the text to the lowest odd level on each line,
     81    // reverse any contiguous sequence of characters that are at that level or higher.
     82
     83    // Reversing the reordering of the line is only done up to the lowest odd level.
     84    if (!(minLevel % 2))
     85        ++minLevel;
     86
     87    auto end = boxes.end();
     88    for (; minLevel <= maxLevel; ++minLevel) {
     89        auto box = boxes.begin();
     90        while (box < end) {
     91            while (box < end && (*box)->bidiLevel() < minLevel)
     92                ++box;
     93
     94            auto first = box;
     95            while (box < end && (*box)->bidiLevel() >= minLevel)
     96                ++box;
     97
     98            auto last = box;
     99            reverseFunction(first, last);
     100        }
     101    }
     102
     103    return boxes;
     104}
     105
    62106}
    63107}
  • trunk/Source/WebCore/rendering/LegacyInlineFlowBox.cpp

    r283893 r284315  
    12961296}
    12971297
    1298 void LegacyInlineFlowBox::collectLeafBoxesInLogicalOrder(Vector<LegacyInlineBox*>& leafBoxesInLogicalOrder, CustomInlineBoxRangeReverse customReverseImplementation, void* userData) const
    1299 {
    1300     LegacyInlineBox* leaf = firstLeafDescendant();
    1301 
    1302     // FIXME: The reordering code is a copy of parts from BidiResolver::createBidiRunsForLine, operating directly on InlineBoxes, instead of BidiRuns.
    1303     // Investigate on how this code could possibly be shared.
    1304     unsigned char minLevel = 128;
    1305     unsigned char maxLevel = 0;
    1306 
    1307     // First find highest and lowest levels, and initialize leafBoxesInLogicalOrder with the leaf boxes in visual order.
    1308     for (; leaf; leaf = leaf->nextLeafOnLine()) {
    1309         minLevel = std::min(minLevel, leaf->bidiLevel());
    1310         maxLevel = std::max(maxLevel, leaf->bidiLevel());
    1311         leafBoxesInLogicalOrder.append(leaf);
    1312     }
    1313 
    1314     if (renderer().style().rtlOrdering() == Order::Visual)
    1315         return;
    1316 
    1317     // Reverse of reordering of the line (L2 according to Bidi spec):
    1318     // L2. From the highest level found in the text to the lowest odd level on each line,
    1319     // reverse any contiguous sequence of characters that are at that level or higher.
    1320 
    1321     // Reversing the reordering of the line is only done up to the lowest odd level.
    1322     if (!(minLevel % 2))
    1323         ++minLevel;
    1324 
    1325     Vector<LegacyInlineBox*>::iterator end = leafBoxesInLogicalOrder.end();
    1326     while (minLevel <= maxLevel) {
    1327         Vector<LegacyInlineBox*>::iterator it = leafBoxesInLogicalOrder.begin();
    1328         while (it != end) {
    1329             while (it != end) {
    1330                 if ((*it)->bidiLevel() >= minLevel)
    1331                     break;
    1332                 ++it;
    1333             }
    1334             Vector<LegacyInlineBox*>::iterator first = it;
    1335             while (it != end) {
    1336                 if ((*it)->bidiLevel() < minLevel)
    1337                     break;
    1338                 ++it;
    1339             }
    1340             Vector<LegacyInlineBox*>::iterator last = it;
    1341             if (customReverseImplementation) {
    1342                 ASSERT(userData);
    1343                 (*customReverseImplementation)(userData, first, last);
    1344             } else
    1345                 std::reverse(first, last);
    1346         }               
    1347         ++minLevel;
    1348     }
    1349 }
    1350 
    13511298void LegacyInlineFlowBox::computeReplacedAndTextLineTopAndBottom(LayoutUnit& lineTop, LayoutUnit& lineBottom) const
    13521299{
  • trunk/Source/WebCore/rendering/LegacyInlineFlowBox.h

    r283893 r284315  
    9494    LegacyInlineBox* lastLeafDescendant() const;
    9595
    96     typedef void (*CustomInlineBoxRangeReverse)(void* userData, Vector<LegacyInlineBox*>::iterator first, Vector<LegacyInlineBox*>::iterator last);
    97     void collectLeafBoxesInLogicalOrder(Vector<LegacyInlineBox*>&, CustomInlineBoxRangeReverse customReverseImplementation = nullptr, void* userData = nullptr) const;
    98 
    9996    void setConstructed() final
    10097    {
  • trunk/Source/WebCore/rendering/svg/SVGRootInlineBox.cpp

    r283851 r284315  
    2626
    2727#include "GraphicsContext.h"
     28#include "InlineIteratorLogicalOrderTraversal.h"
    2829#include "RenderSVGText.h"
    2930#include "RenderSVGTextPath.h"
     
    8687
    8788    if (textRoot.needsReordering())
    88         reorderValueLists(layoutAttributes);
     89        reorderValueListsToLogicalOrder(layoutAttributes);
    8990
    9091    // Perform SVG text layout phase two (see SVGTextLayoutEngine for details).
     
    271272}
    272273
    273 static inline void reverseInlineBoxRangeAndValueListsIfNeeded(void* userData, Vector<LegacyInlineBox*>::iterator first, Vector<LegacyInlineBox*>::iterator last)
    274 {
    275     ASSERT(userData);
    276     Vector<SVGTextLayoutAttributes*>& attributes = *reinterpret_cast<Vector<SVGTextLayoutAttributes*>*>(userData);
    277 
     274static inline void reverseInlineBoxRangeAndValueListsIfNeeded(Vector<SVGTextLayoutAttributes*>& attributes, Vector<InlineIterator::LeafBoxIterator>::iterator first, Vector<InlineIterator::LeafBoxIterator>::iterator last)
     275{
    278276    // This is a copy of std::reverse(first, last). It additionally assures that the metrics map within the renderers belonging to the InlineBoxes are reordered as well.
    279277    while (true)  {
    280278        if (first == last || first == --last)
    281279            return;
    282 
    283         if (!is<SVGInlineTextBox>(**last) || !is<SVGInlineTextBox>(**first)) {
    284             LegacyInlineBox* temp = *first;
     280        auto* legacyFirst = (*first)->legacyInlineBox();
     281        auto* legacyLast = (*last)->legacyInlineBox();
     282        if (!is<SVGInlineTextBox>(legacyFirst) || !is<SVGInlineTextBox>(legacyLast)) {
     283            auto temp = *first;
    285284            *first = *last;
    286285            *last = temp;
     
    289288        }
    290289
    291         auto& firstTextBox = downcast<SVGInlineTextBox>(**first);
    292         auto& lastTextBox = downcast<SVGInlineTextBox>(**last);
     290        auto& firstTextBox = downcast<SVGInlineTextBox>(*legacyFirst);
     291        auto& lastTextBox = downcast<SVGInlineTextBox>(*legacyLast);
    293292
    294293        // Reordering is only necessary for BiDi text that is _absolutely_ positioned.
     
    303302        }
    304303
    305         LegacyInlineBox* temp = *first;
     304        auto temp = *first;
    306305        *first = *last;
    307306        *last = temp;
     
    311310}
    312311
    313 void SVGRootInlineBox::reorderValueLists(Vector<SVGTextLayoutAttributes*>& attributes)
    314 {
    315     Vector<LegacyInlineBox*> leafBoxesInLogicalOrder;
    316     collectLeafBoxesInLogicalOrder(leafBoxesInLogicalOrder, reverseInlineBoxRangeAndValueListsIfNeeded, &attributes);
     312void SVGRootInlineBox::reorderValueListsToLogicalOrder(Vector<SVGTextLayoutAttributes*>& attributes)
     313{
     314    auto line = InlineIterator::LineIterator(this);
     315
     316    InlineIterator::leafBoxesInLogicalOrder(line, [&](auto first, auto last) {
     317        reverseInlineBoxRangeAndValueListsIfNeeded(attributes, first, last);
     318    });
     319
    317320}
    318321
  • trunk/Source/WebCore/rendering/svg/SVGRootInlineBox.h

    r278405 r284315  
    5151private:
    5252    bool isSVGRootInlineBox() const override { return true; }
    53     void reorderValueLists(Vector<SVGTextLayoutAttributes*>&);
     53    void reorderValueListsToLogicalOrder(Vector<SVGTextLayoutAttributes*>&);
    5454    void layoutCharactersInTextBoxes(LegacyInlineFlowBox*, SVGTextLayoutEngine&);
    5555    void layoutChildBoxes(LegacyInlineFlowBox*, FloatRect* = nullptr);
Note: See TracChangeset for help on using the changeset viewer.