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