Title: [286929] trunk/Source/WebCore
Revision
286929
Author
za...@apple.com
Date
2021-12-12 15:49:39 -0800 (Sun, 12 Dec 2021)

Log Message

[LFC][IFC] Add partial unicode-bidi support on the block container
https://bugs.webkit.org/show_bug.cgi?id=234195

Reviewed by Antti Koivisto.

'unicode-bidi: plaintext' on the block container may change the base directionality of
the container itself. We only support LTR inline axis direction.

* layout/formattingContexts/inline/InlineItemsBuilder.cpp:
(WebCore::Layout::handleEnterExitBidiContext):
(WebCore::Layout::buildBidiParagraph): Add control character for the unicode-bidi property on the block container.
(WebCore::Layout::InlineItemsBuilder::breakAndComputeBidiLevels):
* layout/integration/LayoutIntegrationCoverage.cpp:
(WebCore::LayoutIntegration::canUseForStyle):
(WebCore::LayoutIntegration::canUseForRenderInlineChild):
(WebCore::LayoutIntegration::canUseForLineLayoutWithReason):
(WebCore::LayoutIntegration::canUseForLineLayoutAfterStyleChange):

Modified Paths

Diff

Modified: trunk/Source/WebCore/ChangeLog (286928 => 286929)


--- trunk/Source/WebCore/ChangeLog	2021-12-12 22:10:39 UTC (rev 286928)
+++ trunk/Source/WebCore/ChangeLog	2021-12-12 23:49:39 UTC (rev 286929)
@@ -1,5 +1,25 @@
 2021-12-12  Alan Bujtas  <za...@apple.com>
 
+        [LFC][IFC] Add partial unicode-bidi support on the block container
+        https://bugs.webkit.org/show_bug.cgi?id=234195
+
+        Reviewed by Antti Koivisto.
+
+        'unicode-bidi: plaintext' on the block container may change the base directionality of
+        the container itself. We only support LTR inline axis direction.
+
+        * layout/formattingContexts/inline/InlineItemsBuilder.cpp:
+        (WebCore::Layout::handleEnterExitBidiContext):
+        (WebCore::Layout::buildBidiParagraph): Add control character for the unicode-bidi property on the block container.
+        (WebCore::Layout::InlineItemsBuilder::breakAndComputeBidiLevels):
+        * layout/integration/LayoutIntegrationCoverage.cpp:
+        (WebCore::LayoutIntegration::canUseForStyle):
+        (WebCore::LayoutIntegration::canUseForRenderInlineChild):
+        (WebCore::LayoutIntegration::canUseForLineLayoutWithReason):
+        (WebCore::LayoutIntegration::canUseForLineLayoutAfterStyleChange):
+
+2021-12-12  Alan Bujtas  <za...@apple.com>
+
         [LFC][IFC] Ignore zero width glyphs while collecting fallback fonts
         https://bugs.webkit.org/show_bug.cgi?id=234210
 

Modified: trunk/Source/WebCore/layout/formattingContexts/inline/InlineItemsBuilder.cpp (286928 => 286929)


--- trunk/Source/WebCore/layout/formattingContexts/inline/InlineItemsBuilder.cpp	2021-12-12 22:10:39 UTC (rev 286928)
+++ trunk/Source/WebCore/layout/formattingContexts/inline/InlineItemsBuilder.cpp	2021-12-12 23:49:39 UTC (rev 286929)
@@ -170,9 +170,44 @@
         paragraphContentBuilder.append(textContent.right(contentLength - nonReplacedContentStartPosition));
 }
 
+static inline void handleEnterExitBidiContext(StringBuilder& paragraphContentBuilder, EUnicodeBidi unicodeBidi, bool isLTR, bool isEnteringBidi)
+{
+    switch (unicodeBidi) {
+    case EUnicodeBidi::UBNormal:
+        // The box does not open an additional level of embedding with respect to the bidirectional algorithm.
+        // For inline boxes, implicit reordering works across box boundaries.
+        break;
+    case EUnicodeBidi::Embed:
+        paragraphContentBuilder.append(isEnteringBidi ? (isLTR ? leftToRightEmbed : rightToLeftEmbed) : popDirectionalFormatting);
+        break;
+    case EUnicodeBidi::Override:
+        paragraphContentBuilder.append(isEnteringBidi ? (isLTR ? leftToRightOverride : rightToLeftOverride) : popDirectionalFormatting);
+        break;
+    case EUnicodeBidi::Isolate:
+        paragraphContentBuilder.append(isEnteringBidi ? (isLTR ? leftToRightIsolate : rightToLeftIsolate) : popDirectionalIsolate);
+        break;
+    case EUnicodeBidi::Plaintext:
+        paragraphContentBuilder.append(isEnteringBidi ? firstStrongIsolate : popDirectionalIsolate);
+        break;
+    case EUnicodeBidi::IsolateOverride:
+        if (isEnteringBidi) {
+            paragraphContentBuilder.append(firstStrongIsolate);
+            paragraphContentBuilder.append(isLTR ? leftToRightOverride : rightToLeftOverride);
+        } else {
+            paragraphContentBuilder.append(popDirectionalFormatting);
+            paragraphContentBuilder.append(popDirectionalIsolate);
+        }
+        break;
+    default:
+        ASSERT_NOT_REACHED();
+    }
+}
+
 using InlineItemOffsetList = Vector<std::optional<size_t>>;
