Title: [285157] trunk/Source/WebCore
Revision
285157
Author
za...@apple.com
Date
2021-11-02 07:56:44 -0700 (Tue, 02 Nov 2021)

Log Message

[LFC][IFC] Pass in the visual order list to display box construction
https://bugs.webkit.org/show_bug.cgi?id=232600

Reviewed by Antti Koivisto.

In this patch we compute the visual order for the bidi runs if needed. This visual order is then passed
in to the display box builder so that the final display boxes are constructed in the right order (horizontal positions are not yet adjusted).

* layout/formattingContexts/inline/InlineDisplayContentBuilder.cpp:
(WebCore::Layout::InlineDisplayContentBuilder::createBoxesAndUpdateGeometryForLineContent):
* layout/formattingContexts/inline/InlineLine.h:
(WebCore::Layout::Line::contentNeedsBidiReordering const):
* layout/formattingContexts/inline/InlineLineBuilder.cpp:
(WebCore::Layout::LineBuilder::layoutInlineContent):
* layout/formattingContexts/inline/InlineLineBuilder.h:

Modified Paths

Diff

Modified: trunk/Source/WebCore/ChangeLog (285156 => 285157)


--- trunk/Source/WebCore/ChangeLog	2021-11-02 13:56:33 UTC (rev 285156)
+++ trunk/Source/WebCore/ChangeLog	2021-11-02 14:56:44 UTC (rev 285157)
@@ -1,5 +1,23 @@
 2021-11-02  Alan Bujtas  <za...@apple.com>
 
+        [LFC][IFC] Pass in the visual order list to display box construction
+        https://bugs.webkit.org/show_bug.cgi?id=232600
+
+        Reviewed by Antti Koivisto.
+
+        In this patch we compute the visual order for the bidi runs if needed. This visual order is then passed
+        in to the display box builder so that the final display boxes are constructed in the right order (horizontal positions are not yet adjusted). 
+
+        * layout/formattingContexts/inline/InlineDisplayContentBuilder.cpp:
+        (WebCore::Layout::InlineDisplayContentBuilder::createBoxesAndUpdateGeometryForLineContent):
+        * layout/formattingContexts/inline/InlineLine.h:
+        (WebCore::Layout::Line::contentNeedsBidiReordering const):
+        * layout/formattingContexts/inline/InlineLineBuilder.cpp:
+        (WebCore::Layout::LineBuilder::layoutInlineContent):
+        * layout/formattingContexts/inline/InlineLineBuilder.h:
+
+2021-11-02  Alan Bujtas  <za...@apple.com>
+
         [LFC][IFC] Use the isLineSpanningInlineBoxStart line run type to update spanning inline box geometry
         https://bugs.webkit.org/show_bug.cgi?id=232578
 

Modified: trunk/Source/WebCore/layout/formattingContexts/inline/InlineDisplayContentBuilder.cpp (285156 => 285157)


