Title: [288332] trunk/Source/WebCore
Revision
288332
Author
[email protected]
Date
2022-01-20 16:17:44 -0800 (Thu, 20 Jan 2022)

Log Message

[LFC][IFC] Add LineContent::inlineBaseDirection to support line based inline direction
https://bugs.webkit.org/show_bug.cgi?id=235391

Reviewed by Antti Koivisto.

In this patch we introduce the line based inline base direction. With "unicode-bidi: plaintext" each line can have its own
base direction depending on the content on the line.

* layout/formattingContexts/inline/InlineFormattingContext.cpp:
(WebCore::Layout::InlineFormattingContext::computeGeometryForLineContent):
* layout/formattingContexts/inline/InlineLineBuilder.cpp:
(WebCore::Layout::toString): Unfortunately we have to rebuild the text content part of the line here.
(WebCore::Layout::LineBuilder::layoutInlineContent):
* layout/formattingContexts/inline/InlineLineBuilder.h:
* layout/formattingContexts/inline/display/InlineDisplayContentBuilder.cpp:
(WebCore::Layout::InlineDisplayContentBuilder::processNonBidiContent):
* layout/formattingContexts/inline/display/InlineDisplayLineBuilder.cpp:
(WebCore::Layout::InlineDisplayLineBuilder::build const):
* layout/formattingContexts/inline/display/InlineDisplayLineBuilder.h:
* layout/formattingContexts/inline/text/TextUtil.cpp:
(WebCore::Layout::TextUtil::directionForTextContent):
* layout/formattingContexts/inline/text/TextUtil.h:

Modified Paths

Diff

Modified: trunk/Source/WebCore/ChangeLog (288331 => 288332)


--- trunk/Source/WebCore/ChangeLog	2022-01-20 23:48:33 UTC (rev 288331)
+++ trunk/Source/WebCore/ChangeLog	2022-01-21 00:17:44 UTC (rev 288332)
@@ -1,3 +1,28 @@
+2022-01-20  Alan Bujtas  <[email protected]>
+
+        [LFC][IFC] Add LineContent::inlineBaseDirection to support line based inline direction
+        https://bugs.webkit.org/show_bug.cgi?id=235391
+
+        Reviewed by Antti Koivisto.
+
+        In this patch we introduce the line based inline base direction. With "unicode-bidi: plaintext" each line can have its own
+        base direction depending on the content on the line.
+
+        * layout/formattingContexts/inline/InlineFormattingContext.cpp:
+        (WebCore::Layout::InlineFormattingContext::computeGeometryForLineContent):
+        * layout/formattingContexts/inline/InlineLineBuilder.cpp:
+        (WebCore::Layout::toString): Unfortunately we have to rebuild the text content part of the line here.
+        (WebCore::Layout::LineBuilder::layoutInlineContent):
+        * layout/formattingContexts/inline/InlineLineBuilder.h:
+        * layout/formattingContexts/inline/display/InlineDisplayContentBuilder.cpp:
+        (WebCore::Layout::InlineDisplayContentBuilder::processNonBidiContent):
+        * layout/formattingContexts/inline/display/InlineDisplayLineBuilder.cpp:
+        (WebCore::Layout::InlineDisplayLineBuilder::build const):
+        * layout/formattingContexts/inline/display/InlineDisplayLineBuilder.h:
+        * layout/formattingContexts/inline/text/TextUtil.cpp:
+        (WebCore::Layout::TextUtil::directionForTextContent):
+        * layout/formattingContexts/inline/text/TextUtil.h:
+
 2022-01-20  Wenson Hsieh  <[email protected]>
 
         [macOS] Various tests hit debug assertions under `SearchBuffer::search` after system ICU changes

Modified: trunk/Source/WebCore/layout/formattingContexts/inline/InlineFormattingContext.cpp (288331 => 288332)


--- trunk/Source/WebCore/layout/formattingContexts/inline/InlineFormattingContext.cpp	2022-01-20 23:48:33 UTC (rev 288331)
+++ trunk/Source/WebCore/layout/formattingContexts/inline/InlineFormattingContext.cpp	2022-01-21 00:17:44 UTC (rev 288332)
@@ -245,7 +245,7 @@
                 overflowContent = { lineContent.partialTrailingContentLength, lineContent.overflowLogicalWidth };
             else if (lineContent.overflowLogicalWidth)
                 overflowContent = { { }, *lineContent.overflowLogicalWidth };
-            previousLine = LineBuilder::PreviousLine { lineContentRange, !lineContent.runs.isEmpty() && lineContent.runs.last().isLineBreak(), overflowContent };
+            previousLine = LineBuilder::PreviousLine { lineContentRange, !lineContent.runs.isEmpty() && lineContent.runs.last().isLineBreak(), lineContent.inlineBaseDirection, overflowContent };
             continue;
         }
         // Floats prevented us placing any content on the line.
