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