Diff
Modified: trunk/Source/WebCore/ChangeLog (246482 => 246483)
--- trunk/Source/WebCore/ChangeLog 2019-06-16 20:15:02 UTC (rev 246482)
+++ trunk/Source/WebCore/ChangeLog 2019-06-16 20:19:24 UTC (rev 246483)
@@ -1,5 +1,27 @@
2019-06-16 Zalan Bujtas <[email protected]>
+ [LFC][IFC] Intruding float may prevent adding any inline box
+ https://bugs.webkit.org/show_bug.cgi?id=198891
+ <rdar://problem/51779956>
+
+ Reviewed by Antti Koivisto.
+
+ Take the intruding left/right float pair and find the vertical position where the next line might go
+ if these floats prevent us from adding even one inline box to the current line.
+
+ * layout/FormattingContext.cpp:
+ (WebCore::Layout::FormattingContext::mapPointToAncestor):
+ (WebCore::Layout::FormattingContext::mapPointToDescendent):
+ * layout/FormattingContext.h:
+ * layout/LayoutUnits.h:
+ (WebCore::Layout::Point::max):
+ * layout/inlineformatting/InlineFormattingContext.h:
+ * layout/inlineformatting/InlineFormattingContextLineLayout.cpp:
+ (WebCore::Layout::InlineFormattingContext::LineLayout::placeInlineItems const):
+ (WebCore::Layout::InlineFormattingContext::LineLayout::layout const):
+
+2019-06-16 Zalan Bujtas <[email protected]>
+
[LFC][Floats] Add bottom value to FloatingState::Constraints
https://bugs.webkit.org/show_bug.cgi?id=198889
<rdar://problem/51776730>
Modified: trunk/Source/WebCore/layout/FormattingContext.cpp (246482 => 246483)
--- trunk/Source/WebCore/layout/FormattingContext.cpp 2019-06-16 20:15:02 UTC (rev 246482)
+++ trunk/Source/WebCore/layout/FormattingContext.cpp 2019-06-16 20:19:24 UTC (rev 246483)
@@ -211,17 +211,28 @@
return top;
}
-Point FormattingContext::mapPointToAncestor(const LayoutState& layoutState, Point position, const Container& containingBlock, const Container& ancestor)
+Point FormattingContext::mapPointToAncestor(const LayoutState& layoutState, Point position, const Container& from, const Container& to)
{
- if (&containingBlock == &ancestor)
+ if (&from == &to)
return position;
- ASSERT(containingBlock.isContainingBlockDescendantOf(ancestor));
+ ASSERT(from.isContainingBlockDescendantOf(to));
auto mappedPosition = position;
- for (auto* container = &containingBlock; container && container != &ancestor; container = container->containingBlock())
+ for (auto* container = &from; container && container != &to; container = container->containingBlock())
mappedPosition.moveBy(layoutState.displayBoxForLayoutBox(*container).topLeft());
return mappedPosition;
}
+Point FormattingContext::mapPointToDescendent(const LayoutState& layoutState, Point point, const Container& from, const Container& to)
+{
+ // "point" is in the coordinate system of the "from" container.
+ if (&from == &to)
+ return point;
+ ASSERT(to.isContainingBlockDescendantOf(from));
+ for (auto* container = &to; container && container != &from; container = container->containingBlock())
+ point.moveBy(-layoutState.displayBoxForLayoutBox(*container).topLeft());
+ return point;
+}
+
#ifndef NDEBUG
void FormattingContext::validateGeometryConstraintsAfterLayout() const
{
Modified: trunk/Source/WebCore/layout/FormattingContext.h (246482 => 246483)
--- trunk/Source/WebCore/layout/FormattingContext.h 2019-06-16 20:15:02 UTC (rev 246482)
+++ trunk/Source/WebCore/layout/FormattingContext.h 2019-06-16 20:19:24 UTC (rev 246483)
@@ -62,7 +62,8 @@
static LayoutUnit mapTopToAncestor(const LayoutState&, const Box&, const Container& ancestor);
static LayoutUnit mapLeftToAncestor(const LayoutState&, const Box&, const Container& ancestor);
static LayoutUnit mapRightToAncestor(const LayoutState&, const Box&, const Container& ancestor);
- static Point mapPointToAncestor(const LayoutState&, Point, const Container& containingBlock, const Container& ancestor);
+ static Point mapPointToAncestor(const LayoutState&, Point, const Container& from, const Container& to);
+ static Point mapPointToDescendent(const LayoutState&, Point, const Container& from, const Container& to);
protected:
using LayoutQueue = Vector<const Box*>;
Modified: trunk/Source/WebCore/layout/LayoutUnits.h (246482 => 246483)
--- trunk/Source/WebCore/layout/LayoutUnits.h 2019-06-16 20:15:02 UTC (rev 246482)
+++ trunk/Source/WebCore/layout/LayoutUnits.h 2019-06-16 20:19:24 UTC (rev 246483)
@@ -59,6 +59,8 @@
Point() = default;
Point(LayoutUnit, LayoutUnit);
Point(LayoutPoint);
+ static Point max() { return { LayoutUnit::max(), LayoutUnit::max() }; }
+
void move(LayoutSize);
void moveBy(LayoutPoint);
operator LayoutPoint() const { return { x, y }; }
Modified: trunk/Source/WebCore/layout/inlineformatting/InlineFormattingContext.h (246482 => 246483)
--- trunk/Source/WebCore/layout/inlineformatting/InlineFormattingContext.h 2019-06-16 20:15:02 UTC (rev 246482)
+++ trunk/Source/WebCore/layout/inlineformatting/InlineFormattingContext.h 2019-06-16 20:19:24 UTC (rev 246483)
@@ -79,6 +79,7 @@
SkipVerticalAligment skipVerticalAligment;
unsigned firstInlineItemIndex { 0 };
const InlineItems& inlineItems;
+ Optional<LayoutUnit> floatMinimumLogicalBottom;
};
LineContent placeInlineItems(const LineInput&) const;
void createDisplayRuns(const Line::Content&, const Vector<WeakPtr<InlineItem>>& floats, LayoutUnit widthConstraint) const;
Modified: trunk/Source/WebCore/layout/inlineformatting/InlineFormattingContextLineLayout.cpp (246482 => 246483)
--- trunk/Source/WebCore/layout/inlineformatting/InlineFormattingContextLineLayout.cpp 2019-06-16 20:15:02 UTC (rev 246482)
+++ trunk/Source/WebCore/layout/inlineformatting/InlineFormattingContextLineLayout.cpp 2019-06-16 20:19:24 UTC (rev 246483)
@@ -161,10 +161,11 @@
uncommittedContent.reset();
};
+ auto lineHasFloatBox = lineInput.floatMinimumLogicalBottom.hasValue();
auto closeLine = [&] {
- // This might change at some point.
- ASSERT(committedInlineItemCount);
- return LineContent { lineInput.firstInlineItemIndex + (committedInlineItemCount - 1), WTFMove(floats), line->close() };
+ ASSERT(committedInlineItemCount || lineHasFloatBox);
+ auto lastCommittedIndex = committedInlineItemCount ? Optional<unsigned> { lineInput.firstInlineItemIndex + (committedInlineItemCount - 1) } : WTF::nullopt;
+ return LineContent { lastCommittedIndex, WTFMove(floats), line->close() };
};
LineBreaker lineBreaker;
// Iterate through the inline content and place the inline boxes on the current line.
@@ -175,7 +176,8 @@
auto itemLogicalWidth = inlineItemWidth(layoutState(), *inlineItem, currentLogicalRight);
// FIXME: Ensure LineContext::trimmableWidth includes uncommitted content if needed.
- auto breakingContext = lineBreaker.breakingContext(*inlineItem, itemLogicalWidth, { availableWidth, currentLogicalRight, line->trailingTrimmableWidth(), !line->hasContent() });
+ auto lineIsConsideredEmpty = !line->hasContent() && !lineHasFloatBox;
+ auto breakingContext = lineBreaker.breakingContext(*inlineItem, itemLogicalWidth, { availableWidth, currentLogicalRight, line->trailingTrimmableWidth(), lineIsConsideredEmpty });
if (breakingContext.isAtBreakingOpportunity)
commitPendingContent();
@@ -200,6 +202,7 @@
floatBox.isLeftFloatingPositioned() ? line->moveLogicalLeft(floatBoxWidth) : line->moveLogicalRight(floatBoxWidth);
floats.append(makeWeakPtr(*inlineItem));
++committedInlineItemCount;
+ lineHasFloatBox = true;
continue;
}
@@ -222,12 +225,12 @@
auto lineLogicalTop = formattingRootDisplayBox.contentBoxTop();
auto lineLogicalLeft = formattingRootDisplayBox.contentBoxLeft();
- auto applyFloatConstraint = [&](auto& lineHorizontalConstraint) {
+ auto applyFloatConstraint = [&](auto& lineInput) {
// Check for intruding floats and adjust logical left/available width for this line accordingly.
if (m_floatingState.isEmpty())
return;
- auto availableWidth = lineHorizontalConstraint.availableLogicalWidth;
- auto lineLogicalLeft = lineHorizontalConstraint.logicalTopLeft.x();
+ auto availableWidth = lineInput.horizontalConstraint.availableLogicalWidth;
+ auto lineLogicalLeft = lineInput.horizontalConstraint.logicalTopLeft.x();
auto floatConstraints = m_floatingState.constraints({ lineLogicalTop }, m_formattingRoot);
// Check if these constraints actually put limitation on the line.
if (floatConstraints.left && floatConstraints.left->x <= formattingRootDisplayBox.contentBoxLeft())
@@ -236,20 +239,26 @@
if (floatConstraints.right && floatConstraints.right->x >= formattingRootDisplayBox.contentBoxRight())
floatConstraints.right = { };
+ // Set the minimum float bottom value as a hint for the next line if needed.
+ static auto inifitePoint = PointInContextRoot::max();
+ auto floatMinimumLogicalBottom = std::min(floatConstraints.left.valueOr(inifitePoint).y, floatConstraints.right.valueOr(inifitePoint).y);
+ if (floatMinimumLogicalBottom != inifitePoint.y)
+ lineInput.floatMinimumLogicalBottom = floatMinimumLogicalBottom;
+
if (floatConstraints.left && floatConstraints.right) {
- ASSERT(floatConstraints.left->x < floatConstraints.right->x);
+ ASSERT(floatConstraints.left->x <= floatConstraints.right->x);
availableWidth = floatConstraints.right->x - floatConstraints.left->x;
lineLogicalLeft = floatConstraints.left->x;
} else if (floatConstraints.left) {
- ASSERT(floatConstraints.left->x > lineLogicalLeft);
+ ASSERT(floatConstraints.left->x >= lineLogicalLeft);
availableWidth -= (floatConstraints.left->x - lineLogicalLeft);
lineLogicalLeft = floatConstraints.left->x;
} else if (floatConstraints.right) {
- ASSERT(floatConstraints.right->x > lineLogicalLeft);
+ ASSERT(floatConstraints.right->x >= lineLogicalLeft);
availableWidth = floatConstraints.right->x - lineLogicalLeft;
}
- lineHorizontalConstraint.availableLogicalWidth = availableWidth;
- lineHorizontalConstraint.logicalTopLeft.setX(lineLogicalLeft);
+ lineInput.horizontalConstraint.availableLogicalWidth = availableWidth;
+ lineInput.horizontalConstraint.logicalTopLeft.setX(lineLogicalLeft);
};
auto& inlineItems = m_formattingState.inlineItems();
@@ -256,13 +265,18 @@
unsigned currentInlineItemIndex = 0;
while (currentInlineItemIndex < inlineItems.size()) {
auto lineInput = LineInput { { lineLogicalLeft, lineLogicalTop }, widthConstraint, LineInput::SkipVerticalAligment::No, currentInlineItemIndex, inlineItems };
- applyFloatConstraint(lineInput.horizontalConstraint);
+ applyFloatConstraint(lineInput);
auto lineContent = placeInlineItems(lineInput);
createDisplayRuns(*lineContent.runs, lineContent.floats, widthConstraint);
- // We should always put at least one run on the line atm. This might change later on though.
- ASSERT(lineContent.lastInlineItemIndex);
- currentInlineItemIndex = *lineContent.lastInlineItemIndex + 1;
- lineLogicalTop = lineContent.runs->logicalBottom();
+ if (!lineContent.lastInlineItemIndex) {
+ // Floats prevented us putting any content on the line.
+ ASSERT(lineInput.floatMinimumLogicalBottom);
+ ASSERT(lineContent.runs->isEmpty());
+ lineLogicalTop = *lineInput.floatMinimumLogicalBottom;
+ } else {
+ currentInlineItemIndex = *lineContent.lastInlineItemIndex + 1;
+ lineLogicalTop = lineContent.runs->logicalBottom();
+ }
}
}