Diff
Modified: trunk/Source/WebCore/ChangeLog (284268 => 284269)
--- trunk/Source/WebCore/ChangeLog 2021-10-15 20:25:11 UTC (rev 284268)
+++ trunk/Source/WebCore/ChangeLog 2021-10-15 20:29:15 UTC (rev 284269)
@@ -1,3 +1,88 @@
+2021-10-15 Antti Koivisto <[email protected]>
+
+ [LFC][Integration] Factor line logical order traversal out of iterator
+ https://bugs.webkit.org/show_bug.cgi?id=231800
+
+ Reviewed by Alan Bujtas.
+
+ Similar to text logical order traversal, use standalone traversal functions with order cache
+ owned by the caller.
+
+ Make the code generic so it will work with IFC BiDi.
+
+ Factor all traversal functions to a file of their own, InlineIteratorLogicalOrderTraversal.h/cpp.
+
+ * Headers.cmake:
+ * Sources.txt:
+ * WebCore.xcodeproj/project.pbxproj:
+ * dom/Position.cpp:
+ * editing/CompositeEditCommand.cpp:
+ * editing/TextIterator.h:
+ * editing/VisiblePosition.cpp:
+ (WebCore::VisiblePosition::leftVisuallyDistinctCandidate const):
+ (WebCore::VisiblePosition::rightVisuallyDistinctCandidate const):
+ * editing/VisibleUnits.cpp:
+ (WebCore::previousTextOrLineBreakRun):
+ (WebCore::nextTextOrLineBreakRun):
+ (WebCore::startTextOrLineBreakRun):
+ (WebCore::endTextOrLineBreakRun):
+ (WebCore::logicallyPreviousRun):
+ (WebCore::logicallyNextRun):
+ (WebCore::wordBreakIteratorForMinOffsetBoundary):
+ (WebCore::wordBreakIteratorForMaxOffsetBoundary):
+ (WebCore::startPositionForLine):
+ (WebCore::endPositionForLine):
+ * layout/integration/InlineIteratorBox.cpp:
+ (WebCore::InlineIterator::LeafBoxIterator::traversePreviousOnLineIgnoringLineBreak):
+ (WebCore::InlineIterator::LeafBoxIterator::traverseNextOnLineInLogicalOrder): Deleted.
+ (WebCore::InlineIterator::LeafBoxIterator::traversePreviousOnLineInLogicalOrder): Deleted.
+ * layout/integration/InlineIteratorBox.h:
+ (WebCore::InlineIterator::BoxIterator::BoxIterator):
+ * layout/integration/InlineIteratorBoxLegacyPath.h:
+ (WebCore::InlineIterator::BoxLegacyPath::BoxLegacyPath):
+ (WebCore::InlineIterator::BoxLegacyPath::traverseNextOnLineInLogicalOrder): Deleted.
+ (WebCore::InlineIterator::BoxLegacyPath::traversePreviousOnLineInLogicalOrder): Deleted.
+ (WebCore::InlineIterator::BoxLegacyPath::initializeLogicalOrderCacheForLine): Deleted.
+ (WebCore::InlineIterator::BoxLegacyPath::traverseNextInlineBoxInCacheOrder): Deleted.
+ (WebCore::InlineIterator::BoxLegacyPath::traversePreviousInlineBoxInCacheOrder): Deleted.
+ * layout/integration/InlineIteratorBoxModernPath.h:
+ (WebCore::InlineIterator::BoxModernPath::traverseNextOnLineInLogicalOrder): Deleted.
+ (WebCore::InlineIterator::BoxModernPath::traversePreviousOnLineInLogicalOrder): Deleted.
+ * layout/integration/InlineIteratorLine.cpp:
+ (WebCore::InlineIterator::Line::logicalStartRun const): Deleted.
+ (WebCore::InlineIterator::Line::logicalEndRun const): Deleted.
+ (WebCore::InlineIterator::Line::logicalStartRunWithNode const): Deleted.
+ (WebCore::InlineIterator::Line::logicalEndRunWithNode const): Deleted.
+ * layout/integration/InlineIteratorLine.h:
+ * layout/integration/InlineIteratorLineLegacyPath.h:
+ (WebCore::InlineIterator::LineIteratorLegacyPath::logicalStartRun const): Deleted.
+ (WebCore::InlineIterator::LineIteratorLegacyPath::logicalEndRun const): Deleted.
+ * layout/integration/InlineIteratorLineModernPath.h:
+ (WebCore::InlineIterator::LineIteratorModernPath::logicalStartRun const): Deleted.
+ (WebCore::InlineIterator::LineIteratorModernPath::logicalEndRun const): Deleted.
+ * layout/integration/InlineIteratorLogicalOrderTraversal.cpp: Added.
+ (WebCore::InlineIterator::makeTextLogicalOrderCacheIfNeeded):
+ (WebCore::InlineIterator::updateTextLogicalOrderCacheIfNeeded):
+ (WebCore::InlineIterator::firstTextBoxInLogicalOrderFor):
+ (WebCore::InlineIterator::nextTextBoxInLogicalOrder):
+ (WebCore::InlineIterator::makeLineLogicalOrderCacheIfNeeded):
+ (WebCore::InlineIterator::updateLineLogicalOrderCacheIfNeeded):
+ (WebCore::InlineIterator::firstLeafOnLineInLogicalOrder):
+ (WebCore::InlineIterator::lastLeafOnLineInLogicalOrder):
+ (WebCore::InlineIterator::nextLeafOnLineInLogicalOrder):
+ (WebCore::InlineIterator::previousLeafOnLineInLogicalOrder):
+ (WebCore::InlineIterator::firstLeafOnLineInLogicalOrderWithNode):
+ (WebCore::InlineIterator::lastLeafOnLineInLogicalOrderWithNode):
+ * layout/integration/InlineIteratorLogicalOrderTraversal.h: Added.
+ * layout/integration/InlineIteratorTextBox.cpp:
+ (WebCore::InlineIterator::firstTextBoxInLogicalOrderFor): Deleted.
+ (WebCore::InlineIterator::nextTextBoxInLogicalOrder): Deleted.
+ * layout/integration/InlineIteratorTextBox.h:
+ (): Deleted.
+ * rendering/RenderBlockFlow.cpp:
+ (WebCore::RenderBlockFlow::positionForPointWithInlineChildren):
+ * rendering/RenderText.cpp:
+
2021-10-15 Andres Gonzalez <[email protected]>
Calls to AXCoreObject::widget() have to be dispatch to the main thread in isolated tree mode.
Modified: trunk/Source/WebCore/Headers.cmake (284268 => 284269)
--- trunk/Source/WebCore/Headers.cmake 2021-10-15 20:25:11 UTC (rev 284268)
+++ trunk/Source/WebCore/Headers.cmake 2021-10-15 20:29:15 UTC (rev 284269)
@@ -807,6 +807,7 @@
layout/integration/InlineIteratorLine.h
layout/integration/InlineIteratorLineLegacyPath.h
layout/integration/InlineIteratorLineModernPath.h
+ layout/integration/InlineIteratorLogicalOrderTraversal.h
layout/integration/InlineIteratorTextBox.h
layout/integration/LayoutIntegrationInlineContent.h
layout/integration/LayoutIntegrationLine.h
Modified: trunk/Source/WebCore/Sources.txt (284268 => 284269)
--- trunk/Source/WebCore/Sources.txt 2021-10-15 20:25:11 UTC (rev 284268)
+++ trunk/Source/WebCore/Sources.txt 2021-10-15 20:29:15 UTC (rev 284269)
@@ -1522,6 +1522,7 @@
layout/integration/InlineIteratorBox.cpp
layout/integration/InlineIteratorInlineBox.cpp
layout/integration/InlineIteratorLine.cpp
+layout/integration/InlineIteratorLogicalOrderTraversal.cpp
layout/integration/InlineIteratorTextBox.cpp
layout/integration/LayoutIntegrationBoxTree.cpp
layout/integration/LayoutIntegrationCoverage.cpp
Modified: trunk/Source/WebCore/WebCore.xcodeproj/project.pbxproj (284268 => 284269)
--- trunk/Source/WebCore/WebCore.xcodeproj/project.pbxproj 2021-10-15 20:25:11 UTC (rev 284268)
+++ trunk/Source/WebCore/WebCore.xcodeproj/project.pbxproj 2021-10-15 20:29:15 UTC (rev 284269)
@@ -5252,6 +5252,7 @@
E415EB13270C351300E8DA1B /* InlineIteratorInlineBox.h in Headers */ = {isa = PBXBuildFile; fileRef = E415EB11270C351200E8DA1B /* InlineIteratorInlineBox.h */; };
E418025523D4549B00FFB071 /* LayoutIntegrationBoxTree.h in Headers */ = {isa = PBXBuildFile; fileRef = E418025323D4549A00FFB071 /* LayoutIntegrationBoxTree.h */; settings = {ATTRIBUTES = (Private, ); }; };
E419041F1CC6486B00C35F5D /* FontSelectorClient.h in Headers */ = {isa = PBXBuildFile; fileRef = E419041E1CC6486B00C35F5D /* FontSelectorClient.h */; settings = {ATTRIBUTES = (Private, ); }; };
+ E41ACC1627173402003E9157 /* InlineIteratorLogicalOrderTraversal.h in Headers */ = {isa = PBXBuildFile; fileRef = E41ACC1527173402003E9157 /* InlineIteratorLogicalOrderTraversal.h */; settings = {ATTRIBUTES = (Private, ); }; };
E42050172141901B0066EF3B /* ProcessWarming.h in Headers */ = {isa = PBXBuildFile; fileRef = E42050142141901A0066EF3B /* ProcessWarming.h */; settings = {ATTRIBUTES = (Private, ); }; };
E424A39E1330DF0100CF6DC9 /* LegacyTileGridTile.h in Headers */ = {isa = PBXBuildFile; fileRef = E424A39D1330DF0100CF6DC9 /* LegacyTileGridTile.h */; };
E425A49A18292B840020CFCF /* CollectionIndexCache.h in Headers */ = {isa = PBXBuildFile; fileRef = E425A49918292B840020CFCF /* CollectionIndexCache.h */; settings = {ATTRIBUTES = (Private, ); }; };
@@ -5350,9 +5351,9 @@
E4C91A0E1802343100A17F6D /* TextPaintStyle.h in Headers */ = {isa = PBXBuildFile; fileRef = E4C91A0D1802343100A17F6D /* TextPaintStyle.h */; };
E4C91A16180999F100A17F6D /* RenderTextLineBoxes.h in Headers */ = {isa = PBXBuildFile; fileRef = E4C91A15180999F100A17F6D /* RenderTextLineBoxes.h */; settings = {ATTRIBUTES = (Private, ); }; };
E4D33F3B252AEECD00837D05 /* InlineRunAndOffset.h in Headers */ = {isa = PBXBuildFile; fileRef = E4D33F39252AEECC00837D05 /* InlineRunAndOffset.h */; };
- E4D33F41252C4B8300837D05 /* InlineIteratorLine.h in Headers */ = {isa = PBXBuildFile; fileRef = E4D33F3F252C4B8200837D05 /* InlineIteratorLine.h */; };
- E4D33F44252C50E200837D05 /* InlineIteratorLineLegacyPath.h in Headers */ = {isa = PBXBuildFile; fileRef = E4D33F43252C50E200837D05 /* InlineIteratorLineLegacyPath.h */; };
- E4D33F46252C50FC00837D05 /* InlineIteratorLineModernPath.h in Headers */ = {isa = PBXBuildFile; fileRef = E4D33F45252C50FB00837D05 /* InlineIteratorLineModernPath.h */; };
+ E4D33F41252C4B8300837D05 /* InlineIteratorLine.h in Headers */ = {isa = PBXBuildFile; fileRef = E4D33F3F252C4B8200837D05 /* InlineIteratorLine.h */; settings = {ATTRIBUTES = (Private, ); }; };
+ E4D33F44252C50E200837D05 /* InlineIteratorLineLegacyPath.h in Headers */ = {isa = PBXBuildFile; fileRef = E4D33F43252C50E200837D05 /* InlineIteratorLineLegacyPath.h */; settings = {ATTRIBUTES = (Private, ); }; };
+ E4D33F46252C50FC00837D05 /* InlineIteratorLineModernPath.h in Headers */ = {isa = PBXBuildFile; fileRef = E4D33F45252C50FB00837D05 /* InlineIteratorLineModernPath.h */; settings = {ATTRIBUTES = (Private, ); }; };
E4D58EB517B4DBDC00CBDCA8 /* StyleResolveForDocument.h in Headers */ = {isa = PBXBuildFile; fileRef = E4D58EB317B4DBDC00CBDCA8 /* StyleResolveForDocument.h */; };
E4D58EB917B4ED8900CBDCA8 /* StyleFontSizeFunctions.h in Headers */ = {isa = PBXBuildFile; fileRef = E4D58EB717B4ED8900CBDCA8 /* StyleFontSizeFunctions.h */; };
E4D58EBB17B8F12800CBDCA8 /* ElementTraversal.h in Headers */ = {isa = PBXBuildFile; fileRef = E4D58EBA17B8F12800CBDCA8 /* ElementTraversal.h */; settings = {ATTRIBUTES = (Private, ); }; };
@@ -16534,6 +16535,8 @@
E418025323D4549A00FFB071 /* LayoutIntegrationBoxTree.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = LayoutIntegrationBoxTree.h; sourceTree = "<group>"; };
E418025623D454B500FFB071 /* LayoutIntegrationBoxTree.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = LayoutIntegrationBoxTree.cpp; sourceTree = "<group>"; };
E419041E1CC6486B00C35F5D /* FontSelectorClient.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = FontSelectorClient.h; sourceTree = "<group>"; };
+ E41ACC12271733F3003E9157 /* InlineIteratorLogicalOrderTraversal.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = InlineIteratorLogicalOrderTraversal.cpp; sourceTree = "<group>"; };
+ E41ACC1527173402003E9157 /* InlineIteratorLogicalOrderTraversal.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = InlineIteratorLogicalOrderTraversal.h; sourceTree = "<group>"; };
E41EA038119836DB00710BC5 /* CSSPropertyNames.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = CSSPropertyNames.cpp; path = DerivedSources/WebCore/CSSPropertyNames.cpp; sourceTree = BUILT_PRODUCTS_DIR; };
E41EA0391198374900710BC5 /* CSSValueKeywords.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = CSSValueKeywords.cpp; path = DerivedSources/WebCore/CSSValueKeywords.cpp; sourceTree = BUILT_PRODUCTS_DIR; };
E42050142141901A0066EF3B /* ProcessWarming.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ProcessWarming.h; sourceTree = "<group>"; };
@@ -29707,6 +29710,8 @@
E4D33F3F252C4B8200837D05 /* InlineIteratorLine.h */,
E4D33F43252C50E200837D05 /* InlineIteratorLineLegacyPath.h */,
E4D33F45252C50FB00837D05 /* InlineIteratorLineModernPath.h */,
+ E41ACC12271733F3003E9157 /* InlineIteratorLogicalOrderTraversal.cpp */,
+ E41ACC1527173402003E9157 /* InlineIteratorLogicalOrderTraversal.h */,
E47CEBDE2709916400B8D8F5 /* InlineIteratorTextBox.cpp */,
E47CEBE02709916D00B8D8F5 /* InlineIteratorTextBox.h */,
E418025623D454B500FFB071 /* LayoutIntegrationBoxTree.cpp */,
@@ -33248,6 +33253,7 @@
E4D33F41252C4B8300837D05 /* InlineIteratorLine.h in Headers */,
E4D33F44252C50E200837D05 /* InlineIteratorLineLegacyPath.h in Headers */,
E4D33F46252C50FC00837D05 /* InlineIteratorLineModernPath.h in Headers */,
+ E41ACC1627173402003E9157 /* InlineIteratorLogicalOrderTraversal.h in Headers */,
E47CEBE12709916D00B8D8F5 /* InlineIteratorTextBox.h in Headers */,
6FAAE71326A2814B00E07502 /* InlineLevelBox.h in Headers */,
6F0CD695229ED32700C5994E /* InlineLine.h in Headers */,
Modified: trunk/Source/WebCore/dom/Position.cpp (284268 => 284269)
--- trunk/Source/WebCore/dom/Position.cpp 2021-10-15 20:25:11 UTC (rev 284268)
+++ trunk/Source/WebCore/dom/Position.cpp 2021-10-15 20:29:15 UTC (rev 284269)
@@ -37,6 +37,7 @@
#include "HTMLParserIdioms.h"
#include "HTMLTableElement.h"
#include "InlineIteratorLine.h"
+#include "InlineIteratorLogicalOrderTraversal.h"
#include "InlineIteratorTextBox.h"
#include "InlineRunAndOffset.h"
#include "LegacyInlineTextBox.h"
Modified: trunk/Source/WebCore/editing/CompositeEditCommand.cpp (284268 => 284269)
--- trunk/Source/WebCore/editing/CompositeEditCommand.cpp 2021-10-15 20:25:11 UTC (rev 284268)
+++ trunk/Source/WebCore/editing/CompositeEditCommand.cpp 2021-10-15 20:29:15 UTC (rev 284269)
@@ -48,6 +48,7 @@
#include "HTMLNames.h"
#include "HTMLSpanElement.h"
#include "InlineIteratorBox.h"
+#include "InlineIteratorLogicalOrderTraversal.h"
#include "InsertIntoTextNodeCommand.h"
#include "InsertLineBreakCommand.h"
#include "InsertNodeBeforeCommand.h"
Modified: trunk/Source/WebCore/editing/TextIterator.h (284268 => 284269)
--- trunk/Source/WebCore/editing/TextIterator.h 2021-10-15 20:25:11 UTC (rev 284268)
+++ trunk/Source/WebCore/editing/TextIterator.h 2021-10-15 20:29:15 UTC (rev 284269)
@@ -27,6 +27,7 @@
#include "CharacterRange.h"
#include "FindOptions.h"
+#include "InlineIteratorLogicalOrderTraversal.h"
#include "InlineIteratorTextBox.h"
#include "SimpleRange.h"
#include "TextIteratorBehavior.h"
@@ -151,11 +152,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;
+ InlineIterator::TextLogicalOrderCache m_textRunLogicalOrderCache;
// Used when iterating over :first-letter text to save pointer to remaining text box.
InlineIterator::TextBoxIterator m_remainingTextRun;
- InlineIterator::LogicalOrderCache m_remainingTextRunLogicalOrderCache;
+ InlineIterator::TextLogicalOrderCache m_remainingTextRunLogicalOrderCache;
// Used to point to RenderText object for :first-letter.
RenderText* m_firstLetterText { nullptr };
Modified: trunk/Source/WebCore/editing/VisiblePosition.cpp (284268 => 284269)
--- trunk/Source/WebCore/editing/VisiblePosition.cpp 2021-10-15 20:25:11 UTC (rev 284268)
+++ trunk/Source/WebCore/editing/VisiblePosition.cpp 2021-10-15 20:29:15 UTC (rev 284269)
@@ -122,6 +122,8 @@
Position downstreamStart = p.downstream();
TextDirection primaryDirection = p.primaryDirection();
+ InlineIterator::LineLogicalOrderCache orderCache;
+
while (true) {
auto [run, offset] = p.inlineRunAndOffset(m_affinity, primaryDirection);
if (!run)
@@ -174,7 +176,9 @@
if (run->direction() == primaryDirection) {
if (!previousRun) {
- auto logicalStart = (primaryDirection == TextDirection::LTR) ? run->line()->logicalStartRunWithNode() : run->line()->logicalEndRunWithNode();
+ auto logicalStart = primaryDirection == TextDirection::LTR
+ ? InlineIterator::firstLeafOnLineInLogicalOrderWithNode(run->line(), orderCache)
+ : InlineIterator::lastLeafOnLineInLogicalOrderWithNode(run->line(), orderCache);
if (logicalStart) {
run = logicalStart;
renderer = &run->renderer();
@@ -284,6 +288,8 @@
Position downstreamStart = p.downstream();
TextDirection primaryDirection = p.primaryDirection();
+ InlineIterator::LineLogicalOrderCache orderCache;
+
while (true) {
auto [run, offset] = p.inlineRunAndOffset(m_affinity, primaryDirection);
if (!run)
@@ -336,7 +342,10 @@
if (run->direction() == primaryDirection) {
if (!nextRun) {
- auto logicalEnd = primaryDirection == TextDirection::LTR ? run->line()->logicalEndRunWithNode() : run->line()->logicalStartRunWithNode();
+ auto logicalEnd = primaryDirection == TextDirection::LTR
+ ? InlineIterator::lastLeafOnLineInLogicalOrderWithNode(run->line(), orderCache)
+ : InlineIterator::firstLeafOnLineInLogicalOrderWithNode(run->line(), orderCache);
+
if (logicalEnd) {
run = logicalEnd;
renderer = &run->renderer();
Modified: trunk/Source/WebCore/editing/VisibleUnits.cpp (284268 => 284269)
--- trunk/Source/WebCore/editing/VisibleUnits.cpp 2021-10-15 20:25:11 UTC (rev 284268)
+++ trunk/Source/WebCore/editing/VisibleUnits.cpp 2021-10-15 20:29:15 UTC (rev 284269)
@@ -33,6 +33,7 @@
#include "HTMLNames.h"
#include "InlineIteratorBox.h"
#include "InlineIteratorLine.h"
+#include "InlineIteratorLogicalOrderTraversal.h"
#include "InlineRunAndOffset.h"
#include "NodeTraversal.h"
#include "Range.h"
@@ -129,10 +130,10 @@
return run && (run->isText() || run->renderer().isBR());
}
-static InlineIterator::LeafBoxIterator previousTextOrLineBreakRun(InlineIterator::LeafBoxIterator run)
+static InlineIterator::LeafBoxIterator previousTextOrLineBreakRun(InlineIterator::LeafBoxIterator run, InlineIterator::LineLogicalOrderCache& orderCache)
{
while (run) {
- run.traversePreviousOnLineInLogicalOrder();
+ run = InlineIterator::previousLeafOnLineInLogicalOrder(run, orderCache);
if (isTextOrLineBreakRun(run))
return run;
}
@@ -139,10 +140,10 @@
return { };
}
-static InlineIterator::LeafBoxIterator nextTextOrLineBreakRun(InlineIterator::LeafBoxIterator run)
+static InlineIterator::LeafBoxIterator nextTextOrLineBreakRun(InlineIterator::LeafBoxIterator run, InlineIterator::LineLogicalOrderCache& orderCache)
{
while (run) {
- run.traverseNextOnLineInLogicalOrder();
+ run = InlineIterator::nextLeafOnLineInLogicalOrder(run, orderCache);
if (isTextOrLineBreakRun(run))
return run;
}
@@ -149,30 +150,30 @@
return { };
}
-static InlineIterator::LeafBoxIterator startTextOrLineBreakRun(InlineIterator::LineIterator line)
+static InlineIterator::LeafBoxIterator startTextOrLineBreakRun(InlineIterator::LineIterator line, InlineIterator::LineLogicalOrderCache& orderCache)
{
- auto run = line->logicalStartRun();
+ auto run = InlineIterator::firstLeafOnLineInLogicalOrder(line, orderCache);
if (isTextOrLineBreakRun(run))
return run;
- return nextTextOrLineBreakRun(run);
+ return nextTextOrLineBreakRun(run, orderCache);
}
-static InlineIterator::LeafBoxIterator endTextOrLineBreakRun(InlineIterator::LineIterator line)
+static InlineIterator::LeafBoxIterator endTextOrLineBreakRun(InlineIterator::LineIterator line, InlineIterator::LineLogicalOrderCache& orderCache)
{
- auto run = line->logicalEndRun();
+ auto run = InlineIterator::lastLeafOnLineInLogicalOrder(line, orderCache);
if (isTextOrLineBreakRun(run))
return run;
- return previousTextOrLineBreakRun(run);
+ return previousTextOrLineBreakRun(run, orderCache);
}
-static const InlineIterator::LeafBoxIterator logicallyPreviousRun(const VisiblePosition& visiblePosition, InlineIterator::LeafBoxIterator startRun, bool& previousBoxInDifferentLine)
+static const InlineIterator::LeafBoxIterator logicallyPreviousRun(const VisiblePosition& visiblePosition, InlineIterator::LeafBoxIterator startRun, InlineIterator::LineLogicalOrderCache& orderCache, bool& previousBoxInDifferentLine)
{
- if (auto previousRun = previousTextOrLineBreakRun(startRun))
+ if (auto previousRun = previousTextOrLineBreakRun(startRun, orderCache))
return previousRun;
if (auto previousLine = startRun->line()->previous()) {
// FIXME: Why isn't previousBoxInDifferentLine set here?
- if (auto previousRun = endTextOrLineBreakRun(previousLine))
+ if (auto previousRun = endTextOrLineBreakRun(previousLine, orderCache))
return previousRun;
}
@@ -191,26 +192,26 @@
break;
if (previousLine != startRun->line()) {
- if (auto previousRun = endTextOrLineBreakRun(previousLine)) {
+ if (auto previousRun = endTextOrLineBreakRun(previousLine, orderCache)) {
previousBoxInDifferentLine = true;
return previousRun;
}
}
- startRun = previousLine->logicalStartRun();
+ startRun = InlineIterator::firstLeafOnLineInLogicalOrder(previousLine, orderCache);
}
return { };
}
-static const InlineIterator::LeafBoxIterator logicallyNextRun(const VisiblePosition& visiblePosition, InlineIterator::LeafBoxIterator startRun, bool& nextBoxInDifferentLine)
+static const InlineIterator::LeafBoxIterator logicallyNextRun(const VisiblePosition& visiblePosition, InlineIterator::LeafBoxIterator startRun, InlineIterator::LineLogicalOrderCache& orderCache, bool& nextBoxInDifferentLine)
{
- if (auto nextRun = nextTextOrLineBreakRun(startRun))
+ if (auto nextRun = nextTextOrLineBreakRun(startRun, orderCache))
return nextRun;
if (auto nextLine = startRun->line()->next()) {
// FIXME: Why isn't previousBoxInDifferentLine set here?
- if (auto nextRun = startTextOrLineBreakRun(nextLine))
+ if (auto nextRun = startTextOrLineBreakRun(nextLine, orderCache))
return nextRun;
}
@@ -229,13 +230,13 @@
break;
if (nextLine != startRun->line()) {
- if (auto nextRun = startTextOrLineBreakRun(nextLine)) {
+ if (auto nextRun = startTextOrLineBreakRun(nextLine, orderCache)) {
nextBoxInDifferentLine = true;
return nextRun;
}
}
- startRun = nextLine->logicalEndRun();
+ startRun = InlineIterator::lastLeafOnLineInLogicalOrderWithNode(nextLine, orderCache);
}
return { };
}
@@ -245,11 +246,12 @@
{
previousRunInDifferentLine = false;
- auto previousRun = logicallyPreviousRun(visiblePosition, textRun, previousRunInDifferentLine);
+ InlineIterator::LineLogicalOrderCache orderCache;
+ auto previousRun = logicallyPreviousRun(visiblePosition, textRun, orderCache, previousRunInDifferentLine);
while (previousRun && !previousRun->isText()) {
ASSERT(previousRun->renderer().isBR());
previousRunInDifferentLine = true;
- previousRun = logicallyPreviousRun(visiblePosition, previousRun, previousRunInDifferentLine);
+ previousRun = logicallyPreviousRun(visiblePosition, previousRun, orderCache, previousRunInDifferentLine);
}
string.clear();
@@ -269,11 +271,12 @@
{
nextRunInDifferentLine = false;
- auto nextRun = logicallyNextRun(visiblePosition, textRun, nextRunInDifferentLine);
+ InlineIterator::LineLogicalOrderCache orderCache;
+ auto nextRun = logicallyNextRun(visiblePosition, textRun, orderCache, nextRunInDifferentLine);
while (nextRun && !nextRun->isText()) {
ASSERT(nextRun->renderer().isBR());
nextRunInDifferentLine = true;
- nextRun = logicallyNextRun(visiblePosition, nextRun, nextRunInDifferentLine);
+ nextRun = logicallyNextRun(visiblePosition, nextRun, orderCache, nextRunInDifferentLine);
}
string.clear();
@@ -746,8 +749,10 @@
return VisiblePosition();
}
+ InlineIterator::LineLogicalOrderCache orderCache;
+
Node* startNode = nullptr;
- auto startRun = mode == UseLogicalOrdering ? line->logicalStartRunWithNode() : line->firstRun();
+ auto startRun = mode == UseLogicalOrdering ? InlineIterator::firstLeafOnLineInLogicalOrderWithNode(line, orderCache) : line->firstRun();
// Generated content (e.g. list markers and CSS :before and :after pseudoelements) have no corresponding DOM element,
// and so cannot be represented by a VisiblePosition. Use whatever follows instead.
while (true) {
@@ -759,7 +764,7 @@
break;
if (mode == UseLogicalOrdering)
- startRun.traverseNextOnLineInLogicalOrder();
+ startRun = InlineIterator::nextLeafOnLineInLogicalOrder(startRun, orderCache);
else
startRun.traverseNextOnLine();
}
@@ -816,8 +821,10 @@
return VisiblePosition();
}
+ InlineIterator::LineLogicalOrderCache orderCache;
+
Node* endNode = nullptr;
- auto endRun = mode == UseLogicalOrdering ? line->logicalEndRunWithNode() : line->lastRun();
+ auto endRun = mode == UseLogicalOrdering ? InlineIterator::lastLeafOnLineInLogicalOrder(line, orderCache) : line->lastRun();
// Generated content (e.g. list markers and CSS :before and :after pseudoelements) have no corresponding DOM element,
// and so cannot be represented by a VisiblePosition. Use whatever precedes instead.
while (true) {
@@ -829,7 +836,7 @@
break;
if (mode == UseLogicalOrdering)
- endRun.traversePreviousOnLineInLogicalOrder();
+ endRun = InlineIterator::previousLeafOnLineInLogicalOrder(endRun, orderCache);
else
endRun.traversePreviousOnLine();
}
Modified: trunk/Source/WebCore/layout/integration/InlineIteratorBox.cpp (284268 => 284269)
--- trunk/Source/WebCore/layout/integration/InlineIteratorBox.cpp 2021-10-15 20:25:11 UTC (rev 284268)
+++ trunk/Source/WebCore/layout/integration/InlineIteratorBox.cpp 2021-10-15 20:29:15 UTC (rev 284269)
@@ -148,22 +148,6 @@
return *this;
}
-LeafBoxIterator& LeafBoxIterator::traverseNextOnLineInLogicalOrder()
-{
- WTF::switchOn(m_box.m_pathVariant, [](auto& path) {
- path.traverseNextOnLineInLogicalOrder();
- });
- return *this;
-}
-
-LeafBoxIterator& LeafBoxIterator::traversePreviousOnLineInLogicalOrder()
-{
- WTF::switchOn(m_box.m_pathVariant, [](auto& path) {
- path.traversePreviousOnLineInLogicalOrder();
- });
- return *this;
-}
-
LeafBoxIterator boxFor(const RenderLineBreak& renderer)
{
#if ENABLE(LAYOUT_FORMATTING_CONTEXT)
Modified: trunk/Source/WebCore/layout/integration/InlineIteratorBox.h (284268 => 284269)
--- trunk/Source/WebCore/layout/integration/InlineIteratorBox.h 2021-10-15 20:25:11 UTC (rev 284268)
+++ trunk/Source/WebCore/layout/integration/InlineIteratorBox.h 2021-10-15 20:29:15 UTC (rev 284269)
@@ -131,7 +131,7 @@
bool atEnd() const;
protected:
- BoxIterator() : m_box(BoxLegacyPath { nullptr, { } }) { };
+ BoxIterator() : m_box(BoxLegacyPath { nullptr }) { };
BoxIterator(Box::PathVariant&&);
BoxIterator(const Box&);
@@ -148,8 +148,6 @@
LeafBoxIterator& traversePreviousOnLine();
LeafBoxIterator& traverseNextOnLineIgnoringLineBreak();
LeafBoxIterator& traversePreviousOnLineIgnoringLineBreak();
- LeafBoxIterator& traverseNextOnLineInLogicalOrder();
- LeafBoxIterator& traversePreviousOnLineInLogicalOrder();
};
LeafBoxIterator boxFor(const RenderLineBreak&);
Modified: trunk/Source/WebCore/layout/integration/InlineIteratorBoxLegacyPath.h (284268 => 284269)
--- trunk/Source/WebCore/layout/integration/InlineIteratorBoxLegacyPath.h 2021-10-15 20:25:11 UTC (rev 284268)
+++ trunk/Source/WebCore/layout/integration/InlineIteratorBoxLegacyPath.h 2021-10-15 20:29:15 UTC (rev 284269)
@@ -37,22 +37,10 @@
class BoxLegacyPath {
public:
- BoxLegacyPath(const LegacyInlineBox* inlineBox, Vector<const LegacyInlineBox*>&& sortedInlineBoxes = { }, size_t sortedInlineBoxIndex = 0)
+ BoxLegacyPath(const LegacyInlineBox* inlineBox)
: m_inlineBox(inlineBox)
- , m_logicalOrderCache(WTFMove(sortedInlineBoxes))
- , m_logicalOrderCacheIndex(sortedInlineBoxIndex)
{ }
- enum class LogicalOrder { Start, End };
- BoxLegacyPath(const LegacyRootInlineBox& root, LogicalOrder order)
- : m_logicalOrderCache(inlineBoxesInLogicalOrder(root))
- {
- if (!m_logicalOrderCache.isEmpty()) {
- m_logicalOrderCacheIndex = order == LogicalOrder::Start ? 0 : m_logicalOrderCache.size() - 1;
- m_inlineBox = m_logicalOrderCache[m_logicalOrderCacheIndex];
- }
- }
-
bool isText() const { return m_inlineBox->isInlineTextBox(); }
bool isInlineBox() const { return m_inlineBox->isInlineFlowBox(); }
bool isRootInlineBox() const { return m_inlineBox->isRootInlineBox(); }
@@ -98,18 +86,6 @@
m_inlineBox = m_inlineBox->previousLeafOnLine();
}
- void traverseNextOnLineInLogicalOrder()
- {
- initializeLogicalOrderCacheForLine();
- traverseNextInlineBoxInCacheOrder();
- }
-
- void traversePreviousOnLineInLogicalOrder()
- {
- initializeLogicalOrderCacheForLine();
- traversePreviousInlineBoxInCacheOrder();
- }
-
void traverseNextInlineBox()
{
m_inlineBox = inlineFlowBox()->nextLineBox();
@@ -131,49 +107,8 @@
const LegacyInlineTextBox* inlineTextBox() const { return downcast<LegacyInlineTextBox>(m_inlineBox); }
const LegacyInlineFlowBox* inlineFlowBox() const { return downcast<LegacyInlineFlowBox>(m_inlineBox); }
- static Vector<const LegacyInlineBox*> inlineBoxesInLogicalOrder(const LegacyRootInlineBox& root)
- {
- Vector<LegacyInlineBox*> inlineBoxes;
- root.collectLeafBoxesInLogicalOrder(inlineBoxes);
- return reinterpret_cast<Vector<const LegacyInlineBox*>&>(inlineBoxes);
- }
- void initializeLogicalOrderCacheForLine()
- {
- if (!m_inlineBox || !m_logicalOrderCache.isEmpty())
- return;
- m_logicalOrderCache = inlineBoxesInLogicalOrder(m_inlineBox->root());
- for (m_logicalOrderCacheIndex = 0; m_logicalOrderCacheIndex < m_logicalOrderCache.size(); ++m_logicalOrderCacheIndex) {
- if (m_logicalOrderCache[m_logicalOrderCacheIndex] == m_inlineBox)
- return;
- }
- ASSERT_NOT_REACHED();
- }
-
- void traverseNextInlineBoxInCacheOrder();
- void traversePreviousInlineBoxInCacheOrder();
-
const LegacyInlineBox* m_inlineBox { nullptr };
- RefCountedArray<const LegacyInlineBox*> m_logicalOrderCache;
- size_t m_logicalOrderCacheIndex { 0 };
};
-
-inline void BoxLegacyPath::traverseNextInlineBoxInCacheOrder()
-{
- ASSERT(!m_logicalOrderCache.isEmpty());
- ++m_logicalOrderCacheIndex;
- m_inlineBox = m_logicalOrderCacheIndex < m_logicalOrderCache.size() ? m_logicalOrderCache[m_logicalOrderCacheIndex] : nullptr;
}
-
-inline void BoxLegacyPath::traversePreviousInlineBoxInCacheOrder()
-{
- ASSERT(!m_logicalOrderCache.isEmpty());
- if (!m_logicalOrderCacheIndex) {
- m_inlineBox = nullptr;
- return;
- }
- m_inlineBox = m_logicalOrderCache[--m_logicalOrderCacheIndex];
}
-
-}
-}
Modified: trunk/Source/WebCore/layout/integration/InlineIteratorBoxModernPath.h (284268 => 284269)
--- trunk/Source/WebCore/layout/integration/InlineIteratorBoxModernPath.h 2021-10-15 20:25:11 UTC (rev 284268)
+++ trunk/Source/WebCore/layout/integration/InlineIteratorBoxModernPath.h 2021-10-15 20:29:15 UTC (rev 284269)
@@ -160,16 +160,6 @@
setAtEnd();
}
- void traverseNextOnLineInLogicalOrder()
- {
- traverseNextOnLine();
- }
-
- void traversePreviousOnLineInLogicalOrder()
- {
- traversePreviousOnLine();
- }
-
void traverseNextInlineBox()
{
ASSERT(box().isInlineBox());
Modified: trunk/Source/WebCore/layout/integration/InlineIteratorLine.cpp (284268 => 284269)
--- trunk/Source/WebCore/layout/integration/InlineIteratorLine.cpp 2021-10-15 20:25:11 UTC (rev 284268)
+++ trunk/Source/WebCore/layout/integration/InlineIteratorLine.cpp 2021-10-15 20:29:15 UTC (rev 284269)
@@ -115,38 +115,6 @@
});
}
-LeafBoxIterator Line::logicalStartRun() const
-{
- return WTF::switchOn(m_pathVariant, [](auto& path) -> LeafBoxIterator {
- return { path.logicalStartRun() };
- });
-}
-
-LeafBoxIterator Line::logicalEndRun() const
-{
- return WTF::switchOn(m_pathVariant, [](auto& path) -> LeafBoxIterator {
- return { path.logicalEndRun() };
- });
-}
-
-LeafBoxIterator Line::logicalStartRunWithNode() const
-{
- for (auto run = logicalStartRun(); run; run.traverseNextOnLineInLogicalOrder()) {
- if (run->renderer().node())
- return run;
- }
- return { };
-}
-
-LeafBoxIterator Line::logicalEndRunWithNode() const
-{
- for (auto run = logicalEndRun(); run; run.traversePreviousOnLineInLogicalOrder()) {
- if (run->renderer().node())
- return run;
- }
- return { };
-}
-
LeafBoxIterator Line::closestRunForPoint(const IntPoint& pointInContents, bool editableOnly) const
{
return closestRunForLogicalLeftPosition(isHorizontal() ? pointInContents.x() : pointInContents.y(), editableOnly);
Modified: trunk/Source/WebCore/layout/integration/InlineIteratorLine.h (284268 => 284269)
--- trunk/Source/WebCore/layout/integration/InlineIteratorLine.h 2021-10-15 20:25:11 UTC (rev 284268)
+++ trunk/Source/WebCore/layout/integration/InlineIteratorLine.h 2021-10-15 20:29:15 UTC (rev 284269)
@@ -89,11 +89,6 @@
LeafBoxIterator closestRunForPoint(const IntPoint& pointInContents, bool editableOnly) const;
LeafBoxIterator closestRunForLogicalLeftPosition(int position, bool editableOnly = false) const;
-
- LeafBoxIterator logicalStartRun() const;
- LeafBoxIterator logicalEndRun() const;
- LeafBoxIterator logicalStartRunWithNode() const;
- LeafBoxIterator logicalEndRunWithNode() const;
LeafBoxIterator firstSelectedBox() const;
LeafBoxIterator lastSelectedBox() const;
Modified: trunk/Source/WebCore/layout/integration/InlineIteratorLineLegacyPath.h (284268 => 284269)
--- trunk/Source/WebCore/layout/integration/InlineIteratorLineLegacyPath.h 2021-10-15 20:25:11 UTC (rev 284268)
+++ trunk/Source/WebCore/layout/integration/InlineIteratorLineLegacyPath.h 2021-10-15 20:29:15 UTC (rev 284269)
@@ -85,17 +85,6 @@
return { m_rootInlineBox->lastLeafDescendant() };
}
-
- BoxLegacyPath logicalStartRun() const
- {
- return { *m_rootInlineBox, BoxLegacyPath::LogicalOrder::Start };
- }
-
- BoxLegacyPath logicalEndRun() const
- {
- return { *m_rootInlineBox, BoxLegacyPath::LogicalOrder::End };
- }
-
private:
const LegacyRootInlineBox* m_rootInlineBox;
};
Modified: trunk/Source/WebCore/layout/integration/InlineIteratorLineModernPath.h (284268 => 284269)
--- trunk/Source/WebCore/layout/integration/InlineIteratorLineModernPath.h 2021-10-15 20:25:11 UTC (rev 284268)
+++ trunk/Source/WebCore/layout/integration/InlineIteratorLineModernPath.h 2021-10-15 20:29:15 UTC (rev 284269)
@@ -116,16 +116,6 @@
return runIterator;
}
- BoxModernPath logicalStartRun() const
- {
- return firstRun();
- }
-
- BoxModernPath logicalEndRun() const
- {
- return lastRun();
- }
-
private:
void setAtEnd() { m_lineIndex = lines().size(); }
Added: trunk/Source/WebCore/layout/integration/InlineIteratorLogicalOrderTraversal.cpp (0 => 284269)
--- trunk/Source/WebCore/layout/integration/InlineIteratorLogicalOrderTraversal.cpp (rev 0)
+++ trunk/Source/WebCore/layout/integration/InlineIteratorLogicalOrderTraversal.cpp 2021-10-15 20:29:15 UTC (rev 284269)
@@ -0,0 +1,224 @@
+/*
+ * Copyright (C) 2021 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "config.h"
+#include "InlineIteratorLogicalOrderTraversal.h"
+
+#include "InlineIteratorLine.h"
+
+namespace WebCore {
+namespace InlineIterator {
+
+static TextLogicalOrderCache makeTextLogicalOrderCacheIfNeeded(const RenderText& text)
+{
+ if (!text.containsReversedText())
+ return { };
+
+ auto cache = WTF::makeUnique<TextLogicalOrderCacheData>();
+ for (auto textBox : textBoxesFor(text))
+ cache->boxes.append(textBox);
+
+ if (cache->boxes.isEmpty())
+ return nullptr;
+
+ std::sort(cache->boxes.begin(), cache->boxes.end(), [&](auto& a, auto& b) {
+ return a->start() < b->start();
+ });
+
+ return cache;
+}
+
+static void updateTextLogicalOrderCacheIfNeeded(const TextBoxIterator& textBox, TextLogicalOrderCache& cache)
+{
+ if (!cache && !(cache = makeTextLogicalOrderCacheIfNeeded(textBox->renderer())))
+ return;
+
+ if (cache->index < cache->boxes.size() && cache->boxes[cache->index] == textBox)
+ return;
+
+ cache->index = cache->boxes.find(textBox);
+
+ if (cache->index == notFound) {
+ cache = { };
+ updateTextLogicalOrderCacheIfNeeded(textBox, cache);
+ }
+}
+
+std::pair<TextBoxIterator, TextLogicalOrderCache> firstTextBoxInLogicalOrderFor(const RenderText& text)
+{
+ if (auto cache = makeTextLogicalOrderCacheIfNeeded(text))
+ return { cache->boxes.first(), WTFMove(cache) };
+
+ return { firstTextBoxFor(text), nullptr };
+}
+
+TextBoxIterator nextTextBoxInLogicalOrder(const TextBoxIterator& textBox, TextLogicalOrderCache& cache)
+{
+ updateTextLogicalOrderCacheIfNeeded(textBox, cache);
+
+ if (!cache)
+ return textBox->nextTextBox();
+
+ cache->index++;
+
+ if (cache->index < cache->boxes.size())
+ return cache->boxes[cache->index];
+
+ return { };
+}
+
+static LineLogicalOrderCache makeLineLogicalOrderCache(const LineIterator& line)
+{
+ auto cache = WTF::makeUnique<LineLogicalOrderCacheData>();
+ cache->line = line;
+
+ auto& boxes = cache->boxes;
+
+ unsigned char minLevel = 128;
+ unsigned char maxLevel = 0;
+
+ for (auto box = line->firstRun(); box; box = box.traverseNextOnLine()) {
+ minLevel = std::min(minLevel, box->bidiLevel());
+ maxLevel = std::max(maxLevel, box->bidiLevel());
+ boxes.append(box);
+ }
+
+ if (!maxLevel)
+ return cache;
+
+ if (line->containingBlock().style().rtlOrdering() == Order::Visual)
+ return cache;
+
+ // Reverse of reordering of the line (L2 according to Bidi spec):
+ // L2. From the highest level found in the text to the lowest odd level on each line,
+ // reverse any contiguous sequence of characters that are at that level or higher.
+
+ // Reversing the reordering of the line is only done up to the lowest odd level.
+ if (!(minLevel % 2))
+ ++minLevel;
+
+ auto end = boxes.end();
+ for (; minLevel <= maxLevel; ++minLevel) {
+ auto box = boxes.begin();
+ while (box < end) {
+ while (box < end && (*box)->bidiLevel() < minLevel)
+ ++box;
+
+ auto first = box;
+ while (box < end && (*box)->bidiLevel() >= minLevel)
+ ++box;
+
+ auto last = box;
+ std::reverse(first, last);
+ }
+ }
+
+ return cache;
+}
+
+static void updateLineLogicalOrderCacheIfNeeded(const LeafBoxIterator& box, LineLogicalOrderCache& cache)
+{
+ auto line = box->line();
+ if (!cache || cache->line != line)
+ cache = makeLineLogicalOrderCache(line);
+
+ if (cache->index < cache->boxes.size() && cache->boxes[cache->index] == box)
+ return;
+
+ cache->index = cache->boxes.find(box);
+
+ ASSERT(cache->index != notFound);
+}
+
+LeafBoxIterator firstLeafOnLineInLogicalOrder(const LineIterator& line, LineLogicalOrderCache& cache)
+{
+ cache = makeLineLogicalOrderCache(line);
+
+ if (cache->boxes.isEmpty())
+ return { };
+
+ cache->index = 0;
+ return cache->boxes.first();
+}
+
+LeafBoxIterator lastLeafOnLineInLogicalOrder(const LineIterator& line, LineLogicalOrderCache& cache)
+{
+ cache = makeLineLogicalOrderCache(line);
+
+ if (cache->boxes.isEmpty())
+ return { };
+
+ cache->index = cache->boxes.size() - 1;
+ return cache->boxes.last();
+}
+
+LeafBoxIterator nextLeafOnLineInLogicalOrder(const LeafBoxIterator& box, LineLogicalOrderCache& cache)
+{
+ updateLineLogicalOrderCacheIfNeeded(box, cache);
+
+ if (!cache)
+ return box->nextOnLine();
+
+ cache->index++;
+
+ if (cache->index < cache->boxes.size())
+ return cache->boxes[cache->index];
+
+ return { };
+}
+
+LeafBoxIterator previousLeafOnLineInLogicalOrder(const LeafBoxIterator& box, LineLogicalOrderCache& cache)
+{
+ updateLineLogicalOrderCacheIfNeeded(box, cache);
+
+ if (!cache)
+ return box->previousOnLine();
+
+ if (!cache->index)
+ return { };
+
+ cache->index--;
+
+ return cache->boxes[cache->index];
+}
+
+LeafBoxIterator firstLeafOnLineInLogicalOrderWithNode(const LineIterator& line, LineLogicalOrderCache& cache)
+{
+ auto box = firstLeafOnLineInLogicalOrder(line, cache);
+ while (box && !box->renderer().node())
+ box = nextLeafOnLineInLogicalOrder(box, cache);
+ return box;
+}
+
+LeafBoxIterator lastLeafOnLineInLogicalOrderWithNode(const LineIterator& line, LineLogicalOrderCache& cache)
+{
+ auto box = lastLeafOnLineInLogicalOrder(line, cache);
+ while (box && !box->renderer().node())
+ box = previousLeafOnLineInLogicalOrder(box, cache);
+ return box;
+}
+
+}
+}
Added: trunk/Source/WebCore/layout/integration/InlineIteratorLogicalOrderTraversal.h (0 => 284269)
--- trunk/Source/WebCore/layout/integration/InlineIteratorLogicalOrderTraversal.h (rev 0)
+++ trunk/Source/WebCore/layout/integration/InlineIteratorLogicalOrderTraversal.h 2021-10-15 20:29:15 UTC (rev 284269)
@@ -0,0 +1,63 @@
+/*
+ * Copyright (C) 2021 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#pragma once
+
+#include "InlineIteratorLine.h"
+#include "InlineIteratorTextBox.h"
+
+namespace WebCore {
+namespace InlineIterator {
+
+struct TextLogicalOrderCacheData {
+ WTF_MAKE_STRUCT_FAST_ALLOCATED;
+
+ Vector<TextBoxIterator> boxes;
+ size_t index { 0 };
+};
+using TextLogicalOrderCache = std::unique_ptr<TextLogicalOrderCacheData>;
+
+std::pair<TextBoxIterator, TextLogicalOrderCache> firstTextBoxInLogicalOrderFor(const RenderText&);
+TextBoxIterator nextTextBoxInLogicalOrder(const TextBoxIterator&, TextLogicalOrderCache&);
+
+struct LineLogicalOrderCacheData {
+ WTF_MAKE_STRUCT_FAST_ALLOCATED;
+
+ LineIterator line;
+ Vector<LeafBoxIterator> boxes;
+ size_t index { 0 };
+};
+using LineLogicalOrderCache = std::unique_ptr<LineLogicalOrderCacheData>;
+
+LeafBoxIterator firstLeafOnLineInLogicalOrder(const LineIterator&, LineLogicalOrderCache&);
+LeafBoxIterator lastLeafOnLineInLogicalOrder(const LineIterator&, LineLogicalOrderCache&);
+LeafBoxIterator nextLeafOnLineInLogicalOrder(const LeafBoxIterator&, LineLogicalOrderCache&);
+LeafBoxIterator previousLeafOnLineInLogicalOrder(const LeafBoxIterator&, LineLogicalOrderCache&);
+
+LeafBoxIterator firstLeafOnLineInLogicalOrderWithNode(const LineIterator&, LineLogicalOrderCache&);
+LeafBoxIterator lastLeafOnLineInLogicalOrderWithNode(const LineIterator&, LineLogicalOrderCache&);
+
+}
+}
Modified: trunk/Source/WebCore/layout/integration/InlineIteratorTextBox.cpp (284268 => 284269)
--- trunk/Source/WebCore/layout/integration/InlineIteratorTextBox.cpp 2021-10-15 20:25:11 UTC (rev 284268)
+++ trunk/Source/WebCore/layout/integration/InlineIteratorTextBox.cpp 2021-10-15 20:29:15 UTC (rev 284269)
@@ -99,43 +99,6 @@
return { BoxLegacyPath { text.firstTextBox() } };
}
-std::pair<TextBoxIterator, LogicalOrderCache> firstTextBoxInLogicalOrderFor(const RenderText& text)
-{
- 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);
- }
-
- cache->index++;
-
- if (cache->index < cache->boxes.size())
- return cache->boxes[cache->index];
-
- return { };
-}
-
TextBoxIterator textBoxFor(const LegacyInlineTextBox* legacyInlineTextBox)
{
return { BoxLegacyPath { legacyInlineTextBox } };
Modified: trunk/Source/WebCore/layout/integration/InlineIteratorTextBox.h (284268 => 284269)
--- trunk/Source/WebCore/layout/integration/InlineIteratorTextBox.h 2021-10-15 20:25:11 UTC (rev 284268)
+++ trunk/Source/WebCore/layout/integration/InlineIteratorTextBox.h 2021-10-15 20:29:15 UTC (rev 284269)
@@ -32,9 +32,6 @@
namespace InlineIterator {
-struct LogicalOrderCacheData;
-using LogicalOrderCache = std::unique_ptr<LogicalOrderCacheData>;
-
class TextBox : public Box {
public:
TextBox(PathVariant&&);
@@ -63,6 +60,7 @@
const LegacyInlineTextBox* legacyInlineBox() const { return downcast<LegacyInlineTextBox>(Box::legacyInlineBox()); }
TextBoxIterator nextTextBox() const;
+ TextBoxIterator previousTextBox() const;
};
class TextBoxIterator : public LeafBoxIterator {
@@ -83,8 +81,6 @@
BoxIterator& traversePreviousOnLine() = delete;
BoxIterator& traverseNextOnLineIgnoringLineBreak() = delete;
BoxIterator& traversePreviousOnLineIgnoringLineBreak() = delete;
- BoxIterator& traverseNextOnLineInLogicalOrder() = delete;
- BoxIterator& traversePreviousOnLineInLogicalOrder() = delete;
const TextBox& get() const { return downcast<TextBox>(m_box); }
};
@@ -111,15 +107,6 @@
#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/RenderBlockFlow.cpp (284268 => 284269)
--- trunk/Source/WebCore/rendering/RenderBlockFlow.cpp 2021-10-15 20:25:11 UTC (rev 284268)
+++ trunk/Source/WebCore/rendering/RenderBlockFlow.cpp 2021-10-15 20:29:15 UTC (rev 284269)
@@ -36,6 +36,7 @@
#include "HitTestLocation.h"
#include "InlineIteratorBox.h"
#include "InlineIteratorLine.h"
+#include "InlineIteratorLogicalOrderTraversal.h"
#include "InlineIteratorTextBox.h"
#include "InlineWalker.h"
#include "LayoutIntegrationLineLayout.h"
@@ -3619,7 +3620,8 @@
if (lastLineWithChildren) {
// We hit this case for Mac behavior when the Y coordinate is below the last box.
ASSERT(moveCaretToBoundary);
- if (auto logicallyLastRun = lastLineWithChildren->logicalEndRunWithNode())
+ InlineIterator::LineLogicalOrderCache orderCache;
+ if (auto logicallyLastRun = InlineIterator::lastLeafOnLineInLogicalOrderWithNode(lastLineWithChildren, orderCache))
return positionForRun(*this, logicallyLastRun, false);
}
Modified: trunk/Source/WebCore/rendering/RenderText.cpp (284268 => 284269)
--- trunk/Source/WebCore/rendering/RenderText.cpp 2021-10-15 20:25:11 UTC (rev 284268)
+++ trunk/Source/WebCore/rendering/RenderText.cpp 2021-10-15 20:29:15 UTC (rev 284269)
@@ -37,6 +37,7 @@
#include "HTMLParserIdioms.h"
#include "Hyphenation.h"
#include "InlineIteratorLine.h"
+#include "InlineIteratorLogicalOrderTraversal.h"
#include "InlineIteratorTextBox.h"
#include "InlineRunAndOffset.h"
#include "LayoutIntegrationLineLayout.h"