-static inline void buildBidiParagraph(const InlineItems& inlineItems,  StringBuilder& paragraphContentBuilder, InlineItemOffsetList& inlineItemOffsetList)
+static inline void buildBidiParagraph(const RenderStyle& rootStyle, const InlineItems& inlineItems,  StringBuilder& paragraphContentBuilder, InlineItemOffsetList& inlineItemOffsetList)
 {
+    handleEnterExitBidiContext(paragraphContentBuilder, rootStyle.unicodeBidi(), rootStyle.isLeftToRightDirection(), true);
+
     const Box* lastInlineTextBox = nullptr;
     size_t inlineTextBoxOffset = 0;
     for (size_t index = 0; index < inlineItems.size(); ++index) {
@@ -201,36 +236,7 @@
             }
             inlineItemOffsetList.uncheckedAppend({ paragraphContentBuilder.length() });
             auto isEnteringBidi = inlineItem.isInlineBoxStart();
-            switch (style.unicodeBidi()) {
-            case EUnicodeBidi::UBNormal:
-                // The box does not open an additional level of embedding with respect to the bidirectional algorithm.
-                // For inline boxes, implicit reordering works across box boundaries.
-                ASSERT_NOT_REACHED();
-                break;
-            case EUnicodeBidi::Embed:
-                paragraphContentBuilder.append(isEnteringBidi ? (style.isLeftToRightDirection() ? leftToRightEmbed : rightToLeftEmbed) : popDirectionalFormatting);
-                break;
-            case EUnicodeBidi::Override:
-                paragraphContentBuilder.append(isEnteringBidi ? (style.isLeftToRightDirection() ? leftToRightOverride : rightToLeftOverride) : popDirectionalFormatting);
-                break;
-            case EUnicodeBidi::Isolate:
-                paragraphContentBuilder.append(isEnteringBidi ? (style.isLeftToRightDirection() ? leftToRightIsolate : rightToLeftIsolate) : popDirectionalIsolate);
-                break;
-            case EUnicodeBidi::Plaintext:
-                paragraphContentBuilder.append(isEnteringBidi ? firstStrongIsolate : popDirectionalIsolate);
-                break;
-            case EUnicodeBidi::IsolateOverride:
-                if (isEnteringBidi) {
-                    paragraphContentBuilder.append(firstStrongIsolate);
-                    paragraphContentBuilder.append(style.isLeftToRightDirection() ? leftToRightOverride : rightToLeftOverride);
-                } else {
-                    paragraphContentBuilder.append(popDirectionalFormatting);
-                    paragraphContentBuilder.append(popDirectionalIsolate);
-                }
-                break;
-            default:
-                ASSERT_NOT_REACHED();
-            }
+            handleEnterExitBidiContext(paragraphContentBuilder, style.unicodeBidi(), style.isLeftToRightDirection(), isEnteringBidi);
         } else if (inlineItem.isLineBreak()) {
             inlineItemOffsetList.uncheckedAppend({ paragraphContentBuilder.length() });
             paragraphContentBuilder.append(newlineCharacter);
@@ -250,7 +256,7 @@
     StringBuilder paragraphContentBuilder;
     InlineItemOffsetList inlineItemOffsets;
     inlineItemOffsets.reserveInitialCapacity(inlineItems.size());
-    buildBidiParagraph(inlineItems, paragraphContentBuilder, inlineItemOffsets);
+    buildBidiParagraph(root().style(), inlineItems, paragraphContentBuilder, inlineItemOffsets);
     ASSERT(inlineItemOffsets.size() == inlineItems.size());
 
     // 1. Setup the bidi boundary loop by calling ubidi_setPara with the paragraph text.

Modified: trunk/Source/WebCore/layout/integration/LayoutIntegrationCoverage.cpp (286928 => 286929)


--- trunk/Source/WebCore/layout/integration/LayoutIntegrationCoverage.cpp	2021-12-12 22:10:39 UTC (rev 286928)
+++ trunk/Source/WebCore/layout/integration/LayoutIntegrationCoverage.cpp	2021-12-12 23:49:39 UTC (rev 286929)
@@ -428,8 +428,9 @@
     return reasons;
 }
 
