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);