02d2777c04d5823ad07dd6022c7ffb5422e279ba
[WebKit-https.git] / Source / WebCore / rendering / RenderBlockFlow.h
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-2013,  Apple Inc. All rights reserved.
6  *
7  * This library is free software; you can redistribute it and/or
8  * modify it under the terms of the GNU Library General Public
9  * License as published by the Free Software Foundation; either
10  * version 2 of the License, or (at your option) any later version.
11  *
12  * This library is distributed in the hope that it will be useful,
13  * but WITHOUT ANY WARRANTY; without even the implied warranty of
14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
15  * Library General Public License for more details.
16  *
17  * You should have received a copy of the GNU Library General Public License
18  * along with this library; see the file COPYING.LIB.  If not, write to
19  * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
20  * Boston, MA 02110-1301, USA.
21  */
22
23 #ifndef RenderBlockFlow_h
24 #define RenderBlockFlow_h
25
26 #include "FloatingObjects.h"
27 #include "LineWidth.h"
28 #include "RenderBlock.h"
29 #include "RenderLineBoxList.h"
30 #include "SimpleLineLayout.h"
31 #include "TrailingObjects.h"
32 #include <memory>
33
34 namespace WebCore {
35
36 class FloatWithRect;
37 class LayoutStateMaintainer;
38 class LineBreaker;
39 class LineInfo;
40 class LineWidth;
41 class RenderMultiColumnFlowThread;
42 class RenderNamedFlowFragment;
43 class RenderRubyRun;
44
45 struct WordMeasurement;
46
47 template <class Run> class BidiRunList;
48 typedef Vector<WordMeasurement, 64> WordMeasurements;
49
50 #if ENABLE(TEXT_AUTOSIZING)
51 enum LineCount {
52     NOT_SET = 0, NO_LINE = 1, ONE_LINE = 2, MULTI_LINE = 3
53 };
54 #endif
55
56 class RenderBlockFlow : public RenderBlock {
57 public:
58     RenderBlockFlow(Element&, RenderStyle&&);
59     RenderBlockFlow(Document&, RenderStyle&&);
60     virtual ~RenderBlockFlow();
61         
62     void layoutBlock(bool relayoutChildren, LayoutUnit pageLogicalHeight = 0) override;
63
64 protected:
65     void insertedIntoTree() override;
66     void willBeDestroyed() override;
67     
68     // This method is called at the start of layout to wipe away all of the floats in our floating objects list. It also
69     // repopulates the list with any floats that intrude from previous siblings or parents. Floats that were added by
70     // descendants are gone when this call completes and will get added back later on after the children have gotten
71     // a relayout.
72     void rebuildFloatingObjectSetFromIntrudingFloats();
73
74     // RenderBlockFlow always contains either lines or paragraphs. When the children are all blocks (e.g. paragraphs), we call layoutBlockChildren.
75     // When the children are are all inline (e.g., lines), we call layoutInlineChildren.
76     void layoutBlockChildren(bool relayoutChildren, LayoutUnit& maxFloatLogicalBottom);
77     void layoutInlineChildren(bool relayoutChildren, LayoutUnit& repaintLogicalTop, LayoutUnit& repaintLogicalBottom);
78
79     // RenderBlockFlows override these methods, since they are the only class that supports margin collapsing.
80     LayoutUnit collapsedMarginBefore() const final { return maxPositiveMarginBefore() - maxNegativeMarginBefore(); }
81     LayoutUnit collapsedMarginAfter() const final { return maxPositiveMarginAfter() - maxNegativeMarginAfter(); }
82
83     void dirtyLinesFromChangedChild(RenderObject& child) final { lineBoxes().dirtyLinesFromChangedChild(*this, child); }
84     void updateLogicalHeight() override;
85
86     void paintColumnRules(PaintInfo&, const LayoutPoint&) override;
87
88 public:
89     class MarginValues {
90     public:
91         MarginValues(LayoutUnit beforePos, LayoutUnit beforeNeg, LayoutUnit afterPos, LayoutUnit afterNeg)
92             : m_positiveMarginBefore(beforePos)
93             , m_negativeMarginBefore(beforeNeg)
94             , m_positiveMarginAfter(afterPos)
95             , m_negativeMarginAfter(afterNeg)
96         {
97         }
98         
99         LayoutUnit positiveMarginBefore() const { return m_positiveMarginBefore; }
100         LayoutUnit negativeMarginBefore() const { return m_negativeMarginBefore; }
101         LayoutUnit positiveMarginAfter() const { return m_positiveMarginAfter; }
102         LayoutUnit negativeMarginAfter() const { return m_negativeMarginAfter; }
103         
104         void setPositiveMarginBefore(LayoutUnit pos) { m_positiveMarginBefore = pos; }
105         void setNegativeMarginBefore(LayoutUnit neg) { m_negativeMarginBefore = neg; }
106         void setPositiveMarginAfter(LayoutUnit pos) { m_positiveMarginAfter = pos; }
107         void setNegativeMarginAfter(LayoutUnit neg) { m_negativeMarginAfter = neg; }
108     
109     private:
110         LayoutUnit m_positiveMarginBefore;
111         LayoutUnit m_negativeMarginBefore;
112         LayoutUnit m_positiveMarginAfter;
113         LayoutUnit m_negativeMarginAfter;
114     };
115     MarginValues marginValuesForChild(RenderBox& child) const;
116
117     // Allocated only when some of these fields have non-default values
118     struct RenderBlockFlowRareData {
119         WTF_MAKE_NONCOPYABLE(RenderBlockFlowRareData); WTF_MAKE_FAST_ALLOCATED;
120     public:
121         RenderBlockFlowRareData(const RenderBlockFlow& block)
122             : m_margins(positiveMarginBeforeDefault(block), negativeMarginBeforeDefault(block), positiveMarginAfterDefault(block), negativeMarginAfterDefault(block))
123             , m_lineBreakToAvoidWidow(-1)
124             , m_renderNamedFlowFragment(nullptr)
125             , m_multiColumnFlowThread(nullptr)
126             , m_discardMarginBefore(false)
127             , m_discardMarginAfter(false)
128             , m_didBreakAtLineToAvoidWidow(false)
129         { 
130         }
131
132         ~RenderBlockFlowRareData()
133         {
134         }
135
136         static LayoutUnit positiveMarginBeforeDefault(const RenderBlock& block)
137         { 
138             return std::max<LayoutUnit>(block.marginBefore(), 0);
139         }
140         static LayoutUnit negativeMarginBeforeDefault(const RenderBlock& block)
141         { 
142             return std::max<LayoutUnit>(-block.marginBefore(), 0);
143         }
144         static LayoutUnit positiveMarginAfterDefault(const RenderBlock& block)
145         {
146             return std::max<LayoutUnit>(block.marginAfter(), 0);
147         }
148         static LayoutUnit negativeMarginAfterDefault(const RenderBlock& block)
149         {
150             return std::max<LayoutUnit>(-block.marginAfter(), 0);
151         }
152         
153         MarginValues m_margins;
154         int m_lineBreakToAvoidWidow;
155         std::unique_ptr<RootInlineBox> m_lineGridBox;
156         RenderNamedFlowFragment* m_renderNamedFlowFragment;
157
158         RenderMultiColumnFlowThread* m_multiColumnFlowThread;
159         
160         bool m_discardMarginBefore : 1;
161         bool m_discardMarginAfter : 1;
162         bool m_didBreakAtLineToAvoidWidow : 1;
163     };
164
165     class MarginInfo {
166         // Collapsing flags for whether we can collapse our margins with our children's margins.
167         bool m_canCollapseWithChildren : 1;
168         bool m_canCollapseMarginBeforeWithChildren : 1;
169         bool m_canCollapseMarginAfterWithChildren : 1;
170
171         // Whether or not we are a quirky container, i.e., do we collapse away top and bottom
172         // margins in our container. Table cells and the body are the common examples. We
173         // also have a custom style property for Safari RSS to deal with TypePad blog articles.
174         bool m_quirkContainer : 1;
175
176         // This flag tracks whether we are still looking at child margins that can all collapse together at the beginning of a block.  
177         // They may or may not collapse with the top margin of the block (|m_canCollapseTopWithChildren| tells us that), but they will
178         // always be collapsing with one another. This variable can remain set to true through multiple iterations 
179         // as long as we keep encountering self-collapsing blocks.
180         bool m_atBeforeSideOfBlock : 1;
181
182         // This flag is set when we know we're examining bottom margins and we know we're at the bottom of the block.
183         bool m_atAfterSideOfBlock : 1;
184
185         // These variables are used to detect quirky margins that we need to collapse away (in table cells
186         // and in the body element).
187         bool m_hasMarginBeforeQuirk : 1;
188         bool m_hasMarginAfterQuirk : 1;
189         bool m_determinedMarginBeforeQuirk : 1;
190
191         bool m_discardMargin : 1;
192
193         // These flags track the previous maximal positive and negative margins.
194         LayoutUnit m_positiveMargin;
195         LayoutUnit m_negativeMargin;
196
197     public:
198         MarginInfo(const RenderBlockFlow&, LayoutUnit beforeBorderPadding, LayoutUnit afterBorderPadding);
199
200         void setAtBeforeSideOfBlock(bool b) { m_atBeforeSideOfBlock = b; }
201         void setAtAfterSideOfBlock(bool b) { m_atAfterSideOfBlock = b; }
202         void clearMargin()
203         {
204             m_positiveMargin = 0;
205             m_negativeMargin = 0;
206         }
207         void setHasMarginBeforeQuirk(bool b) { m_hasMarginBeforeQuirk = b; }
208         void setHasMarginAfterQuirk(bool b) { m_hasMarginAfterQuirk = b; }
209         void setDeterminedMarginBeforeQuirk(bool b) { m_determinedMarginBeforeQuirk = b; }
210         void setPositiveMargin(LayoutUnit p) { ASSERT(!m_discardMargin); m_positiveMargin = p; }
211         void setNegativeMargin(LayoutUnit n) { ASSERT(!m_discardMargin); m_negativeMargin = n; }
212         void setPositiveMarginIfLarger(LayoutUnit p)
213         {
214             ASSERT(!m_discardMargin);
215             if (p > m_positiveMargin)
216                 m_positiveMargin = p;
217         }
218         void setNegativeMarginIfLarger(LayoutUnit n)
219         {
220             ASSERT(!m_discardMargin);
221             if (n > m_negativeMargin)
222                 m_negativeMargin = n;
223         }
224
225         void setMargin(LayoutUnit p, LayoutUnit n) { ASSERT(!m_discardMargin); m_positiveMargin = p; m_negativeMargin = n; }
226         void setCanCollapseMarginAfterWithChildren(bool collapse) { m_canCollapseMarginAfterWithChildren = collapse; }
227         void setDiscardMargin(bool value) { m_discardMargin = value; }
228
229         bool atBeforeSideOfBlock() const { return m_atBeforeSideOfBlock; }
230         bool canCollapseWithMarginBefore() const { return m_atBeforeSideOfBlock && m_canCollapseMarginBeforeWithChildren; }
231         bool canCollapseWithMarginAfter() const { return m_atAfterSideOfBlock && m_canCollapseMarginAfterWithChildren; }
232         bool canCollapseMarginBeforeWithChildren() const { return m_canCollapseMarginBeforeWithChildren; }
233         bool canCollapseMarginAfterWithChildren() const { return m_canCollapseMarginAfterWithChildren; }
234         bool quirkContainer() const { return m_quirkContainer; }
235         bool determinedMarginBeforeQuirk() const { return m_determinedMarginBeforeQuirk; }
236         bool hasMarginBeforeQuirk() const { return m_hasMarginBeforeQuirk; }
237         bool hasMarginAfterQuirk() const { return m_hasMarginAfterQuirk; }
238         LayoutUnit positiveMargin() const { return m_positiveMargin; }
239         LayoutUnit negativeMargin() const { return m_negativeMargin; }
240         bool discardMargin() const { return m_discardMargin; }
241         LayoutUnit margin() const { return m_positiveMargin - m_negativeMargin; }
242     };
243     LayoutUnit marginOffsetForSelfCollapsingBlock();
244
245     void layoutBlockChild(RenderBox& child, MarginInfo&, LayoutUnit& previousFloatLogicalBottom, LayoutUnit& maxFloatLogicalBottom);
246     void adjustPositionedBlock(RenderBox& child, const MarginInfo&);
247     void adjustFloatingBlock(const MarginInfo&);
248
249     void setStaticInlinePositionForChild(RenderBox& child, LayoutUnit blockOffset, LayoutUnit inlinePosition);
250     void updateStaticInlinePositionForChild(RenderBox& child, LayoutUnit logicalTop, IndentTextOrNot shouldIndentText);
251
252     LayoutUnit collapseMargins(RenderBox& child, MarginInfo&);
253     LayoutUnit collapseMarginsWithChildInfo(RenderBox* child, RenderObject* prevSibling, MarginInfo&);
254
255     LayoutUnit clearFloatsIfNeeded(RenderBox& child, MarginInfo&, LayoutUnit oldTopPosMargin, LayoutUnit oldTopNegMargin, LayoutUnit yPos);
256     LayoutUnit estimateLogicalTopPosition(RenderBox& child, const MarginInfo&, LayoutUnit& estimateWithoutPagination);
257     void marginBeforeEstimateForChild(RenderBox&, LayoutUnit&, LayoutUnit&, bool&) const;
258     void handleAfterSideOfBlock(LayoutUnit top, LayoutUnit bottom, MarginInfo&);
259     void setCollapsedBottomMargin(const MarginInfo&);
260
261     bool childrenPreventSelfCollapsing() const final;
262
263     bool shouldBreakAtLineToAvoidWidow() const { return hasRareBlockFlowData() && rareBlockFlowData()->m_lineBreakToAvoidWidow >= 0; }
264     void clearShouldBreakAtLineToAvoidWidow() const;
265     int lineBreakToAvoidWidow() const { return hasRareBlockFlowData() ? rareBlockFlowData()->m_lineBreakToAvoidWidow : -1; }
266     void setBreakAtLineToAvoidWidow(int);
267     void clearDidBreakAtLineToAvoidWidow();
268     void setDidBreakAtLineToAvoidWidow();
269     bool didBreakAtLineToAvoidWidow() const { return hasRareBlockFlowData() && rareBlockFlowData()->m_didBreakAtLineToAvoidWidow; }
270     bool relayoutToAvoidWidows(LayoutStateMaintainer&);
271
272     bool canHaveGeneratedChildren() const override;
273
274     RootInlineBox* lineGridBox() const { return hasRareBlockFlowData() ? rareBlockFlowData()->m_lineGridBox.get() : nullptr; }
275     void setLineGridBox(std::unique_ptr<RootInlineBox> box)
276     {
277         ensureRareBlockFlowData().m_lineGridBox = WTFMove(box);
278     }
279     void layoutLineGridBox();
280
281     bool canDropAnonymousBlockChild() const override { return !renderNamedFlowFragment(); }
282     RenderNamedFlowFragment* renderNamedFlowFragment() const { return hasRareBlockFlowData() ? rareBlockFlowData()->m_renderNamedFlowFragment : nullptr; }
283     void setRenderNamedFlowFragment(RenderNamedFlowFragment*);
284
285     RenderMultiColumnFlowThread* multiColumnFlowThread() const { return hasRareBlockFlowData() ? rareBlockFlowData()->m_multiColumnFlowThread : nullptr; }
286     void setMultiColumnFlowThread(RenderMultiColumnFlowThread*);
287     
288     bool containsFloats() const override { return m_floatingObjects && !m_floatingObjects->set().isEmpty(); }
289     bool containsFloat(RenderBox&) const;
290
291     void deleteLines() override;
292     void computeOverflow(LayoutUnit oldClientAfterEdge, bool recomputeFloats = false) override;
293     VisiblePosition positionForPoint(const LayoutPoint&, const RenderRegion*) override;
294
295     void removeFloatingObjects();
296     void markAllDescendantsWithFloatsForLayout(RenderBox* floatToRemove = nullptr, bool inLayout = true);
297     void markSiblingsWithFloatsForLayout(RenderBox* floatToRemove = nullptr);
298
299     const FloatingObjectSet* floatingObjectSet() const { return m_floatingObjects ? &m_floatingObjects->set() : nullptr; }
300
301     LayoutUnit logicalTopForFloat(const FloatingObject& floatingObject) const { return isHorizontalWritingMode() ? floatingObject.y() : floatingObject.x(); }
302     LayoutUnit logicalBottomForFloat(const FloatingObject& floatingObject) const { return isHorizontalWritingMode() ? floatingObject.maxY() : floatingObject.maxX(); }
303     LayoutUnit logicalLeftForFloat(const FloatingObject& floatingObject) const { return isHorizontalWritingMode() ? floatingObject.x() : floatingObject.y(); }
304     LayoutUnit logicalRightForFloat(const FloatingObject& floatingObject) const { return isHorizontalWritingMode() ? floatingObject.maxX() : floatingObject.maxY(); }
305     LayoutUnit logicalWidthForFloat(const FloatingObject& floatingObject) const { return isHorizontalWritingMode() ? floatingObject.width() : floatingObject.height(); }
306     LayoutUnit logicalHeightForFloat(const FloatingObject& floatingObject) const { return isHorizontalWritingMode() ? floatingObject.height() : floatingObject.width(); }
307
308     void setLogicalTopForFloat(FloatingObject& floatingObject, LayoutUnit logicalTop)
309     {
310         if (isHorizontalWritingMode())
311             floatingObject.setY(logicalTop);
312         else
313             floatingObject.setX(logicalTop);
314     }
315     void setLogicalLeftForFloat(FloatingObject& floatingObject, LayoutUnit logicalLeft)
316     {
317         if (isHorizontalWritingMode())
318             floatingObject.setX(logicalLeft);
319         else
320             floatingObject.setY(logicalLeft);
321     }
322     void setLogicalHeightForFloat(FloatingObject& floatingObject, LayoutUnit logicalHeight)
323     {
324         if (isHorizontalWritingMode())
325             floatingObject.setHeight(logicalHeight);
326         else
327             floatingObject.setWidth(logicalHeight);
328     }
329     void setLogicalWidthForFloat(FloatingObject& floatingObject, LayoutUnit logicalWidth)
330     {
331         if (isHorizontalWritingMode())
332             floatingObject.setWidth(logicalWidth);
333         else
334             floatingObject.setHeight(logicalWidth);
335     }
336
337     LayoutUnit xPositionForFloatIncludingMargin(const FloatingObject& floatingObject) const { return isHorizontalWritingMode() ? floatingObject.x() + floatingObject.renderer().marginLeft() : floatingObject.x() + marginBeforeForChild(floatingObject.renderer()); }
338     LayoutUnit yPositionForFloatIncludingMargin(const FloatingObject& floatingObject) const { return isHorizontalWritingMode() ? floatingObject.y() + marginBeforeForChild(floatingObject.renderer()) : floatingObject.y() + floatingObject.renderer().marginTop(); }
339
340     LayoutPoint flipFloatForWritingModeForChild(const FloatingObject&, const LayoutPoint&) const;
341
342     RenderLineBoxList& lineBoxes() { return m_lineBoxes; }
343     const RenderLineBoxList& lineBoxes() const { return m_lineBoxes; }
344
345     RootInlineBox* firstRootBox() const { return downcast<RootInlineBox>(m_lineBoxes.firstLineBox()); }
346     RootInlineBox* lastRootBox() const { return downcast<RootInlineBox>(m_lineBoxes.lastLineBox()); }
347
348     bool hasLines() const;
349     void invalidateLineLayoutPath() final;
350
351     enum LineLayoutPath { UndeterminedPath = 0, SimpleLinesPath, LineBoxesPath, ForceLineBoxesPath };
352     LineLayoutPath lineLayoutPath() const { return static_cast<LineLayoutPath>(renderBlockFlowLineLayoutPath()); }
353     void setLineLayoutPath(LineLayoutPath path) { setRenderBlockFlowLineLayoutPath(path); }
354
355     // Helper methods for computing line counts and heights for line counts.
356     RootInlineBox* lineAtIndex(int) const;
357     int lineCount(const RootInlineBox* = nullptr, bool* = nullptr) const;
358     int heightForLineCount(int);
359     void clearTruncation();
360
361     void setHasMarkupTruncation(bool b) { setRenderBlockFlowHasMarkupTruncation(b); }
362     bool hasMarkupTruncation() const { return renderBlockFlowHasMarkupTruncation(); }
363
364     bool containsNonZeroBidiLevel() const;
365
366     const SimpleLineLayout::Layout* simpleLineLayout() const;
367     void deleteLineBoxesBeforeSimpleLineLayout();
368     void ensureLineBoxes();
369
370 #if ENABLE(TREE_DEBUGGING)
371     void showLineTreeAndMark(const InlineBox* markedBox, int depth) const;
372 #endif
373
374     // Returns the logicalOffset at the top of the next page. If the offset passed in is already at the top of the current page,
375     // then nextPageLogicalTop with ExcludePageBoundary will still move to the top of the next page. nextPageLogicalTop with
376     // IncludePageBoundary set will not.
377     //
378     // For a page height of 800px, the first rule will return 800 if the value passed in is 0. The second rule will simply return 0.
379     enum PageBoundaryRule { ExcludePageBoundary, IncludePageBoundary };
380     LayoutUnit nextPageLogicalTop(LayoutUnit logicalOffset, PageBoundaryRule = ExcludePageBoundary) const;
381     LayoutUnit pageLogicalTopForOffset(LayoutUnit offset) const;
382     LayoutUnit pageLogicalHeightForOffset(LayoutUnit offset) const;
383     LayoutUnit pageRemainingLogicalHeightForOffset(LayoutUnit offset, PageBoundaryRule = IncludePageBoundary) const;
384     LayoutUnit logicalHeightForChildForFragmentation(const RenderBox& child) const;
385     bool hasNextPage(LayoutUnit logicalOffset, PageBoundaryRule = ExcludePageBoundary) const;
386
387     void addChild(RenderObject* newChild, RenderObject* beforeChild = 0) override;
388     void removeChild(RenderObject&) override;
389
390     void createMultiColumnFlowThread();
391     void destroyMultiColumnFlowThread();
392
393     void updateColumnProgressionFromStyle(RenderStyle&);
394     void updateStylesForColumnChildren();
395
396     bool needsLayoutAfterRegionRangeChange() const override;
397     WEBCORE_EXPORT RenderText* findClosestTextAtAbsolutePoint(const FloatPoint&);
398
399 protected:
400     void computeIntrinsicLogicalWidths(LayoutUnit& minLogicalWidth, LayoutUnit& maxLogicalWidth) const override;
401     
402     // A page break is required at some offset due to space shortage in the current fragmentainer.
403     void setPageBreak(LayoutUnit offset, LayoutUnit spaceShortage);
404
405     // Update minimum page height required to avoid fragmentation where it shouldn't occur (inside
406     // unbreakable content, between orphans and widows, etc.). This will be used as a hint to the
407     // column balancer to help set a good minimum column height.
408     void updateMinimumPageHeight(LayoutUnit offset, LayoutUnit minHeight);
409     bool pushToNextPageWithMinimumLogicalHeight(LayoutUnit& adjustment, LayoutUnit logicalOffset, LayoutUnit minimumLogicalHeight) const;
410
411     // If the child is unsplittable and can't fit on the current page, return the top of the next page/column.
412     LayoutUnit adjustForUnsplittableChild(RenderBox& child, LayoutUnit logicalOffset, bool includeMargins = false);
413     LayoutUnit adjustBlockChildForPagination(LayoutUnit logicalTopAfterClear, LayoutUnit estimateWithoutPagination, RenderBox& child, bool atBeforeSideOfBlock);
414     LayoutUnit applyBeforeBreak(RenderBox& child, LayoutUnit logicalOffset); // If the child has a before break, then return a new yPos that shifts to the top of the next page/column.
415     LayoutUnit applyAfterBreak(RenderBox& child, LayoutUnit logicalOffset, MarginInfo&); // If the child has an after break, then return a new offset that shifts to the top of the next page/column.
416
417     LayoutUnit maxPositiveMarginBefore() const { return hasRareBlockFlowData() ? rareBlockFlowData()->m_margins.positiveMarginBefore() : RenderBlockFlowRareData::positiveMarginBeforeDefault(*this); }
418     LayoutUnit maxNegativeMarginBefore() const { return hasRareBlockFlowData() ? rareBlockFlowData()->m_margins.negativeMarginBefore() : RenderBlockFlowRareData::negativeMarginBeforeDefault(*this); }
419     LayoutUnit maxPositiveMarginAfter() const { return hasRareBlockFlowData() ? rareBlockFlowData()->m_margins.positiveMarginAfter() : RenderBlockFlowRareData::positiveMarginAfterDefault(*this); }
420     LayoutUnit maxNegativeMarginAfter() const { return hasRareBlockFlowData() ? rareBlockFlowData()->m_margins.negativeMarginAfter() : RenderBlockFlowRareData::negativeMarginAfterDefault(*this); }
421
422     void initMaxMarginValues()
423     {
424         if (!hasRareBlockFlowData())
425             return;
426
427         rareBlockFlowData()->m_margins = MarginValues(RenderBlockFlowRareData::positiveMarginBeforeDefault(*this) , RenderBlockFlowRareData::negativeMarginBeforeDefault(*this),
428             RenderBlockFlowRareData::positiveMarginAfterDefault(*this), RenderBlockFlowRareData::negativeMarginAfterDefault(*this));
429         rareBlockFlowData()->m_discardMarginBefore = false;
430         rareBlockFlowData()->m_discardMarginAfter = false;
431     }
432
433     void setMaxMarginBeforeValues(LayoutUnit pos, LayoutUnit neg);
434     void setMaxMarginAfterValues(LayoutUnit pos, LayoutUnit neg);
435
436     void setMustDiscardMarginBefore(bool = true);
437     void setMustDiscardMarginAfter(bool = true);
438
439     bool mustDiscardMarginBefore() const;
440     bool mustDiscardMarginAfter() const;
441
442     bool mustDiscardMarginBeforeForChild(const RenderBox&) const;
443     bool mustDiscardMarginAfterForChild(const RenderBox&) const;
444     bool mustSeparateMarginBeforeForChild(const RenderBox&) const;
445     bool mustSeparateMarginAfterForChild(const RenderBox&) const;
446
447     void styleWillChange(StyleDifference, const RenderStyle& newStyle) override;
448     void styleDidChange(StyleDifference, const RenderStyle* oldStyle) override;
449
450     void createFloatingObjects();
451
452     Optional<int> firstLineBaseline() const override;
453     Optional<int> inlineBlockBaseline(LineDirectionMode) const override;
454
455     bool isMultiColumnBlockFlow() const override { return multiColumnFlowThread(); }
456     
457     void setComputedColumnCountAndWidth(int, LayoutUnit);
458
459     LayoutUnit computedColumnWidth() const;
460     unsigned computedColumnCount() const;
461     
462     bool isTopLayoutOverflowAllowed() const override;
463     bool isLeftLayoutOverflowAllowed() const override;
464
465     void moveFloatsTo(RenderBlockFlow* toBlock);
466     
467     virtual void computeColumnCountAndWidth();
468     virtual bool requiresColumns(int) const;
469     
470     virtual void cachePriorCharactersIfNeeded(const LazyLineBreakIterator&) {};
471     
472 private:
473     bool recomputeLogicalWidthAndColumnWidth();
474     LayoutUnit columnGap() const;
475     
476     RenderBlockFlow* previousSiblingWithOverhangingFloats(bool& parentHasFloats) const;
477
478     // Called to lay out the legend for a fieldset or the ruby text of a ruby run. Also used by multi-column layout to handle
479     // the flow thread child.
480     virtual RenderObject* layoutSpecialExcludedChild(bool /*relayoutChildren*/);
481
482     void checkForPaginationLogicalHeightChange(bool& relayoutChildren, LayoutUnit& pageLogicalHeight, bool& pageLogicalHeightChanged);
483     
484     void paintInlineChildren(PaintInfo&, const LayoutPoint&) override;
485     void paintFloats(PaintInfo&, const LayoutPoint&, bool preservePhase = false) override;
486
487     void moveAllChildrenIncludingFloatsTo(RenderBlock& toBlock, bool fullRemoveInsert) override;
488     void repaintOverhangingFloats(bool paintAllDescendants) final;
489     void clipOutFloatingObjects(RenderBlock&, const PaintInfo*, const LayoutPoint&, const LayoutSize&) override;
490
491     FloatingObject* insertFloatingObject(RenderBox&);
492     void removeFloatingObject(RenderBox&);
493     void removeFloatingObjectsBelow(FloatingObject*, int logicalOffset);
494     LayoutPoint computeLogicalLocationForFloat(const FloatingObject&, LayoutUnit logicalTopOffset);
495
496     // Called from lineWidth, to position the floats added in the last line.
497     // Returns true if and only if it has positioned any floats.
498     bool positionNewFloats();
499
500     void clearFloats(EClear);
501
502     LayoutUnit logicalRightFloatOffsetForLine(LayoutUnit logicalTop, LayoutUnit fixedOffset, LayoutUnit logicalHeight) const override;
503     LayoutUnit logicalLeftFloatOffsetForLine(LayoutUnit logicalTop, LayoutUnit fixedOffset, LayoutUnit logicalHeight) const override;
504
505     LayoutUnit logicalRightOffsetForPositioningFloat(LayoutUnit logicalTop, LayoutUnit fixedOffset, bool applyTextIndent, LayoutUnit* heightRemaining) const;
506     LayoutUnit logicalLeftOffsetForPositioningFloat(LayoutUnit logicalTop, LayoutUnit fixedOffset, bool applyTextIndent, LayoutUnit* heightRemaining) const;
507
508     LayoutUnit lowestInitialLetterLogicalBottom() const;
509     
510     LayoutUnit lowestFloatLogicalBottom(FloatingObject::Type = FloatingObject::FloatLeftRight) const; 
511     LayoutUnit nextFloatLogicalBottomBelow(LayoutUnit) const;
512     LayoutUnit nextFloatLogicalBottomBelowForBlock(LayoutUnit) const;
513     
514     LayoutUnit addOverhangingFloats(RenderBlockFlow& child, bool makeChildPaintOtherFloats);
515     bool hasOverhangingFloat(RenderBox&);
516     void addIntrudingFloats(RenderBlockFlow* prev, RenderBlockFlow* container, LayoutUnit xoffset, LayoutUnit yoffset);
517     bool hasOverhangingFloats() { return parent() && containsFloats() && lowestFloatLogicalBottom() > logicalHeight(); }
518     LayoutUnit getClearDelta(RenderBox& child, LayoutUnit yPos);
519
520     void determineLogicalLeftPositionForChild(RenderBox& child, ApplyLayoutDeltaMode = DoNotApplyLayoutDelta);
521     
522     bool hitTestFloats(const HitTestRequest&, HitTestResult&, const HitTestLocation& locationInContainer, const LayoutPoint& accumulatedOffset) override;
523     bool hitTestInlineChildren(const HitTestRequest&, HitTestResult&, const HitTestLocation& locationInContainer, const LayoutPoint& accumulatedOffset, HitTestAction) override;
524
525     void addOverflowFromFloats();
526     void addOverflowFromInlineChildren() override;
527     
528     void fitBorderToLinesIfNeeded(); // Shrink the box in which the border paints if border-fit is set.
529     void adjustForBorderFit(LayoutUnit x, LayoutUnit& left, LayoutUnit& right) const;
530
531     void markLinesDirtyInBlockRange(LayoutUnit logicalTop, LayoutUnit logicalBottom, RootInlineBox* highest = 0);
532
533     GapRects inlineSelectionGaps(RenderBlock& rootBlock, const LayoutPoint& rootBlockPhysicalPosition, const LayoutSize& offsetFromRootBlock,
534         LayoutUnit& lastLogicalTop, LayoutUnit& lastLogicalLeft, LayoutUnit& lastLogicalRight, const LogicalSelectionOffsetCaches&, const PaintInfo*) override;
535     
536     Position positionForBox(InlineBox*, bool start = true) const;
537     VisiblePosition positionForPointWithInlineChildren(const LayoutPoint& pointInLogicalContents, const RenderRegion*) override;
538     void addFocusRingRectsForInlineChildren(Vector<LayoutRect>& rects, const LayoutPoint& additionalOffset, const RenderLayerModelObject*) override;
539
540 // FIXME-BLOCKFLOW: These methods have implementations in
541 // RenderBlockLineLayout. They should be moved to the proper header once the
542 // line layout code is separated from RenderBlock and RenderBlockFlow.
543 // START METHODS DEFINED IN RenderBlockLineLayout
544 public:
545     static void appendRunsForObject(BidiRunList<BidiRun>*, int start, int end, RenderObject&, InlineBidiResolver&);
546     RootInlineBox* createAndAppendRootInlineBox();
547
548     LayoutUnit startAlignedOffsetForLine(LayoutUnit position, IndentTextOrNot shouldIndentText);
549     virtual ETextAlign textAlignmentForLine(bool endsWithSoftBreak) const;
550     virtual void adjustInlineDirectionLineBounds(int /* expansionOpportunityCount */, float& /* logicalLeft */, float& /* logicalWidth */) const { }
551
552 private:        
553     void adjustIntrinsicLogicalWidthsForColumns(LayoutUnit& minLogicalWidth, LayoutUnit& maxLogicalWidth) const;
554
555     void layoutLineBoxes(bool relayoutChildren, LayoutUnit& repaintLogicalTop, LayoutUnit& repaintLogicalBottom);
556     void layoutSimpleLines(bool relayoutChildren, LayoutUnit& repaintLogicalTop, LayoutUnit& repaintLogicalBottom);
557
558     virtual std::unique_ptr<RootInlineBox> createRootInlineBox(); // Subclassed by RenderSVGText.
559     InlineFlowBox* createLineBoxes(RenderObject*, const LineInfo&, InlineBox* childBox);
560     RootInlineBox* constructLine(BidiRunList<BidiRun>&, const LineInfo&);
561     void setMarginsForRubyRun(BidiRun*, RenderRubyRun&, RenderObject*, const LineInfo&);
562     void computeInlineDirectionPositionsForLine(RootInlineBox*, const LineInfo&, BidiRun* firstRun, BidiRun* trailingSpaceRun, bool reachedEnd, GlyphOverflowAndFallbackFontsMap&, VerticalPositionCache&, WordMeasurements&);
563     void updateRubyForJustifiedText(RenderRubyRun&, BidiRun&, const Vector<unsigned, 16>& expansionOpportunities, unsigned& expansionOpportunityCount, float& totalLogicalWidth, float availableLogicalWidth, size_t& expansionIndex);
564     void computeExpansionForJustifiedText(BidiRun* firstRun, BidiRun* trailingSpaceRun, const Vector<unsigned, 16>& expansionOpportunities, unsigned expansionOpportunityCount, float totalLogicalWidth, float availableLogicalWidth);
565     BidiRun* computeInlineDirectionPositionsForSegment(RootInlineBox*, const LineInfo&, ETextAlign, float& logicalLeft,
566         float& availableLogicalWidth, BidiRun* firstRun, BidiRun* trailingSpaceRun, GlyphOverflowAndFallbackFontsMap& textBoxDataMap, VerticalPositionCache&, WordMeasurements&);
567     void computeBlockDirectionPositionsForLine(RootInlineBox*, BidiRun*, GlyphOverflowAndFallbackFontsMap&, VerticalPositionCache&);
568     BidiRun* handleTrailingSpaces(BidiRunList<BidiRun>&, BidiContext*);
569     void appendFloatingObjectToLastLine(FloatingObject&);
570     // Helper function for layoutInlineChildren()
571     RootInlineBox* createLineBoxesFromBidiRuns(unsigned bidiLevel, BidiRunList<BidiRun>&, const InlineIterator& end, LineInfo&, VerticalPositionCache&, BidiRun* trailingSpaceRun, WordMeasurements&);
572     void layoutRunsAndFloats(LineLayoutState&, bool hasInlineChild);
573     const InlineIterator& restartLayoutRunsAndFloatsInRange(LayoutUnit oldLogicalHeight, LayoutUnit newLogicalHeight,  FloatingObject* lastFloatFromPreviousLine, InlineBidiResolver&,  const InlineIterator&);
574     void layoutRunsAndFloatsInRange(LineLayoutState&, InlineBidiResolver&, const InlineIterator& cleanLineStart, const BidiStatus& cleanLineBidiStatus, unsigned consecutiveHyphenatedLines);
575     void reattachCleanLineFloats(RootInlineBox& cleanLine, LayoutUnit delta, bool isFirstCleanLine);
576     void linkToEndLineIfNeeded(LineLayoutState&);
577     void checkFloatInCleanLine(RootInlineBox& cleanLine, RenderBox& floatBoxOnCleanLine, FloatWithRect& matchingFloatWithRect,
578         bool& encounteredNewFloat, bool& dirtiedByFloat);
579     RootInlineBox* determineStartPosition(LineLayoutState&, InlineBidiResolver&);
580     void determineEndPosition(LineLayoutState&, RootInlineBox* startBox, InlineIterator& cleanLineStart, BidiStatus& cleanLineBidiStatus);
581     bool checkPaginationAndFloatsAtEndLine(LineLayoutState&);
582     bool matchedEndLine(LineLayoutState&, const InlineBidiResolver&, const InlineIterator& endLineStart, const BidiStatus& endLineStatus);
583     void deleteEllipsisLineBoxes();
584     void checkLinesForTextOverflow();
585     // Positions new floats and also adjust all floats encountered on the line if any of them
586     // have to move to the next page/column.
587     bool positionNewFloatOnLine(const FloatingObject& newFloat, FloatingObject* lastFloatFromPreviousLine, LineInfo&, LineWidth&);
588     // This function is called to test a line box that has moved in the block direction to see if it has ended up in a new
589     // region/page/column that has a different available line width than the old one. Used to know when you have to dirty a
590     // line, i.e., that it can't be re-used.
591     bool lineWidthForPaginatedLineChanged(RootInlineBox*, LayoutUnit lineDelta, RenderFlowThread*) const;
592     void updateLogicalWidthForAlignment(const ETextAlign&, const RootInlineBox*, BidiRun* trailingSpaceRun, float& logicalLeft, float& totalLogicalWidth, float& availableLogicalWidth, int expansionOpportunityCount);
593     void marginCollapseLinesFromStart(LineLayoutState&, RootInlineBox* stopLine);
594 // END METHODS DEFINED IN RenderBlockLineLayout
595
596     bool namedFlowFragmentNeedsUpdate() const;
597     bool canHaveChildren() const override;
598
599     void computeInlinePreferredLogicalWidths(LayoutUnit& minLogicalWidth, LayoutUnit& maxLogicalWidth) const;
600
601 #if ENABLE(TEXT_AUTOSIZING)
602     int m_widthForTextAutosizing;
603     unsigned m_lineCountForTextAutosizing : 2;
604 #endif
605     void setSelectionState(SelectionState) final;
606
607     void removeInlineBox(BidiRun&, const RootInlineBox&) const;
608
609 public:
610     // FIXME-BLOCKFLOW: These can be made protected again once all callers have been moved here.
611     void adjustLinePositionForPagination(RootInlineBox*, LayoutUnit& deltaOffset, bool& overflowsRegion, RenderFlowThread*); // Computes a deltaOffset value that put a line at the top of the next page if it doesn't fit on the current page.
612     void updateRegionForLine(RootInlineBox*) const;
613     void createRenderNamedFlowFragmentIfNeeded();
614
615     // Pagination routines.
616     bool relayoutForPagination(LayoutStateMaintainer&);
617
618     bool hasRareBlockFlowData() const { return m_rareBlockFlowData.get(); }
619     RenderBlockFlowRareData* rareBlockFlowData() const { ASSERT_WITH_SECURITY_IMPLICATION(hasRareBlockFlowData()); return m_rareBlockFlowData.get(); }
620     RenderBlockFlowRareData& ensureRareBlockFlowData();
621     void materializeRareBlockFlowData();
622
623 #if ENABLE(TEXT_AUTOSIZING)
624     int lineCountForTextAutosizing();
625     void adjustComputedFontSizes(float size, float visibleWidth);
626     void resetComputedFontSize()
627     {
628         m_widthForTextAutosizing = -1;
629         m_lineCountForTextAutosizing = NOT_SET;
630     }
631 #endif
632
633 protected:
634     std::unique_ptr<FloatingObjects> m_floatingObjects;
635     std::unique_ptr<RenderBlockFlowRareData> m_rareBlockFlowData;
636     RenderLineBoxList m_lineBoxes;
637     std::unique_ptr<SimpleLineLayout::Layout> m_simpleLineLayout;
638
639     friend class LineBreaker;
640     friend class LineWidth; // Needs to know FloatingObject
641 };
642
643 inline bool RenderElement::isRenderNamedFlowFragmentContainer() const
644 {
645     return is<RenderBlockFlow>(*this) && downcast<RenderBlockFlow>(*this).renderNamedFlowFragment();
646 }
647
648 inline const SimpleLineLayout::Layout* RenderBlockFlow::simpleLineLayout() const
649 {
650     ASSERT(lineLayoutPath() == SimpleLinesPath || !m_simpleLineLayout);
651     return m_simpleLineLayout.get();
652 }
653
654 } // namespace WebCore
655
656 SPECIALIZE_TYPE_TRAITS_RENDER_OBJECT(RenderBlockFlow, isRenderBlockFlow())
657
658 #endif // RenderBlockFlow_h