Modified: trunk/Source/WebCore/ChangeLog (286499 => 286500)
--- trunk/Source/WebCore/ChangeLog 2021-12-03 18:00:42 UTC (rev 286499)
+++ trunk/Source/WebCore/ChangeLog 2021-12-03 18:15:04 UTC (rev 286500)
@@ -1,3 +1,18 @@
+2021-12-03 Alan Bujtas <za...@apple.com>
+
+ [LFC][IFC] Set the first/last box flag on the (bidi fragmented) inline box type of display boxes
+ https://bugs.webkit.org/show_bug.cgi?id=233743
+
+ Reviewed by Antti Koivisto.
+
+ Keep track of the last constructed inline box type of display box position so that when we
+ happen to create another fragment for this same inline box, we can change the 'isLastBox' box to false.
+
+ * layout/formattingContexts/inline/InlineDisplayContentBuilder.cpp:
+ (WebCore::Layout::InlineDisplayContentBuilder::insertInlineBoxDisplayBoxForBidiBoundary):
+ (WebCore::Layout::InlineDisplayContentBuilder::processBidiContent):
+ * layout/formattingContexts/inline/InlineDisplayContentBuilder.h:
+
2021-12-03 Chris Dumez <cdu...@apple.com>
Introduce WorkerGlobalScope::type() function
Modified: trunk/Source/WebCore/layout/formattingContexts/inline/InlineDisplayContentBuilder.cpp (286499 => 286500)
--- trunk/Source/WebCore/layout/formattingContexts/inline/InlineDisplayContentBuilder.cpp 2021-12-03 18:00:42 UTC (rev 286499)
+++ trunk/Source/WebCore/layout/formattingContexts/inline/InlineDisplayContentBuilder.cpp 2021-12-03 18:15:04 UTC (rev 286500)
@@ -270,9 +270,16 @@
setInlineBoxGeometry(layoutBox, inlineBoxBorderBox, false);
}
-void InlineDisplayContentBuilder::insertInlineBoxDisplayBoxForBidiBoundary(const InlineLevelBox& inlineBox, const InlineRect& inlineBoxRect, size_t insertionPoint, DisplayBoxes& boxes)
+void InlineDisplayContentBuilder::insertInlineBoxDisplayBoxForBidiBoundary(const InlineLevelBox& inlineBox, const InlineRect& inlineBoxRect, bool isFirstInlineBoxFragment, size_t insertionPoint, DisplayBoxes& boxes)
{
ASSERT(inlineBox.isInlineBox());
+
+ auto isFirstLastBox = OptionSet<InlineDisplay::Box::PositionWithinInlineLevelBox> { };
+ if (inlineBox.isFirstBox() && isFirstInlineBoxFragment)
+ isFirstLastBox.add({ InlineDisplay::Box::PositionWithinInlineLevelBox::First });
+ if (inlineBox.isLastBox())
+ isFirstLastBox.add({ InlineDisplay::Box::PositionWithinInlineLevelBox::Last });
+
// FIXME: Compute ink overflow.
boxes.insert(insertionPoint, { m_lineIndex
, InlineDisplay::Box::Type::NonRootInlineBox
@@ -283,7 +290,7 @@
, { }
, { }
, true
- , isFirstLastBox(inlineBox) });
+ , isFirstLastBox });
}
void InlineDisplayContentBuilder::adjustInlineBoxDisplayBoxForBidiBoundary(InlineDisplay::Box& displayBox, const InlineRect& inlineBoxRect)
@@ -422,6 +429,7 @@
// abcdefg
// with the following, fragmented inline boxes:
// a[first open]b[first close][second open]c[second close]d[second open]e[second close]f[first open]g[first close]
+ HashMap<const Box*, size_t> inlineBoxDisplayBoxMap;
ListHashSet<const Box*> parentBoxStack;
parentBoxStack.add(&root());
@@ -458,6 +466,13 @@
parentBoxStack.add(inlineBox);
auto createAndInsertDisplayBoxForInlineBoxFragment = [&] {
+ // Make sure that the "previous" display box for this particular inline box is not tracked as the "last box".
+ auto lastDisplayBoxForInlineBoxIndex = inlineBoxDisplayBoxMap.take(inlineBox);
+ auto isFirstFragment = !lastDisplayBoxForInlineBoxIndex;
+ if (!isFirstFragment)
+ boxes[lastDisplayBoxForInlineBoxIndex].setIsLastBox(false);
+ inlineBoxDisplayBoxMap.set(inlineBox, index);
+
auto& boxGeometry = formattingState().boxGeometry(*inlineBox);
auto visualRect = lineBox.logicalBorderBoxForInlineBox(*inlineBox, boxGeometry);
// Use the current content left as the starting point for this display box.
@@ -465,7 +480,7 @@
visualRect.moveVertically(lineBoxLogicalTopLeft.y());
// Visual width is not yet known.
visualRect.setWidth({ });
- insertInlineBoxDisplayBoxForBidiBoundary(lineBox.inlineLevelBoxForLayoutBox(*inlineBox), visualRect, index, boxes);
+ insertInlineBoxDisplayBoxForBidiBoundary(lineBox.inlineLevelBoxForLayoutBox(*inlineBox), visualRect, isFirstFragment, index, boxes);
++index;
// Need to push the rest of the content when this inline box has margin/border/padding.
needsDisplayBoxHorizontalAdjustment = needsDisplayBoxHorizontalAdjustment
Modified: trunk/Source/WebCore/layout/formattingContexts/inline/InlineDisplayContentBuilder.h (286499 => 286500)
--- trunk/Source/WebCore/layout/formattingContexts/inline/InlineDisplayContentBuilder.h 2021-12-03 18:00:42 UTC (rev 286499)
+++ trunk/Source/WebCore/layout/formattingContexts/inline/InlineDisplayContentBuilder.h 2021-12-03 18:15:04 UTC (rev 286500)
@@ -55,7 +55,7 @@
void appendAtomicInlineLevelDisplayBox(const Line::Run&, const InlineRect& , DisplayBoxes&);
void appendInlineBoxDisplayBox(const Line::Run&, const InlineLevelBox&, const InlineRect&, bool linehasContent, DisplayBoxes&);
void appendSpanningInlineBoxDisplayBox(const Line::Run&, const InlineLevelBox&, const InlineRect&, DisplayBoxes&);
- void insertInlineBoxDisplayBoxForBidiBoundary(const InlineLevelBox&, const InlineRect&, size_t insertionPoint, DisplayBoxes&);
+ void insertInlineBoxDisplayBoxForBidiBoundary(const InlineLevelBox&, const InlineRect&, bool isFirstInlineBoxFragment, size_t insertionPoint, DisplayBoxes&);
void adjustInlineBoxDisplayBoxForBidiBoundary(InlineDisplay::Box&, const InlineRect&);
void setInlineBoxGeometry(const Box&, const InlineRect&, bool isFirstInlineBoxFragment);
Modified: trunk/Source/WebCore/layout/formattingContexts/inline/display/InlineDisplayBox.h (286499 => 286500)
--- trunk/Source/WebCore/layout/formattingContexts/inline/display/InlineDisplayBox.h 2021-12-03 18:00:42 UTC (rev 286499)
+++ trunk/Source/WebCore/layout/formattingContexts/inline/display/InlineDisplayBox.h 2021-12-03 18:15:04 UTC (rev 286500)
@@ -128,6 +128,8 @@
bool isFirstBox() const { return m_isFirstWithinInlineLevelBox; }
bool isLastBox() const { return m_isLastWithinInlineLevelBox; }
+ void setIsLastBox(bool isLastBox) { m_isLastWithinInlineLevelBox = isLastBox; }
+
private:
const size_t m_lineIndex { 0 };
const Type m_type { Type::GenericInlineLevelBox };