-static OptionSet<AvoidanceReason> canUseForStyle(const RenderStyle& style, IncludeReasons includeReasons)
+static OptionSet<AvoidanceReason> canUseForStyle(const RenderElement& renderer, IncludeReasons includeReasons)
 {
+    auto& style = renderer.style();
     OptionSet<AvoidanceReason> reasons;
     if ((style.overflowX() != Overflow::Visible && style.overflowX() != Overflow::Hidden)
         || (style.overflowY() != Overflow::Visible && style.overflowY() != Overflow::Hidden))
@@ -440,8 +441,12 @@
         SET_REASON_AND_RETURN_IF_NEEDED(FlowIsNotLTR, reasons, includeReasons);
     if (style.writingMode() != WritingMode::TopToBottom)
         SET_REASON_AND_RETURN_IF_NEEDED(FlowIsNotTopToBottom, reasons, includeReasons);
-    if (style.unicodeBidi() != UBNormal)
-        SET_REASON_AND_RETURN_IF_NEEDED(FlowHasNonNormalUnicodeBiDi, reasons, includeReasons);
+    if (style.unicodeBidi() != UBNormal) {
+        if (!is<RenderBlockFlow>(renderer))
+            SET_REASON_AND_RETURN_IF_NEEDED(FlowHasNonNormalUnicodeBiDi, reasons, includeReasons);
+        if (style.unicodeBidi() == EUnicodeBidi::Plaintext)
+            SET_REASON_AND_RETURN_IF_NEEDED(FlowHasNonNormalUnicodeBiDi, reasons, includeReasons);
+    }
     if (style.rtlOrdering() != Order::Logical)
         SET_REASON_AND_RETURN_IF_NEEDED(FlowHasRTLOrdering, reasons, includeReasons);
     if (style.textEmphasisFill() != TextEmphasisFill::Filled || style.textEmphasisMark() != TextEmphasisMark::None)
@@ -497,7 +502,7 @@
     if (fontAndTextReasons)
         ADD_REASONS_AND_RETURN_IF_NEEDED(fontAndTextReasons, reasons, includeReasons);
 
-    auto styleReasons = canUseForStyle(style, includeReasons);
+    auto styleReasons = canUseForStyle(renderInline, includeReasons);
     if (styleReasons)
         ADD_REASONS_AND_RETURN_IF_NEEDED(styleReasons, reasons, includeReasons);
 
@@ -637,7 +642,7 @@
             ADD_REASONS_AND_RETURN_IF_NEEDED(childReasons, reasons, includeReasons);
         hasSeenInlineBox = hasSeenInlineBox || is<RenderInline>(*walker.current());
     }
-    auto styleReasons = canUseForStyle(flow.style(), includeReasons);
+    auto styleReasons = canUseForStyle(flow, includeReasons);
     if (styleReasons)
         ADD_REASONS_AND_RETURN_IF_NEEDED(styleReasons, reasons, includeReasons);
     // We can't use the code path if any lines would need to be shifted below floats. This is because we don't keep per-line y coordinates.
@@ -679,12 +684,12 @@
     case StyleDifference::RepaintIfTextOrBorderOrOutline:
     case StyleDifference::RepaintLayer:
         // FIXME: We could do a more focused style check by matching RendererStyle::changeRequiresRepaint&co.
-        return canUseForStyle(blockContainer.style(), IncludeReasons::First).isEmpty();
+        return canUseForStyle(blockContainer, IncludeReasons::First).isEmpty();
     case StyleDifference::LayoutPositionedMovementOnly:
         return true;
     case StyleDifference::SimplifiedLayout:
     case StyleDifference::SimplifiedLayoutAndPositionedMovement:
-        return canUseForStyle(blockContainer.style(), IncludeReasons::First).isEmpty();
+        return canUseForStyle(blockContainer, IncludeReasons::First).isEmpty();
     case StyleDifference::Layout:
     case StyleDifference::NewStyle:
         return canUseForLineLayout(blockContainer);
_______________________________________________
webkit-changes mailing list
webkit-changes@lists.webkit.org
https://lists.webkit.org/mailman/listinfo/webkit-changes

Reply via email to