Modified: trunk/Source/WebCore/layout/formattingContexts/inline/InlineDisplayContentBuilder.cpp (287196 => 287197)
--- trunk/Source/WebCore/layout/formattingContexts/inline/InlineDisplayContentBuilder.cpp 2021-12-17 18:55:42 UTC (rev 287196)
+++ trunk/Source/WebCore/layout/formattingContexts/inline/InlineDisplayContentBuilder.cpp 2021-12-17 18:58:49 UTC (rev 287197)
@@ -452,7 +452,12 @@
return createdDisplayBoxNodeForContainerBoxAndPushToAncestorStack(containerBox, boxes.size() - 1, enclosingDisplayBoxNodeIndexForContainer, displayBoxTree, ancestorStack);
}
-void InlineDisplayContentBuilder::adjustVisualGeometryForDisplayBox(size_t displayBoxNodeIndex, InlineLayoutUnit& contentRightInVisualOrder, InlineLayoutUnit lineBoxLogicalTop, const DisplayBoxTree& displayBoxTree, DisplayBoxes& boxes, const LineBox& lineBox)
+struct IsFirstLastIndex {
+ std::optional<size_t> first;
+ std::optional<size_t> last;
+};
+using IsFirstLastIndexesMap = HashMap<const Box*, IsFirstLastIndex>;
+void InlineDisplayContentBuilder::adjustVisualGeometryForDisplayBox(size_t displayBoxNodeIndex, InlineLayoutUnit& contentRightInVisualOrder, InlineLayoutUnit lineBoxLogicalTop, const DisplayBoxTree& displayBoxTree, DisplayBoxes& boxes, const LineBox& lineBox, const IsFirstLastIndexesMap& isFirstLastIndexesMap)
{
// Non-inline box display boxes just need a horizontal adjustment while
// inline box type of display boxes need
@@ -469,12 +474,15 @@
return;
}
+ auto& boxGeometry = formattingState().boxGeometry(layoutBox);
auto isLeftToRightDirection = layoutBox.style().isLeftToRightDirection();
- auto& boxGeometry = formattingState().boxGeometry(layoutBox);
+ auto isFirstLastIndexes = isFirstLastIndexesMap.get(&layoutBox);
+ auto isFirstBox = isFirstLastIndexes.first && *isFirstLastIndexes.first == displayBoxNodeIndex;
+ auto isLastBox = isFirstLastIndexes.last && *isFirstLastIndexes.last == displayBoxNodeIndex;
auto beforeInlineBoxContent = [&] {
auto logicalRect = lineBox.logicalBorderBoxForInlineBox(layoutBox, boxGeometry);
auto visualRect = InlineRect { lineBoxLogicalTop + logicalRect.top(), contentRightInVisualOrder, { }, logicalRect.height() };
- if (!displayBox.isFirstForLayoutBox())
+ if (!isFirstBox)
return displayBox.setRect(visualRect, visualRect);
contentRightInVisualOrder += marginLeft(boxGeometry, isLeftToRightDirection);
@@ -485,10 +493,10 @@
beforeInlineBoxContent();
for (auto childDisplayBoxNodeIndex : displayBoxTree.at(displayBoxNodeIndex).children)
- adjustVisualGeometryForDisplayBox(childDisplayBoxNodeIndex, contentRightInVisualOrder, lineBoxLogicalTop, displayBoxTree, boxes, lineBox);
+ adjustVisualGeometryForDisplayBox(childDisplayBoxNodeIndex, contentRightInVisualOrder, lineBoxLogicalTop, displayBoxTree, boxes, lineBox, isFirstLastIndexesMap);
auto afterInlineBoxContent = [&] {
- if (!displayBox.isLastForLayoutBox())
+ if (!isLastBox)
return displayBox.setRight(contentRightInVisualOrder);
contentRightInVisualOrder += borderRight(boxGeometry, isLeftToRightDirection) + paddingRight(boxGeometry, isLeftToRightDirection);
@@ -504,7 +512,7 @@
};
computeInkOverflow();
- setInlineBoxGeometry(layoutBox, displayBox.rect(), displayBox.isFirstForLayoutBox());
+ setInlineBoxGeometry(layoutBox, displayBox.rect(), isFirstBox);
if (lineBox.inlineLevelBoxForLayoutBox(layoutBox).hasContent())
displayBox.setHasContent();
}
@@ -586,22 +594,29 @@
createDisplayBoxesInVisualOrder();
if (displayBoxTree.hasInlineBox()) {
+ IsFirstLastIndexesMap isFirstLastIndexesMap;
auto computeIsFirstIsLastBox = [&] {
- HashMap<const Box*, size_t> lastDisplayBoxIndexes;
ASSERT(boxes[0].isRootInlineBox());
for (size_t index = 1; index < boxes.size(); ++index) {
- auto& displayBox = boxes[index];
- if (!displayBox.isNonRootInlineBox())
+ if (!boxes[index].isNonRootInlineBox())
continue;
- auto& layoutBox = displayBox.layoutBox();
- auto isFirstBoxOnCurrentLine = lastDisplayBoxIndexes.set(&layoutBox, index).isNewEntry;
- if (lineBox.inlineLevelBoxForLayoutBox(layoutBox).isFirstBox() && isFirstBoxOnCurrentLine)
- displayBox.setIsFirstForLayoutBox(true);
+ auto& layoutBox = boxes[index].layoutBox();
+ auto isFirstBox = lineBox.inlineLevelBoxForLayoutBox(layoutBox).isFirstBox();
+ auto isLastBox = lineBox.inlineLevelBoxForLayoutBox(layoutBox).isLastBox();
+ if (!isFirstBox && !isLastBox)
+ continue;
+ if (isFirstBox) {
+ auto isFirstLastIndexes = isFirstLastIndexesMap.get(&layoutBox);
+ if (!isFirstLastIndexes.first || isLastBox)
+ isFirstLastIndexesMap.set(&layoutBox, IsFirstLastIndex { isFirstLastIndexes.first.value_or(index), isLastBox ? index : isFirstLastIndexes.last });
+ continue;
+ }
+ if (isLastBox) {
+ ASSERT(!isFirstBox);
+ isFirstLastIndexesMap.set(&layoutBox, IsFirstLastIndex { { }, index });
+ continue;
+ }
}
- for (auto index : lastDisplayBoxIndexes.values()) {
- if (lineBox.inlineLevelBoxForLayoutBox(boxes[index].layoutBox()).isLastBox())
- boxes[index].setIsLastForLayoutBox(true);
- }
};
computeIsFirstIsLastBox();
@@ -609,7 +624,7 @@
auto contentRightInVisualOrder = lineBoxLogicalTopLeft.x() + contentStartInVisualOrder;
for (auto childDisplayBoxNodeIndex : displayBoxTree.root().children)
- adjustVisualGeometryForDisplayBox(childDisplayBoxNodeIndex, contentRightInVisualOrder, lineBoxLogicalTopLeft.y(), displayBoxTree, boxes, lineBox);
+ adjustVisualGeometryForDisplayBox(childDisplayBoxNodeIndex, contentRightInVisualOrder, lineBoxLogicalTopLeft.y(), displayBoxTree, boxes, lineBox, isFirstLastIndexesMap);
};
adjustVisualGeometryWithInlineBoxes();
}
Modified: trunk/Source/WebCore/layout/formattingContexts/inline/InlineDisplayContentBuilder.h (287196 => 287197)
--- trunk/Source/WebCore/layout/formattingContexts/inline/InlineDisplayContentBuilder.h 2021-12-17 18:55:42 UTC (rev 287196)
+++ trunk/Source/WebCore/layout/formattingContexts/inline/InlineDisplayContentBuilder.h 2021-12-17 18:58:49 UTC (rev 287197)
@@ -36,6 +36,7 @@
struct AncestorStack;
class ContainerBox;
struct DisplayBoxTree;
+struct IsFirstLastIndex;
class InlineFormattingState;
class LineBox;
@@ -62,7 +63,7 @@
void appendInlineDisplayBoxAtBidiBoundary(const Box&, DisplayBoxes&);
void setInlineBoxGeometry(const Box&, const InlineRect&, bool isFirstInlineBoxFragment);
- void adjustVisualGeometryForDisplayBox(size_t displayBoxNodeIndex, InlineLayoutUnit& accumulatedOffset, InlineLayoutUnit lineBoxLogicalTop, const DisplayBoxTree&, DisplayBoxes&, const LineBox&);
+ void adjustVisualGeometryForDisplayBox(size_t displayBoxNodeIndex, InlineLayoutUnit& accumulatedOffset, InlineLayoutUnit lineBoxLogicalTop, const DisplayBoxTree&, DisplayBoxes&, const LineBox&, const HashMap<const Box*, IsFirstLastIndex>&);
size_t ensureDisplayBoxForContainer(const ContainerBox&, DisplayBoxTree&, AncestorStack&, DisplayBoxes&);
const ContainerBox& root() const { return m_formattingContextRoot; }