3b287f809f14af7c0224713f5f122c679f3f9053
[WebKit-https.git] / Source / WebCore / rendering / RenderBlockFlow.cpp
1 /*
2  * Copyright (C) 1999 Lars Knoll (knoll@kde.org)
3  *           (C) 1999 Antti Koivisto (koivisto@kde.org)
4  *           (C) 2007 David Smith (catfish.man@gmail.com)
5  * Copyright (C) 2003-2015 Apple Inc. All rights reserved.
6  * Copyright (C) Research In Motion Limited 2010. All rights reserved.
7  *
8  * This library is free software; you can redistribute it and/or
9  * modify it under the terms of the GNU Library General Public
10  * License as published by the Free Software Foundation; either
11  * version 2 of the License, or (at your option) any later version.
12  *
13  * This library is distributed in the hope that it will be useful,
14  * but WITHOUT ANY WARRANTY; without even the implied warranty of
15  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
16  * Library General Public License for more details.
17  *
18  * You should have received a copy of the GNU Library General Public License
19  * along with this library; see the file COPYING.LIB.  If not, write to
20  * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
21  * Boston, MA 02110-1301, USA.
22  */
23
24 #include "config.h"
25 #include "RenderBlockFlow.h"
26
27 #include "Editor.h"
28 #include "FloatingObjects.h"
29 #include "Frame.h"
30 #include "FrameSelection.h"
31 #include "HTMLElement.h"
32 #include "HTMLInputElement.h"
33 #include "HTMLTextAreaElement.h"
34 #include "HitTestLocation.h"
35 #include "InlineTextBox.h"
36 #include "LayoutRepainter.h"
37 #include "Logging.h"
38 #include "RenderCombineText.h"
39 #include "RenderFlexibleBox.h"
40 #include "RenderInline.h"
41 #include "RenderIterator.h"
42 #include "RenderLayer.h"
43 #include "RenderLineBreak.h"
44 #include "RenderListItem.h"
45 #include "RenderMarquee.h"
46 #include "RenderMultiColumnFlowThread.h"
47 #include "RenderMultiColumnSet.h"
48 #include "RenderNamedFlowFragment.h"
49 #include "RenderNamedFlowThread.h"
50 #include "RenderTableCell.h"
51 #include "RenderText.h"
52 #include "RenderView.h"
53 #include "Settings.h"
54 #include "SimpleLineLayoutFunctions.h"
55 #include "SimpleLineLayoutPagination.h"
56 #include "VerticalPositionCache.h"
57 #include "VisiblePosition.h"
58
59 namespace WebCore {
60
61 bool RenderBlock::s_canPropagateFloatIntoSibling = false;
62
63 struct SameSizeAsMarginInfo {
64     uint32_t bitfields : 16;
65     LayoutUnit margins[2];
66 };
67
68 COMPILE_ASSERT(sizeof(RenderBlockFlow::MarginValues) == sizeof(LayoutUnit[4]), MarginValues_should_stay_small);
69 COMPILE_ASSERT(sizeof(RenderBlockFlow::MarginInfo) == sizeof(SameSizeAsMarginInfo), MarginInfo_should_stay_small);
70
71 class PaginatedLayoutStateMaintainer {
72 public:
73     PaginatedLayoutStateMaintainer(RenderBlockFlow& flow)
74         : m_flow(flow)
75         , m_pushed(flow.view().pushLayoutStateForPaginationIfNeeded(flow))
76     {
77     }
78
79     ~PaginatedLayoutStateMaintainer()
80     {
81         if (m_pushed)
82             m_flow.view().popLayoutState(m_flow);
83     }
84
85 private:
86     RenderBlockFlow& m_flow;
87     bool m_pushed { false };
88 };
89
90 // Our MarginInfo state used when laying out block children.
91 RenderBlockFlow::MarginInfo::MarginInfo(const RenderBlockFlow& block, LayoutUnit beforeBorderPadding, LayoutUnit afterBorderPadding)
92     : m_atBeforeSideOfBlock(true)
93     , m_atAfterSideOfBlock(false)
94     , m_hasMarginBeforeQuirk(false)
95     , m_hasMarginAfterQuirk(false)
96     , m_determinedMarginBeforeQuirk(false)
97     , m_discardMargin(false)
98 {
99     const RenderStyle& blockStyle = block.style();
100     ASSERT(block.isRenderView() || block.parent());
101     m_canCollapseWithChildren = !block.createsNewFormattingContext() && !block.isRenderView();
102
103     m_canCollapseMarginBeforeWithChildren = m_canCollapseWithChildren && !beforeBorderPadding && blockStyle.marginBeforeCollapse() != MSEPARATE;
104
105     // If any height other than auto is specified in CSS, then we don't collapse our bottom
106     // margins with our children's margins. To do otherwise would be to risk odd visual
107     // effects when the children overflow out of the parent block and yet still collapse
108     // with it. We also don't collapse if we have any bottom border/padding.
109     m_canCollapseMarginAfterWithChildren = m_canCollapseWithChildren && !afterBorderPadding
110         && (blockStyle.logicalHeight().isAuto() && !blockStyle.logicalHeight().value()) && blockStyle.marginAfterCollapse() != MSEPARATE;
111     
112     m_quirkContainer = block.isTableCell() || block.isBody();
113
114     m_discardMargin = m_canCollapseMarginBeforeWithChildren && block.mustDiscardMarginBefore();
115
116     m_positiveMargin = (m_canCollapseMarginBeforeWithChildren && !block.mustDiscardMarginBefore()) ? block.maxPositiveMarginBefore() : LayoutUnit();
117     m_negativeMargin = (m_canCollapseMarginBeforeWithChildren && !block.mustDiscardMarginBefore()) ? block.maxNegativeMarginBefore() : LayoutUnit();
118 }
119
120 RenderBlockFlow::RenderBlockFlow(Element& element, RenderStyle&& style)
121     : RenderBlock(element, WTFMove(style), RenderBlockFlowFlag)
122 #if ENABLE(TEXT_AUTOSIZING)
123     , m_widthForTextAutosizing(-1)
124     , m_lineCountForTextAutosizing(NOT_SET)
125 #endif
126 {
127     setChildrenInline(true);
128 }
129
130 RenderBlockFlow::RenderBlockFlow(Document& document, RenderStyle&& style)
131     : RenderBlock(document, WTFMove(style), RenderBlockFlowFlag)
132 #if ENABLE(TEXT_AUTOSIZING)
133     , m_widthForTextAutosizing(-1)
134     , m_lineCountForTextAutosizing(NOT_SET)
135 #endif
136 {
137     setChildrenInline(true);
138 }
139
140 RenderBlockFlow::~RenderBlockFlow()
141 {
142     // Do not add any code here. Add it to willBeDestroyed() instead.
143 }
144
145 void RenderBlockFlow::createMultiColumnFlowThread()
146 {
147     RenderMultiColumnFlowThread* flowThread = new RenderMultiColumnFlowThread(document(), RenderStyle::createAnonymousStyleWithDisplay(style(), BLOCK));
148     flowThread->initializeStyle();
149     setChildrenInline(false); // Do this to avoid wrapping inline children that are just going to move into the flow thread.
150     deleteLines();
151     RenderBlock::addChild(flowThread);
152     flowThread->populate(); // Called after the flow thread is inserted so that we are reachable by the flow thread.
153     setMultiColumnFlowThread(flowThread);
154 }
155
156 void RenderBlockFlow::destroyMultiColumnFlowThread()
157 {
158     multiColumnFlowThread()->evacuateAndDestroy();
159     ASSERT(!multiColumnFlowThread());
160 }
161
162 void RenderBlockFlow::insertedIntoTree()
163 {
164     RenderBlock::insertedIntoTree();
165     createRenderNamedFlowFragmentIfNeeded();
166 }
167
168 void RenderBlockFlow::willBeDestroyed()
169 {
170     if (renderNamedFlowFragment())
171         setRenderNamedFlowFragment(nullptr);
172
173     // Make sure to destroy anonymous children first while they are still connected to the rest of the tree, so that they will
174     // properly dirty line boxes that they are removed from. Effects that do :before/:after only on hover could crash otherwise.
175     destroyLeftoverChildren();
176
177     if (!renderTreeBeingDestroyed()) {
178         if (firstRootBox()) {
179             // We can't wait for RenderBox::destroy to clear the selection,
180             // because by then we will have nuked the line boxes.
181             if (isSelectionBorder())
182                 frame().selection().setNeedsSelectionUpdate();
183
184             // If we are an anonymous block, then our line boxes might have children
185             // that will outlast this block. In the non-anonymous block case those
186             // children will be destroyed by the time we return from this function.
187             if (isAnonymousBlock()) {
188                 for (auto* box = firstRootBox(); box; box = box->nextRootBox()) {
189                     while (auto childBox = box->firstChild())
190                         childBox->removeFromParent();
191                 }
192             }
193         } else if (parent())
194             parent()->dirtyLinesFromChangedChild(*this);
195     }
196
197     m_lineBoxes.deleteLineBoxes();
198
199     blockWillBeDestroyed();
200
201     // NOTE: This jumps down to RenderBox, bypassing RenderBlock since it would do duplicate work.
202     RenderBox::willBeDestroyed();
203 }
204
205 RenderBlockFlow* RenderBlockFlow::previousSiblingWithOverhangingFloats(bool& parentHasFloats) const
206 {
207     // Attempt to locate a previous sibling with overhanging floats. We skip any elements that are
208     // out of flow (like floating/positioned elements), and we also skip over any objects that may have shifted
209     // to avoid floats.
210     parentHasFloats = false;
211     for (RenderObject* sibling = previousSibling(); sibling; sibling = sibling->previousSibling()) {
212         if (is<RenderBlockFlow>(*sibling)) {
213             auto& siblingBlock = downcast<RenderBlockFlow>(*sibling);
214             if (!siblingBlock.avoidsFloats())
215                 return &siblingBlock;
216         }
217         if (sibling->isFloating())
218             parentHasFloats = true;
219     }
220     return nullptr;
221 }
222
223 void RenderBlockFlow::rebuildFloatingObjectSetFromIntrudingFloats()
224 {
225     if (m_floatingObjects)
226         m_floatingObjects->setHorizontalWritingMode(isHorizontalWritingMode());
227
228     HashSet<RenderBox*> oldIntrudingFloatSet;
229     if (!childrenInline() && m_floatingObjects) {
230         const FloatingObjectSet& floatingObjectSet = m_floatingObjects->set();
231         auto end = floatingObjectSet.end();
232         for (auto it = floatingObjectSet.begin(); it != end; ++it) {
233             FloatingObject* floatingObject = it->get();
234             if (!floatingObject->isDescendant())
235                 oldIntrudingFloatSet.add(&floatingObject->renderer());
236         }
237     }
238
239     // Inline blocks are covered by the isReplaced() check in the avoidFloats method.
240     if (avoidsFloats() || isDocumentElementRenderer() || isRenderView() || isFloatingOrOutOfFlowPositioned() || isTableCell()) {
241         if (m_floatingObjects)
242             m_floatingObjects->clear();
243         if (!oldIntrudingFloatSet.isEmpty())
244             markAllDescendantsWithFloatsForLayout();
245         return;
246     }
247
248     RendererToFloatInfoMap floatMap;
249
250     if (m_floatingObjects) {
251         if (childrenInline())
252             m_floatingObjects->moveAllToFloatInfoMap(floatMap);
253         else
254             m_floatingObjects->clear();
255     }
256
257     // We should not process floats if the parent node is not a RenderBlock. Otherwise, we will add 
258     // floats in an invalid context. This will cause a crash arising from a bad cast on the parent.
259     // See <rdar://problem/8049753>, where float property is applied on a text node in a SVG.
260     bool isBlockInsideInline = isAnonymousInlineBlock();
261     if (!is<RenderBlockFlow>(parent()) && !isBlockInsideInline)
262         return;
263
264     // First add in floats from the parent. Self-collapsing blocks let their parent track any floats that intrude into
265     // them (as opposed to floats they contain themselves) so check for those here too.
266     RenderBlockFlow& parentBlock = downcast<RenderBlockFlow>(isBlockInsideInline ? *containingBlock() : *parent());
267     bool parentHasFloats = isBlockInsideInline ? parentBlock.containsFloats() : false;
268     RenderBlockFlow* previousBlock = nullptr;
269     if (!isBlockInsideInline)
270         previousBlock = previousSiblingWithOverhangingFloats(parentHasFloats);
271     LayoutUnit logicalTopOffset = logicalTop();
272     if (parentHasFloats || (parentBlock.lowestFloatLogicalBottom() > logicalTopOffset && previousBlock && previousBlock->isSelfCollapsingBlock()))
273         addIntrudingFloats(&parentBlock, &parentBlock, parentBlock.logicalLeftOffsetForContent(), logicalTopOffset);
274     
275     LayoutUnit logicalLeftOffset = 0;
276     if (previousBlock)
277         logicalTopOffset -= previousBlock->logicalTop();
278     else {
279         previousBlock = &parentBlock;
280         logicalLeftOffset += parentBlock.logicalLeftOffsetForContent();
281     }
282
283     // Add overhanging floats from the previous RenderBlock, but only if it has a float that intrudes into our space.    
284     if (previousBlock->m_floatingObjects && previousBlock->lowestFloatLogicalBottom() > logicalTopOffset)
285         addIntrudingFloats(previousBlock, &parentBlock, logicalLeftOffset, logicalTopOffset);
286
287     if (childrenInline()) {
288         LayoutUnit changeLogicalTop = LayoutUnit::max();
289         LayoutUnit changeLogicalBottom = LayoutUnit::min();
290         if (m_floatingObjects) {
291             const FloatingObjectSet& floatingObjectSet = m_floatingObjects->set();
292             auto end = floatingObjectSet.end();
293             for (auto it = floatingObjectSet.begin(); it != end; ++it) {
294                 const auto& floatingObject = *it->get();
295                 std::unique_ptr<FloatingObject> oldFloatingObject = floatMap.take(&floatingObject.renderer());
296                 LayoutUnit logicalBottom = logicalBottomForFloat(floatingObject);
297                 if (oldFloatingObject) {
298                     LayoutUnit oldLogicalBottom = logicalBottomForFloat(*oldFloatingObject);
299                     if (logicalWidthForFloat(floatingObject) != logicalWidthForFloat(*oldFloatingObject) || logicalLeftForFloat(floatingObject) != logicalLeftForFloat(*oldFloatingObject)) {
300                         changeLogicalTop = 0;
301                         changeLogicalBottom = std::max(changeLogicalBottom, std::max(logicalBottom, oldLogicalBottom));
302                     } else {
303                         if (logicalBottom != oldLogicalBottom) {
304                             changeLogicalTop = std::min(changeLogicalTop, std::min(logicalBottom, oldLogicalBottom));
305                             changeLogicalBottom = std::max(changeLogicalBottom, std::max(logicalBottom, oldLogicalBottom));
306                         }
307                         LayoutUnit logicalTop = logicalTopForFloat(floatingObject);
308                         LayoutUnit oldLogicalTop = logicalTopForFloat(*oldFloatingObject);
309                         if (logicalTop != oldLogicalTop) {
310                             changeLogicalTop = std::min(changeLogicalTop, std::min(logicalTop, oldLogicalTop));
311                             changeLogicalBottom = std::max(changeLogicalBottom, std::max(logicalTop, oldLogicalTop));
312                         }
313                     }
314
315                     if (oldFloatingObject->originatingLine() && !selfNeedsLayout()) {
316                         ASSERT(&oldFloatingObject->originatingLine()->renderer() == this);
317                         oldFloatingObject->originatingLine()->markDirty();
318                     }
319                 } else {
320                     changeLogicalTop = 0;
321                     changeLogicalBottom = std::max(changeLogicalBottom, logicalBottom);
322                 }
323             }
324         }
325
326         auto end = floatMap.end();
327         for (auto it = floatMap.begin(); it != end; ++it) {
328             const auto& floatingObject = *it->value.get();
329             if (!floatingObject.isDescendant()) {
330                 changeLogicalTop = 0;
331                 changeLogicalBottom = std::max(changeLogicalBottom, logicalBottomForFloat(floatingObject));
332             }
333         }
334
335         markLinesDirtyInBlockRange(changeLogicalTop, changeLogicalBottom);
336     } else if (!oldIntrudingFloatSet.isEmpty()) {
337         // If there are previously intruding floats that no longer intrude, then children with floats
338         // should also get layout because they might need their floating object lists cleared.
339         if (m_floatingObjects->set().size() < oldIntrudingFloatSet.size())
340             markAllDescendantsWithFloatsForLayout();
341         else {
342             const FloatingObjectSet& floatingObjectSet = m_floatingObjects->set();
343             auto end = floatingObjectSet.end();
344             for (auto it = floatingObjectSet.begin(); it != end && !oldIntrudingFloatSet.isEmpty(); ++it)
345                 oldIntrudingFloatSet.remove(&(*it)->renderer());
346             if (!oldIntrudingFloatSet.isEmpty())
347                 markAllDescendantsWithFloatsForLayout();
348         }
349     }
350 }
351
352 void RenderBlockFlow::adjustIntrinsicLogicalWidthsForColumns(LayoutUnit& minLogicalWidth, LayoutUnit& maxLogicalWidth) const
353 {
354     if (!style().hasAutoColumnCount() || !style().hasAutoColumnWidth()) {
355         // The min/max intrinsic widths calculated really tell how much space elements need when
356         // laid out inside the columns. In order to eventually end up with the desired column width,
357         // we need to convert them to values pertaining to the multicol container.
358         int columnCount = style().hasAutoColumnCount() ? 1 : style().columnCount();
359         LayoutUnit columnWidth;
360         LayoutUnit colGap = columnGap();
361         LayoutUnit gapExtra = (columnCount - 1) * colGap;
362         if (style().hasAutoColumnWidth())
363             minLogicalWidth = minLogicalWidth * columnCount + gapExtra;
364         else {
365             columnWidth = style().columnWidth();
366             minLogicalWidth = std::min(minLogicalWidth, columnWidth);
367         }
368         // FIXME: If column-count is auto here, we should resolve it to calculate the maximum
369         // intrinsic width, instead of pretending that it's 1. The only way to do that is by
370         // performing a layout pass, but this is not an appropriate time or place for layout. The
371         // good news is that if height is unconstrained and there are no explicit breaks, the
372         // resolved column-count really should be 1.
373         maxLogicalWidth = std::max(maxLogicalWidth, columnWidth) * columnCount + gapExtra;
374     }
375 }
376
377 void RenderBlockFlow::computeIntrinsicLogicalWidths(LayoutUnit& minLogicalWidth, LayoutUnit& maxLogicalWidth) const
378 {
379     if (childrenInline())
380         computeInlinePreferredLogicalWidths(minLogicalWidth, maxLogicalWidth);
381     else
382         computeBlockPreferredLogicalWidths(minLogicalWidth, maxLogicalWidth);
383
384     maxLogicalWidth = std::max(minLogicalWidth, maxLogicalWidth);
385
386     adjustIntrinsicLogicalWidthsForColumns(minLogicalWidth, maxLogicalWidth);
387
388     if (!style().autoWrap() && childrenInline()) {
389         // A horizontal marquee with inline children has no minimum width.
390         if (layer() && layer()->marquee() && layer()->marquee()->isHorizontal())
391             minLogicalWidth = 0;
392     }
393
394     if (is<RenderTableCell>(*this)) {
395         Length tableCellWidth = downcast<RenderTableCell>(*this).styleOrColLogicalWidth();
396         if (tableCellWidth.isFixed() && tableCellWidth.value() > 0)
397             maxLogicalWidth = std::max(minLogicalWidth, adjustContentBoxLogicalWidthForBoxSizing(tableCellWidth.value()));
398     }
399
400     int scrollbarWidth = intrinsicScrollbarLogicalWidth();
401     maxLogicalWidth += scrollbarWidth;
402     minLogicalWidth += scrollbarWidth;
403 }
404
405 bool RenderBlockFlow::recomputeLogicalWidthAndColumnWidth()
406 {
407     bool changed = recomputeLogicalWidth();
408
409     LayoutUnit oldColumnWidth = computedColumnWidth();
410     computeColumnCountAndWidth();
411     
412     return changed || oldColumnWidth != computedColumnWidth();
413 }
414
415 LayoutUnit RenderBlockFlow::columnGap() const
416 {
417     if (style().hasNormalColumnGap())
418         return style().fontDescription().computedPixelSize(); // "1em" is recommended as the normal gap setting. Matches <p> margins.
419     return style().columnGap();
420 }
421
422 void RenderBlockFlow::computeColumnCountAndWidth()
423 {
424     // Calculate our column width and column count.
425     // FIXME: Can overflow on fast/block/float/float-not-removed-from-next-sibling4.html, see https://bugs.webkit.org/show_bug.cgi?id=68744
426     unsigned desiredColumnCount = 1;
427     LayoutUnit desiredColumnWidth = contentLogicalWidth();
428
429     // For now, we don't support multi-column layouts when printing, since we have to do a lot of work for proper pagination.
430     if (document().paginated() || (style().hasAutoColumnCount() && style().hasAutoColumnWidth()) || !style().hasInlineColumnAxis()) {
431         setComputedColumnCountAndWidth(desiredColumnCount, desiredColumnWidth);
432         return;
433     }
434
435     LayoutUnit availWidth = desiredColumnWidth;
436     LayoutUnit colGap = columnGap();
437     LayoutUnit colWidth = std::max<LayoutUnit>(1, style().columnWidth());
438     unsigned colCount = std::max<unsigned>(1, style().columnCount());
439
440     if (style().hasAutoColumnWidth() && !style().hasAutoColumnCount()) {
441         desiredColumnCount = colCount;
442         desiredColumnWidth = std::max<LayoutUnit>(0, (availWidth - ((desiredColumnCount - 1) * colGap)) / desiredColumnCount);
443     } else if (!style().hasAutoColumnWidth() && style().hasAutoColumnCount()) {
444         desiredColumnCount = std::max<unsigned>(1, ((availWidth + colGap) / (colWidth + colGap)).toUnsigned());
445         desiredColumnWidth = ((availWidth + colGap) / desiredColumnCount) - colGap;
446     } else {
447         desiredColumnCount = std::max<unsigned>(std::min(colCount, ((availWidth + colGap) / (colWidth + colGap)).toUnsigned()), 1);
448         desiredColumnWidth = ((availWidth + colGap) / desiredColumnCount) - colGap;
449     }
450     setComputedColumnCountAndWidth(desiredColumnCount, desiredColumnWidth);
451 }
452
453 bool RenderBlockFlow::willCreateColumns(std::optional<unsigned> desiredColumnCount) const
454 {
455     // The following types are not supposed to create multicol context.
456     if (isFileUploadControl() || isTextControl() || isListBox())
457         return false;
458
459     if (!firstChild())
460         return false;
461
462     // If overflow-y is set to paged-x or paged-y on the body or html element, we'll handle the paginating in the RenderView instead.
463     if ((style().overflowY() == OPAGEDX || style().overflowY() == OPAGEDY) && !(isDocumentElementRenderer() || isBody()))
464         return true;
465
466     if (!style().specifiesColumns())
467         return false;
468
469     // column-axis with opposite writing direction initiates MultiColumnFlowThread.
470     if (!style().hasInlineColumnAxis())
471         return true;
472
473     // Non-auto column-width always initiates MultiColumnFlowThread.
474     if (!style().hasAutoColumnWidth())
475         return true;
476
477     if (desiredColumnCount)
478         return desiredColumnCount.value() > 1;
479
480     // column-count > 1 always initiates MultiColumnFlowThread.
481     if (!style().hasAutoColumnCount())
482         return style().columnCount() > 1;
483
484     ASSERT_NOT_REACHED();
485     return false;
486 }
487
488 void RenderBlockFlow::layoutBlock(bool relayoutChildren, LayoutUnit pageLogicalHeight)
489 {
490     ASSERT(needsLayout());
491
492     if (!relayoutChildren && simplifiedLayout())
493         return;
494
495     LayoutRepainter repainter(*this, checkForRepaintDuringLayout());
496
497     if (recomputeLogicalWidthAndColumnWidth())
498         relayoutChildren = true;
499
500     rebuildFloatingObjectSetFromIntrudingFloats();
501
502     LayoutUnit previousHeight = logicalHeight();
503     // FIXME: should this start out as borderAndPaddingLogicalHeight() + scrollbarLogicalHeight(),
504     // for consistency with other render classes?
505     setLogicalHeight(0);
506
507     bool pageLogicalHeightChanged = false;
508     checkForPaginationLogicalHeightChange(relayoutChildren, pageLogicalHeight, pageLogicalHeightChanged);
509
510     const RenderStyle& styleToUse = style();
511     LayoutStateMaintainer statePusher(view(), *this, locationOffset(), hasTransform() || hasReflection() || styleToUse.isFlippedBlocksWritingMode(), pageLogicalHeight, pageLogicalHeightChanged);
512
513     preparePaginationBeforeBlockLayout(relayoutChildren);
514     if (!relayoutChildren)
515         relayoutChildren = namedFlowFragmentNeedsUpdate();
516
517     // We use four values, maxTopPos, maxTopNeg, maxBottomPos, and maxBottomNeg, to track
518     // our current maximal positive and negative margins. These values are used when we
519     // are collapsed with adjacent blocks, so for example, if you have block A and B
520     // collapsing together, then you'd take the maximal positive margin from both A and B
521     // and subtract it from the maximal negative margin from both A and B to get the
522     // true collapsed margin. This algorithm is recursive, so when we finish layout()
523     // our block knows its current maximal positive/negative values.
524     //
525     // Start out by setting our margin values to our current margins. Table cells have
526     // no margins, so we don't fill in the values for table cells.
527     bool isCell = isTableCell();
528     if (!isCell) {
529         initMaxMarginValues();
530         
531         setHasMarginBeforeQuirk(styleToUse.hasMarginBeforeQuirk());
532         setHasMarginAfterQuirk(styleToUse.hasMarginAfterQuirk());
533         setPaginationStrut(0);
534     }
535
536     LayoutUnit repaintLogicalTop = 0;
537     LayoutUnit repaintLogicalBottom = 0;
538     LayoutUnit maxFloatLogicalBottom = 0;
539     if (!firstChild() && !isAnonymousBlock())
540         setChildrenInline(true);
541     if (childrenInline())
542         layoutInlineChildren(relayoutChildren, repaintLogicalTop, repaintLogicalBottom);
543     else
544         layoutBlockChildren(relayoutChildren, maxFloatLogicalBottom);
545
546     // Expand our intrinsic height to encompass floats.
547     LayoutUnit toAdd = borderAndPaddingAfter() + scrollbarLogicalHeight();
548     if (lowestFloatLogicalBottom() > (logicalHeight() - toAdd) && createsNewFormattingContext())
549         setLogicalHeight(lowestFloatLogicalBottom() + toAdd);
550     
551     if (relayoutForPagination(statePusher) || relayoutToAvoidWidows(statePusher)) {
552         ASSERT(!shouldBreakAtLineToAvoidWidow());
553         return;
554     }
555
556     // Calculate our new height.
557     LayoutUnit oldHeight = logicalHeight();
558     LayoutUnit oldClientAfterEdge = clientLogicalBottom();
559
560     // Before updating the final size of the flow thread make sure a forced break is applied after the content.
561     // This ensures the size information is correctly computed for the last auto-height region receiving content.
562     if (is<RenderFlowThread>(*this))
563         downcast<RenderFlowThread>(*this).applyBreakAfterContent(oldClientAfterEdge);
564
565     updateLogicalHeight();
566     LayoutUnit newHeight = logicalHeight();
567     if (oldHeight != newHeight) {
568         if (oldHeight > newHeight && maxFloatLogicalBottom > newHeight && !childrenInline()) {
569             // One of our children's floats may have become an overhanging float for us. We need to look for it.
570             for (auto& blockFlow : childrenOfType<RenderBlockFlow>(*this)) {
571                 if (blockFlow.isFloatingOrOutOfFlowPositioned())
572                     continue;
573                 if (blockFlow.lowestFloatLogicalBottom() + blockFlow.logicalTop() > newHeight)
574                     addOverhangingFloats(blockFlow, false);
575             }
576         }
577     }
578
579     bool heightChanged = (previousHeight != newHeight);
580     if (heightChanged)
581         relayoutChildren = true;
582
583     layoutPositionedObjects(relayoutChildren || isDocumentElementRenderer());
584
585     // Add overflow from children (unless we're multi-column, since in that case all our child overflow is clipped anyway).
586     computeOverflow(oldClientAfterEdge);
587     
588     statePusher.pop();
589
590     fitBorderToLinesIfNeeded();
591
592     if (view().layoutState()->m_pageLogicalHeight)
593         setPageLogicalOffset(view().layoutState()->pageLogicalOffset(this, logicalTop()));
594
595     updateLayerTransform();
596
597     // Update our scroll information if we're overflow:auto/scroll/hidden now that we know if
598     // we overflow or not.
599     updateScrollInfoAfterLayout();
600
601     // FIXME: This repaint logic should be moved into a separate helper function!
602     // Repaint with our new bounds if they are different from our old bounds.
603     bool didFullRepaint = repainter.repaintAfterLayout();
604     if (!didFullRepaint && repaintLogicalTop != repaintLogicalBottom && (styleToUse.visibility() == VISIBLE || enclosingLayer()->hasVisibleContent())) {
605         // FIXME: We could tighten up the left and right invalidation points if we let layoutInlineChildren fill them in based off the particular lines
606         // it had to lay out. We wouldn't need the hasOverflowClip() hack in that case either.
607         LayoutUnit repaintLogicalLeft = logicalLeftVisualOverflow();
608         LayoutUnit repaintLogicalRight = logicalRightVisualOverflow();
609         if (hasOverflowClip()) {
610             // If we have clipped overflow, we should use layout overflow as well, since visual overflow from lines didn't propagate to our block's overflow.
611             // Note the old code did this as well but even for overflow:visible. The addition of hasOverflowClip() at least tightens up the hack a bit.
612             // layoutInlineChildren should be patched to compute the entire repaint rect.
613             repaintLogicalLeft = std::min(repaintLogicalLeft, logicalLeftLayoutOverflow());
614             repaintLogicalRight = std::max(repaintLogicalRight, logicalRightLayoutOverflow());
615         }
616         
617         LayoutRect repaintRect;
618         if (isHorizontalWritingMode())
619             repaintRect = LayoutRect(repaintLogicalLeft, repaintLogicalTop, repaintLogicalRight - repaintLogicalLeft, repaintLogicalBottom - repaintLogicalTop);
620         else
621             repaintRect = LayoutRect(repaintLogicalTop, repaintLogicalLeft, repaintLogicalBottom - repaintLogicalTop, repaintLogicalRight - repaintLogicalLeft);
622
623         if (hasOverflowClip()) {
624             // Adjust repaint rect for scroll offset
625             repaintRect.moveBy(-scrollPosition());
626
627             // Don't allow this rect to spill out of our overflow box.
628             repaintRect.intersect(LayoutRect(LayoutPoint(), size()));
629         }
630
631         // Make sure the rect is still non-empty after intersecting for overflow above
632         if (!repaintRect.isEmpty()) {
633             repaintRectangle(repaintRect); // We need to do a partial repaint of our content.
634             if (hasReflection())
635                 repaintRectangle(reflectedRect(repaintRect));
636         }
637     }
638
639     clearNeedsLayout();
640 }
641
642 void RenderBlockFlow::layoutBlockChildren(bool relayoutChildren, LayoutUnit& maxFloatLogicalBottom)
643 {
644     dirtyForLayoutFromPercentageHeightDescendants();
645
646     LayoutUnit beforeEdge = borderAndPaddingBefore();
647     LayoutUnit afterEdge = borderAndPaddingAfter() + scrollbarLogicalHeight();
648
649     setLogicalHeight(beforeEdge);
650     
651     // Lay out our hypothetical grid line as though it occurs at the top of the block.
652     if (view().layoutState()->lineGrid() == this)
653         layoutLineGridBox();
654
655     // The margin struct caches all our current margin collapsing state.
656     MarginInfo marginInfo(*this, beforeEdge, afterEdge);
657
658     // Fieldsets need to find their legend and position it inside the border of the object.
659     // The legend then gets skipped during normal layout. The same is true for ruby text.
660     // It doesn't get included in the normal layout process but is instead skipped.
661     layoutExcludedChildren(relayoutChildren);
662
663     LayoutUnit previousFloatLogicalBottom = 0;
664     maxFloatLogicalBottom = 0;
665
666     RenderBox* next = firstChildBox();
667
668     while (next) {
669         RenderBox& child = *next;
670         next = child.nextSiblingBox();
671
672         if (child.isExcludedFromNormalLayout())
673             continue; // Skip this child, since it will be positioned by the specialized subclass (fieldsets and ruby runs).
674
675         updateBlockChildDirtyBitsBeforeLayout(relayoutChildren, child);
676
677         if (child.isOutOfFlowPositioned()) {
678             child.containingBlock()->insertPositionedObject(child);
679             adjustPositionedBlock(child, marginInfo);
680             continue;
681         }
682         if (child.isFloating()) {
683             insertFloatingObject(child);
684             adjustFloatingBlock(marginInfo);
685             continue;
686         }
687
688         // Lay out the child.
689         layoutBlockChild(child, marginInfo, previousFloatLogicalBottom, maxFloatLogicalBottom);
690     }
691     
692     // Now do the handling of the bottom of the block, adding in our bottom border/padding and
693     // determining the correct collapsed bottom margin information.
694     handleAfterSideOfBlock(beforeEdge, afterEdge, marginInfo);
695 }
696
697 void RenderBlockFlow::layoutInlineChildren(bool relayoutChildren, LayoutUnit& repaintLogicalTop, LayoutUnit& repaintLogicalBottom)
698 {
699     if (lineLayoutPath() == UndeterminedPath)
700         setLineLayoutPath(SimpleLineLayout::canUseFor(*this) ? SimpleLinesPath : LineBoxesPath);
701
702     if (lineLayoutPath() == SimpleLinesPath) {
703         layoutSimpleLines(relayoutChildren, repaintLogicalTop, repaintLogicalBottom);
704         return;
705     }
706
707     m_simpleLineLayout = nullptr;
708     layoutLineBoxes(relayoutChildren, repaintLogicalTop, repaintLogicalBottom);
709 }
710
711 void RenderBlockFlow::layoutBlockChild(RenderBox& child, MarginInfo& marginInfo, LayoutUnit& previousFloatLogicalBottom, LayoutUnit& maxFloatLogicalBottom)
712 {
713     LayoutUnit oldPosMarginBefore = maxPositiveMarginBefore();
714     LayoutUnit oldNegMarginBefore = maxNegativeMarginBefore();
715
716     // The child is a normal flow object. Compute the margins we will use for collapsing now.
717     child.computeAndSetBlockDirectionMargins(*this);
718
719     // Try to guess our correct logical top position. In most cases this guess will
720     // be correct. Only if we're wrong (when we compute the real logical top position)
721     // will we have to potentially relayout.
722     LayoutUnit estimateWithoutPagination;
723     LayoutUnit logicalTopEstimate = estimateLogicalTopPosition(child, marginInfo, estimateWithoutPagination);
724
725     // Cache our old rect so that we can dirty the proper repaint rects if the child moves.
726     LayoutRect oldRect = child.frameRect();
727     LayoutUnit oldLogicalTop = logicalTopForChild(child);
728
729 #if !ASSERT_DISABLED
730     LayoutSize oldLayoutDelta = view().layoutDelta();
731 #endif
732     // Position the child as though it didn't collapse with the top.
733     setLogicalTopForChild(child, logicalTopEstimate, ApplyLayoutDelta);
734     estimateRegionRangeForBoxChild(child);
735
736     RenderBlockFlow* childBlockFlow = is<RenderBlockFlow>(child) ? &downcast<RenderBlockFlow>(child) : nullptr;
737     bool markDescendantsWithFloats = false;
738     if (logicalTopEstimate != oldLogicalTop && !child.avoidsFloats() && childBlockFlow && childBlockFlow->containsFloats())
739         markDescendantsWithFloats = true;
740     else if (UNLIKELY(logicalTopEstimate.mightBeSaturated()))
741         // logicalTopEstimate, returned by estimateLogicalTopPosition, might be saturated for
742         // very large elements. If it does the comparison with oldLogicalTop might yield a
743         // false negative as adding and removing margins, borders etc from a saturated number
744         // might yield incorrect results. If this is the case always mark for layout.
745         markDescendantsWithFloats = true;
746     else if (!child.avoidsFloats() || child.shrinkToAvoidFloats()) {
747         // If an element might be affected by the presence of floats, then always mark it for
748         // layout.
749         LayoutUnit fb = std::max(previousFloatLogicalBottom, lowestFloatLogicalBottom());
750         if (fb > logicalTopEstimate)
751             markDescendantsWithFloats = true;
752     }
753
754     if (childBlockFlow) {
755         if (markDescendantsWithFloats)
756             childBlockFlow->markAllDescendantsWithFloatsForLayout();
757         if (!child.isWritingModeRoot())
758             previousFloatLogicalBottom = std::max(previousFloatLogicalBottom, oldLogicalTop + childBlockFlow->lowestFloatLogicalBottom());
759     }
760
761     child.markForPaginationRelayoutIfNeeded();
762
763     bool childHadLayout = child.everHadLayout();
764     bool childNeededLayout = child.needsLayout();
765     if (childNeededLayout)
766         child.layout();
767
768     // Cache if we are at the top of the block right now.
769     bool atBeforeSideOfBlock = marginInfo.atBeforeSideOfBlock();
770
771     // Now determine the correct ypos based off examination of collapsing margin
772     // values.
773     LayoutUnit logicalTopBeforeClear = collapseMargins(child, marginInfo);
774
775     // Now check for clear.
776     LayoutUnit logicalTopAfterClear = clearFloatsIfNeeded(child, marginInfo, oldPosMarginBefore, oldNegMarginBefore, logicalTopBeforeClear);
777     
778     bool paginated = view().layoutState()->isPaginated();
779     if (paginated)
780         logicalTopAfterClear = adjustBlockChildForPagination(logicalTopAfterClear, estimateWithoutPagination, child, atBeforeSideOfBlock && logicalTopBeforeClear == logicalTopAfterClear);
781
782     setLogicalTopForChild(child, logicalTopAfterClear, ApplyLayoutDelta);
783
784     // Now we have a final top position. See if it really does end up being different from our estimate.
785     // clearFloatsIfNeeded can also mark the child as needing a layout even though we didn't move. This happens
786     // when collapseMargins dynamically adds overhanging floats because of a child with negative margins.
787     if (logicalTopAfterClear != logicalTopEstimate || child.needsLayout() || (paginated && childBlockFlow && childBlockFlow->shouldBreakAtLineToAvoidWidow())) {
788         if (child.shrinkToAvoidFloats()) {
789             // The child's width depends on the line width. When the child shifts to clear an item, its width can
790             // change (because it has more available line width). So mark the item as dirty.
791             child.setChildNeedsLayout(MarkOnlyThis);
792         }
793         
794         if (childBlockFlow) {
795             if (!child.avoidsFloats() && childBlockFlow->containsFloats())
796                 childBlockFlow->markAllDescendantsWithFloatsForLayout();
797             child.markForPaginationRelayoutIfNeeded();
798         }
799     }
800
801     if (updateRegionRangeForBoxChild(child))
802         child.setNeedsLayout(MarkOnlyThis);
803
804     // In case our guess was wrong, relayout the child.
805     child.layoutIfNeeded();
806
807     // We are no longer at the top of the block if we encounter a non-empty child.  
808     // This has to be done after checking for clear, so that margins can be reset if a clear occurred.
809     if (marginInfo.atBeforeSideOfBlock() && !child.isSelfCollapsingBlock())
810         marginInfo.setAtBeforeSideOfBlock(false);
811
812     // Now place the child in the correct left position
813     determineLogicalLeftPositionForChild(child, ApplyLayoutDelta);
814
815     // Update our height now that the child has been placed in the correct position.
816     setLogicalHeight(logicalHeight() + logicalHeightForChildForFragmentation(child));
817     if (mustSeparateMarginAfterForChild(child)) {
818         setLogicalHeight(logicalHeight() + marginAfterForChild(child));
819         marginInfo.clearMargin();
820     }
821     // If the child has overhanging floats that intrude into following siblings (or possibly out
822     // of this block), then the parent gets notified of the floats now.
823     if (childBlockFlow && childBlockFlow->containsFloats())
824         maxFloatLogicalBottom = std::max(maxFloatLogicalBottom, addOverhangingFloats(*childBlockFlow, !childNeededLayout));
825
826     LayoutSize childOffset = child.location() - oldRect.location();
827     if (childOffset.width() || childOffset.height()) {
828         view().addLayoutDelta(childOffset);
829
830         // If the child moved, we have to repaint it as well as any floating/positioned
831         // descendants. An exception is if we need a layout. In this case, we know we're going to
832         // repaint ourselves (and the child) anyway.
833         if (childHadLayout && !selfNeedsLayout() && child.checkForRepaintDuringLayout())
834             child.repaintDuringLayoutIfMoved(oldRect);
835     }
836
837     if (!childHadLayout && child.checkForRepaintDuringLayout()) {
838         child.repaint();
839         child.repaintOverhangingFloats(true);
840     }
841
842     if (paginated) {
843         if (RenderFlowThread* flowThread = flowThreadContainingBlock())
844             flowThread->flowThreadDescendantBoxLaidOut(&child);
845         // Check for an after page/column break.
846         LayoutUnit newHeight = applyAfterBreak(child, logicalHeight(), marginInfo);
847         if (newHeight != height())
848             setLogicalHeight(newHeight);
849     }
850
851     ASSERT(view().layoutDeltaMatches(oldLayoutDelta));
852 }
853
854 void RenderBlockFlow::adjustPositionedBlock(RenderBox& child, const MarginInfo& marginInfo)
855 {
856     bool isHorizontal = isHorizontalWritingMode();
857     bool hasStaticBlockPosition = child.style().hasStaticBlockPosition(isHorizontal);
858     
859     LayoutUnit logicalTop = logicalHeight();
860     updateStaticInlinePositionForChild(child, logicalTop, DoNotIndentText);
861
862     if (!marginInfo.canCollapseWithMarginBefore()) {
863         // Positioned blocks don't collapse margins, so add the margin provided by
864         // the container now. The child's own margin is added later when calculating its logical top.
865         LayoutUnit collapsedBeforePos = marginInfo.positiveMargin();
866         LayoutUnit collapsedBeforeNeg = marginInfo.negativeMargin();
867         logicalTop += collapsedBeforePos - collapsedBeforeNeg;
868     }
869     
870     RenderLayer* childLayer = child.layer();
871     if (childLayer->staticBlockPosition() != logicalTop) {
872         childLayer->setStaticBlockPosition(logicalTop);
873         if (hasStaticBlockPosition)
874             child.setChildNeedsLayout(MarkOnlyThis);
875     }
876 }
877
878 LayoutUnit RenderBlockFlow::marginOffsetForSelfCollapsingBlock()
879 {
880     ASSERT(isSelfCollapsingBlock());
881     RenderBlockFlow* parentBlock = downcast<RenderBlockFlow>(parent());
882     if (parentBlock && style().clear() && parentBlock->getClearDelta(*this, logicalHeight()))
883         return marginValuesForChild(*this).positiveMarginBefore();
884     return LayoutUnit();
885 }
886
887 void RenderBlockFlow::determineLogicalLeftPositionForChild(RenderBox& child, ApplyLayoutDeltaMode applyDelta)
888 {
889     LayoutUnit startPosition = borderStart() + paddingStart();
890     if (shouldPlaceBlockDirectionScrollbarOnLeft())
891         startPosition += (style().isLeftToRightDirection() ? 1 : -1) * verticalScrollbarWidth();
892     LayoutUnit totalAvailableLogicalWidth = borderAndPaddingLogicalWidth() + availableLogicalWidth();
893
894     // Add in our start margin.
895     LayoutUnit childMarginStart = marginStartForChild(child);
896     LayoutUnit newPosition = startPosition + childMarginStart;
897         
898     // Some objects (e.g., tables, horizontal rules, overflow:auto blocks) avoid floats. They need
899     // to shift over as necessary to dodge any floats that might get in the way.
900     if (child.avoidsFloats() && containsFloats() && !is<RenderNamedFlowThread>(flowThreadContainingBlock()))
901         newPosition += computeStartPositionDeltaForChildAvoidingFloats(child, marginStartForChild(child));
902
903     setLogicalLeftForChild(child, style().isLeftToRightDirection() ? newPosition : totalAvailableLogicalWidth - newPosition - logicalWidthForChild(child), applyDelta);
904 }
905
906 void RenderBlockFlow::adjustFloatingBlock(const MarginInfo& marginInfo)
907 {
908     // The float should be positioned taking into account the bottom margin
909     // of the previous flow. We add that margin into the height, get the
910     // float positioned properly, and then subtract the margin out of the
911     // height again. In the case of self-collapsing blocks, we always just
912     // use the top margins, since the self-collapsing block collapsed its
913     // own bottom margin into its top margin.
914     //
915     // Note also that the previous flow may collapse its margin into the top of
916     // our block. If this is the case, then we do not add the margin in to our
917     // height when computing the position of the float. This condition can be tested
918     // for by simply calling canCollapseWithMarginBefore. See
919     // http://www.hixie.ch/tests/adhoc/css/box/block/margin-collapse/046.html for
920     // an example of this scenario.
921     LayoutUnit marginOffset = marginInfo.canCollapseWithMarginBefore() ? LayoutUnit() : marginInfo.margin();
922     setLogicalHeight(logicalHeight() + marginOffset);
923     positionNewFloats();
924     setLogicalHeight(logicalHeight() - marginOffset);
925 }
926
927 void RenderBlockFlow::updateStaticInlinePositionForChild(RenderBox& child, LayoutUnit logicalTop, IndentTextOrNot shouldIndentText)
928 {
929     if (child.style().isOriginalDisplayInlineType())
930         setStaticInlinePositionForChild(child, logicalTop, startAlignedOffsetForLine(logicalTop, shouldIndentText));
931     else
932         setStaticInlinePositionForChild(child, logicalTop, startOffsetForContent(logicalTop));
933 }
934
935 void RenderBlockFlow::setStaticInlinePositionForChild(RenderBox& child, LayoutUnit blockOffset, LayoutUnit inlinePosition)
936 {
937     if (flowThreadContainingBlock()) {
938         // Shift the inline position to exclude the region offset.
939         inlinePosition += startOffsetForContent() - startOffsetForContent(blockOffset);
940     }
941     child.layer()->setStaticInlinePosition(inlinePosition);
942 }
943
944 RenderBlockFlow::MarginValues RenderBlockFlow::marginValuesForChild(RenderBox& child) const
945 {
946     LayoutUnit childBeforePositive = 0;
947     LayoutUnit childBeforeNegative = 0;
948     LayoutUnit childAfterPositive = 0;
949     LayoutUnit childAfterNegative = 0;
950
951     LayoutUnit beforeMargin = 0;
952     LayoutUnit afterMargin = 0;
953
954     RenderBlockFlow* childRenderBlock = is<RenderBlockFlow>(child) ? &downcast<RenderBlockFlow>(child) : nullptr;
955     
956     // If the child has the same directionality as we do, then we can just return its
957     // margins in the same direction.
958     if (!child.isWritingModeRoot()) {
959         if (childRenderBlock) {
960             childBeforePositive = childRenderBlock->maxPositiveMarginBefore();
961             childBeforeNegative = childRenderBlock->maxNegativeMarginBefore();
962             childAfterPositive = childRenderBlock->maxPositiveMarginAfter();
963             childAfterNegative = childRenderBlock->maxNegativeMarginAfter();
964         } else {
965             beforeMargin = child.marginBefore();
966             afterMargin = child.marginAfter();
967         }
968     } else if (child.isHorizontalWritingMode() == isHorizontalWritingMode()) {
969         // The child has a different directionality. If the child is parallel, then it's just
970         // flipped relative to us. We can use the margins for the opposite edges.
971         if (childRenderBlock) {
972             childBeforePositive = childRenderBlock->maxPositiveMarginAfter();
973             childBeforeNegative = childRenderBlock->maxNegativeMarginAfter();
974             childAfterPositive = childRenderBlock->maxPositiveMarginBefore();
975             childAfterNegative = childRenderBlock->maxNegativeMarginBefore();
976         } else {
977             beforeMargin = child.marginAfter();
978             afterMargin = child.marginBefore();
979         }
980     } else {
981         // The child is perpendicular to us, which means its margins don't collapse but are on the
982         // "logical left/right" sides of the child box. We can just return the raw margin in this case.
983         beforeMargin = marginBeforeForChild(child);
984         afterMargin = marginAfterForChild(child);
985     }
986
987     // Resolve uncollapsing margins into their positive/negative buckets.
988     if (beforeMargin) {
989         if (beforeMargin > 0)
990             childBeforePositive = beforeMargin;
991         else
992             childBeforeNegative = -beforeMargin;
993     }
994     if (afterMargin) {
995         if (afterMargin > 0)
996             childAfterPositive = afterMargin;
997         else
998             childAfterNegative = -afterMargin;
999     }
1000
1001     return MarginValues(childBeforePositive, childBeforeNegative, childAfterPositive, childAfterNegative);
1002 }
1003
1004 bool RenderBlockFlow::childrenPreventSelfCollapsing() const
1005 {
1006     if (!childrenInline())
1007         return RenderBlock::childrenPreventSelfCollapsing();
1008
1009     // If the block has inline children, see if we generated any line boxes. If we have any
1010     // line boxes, then we can only be self-collapsing if we have nothing but anonymous inline blocks
1011     // that are also self-collapsing inside us.
1012     if (!hasLines())
1013         return false;
1014     
1015     if (simpleLineLayout())
1016         return true; // We have simple line layout lines, so we can't be self-collapsing.
1017     
1018     for (auto* child = firstRootBox(); child; child = child->nextRootBox()) {
1019         if (!child->hasAnonymousInlineBlock() || !child->anonymousInlineBlock()->isSelfCollapsingBlock())
1020             return true;
1021     }
1022     return false; // We have no line boxes, so we must be self-collapsing.
1023 }
1024
1025 LayoutUnit RenderBlockFlow::collapseMargins(RenderBox& child, MarginInfo& marginInfo)
1026 {
1027     return collapseMarginsWithChildInfo(&child, child.previousSibling(), marginInfo);
1028 }
1029
1030 LayoutUnit RenderBlockFlow::collapseMarginsWithChildInfo(RenderBox* child, RenderObject* prevSibling, MarginInfo& marginInfo)
1031 {
1032     bool childDiscardMarginBefore = child ? mustDiscardMarginBeforeForChild(*child) : false;
1033     bool childDiscardMarginAfter = child ? mustDiscardMarginAfterForChild(*child) : false;
1034     bool childIsSelfCollapsing = child ? child->isSelfCollapsingBlock() : false;
1035     bool beforeQuirk = child ? hasMarginBeforeQuirk(*child) : false;
1036     bool afterQuirk = child ? hasMarginAfterQuirk(*child) : false;
1037     
1038     // The child discards the before margin when the the after margin has discard in the case of a self collapsing block.
1039     childDiscardMarginBefore = childDiscardMarginBefore || (childDiscardMarginAfter && childIsSelfCollapsing);
1040     
1041     // Get the four margin values for the child and cache them.
1042     const MarginValues childMargins = child ? marginValuesForChild(*child) : MarginValues(0, 0, 0, 0);
1043
1044     // Get our max pos and neg top margins.
1045     LayoutUnit posTop = childMargins.positiveMarginBefore();
1046     LayoutUnit negTop = childMargins.negativeMarginBefore();
1047
1048     // For self-collapsing blocks, collapse our bottom margins into our
1049     // top to get new posTop and negTop values.
1050     if (childIsSelfCollapsing) {
1051         posTop = std::max(posTop, childMargins.positiveMarginAfter());
1052         negTop = std::max(negTop, childMargins.negativeMarginAfter());
1053     }
1054     
1055     if (marginInfo.canCollapseWithMarginBefore()) {
1056         if (!childDiscardMarginBefore && !marginInfo.discardMargin()) {
1057             // This child is collapsing with the top of the
1058             // block. If it has larger margin values, then we need to update
1059             // our own maximal values.
1060             if (!document().inQuirksMode() || !marginInfo.quirkContainer() || !beforeQuirk)
1061                 setMaxMarginBeforeValues(std::max(posTop, maxPositiveMarginBefore()), std::max(negTop, maxNegativeMarginBefore()));
1062
1063             // The minute any of the margins involved isn't a quirk, don't
1064             // collapse it away, even if the margin is smaller (www.webreference.com
1065             // has an example of this, a <dt> with 0.8em author-specified inside
1066             // a <dl> inside a <td>.
1067             if (!marginInfo.determinedMarginBeforeQuirk() && !beforeQuirk && (posTop - negTop)) {
1068                 setHasMarginBeforeQuirk(false);
1069                 marginInfo.setDeterminedMarginBeforeQuirk(true);
1070             }
1071
1072             if (!marginInfo.determinedMarginBeforeQuirk() && beforeQuirk && !marginBefore()) {
1073                 // We have no top margin and our top child has a quirky margin.
1074                 // We will pick up this quirky margin and pass it through.
1075                 // This deals with the <td><div><p> case.
1076                 // Don't do this for a block that split two inlines though. You do
1077                 // still apply margins in this case.
1078                 setHasMarginBeforeQuirk(true);
1079             }
1080         } else
1081             // The before margin of the container will also discard all the margins it is collapsing with.
1082             setMustDiscardMarginBefore();
1083     }
1084
1085     // Once we find a child with discardMarginBefore all the margins collapsing with us must also discard. 
1086     if (childDiscardMarginBefore) {
1087         marginInfo.setDiscardMargin(true);
1088         marginInfo.clearMargin();
1089     }
1090
1091     if (marginInfo.quirkContainer() && marginInfo.atBeforeSideOfBlock() && (posTop - negTop))
1092         marginInfo.setHasMarginBeforeQuirk(beforeQuirk);
1093
1094     LayoutUnit beforeCollapseLogicalTop = logicalHeight();
1095     LayoutUnit logicalTop = beforeCollapseLogicalTop;
1096
1097     LayoutUnit clearanceForSelfCollapsingBlock;
1098     
1099     // If the child's previous sibling is a self-collapsing block that cleared a float then its top border edge has been set at the bottom border edge
1100     // of the float. Since we want to collapse the child's top margin with the self-collapsing block's top and bottom margins we need to adjust our parent's height to match the 
1101     // margin top of the self-collapsing block. If the resulting collapsed margin leaves the child still intruding into the float then we will want to clear it.
1102     if (!marginInfo.canCollapseWithMarginBefore() && is<RenderBlockFlow>(prevSibling) && downcast<RenderBlockFlow>(*prevSibling).isSelfCollapsingBlock()) {
1103         clearanceForSelfCollapsingBlock = downcast<RenderBlockFlow>(*prevSibling).marginOffsetForSelfCollapsingBlock();
1104         setLogicalHeight(logicalHeight() - clearanceForSelfCollapsingBlock);
1105     }
1106
1107     if (childIsSelfCollapsing) {
1108         // For a self collapsing block both the before and after margins get discarded. The block doesn't contribute anything to the height of the block.
1109         // Also, the child's top position equals the logical height of the container.
1110         if (!childDiscardMarginBefore && !marginInfo.discardMargin()) {
1111             // This child has no height. We need to compute our
1112             // position before we collapse the child's margins together,
1113             // so that we can get an accurate position for the zero-height block.
1114             LayoutUnit collapsedBeforePos = std::max(marginInfo.positiveMargin(), childMargins.positiveMarginBefore());
1115             LayoutUnit collapsedBeforeNeg = std::max(marginInfo.negativeMargin(), childMargins.negativeMarginBefore());
1116             marginInfo.setMargin(collapsedBeforePos, collapsedBeforeNeg);
1117             
1118             // Now collapse the child's margins together, which means examining our
1119             // bottom margin values as well. 
1120             marginInfo.setPositiveMarginIfLarger(childMargins.positiveMarginAfter());
1121             marginInfo.setNegativeMarginIfLarger(childMargins.negativeMarginAfter());
1122
1123             if (!marginInfo.canCollapseWithMarginBefore())
1124                 // We need to make sure that the position of the self-collapsing block
1125                 // is correct, since it could have overflowing content
1126                 // that needs to be positioned correctly (e.g., a block that
1127                 // had a specified height of 0 but that actually had subcontent).
1128                 logicalTop = logicalHeight() + collapsedBeforePos - collapsedBeforeNeg;
1129         }
1130     } else {
1131         if (child && mustSeparateMarginBeforeForChild(*child)) {
1132             ASSERT(!marginInfo.discardMargin() || (marginInfo.discardMargin() && !marginInfo.margin()));
1133             // If we are at the before side of the block and we collapse, ignore the computed margin
1134             // and just add the child margin to the container height. This will correctly position
1135             // the child inside the container.
1136             LayoutUnit separateMargin = !marginInfo.canCollapseWithMarginBefore() ? marginInfo.margin() : LayoutUnit::fromPixel(0);
1137             setLogicalHeight(logicalHeight() + separateMargin + marginBeforeForChild(*child));
1138             logicalTop = logicalHeight();
1139         } else if (!marginInfo.discardMargin() && (!marginInfo.atBeforeSideOfBlock()
1140             || (!marginInfo.canCollapseMarginBeforeWithChildren()
1141             && (!document().inQuirksMode() || !marginInfo.quirkContainer() || !marginInfo.hasMarginBeforeQuirk())))) {
1142             // We're collapsing with a previous sibling's margins and not
1143             // with the top of the block.
1144             setLogicalHeight(logicalHeight() + std::max(marginInfo.positiveMargin(), posTop) - std::max(marginInfo.negativeMargin(), negTop));
1145             logicalTop = logicalHeight();
1146         }
1147
1148         marginInfo.setDiscardMargin(childDiscardMarginAfter);
1149         
1150         if (!marginInfo.discardMargin()) {
1151             marginInfo.setPositiveMargin(childMargins.positiveMarginAfter());
1152             marginInfo.setNegativeMargin(childMargins.negativeMarginAfter());
1153         } else
1154             marginInfo.clearMargin();
1155
1156         if (marginInfo.margin())
1157             marginInfo.setHasMarginAfterQuirk(afterQuirk);
1158     }
1159     
1160     // If margins would pull us past the top of the next page, then we need to pull back and pretend like the margins
1161     // collapsed into the page edge.
1162     LayoutState* layoutState = view().layoutState();
1163     if (layoutState->isPaginated() && layoutState->pageLogicalHeight() && logicalTop > beforeCollapseLogicalTop
1164         && hasNextPage(beforeCollapseLogicalTop)) {
1165         LayoutUnit oldLogicalTop = logicalTop;
1166         logicalTop = std::min(logicalTop, nextPageLogicalTop(beforeCollapseLogicalTop));
1167         setLogicalHeight(logicalHeight() + (logicalTop - oldLogicalTop));
1168     }
1169
1170     if (is<RenderBlockFlow>(prevSibling) && !prevSibling->isFloatingOrOutOfFlowPositioned()) {
1171         // If |child| is a self-collapsing block it may have collapsed into a previous sibling and although it hasn't reduced the height of the parent yet
1172         // any floats from the parent will now overhang.
1173         RenderBlockFlow& block = downcast<RenderBlockFlow>(*prevSibling);
1174         LayoutUnit oldLogicalHeight = logicalHeight();
1175         setLogicalHeight(logicalTop);
1176         if (block.containsFloats() && !block.avoidsFloats() && (block.logicalTop() + block.lowestFloatLogicalBottom()) > logicalTop)
1177             addOverhangingFloats(block, false);
1178         setLogicalHeight(oldLogicalHeight);
1179
1180         // If |child|'s previous sibling is a self-collapsing block that cleared a float and margin collapsing resulted in |child| moving up
1181         // into the margin area of the self-collapsing block then the float it clears is now intruding into |child|. Layout again so that we can look for
1182         // floats in the parent that overhang |child|'s new logical top.
1183         bool logicalTopIntrudesIntoFloat = clearanceForSelfCollapsingBlock > 0 && logicalTop < beforeCollapseLogicalTop;
1184         if (child && logicalTopIntrudesIntoFloat && containsFloats() && !child->avoidsFloats() && lowestFloatLogicalBottom() > logicalTop)
1185             child->setNeedsLayout();
1186     }
1187
1188     return logicalTop;
1189 }
1190
1191 LayoutUnit RenderBlockFlow::clearFloatsIfNeeded(RenderBox& child, MarginInfo& marginInfo, LayoutUnit oldTopPosMargin, LayoutUnit oldTopNegMargin, LayoutUnit yPos)
1192 {
1193     LayoutUnit heightIncrease = getClearDelta(child, yPos);
1194     if (!heightIncrease)
1195         return yPos;
1196
1197     if (child.isSelfCollapsingBlock()) {
1198         bool childDiscardMargin = mustDiscardMarginBeforeForChild(child) || mustDiscardMarginAfterForChild(child);
1199
1200         // For self-collapsing blocks that clear, they can still collapse their
1201         // margins with following siblings. Reset the current margins to represent
1202         // the self-collapsing block's margins only.
1203         // If DISCARD is specified for -webkit-margin-collapse, reset the margin values.
1204         MarginValues childMargins = marginValuesForChild(child);
1205         if (!childDiscardMargin) {
1206             marginInfo.setPositiveMargin(std::max(childMargins.positiveMarginBefore(), childMargins.positiveMarginAfter()));
1207             marginInfo.setNegativeMargin(std::max(childMargins.negativeMarginBefore(), childMargins.negativeMarginAfter()));
1208         } else
1209             marginInfo.clearMargin();
1210         marginInfo.setDiscardMargin(childDiscardMargin);
1211
1212         // CSS2.1 states:
1213         // "If the top and bottom margins of an element with clearance are adjoining, its margins collapse with 
1214         // the adjoining margins of following siblings but that resulting margin does not collapse with the bottom margin of the parent block."
1215         // So the parent's bottom margin cannot collapse through this block or any subsequent self-collapsing blocks. Check subsequent siblings
1216         // for a block with height - if none is found then don't allow the margins to collapse with the parent.
1217         bool wouldCollapseMarginsWithParent = marginInfo.canCollapseMarginAfterWithChildren();
1218         for (RenderBox* curr = child.nextSiblingBox(); curr && wouldCollapseMarginsWithParent; curr = curr->nextSiblingBox()) {
1219             if (!curr->isFloatingOrOutOfFlowPositioned() && !curr->isSelfCollapsingBlock())
1220                 wouldCollapseMarginsWithParent = false;
1221         }
1222         if (wouldCollapseMarginsWithParent)
1223             marginInfo.setCanCollapseMarginAfterWithChildren(false);
1224
1225         // For now set the border-top of |child| flush with the bottom border-edge of the float so it can layout any floating or positioned children of
1226         // its own at the correct vertical position. If subsequent siblings attempt to collapse with |child|'s margins in |collapseMargins| we will
1227         // adjust the height of the parent to |child|'s margin top (which if it is positive sits up 'inside' the float it's clearing) so that all three 
1228         // margins can collapse at the correct vertical position.
1229         // Per CSS2.1 we need to ensure that any negative margin-top clears |child| beyond the bottom border-edge of the float so that the top border edge of the child
1230         // (i.e. its clearance)  is at a position that satisfies the equation: "the amount of clearance is set so that clearance + margin-top = [height of float],
1231         // i.e., clearance = [height of float] - margin-top".
1232         setLogicalHeight(child.logicalTop() + childMargins.negativeMarginBefore());
1233     } else
1234         // Increase our height by the amount we had to clear.
1235         setLogicalHeight(logicalHeight() + heightIncrease);
1236     
1237     if (marginInfo.canCollapseWithMarginBefore()) {
1238         // We can no longer collapse with the top of the block since a clear
1239         // occurred. The empty blocks collapse into the cleared block.
1240         // FIXME: This isn't quite correct. Need clarification for what to do
1241         // if the height the cleared block is offset by is smaller than the
1242         // margins involved.
1243         setMaxMarginBeforeValues(oldTopPosMargin, oldTopNegMargin);
1244         marginInfo.setAtBeforeSideOfBlock(false);
1245
1246         // In case the child discarded the before margin of the block we need to reset the mustDiscardMarginBefore flag to the initial value.
1247         setMustDiscardMarginBefore(style().marginBeforeCollapse() == MDISCARD);
1248     }
1249
1250     return yPos + heightIncrease;
1251 }
1252
1253 void RenderBlockFlow::marginBeforeEstimateForChild(RenderBox& child, LayoutUnit& positiveMarginBefore, LayoutUnit& negativeMarginBefore, bool& discardMarginBefore) const
1254 {
1255     // Give up if in quirks mode and we're a body/table cell and the top margin of the child box is quirky.
1256     // Give up if the child specified -webkit-margin-collapse: separate that prevents collapsing.
1257     // FIXME: Use writing mode independent accessor for marginBeforeCollapse.
1258     if ((document().inQuirksMode() && hasMarginAfterQuirk(child) && (isTableCell() || isBody())) || child.style().marginBeforeCollapse() == MSEPARATE)
1259         return;
1260
1261     // The margins are discarded by a child that specified -webkit-margin-collapse: discard.
1262     // FIXME: Use writing mode independent accessor for marginBeforeCollapse.
1263     if (child.style().marginBeforeCollapse() == MDISCARD) {
1264         positiveMarginBefore = 0;
1265         negativeMarginBefore = 0;
1266         discardMarginBefore = true;
1267         return;
1268     }
1269
1270     LayoutUnit beforeChildMargin = marginBeforeForChild(child);
1271     positiveMarginBefore = std::max(positiveMarginBefore, beforeChildMargin);
1272     negativeMarginBefore = std::max(negativeMarginBefore, -beforeChildMargin);
1273
1274     if (!is<RenderBlockFlow>(child))
1275         return;
1276     
1277     RenderBlockFlow& childBlock = downcast<RenderBlockFlow>(child);
1278     if (childBlock.childrenInline() || childBlock.isWritingModeRoot())
1279         return;
1280
1281     MarginInfo childMarginInfo(childBlock, childBlock.borderAndPaddingBefore(), childBlock.borderAndPaddingAfter());
1282     if (!childMarginInfo.canCollapseMarginBeforeWithChildren())
1283         return;
1284
1285     RenderBox* grandchildBox = childBlock.firstChildBox();
1286     for (; grandchildBox; grandchildBox = grandchildBox->nextSiblingBox()) {
1287         if (!grandchildBox->isFloatingOrOutOfFlowPositioned())
1288             break;
1289     }
1290     
1291     // Give up if there is clearance on the box, since it probably won't collapse into us.
1292     if (!grandchildBox || grandchildBox->style().clear() != CNONE)
1293         return;
1294
1295     // Make sure to update the block margins now for the grandchild box so that we're looking at current values.
1296     if (grandchildBox->needsLayout()) {
1297         grandchildBox->computeAndSetBlockDirectionMargins(*this);
1298         if (is<RenderBlock>(*grandchildBox)) {
1299             RenderBlock& grandchildBlock = downcast<RenderBlock>(*grandchildBox);
1300             grandchildBlock.setHasMarginBeforeQuirk(grandchildBox->style().hasMarginBeforeQuirk());
1301             grandchildBlock.setHasMarginAfterQuirk(grandchildBox->style().hasMarginAfterQuirk());
1302         }
1303     }
1304
1305     // Collapse the margin of the grandchild box with our own to produce an estimate.
1306     childBlock.marginBeforeEstimateForChild(*grandchildBox, positiveMarginBefore, negativeMarginBefore, discardMarginBefore);
1307 }
1308
1309 LayoutUnit RenderBlockFlow::estimateLogicalTopPosition(RenderBox& child, const MarginInfo& marginInfo, LayoutUnit& estimateWithoutPagination)
1310 {
1311     // FIXME: We need to eliminate the estimation of vertical position, because when it's wrong we sometimes trigger a pathological
1312     // relayout if there are intruding floats.
1313     LayoutUnit logicalTopEstimate = logicalHeight();
1314     if (!marginInfo.canCollapseWithMarginBefore()) {
1315         LayoutUnit positiveMarginBefore = 0;
1316         LayoutUnit negativeMarginBefore = 0;
1317         bool discardMarginBefore = false;
1318         if (child.selfNeedsLayout()) {
1319             // Try to do a basic estimation of how the collapse is going to go.
1320             marginBeforeEstimateForChild(child, positiveMarginBefore, negativeMarginBefore, discardMarginBefore);
1321         } else {
1322             // Use the cached collapsed margin values from a previous layout. Most of the time they
1323             // will be right.
1324             MarginValues marginValues = marginValuesForChild(child);
1325             positiveMarginBefore = std::max(positiveMarginBefore, marginValues.positiveMarginBefore());
1326             negativeMarginBefore = std::max(negativeMarginBefore, marginValues.negativeMarginBefore());
1327             discardMarginBefore = mustDiscardMarginBeforeForChild(child);
1328         }
1329
1330         // Collapse the result with our current margins.
1331         if (!discardMarginBefore)
1332             logicalTopEstimate += std::max(marginInfo.positiveMargin(), positiveMarginBefore) - std::max(marginInfo.negativeMargin(), negativeMarginBefore);
1333     }
1334
1335     // Adjust logicalTopEstimate down to the next page if the margins are so large that we don't fit on the current
1336     // page.
1337     LayoutState* layoutState = view().layoutState();
1338     if (layoutState->isPaginated() && layoutState->pageLogicalHeight() && logicalTopEstimate > logicalHeight()
1339         && hasNextPage(logicalHeight()))
1340         logicalTopEstimate = std::min(logicalTopEstimate, nextPageLogicalTop(logicalHeight()));
1341
1342     logicalTopEstimate += getClearDelta(child, logicalTopEstimate);
1343     
1344     estimateWithoutPagination = logicalTopEstimate;
1345
1346     if (layoutState->isPaginated()) {
1347         // If the object has a page or column break value of "before", then we should shift to the top of the next page.
1348         logicalTopEstimate = applyBeforeBreak(child, logicalTopEstimate);
1349     
1350         // For replaced elements and scrolled elements, we want to shift them to the next page if they don't fit on the current one.
1351         logicalTopEstimate = adjustForUnsplittableChild(child, logicalTopEstimate);
1352         
1353         if (!child.selfNeedsLayout() && is<RenderBlock>(child))
1354             logicalTopEstimate += downcast<RenderBlock>(child).paginationStrut();
1355     }
1356
1357     return logicalTopEstimate;
1358 }
1359
1360 void RenderBlockFlow::setCollapsedBottomMargin(const MarginInfo& marginInfo)
1361 {
1362     if (marginInfo.canCollapseWithMarginAfter() && !marginInfo.canCollapseWithMarginBefore()) {
1363         // Update the after side margin of the container to discard if the after margin of the last child also discards and we collapse with it.
1364         // Don't update the max margin values because we won't need them anyway.
1365         if (marginInfo.discardMargin()) {
1366             setMustDiscardMarginAfter();
1367             return;
1368         }
1369
1370         // Update our max pos/neg bottom margins, since we collapsed our bottom margins
1371         // with our children.
1372         setMaxMarginAfterValues(std::max(maxPositiveMarginAfter(), marginInfo.positiveMargin()), std::max(maxNegativeMarginAfter(), marginInfo.negativeMargin()));
1373
1374         if (!marginInfo.hasMarginAfterQuirk())
1375             setHasMarginAfterQuirk(false);
1376
1377         if (marginInfo.hasMarginAfterQuirk() && !marginAfter())
1378             // We have no bottom margin and our last child has a quirky margin.
1379             // We will pick up this quirky margin and pass it through.
1380             // This deals with the <td><div><p> case.
1381             setHasMarginAfterQuirk(true);
1382     }
1383 }
1384
1385 void RenderBlockFlow::handleAfterSideOfBlock(LayoutUnit beforeSide, LayoutUnit afterSide, MarginInfo& marginInfo)
1386 {
1387     marginInfo.setAtAfterSideOfBlock(true);
1388
1389     // If our last child was a self-collapsing block with clearance then our logical height is flush with the
1390     // bottom edge of the float that the child clears. The correct vertical position for the margin-collapsing we want
1391     // to perform now is at the child's margin-top - so adjust our height to that position.
1392     RenderObject* lastBlock = lastChild();
1393     if (is<RenderBlockFlow>(lastBlock) && downcast<RenderBlockFlow>(*lastBlock).isSelfCollapsingBlock())
1394         setLogicalHeight(logicalHeight() - downcast<RenderBlockFlow>(*lastBlock).marginOffsetForSelfCollapsingBlock());
1395
1396     // If we can't collapse with children then add in the bottom margin.
1397     if (!marginInfo.discardMargin() && (!marginInfo.canCollapseWithMarginAfter() && !marginInfo.canCollapseWithMarginBefore()
1398         && (!document().inQuirksMode() || !marginInfo.quirkContainer() || !marginInfo.hasMarginAfterQuirk())))
1399         setLogicalHeight(logicalHeight() + marginInfo.margin());
1400         
1401     // Now add in our bottom border/padding.
1402     setLogicalHeight(logicalHeight() + afterSide);
1403
1404     // Negative margins can cause our height to shrink below our minimal height (border/padding).
1405     // If this happens, ensure that the computed height is increased to the minimal height.
1406     setLogicalHeight(std::max(logicalHeight(), beforeSide + afterSide));
1407
1408     // Update our bottom collapsed margin info.
1409     setCollapsedBottomMargin(marginInfo);
1410 }
1411
1412 void RenderBlockFlow::setMaxMarginBeforeValues(LayoutUnit pos, LayoutUnit neg)
1413 {
1414     if (!hasRareBlockFlowData()) {
1415         if (pos == RenderBlockFlowRareData::positiveMarginBeforeDefault(*this) && neg == RenderBlockFlowRareData::negativeMarginBeforeDefault(*this))
1416             return;
1417         materializeRareBlockFlowData();
1418     }
1419
1420     rareBlockFlowData()->m_margins.setPositiveMarginBefore(pos);
1421     rareBlockFlowData()->m_margins.setNegativeMarginBefore(neg);
1422 }
1423
1424 void RenderBlockFlow::setMaxMarginAfterValues(LayoutUnit pos, LayoutUnit neg)
1425 {
1426     if (!hasRareBlockFlowData()) {
1427         if (pos == RenderBlockFlowRareData::positiveMarginAfterDefault(*this) && neg == RenderBlockFlowRareData::negativeMarginAfterDefault(*this))
1428             return;
1429         materializeRareBlockFlowData();
1430     }
1431
1432     rareBlockFlowData()->m_margins.setPositiveMarginAfter(pos);
1433     rareBlockFlowData()->m_margins.setNegativeMarginAfter(neg);
1434 }
1435
1436 void RenderBlockFlow::setMustDiscardMarginBefore(bool value)
1437 {
1438     if (style().marginBeforeCollapse() == MDISCARD) {
1439         ASSERT(value);
1440         return;
1441     }
1442
1443     if (!hasRareBlockFlowData()) {
1444         if (!value)
1445             return;
1446         materializeRareBlockFlowData();
1447     }
1448
1449     rareBlockFlowData()->m_discardMarginBefore = value;
1450 }
1451
1452 void RenderBlockFlow::setMustDiscardMarginAfter(bool value)
1453 {
1454     if (style().marginAfterCollapse() == MDISCARD) {
1455         ASSERT(value);
1456         return;
1457     }
1458
1459     if (!hasRareBlockFlowData()) {
1460         if (!value)
1461             return;
1462         materializeRareBlockFlowData();
1463     }
1464
1465     rareBlockFlowData()->m_discardMarginAfter = value;
1466 }
1467
1468 bool RenderBlockFlow::mustDiscardMarginBefore() const
1469 {
1470     return style().marginBeforeCollapse() == MDISCARD || (hasRareBlockFlowData() && rareBlockFlowData()->m_discardMarginBefore);
1471 }
1472
1473 bool RenderBlockFlow::mustDiscardMarginAfter() const
1474 {
1475     return style().marginAfterCollapse() == MDISCARD || (hasRareBlockFlowData() && rareBlockFlowData()->m_discardMarginAfter);
1476 }
1477
1478 bool RenderBlockFlow::mustDiscardMarginBeforeForChild(const RenderBox& child) const
1479 {
1480     ASSERT(!child.selfNeedsLayout());
1481     if (!child.isWritingModeRoot())
1482         return is<RenderBlockFlow>(child) ? downcast<RenderBlockFlow>(child).mustDiscardMarginBefore() : (child.style().marginBeforeCollapse() == MDISCARD);
1483     if (child.isHorizontalWritingMode() == isHorizontalWritingMode())
1484         return is<RenderBlockFlow>(child) ? downcast<RenderBlockFlow>(child).mustDiscardMarginAfter() : (child.style().marginAfterCollapse() == MDISCARD);
1485
1486     // FIXME: We return false here because the implementation is not geometrically complete. We have values only for before/after, not start/end.
1487     // In case the boxes are perpendicular we assume the property is not specified.
1488     return false;
1489 }
1490
1491 bool RenderBlockFlow::mustDiscardMarginAfterForChild(const RenderBox& child) const
1492 {
1493     ASSERT(!child.selfNeedsLayout());
1494     if (!child.isWritingModeRoot())
1495         return is<RenderBlockFlow>(child) ? downcast<RenderBlockFlow>(child).mustDiscardMarginAfter() : (child.style().marginAfterCollapse() == MDISCARD);
1496     if (child.isHorizontalWritingMode() == isHorizontalWritingMode())
1497         return is<RenderBlockFlow>(child) ? downcast<RenderBlockFlow>(child).mustDiscardMarginBefore() : (child.style().marginBeforeCollapse() == MDISCARD);
1498
1499     // FIXME: See |mustDiscardMarginBeforeForChild| above.
1500     return false;
1501 }
1502
1503 bool RenderBlockFlow::mustSeparateMarginBeforeForChild(const RenderBox& child) const
1504 {
1505     ASSERT(!child.selfNeedsLayout());
1506     const RenderStyle& childStyle = child.style();
1507     if (!child.isWritingModeRoot())
1508         return childStyle.marginBeforeCollapse() == MSEPARATE;
1509     if (child.isHorizontalWritingMode() == isHorizontalWritingMode())
1510         return childStyle.marginAfterCollapse() == MSEPARATE;
1511
1512     // FIXME: See |mustDiscardMarginBeforeForChild| above.
1513     return false;
1514 }
1515
1516 bool RenderBlockFlow::mustSeparateMarginAfterForChild(const RenderBox& child) const
1517 {
1518     ASSERT(!child.selfNeedsLayout());
1519     const RenderStyle& childStyle = child.style();
1520     if (!child.isWritingModeRoot())
1521         return childStyle.marginAfterCollapse() == MSEPARATE;
1522     if (child.isHorizontalWritingMode() == isHorizontalWritingMode())
1523         return childStyle.marginBeforeCollapse() == MSEPARATE;
1524
1525     // FIXME: See |mustDiscardMarginBeforeForChild| above.
1526     return false;
1527 }
1528
1529 static bool inNormalFlow(RenderBox& child)
1530 {
1531     RenderBlock* curr = child.containingBlock();
1532     while (curr && curr != &child.view()) {
1533         if (curr->isRenderFlowThread())
1534             return true;
1535         if (curr->isFloatingOrOutOfFlowPositioned())
1536             return false;
1537         curr = curr->containingBlock();
1538     }
1539     return true;
1540 }
1541
1542 LayoutUnit RenderBlockFlow::applyBeforeBreak(RenderBox& child, LayoutUnit logicalOffset)
1543 {
1544     // FIXME: Add page break checking here when we support printing.
1545     RenderFlowThread* flowThread = flowThreadContainingBlock();
1546     bool isInsideMulticolFlowThread = flowThread && !flowThread->isRenderNamedFlowThread();
1547     bool checkColumnBreaks = flowThread && flowThread->shouldCheckColumnBreaks();
1548     bool checkPageBreaks = !checkColumnBreaks && view().layoutState()->m_pageLogicalHeight; // FIXME: Once columns can print we have to check this.
1549     bool checkRegionBreaks = flowThread && flowThread->isRenderNamedFlowThread();
1550     bool checkBeforeAlways = (checkColumnBreaks && child.style().breakBefore() == ColumnBreakBetween)
1551         || (checkPageBreaks && alwaysPageBreak(child.style().breakBefore()))
1552         || (checkRegionBreaks && child.style().breakBefore() == RegionBreakBetween);
1553     if (checkBeforeAlways && inNormalFlow(child) && hasNextPage(logicalOffset, IncludePageBoundary)) {
1554         if (checkColumnBreaks) {
1555             if (isInsideMulticolFlowThread)
1556                 checkRegionBreaks = true;
1557         }
1558         if (checkRegionBreaks) {
1559             LayoutUnit offsetBreakAdjustment = 0;
1560             if (flowThread->addForcedRegionBreak(this, offsetFromLogicalTopOfFirstPage() + logicalOffset, &child, true, &offsetBreakAdjustment))
1561                 return logicalOffset + offsetBreakAdjustment;
1562         }
1563         return nextPageLogicalTop(logicalOffset, IncludePageBoundary);
1564     }
1565     return logicalOffset;
1566 }
1567
1568 LayoutUnit RenderBlockFlow::applyAfterBreak(RenderBox& child, LayoutUnit logicalOffset, MarginInfo& marginInfo)
1569 {
1570     // FIXME: Add page break checking here when we support printing.
1571     RenderFlowThread* flowThread = flowThreadContainingBlock();
1572     bool isInsideMulticolFlowThread = flowThread && !flowThread->isRenderNamedFlowThread();
1573     bool checkColumnBreaks = flowThread && flowThread->shouldCheckColumnBreaks();
1574     bool checkPageBreaks = !checkColumnBreaks && view().layoutState()->m_pageLogicalHeight; // FIXME: Once columns can print we have to check this.
1575     bool checkRegionBreaks = flowThread && flowThread->isRenderNamedFlowThread();
1576     bool checkAfterAlways = (checkColumnBreaks && child.style().breakAfter() == ColumnBreakBetween)
1577         || (checkPageBreaks && alwaysPageBreak(child.style().breakAfter()))
1578         || (checkRegionBreaks && child.style().breakAfter() == RegionBreakBetween);
1579     if (checkAfterAlways && inNormalFlow(child) && hasNextPage(logicalOffset, IncludePageBoundary)) {
1580         LayoutUnit marginOffset = marginInfo.canCollapseWithMarginBefore() ? LayoutUnit() : marginInfo.margin();
1581
1582         // So our margin doesn't participate in the next collapsing steps.
1583         marginInfo.clearMargin();
1584
1585         if (checkColumnBreaks) {
1586             if (isInsideMulticolFlowThread)
1587                 checkRegionBreaks = true;
1588         }
1589         if (checkRegionBreaks) {
1590             LayoutUnit offsetBreakAdjustment = 0;
1591             if (flowThread->addForcedRegionBreak(this, offsetFromLogicalTopOfFirstPage() + logicalOffset + marginOffset, &child, false, &offsetBreakAdjustment))
1592                 return logicalOffset + marginOffset + offsetBreakAdjustment;
1593         }
1594         return nextPageLogicalTop(logicalOffset, IncludePageBoundary);
1595     }
1596     return logicalOffset;
1597 }
1598
1599 LayoutUnit RenderBlockFlow::adjustBlockChildForPagination(LayoutUnit logicalTopAfterClear, LayoutUnit estimateWithoutPagination, RenderBox& child, bool atBeforeSideOfBlock)
1600 {
1601     RenderBlock* childRenderBlock = is<RenderBlock>(child) ? &downcast<RenderBlock>(child) : nullptr;
1602
1603     if (estimateWithoutPagination != logicalTopAfterClear) {
1604         // Our guess prior to pagination movement was wrong. Before we attempt to paginate, let's try again at the new
1605         // position.
1606         setLogicalHeight(logicalTopAfterClear);
1607         setLogicalTopForChild(child, logicalTopAfterClear, ApplyLayoutDelta);
1608
1609         if (child.shrinkToAvoidFloats()) {
1610             // The child's width depends on the line width. When the child shifts to clear an item, its width can
1611             // change (because it has more available line width). So mark the item as dirty.
1612             child.setChildNeedsLayout(MarkOnlyThis);
1613         }
1614         
1615         if (childRenderBlock) {
1616             if (!child.avoidsFloats() && childRenderBlock->containsFloats())
1617                 downcast<RenderBlockFlow>(*childRenderBlock).markAllDescendantsWithFloatsForLayout();
1618             child.markForPaginationRelayoutIfNeeded();
1619         }
1620
1621         // Our guess was wrong. Make the child lay itself out again.
1622         child.layoutIfNeeded();
1623     }
1624
1625     LayoutUnit oldTop = logicalTopAfterClear;
1626
1627     // If the object has a page or column break value of "before", then we should shift to the top of the next page.
1628     LayoutUnit result = applyBeforeBreak(child, logicalTopAfterClear);
1629
1630     if (pageLogicalHeightForOffset(result)) {
1631         LayoutUnit remainingLogicalHeight = pageRemainingLogicalHeightForOffset(result, ExcludePageBoundary);
1632         LayoutUnit spaceShortage = child.logicalHeight() - remainingLogicalHeight;
1633         if (spaceShortage > 0) {
1634             // If the child crosses a column boundary, report a break, in case nothing inside it has already
1635             // done so. The column balancer needs to know how much it has to stretch the columns to make more
1636             // content fit. If no breaks are reported (but do occur), the balancer will have no clue. FIXME:
1637             // This should be improved, though, because here we just pretend that the child is
1638             // unsplittable. A splittable child, on the other hand, has break opportunities at every position
1639             // where there's no child content, border or padding. In other words, we risk stretching more
1640             // than necessary.
1641             setPageBreak(result, spaceShortage);
1642         }
1643     }
1644
1645     // For replaced elements and scrolled elements, we want to shift them to the next page if they don't fit on the current one.
1646     LayoutUnit logicalTopBeforeUnsplittableAdjustment = result;
1647     LayoutUnit logicalTopAfterUnsplittableAdjustment = adjustForUnsplittableChild(child, result);
1648     
1649     LayoutUnit paginationStrut = 0;
1650     LayoutUnit unsplittableAdjustmentDelta = logicalTopAfterUnsplittableAdjustment - logicalTopBeforeUnsplittableAdjustment;
1651     if (unsplittableAdjustmentDelta)
1652         paginationStrut = unsplittableAdjustmentDelta;
1653     else if (childRenderBlock && childRenderBlock->paginationStrut())
1654         paginationStrut = childRenderBlock->paginationStrut();
1655
1656     if (paginationStrut) {
1657         // We are willing to propagate out to our parent block as long as we were at the top of the block prior
1658         // to collapsing our margins, and as long as we didn't clear or move as a result of other pagination.
1659         if (atBeforeSideOfBlock && oldTop == result && !isOutOfFlowPositioned() && !isTableCell()) {
1660             // FIXME: Should really check if we're exceeding the page height before propagating the strut, but we don't
1661             // have all the information to do so (the strut only has the remaining amount to push). Gecko gets this wrong too
1662             // and pushes to the next page anyway, so not too concerned about it.
1663             setPaginationStrut(result + paginationStrut);
1664             if (childRenderBlock)
1665                 childRenderBlock->setPaginationStrut(0);
1666         } else
1667             result += paginationStrut;
1668     }
1669
1670     // Similar to how we apply clearance. Boost height() to be the place where we're going to position the child.
1671     setLogicalHeight(logicalHeight() + (result - oldTop));
1672     
1673     // Return the final adjusted logical top.
1674     return result;
1675 }
1676
1677 static inline LayoutUnit calculateMinimumPageHeight(const RenderStyle& renderStyle, RootInlineBox& lastLine, LayoutUnit lineTop, LayoutUnit lineBottom)
1678 {
1679     // We may require a certain minimum number of lines per page in order to satisfy
1680     // orphans and widows, and that may affect the minimum page height.
1681     unsigned lineCount = std::max<unsigned>(renderStyle.hasAutoOrphans() ? 1 : renderStyle.orphans(), renderStyle.hasAutoWidows() ? 1 : renderStyle.widows());
1682     if (lineCount > 1) {
1683         RootInlineBox* line = &lastLine;
1684         for (unsigned i = 1; i < lineCount && line->prevRootBox(); i++)
1685             line = line->prevRootBox();
1686
1687         // FIXME: Paginating using line overflow isn't all fine. See FIXME in
1688         // adjustLinePositionForPagination() for more details.
1689         LayoutRect overflow = line->logicalVisualOverflowRect(line->lineTop(), line->lineBottom());
1690         lineTop = std::min(line->lineTopWithLeading(), overflow.y());
1691     }
1692     return lineBottom - lineTop;
1693 }
1694
1695 static inline bool needsAppleMailPaginationQuirk(RootInlineBox& lineBox)
1696 {
1697     auto& renderer = lineBox.renderer();
1698
1699     if (!renderer.settings().appleMailPaginationQuirkEnabled())
1700         return false;
1701
1702     if (renderer.element() && renderer.element()->idForStyleResolution() == "messageContentContainer")
1703         return true;
1704
1705     return false;
1706 }
1707
1708 static void clearShouldBreakAtLineToAvoidWidowIfNeeded(RenderBlockFlow& blockFlow)
1709 {
1710     if (!blockFlow.shouldBreakAtLineToAvoidWidow())
1711         return;
1712     blockFlow.clearShouldBreakAtLineToAvoidWidow();
1713     blockFlow.setDidBreakAtLineToAvoidWidow();
1714 }
1715
1716 void RenderBlockFlow::adjustLinePositionForPagination(RootInlineBox* lineBox, LayoutUnit& delta, bool& overflowsRegion, RenderFlowThread* flowThread)
1717 {
1718     // FIXME: Ignore anonymous inline blocks. Handle the delta already having been set because of
1719     // collapsing margins from a previous anonymous inline block.
1720     // FIXME: For now we paginate using line overflow. This ensures that lines don't overlap at all when we
1721     // put a strut between them for pagination purposes. However, this really isn't the desired rendering, since
1722     // the line on the top of the next page will appear too far down relative to the same kind of line at the top
1723     // of the first column.
1724     //
1725     // The rendering we would like to see is one where the lineTopWithLeading is at the top of the column, and any line overflow
1726     // simply spills out above the top of the column. This effect would match what happens at the top of the first column.
1727     // We can't achieve this rendering, however, until we stop columns from clipping to the column bounds (thus allowing
1728     // for overflow to occur), and then cache visible overflow for each column rect.
1729     //
1730     // Furthermore, the paint we have to do when a column has overflow has to be special. We need to exclude
1731     // content that paints in a previous column (and content that paints in the following column).
1732     //
1733     // For now we'll at least honor the lineTopWithLeading when paginating if it is above the logical top overflow. This will
1734     // at least make positive leading work in typical cases.
1735     //
1736     // FIXME: Another problem with simply moving lines is that the available line width may change (because of floats).
1737     // Technically if the location we move the line to has a different line width than our old position, then we need to dirty the
1738     // line and all following lines.
1739     overflowsRegion = false;
1740     LayoutRect logicalVisualOverflow = lineBox->logicalVisualOverflowRect(lineBox->lineTop(), lineBox->lineBottom());
1741     LayoutUnit logicalOffset = std::min(lineBox->lineTopWithLeading(), logicalVisualOverflow.y());
1742     LayoutUnit logicalBottom = std::max(lineBox->lineBottomWithLeading(), logicalVisualOverflow.maxY());
1743     LayoutUnit lineHeight = logicalBottom - logicalOffset;
1744     updateMinimumPageHeight(logicalOffset, calculateMinimumPageHeight(style(), *lineBox, logicalOffset, logicalBottom));
1745     logicalOffset += delta;
1746     lineBox->setPaginationStrut(0);
1747     lineBox->setIsFirstAfterPageBreak(false);
1748     LayoutUnit pageLogicalHeight = pageLogicalHeightForOffset(logicalOffset);
1749     bool hasUniformPageLogicalHeight = !flowThread || flowThread->regionsHaveUniformLogicalHeight();
1750     // If lineHeight is greater than pageLogicalHeight, but logicalVisualOverflow.height() still fits, we are
1751     // still going to add a strut, so that the visible overflow fits on a single page.
1752     if (!pageLogicalHeight || !hasNextPage(logicalOffset)) {
1753         // FIXME: In case the line aligns with the top of the page (or it's slightly shifted downwards) it will not be marked as the first line in the page.
1754         // From here, the fix is not straightforward because it's not easy to always determine when the current line is the first in the page.
1755         return;
1756     }
1757
1758     if (hasUniformPageLogicalHeight && logicalVisualOverflow.height() > pageLogicalHeight) {
1759         // We are so tall that we are bigger than a page. Before we give up and just leave the line where it is, try drilling into the
1760         // line and computing a new height that excludes anything we consider "blank space". We will discard margins, descent, and even overflow. If we are
1761         // able to fit with the blank space and overflow excluded, we will give the line its own page with the highest non-blank element being aligned with the
1762         // top of the page.
1763         // FIXME: We are still honoring gigantic margins, which does leave open the possibility of blank pages caused by this heuristic. It remains to be seen whether or not
1764         // this will be a real-world issue. For now we don't try to deal with this problem.
1765         logicalOffset = intMaxForLayoutUnit;
1766         logicalBottom = intMinForLayoutUnit;
1767         lineBox->computeReplacedAndTextLineTopAndBottom(logicalOffset, logicalBottom);
1768         lineHeight = logicalBottom - logicalOffset;
1769         if (logicalOffset == intMaxForLayoutUnit || lineHeight > pageLogicalHeight) {
1770             // Give up. We're genuinely too big even after excluding blank space and overflow.
1771             clearShouldBreakAtLineToAvoidWidowIfNeeded(*this);
1772             return;
1773         }
1774         pageLogicalHeight = pageLogicalHeightForOffset(logicalOffset);
1775     }
1776     
1777     LayoutUnit remainingLogicalHeight = pageRemainingLogicalHeightForOffset(logicalOffset, ExcludePageBoundary);
1778     overflowsRegion = (lineHeight > remainingLogicalHeight);
1779
1780     int lineIndex = lineCount(lineBox);
1781     if (remainingLogicalHeight < lineHeight || (shouldBreakAtLineToAvoidWidow() && lineBreakToAvoidWidow() == lineIndex)) {
1782         if (lineBreakToAvoidWidow() == lineIndex)
1783             clearShouldBreakAtLineToAvoidWidowIfNeeded(*this);
1784         // If we have a non-uniform page height, then we have to shift further possibly.
1785         if (!hasUniformPageLogicalHeight && !pushToNextPageWithMinimumLogicalHeight(remainingLogicalHeight, logicalOffset, lineHeight))
1786             return;
1787         if (lineHeight > pageLogicalHeight) {
1788             // Split the top margin in order to avoid splitting the visible part of the line.
1789             remainingLogicalHeight -= std::min(lineHeight - pageLogicalHeight, std::max<LayoutUnit>(0, logicalVisualOverflow.y() - lineBox->lineTopWithLeading()));
1790         }
1791         LayoutUnit remainingLogicalHeightAtNewOffset = pageRemainingLogicalHeightForOffset(logicalOffset + remainingLogicalHeight, ExcludePageBoundary);
1792         overflowsRegion = (lineHeight > remainingLogicalHeightAtNewOffset);
1793         LayoutUnit totalLogicalHeight = lineHeight + std::max<LayoutUnit>(0, logicalOffset);
1794         LayoutUnit pageLogicalHeightAtNewOffset = hasUniformPageLogicalHeight ? pageLogicalHeight : pageLogicalHeightForOffset(logicalOffset + remainingLogicalHeight);
1795         setPageBreak(logicalOffset, lineHeight - remainingLogicalHeight);
1796         if (((lineBox == firstRootBox() && totalLogicalHeight < pageLogicalHeightAtNewOffset) || (!style().hasAutoOrphans() && style().orphans() >= lineIndex))
1797             && !isOutOfFlowPositioned() && !isTableCell()) {
1798             auto firstRootBox = this->firstRootBox();
1799             auto firstRootBoxOverflowRect = firstRootBox->logicalVisualOverflowRect(firstRootBox->lineTop(), firstRootBox->lineBottom());
1800             auto firstLineUpperOverhang = std::max(-firstRootBoxOverflowRect.y(), LayoutUnit());
1801             if (needsAppleMailPaginationQuirk(*lineBox))
1802                 return;
1803             setPaginationStrut(remainingLogicalHeight + logicalOffset + firstLineUpperOverhang);
1804         } else {
1805             delta += remainingLogicalHeight;
1806             lineBox->setPaginationStrut(remainingLogicalHeight);
1807             lineBox->setIsFirstAfterPageBreak(true);
1808         }
1809     } else if (remainingLogicalHeight == pageLogicalHeight) {
1810         // We're at the very top of a page or column.
1811         if (lineBox != firstRootBox())
1812             lineBox->setIsFirstAfterPageBreak(true);
1813         if (lineBox != firstRootBox() || offsetFromLogicalTopOfFirstPage())
1814             setPageBreak(logicalOffset, lineHeight);
1815     }
1816 }
1817
1818 void RenderBlockFlow::setBreakAtLineToAvoidWidow(int lineToBreak)
1819 {
1820     ASSERT(lineToBreak >= 0);
1821     ASSERT(!ensureRareBlockFlowData().m_didBreakAtLineToAvoidWidow);
1822     ensureRareBlockFlowData().m_lineBreakToAvoidWidow = lineToBreak;
1823 }
1824
1825 void RenderBlockFlow::setDidBreakAtLineToAvoidWidow()
1826 {
1827     ASSERT(!shouldBreakAtLineToAvoidWidow());
1828     if (!hasRareBlockFlowData())
1829         return;
1830
1831     rareBlockFlowData()->m_didBreakAtLineToAvoidWidow = true;
1832 }
1833
1834 void RenderBlockFlow::clearDidBreakAtLineToAvoidWidow()
1835 {
1836     if (!hasRareBlockFlowData())
1837         return;
1838
1839     rareBlockFlowData()->m_didBreakAtLineToAvoidWidow = false;
1840 }
1841
1842 void RenderBlockFlow::clearShouldBreakAtLineToAvoidWidow() const
1843 {
1844     ASSERT(shouldBreakAtLineToAvoidWidow());
1845     if (!hasRareBlockFlowData())
1846         return;
1847
1848     rareBlockFlowData()->m_lineBreakToAvoidWidow = -1;
1849 }
1850
1851 bool RenderBlockFlow::relayoutToAvoidWidows(LayoutStateMaintainer& statePusher)
1852 {
1853     if (!shouldBreakAtLineToAvoidWidow())
1854         return false;
1855
1856     statePusher.pop();
1857     setEverHadLayout(true);
1858     layoutBlock(false);
1859     return true;
1860 }
1861
1862 bool RenderBlockFlow::hasNextPage(LayoutUnit logicalOffset, PageBoundaryRule pageBoundaryRule) const
1863 {
1864     ASSERT(view().layoutState() && view().layoutState()->isPaginated());
1865
1866     RenderFlowThread* flowThread = flowThreadContainingBlock();
1867     if (!flowThread)
1868         return true; // Printing and multi-column both make new pages to accommodate content.
1869
1870     // See if we're in the last region.
1871     LayoutUnit pageOffset = offsetFromLogicalTopOfFirstPage() + logicalOffset;
1872     RenderRegion* region = flowThread->regionAtBlockOffset(this, pageOffset, true);
1873     if (!region)
1874         return false;
1875
1876     if (region->isLastRegion())
1877         return region->isRenderRegionSet() || region->style().regionFragment() == BreakRegionFragment
1878             || (pageBoundaryRule == IncludePageBoundary && pageOffset == region->logicalTopForFlowThreadContent());
1879
1880     RenderRegion* startRegion = nullptr;
1881     RenderRegion* endRegion = nullptr;
1882     flowThread->getRegionRangeForBox(this, startRegion, endRegion);
1883     return (endRegion && region != endRegion);
1884 }
1885
1886 LayoutUnit RenderBlockFlow::adjustForUnsplittableChild(RenderBox& child, LayoutUnit logicalOffset, LayoutUnit childBeforeMargin, LayoutUnit childAfterMargin)
1887 {
1888     // When flexboxes are embedded inside a block flow, they don't perform any adjustments for unsplittable
1889     // children. We'll treat flexboxes themselves as unsplittable just to get them to paginate properly inside
1890     // a block flow.
1891     bool isUnsplittable = childBoxIsUnsplittableForFragmentation(child);
1892     if (!isUnsplittable && !(child.isFlexibleBox() && !downcast<RenderFlexibleBox>(child).isFlexibleBoxImpl()))
1893         return logicalOffset;
1894     
1895     RenderFlowThread* flowThread = flowThreadContainingBlock();
1896     LayoutUnit childLogicalHeight = logicalHeightForChild(child) + childBeforeMargin + childAfterMargin;
1897     LayoutUnit pageLogicalHeight = pageLogicalHeightForOffset(logicalOffset);
1898     bool hasUniformPageLogicalHeight = !flowThread || flowThread->regionsHaveUniformLogicalHeight();
1899     if (isUnsplittable)
1900         updateMinimumPageHeight(logicalOffset, childLogicalHeight);
1901     if (!pageLogicalHeight || (hasUniformPageLogicalHeight && childLogicalHeight > pageLogicalHeight)
1902         || !hasNextPage(logicalOffset))
1903         return logicalOffset;
1904     LayoutUnit remainingLogicalHeight = pageRemainingLogicalHeightForOffset(logicalOffset, ExcludePageBoundary);
1905     if (remainingLogicalHeight < childLogicalHeight) {
1906         if (!hasUniformPageLogicalHeight && !pushToNextPageWithMinimumLogicalHeight(remainingLogicalHeight, logicalOffset, childLogicalHeight))
1907             return logicalOffset;
1908         auto result = logicalOffset + remainingLogicalHeight;
1909         bool isInitialLetter = child.isFloating() && child.style().styleType() == FIRST_LETTER && child.style().initialLetterDrop() > 0;
1910         if (isInitialLetter) {
1911             // Increase our logical height to ensure that lines all get pushed along with the letter.
1912             setLogicalHeight(logicalOffset + remainingLogicalHeight);
1913         }
1914         return result;
1915     }
1916
1917     return logicalOffset;
1918 }
1919
1920 bool RenderBlockFlow::pushToNextPageWithMinimumLogicalHeight(LayoutUnit& adjustment, LayoutUnit logicalOffset, LayoutUnit minimumLogicalHeight) const
1921 {
1922     bool checkRegion = false;
1923     for (LayoutUnit pageLogicalHeight = pageLogicalHeightForOffset(logicalOffset + adjustment); pageLogicalHeight;
1924         pageLogicalHeight = pageLogicalHeightForOffset(logicalOffset + adjustment)) {
1925         if (minimumLogicalHeight <= pageLogicalHeight)
1926             return true;
1927         if (!hasNextPage(logicalOffset + adjustment))
1928             return false;
1929         adjustment += pageLogicalHeight;
1930         checkRegion = true;
1931     }
1932     return !checkRegion;
1933 }
1934
1935 void RenderBlockFlow::setPageBreak(LayoutUnit offset, LayoutUnit spaceShortage)
1936 {
1937     if (RenderFlowThread* flowThread = flowThreadContainingBlock())
1938         flowThread->setPageBreak(this, offsetFromLogicalTopOfFirstPage() + offset, spaceShortage);
1939 }
1940
1941 void RenderBlockFlow::updateMinimumPageHeight(LayoutUnit offset, LayoutUnit minHeight)
1942 {
1943     if (RenderFlowThread* flowThread = flowThreadContainingBlock())
1944         flowThread->updateMinimumPageHeight(this, offsetFromLogicalTopOfFirstPage() + offset, minHeight);
1945 }
1946
1947 LayoutUnit RenderBlockFlow::nextPageLogicalTop(LayoutUnit logicalOffset, PageBoundaryRule pageBoundaryRule) const
1948 {
1949     LayoutUnit pageLogicalHeight = pageLogicalHeightForOffset(logicalOffset);
1950     if (!pageLogicalHeight)
1951         return logicalOffset;
1952     
1953     // The logicalOffset is in our coordinate space.  We can add in our pushed offset.
1954     LayoutUnit remainingLogicalHeight = pageRemainingLogicalHeightForOffset(logicalOffset);
1955     if (pageBoundaryRule == ExcludePageBoundary)
1956         return logicalOffset + (remainingLogicalHeight ? remainingLogicalHeight : pageLogicalHeight);
1957     return logicalOffset + remainingLogicalHeight;
1958 }
1959
1960 LayoutUnit RenderBlockFlow::pageLogicalTopForOffset(LayoutUnit offset) const
1961 {
1962     // Unsplittable objects clear out the pageLogicalHeight in the layout state as a way of signaling that no
1963     // pagination should occur. Therefore we have to check this first and bail if the value has been set to 0.
1964     LayoutUnit pageLogicalHeight = view().layoutState()->m_pageLogicalHeight;
1965     if (!pageLogicalHeight)
1966         return 0;
1967
1968     LayoutUnit firstPageLogicalTop = isHorizontalWritingMode() ? view().layoutState()->m_pageOffset.height() : view().layoutState()->m_pageOffset.width();
1969     LayoutUnit blockLogicalTop = isHorizontalWritingMode() ? view().layoutState()->m_layoutOffset.height() : view().layoutState()->m_layoutOffset.width();
1970
1971     LayoutUnit cumulativeOffset = offset + blockLogicalTop;
1972     RenderFlowThread* flowThread = flowThreadContainingBlock();
1973     if (!flowThread)
1974         return cumulativeOffset - roundToInt(cumulativeOffset - firstPageLogicalTop) % roundToInt(pageLogicalHeight);
1975     return firstPageLogicalTop + flowThread->pageLogicalTopForOffset(cumulativeOffset - firstPageLogicalTop);
1976 }
1977
1978 LayoutUnit RenderBlockFlow::pageLogicalHeightForOffset(LayoutUnit offset) const
1979 {
1980     // Unsplittable objects clear out the pageLogicalHeight in the layout state as a way of signaling that no
1981     // pagination should occur. Therefore we have to check this first and bail if the value has been set to 0.
1982     LayoutUnit pageLogicalHeight = view().layoutState()->m_pageLogicalHeight;
1983     if (!pageLogicalHeight)
1984         return 0;
1985     
1986     // Now check for a flow thread.
1987     RenderFlowThread* flowThread = flowThreadContainingBlock();
1988     if (!flowThread)
1989         return pageLogicalHeight;
1990     return flowThread->pageLogicalHeightForOffset(offset + offsetFromLogicalTopOfFirstPage());
1991 }
1992
1993 LayoutUnit RenderBlockFlow::pageRemainingLogicalHeightForOffset(LayoutUnit offset, PageBoundaryRule pageBoundaryRule) const
1994 {
1995     offset += offsetFromLogicalTopOfFirstPage();
1996     
1997     RenderFlowThread* flowThread = flowThreadContainingBlock();
1998     if (!flowThread) {
1999         LayoutUnit pageLogicalHeight = view().layoutState()->m_pageLogicalHeight;
2000         LayoutUnit remainingHeight = pageLogicalHeight - intMod(offset, pageLogicalHeight);
2001         if (pageBoundaryRule == IncludePageBoundary) {
2002             // If includeBoundaryPoint is true the line exactly on the top edge of a
2003             // column will act as being part of the previous column.
2004             remainingHeight = intMod(remainingHeight, pageLogicalHeight);
2005         }
2006         return remainingHeight;
2007     }
2008     
2009     return flowThread->pageRemainingLogicalHeightForOffset(offset, pageBoundaryRule);
2010 }
2011
2012 LayoutUnit RenderBlockFlow::logicalHeightForChildForFragmentation(const RenderBox& child) const
2013 {
2014     // This method is required because regions do not fragment monolithic elements but instead
2015     // they let them overflow the region they flow in. This behaviour is different from the 
2016     // multicol/printing implementations, which have not yet been updated to correctly handle
2017     // monolithic elements.
2018     // As a result, for the moment, this method will only be used for regions, the multicol and
2019     // printing implementations will stick to the existing behaviour until their fragmentation
2020     // implementation is updated to match the regions implementation.
2021     if (!flowThreadContainingBlock() || !flowThreadContainingBlock()->isRenderNamedFlowThread())
2022         return logicalHeightForChild(child);
2023
2024     // For unsplittable elements, this method will just return the height of the element that
2025     // fits into the current region, without the height of the part that overflows the region.
2026     // This is done for all regions, except the last one because in that case, the logical
2027     // height of the flow thread needs to also
2028     if (!childBoxIsUnsplittableForFragmentation(child) || !pageLogicalHeightForOffset(logicalTopForChild(child)))
2029         return logicalHeightForChild(child);
2030
2031     // If we're on the last page this block fragments to, the logical height of the flow thread must include
2032     // the entire unsplittable child because any following children will not be moved to the next page
2033     // so they will need to be laid out below the current unsplittable child.
2034     LayoutUnit childLogicalTop = logicalTopForChild(child);
2035     if (!hasNextPage(childLogicalTop))
2036         return logicalHeightForChild(child);
2037     
2038     LayoutUnit remainingLogicalHeight = pageRemainingLogicalHeightForOffset(childLogicalTop, ExcludePageBoundary);
2039     return std::min(child.logicalHeight(), remainingLogicalHeight);
2040 }
2041
2042 void RenderBlockFlow::layoutLineGridBox()
2043 {
2044     if (style().lineGrid() == RenderStyle::initialLineGrid()) {
2045         setLineGridBox(0);
2046         return;
2047     }
2048     
2049     setLineGridBox(0);
2050
2051     auto lineGridBox = std::make_unique<RootInlineBox>(*this);
2052     lineGridBox->setHasTextChildren(); // Needed to make the line ascent/descent actually be honored in quirks mode.
2053     lineGridBox->setConstructed();
2054     GlyphOverflowAndFallbackFontsMap textBoxDataMap;
2055     VerticalPositionCache verticalPositionCache;
2056     lineGridBox->alignBoxesInBlockDirection(logicalHeight(), textBoxDataMap, verticalPositionCache);
2057     
2058     setLineGridBox(WTFMove(lineGridBox));
2059
2060     // FIXME: If any of the characteristics of the box change compared to the old one, then we need to do a deep dirtying
2061     // (similar to what happens when the page height changes). Ideally, though, we only do this if someone is actually snapping
2062     // to this grid.
2063 }
2064
2065 bool RenderBlockFlow::containsFloat(RenderBox& renderer) const
2066 {
2067     return m_floatingObjects && m_floatingObjects->set().contains<RenderBox&, FloatingObjectHashTranslator>(renderer);
2068 }
2069
2070 void RenderBlockFlow::styleDidChange(StyleDifference diff, const RenderStyle* oldStyle)
2071 {
2072     RenderBlock::styleDidChange(diff, oldStyle);
2073     
2074     // After our style changed, if we lose our ability to propagate floats into next sibling
2075     // blocks, then we need to find the top most parent containing that overhanging float and
2076     // then mark its descendants with floats for layout and clear all floats from its next
2077     // sibling blocks that exist in our floating objects list. See bug 56299 and 62875.
2078     bool canPropagateFloatIntoSibling = !isFloatingOrOutOfFlowPositioned() && !avoidsFloats();
2079     if (diff == StyleDifferenceLayout && s_canPropagateFloatIntoSibling && !canPropagateFloatIntoSibling && hasOverhangingFloats()) {
2080         RenderBlockFlow* parentBlock = this;
2081         const FloatingObjectSet& floatingObjectSet = m_floatingObjects->set();
2082
2083         for (auto& ancestor : ancestorsOfType<RenderBlockFlow>(*this)) {
2084             if (ancestor.isRenderView())
2085                 break;
2086             if (ancestor.hasOverhangingFloats()) {
2087                 for (auto it = floatingObjectSet.begin(), end = floatingObjectSet.end(); it != end; ++it) {
2088                     RenderBox& renderer = (*it)->renderer();
2089                     if (ancestor.hasOverhangingFloat(renderer)) {
2090                         parentBlock = &ancestor;
2091                         break;
2092                     }
2093                 }
2094             }
2095         }
2096
2097         parentBlock->markAllDescendantsWithFloatsForLayout();
2098         parentBlock->markSiblingsWithFloatsForLayout();
2099     }
2100     // Fresh floats need to be reparented if they actually belong to the previous anonymous block.
2101     // It copies the logic of RenderBlock::addChildIgnoringContinuation
2102     if (noLongerAffectsParentBlock() && style().isFloating() && previousSibling() && previousSibling()->isAnonymousBlock())
2103         downcast<RenderBoxModelObject>(*parent()).moveChildTo(&downcast<RenderBoxModelObject>(*previousSibling()), this);
2104
2105     if (auto fragment = renderNamedFlowFragment())
2106         fragment->setStyle(RenderNamedFlowFragment::createStyle(style()));
2107
2108     if (diff >= StyleDifferenceRepaint) {
2109         // FIXME: This could use a cheaper style-only test instead of SimpleLineLayout::canUseFor.
2110         if (selfNeedsLayout() || !m_simpleLineLayout || !SimpleLineLayout::canUseFor(*this))
2111             invalidateLineLayoutPath();
2112     }
2113
2114     if (multiColumnFlowThread())
2115         updateStylesForColumnChildren();
2116 }
2117
2118 void RenderBlockFlow::updateStylesForColumnChildren()
2119 {
2120     for (auto* child = firstChildBox(); child && (child->isInFlowRenderFlowThread() || child->isRenderMultiColumnSet()); child = child->nextSiblingBox())
2121         child->setStyle(RenderStyle::createAnonymousStyleWithDisplay(style(), BLOCK));
2122 }
2123
2124 void RenderBlockFlow::styleWillChange(StyleDifference diff, const RenderStyle& newStyle)
2125 {
2126     const RenderStyle* oldStyle = hasInitializedStyle() ? &style() : nullptr;
2127     s_canPropagateFloatIntoSibling = oldStyle ? !isFloatingOrOutOfFlowPositioned() && !avoidsFloats() : false;
2128
2129     if (oldStyle) {
2130         EPosition oldPosition = oldStyle->position();
2131         EPosition newPosition = newStyle.position();
2132
2133         if (parent() && diff == StyleDifferenceLayout && oldPosition != newPosition) {
2134             if (containsFloats() && !isFloating() && !isOutOfFlowPositioned() && newStyle.hasOutOfFlowPosition())
2135                 markAllDescendantsWithFloatsForLayout();
2136         }
2137     }
2138
2139     RenderBlock::styleWillChange(diff, newStyle);
2140 }
2141
2142 void RenderBlockFlow::deleteLines()
2143 {
2144     if (containsFloats())
2145         m_floatingObjects->clearLineBoxTreePointers();
2146
2147     if (m_simpleLineLayout) {
2148         ASSERT(!m_lineBoxes.firstLineBox());
2149         m_simpleLineLayout = nullptr;
2150     } else
2151         m_lineBoxes.deleteLineBoxTree();
2152
2153     RenderBlock::deleteLines();
2154 }
2155
2156 void RenderBlockFlow::addFloatsToNewParent(RenderBlockFlow& toBlockFlow) const
2157 {
2158     // When a portion of the render tree is being detached, anonymous blocks
2159     // will be combined as their children are deleted. In this process, the
2160     // anonymous block later in the tree is merged into the one preceeding it.
2161     // It can happen that the later block (this) contains floats that the
2162     // previous block (toBlockFlow) did not contain, and thus are not in the
2163     // floating objects list for toBlockFlow. This can result in toBlockFlow
2164     // containing floats that are not in it's floating objects list, but are in
2165     // the floating objects lists of siblings and parents. This can cause
2166     // problems when the float itself is deleted, since the deletion code
2167     // assumes that if a float is not in it's containing block's floating
2168     // objects list, it isn't in any floating objects list. In order to
2169     // preserve this condition (removing it has serious performance
2170     // implications), we need to copy the floating objects from the old block
2171     // (this) to the new block (toBlockFlow). The float's metrics will likely
2172     // all be wrong, but since toBlockFlow is already marked for layout, this
2173     // will get fixed before anything gets displayed.
2174     // See bug https://bugs.webkit.org/show_bug.cgi?id=115566
2175     if (!m_floatingObjects)
2176         return;
2177
2178     if (!toBlockFlow.m_floatingObjects)
2179         toBlockFlow.createFloatingObjects();
2180
2181     for (auto& floatingObject : m_floatingObjects->set()) {
2182         if (toBlockFlow.containsFloat(floatingObject->renderer()))
2183             continue;
2184         toBlockFlow.m_floatingObjects->add(floatingObject->cloneForNewParent());
2185     }
2186 }
2187
2188 void RenderBlockFlow::moveAllChildrenIncludingFloatsTo(RenderBlock& toBlock, bool fullRemoveInsert)
2189 {
2190     auto& toBlockFlow = downcast<RenderBlockFlow>(toBlock);
2191     moveAllChildrenTo(&toBlockFlow, fullRemoveInsert);
2192     addFloatsToNewParent(toBlockFlow);
2193 }
2194
2195 void RenderBlockFlow::addOverflowFromFloats()
2196 {
2197     if (!m_floatingObjects)
2198         return;
2199
2200     const FloatingObjectSet& floatingObjectSet = m_floatingObjects->set();
2201     auto end = floatingObjectSet.end();
2202     for (auto it = floatingObjectSet.begin(); it != end; ++it) {
2203         const auto& floatingObject = *it->get();
2204         if (floatingObject.isDescendant())
2205             addOverflowFromChild(&floatingObject.renderer(), floatingObject.locationOffsetOfBorderBox());
2206     }
2207 }
2208
2209 void RenderBlockFlow::computeOverflow(LayoutUnit oldClientAfterEdge, bool recomputeFloats)
2210 {
2211     RenderBlock::computeOverflow(oldClientAfterEdge, recomputeFloats);
2212
2213     if (!multiColumnFlowThread() && (recomputeFloats || createsNewFormattingContext() || hasSelfPaintingLayer()))
2214         addOverflowFromFloats();
2215 }
2216
2217 void RenderBlockFlow::repaintOverhangingFloats(bool paintAllDescendants)
2218 {
2219     // Repaint any overhanging floats (if we know we're the one to paint them).
2220     // Otherwise, bail out.
2221     if (!hasOverhangingFloats())
2222         return;
2223
2224     // FIXME: Avoid disabling LayoutState. At the very least, don't disable it for floats originating
2225     // in this block. Better yet would be to push extra state for the containers of other floats.
2226     LayoutStateDisabler layoutStateDisabler(view());
2227     const FloatingObjectSet& floatingObjectSet = m_floatingObjects->set();
2228     auto end = floatingObjectSet.end();
2229     for (auto it = floatingObjectSet.begin(); it != end; ++it) {
2230         const auto& floatingObject = *it->get();
2231         // Only repaint the object if it is overhanging, is not in its own layer, and
2232         // is our responsibility to paint (m_shouldPaint is set). When paintAllDescendants is true, the latter
2233         // condition is replaced with being a descendant of us.
2234         auto& renderer = floatingObject.renderer();
2235         if (logicalBottomForFloat(floatingObject) > logicalHeight()
2236             && !renderer.hasSelfPaintingLayer()
2237             && (floatingObject.shouldPaint() || (paintAllDescendants && renderer.isDescendantOf(this)))) {
2238             renderer.repaint();
2239             renderer.repaintOverhangingFloats(false);
2240         }
2241     }
2242 }
2243
2244 void RenderBlockFlow::paintColumnRules(PaintInfo& paintInfo, const LayoutPoint& point)
2245 {
2246     RenderBlock::paintColumnRules(paintInfo, point);
2247     
2248     if (!multiColumnFlowThread() || paintInfo.context().paintingDisabled())
2249         return;
2250
2251     // Iterate over our children and paint the column rules as needed.
2252     for (auto& columnSet : childrenOfType<RenderMultiColumnSet>(*this)) {
2253         LayoutPoint childPoint = columnSet.location() + flipForWritingModeForChild(&columnSet, point);
2254         columnSet.paintColumnRules(paintInfo, childPoint);
2255     }
2256 }
2257
2258 void RenderBlockFlow::paintFloats(PaintInfo& paintInfo, const LayoutPoint& paintOffset, bool preservePhase)
2259 {
2260     if (!m_floatingObjects)
2261         return;
2262
2263     const FloatingObjectSet& floatingObjectSet = m_floatingObjects->set();
2264     auto end = floatingObjectSet.end();
2265     for (auto it = floatingObjectSet.begin(); it != end; ++it) {
2266         const auto& floatingObject = *it->get();
2267         auto& renderer = floatingObject.renderer();
2268         // Only paint the object if our m_shouldPaint flag is set.
2269         if (floatingObject.shouldPaint() && !renderer.hasSelfPaintingLayer()) {
2270             PaintInfo currentPaintInfo(paintInfo);
2271             currentPaintInfo.phase = preservePhase ? paintInfo.phase : PaintPhaseBlockBackground;
2272             LayoutPoint childPoint = flipFloatForWritingModeForChild(floatingObject, paintOffset + floatingObject.translationOffsetToAncestor());
2273             renderer.paint(currentPaintInfo, childPoint);
2274             if (!preservePhase) {
2275                 currentPaintInfo.phase = PaintPhaseChildBlockBackgrounds;
2276                 renderer.paint(currentPaintInfo, childPoint);
2277                 currentPaintInfo.phase = PaintPhaseFloat;
2278                 renderer.paint(currentPaintInfo, childPoint);
2279                 currentPaintInfo.phase = PaintPhaseForeground;
2280                 renderer.paint(currentPaintInfo, childPoint);
2281                 currentPaintInfo.phase = PaintPhaseOutline;
2282                 renderer.paint(currentPaintInfo, childPoint);
2283             }
2284         }
2285     }
2286 }
2287
2288 void RenderBlockFlow::clipOutFloatingObjects(RenderBlock& rootBlock, const PaintInfo* paintInfo, const LayoutPoint& rootBlockPhysicalPosition, const LayoutSize& offsetFromRootBlock)
2289 {
2290     if (m_floatingObjects) {
2291         const FloatingObjectSet& floatingObjectSet = m_floatingObjects->set();
2292         auto end = floatingObjectSet.end();
2293         for (auto it = floatingObjectSet.begin(); it != end; ++it) {
2294             const auto& floatingObject = *it->get();
2295             LayoutRect floatBox(offsetFromRootBlock.width(), offsetFromRootBlock.height(), floatingObject.renderer().width(), floatingObject.renderer().height());
2296             floatBox.move(floatingObject.locationOffsetOfBorderBox());
2297             rootBlock.flipForWritingMode(floatBox);
2298             floatBox.move(rootBlockPhysicalPosition.x(), rootBlockPhysicalPosition.y());
2299             paintInfo->context().clipOut(snappedIntRect(floatBox));
2300         }
2301     }
2302 }
2303
2304 void RenderBlockFlow::createFloatingObjects()
2305 {
2306     m_floatingObjects = std::make_unique<FloatingObjects>(*this);
2307 }
2308
2309 void RenderBlockFlow::removeFloatingObjects()
2310 {
2311     if (!m_floatingObjects)
2312         return;
2313
2314     markSiblingsWithFloatsForLayout();
2315
2316     m_floatingObjects->clear();
2317 }
2318
2319 FloatingObject* RenderBlockFlow::insertFloatingObject(RenderBox& floatBox)
2320 {
2321     ASSERT(floatBox.isFloating());
2322
2323     // Create the list of special objects if we don't aleady have one
2324     if (!m_floatingObjects)
2325         createFloatingObjects();
2326     else {
2327         // Don't insert the floatingObject again if it's already in the list
2328         const FloatingObjectSet& floatingObjectSet = m_floatingObjects->set();
2329         auto it = floatingObjectSet.find<RenderBox&, FloatingObjectHashTranslator>(floatBox);
2330         if (it != floatingObjectSet.end())
2331             return it->get();
2332     }
2333
2334     // Create the special floatingObject entry & append it to the list
2335
2336     std::unique_ptr<FloatingObject> floatingObject = FloatingObject::create(floatBox);
2337     
2338     // Our location is irrelevant if we're unsplittable or no pagination is in effect. Just lay out the float.
2339     bool isChildRenderBlock = floatBox.isRenderBlock();
2340     if (isChildRenderBlock && !floatBox.needsLayout() && view().layoutState()->pageLogicalHeightChanged())
2341         floatBox.setChildNeedsLayout(MarkOnlyThis);
2342             
2343     bool needsBlockDirectionLocationSetBeforeLayout = isChildRenderBlock && view().layoutState()->needsBlockDirectionLocationSetBeforeLayout();
2344     if (!needsBlockDirectionLocationSetBeforeLayout || isWritingModeRoot()) {
2345         // We are unsplittable if we're a block flow root.
2346         floatBox.layoutIfNeeded();
2347         floatingObject->setShouldPaint(!floatBox.hasSelfPaintingLayer());
2348     }
2349     else {
2350         floatBox.updateLogicalWidth();
2351         floatBox.computeAndSetBlockDirectionMargins(*this);
2352     }
2353
2354     setLogicalWidthForFloat(*floatingObject, logicalWidthForChild(floatBox) + marginStartForChild(floatBox) + marginEndForChild(floatBox));
2355
2356     return m_floatingObjects->add(WTFMove(floatingObject));
2357 }
2358
2359 void RenderBlockFlow::removeFloatingObject(RenderBox& floatBox)
2360 {
2361     if (m_floatingObjects) {
2362         const FloatingObjectSet& floatingObjectSet = m_floatingObjects->set();
2363         auto it = floatingObjectSet.find<RenderBox&, FloatingObjectHashTranslator>(floatBox);
2364         if (it != floatingObjectSet.end()) {
2365             auto& floatingObject = *it->get();
2366             if (childrenInline()) {
2367                 LayoutUnit logicalTop = logicalTopForFloat(floatingObject);
2368                 LayoutUnit logicalBottom = logicalBottomForFloat(floatingObject);
2369
2370                 // Fix for https://bugs.webkit.org/show_bug.cgi?id=54995.
2371                 if (logicalBottom < 0 || logicalBottom < logicalTop || logicalTop == LayoutUnit::max())
2372                     logicalBottom = LayoutUnit::max();
2373                 else {
2374                     // Special-case zero- and less-than-zero-height floats: those don't touch
2375                     // the line that they're on, but it still needs to be dirtied. This is
2376                     // accomplished by pretending they have a height of 1.
2377                     logicalBottom = std::max(logicalBottom, logicalTop + 1);
2378                 }
2379                 if (floatingObject.originatingLine()) {
2380                     floatingObject.originatingLine()->removeFloat(floatBox);
2381                     if (!selfNeedsLayout()) {
2382                         ASSERT(&floatingObject.originatingLine()->renderer() == this);
2383                         floatingObject.originatingLine()->markDirty();
2384                     }
2385 #if !ASSERT_DISABLED
2386                     floatingObject.setOriginatingLine(0);
2387 #endif
2388                 }
2389                 markLinesDirtyInBlockRange(0, logicalBottom);
2390             }
2391             m_floatingObjects->remove(&floatingObject);
2392         }
2393     }
2394 }
2395
2396 void RenderBlockFlow::removeFloatingObjectsBelow(FloatingObject* lastFloat, int logicalOffset)
2397 {
2398     if (!containsFloats())
2399         return;
2400     
2401     const FloatingObjectSet& floatingObjectSet = m_floatingObjects->set();
2402     FloatingObject* curr = floatingObjectSet.last().get();
2403     while (curr != lastFloat && (!curr->isPlaced() || logicalTopForFloat(*curr) >= logicalOffset)) {
2404         m_floatingObjects->remove(curr);
2405         if (floatingObjectSet.isEmpty())
2406             break;
2407         curr = floatingObjectSet.last().get();
2408     }
2409 }
2410
2411 LayoutUnit RenderBlockFlow::logicalLeftOffsetForPositioningFloat(LayoutUnit logicalTop, LayoutUnit fixedOffset, bool applyTextIndent, LayoutUnit* heightRemaining) const
2412 {
2413     LayoutUnit offset = fixedOffset;
2414     if (m_floatingObjects && m_floatingObjects->hasLeftObjects())
2415         offset = m_floatingObjects->logicalLeftOffsetForPositioningFloat(fixedOffset, logicalTop, heightRemaining);
2416     return adjustLogicalLeftOffsetForLine(offset, applyTextIndent);
2417 }
2418
2419 LayoutUnit RenderBlockFlow::logicalRightOffsetForPositioningFloat(LayoutUnit logicalTop, LayoutUnit fixedOffset, bool applyTextIndent, LayoutUnit* heightRemaining) const
2420 {
2421     LayoutUnit offset = fixedOffset;
2422     if (m_floatingObjects && m_floatingObjects->hasRightObjects())
2423         offset = m_floatingObjects->logicalRightOffsetForPositioningFloat(fixedOffset, logicalTop, heightRemaining);
2424     return adjustLogicalRightOffsetForLine(offset, applyTextIndent);
2425 }
2426
2427 void RenderBlockFlow::computeLogicalLocationForFloat(FloatingObject& floatingObject, LayoutUnit& logicalTopOffset)
2428 {
2429     auto& childBox = floatingObject.renderer();
2430     LayoutUnit logicalLeftOffset = logicalLeftOffsetForContent(logicalTopOffset); // Constant part of left offset.
2431     LayoutUnit logicalRightOffset = logicalRightOffsetForContent(logicalTopOffset); // Constant part of right offset.
2432
2433     LayoutUnit floatLogicalWidth = std::min(logicalWidthForFloat(floatingObject), logicalRightOffset - logicalLeftOffset); // The width we look for.
2434
2435     LayoutUnit floatLogicalLeft;
2436
2437     bool insideFlowThread = flowThreadContainingBlock();
2438     bool isInitialLetter = childBox.style().styleType() == FIRST_LETTER && childBox.style().initialLetterDrop() > 0;
2439     
2440     if (isInitialLetter) {
2441         int letterClearance = lowestInitialLetterLogicalBottom() - logicalTopOffset;
2442         if (letterClearance > 0) {
2443             logicalTopOffset += letterClearance;
2444             setLogicalHeight(logicalHeight() + letterClearance);
2445         }
2446     }
2447     
2448     if (childBox.style().floating() == LeftFloat) {
2449         LayoutUnit heightRemainingLeft = 1;
2450         LayoutUnit heightRemainingRight = 1;
2451         floatLogicalLeft = logicalLeftOffsetForPositioningFloat(logicalTopOffset, logicalLeftOffset, false, &heightRemainingLeft);
2452         while (logicalRightOffsetForPositioningFloat(logicalTopOffset, logicalRightOffset, false, &heightRemainingRight) - floatLogicalLeft < floatLogicalWidth) {
2453             logicalTopOffset += std::min(heightRemainingLeft, heightRemainingRight);
2454             floatLogicalLeft = logicalLeftOffsetForPositioningFloat(logicalTopOffset, logicalLeftOffset, false, &heightRemainingLeft);
2455             if (insideFlowThread) {
2456                 // Have to re-evaluate all of our offsets, since they may have changed.
2457                 logicalRightOffset = logicalRightOffsetForContent(logicalTopOffset); // Constant part of right offset.
2458                 logicalLeftOffset = logicalLeftOffsetForContent(logicalTopOffset); // Constant part of left offset.
2459                 floatLogicalWidth = std::min(logicalWidthForFloat(floatingObject), logicalRightOffset - logicalLeftOffset);
2460             }
2461         }
2462         floatLogicalLeft = std::max(logicalLeftOffset - borderAndPaddingLogicalLeft(), floatLogicalLeft);
2463     } else {
2464         LayoutUnit heightRemainingLeft = 1;
2465         LayoutUnit heightRemainingRight = 1;
2466         floatLogicalLeft = logicalRightOffsetForPositioningFloat(logicalTopOffset, logicalRightOffset, false, &heightRemainingRight);
2467         while (floatLogicalLeft - logicalLeftOffsetForPositioningFloat(logicalTopOffset, logicalLeftOffset, false, &heightRemainingLeft) < floatLogicalWidth) {
2468             logicalTopOffset += std::min(heightRemainingLeft, heightRemainingRight);
2469             floatLogicalLeft = logicalRightOffsetForPositioningFloat(logicalTopOffset, logicalRightOffset, false, &heightRemainingRight);
2470             if (insideFlowThread) {
2471                 // Have to re-evaluate all of our offsets, since they may have changed.
2472                 logicalRightOffset = logicalRightOffsetForContent(logicalTopOffset); // Constant part of right offset.
2473                 logicalLeftOffset = logicalLeftOffsetForContent(logicalTopOffset); // Constant part of left offset.
2474                 floatLogicalWidth = std::min(logicalWidthForFloat(floatingObject), logicalRightOffset - logicalLeftOffset);
2475             }
2476         }
2477         // Use the original width of the float here, since the local variable
2478         // |floatLogicalWidth| was capped to the available line width. See
2479         // fast/block/float/clamped-right-float.html.
2480         floatLogicalLeft -= logicalWidthForFloat(floatingObject);
2481     }
2482     
2483     LayoutUnit childLogicalLeftMargin = style().isLeftToRightDirection() ? marginStartForChild(childBox) : marginEndForChild(childBox);
2484     LayoutUnit childBeforeMargin = marginBeforeForChild(childBox);
2485     
2486     if (isInitialLetter)
2487         adjustInitialLetterPosition(childBox, logicalTopOffset, childBeforeMargin);
2488     
2489     setLogicalLeftForFloat(floatingObject, floatLogicalLeft);
2490     setLogicalLeftForChild(childBox, floatLogicalLeft + childLogicalLeftMargin);
2491     
2492     setLogicalTopForFloat(floatingObject, logicalTopOffset);
2493     setLogicalTopForChild(childBox, logicalTopOffset + childBeforeMargin);
2494     
2495     setLogicalMarginsForFloat(floatingObject, childLogicalLeftMargin, childBeforeMargin);
2496 }
2497
2498 void RenderBlockFlow::adjustInitialLetterPosition(RenderBox& childBox, LayoutUnit& logicalTopOffset, LayoutUnit& marginBeforeOffset)
2499 {
2500     const RenderStyle& style = firstLineStyle();
2501     const FontMetrics& fontMetrics = style.fontMetrics();
2502     if (!fontMetrics.hasCapHeight())
2503         return;
2504
2505     LayoutUnit heightOfLine = lineHeight(true, isHorizontalWritingMode() ? HorizontalLine : VerticalLine, PositionOfInteriorLineBoxes);
2506     LayoutUnit beforeMarginBorderPadding = childBox.borderAndPaddingBefore() + childBox.marginBefore();
2507     
2508     // Make an adjustment to align with the cap height of a theoretical block line.
2509     LayoutUnit adjustment = fontMetrics.ascent() + (heightOfLine - fontMetrics.height()) / 2 - fontMetrics.capHeight() - beforeMarginBorderPadding;
2510     logicalTopOffset += adjustment;
2511
2512     // For sunken and raised caps, we have to make some adjustments. Test if we're sunken or raised (dropHeightDelta will be
2513     // positive for raised and negative for sunken).
2514     int dropHeightDelta = childBox.style().initialLetterHeight() - childBox.style().initialLetterDrop();
2515     
2516     // If we're sunken, the float needs to shift down but lines still need to avoid it. In order to do that we increase the float's margin.
2517     if (dropHeightDelta < 0)
2518         marginBeforeOffset += -dropHeightDelta * heightOfLine;
2519     
2520     // If we're raised, then we actually have to grow the height of the block, since the lines have to be pushed down as though we're placing
2521     // empty lines beside the first letter.
2522     if (dropHeightDelta > 0)
2523         setLogicalHeight(logicalHeight() + dropHeightDelta * heightOfLine);
2524 }
2525
2526 bool RenderBlockFlow::positionNewFloats()
2527 {
2528     if (!m_floatingObjects)
2529         return false;
2530
2531     const FloatingObjectSet& floatingObjectSet = m_floatingObjects->set();
2532     if (floatingObjectSet.isEmpty())
2533         return false;
2534
2535     // If all floats have already been positioned, then we have no work to do.
2536     if (floatingObjectSet.last()->isPlaced())
2537         return false;
2538
2539     // Move backwards through our floating object list until we find a float that has
2540     // already been positioned. Then we'll be able to move forward, positioning all of
2541     // the new floats that need it.
2542     auto it = floatingObjectSet.end();
2543     --it; // Go to last item.
2544     auto begin = floatingObjectSet.begin();
2545     FloatingObject* lastPlacedFloatingObject = 0;
2546     while (it != begin) {
2547         --it;
2548         if ((*it)->isPlaced()) {
2549             lastPlacedFloatingObject = it->get();
2550             ++it;
2551             break;
2552         }
2553     }
2554
2555     LayoutUnit logicalTop = logicalHeight();
2556     
2557     // The float cannot start above the top position of the last positioned float.
2558     if (lastPlacedFloatingObject)
2559         logicalTop = std::max(logicalTopForFloat(*lastPlacedFloatingObject), logicalTop);
2560
2561     auto end = floatingObjectSet.end();
2562     // Now walk through the set of unpositioned floats and place them.
2563     for (; it != end; ++it) {
2564         auto& floatingObject = *it->get();
2565         // The containing block is responsible for positioning floats, so if we have floats in our
2566         // list that come from somewhere else, do not attempt to position them.
2567         auto& childBox = floatingObject.renderer();
2568         if (childBox.containingBlock() != this)
2569             continue;
2570
2571         LayoutRect oldRect = childBox.frameRect();
2572
2573         if (childBox.style().clear() & CLEFT)
2574             logicalTop = std::max(lowestFloatLogicalBottom(FloatingObject::FloatLeft), logicalTop);
2575         if (childBox.style().clear() & CRIGHT)
2576             logicalTop = std::max(lowestFloatLogicalBottom(FloatingObject::FloatRight), logicalTop);
2577
2578         computeLogicalLocationForFloat(floatingObject, logicalTop);
2579         LayoutUnit childLogicalTop = logicalTopForChild(childBox);
2580
2581         estimateRegionRangeForBoxChild(childBox);
2582
2583         childBox.markForPaginationRelayoutIfNeeded();
2584         childBox.layoutIfNeeded();
2585
2586         LayoutState* layoutState = view().layoutState();
2587         bool isPaginated = layoutState->isPaginated();
2588         if (isPaginated) {
2589             // If we are unsplittable and don't fit, then we need to move down.
2590             // We include our margins as part of the unsplittable area.
2591             LayoutUnit newLogicalTop = adjustForUnsplittableChild(childBox, logicalTop, childLogicalTop - logicalTop, marginAfterForChild(childBox));
2592             
2593             // See if we have a pagination strut that is making us move down further.
2594             // Note that an unsplittable child can't also have a pagination strut, so this
2595             // is exclusive with the case above.
2596             RenderBlock* childBlock = is<RenderBlock>(childBox) ? &downcast<RenderBlock>(childBox) : nullptr;
2597             if (childBlock && childBlock->paginationStrut()) {
2598                 newLogicalTop += childBlock->paginationStrut();
2599                 childBlock->setPaginationStrut(0);
2600             }
2601             
2602             if (newLogicalTop != logicalTop) {
2603                 floatingObject.setPaginationStrut(newLogicalTop - logicalTop);
2604                 computeLogicalLocationForFloat(floatingObject, newLogicalTop);
2605                 if (childBlock)
2606                     childBlock->setChildNeedsLayout(MarkOnlyThis);
2607                 childBox.layoutIfNeeded();
2608                 logicalTop = newLogicalTop;
2609             }
2610
2611             if (updateRegionRangeForBoxChild(childBox)) {
2612                 childBox.setNeedsLayout(MarkOnlyThis);
2613                 childBox.layoutIfNeeded();
2614             }
2615         }
2616
2617         setLogicalHeightForFloat(floatingObject, logicalHeightForChildForFragmentation(childBox) + (logicalTopForChild(childBox) - logicalTop) + marginAfterForChild(childBox));
2618
2619         m_floatingObjects->addPlacedObject(&floatingObject);
2620
2621         if (ShapeOutsideInfo* shapeOutside = childBox.shapeOutsideInfo())
2622             shapeOutside->setReferenceBoxLogicalSize(logicalSizeForChild(childBox));
2623         // If the child moved, we have to repaint it.
2624         if (childBox.checkForRepaintDuringLayout())
2625             childBox.repaintDuringLayoutIfMoved(oldRect);
2626     }
2627     return true;
2628 }
2629
2630 void RenderBlockFlow::clearFloats(EClear clear)
2631 {
2632     positionNewFloats();
2633     // set y position
2634     LayoutUnit newY = 0;
2635     switch (clear) {
2636     case CLEFT:
2637         newY = lowestFloatLogicalBottom(FloatingObject::FloatLeft);
2638         break;
2639     case CRIGHT:
2640         newY = lowestFloatLogicalBottom(FloatingObject::FloatRight);
2641         break;
2642     case CBOTH:
2643         newY = lowestFloatLogicalBottom();
2644         break;
2645     default:
2646         break;
2647     }
2648     if (height() < newY)
2649         setLogicalHeight(newY);
2650 }
2651
2652 LayoutUnit RenderBlockFlow::logicalLeftFloatOffsetForLine(LayoutUnit logicalTop, LayoutUnit fixedOffset, LayoutUnit logicalHeight) const
2653 {
2654     if (m_floatingObjects && m_floatingObjects->hasLeftObjects())
2655         return m_floatingObjects->logicalLeftOffset(fixedOffset, logicalTop, logicalHeight);
2656
2657     return fixedOffset;
2658 }
2659
2660 LayoutUnit RenderBlockFlow::logicalRightFloatOffsetForLine(LayoutUnit logicalTop, LayoutUnit fixedOffset, LayoutUnit logicalHeight) const
2661 {
2662     if (m_floatingObjects && m_floatingObjects->hasRightObjects())
2663         return m_floatingObjects->logicalRightOffset(fixedOffset, logicalTop, logicalHeight);
2664
2665     return fixedOffset;
2666 }
2667
2668 LayoutUnit RenderBlockFlow::nextFloatLogicalBottomBelow(LayoutUnit logicalHeight) const
2669 {
2670     if (!m_floatingObjects)
2671         return logicalHeight;
2672
2673     return m_floatingObjects->findNextFloatLogicalBottomBelow(logicalHeight);
2674 }
2675
2676 LayoutUnit RenderBlockFlow::nextFloatLogicalBottomBelowForBlock(LayoutUnit logicalHeight) const
2677 {
2678     if (!m_floatingObjects)
2679         return logicalHeight;
2680
2681     return m_floatingObjects->findNextFloatLogicalBottomBelowForBlock(logicalHeight);
2682 }
2683
2684 LayoutUnit RenderBlockFlow::lowestFloatLogicalBottom(FloatingObject::Type floatType) const
2685 {
2686     if (!m_floatingObjects)
2687         return 0;
2688     LayoutUnit lowestFloatBottom = 0;
2689     const FloatingObjectSet& floatingObjectSet = m_floatingObjects->set();
2690     auto end = floatingObjectSet.end();
2691     for (auto it = floatingObjectSet.begin(); it != end; ++it) {
2692         const auto& floatingObject = *it->get();
2693         if (floatingObject.isPlaced() && floatingObject.type() & floatType)
2694             lowestFloatBottom = std::max(lowestFloatBottom, logicalBottomForFloat(floatingObject));
2695     }
2696     return lowestFloatBottom;
2697 }
2698
2699 LayoutUnit RenderBlockFlow::lowestInitialLetterLogicalBottom() const
2700 {
2701     if (!m_floatingObjects)
2702         return 0;
2703     LayoutUnit lowestFloatBottom = 0;
2704     const FloatingObjectSet& floatingObjectSet = m_floatingObjects->set();
2705     auto end = floatingObjectSet.end();
2706     for (auto it = floatingObjectSet.begin(); it != end; ++it) {
2707         const auto& floatingObject = *it->get();
2708         if (floatingObject.isPlaced() && floatingObject.renderer().style().styleType() == FIRST_LETTER && floatingObject.renderer().style().initialLetterDrop() > 0)
2709             lowestFloatBottom = std::max(lowestFloatBottom, logicalBottomForFloat(floatingObject));
2710     }
2711     return lowestFloatBottom;
2712 }
2713
2714 LayoutUnit RenderBlockFlow::addOverhangingFloats(RenderBlockFlow& child, bool makeChildPaintOtherFloats)
2715 {
2716     // Prevent floats from being added to the canvas by the root element, e.g., <html>.
2717     if (!child.containsFloats() || child.createsNewFormattingContext())
2718         return 0;
2719
2720     LayoutUnit childLogicalTop = child.logicalTop();
2721     LayoutUnit childLogicalLeft = child.logicalLeft();
2722     LayoutUnit lowestFloatLogicalBottom = 0;
2723
2724     // Floats that will remain the child's responsibility to paint should factor into its
2725     // overflow.
2726     auto childEnd = child.m_floatingObjects->set().end();
2727     for (auto childIt = child.m_floatingObjects->set().begin(); childIt != childEnd; ++childIt) {
2728         auto& floatingObject = *childIt->get();
2729         LayoutUnit floatLogicalBottom = std::min(logicalBottomForFloat(floatingObject), LayoutUnit::max() - childLogicalTop);
2730         LayoutUnit logicalBottom = childLogicalTop + floatLogicalBottom;
2731         lowestFloatLogicalBottom = std::max(lowestFloatLogicalBottom, logicalBottom);
2732
2733         if (logicalBottom > logicalHeight()) {
2734             // If the object is not in the list, we add it now.
2735             if (!containsFloat(floatingObject.renderer())) {
2736                 LayoutSize offset = isHorizontalWritingMode() ? LayoutSize(-childLogicalLeft, -childLogicalTop) : LayoutSize(-childLogicalTop, -childLogicalLeft);
2737                 bool shouldPaint = false;
2738
2739                 // The nearest enclosing layer always paints the float (so that zindex and stacking
2740                 // behaves properly). We always want to propagate the desire to paint the float as
2741                 // far out as we can, to the outermost block that overlaps the float, stopping only
2742                 // if we hit a self-painting layer boundary.
2743                 if (floatingObject.renderer().enclosingFloatPaintingLayer() == enclosingFloatPaintingLayer()) {
2744                     floatingObject.setShouldPaint(false);
2745                     shouldPaint = true;
2746                 }
2747                 // We create the floating object list lazily.
2748                 if (!m_floatingObjects)
2749                     createFloatingObjects();
2750
2751                 m_floatingObjects->add(floatingObject.copyToNewContainer(offset, shouldPaint, true));
2752             }
2753         } else {
2754             const auto& renderer = floatingObject.renderer();
2755             if (makeChildPaintOtherFloats && !floatingObject.shouldPaint() && !renderer.hasSelfPaintingLayer()
2756                 && renderer.isDescendantOf(&child) && renderer.enclosingFloatPaintingLayer() == child.enclosingFloatPaintingLayer()) {
2757                 // The float is not overhanging from this block, so if it is a descendant of the child, the child should
2758                 // paint it (the other case is that it is intruding into the child), unless it has its own layer or enclosing
2759                 // layer.
2760                 // If makeChildPaintOtherFloats is false, it means that the child must already know about all the floats
2761                 // it should paint.
2762                 floatingObject.setShouldPaint(true);
2763             }
2764             
2765             // Since the float doesn't overhang, it didn't get put into our list. We need to add its overflow in to the child now.
2766             if (floatingObject.isDescendant())
2767                 child.addOverflowFromChild(&renderer, floatingObject.locationOffsetOfBorderBox());
2768         }
2769     }
2770     return lowestFloatLogicalBottom;
2771 }
2772
2773 bool RenderBlockFlow::hasOverhangingFloat(RenderBox& renderer)
2774 {
2775     if (!m_floatingObjects || !parent())
2776         return false;
2777
2778     const FloatingObjectSet& floatingObjectSet = m_floatingObjects->set();
2779     const auto it = floatingObjectSet.find<RenderBox&, FloatingObjectHashTranslator>(renderer);
2780     if (it == floatingObjectSet.end())
2781         return false;
2782
2783     return logicalBottomForFloat(*it->get()) > logicalHeight();
2784 }
2785
2786 void RenderBlockFlow::addIntrudingFloats(RenderBlockFlow* prev, RenderBlockFlow* container, LayoutUnit logicalLeftOffset, LayoutUnit logicalTopOffset)
2787 {
2788     ASSERT(!avoidsFloats());
2789
2790     // If we create our own block formatting context then our contents don't interact with floats outside it, even those from our parent.
2791     if (createsNewFormattingContext())
2792         return;
2793
2794     // If the parent or previous sibling doesn't have any floats to add, don't bother.
2795     if (!prev->m_floatingObjects)
2796         return;
2797
2798     logicalLeftOffset += marginLogicalLeft();
2799
2800     const FloatingObjectSet& prevSet = prev->m_floatingObjects->set();
2801     auto prevEnd = prevSet.end();
2802     for (auto prevIt = prevSet.begin(); prevIt != prevEnd; ++prevIt) {
2803         auto& floatingObject = *prevIt->get();
2804         if (logicalBottomForFloat(floatingObject) > logicalTopOffset) {
2805             if (!m_floatingObjects || !m_floatingObjects->set().contains<FloatingObject&, FloatingObjectHashTranslator>(floatingObject)) {
2806                 // We create the floating object list lazily.
2807                 if (!m_floatingObjects)
2808                     createFloatingObjects();
2809
2810                 // Applying the child's margin makes no sense in the case where the child was passed in.
2811                 // since this margin was added already through the modification of the |logicalLeftOffset| variable
2812                 // above. |logicalLeftOffset| will equal the margin in this case, so it's already been taken
2813                 // into account. Only apply this code if prev is the parent, since otherwise the left margin
2814                 // will get applied twice.
2815                 LayoutSize offset = isHorizontalWritingMode()
2816                     ? LayoutSize(logicalLeftOffset - (prev != container ? prev->marginLeft() : LayoutUnit()), logicalTopOffset)
2817                     : LayoutSize(logicalTopOffset, logicalLeftOffset - (prev != container ? prev->marginTop() : LayoutUnit()));
2818
2819                 m_floatingObjects->add(floatingObject.copyToNewContainer(offset));
2820             }
2821         }
2822     }
2823 }
2824
2825 void RenderBlockFlow::markAllDescendantsWithFloatsForLayout(RenderBox* floatToRemove, bool inLayout)
2826 {
2827     if (!everHadLayout() && !containsFloats())
2828         return;
2829
2830     MarkingBehavior markParents = inLayout ? MarkOnlyThis : MarkContainingBlockChain;
2831     setChildNeedsLayout(markParents);
2832
2833     if (floatToRemove)
2834         removeFloatingObject(*floatToRemove);
2835     else if (childrenInline())
2836         return;
2837
2838     // Iterate over our block children and mark them as needed.
2839     for (auto& block : childrenOfType<RenderBlock>(*this)) {
2840         if (!floatToRemove && block.isFloatingOrOutOfFlowPositioned())
2841             continue;
2842         if (!is<RenderBlockFlow>(block)) {
2843             if (block.shrinkToAvoidFloats() && block.everHadLayout())
2844                 block.setChildNeedsLayout(markParents);
2845             continue;
2846         }
2847         auto& blockFlow = downcast<RenderBlockFlow>(block);
2848         if ((floatToRemove ? blockFlow.containsFloat(*floatToRemove) : blockFlow.containsFloats()) || blockFlow.shrinkToAvoidFloats())
2849             blockFlow.markAllDescendantsWithFloatsForLayout(floatToRemove, inLayout);
2850     }
2851 }
2852
2853 void RenderBlockFlow::markSiblingsWithFloatsForLayout(RenderBox* floatToRemove)
2854 {
2855     if (!m_floatingObjects)
2856         return;
2857
2858     const FloatingObjectSet& floatingObjectSet = m_floatingObjects->set();
2859     auto end = floatingObjectSet.end();
2860
2861     for (RenderObject* next = nextSibling(); next; next = next->nextSibling()) {
2862         if (!is<RenderBlockFlow>(*next) || next->isFloatingOrOutOfFlowPositioned())
2863             continue;
2864
2865         RenderBlockFlow& nextBlock = downcast<RenderBlockFlow>(*next);
2866         for (auto it = floatingObjectSet.begin(); it != end; ++it) {
2867             RenderBox& floatingBox = (*it)->renderer();
2868             if (floatToRemove && &floatingBox != floatToRemove)
2869                 continue;
2870             if (nextBlock.containsFloat(floatingBox))
2871                 nextBlock.markAllDescendantsWithFloatsForLayout(&floatingBox);
2872         }
2873     }
2874 }
2875
2876 LayoutPoint RenderBlockFlow::flipFloatForWritingModeForChild(const FloatingObject& child, const LayoutPoint& point) const
2877 {
2878     if (!style().isFlippedBlocksWritingMode())
2879         return point;
2880     
2881     // This is similar to RenderBox::flipForWritingModeForChild. We have to subtract out our left/top offsets twice, since
2882     // it's going to get added back in. We hide this complication here so that the calling code looks normal for the unflipped
2883     // case.
2884     if (isHorizontalWritingMode())
2885         return LayoutPoint(point.x(), point.y() + height() - child.renderer().height() - 2 * child.locationOffsetOfBorderBox().height());
2886     return LayoutPoint(point.x() + width() - child.renderer().width() - 2 * child.locationOffsetOfBorderBox().width(), point.y());
2887 }
2888
2889 LayoutUnit RenderBlockFlow::getClearDelta(RenderBox& child, LayoutUnit logicalTop)
2890 {
2891     // There is no need to compute clearance if we have no floats.
2892     if (!containsFloats())
2893         return 0;
2894     
2895     // At least one float is present. We need to perform the clearance computation.
2896     bool clearSet = child.style().clear() != CNONE;
2897     LayoutUnit logicalBottom = 0;
2898     switch (child.style().clear()) {
2899     case CNONE:
2900         break;
2901     case CLEFT:
2902         logicalBottom = lowestFloatLogicalBottom(FloatingObject::FloatLeft);
2903         break;
2904     case CRIGHT:
2905         logicalBottom = lowestFloatLogicalBottom(FloatingObject::FloatRight);
2906         break;
2907     case CBOTH:
2908         logicalBottom = lowestFloatLogicalBottom();
2909         break;
2910     }
2911
2912     // We also clear floats if we are too big to sit on the same line as a float (and wish to avoid floats by default).
2913     LayoutUnit result = clearSet ? std::max<LayoutUnit>(0, logicalBottom - logicalTop) : LayoutUnit();
2914     if (!result && child.avoidsFloats()) {
2915         LayoutUnit newLogicalTop = logicalTop;
2916         while (true) {
2917             LayoutUnit availableLogicalWidthAtNewLogicalTopOffset = availableLogicalWidthForLine(newLogicalTop, DoNotIndentText, logicalHeightForChild(child));
2918             if (availableLogicalWidthAtNewLogicalTopOffset == availableLogicalWidthForContent(newLogicalTop))
2919                 return newLogicalTop - logicalTop;
2920
2921             RenderRegion* region = regionAtBlockOffset(logicalTopForChild(child));
2922             LayoutRect borderBox = child.borderBoxRectInRegion(region, DoNotCacheRenderBoxRegionInfo);
2923             LayoutUnit childLogicalWidthAtOldLogicalTopOffset = isHorizontalWritingMode() ? borderBox.width() : borderBox.height();
2924
2925             // FIXME: None of this is right for perpendicular writing-mode children.
2926             LayoutUnit childOldLogicalWidth = child.logicalWidth();
2927             LayoutUnit childOldMarginLeft = child.marginLeft();
2928             LayoutUnit childOldMarginRight = child.marginRight();
2929             LayoutUnit childOldLogicalTop = child.logicalTop();
2930
2931             child.setLogicalTop(newLogicalTop);
2932             child.updateLogicalWidth();
2933             region = regionAtBlockOffset(logicalTopForChild(child));
2934             borderBox = child.borderBoxRectInRegion(region, DoNotCacheRenderBoxRegionInfo);
2935             LayoutUnit childLogicalWidthAtNewLogicalTopOffset = isHorizontalWritingMode() ? borderBox.width() : borderBox.height();
2936
2937             child.setLogicalTop(childOldLogicalTop);
2938             child.setLogicalWidth(childOldLogicalWidth);
2939             child.setMarginLeft(childOldMarginLeft);
2940             child.setMarginRight(childOldMarginRight);
2941             
2942             if (childLogicalWidthAtNewLogicalTopOffset <= availableLogicalWidthAtNewLogicalTopOffset) {
2943                 // Even though we may not be moving, if the logical width did shrink because of the presence of new floats, then
2944                 // we need to force a relayout as though we shifted. This happens because of the dynamic addition of overhanging floats
2945                 // from previous siblings when negative margins exist on a child (see the addOverhangingFloats call at the end of collapseMargins).
2946                 if (childLogicalWidthAtOldLogicalTopOffset != childLogicalWidthAtNewLogicalTopOffset)
2947                     child.setChildNeedsLayout(MarkOnlyThis);
2948                 return newLogicalTop - logicalTop;
2949             }
2950
2951             newLogicalTop = nextFloatLogicalBottomBelowForBlock(newLogicalTop);
2952             ASSERT(newLogicalTop >= logicalTop);
2953             if (newLogicalTop < logicalTop)
2954                 break;
2955         }
2956         ASSERT_NOT_REACHED();
2957     }
2958     return result;
2959 }
2960
2961 bool RenderBlockFlow::hitTestFloats(const HitTestRequest& request, HitTestResult& result, const HitTestLocation& locationInContainer, const LayoutPoint& accumulatedOffset)
2962 {
2963     if (!m_floatingObjects)
2964         return false;
2965
2966     LayoutPoint adjustedLocation = accumulatedOffset;
2967     if (is<RenderView>(*this))
2968         adjustedLocation += toLayoutSize(downcast<RenderView>(*this).frameView().scrollPosition());
2969
2970     const FloatingObjectSet& floatingObjectSet = m_floatingObjects->set();
2971     auto begin = floatingObjectSet.begin();
2972     for (auto it = floatingObjectSet.end(); it != begin;) {
2973         --it;
2974         const auto& floatingObject = *it->get();
2975         auto& renderer = floatingObject.renderer();
2976         if (floatingObject.shouldPaint() && !renderer.hasSelfPaintingLayer()) {
2977             LayoutPoint childPoint = flipFloatForWritingModeForChild(floatingObject, adjustedLocation + floatingObject.translationOffsetToAncestor());
2978             if (renderer.hitTest(request, result, locationInContainer, childPoint)) {
2979                 updateHitTestResult(result, locationInContainer.point() - toLayoutSize(childPoint));
2980                 return true;
2981             }
2982         }
2983     }
2984
2985     return false;
2986 }
2987
2988 bool RenderBlockFlow::hitTestInlineChildren(const HitTestRequest& request, HitTestResult& result, const HitTestLocation& locationInContainer, const LayoutPoint& accumulatedOffset, HitTestAction hitTestAction)
2989 {
2990     ASSERT(childrenInline());
2991
2992     if (auto simpleLineLayout = this->simpleLineLayout())
2993         return SimpleLineLayout::hitTestFlow(*this, *simpleLineLayout, request, result, locationInContainer, accumulatedOffset, hitTestAction);
2994
2995     return m_lineBoxes.hitTest(this, request, result, locationInContainer, accumulatedOffset, hitTestAction);
2996 }
2997
2998 void RenderBlockFlow::adjustForBorderFit(LayoutUnit x, LayoutUnit& left, LayoutUnit& right) const
2999 {
3000     if (style().visibility() != VISIBLE)
3001         return;
3002
3003     // We don't deal with relative positioning.  Our assumption is that you shrink to fit the lines without accounting
3004     // for either overflow or translations via relative positioning.
3005     if (childrenInline()) {
3006         const_cast<RenderBlockFlow&>(*this).ensureLineBoxes();
3007
3008         for (auto* box = firstRootBox(); box; box = box->nextRootBox()) {
3009             if (box->firstChild())
3010                 left = std::min(left, x + LayoutUnit(box->firstChild()->x()));
3011             if (box->lastChild())
3012                 right = std::max(right, x + LayoutUnit(ceilf(box->lastChild()->logicalRight())));
3013         }
3014     } else {
3015         for (RenderBox* obj = firstChildBox(); obj; obj = obj->nextSiblingBox()) {
3016             if (!obj->isFloatingOrOutOfFlowPositioned()) {
3017                 if (is<RenderBlockFlow>(*obj) && !obj->hasOverflowClip())
3018                     downcast<RenderBlockFlow>(*obj).adjustForBorderFit(x + obj->x(), left, right);
3019                 else if (obj->style().visibility() == VISIBLE) {
3020                     // We are a replaced element or some kind of non-block-flow object.
3021                     left = std::min(left, x + obj->x());
3022                     right = std::max(right, x + obj->x() + obj->width());
3023                 }
3024             }
3025         }
3026     }
3027
3028     if (m_floatingObjects) {
3029         const FloatingObjectSet& floatingObjectSet = m_floatingObjects->set();
3030         auto end = floatingObjectSet.end();
3031         for (auto it = floatingObjectSet.begin(); it != end; ++it) {
3032             const auto& floatingObject = *it->get();
3033             // Only examine the object if our m_shouldPaint flag is set.
3034             if (floatingObject.shouldPaint()) {
3035                 LayoutUnit floatLeft = floatingObject.translationOffsetToAncestor().width();
3036                 LayoutUnit floatRight = floatLeft + floatingObject.renderer().width();
3037                 left = std::min(left, floatLeft);
3038                 right = std::max(right, floatRight);
3039             }
3040         }
3041     }
3042 }
3043
3044 void RenderBlockFlow::fitBorderToLinesIfNeeded()
3045 {
3046     if (style().borderFit() == BorderFitBorder || hasOverrideLogicalContentWidth())
3047         return;
3048
3049     // Walk any normal flow lines to snugly fit.
3050     LayoutUnit left = LayoutUnit::max();
3051     LayoutUnit right = LayoutUnit::min();
3052     LayoutUnit oldWidth = contentWidth();
3053     adjustForBorderFit(0, left, right);
3054     
3055     // Clamp to our existing edges. We can never grow. We only shrink.
3056     LayoutUnit leftEdge = borderLeft() + paddingLeft();
3057     LayoutUnit rightEdge = leftEdge + oldWidth;
3058     left = std::min(rightEdge, std::max(leftEdge, left));
3059     right = std::max(leftEdge, std::min(rightEdge, right));
3060     
3061     LayoutUnit newContentWidth = right - left;
3062     if (newContentWidth == oldWidth)
3063         return;
3064     
3065     setOverrideLogicalContentWidth(newContentWidth);
3066     layoutBlock(false);
3067     clearOverrideLogicalContentWidth();
3068 }
3069
3070 void RenderBlockFlow::markLinesDirtyInBlockRange(LayoutUnit logicalTop, LayoutUnit logicalBottom, RootInlineBox* highest)
3071 {
3072     if (logicalTop >= logicalBottom)
3073         return;
3074
3075     // Floats currently affect the choice whether to use simple line layout path.
3076     if (m_simpleLineLayout) {
3077         invalidateLineLayoutPath();
3078         return;
3079     }
3080
3081     RootInlineBox* lowestDirtyLine = lastRootBox();
3082     RootInlineBox* afterLowest = lowestDirtyLine;
3083     while (lowestDirtyLine && lowestDirtyLine->lineBottomWithLeading() >= logicalBottom && logicalBottom < LayoutUnit::max()) {
3084         afterLowest = lowestDirtyLine;
3085         lowestDirtyLine = lowestDirtyLine->prevRootBox();
3086     }
3087
3088     while (afterLowest && afterLowest != highest && (afterLowest->lineBottomWithLeading() >= logicalTop || afterLowest->lineBottomWithLeading() < 0)) {
3089         afterLowest->markDirty();
3090         afterLowest = afterLowest->prevRootBox();
3091     }
3092 }
3093
3094 std::optional<int> RenderBlockFlow::firstLineBaseline() const
3095 {
3096     if (isWritingModeRoot() && !isRubyRun())
3097         return std::optional<int>();
3098
3099     if (!childrenInline())
3100         return RenderBlock::firstLineBaseline();
3101
3102     if (!hasLines())
3103         return std::optional<int>();
3104
3105     if (auto simpleLineLayout = this->simpleLineLayout())
3106         return std::optional<int>(SimpleLineLayout::computeFlowFirstLineBaseline(*this, *simpleLineLayout));
3107
3108     ASSERT(firstRootBox());
3109     return firstRootBox()->logicalTop() + firstLineStyle().fontMetrics().ascent(firstRootBox()->baselineType());
3110 }
3111
3112 std::optional<int> RenderBlockFlow::inlineBlockBaseline(LineDirectionMode lineDirection) const
3113 {
3114     if (isWritingModeRoot() && !isRubyRun())
3115         return std::optional<int>();
3116
3117     // Note that here we only take the left and bottom into consideration. Our caller takes the right and top into consideration.
3118     float boxHeight = lineDirection == HorizontalLine ? height() + m_marginBox.bottom() : width() + m_marginBox.left();
3119     float lastBaseline;
3120     if (!childrenInline()) {
3121         std::optional<int> inlineBlockBaseline = RenderBlock::inlineBlockBaseline(lineDirection);
3122         if (!inlineBlockBaseline)
3123             return inlineBlockBaseline;
3124         lastBaseline = inlineBlockBaseline.value();
3125     } else {
3126         if (!hasLines()) {
3127             if (!hasLineIfEmpty())
3128                 return std::optional<int>();
3129             const auto& fontMetrics = firstLineStyle().fontMetrics();
3130             return std::optional<int>(fontMetrics.ascent()
3131                 + (lineHeight(true, lineDirection, PositionOfInteriorLineBoxes) - fontMetrics.height()) / 2
3132                 + (lineDirection == HorizontalLine ? borderTop() + paddingTop() : borderRight() + paddingRight()));
3133         }
3134
3135         if (auto simpleLineLayout = this->simpleLineLayout())
3136             lastBaseline = SimpleLineLayout::computeFlowLastLineBaseline(*this, *simpleLineLayout);
3137         else {
3138             bool isFirstLine = lastRootBox() == firstRootBox();
3139             const auto& style = isFirstLine ? firstLineStyle() : this->style();
3140             lastBaseline = lastRootBox()->logicalTop() + style.fontMetrics().ascent(lastRootBox()->baselineType());
3141         }
3142     }
3143     // According to the CSS spec http://www.w3.org/TR/CSS21/visudet.html, we shouldn't be performing this min, but should
3144     // instead be returning boxHeight directly. However, we feel that a min here is better behavior (and is consistent
3145     // enough with the spec to not cause tons of breakages).
3146     return std::optional<int>(style().overflowY() == OVISIBLE ? lastBaseline : std::min(boxHeight, lastBaseline));
3147 }
3148
3149 void RenderBlockFlow::setSelectionState(SelectionState state)
3150 {
3151     if (state != SelectionNone)
3152         ensureLineBoxes();
3153     RenderBoxModelObject::setSelectionState(state);
3154 }
3155
3156 GapRects RenderBlockFlow::inlineSelectionGaps(RenderBlock& rootBlock, const LayoutPoint& rootBlockPhysicalPosition, const LayoutSize& offsetFromRootBlock,
3157     LayoutUnit& lastLogicalTop, LayoutUnit& lastLogicalLeft, LayoutUnit& lastLogicalRight, const LogicalSelectionOffsetCaches& cache, const PaintInfo* paintInfo)
3158 {
3159     ASSERT(!m_simpleLineLayout);
3160
3161     GapRects result;
3162
3163     bool containsStart = selectionState() == SelectionStart || selectionState() == SelectionBoth;
3164
3165     if (!hasLines()) {
3166         if (containsStart) {
3167             // Update our lastLogicalTop to be the bottom of the block. <hr>s or empty blocks with height can trip this case.
3168             lastLogicalTop = blockDirectionOffset(rootBlock, offsetFromRootBlock) + logicalHeight();
3169             lastLogicalLeft = logicalLeftSelectionOffset(rootBlock, logicalHeight(), cache);
3170             lastLogicalRight = logicalRightSelectionOffset(rootBlock, logicalHeight(), cache);
3171         }
3172         return result;
3173     }
3174
3175     RootInlineBox* lastSelectedLine = 0;
3176     RootInlineBox* curr;
3177     for (curr = firstRootBox(); curr && !curr->hasSelectedChildren(); curr = curr->nextRootBox()) { }
3178
3179     // Now paint the gaps for the lines.
3180     for (; curr && curr->hasSelectedChildren(); curr = curr->nextRootBox()) {
3181         LayoutUnit selTop =  curr->selectionTopAdjustedForPrecedingBlock();
3182         LayoutUnit selHeight = curr->selectionHeightAdjustedForPrecedingBlock();
3183
3184         if (!containsStart && !lastSelectedLine &&
3185             selectionState() != SelectionStart && selectionState() != SelectionBoth && !isRubyBase())
3186             result.uniteCenter(blockSelectionGap(rootBlock, rootBlockPhysicalPosition, offsetFromRootBlock, lastLogicalTop, lastLogicalLeft, lastLogicalRight, selTop, cache, paintInfo));
3187         
3188         LayoutRect logicalRect(curr->logicalLeft(), selTop, curr->logicalWidth(), selTop + selHeight);
3189         logicalRect.move(isHorizontalWritingMode() ? offsetFromRootBlock : offsetFromRootBlock.transposedSize());
3190         LayoutRect physicalRect = rootBlock.logicalRectToPhysicalRect(rootBlockPhysicalPosition, logicalRect);
3191         if (!paintInfo || (isHorizontalWritingMode() && physicalRect.y() < paintInfo->rect.maxY() && physicalRect.maxY() > paintInfo->rect.y())
3192             || (!isHorizontalWritingMode() && physicalRect.x() < paintInfo->rect.maxX() && physicalRect.maxX() > paintInfo->rect.x()))
3193             result.unite(curr->lineSelectionGap(rootBlock, rootBlockPhysicalPosition, offsetFromRootBlock, selTop, selHeight, cache, paintInfo));
3194
3195         lastSelectedLine = curr;
3196     }
3197
3198     if (containsStart && !lastSelectedLine)
3199         // VisibleSelection must start just after our last line.
3200         lastSelectedLine = lastRootBox();
3201
3202     if (lastSelectedLine && selectionState() != SelectionEnd && selectionState() != SelectionBoth) {
3203         // Update our lastY to be the bottom of the last selected line.
3204         lastLogicalTop = blockDirectionOffset(rootBlock, offsetFromRootBlock) + lastSelectedLine->selectionBottom();
3205         lastLogicalLeft = logicalLeftSelectionOffset(rootBlock, lastSelectedLine->selectionBottom(), cache);
3206         lastLogicalRight = logicalRightSelectionOffset(rootBlock, lastSelectedLine->selectionBottom(), cache);
3207     }
3208     return result;
3209 }
3210
3211 void RenderBlockFlow::createRenderNamedFlowFragmentIfNeeded()
3212 {
3213     if (renderNamedFlowFragment() || isRenderNamedFlowFragment())
3214         return;
3215
3216     // FIXME: Multicolumn regions not yet supported (http://dev.w3.org/csswg/css-regions/#multi-column-regions)
3217     if (style().isDisplayRegionType() && style().hasFlowFrom() && !style().specifiesColumns()) {
3218         RenderNamedFlowFragment* flowFragment = new RenderNamedFlowFragment(document(), RenderNamedFlowFragment::createStyle(style()));
3219         flowFragment->initializeStyle();
3220         addChild(flowFragment);
3221         setRenderNamedFlowFragment(flowFragment);
3222     }
3223 }
3224
3225 bool RenderBlockFlow::needsLayoutAfterRegionRangeChange() const
3226 {
3227     // A block without floats or that expands to enclose them won't need a relayout
3228     // after a region range change. There is no overflow content needing relayout
3229     // in the region chain because the region range can only shrink after the estimation.
3230     if (!containsFloats() || createsNewFormattingContext())
3231         return false;
3232
3233     return true;
3234 }
3235
3236 bool RenderBlockFlow::canHaveChildren() const
3237 {
3238     return !renderNamedFlowFragment() ? RenderBlock::canHaveChildren() : renderNamedFlowFragment()->canHaveChildren();
3239 }
3240
3241 bool RenderBlockFlow::canHaveGeneratedChildren() const
3242 {
3243     return !renderNamedFlowFragment() ? RenderBlock::canHaveGeneratedChildren() : renderNamedFlowFragment()->canHaveGeneratedChildren();
3244 }
3245
3246 bool RenderBlockFlow::namedFlowFragmentNeedsUpdate() const
3247 {
3248     if (!isRenderNamedFlowFragmentContainer())
3249         return false;
3250
3251     return hasRelativeLogicalHeight() && !isRenderView();
3252 }
3253
3254 void RenderBlockFlow::updateLogicalHeight()
3255 {
3256     RenderBlock::updateLogicalHeight();
3257
3258     if (renderNamedFlowFragment()) {
3259         renderNamedFlowFragment()->setLogicalHeight(std::max<LayoutUnit>(0, logicalHeight() - borderAndPaddingLogicalHeight()));
3260         renderNamedFlowFragment()->invalidateRegionIfNeeded();
3261     }
3262 }
3263
3264 void RenderBlockFlow::setRenderNamedFlowFragment(RenderNamedFlowFragment* flowFragment)
3265 {
3266     RenderBlockFlowRareData& rareData = ensureRareBlockFlowData();
3267     if (auto* flowFragmentOnFlow = std::exchange(rareData.m_renderNamedFlowFragment, nullptr))
3268         flowFragmentOnFlow->destroy();
3269     rareData.m_renderNamedFlowFragment = flowFragment;
3270 }
3271
3272 void RenderBlockFlow::setMultiColumnFlowThread(RenderMultiColumnFlowThread* flowThread)
3273 {
3274     if (flowThread || hasRareBlockFlowData()) {
3275         RenderBlockFlowRareData& rareData = ensureRareBlockFlowData();
3276         rareData.m_multiColumnFlowThread = flowThread;
3277     }
3278 }
3279
3280 static bool shouldCheckLines(const RenderBlockFlow& blockFlow)
3281 {
3282     return !blockFlow.isFloatingOrOutOfFlowPositioned() && blockFlow.style().height().isAuto();
3283 }
3284
3285 RootInlineBox* RenderBlockFlow::lineAtIndex(int i) const
3286 {
3287     ASSERT(i >= 0);
3288
3289     if (style().visibility() != VISIBLE)
3290         return nullptr;
3291
3292     if (childrenInline()) {
3293         for (auto* box = firstRootBox(); box; box = box->nextRootBox()) {
3294             if (!i--)
3295                 return box;
3296         }
3297         return nullptr;
3298     }
3299
3300     for (auto& blockFlow : childrenOfType<RenderBlockFlow>(*this)) {
3301         if (!shouldCheckLines(blockFlow))
3302             continue;
3303         if (RootInlineBox* box = blockFlow.lineAtIndex(i))
3304             return box;
3305     }
3306
3307     return nullptr;
3308 }
3309
3310 int RenderBlockFlow::lineCount(const RootInlineBox* stopRootInlineBox, bool* found) const
3311 {
3312     if (style().visibility() != VISIBLE)
3313         return 0;
3314
3315     int count = 0;
3316
3317     if (childrenInline()) {
3318         if (auto simpleLineLayout = this->simpleLineLayout()) {
3319             ASSERT(!stopRootInlineBox);
3320             return simpleLineLayout->lineCount();
3321         }
3322         for (auto* box = firstRootBox(); box; box = box->nextRootBox()) {
3323             ++count;
3324             if (box == stopRootInlineBox) {
3325                 if (found)
3326                     *found = true;
3327                 break;
3328             }
3329         }
3330         return count;
3331     }
3332
3333     for (auto& blockFlow : childrenOfType<RenderBlockFlow>(*this)) {
3334         if (!shouldCheckLines(blockFlow))
3335             continue;
3336         bool recursiveFound = false;
3337         count += blockFlow.lineCount(stopRootInlineBox, &recursiveFound);
3338         if (recursiveFound) {
3339             if (found)
3340                 *found = true;
3341             break;
3342         }
3343     }
3344
3345     return count;
3346 }
3347
3348 static int getHeightForLineCount(const RenderBlockFlow& block, int lineCount, bool includeBottom, int& count)
3349 {
3350     if (block.style().visibility() != VISIBLE)
3351         return -1;
3352
3353     if (block.childrenInline()) {
3354         for (auto* box = block.firstRootBox(); box; box = box->nextRootBox()) {
3355             if (++count == lineCount)
3356                 return box->lineBottom() + (includeBottom ? (block.borderBottom() + block.paddingBottom()) : LayoutUnit());
3357         }
3358     } else {
3359         RenderBox* normalFlowChildWithoutLines = nullptr;
3360         for (auto* obj = block.firstChildBox(); obj; obj = obj->nextSiblingBox()) {
3361             if (is<RenderBlockFlow>(*obj) && shouldCheckLines(downcast<RenderBlockFlow>(*obj))) {
3362                 int result = getHeightForLineCount(downcast<RenderBlockFlow>(*obj), lineCount, false, count);
3363                 if (result != -1)
3364                     return result + obj->y() + (includeBottom ? (block.borderBottom() + block.paddingBottom()) : LayoutUnit());
3365             } else if (!obj->isFloatingOrOutOfFlowPositioned())
3366                 normalFlowChildWithoutLines = obj;
3367         }
3368         if (normalFlowChildWithoutLines && !lineCount)
3369             return normalFlowChildWithoutLines->y() + normalFlowChildWithoutLines->height();
3370     }
3371     
3372     return -1;
3373 }
3374
3375 int RenderBlockFlow::heightForLineCount(int lineCount)
3376 {
3377     int count = 0;
3378     return getHeightForLineCount(*this, lineCount, true, count);
3379 }
3380
3381 void RenderBlockFlow::clearTruncation()
3382 {
3383     if (style().visibility() != VISIBLE)
3384         return;
3385
3386     if (childrenInline() && hasMarkupTruncation()) {
3387         ensureLineBoxes();
3388
3389         setHasMarkupTruncation(false);
3390         for (auto* box = firstRootBox(); box; box = box->nextRootBox())
3391             box->clearTruncation();
3392         return;
3393     }
3394
3395     for (auto& blockFlow : childrenOfType<RenderBlockFlow>(*this)) {
3396         if (shouldCheckLines(blockFlow))
3397             blockFlow.clearTruncation();
3398     }
3399 }
3400
3401 bool RenderBlockFlow::containsNonZeroBidiLevel() const
3402 {
3403     for (auto* root = firstRootBox(); root; root = root->nextRootBox()) {
3404         for (auto* box = root->firstLeafChild(); box; box = box->nextLeafChild()) {
3405             if (box->bidiLevel())
3406                 return true;
3407         }
3408     }
3409     return false;
3410 }
3411
3412 Position RenderBlockFlow::positionForBox(InlineBox *box, bool start) const
3413 {
3414     if (!box)
3415         return Position();
3416
3417     if (!box->renderer().nonPseudoNode())
3418         return createLegacyEditingPosition(nonPseudoElement(), start ? caretMinOffset() : caretMaxOffset());
3419
3420     if (!is<InlineTextBox>(*box))
3421         return createLegacyEditingPosition(box->renderer().nonPseudoNode(), start ? box->renderer().caretMinOffset() : box->renderer().caretMaxOffset());
3422
3423     auto& textBox = downcast<InlineTextBox>(*box);
3424     return createLegacyEditingPosition(textBox.renderer().nonPseudoNode(), start ? textBox.start() : textBox.start() + textBox.len());
3425 }
3426
3427 RenderText* RenderBlockFlow::findClosestTextAtAbsolutePoint(const FloatPoint& point)
3428 {
3429     // A light, non-recursive version of RenderBlock::positionForCoordinates that looks at
3430     // whether a point lies within the gaps between its root line boxes, to be called against
3431     // a node returned from elementAtPoint. We make the assumption that either the node or one
3432     // of its immediate children contains the root line boxes in question.
3433     // See <rdar://problem/6824650> for context.
3434     
3435     RenderBlock* block = this;
3436     
3437     FloatPoint localPoint = block->absoluteToLocal(point);
3438     
3439     if (!block->childrenInline()) {
3440         // Look among our immediate children for an alternate box that contains the point.
3441         for (RenderBox* child = block->firstChildBox(); child; child = child->nextSiblingBox()) {
3442             if (!child->height() || child->style().visibility() != WebCore::VISIBLE || child->isFloatingOrOutOfFlowPositioned())
3443                 continue;
3444             float top = child->y();
3445             
3446             RenderBox* nextChild = child->nextSiblingBox();
3447             while (nextChild && nextChild->isFloatingOrOutOfFlowPositioned())
3448                 nextChild = nextChild->nextSiblingBox();
3449             if (!nextChild) {
3450                 if (localPoint.y() >= top) {
3451                     block = downcast<RenderBlock>(child);
3452                     break;
3453                 }
3454                 continue;
3455             }
3456             
3457             float bottom = nextChild->y();
3458             
3459             if (localPoint.y() >= top && localPoint.y() < bottom && is<RenderBlock>(*child)) {
3460                 block = downcast<RenderBlock>(child);
3461                 break;
3462             }
3463         }
3464         
3465         if (!block->childrenInline())
3466             return nullptr;
3467         
3468         localPoint = block->absoluteToLocal(point);
3469     }
3470     
3471     RenderBlockFlow& blockFlow = downcast<RenderBlockFlow>(*block);
3472     
3473     // Only check the gaps between the root line boxes. We deliberately ignore overflow because
3474     // experience has shown that hit tests on an exploded text node can fail when within the
3475     // overflow region.
3476     for (RootInlineBox* current = blockFlow.firstRootBox(); current && current != blockFlow.lastRootBox(); current = current->nextRootBox()) {
3477         float currentBottom = current->y() + current->logicalHeight();
3478         if (localPoint.y() < currentBottom)
3479             return nullptr;
3480         
3481         RootInlineBox* next = current->nextRootBox();
3482         float nextTop = next->y();
3483         if (localPoint.y() < nextTop) {
3484             InlineBox* inlineBox = current->closestLeafChildForLogicalLeftPosition(localPoint.x());
3485             if (inlineBox && inlineBox->behavesLikeText() && is<RenderText>(inlineBox->renderer()))
3486                 return &downcast<RenderText>(inlineBox->renderer());
3487         }
3488     }
3489     return nullptr;
3490 }
3491
3492 VisiblePosition RenderBlockFlow::positionForPointWithInlineChildren(const LayoutPoint& pointInLogicalContents, const RenderRegion* region)
3493 {
3494     ASSERT(childrenInline());
3495
3496     ensureLineBoxes();
3497
3498     if (!firstRootBox())
3499         return createVisiblePosition(0, DOWNSTREAM);
3500
3501     bool linesAreFlipped = style().isFlippedLinesWritingMode();
3502     bool blocksAreFlipped = style().isFlippedBlocksWritingMode();
3503
3504     // look for the closest line box in the root box which is at the passed-in y coordinate
3505     InlineBox* closestBox = 0;
3506     RootInlineBox* firstRootBoxWithChildren = 0;
3507     RootInlineBox* lastRootBoxWithChildren = 0;
3508     for (RootInlineBox* root = firstRootBox(); root; root = root->nextRootBox()) {
3509         if (region && root->containingRegion() != region)
3510             continue;
3511
3512         if (!root->firstLeafChild())
3513             continue;
3514         if (!firstRootBoxWithChildren)
3515             firstRootBoxWithChildren = root;
3516
3517         if (!linesAreFlipped && root->isFirstAfterPageBreak() && (pointInLogicalContents.y() < root->lineTopWithLeading()
3518             || (blocksAreFlipped && pointInLogicalContents.y() == root->lineTopWithLeading())))
3519             break;
3520
3521         lastRootBoxWithChildren = root;
3522
3523         // check if this root line box is located at this y coordinate
3524         if (pointInLogicalContents.y() < root->selectionBottom() || (blocksAreFlipped && pointInLogicalContents.y() == root->selectionBottom())) {
3525             if (linesAreFlipped) {
3526                 RootInlineBox* nextRootBoxWithChildren = root->nextRootBox();
3527                 while (nextRootBoxWithChildren && !nextRootBoxWithChildren->firstLeafChild())
3528                     nextRootBoxWithChildren = nextRootBoxWithChildren->nextRootBox();
3529
3530                 if (nextRootBoxWithChildren && nextRootBoxWithChildren->isFirstAfterPageBreak() && (pointInLogicalContents.y() > nextRootBoxWithChildren->lineTopWithLeading()
3531                     || (!blocksAreFlipped && pointInLogicalContents.y() == nextRootBoxWithChildren->lineTopWithLeading())))
3532                     continue;
3533             }
3534             closestBox = root->closestLeafChildForLogicalLeftPosition(pointInLogicalContents.x());
3535             if (closestBox)
3536                 break;
3537         }
3538     }
3539
3540     bool moveCaretToBoundary = frame().editor().behavior().shouldMoveCaretToHorizontalBoundaryWhenPastTopOrBottom();
3541
3542     if (!moveCaretToBoundary && !closestBox && lastRootBoxWithChildren) {
3543         // y coordinate is below last root line box, pretend we hit it
3544         closestBox = lastRootBoxWithChildren->closestLeafChildForLogicalLeftPosition(pointInLogicalContents.x());
3545     }
3546
3547     if (closestBox) {
3548         if (moveCaretToBoundary) {
3549             LayoutUnit firstRootBoxWithChildrenTop = std::min<LayoutUnit>(firstRootBoxWithChildren->selectionTop(), firstRootBoxWithChildren->logicalTop());
3550             if (pointInLogicalContents.y() < firstRootBoxWithChildrenTop
3551                 || (blocksAreFlipped && pointInLogicalContents.y() == firstRootBoxWithChildrenTop)) {
3552                 InlineBox* box = firstRootBoxWithChildren->firstLeafChild();
3553                 if (box->isLineBreak()) {
3554                     if (InlineBox* newBox = box->nextLeafChildIgnoringLineBreak())
3555                         box = newBox;
3556                 }
3557                 // y coordinate is above first root line box, so return the start of the first
3558                 return VisiblePosition(positionForBox(box, true), DOWNSTREAM);
3559             }
3560         }
3561
3562         // pass the box a top position that is inside it
3563         LayoutPoint point(pointInLogicalContents.x(), closestBox->root().blockDirectionPointInLine());
3564         if (!isHorizontalWritingMode())
3565             point = point.transposedPoint();
3566         if (closestBox->renderer().isReplaced())
3567             return positionForPointRespectingEditingBoundaries(*this, downcast<RenderBox>(closestBox->renderer()), point);
3568         return closestBox->renderer().positionForPoint(point, nullptr);
3569     }
3570
3571     if (lastRootBoxWithChildren) {
3572         // We hit this case for Mac behavior when the Y coordinate is below the last box.
3573         ASSERT(moveCaretToBoundary);
3574         InlineBox* logicallyLastBox;
3575         if (lastRootBoxWithChildren->getLogicalEndBoxWithNode(logicallyLastBox))
3576             return VisiblePosition(positionForBox(logicallyLastBox, false), DOWNSTREAM);
3577     }
3578
3579     // Can't reach this. We have a root line box, but it has no kids.
3580     // FIXME: This should ASSERT_NOT_REACHED(), but clicking on placeholder text
3581     // seems to hit this code path.
3582     return createVisiblePosition(0, DOWNSTREAM);
3583 }
3584
3585 Position RenderBlockFlow::positionForPoint(const LayoutPoint& point)
3586 {
3587     // FIXME: It supports single text child only (which is the majority of simple line layout supported content at this point).
3588     if (!simpleLineLayout() || firstChild() != lastChild() || !is<RenderText>(firstChild()))
3589         return positionForPoint(point, nullptr).deepEquivalent();
3590     return downcast<RenderText>(*firstChild()).positionForPoint(point);
3591 }
3592
3593 VisiblePosition RenderBlockFlow::positionForPoint(const LayoutPoint& point, const RenderRegion* region)
3594 {
3595     if (auto fragment = renderNamedFlowFragment())
3596         return fragment->positionForPoint(point, region);
3597     return RenderBlock::positionForPoint(point, region);
3598 }
3599
3600 void RenderBlockFlow::addFocusRingRectsForInlineChildren(Vector<LayoutRect>& rects, const LayoutPoint& additionalOffset, const RenderLayerModelObject*)
3601 {
3602     ASSERT(childrenInline());
3603     for (RootInlineBox* curr = firstRootBox(); curr; curr = curr->nextRootBox()) {
3604         LayoutUnit top = std::max<LayoutUnit>(curr->lineTop(), curr->top());
3605         LayoutUnit bottom = std::min<LayoutUnit>(curr->lineBottom(), curr->top() + curr->height());
3606         LayoutRect rect(additionalOffset.x() + curr->x(), additionalOffset.y() + top, curr->width(), bottom - top);
3607         if (!rect.isEmpty())
3608             rects.append(rect);
3609     }
3610 }
3611
3612 void RenderBlockFlow::paintInlineChildren(PaintInfo& paintInfo, const LayoutPoint& paintOffset)
3613 {
3614     ASSERT(childrenInline());
3615
3616     if (auto simpleLineLayout = this->simpleLineLayout()) {
3617         SimpleLineLayout::paintFlow(*this, *simpleLineLayout, paintInfo, paintOffset);
3618         return;
3619     }
3620     m_lineBoxes.paint(this, paintInfo, paintOffset);
3621 }
3622
3623 bool RenderBlockFlow::relayoutForPagination(LayoutStateMaintainer& statePusher)
3624 {
3625     if (!multiColumnFlowThread() || !multiColumnFlowThread()->shouldRelayoutForPagination())
3626         return false;
3627     
3628     multiColumnFlowThread()->setNeedsHeightsRecalculation(false);
3629     multiColumnFlowThread()->setInBalancingPass(true); // Prevent re-entering this method (and recursion into layout).
3630
3631     bool needsRelayout;
3632     bool neededRelayout = false;
3633     bool firstPass = true;
3634     do {
3635         // Column heights may change here because of balancing. We may have to do multiple layout
3636         // passes, depending on how the contents is fitted to the changed column heights. In most
3637         // cases, laying out again twice or even just once will suffice. Sometimes we need more
3638         // passes than that, though, but the number of retries should not exceed the number of
3639         // columns, unless we have a bug.
3640         needsRelayout = false;
3641         for (RenderMultiColumnSet* multicolSet = multiColumnFlowThread()->firstMultiColumnSet(); multicolSet; multicolSet = multicolSet->nextSiblingMultiColumnSet()) {
3642             if (multicolSet->recalculateColumnHeight(firstPass))
3643                 needsRelayout = true;
3644             if (needsRelayout) {
3645                 // Once a column set gets a new column height, that column set and all successive column
3646                 // sets need to be laid out over again, since their logical top will be affected by
3647                 // this, and therefore their column heights may change as well, at least if the multicol
3648                 // height is constrained.
3649                 multicolSet->setChildNeedsLayout(MarkOnlyThis);
3650             }
3651         }
3652         if (needsRelayout) {
3653             // Layout again. Column balancing resulted in a new height.
3654             neededRelayout = true;
3655             multiColumnFlowThread()->setChildNeedsLayout(MarkOnlyThis);
3656             setChildNeedsLayout(MarkOnlyThis);
3657             if (firstPass)
3658                 statePusher.pop();
3659             layoutBlock(false);
3660         }
3661         firstPass = false;
3662     } while (needsRelayout);