Modified: trunk/Source/WebCore/layout/inlineformatting/InlineFormattingContext.cpp (270428 => 270429)
--- trunk/Source/WebCore/layout/inlineformatting/InlineFormattingContext.cpp 2020-12-04 13:35:23 UTC (rev 270428)
+++ trunk/Source/WebCore/layout/inlineformatting/InlineFormattingContext.cpp 2020-12-04 13:48:09 UTC (rev 270429)
@@ -149,10 +149,11 @@
size_t overflowContentLength { 0 };
};
Optional<PreviousLine> previousLine;
- auto floatingContext = FloatingContext { *this, formattingState().floatingState() };
+ auto& floatingState = formattingState().floatingState();
+ auto floatingContext = FloatingContext { *this, floatingState };
auto isFirstLine = formattingState().lines().isEmpty();
- auto lineBuilder = LineBuilder { *this, floatingContext, inlineItems };
+ auto lineBuilder = LineBuilder { *this, floatingState, constraints.horizontal, inlineItems };
while (!needsLayoutRange.isEmpty()) {
// Turn previous line's overflow content length into the next line's leading content partial length.
// "sp[<-line break->]lit_content" -> overflow length: 11 -> leading partial content length: 11.
@@ -261,19 +262,19 @@
InlineLayoutUnit InlineFormattingContext::computedIntrinsicWidthForConstraint(InlineLayoutUnit availableWidth) const
{
auto& inlineItems = formattingState().inlineItems();
- // Preferred width computation is not constrained by floats.
- auto floatingState = FloatingState::create(layoutState(), root());
- auto floatingContext = FloatingContext { *this, floatingState };
- auto lineBuilder = LineBuilder { *this, floatingContext, inlineItems };
+ auto lineBuilder = LineBuilder { *this, inlineItems };
auto layoutRange = LineBuilder::InlineItemRange { 0 , inlineItems.size() };
auto maximumLineWidth = InlineLayoutUnit { };
+ auto maximumFloatWidth = LayoutUnit { };
while (!layoutRange.isEmpty()) {
auto intrinsicContent = lineBuilder.computedIntrinsicWidth(layoutRange, availableWidth);
layoutRange.start = intrinsicContent.inlineItemRange.end;
- // FIXME: Use line logical left and right to take floats into account.
maximumLineWidth = std::max(maximumLineWidth, intrinsicContent.logicalWidth);
+ // FIXME: Add support for clear.
+ for (auto* floatBox : intrinsicContent.floats)
+ maximumFloatWidth += geometryForBox(*floatBox).marginBoxWidth();
}
- return maximumLineWidth;
+ return maximumLineWidth + maximumFloatWidth;
}
void InlineFormattingContext::computeIntrinsicWidthForFormattingRoot(const Box& formattingRoot)
@@ -414,23 +415,6 @@
const auto& lineBox = formattingState.lineBoxes().last();
auto& lineBoxLogicalRect = lineBox.logicalRect();
- auto updateFloatGeometry = [&] {
- if (lineContent.floats.isEmpty())
- return;
- auto& floatingState = formattingState.floatingState();
- auto floatingContext = FloatingContext { *this, floatingState };
- // Move floats to their final position.
- for (auto* floatBox : lineContent.floats) {
- auto& boxGeometry = formattingState.boxGeometry(*floatBox);
- // Set static position first.
- boxGeometry.setLogicalTopLeft({ lineBoxLogicalRect.left(), lineBoxLogicalRect.top() });
- // Float it.
- boxGeometry.setLogicalTopLeft(floatingContext.positionForFloat(*floatBox, horizontalConstraints));
- floatingState.append(floatingContext.toFloatItem(*floatBox));
- }
- };
- updateFloatGeometry();
-
auto constructLineRuns = [&] {
auto lineIndex = formattingState.lines().size();
// Create the inline runs on the current line. This is mostly text and atomic inline runs.
Modified: trunk/Source/WebCore/layout/inlineformatting/InlineLineBuilder.cpp (270428 => 270429)
--- trunk/Source/WebCore/layout/inlineformatting/InlineLineBuilder.cpp 2020-12-04 13:35:23 UTC (rev 270428)
+++ trunk/Source/WebCore/layout/inlineformatting/InlineLineBuilder.cpp 2020-12-04 13:48:09 UTC (rev 270429)
@@ -230,14 +230,23 @@
return boxGeometry.marginBoxWidth();
}
-LineBuilder::LineBuilder(const InlineFormattingContext& inlineFormattingContext, const FloatingContext& floatingContext, const InlineItems& inlineItems)
+LineBuilder::LineBuilder(InlineFormattingContext& inlineFormattingContext, FloatingState& floatingState, HorizontalConstraints rootHorizontalConstraints, const InlineItems& inlineItems)
: m_inlineFormattingContext(inlineFormattingContext)
- , m_floatingContext(floatingContext)
+ , m_inlineFormattingState(&inlineFormattingContext.formattingState())
+ , m_floatingState(&floatingState)
+ , m_rootHorizontalConstraints(rootHorizontalConstraints)
, m_line(inlineFormattingContext)
, m_inlineItems(inlineItems)
{
}
+LineBuilder::LineBuilder(const InlineFormattingContext& inlineFormattingContext, const InlineItems& inlineItems)
+ : m_inlineFormattingContext(inlineFormattingContext)
+ , m_line(inlineFormattingContext)
+ , m_inlineItems(inlineItems)
+{
+}
+
LineBuilder::LineContent LineBuilder::layoutInlineContent(const InlineItemRange& needsLayoutRange, size_t partialLeadingContentLength, const InlineRect& initialConstraintsForLine, bool isFirstLine)
{
auto usedConstraints = constraintsForLine(initialConstraintsForLine, isFirstLine);
@@ -246,7 +255,7 @@
auto committedContent = placeInlineContent(needsLayoutRange, partialLeadingContentLength);
auto committedRange = close(needsLayoutRange, committedContent);
- auto lineLogicalTopLeft = InlineLayoutPoint { usedConstraints.logicalLeft, initialConstraintsForLine.top() };
+ auto lineLogicalTopLeft = usedConstraints.logicalTopLeft;
auto isLastLine = isLastLineWithInlineContent(committedRange, needsLayoutRange.end, committedContent.partialTrailingContentLength);
return LineContent { committedRange, committedContent.partialTrailingContentLength, m_floats, m_contentIsConstrainedByFloat
, lineLogicalTopLeft
@@ -262,7 +271,7 @@
initialize({ { }, availableWidth, false });
auto committedContent = placeInlineContent(needsLayoutRange, { });
auto committedRange = close(needsLayoutRange, committedContent);
- return { committedRange, m_line.contentLogicalWidth() };
+ return { committedRange, m_line.contentLogicalWidth(), m_floats };
}
void LineBuilder::initialize(const UsedConstraints& lineConstraints)
@@ -274,6 +283,7 @@
m_line.initialize();
m_contentIsConstrainedByFloat = lineConstraints.isConstrainedByFloat;
m_horizontalSpaceForLine = lineConstraints.logicalWidth;
+ m_lineLogicalTopLeft = lineConstraints.logicalTopLeft;
}
LineBuilder::CommittedContent LineBuilder::placeInlineContent(const InlineItemRange& needsLayoutRange, size_t partialLeadingContentLength)
@@ -360,28 +370,31 @@
auto lineIsConstrainedByFloat = false;
// Check for intruding floats and adjust logical left/available width for this line accordingly.
- if (!m_floatingContext.isEmpty()) {
- // FIXME: Add support for variable line height, where the floats should be probed as the line height grows.
- auto floatConstraints = m_floatingContext.constraints(toLayoutUnit(lineLogicalTop), toLayoutUnit(lineLogicalTop + lineLogicalConstraints.height()));
- // Check if these values actually constrain the line.
- if (floatConstraints.left && floatConstraints.left->x <= lineLogicalLeft)
- floatConstraints.left = { };
+ if (auto* floatingState = this->floatingState()) {
+ auto floatingContext = FloatingContext { formattingContext(), *floatingState };
+ if (!floatingContext.isEmpty()) {
+ // FIXME: Add support for variable line height, where the floats should be probed as the line height grows.
+ auto floatConstraints = floatingContext.constraints(toLayoutUnit(lineLogicalTop), toLayoutUnit(lineLogicalTop + lineLogicalConstraints.height()));
+ // Check if these values actually constrain the line.
+ if (floatConstraints.left && floatConstraints.left->x <= lineLogicalLeft)
+ floatConstraints.left = { };
- if (floatConstraints.right && floatConstraints.right->x >= lineLogicalRight)
- floatConstraints.right = { };
+ if (floatConstraints.right && floatConstraints.right->x >= lineLogicalRight)
+ floatConstraints.right = { };
- lineIsConstrainedByFloat = floatConstraints.left || floatConstraints.right;
+ lineIsConstrainedByFloat = floatConstraints.left || floatConstraints.right;
- if (floatConstraints.left && floatConstraints.right) {
- ASSERT(floatConstraints.left->x <= floatConstraints.right->x);
- lineLogicalRight = floatConstraints.right->x;
- lineLogicalLeft = floatConstraints.left->x;
- } else if (floatConstraints.left) {
- ASSERT(floatConstraints.left->x >= lineLogicalLeft);
- lineLogicalLeft = floatConstraints.left->x;
- } else if (floatConstraints.right) {
- // Right float boxes may overflow the containing block on the left.
- lineLogicalRight = std::max<InlineLayoutUnit>(lineLogicalLeft, floatConstraints.right->x);
+ if (floatConstraints.left && floatConstraints.right) {
+ ASSERT(floatConstraints.left->x <= floatConstraints.right->x);
+ lineLogicalRight = floatConstraints.right->x;
+ lineLogicalLeft = floatConstraints.left->x;
+ } else if (floatConstraints.left) {
+ ASSERT(floatConstraints.left->x >= lineLogicalLeft);
+ lineLogicalLeft = floatConstraints.left->x;
+ } else if (floatConstraints.right) {
+ // Right float boxes may overflow the containing block on the left.
+ lineLogicalRight = std::max<InlineLayoutUnit>(lineLogicalLeft, floatConstraints.right->x);
+ }
}
}
@@ -423,7 +436,7 @@
return { minimumValueForLength(textIndent, lineLogicalConstraints.width()) };
};
lineLogicalLeft += computedTextIndent();
- return UsedConstraints { lineLogicalLeft, lineLogicalRight - lineLogicalLeft, lineIsConstrainedByFloat };
+ return UsedConstraints { { lineLogicalLeft, lineLogicalTop }, lineLogicalRight - lineLogicalLeft, lineIsConstrainedByFloat };
}
void LineBuilder::candidateContentForLine(LineCandidate& lineCandidate, size_t currentInlineItemIndex, const InlineItemRange& layoutRange, size_t partialLeadingContentLength, InlineLayoutUnit currentLogicalRight)
@@ -539,6 +552,20 @@
auto& floatBox = floatItem.layoutBox();
m_floats.append(&floatBox);
m_contentIsConstrainedByFloat = true;
+
+ if (auto* floatingState = this->floatingState()) {
+ ASSERT(formattingState());
+ auto& boxGeometry = formattingState()->boxGeometry(floatBox);
+ // Set static position first.
+ boxGeometry.setLogicalTopLeft(LayoutPoint { m_lineLogicalTopLeft });
+ // Float it.
+ ASSERT(m_rootHorizontalConstraints);
+ auto floatingContext = FloatingContext { formattingContext(), *floatingState };
+ auto floatingPosition = floatingContext.positionForFloat(floatBox, *m_rootHorizontalConstraints);
+ boxGeometry.setLogicalTopLeft(floatingPosition);
+ floatingState->append(floatingContext.toFloatItem(floatBox));
+ }
+
if (floatBox.isLeftFloatingPositioned())
m_line.moveLogicalLeft(floatBoxWidth);
m_horizontalSpaceForLine -= floatBoxWidth;
Modified: trunk/Source/WebCore/layout/inlineformatting/InlineLineBuilder.h (270428 => 270429)
--- trunk/Source/WebCore/layout/inlineformatting/InlineLineBuilder.h 2020-12-04 13:35:23 UTC (rev 270428)
+++ trunk/Source/WebCore/layout/inlineformatting/InlineLineBuilder.h 2020-12-04 13:48:09 UTC (rev 270429)
@@ -39,7 +39,8 @@
class LineBuilder {
public:
- LineBuilder(const InlineFormattingContext&, const FloatingContext&, const InlineItems&);
+ LineBuilder(InlineFormattingContext&, FloatingState&, HorizontalConstraints rootHorizontalConstraints, const InlineItems&);
+ LineBuilder(const InlineFormattingContext&, const InlineItems&);
struct InlineItemRange {
bool isEmpty() const { return start == end; }
@@ -47,10 +48,10 @@
size_t start { 0 };
size_t end { 0 };
};
+ using FloatList = Vector<const Box*>;
struct LineContent {
InlineItemRange inlineItemRange;
size_t partialTrailingContentLength { 0 };
- using FloatList = Vector<const Box*>;
const FloatList& floats;
bool hasIntrusiveFloat { false };
InlineLayoutPoint logicalTopLeft;
@@ -65,6 +66,7 @@
struct IntrinsicContent {
InlineItemRange inlineItemRange;
InlineLayoutUnit logicalWidth { 0 };
+ const FloatList& floats;
};
IntrinsicContent computedIntrinsicWidth(const InlineItemRange&, InlineLayoutUnit availableWidth);
@@ -82,7 +84,7 @@
size_t partialTrailingContentLength { 0 };
};
struct UsedConstraints {
- InlineLayoutUnit logicalLeft { 0 };
+ InlineLayoutPoint logicalTopLeft;
InlineLayoutUnit logicalWidth { 0 };
bool isConstrainedByFloat { false };
};
@@ -104,15 +106,21 @@
bool isLastLineWithInlineContent(const InlineItemRange& lineRange, size_t lastInlineItemIndex, bool hasPartialTrailingContent) const;
const InlineFormattingContext& formattingContext() const { return m_inlineFormattingContext; }
+ InlineFormattingState* formattingState() { return m_inlineFormattingState; }
+ FloatingState* floatingState() { return m_floatingState; }
const ContainerBox& root() const;
const LayoutState& layoutState() const;
const InlineFormattingContext& m_inlineFormattingContext;
- const FloatingContext& m_floatingContext;
+ InlineFormattingState* m_inlineFormattingState { nullptr };
+ FloatingState* m_floatingState { nullptr };
+ Optional<HorizontalConstraints> m_rootHorizontalConstraints;
+
Line m_line;
+ InlineLayoutPoint m_lineLogicalTopLeft;
InlineLayoutUnit m_horizontalSpaceForLine { 0 };
const InlineItems& m_inlineItems;
- LineContent::FloatList m_floats;
+ FloatList m_floats;
Optional<InlineTextItem> m_partialLeadingTextItem;
Vector<const InlineItem*> m_wrapOpportunityList;
unsigned m_successiveHyphenatedLineCount { 0 };