@@ -548,11 +548,7 @@
     auto currentLineIndex = formattingState.lines().size();
 
     auto lineBoxAndHeight = LineBoxBuilder { *this }.build(lineContent, currentLineIndex);
-    auto displayLine = InlineDisplayLineBuilder { *this }.build(lineContent
-        , lineBoxAndHeight.lineBox
-        , lineBoxAndHeight.lineBoxLogicalHeight
-        , currentLineIndex
-    );
+    auto displayLine = InlineDisplayLineBuilder { *this }.build(lineContent, lineBoxAndHeight.lineBox, lineBoxAndHeight.lineBoxLogicalHeight);
     formattingState.addBoxes(InlineDisplayContentBuilder { root(), formattingState }.build(lineContent
         , lineBoxAndHeight.lineBox
         , displayLine

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


--- trunk/Source/WebCore/layout/formattingContexts/inline/InlineLineBuilder.cpp	2022-01-20 23:48:33 UTC (rev 288331)
+++ trunk/Source/WebCore/layout/formattingContexts/inline/InlineLineBuilder.cpp	2022-01-21 00:17:44 UTC (rev 288332)
@@ -41,6 +41,19 @@
 namespace WebCore {
 namespace Layout {
 
+static inline StringBuilder toString(const Line::RunList& runs)
+{
+    // FIXME: We could try to reuse the content builder in InlineItemsBuilder if this turns out to be a perf bottleneck.
+    StringBuilder lineContentBuilder;
+    for (auto& run : runs) {
+        if (!run.isText())
+            continue;
+        auto& textContent = run.textContent();
+        lineContentBuilder.append(downcast<InlineTextBox>(run.layoutBox()).content().substring(textContent->start, textContent->length));
+    }
+    return lineContentBuilder;
+}
+
 static inline bool endsWithSoftWrapOpportunity(const InlineTextItem& currentTextItem, const InlineTextItem& nextInlineTextItem)
 {
     ASSERT(!nextInlineTextItem.isWhitespace());
@@ -343,6 +356,17 @@
         return visualOrderList;
     };
 
+    auto inlineBaseDirectionForLineContent = [&] {
+        auto& rootStyle = !previousLine ? root().firstLineStyle() : root().style();
+        auto shouldUseBlockDirection = rootStyle.unicodeBidi() != UnicodeBidi::Plaintext || !previousLine;
+        if (shouldUseBlockDirection)
+            return rootStyle.direction();
+        // A previous line ending with a line break (<br> or preserved \n) introduces a new unicode paragraph with its own direction.
+        if (!previousLine->endsWithLineBreak)
+            return previousLine->inlineBaseDirection;
+        return TextUtil::directionForTextContent(toString(lineRuns));
+    };
+
     auto isLastLine = isLastLineWithInlineContent(committedRange, needsLayoutRange.end, committedContent.partialTrailingContentLength);
     return LineContent { committedRange
         , committedContent.partialTrailingContentLength
@@ -358,6 +382,7 @@
         , isLastLine
         , m_line.nonSpanningInlineLevelBoxCount()
         , computedVisualOrder()
+        , inlineBaseDirectionForLineContent()
         , lineRuns };
 }
 

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


--- trunk/Source/WebCore/layout/formattingContexts/inline/InlineLineBuilder.h	2022-01-20 23:48:33 UTC (rev 288331)
+++ trunk/Source/WebCore/layout/formattingContexts/inline/InlineLineBuilder.h	2022-01-21 00:17:44 UTC (rev 288332)
@@ -53,6 +53,7 @@
     struct PreviousLine {
         InlineItemRange range;
         bool endsWithLineBreak { false };
+        TextDirection inlineBaseDirection { TextDirection::LTR };
         struct OverflowContent {
             size_t partialContentLength { 0 };
             std::optional<InlineLayoutUnit> width { };
@@ -75,6 +76,7 @@
         bool isLastLineWithInlineContent { true };
         size_t nonSpanningInlineLevelBoxCount { 0 };
         Vector<int32_t> visualOrderList;
+        TextDirection inlineBaseDirection { TextDirection::LTR };
         const Line::RunList& runs;
     };
     LineContent layoutInlineContent(const InlineItemRange&, const InlineRect& lineLogicalRect, const std::optional<PreviousLine>&);

Modified: trunk/Source/WebCore/layout/formattingContexts/inline/display/InlineDisplayContentBuilder.cpp (288331 => 288332)


--- trunk/Source/WebCore/layout/formattingContexts/inline/display/InlineDisplayContentBuilder.cpp	2022-01-20 23:48:33 UTC (rev 288331)
+++ trunk/Source/WebCore/layout/formattingContexts/inline/display/InlineDisplayContentBuilder.cpp	2022-01-21 00:17:44 UTC (rev 288332)
@@ -324,7 +324,7 @@
     auto hasContent = false;
     for (auto& lineRun : lineContent.runs)
         hasContent = hasContent || lineRun.isText() || lineRun.isBox();
-    ASSERT(root().style().isLeftToRightDirection() || !hasContent);
+    ASSERT(lineContent.inlineBaseDirection == TextDirection::LTR || !hasContent);
 #endif
     auto contentStartInVisualOrder = displayLine.left() + displayLine.contentLeft();
 

Modified: trunk/Source/WebCore/layout/formattingContexts/inline/display/InlineDisplayLineBuilder.cpp (288331 => 288332)


--- trunk/Source/WebCore/layout/formattingContexts/inline/display/InlineDisplayLineBuilder.cpp	2022-01-20 23:48:33 UTC (rev 288331)
+++ trunk/Source/WebCore/layout/formattingContexts/inline/display/InlineDisplayLineBuilder.cpp	2022-01-21 00:17:44 UTC (rev 288332)
@@ -76,12 +76,11 @@
     return { enclosingTopAndBottom, scrollableOverflowRect };
 }
 
-InlineDisplay::Line InlineDisplayLineBuilder::build(const LineBuilder::LineContent& lineContent, const LineBox& lineBox, InlineLayoutUnit lineBoxLogicalHeight, size_t lineIndex) const
+InlineDisplay::Line InlineDisplayLineBuilder::build(const LineBuilder::LineContent& lineContent, const LineBox& lineBox, InlineLayoutUnit lineBoxLogicalHeight) const
 {
-    auto& rootStyle = lineIndex ? root().firstLineStyle() : root().style();
     auto& rootInlineBox = lineBox.rootInlineBox();
     auto& rootGeometry = layoutState().geometryForBox(root());
-    auto isLeftToRightDirection = rootStyle.isLeftToRightDirection();
+    auto isLeftToRightDirection = lineContent.inlineBaseDirection == TextDirection::LTR;
     auto lineOffsetFromContentBox = lineContent.lineLogicalTopLeft.x() - rootGeometry.contentBoxLeft();
 
     auto lineBoxVisualLeft = isLeftToRightDirection

Modified: trunk/Source/WebCore/layout/formattingContexts/inline/display/InlineDisplayLineBuilder.h (288331 => 288332)


--- trunk/Source/WebCore/layout/formattingContexts/inline/display/InlineDisplayLineBuilder.h	2022-01-20 23:48:33 UTC (rev 288331)
+++ trunk/Source/WebCore/layout/formattingContexts/inline/display/InlineDisplayLineBuilder.h	2022-01-21 00:17:44 UTC (rev 288332)
@@ -40,7 +40,7 @@
 public:
     InlineDisplayLineBuilder(const InlineFormattingContext&);
 
-    InlineDisplay::Line build(const LineBuilder::LineContent&, const LineBox&, InlineLayoutUnit lineBoxLogicalHeight, size_t lineIndex) const;
+    InlineDisplay::Line build(const LineBuilder::LineContent&, const LineBox&, InlineLayoutUnit lineBoxLogicalHeight) const;
 
 private:
     struct EnclosingLineGeometry {

Modified: trunk/Source/WebCore/layout/formattingContexts/inline/text/TextUtil.cpp (288331 => 288332)


--- trunk/Source/WebCore/layout/formattingContexts/inline/text/TextUtil.cpp	2022-01-20 23:48:33 UTC (rev 288331)
+++ trunk/Source/WebCore/layout/formattingContexts/inline/text/TextUtil.cpp	2022-01-21 00:17:44 UTC (rev 288332)
@@ -336,6 +336,12 @@
     return nextPosition - inlineTextItem.start();
 }
 
+TextDirection TextUtil::directionForTextContent(StringView)
+{
+    ASSERT_NOT_IMPLEMENTED_YET();
+    return TextDirection::LTR;
 }
+
 }
+}
 #endif

Modified: trunk/Source/WebCore/layout/formattingContexts/inline/text/TextUtil.h (288331 => 288332)


--- trunk/Source/WebCore/layout/formattingContexts/inline/text/TextUtil.h	2022-01-20 23:48:33 UTC (rev 288331)
+++ trunk/Source/WebCore/layout/formattingContexts/inline/text/TextUtil.h	2022-01-21 00:17:44 UTC (rev 288332)
@@ -71,6 +71,7 @@
     static bool containsStrongDirectionalityText(StringView);
 
     static size_t firstUserPerceivedCharacterLength(const InlineTextItem&);
+    static TextDirection directionForTextContent(StringView);
 };
 
 }
_______________________________________________
webkit-changes mailing list
[email protected]
https://lists.webkit.org/mailman/listinfo/webkit-changes

Reply via email to