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