Changeset 284315 in webkit
- Timestamp:
- Oct 16, 2021 5:39:37 AM (3 years ago)
- Location:
- trunk/Source/WebCore
- Files:
-
- 7 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/Source/WebCore/ChangeLog
r284314 r284315 1 2021-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 1 38 2021-10-16 Simon Fraser <simon.fraser@apple.com> 2 39 -
trunk/Source/WebCore/layout/integration/InlineIteratorLogicalOrderTraversal.cpp
r284269 r284315 93 93 { 94 94 auto cache = WTF::makeUnique<LineLogicalOrderCacheData>(); 95 95 96 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 }); 137 100 138 101 return cache; … … 179 142 updateLineLogicalOrderCacheIfNeeded(box, cache); 180 143 181 if (!cache)182 return box->nextOnLine();183 184 144 cache->index++; 185 145 … … 193 153 { 194 154 updateLineLogicalOrderCacheIfNeeded(box, cache); 195 196 if (!cache)197 return box->previousOnLine();198 155 199 156 if (!cache->index) -
trunk/Source/WebCore/layout/integration/InlineIteratorLogicalOrderTraversal.h
r284269 r284315 60 60 LeafBoxIterator lastLeafOnLineInLogicalOrderWithNode(const LineIterator&, LineLogicalOrderCache&); 61 61 62 template<typename ReverseFunction> 63 Vector<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 62 106 } 63 107 } -
trunk/Source/WebCore/rendering/LegacyInlineFlowBox.cpp
r283893 r284315 1296 1296 } 1297 1297 1298 void LegacyInlineFlowBox::collectLeafBoxesInLogicalOrder(Vector<LegacyInlineBox*>& leafBoxesInLogicalOrder, CustomInlineBoxRangeReverse customReverseImplementation, void* userData) const1299 {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 } else1345 std::reverse(first, last);1346 }1347 ++minLevel;1348 }1349 }1350 1351 1298 void LegacyInlineFlowBox::computeReplacedAndTextLineTopAndBottom(LayoutUnit& lineTop, LayoutUnit& lineBottom) const 1352 1299 { -
trunk/Source/WebCore/rendering/LegacyInlineFlowBox.h
r283893 r284315 94 94 LegacyInlineBox* lastLeafDescendant() const; 95 95 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 99 96 void setConstructed() final 100 97 { -
trunk/Source/WebCore/rendering/svg/SVGRootInlineBox.cpp
r283851 r284315 26 26 27 27 #include "GraphicsContext.h" 28 #include "InlineIteratorLogicalOrderTraversal.h" 28 29 #include "RenderSVGText.h" 29 30 #include "RenderSVGTextPath.h" … … 86 87 87 88 if (textRoot.needsReordering()) 88 reorderValueLists (layoutAttributes);89 reorderValueListsToLogicalOrder(layoutAttributes); 89 90 90 91 // Perform SVG text layout phase two (see SVGTextLayoutEngine for details). … … 271 272 } 272 273 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 274 static inline void reverseInlineBoxRangeAndValueListsIfNeeded(Vector<SVGTextLayoutAttributes*>& attributes, Vector<InlineIterator::LeafBoxIterator>::iterator first, Vector<InlineIterator::LeafBoxIterator>::iterator last) 275 { 278 276 // 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. 279 277 while (true) { 280 278 if (first == last || first == --last) 281 279 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; 285 284 *first = *last; 286 285 *last = temp; … … 289 288 } 290 289 291 auto& firstTextBox = downcast<SVGInlineTextBox>(* *first);292 auto& lastTextBox = downcast<SVGInlineTextBox>(* *last);290 auto& firstTextBox = downcast<SVGInlineTextBox>(*legacyFirst); 291 auto& lastTextBox = downcast<SVGInlineTextBox>(*legacyLast); 293 292 294 293 // Reordering is only necessary for BiDi text that is _absolutely_ positioned. … … 303 302 } 304 303 305 LegacyInlineBox*temp = *first;304 auto temp = *first; 306 305 *first = *last; 307 306 *last = temp; … … 311 310 } 312 311 313 void SVGRootInlineBox::reorderValueLists(Vector<SVGTextLayoutAttributes*>& attributes) 314 { 315 Vector<LegacyInlineBox*> leafBoxesInLogicalOrder; 316 collectLeafBoxesInLogicalOrder(leafBoxesInLogicalOrder, reverseInlineBoxRangeAndValueListsIfNeeded, &attributes); 312 void 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 317 320 } 318 321 -
trunk/Source/WebCore/rendering/svg/SVGRootInlineBox.h
r278405 r284315 51 51 private: 52 52 bool isSVGRootInlineBox() const override { return true; } 53 void reorderValueLists (Vector<SVGTextLayoutAttributes*>&);53 void reorderValueListsToLogicalOrder(Vector<SVGTextLayoutAttributes*>&); 54 54 void layoutCharactersInTextBoxes(LegacyInlineFlowBox*, SVGTextLayoutEngine&); 55 55 void layoutChildBoxes(LegacyInlineFlowBox*, FloatRect* = nullptr);
Note: See TracChangeset
for help on using the changeset viewer.