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