Source/WebCore/ChangeLog

 12019-07-06 Zalan Bujtas <zalan@apple.com>
 2
 3 [LFC][IFC] Introduce splitPosition to LineLayout
 4 https://bugs.webkit.org/show_bug.cgi?id=199558
 5 <rdar://problem/52737649>
 6
 7 Reviewed by NOBODY (OOPS!).
 8
 9 This is in preparation for breaking runs at line end.
 10
 11 * layout/inlineformatting/InlineFormattingContext.h:
 12 * layout/inlineformatting/InlineFormattingContextLineLayout.cpp:
 13 (WebCore::Layout::InlineFormattingContext::LineLayout::LineInput::LineInput):
 14 (WebCore::Layout::InlineFormattingContext::LineLayout::placeInlineItems const):
 15 (WebCore::Layout::InlineFormattingContext::LineLayout::layout const):
 16 (WebCore::Layout::InlineFormattingContext::LineLayout::computedIntrinsicWidth const):
 17
1182019-07-06 Zalan Bujtas <zalan@apple.com>
219
320 [LFC] Fix formatting context root for inflow positioned inline containers

Source/WebCore/layout/inlineformatting/InlineFormattingContext.h

@@private:
5959 private:
6060 LayoutState& layoutState() const { return m_formattingContext.layoutState(); }
6161
62  struct LineContent {
63  Optional<unsigned> lastInlineItemIndex;
64  Vector<WeakPtr<InlineItem>> floats;
65  std::unique_ptr<Line::Content> runs;
 62 struct InlineIndexAndSplitPosition {
 63 unsigned index { 0 };
 64 Optional<unsigned> splitPosition;
6665 };
6766
6867 struct LineInput {
69  LineInput(LayoutPoint logicalTopLeft, LayoutUnit availableLogicalWidth, Line::SkipVerticalAligment, unsigned firstInlineItemIndex, const InlineItems&);
 68 LineInput(LayoutPoint logicalTopLeft, LayoutUnit availableLogicalWidth, Line::SkipVerticalAligment, InlineIndexAndSplitPosition firstToProcess, const InlineItems&);
7069 struct HorizontalConstraint {
7170 HorizontalConstraint(LayoutPoint logicalTopLeft, LayoutUnit availableLogicalWidth);
7271

@@private:
7675 HorizontalConstraint horizontalConstraint;
7776 // FIXME Alternatively we could just have a second pass with vertical positioning (preferred width computation opts out)
7877 Line::SkipVerticalAligment skipVerticalAligment;
79  unsigned firstInlineItemIndex { 0 };
 78 InlineIndexAndSplitPosition firstInlineItem;
8079 const InlineItems& inlineItems;
8180 Optional<LayoutUnit> floatMinimumLogicalBottom;
8281 };
 82
 83 struct LineContent {
 84 Optional<InlineIndexAndSplitPosition> lastCommitted;
 85 Vector<WeakPtr<InlineItem>> floats;
 86 std::unique_ptr<Line::Content> runs;
 87 };
8388 LineContent placeInlineItems(const LineInput&) const;
8489 void createDisplayRuns(const Line::Content&, const Vector<WeakPtr<InlineItem>>& floats, LayoutUnit widthConstraint) const;
8590 void alignRuns(TextAlignMode, unsigned firstRunIndex, LayoutUnit availableWidth) const;

Source/WebCore/layout/inlineformatting/InlineFormattingContextLineLayout.cpp

@@InlineFormattingContext::LineLayout::LineInput::HorizontalConstraint::Horizontal
7878{
7979}
8080
81 InlineFormattingContext::LineLayout::LineInput::LineInput(LayoutPoint logicalTopLeft, LayoutUnit availableLogicalWidth, Line::SkipVerticalAligment skipVerticalAligment, unsigned firstInlineItemIndex, const InlineItems& inlineItems)
 81InlineFormattingContext::LineLayout::LineInput::LineInput(LayoutPoint logicalTopLeft, LayoutUnit availableLogicalWidth, Line::SkipVerticalAligment skipVerticalAligment, InlineIndexAndSplitPosition firstToProcess, const InlineItems& inlineItems)
8282 : horizontalConstraint(logicalTopLeft, availableLogicalWidth)
8383 , skipVerticalAligment(skipVerticalAligment)
84  , firstInlineItemIndex(firstInlineItemIndex)
 84 , firstInlineItem(firstToProcess)
8585 , inlineItems(inlineItems)
8686{
8787}

@@InlineFormattingContext::LineLayout::LineContent InlineFormattingContext::LineLa
136136
137137 Vector<WeakPtr<InlineItem>> floats;
138138 unsigned committedInlineItemCount = 0;
 139 Optional<unsigned> splitPosition;
139140
140141 UncommittedContent uncommittedContent;
141142 auto commitPendingContent = [&] {

@@InlineFormattingContext::LineLayout::LineContent InlineFormattingContext::LineLa
150151 auto lineHasFloatBox = lineInput.floatMinimumLogicalBottom.hasValue();
151152 auto closeLine = [&] {
152153 ASSERT(committedInlineItemCount || lineHasFloatBox);
153  auto lastCommittedIndex = committedInlineItemCount ? Optional<unsigned> { lineInput.firstInlineItemIndex + (committedInlineItemCount - 1) } : WTF::nullopt;
154  return LineContent { lastCommittedIndex, WTFMove(floats), line.close() };
 154 if (!committedInlineItemCount)
 155 return LineContent { WTF::nullopt, WTFMove(floats), line.close() };
 156 auto lastCommitedItem = InlineIndexAndSplitPosition { lineInput.firstInlineItem.index + (committedInlineItemCount - 1), splitPosition };
 157 return LineContent { lastCommitedItem, WTFMove(floats), line.close() };
155158 };
156159 LineBreaker lineBreaker;
157160 // Iterate through the inline content and place the inline boxes on the current line.
158  for (auto inlineItemIndex = lineInput.firstInlineItemIndex; inlineItemIndex < lineInput.inlineItems.size(); ++inlineItemIndex) {
 161 for (auto inlineItemIndex = lineInput.firstInlineItem.index; inlineItemIndex < lineInput.inlineItems.size(); ++inlineItemIndex) {
159162 auto availableWidth = line.availableWidth() - uncommittedContent.width();
160163 auto currentLogicalRight = line.contentLogicalRight() + uncommittedContent.width();
161164 auto& inlineItem = lineInput.inlineItems[inlineItemIndex];

@@void InlineFormattingContext::LineLayout::layout(LayoutUnit widthConstraint) con
248251 };
249252
250253 auto& inlineItems = m_formattingState.inlineItems();
251  unsigned currentInlineItemIndex = 0;
252  while (currentInlineItemIndex < inlineItems.size()) {
253  auto lineInput = LineInput { { lineLogicalLeft, lineLogicalTop }, widthConstraint, Line::SkipVerticalAligment::No, currentInlineItemIndex, inlineItems };
 254 InlineIndexAndSplitPosition currentInlineItem;
 255 while (currentInlineItem.index < inlineItems.size()) {
 256 auto lineInput = LineInput { { lineLogicalLeft, lineLogicalTop }, widthConstraint, Line::SkipVerticalAligment::No, currentInlineItem, inlineItems };
254257 applyFloatConstraint(lineInput);
255258 auto lineContent = placeInlineItems(lineInput);
256259 createDisplayRuns(*lineContent.runs, lineContent.floats, widthConstraint);
257  if (!lineContent.lastInlineItemIndex) {
 260 if (!lineContent.lastCommitted) {
258261 // Floats prevented us putting any content on the line.
259262 ASSERT(lineInput.floatMinimumLogicalBottom);
260263 ASSERT(lineContent.runs->isEmpty());
261264 lineLogicalTop = *lineInput.floatMinimumLogicalBottom;
262265 } else {
263  currentInlineItemIndex = *lineContent.lastInlineItemIndex + 1;
 266 currentInlineItem = { lineContent.lastCommitted->index + 1, WTF::nullopt };
264267 lineLogicalTop = lineContent.runs->logicalBottom();
265268 }
266269 }

@@LayoutUnit InlineFormattingContext::LineLayout::computedIntrinsicWidth(LayoutUni
270273{
271274 LayoutUnit maximumLineWidth;
272275 auto& inlineItems = m_formattingState.inlineItems();
273  unsigned currentInlineItemIndex = 0;
274  while (currentInlineItemIndex < inlineItems.size()) {
275  auto lineContent = placeInlineItems({ { }, widthConstraint, Line::SkipVerticalAligment::Yes, currentInlineItemIndex, inlineItems });
276  currentInlineItemIndex = *lineContent.lastInlineItemIndex + 1;
 276 InlineIndexAndSplitPosition currentInlineItem;
 277 while (currentInlineItem.index < inlineItems.size()) {
 278 auto lineContent = placeInlineItems({ { }, widthConstraint, Line::SkipVerticalAligment::Yes, currentInlineItem, inlineItems });
 279 currentInlineItem = { lineContent.lastCommitted->index + 1, WTF::nullopt };
277280 LayoutUnit floatsWidth;
278281 for (auto& floatItem : lineContent.floats)
279282 floatsWidth += layoutState().displayBoxForLayoutBox(floatItem->layoutBox()).marginBoxWidth();