--- trunk/Source/WebCore/layout/formattingContexts/inline/InlineDisplayContentBuilder.cpp	2021-11-02 13:56:33 UTC (rev 285156)
+++ trunk/Source/WebCore/layout/formattingContexts/inline/InlineDisplayContentBuilder.cpp	2021-11-02 14:56:44 UTC (rev 285157)
@@ -69,9 +69,13 @@
 
 void InlineDisplayContentBuilder::createBoxesAndUpdateGeometryForLineContent(const LineBuilder::LineContent& lineContent, const LineBox& lineBox, const InlineLayoutPoint& lineBoxLogicalTopLeft, const size_t lineIndex, DisplayBoxes& boxes)
 {
+    // Create the inline boxes on the current line. This is mostly text and atomic inline boxes.
     auto& formattingState = this->formattingState();
-    // Create the inline boxes on the current line. This is mostly text and atomic inline boxes.
-    for (auto& lineRun : lineContent.runs) {
+    auto& runs = lineContent.runs;
+    auto contentNeedsBidiReordering = !lineContent.visualOrderList.isEmpty();
+    ASSERT(!contentNeedsBidiReordering || lineContent.visualOrderList.size() == runs.size());
+    for (size_t i = 0; i < runs.size(); ++i) {
+        auto& lineRun = runs[contentNeedsBidiReordering ? lineContent.visualOrderList[i] : i];
         auto& layoutBox = lineRun.layoutBox();
         auto& style = [&] () -> const RenderStyle& {
             return !lineIndex ? layoutBox.firstLineStyle() : layoutBox.style();

Modified: trunk/Source/WebCore/layout/formattingContexts/inline/InlineLine.h (285156 => 285157)


--- trunk/Source/WebCore/layout/formattingContexts/inline/InlineLine.h	2021-11-02 13:56:33 UTC (rev 285156)
+++ trunk/Source/WebCore/layout/formattingContexts/inline/InlineLine.h	2021-11-02 14:56:44 UTC (rev 285157)
@@ -49,6 +49,8 @@
 
     bool hasContent() const { return !m_runs.isEmpty() && !m_runs.last().isLineSpanningInlineBoxStart(); }
 
+    bool contentNeedsBidiReordering() const { return false; }
+
     InlineLayoutUnit contentLogicalWidth() const { return m_contentLogicalWidth; }
     InlineLayoutUnit contentLogicalRight() const { return lastRunLogicalRight() + m_clonedEndDecorationWidthForInlineBoxRuns; }
     size_t nonSpanningInlineLevelBoxCount() const { return m_nonSpanningInlineLevelBoxCount; }

Modified: trunk/Source/WebCore/layout/formattingContexts/inline/InlineLineBuilder.cpp (285156 => 285157)


--- trunk/Source/WebCore/layout/formattingContexts/inline/InlineLineBuilder.cpp	2021-11-02 13:56:33 UTC (rev 285156)
+++ trunk/Source/WebCore/layout/formattingContexts/inline/InlineLineBuilder.cpp	2021-11-02 14:56:44 UTC (rev 285157)
@@ -283,9 +283,28 @@
 
     auto committedContent = placeInlineContent(needsLayoutRange);
     auto committedRange = close(needsLayoutRange, committedContent);
+    auto& lineRuns = m_line.runs();
 
+    auto computedVisualOrder = [&]() -> Vector<int32_t> {
+        if (!m_line.contentNeedsBidiReordering())
+            return { };
+
+        Vector<UBiDiLevel> runLevels(lineRuns.size());
+        // FIXME: We may cache these values in Line, if it turns out to be a perf hit.
+        for (size_t i = 0; i < lineRuns.size(); ++i)
+            runLevels[i] = lineRuns[i].bidiLevel();
+
+        Vector<int32_t> visualOrderList(lineRuns.size());
+        ubidi_reorderVisual(runLevels.data(), runLevels.size(), visualOrderList.data());
+        return visualOrderList;
+    };
+
     auto isLastLine = isLastLineWithInlineContent(committedRange, needsLayoutRange.end, committedContent.partialTrailingContentLength);
-    return LineContent { committedRange, committedContent.partialTrailingContentLength, committedContent.overflowLogicalWidth, m_floats, m_contentIsConstrainedByFloat
+    return LineContent { committedRange
+        , committedContent.partialTrailingContentLength
+        , committedContent.overflowLogicalWidth
+        , m_floats
+        , m_contentIsConstrainedByFloat
         , m_lineLogicalRect.topLeft()
         , m_lineLogicalRect.width()
         , m_line.contentLogicalWidth()
@@ -292,7 +311,8 @@
         , m_line.hangingWhitespaceWidth()
         , isLastLine
         , m_line.nonSpanningInlineLevelBoxCount()
-        , m_line.runs()};
+        , computedVisualOrder()
+        , lineRuns };
 }
 
 LineBuilder::IntrinsicContent LineBuilder::computedIntrinsicWidth(const InlineItemRange& needsLayoutRange, InlineLayoutUnit availableWidth)

Modified: trunk/Source/WebCore/layout/formattingContexts/inline/InlineLineBuilder.h (285156 => 285157)


--- trunk/Source/WebCore/layout/formattingContexts/inline/InlineLineBuilder.h	2021-11-02 13:56:33 UTC (rev 285156)
+++ trunk/Source/WebCore/layout/formattingContexts/inline/InlineLineBuilder.h	2021-11-02 14:56:44 UTC (rev 285157)
@@ -61,6 +61,7 @@
         InlineLayoutUnit hangingWhitespaceWidth { 0 };
         bool isLastLineWithInlineContent { true };
         size_t nonSpanningInlineLevelBoxCount { 0 };
+        Vector<int32_t> visualOrderList;
         const Line::RunList& runs;
     };
     LineContent layoutInlineContent(const InlineItemRange&, size_t partialLeadingContentLength, std::optional<InlineLayoutUnit> overflowingLogicalWidth, const InlineRect& initialLineLogicalRect, bool isFirstLine);
_______________________________________________
webkit-changes mailing list
webkit-changes@lists.webkit.org
https://lists.webkit.org/mailman/listinfo/webkit-changes

Reply via email to