• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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  * Copyright (C) Research In Motion Limited 2010. All rights reserved.
7  * Copyright (C) 2013 Google Inc. All rights reserved.
8  *
9  * Redistribution and use in source and binary forms, with or without
10  * modification, are permitted provided that the following conditions are
11  * met:
12  *
13  *     * Redistributions of source code must retain the above copyright
14  * notice, this list of conditions and the following disclaimer.
15  *     * Redistributions in binary form must reproduce the above
16  * copyright notice, this list of conditions and the following disclaimer
17  * in the documentation and/or other materials provided with the
18  * distribution.
19  *     * Neither the name of Google Inc. nor the names of its
20  * contributors may be used to endorse or promote products derived from
21  * this software without specific prior written permission.
22  *
23  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
24  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
25  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
26  * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
27  * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
28  * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
29  * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
30  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
31  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
32  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
33  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
34  */
35 
36 #ifndef RenderBlockFlow_h
37 #define RenderBlockFlow_h
38 
39 #include "core/rendering/FloatingObjects.h"
40 #include "core/rendering/RenderBlock.h"
41 #include "core/rendering/line/TrailingObjects.h"
42 #include "core/rendering/style/RenderStyleConstants.h"
43 
44 namespace blink {
45 
46 class MarginInfo;
47 class LineBreaker;
48 class LineWidth;
49 class RenderMultiColumnFlowThread;
50 
51 class RenderBlockFlow : public RenderBlock {
52 public:
53     explicit RenderBlockFlow(ContainerNode*);
54     virtual ~RenderBlockFlow();
55     virtual void trace(Visitor*) OVERRIDE;
56 
57     static RenderBlockFlow* createAnonymous(Document*);
58 
isRenderBlockFlow()59     virtual bool isRenderBlockFlow() const OVERRIDE FINAL { return true; }
60 
61     virtual void layoutBlock(bool relayoutChildren) OVERRIDE;
62 
63     virtual void computeOverflow(LayoutUnit oldClientAfterEdge, bool recomputeFloats = false) OVERRIDE;
64 
65     virtual void deleteLineBoxTree() OVERRIDE FINAL;
66 
67     LayoutUnit availableLogicalWidthForLine(LayoutUnit position, bool shouldIndentText, LayoutUnit logicalHeight = 0) const
68     {
69         return max<LayoutUnit>(0, logicalRightOffsetForLine(position, shouldIndentText, logicalHeight) - logicalLeftOffsetForLine(position, shouldIndentText, logicalHeight));
70     }
71     LayoutUnit logicalRightOffsetForLine(LayoutUnit position, bool shouldIndentText, LayoutUnit logicalHeight = 0) const
72     {
73         return logicalRightOffsetForLine(position, logicalRightOffsetForContent(), shouldIndentText, logicalHeight);
74     }
75     LayoutUnit logicalLeftOffsetForLine(LayoutUnit position, bool shouldIndentText, LayoutUnit logicalHeight = 0) const
76     {
77         return logicalLeftOffsetForLine(position, logicalLeftOffsetForContent(), shouldIndentText, logicalHeight);
78     }
79     LayoutUnit startOffsetForLine(LayoutUnit position, bool shouldIndentText, LayoutUnit logicalHeight = 0) const
80     {
81         return style()->isLeftToRightDirection() ? logicalLeftOffsetForLine(position, shouldIndentText, logicalHeight)
82             : logicalWidth() - logicalRightOffsetForLine(position, shouldIndentText, logicalHeight);
83     }
84     LayoutUnit endOffsetForLine(LayoutUnit position, bool shouldIndentText, LayoutUnit logicalHeight = 0) const
85     {
86         return !style()->isLeftToRightDirection() ? logicalLeftOffsetForLine(position, shouldIndentText, logicalHeight)
87             : logicalWidth() - logicalRightOffsetForLine(position, shouldIndentText, logicalHeight);
88     }
89 
90     // FIXME-BLOCKFLOW: Move this into RenderBlockFlow once there are no calls
91     // in RenderBlock. http://crbug.com/393945, http://crbug.com/302024
92     using RenderBlock::lineBoxes;
93     using RenderBlock::firstLineBox;
94     using RenderBlock::lastLineBox;
95     using RenderBlock::firstRootBox;
96     using RenderBlock::lastRootBox;
97 
98     virtual LayoutUnit logicalLeftSelectionOffset(const RenderBlock* rootBlock, LayoutUnit position) const OVERRIDE;
99     virtual LayoutUnit logicalRightSelectionOffset(const RenderBlock* rootBlock, LayoutUnit position) const OVERRIDE;
100 
101     RootInlineBox* createAndAppendRootInlineBox();
102 
103     void markAllDescendantsWithFloatsForLayout(RenderBox* floatToRemove = 0, bool inLayout = true);
104     void markSiblingsWithFloatsForLayout(RenderBox* floatToRemove = 0);
105 
containsFloats()106     bool containsFloats() const { return m_floatingObjects && !m_floatingObjects->set().isEmpty(); }
107     bool containsFloat(RenderBox*) const;
108 
109     void removeFloatingObjects();
110 
111     virtual void addChild(RenderObject* newChild, RenderObject* beforeChild = 0) OVERRIDE;
112 
113     void moveAllChildrenIncludingFloatsTo(RenderBlock* toBlock, bool fullRemoveInsert);
114 
115     bool generatesLineBoxesForInlineChild(RenderObject*);
116 
logicalTopForFloat(const FloatingObject * floatingObject)117     LayoutUnit logicalTopForFloat(const FloatingObject* floatingObject) const { return isHorizontalWritingMode() ? floatingObject->y() : floatingObject->x(); }
logicalBottomForFloat(const FloatingObject * floatingObject)118     LayoutUnit logicalBottomForFloat(const FloatingObject* floatingObject) const { return isHorizontalWritingMode() ? floatingObject->maxY() : floatingObject->maxX(); }
logicalLeftForFloat(const FloatingObject * floatingObject)119     LayoutUnit logicalLeftForFloat(const FloatingObject* floatingObject) const { return isHorizontalWritingMode() ? floatingObject->x() : floatingObject->y(); }
logicalRightForFloat(const FloatingObject * floatingObject)120     LayoutUnit logicalRightForFloat(const FloatingObject* floatingObject) const { return isHorizontalWritingMode() ? floatingObject->maxX() : floatingObject->maxY(); }
logicalWidthForFloat(const FloatingObject * floatingObject)121     LayoutUnit logicalWidthForFloat(const FloatingObject* floatingObject) const { return isHorizontalWritingMode() ? floatingObject->width() : floatingObject->height(); }
logicalHeightForFloat(const FloatingObject * floatingObject)122     LayoutUnit logicalHeightForFloat(const FloatingObject* floatingObject) const { return isHorizontalWritingMode() ? floatingObject->height() : floatingObject->width(); }
logicalSizeForFloat(const FloatingObject * floatingObject)123     LayoutSize logicalSizeForFloat(const FloatingObject* floatingObject) const { return isHorizontalWritingMode() ? LayoutSize(floatingObject->width(), floatingObject->height()) : LayoutSize(floatingObject->height(), floatingObject->width()); }
124 
pixelSnappedLogicalTopForFloat(const FloatingObject * floatingObject)125     int pixelSnappedLogicalTopForFloat(const FloatingObject* floatingObject) const { return isHorizontalWritingMode() ? floatingObject->frameRect().pixelSnappedY() : floatingObject->frameRect().pixelSnappedX(); }
pixelSnappedLogicalBottomForFloat(const FloatingObject * floatingObject)126     int pixelSnappedLogicalBottomForFloat(const FloatingObject* floatingObject) const { return isHorizontalWritingMode() ? floatingObject->frameRect().pixelSnappedMaxY() : floatingObject->frameRect().pixelSnappedMaxX(); }
pixelSnappedLogicalLeftForFloat(const FloatingObject * floatingObject)127     int pixelSnappedLogicalLeftForFloat(const FloatingObject* floatingObject) const { return isHorizontalWritingMode() ? floatingObject->frameRect().pixelSnappedX() : floatingObject->frameRect().pixelSnappedY(); }
pixelSnappedLogicalRightForFloat(const FloatingObject * floatingObject)128     int pixelSnappedLogicalRightForFloat(const FloatingObject* floatingObject) const { return isHorizontalWritingMode() ? floatingObject->frameRect().pixelSnappedMaxX() : floatingObject->frameRect().pixelSnappedMaxY(); }
129 
setLogicalTopForFloat(FloatingObject * floatingObject,LayoutUnit logicalTop)130     void setLogicalTopForFloat(FloatingObject* floatingObject, LayoutUnit logicalTop)
131     {
132         if (isHorizontalWritingMode())
133             floatingObject->setY(logicalTop);
134         else
135             floatingObject->setX(logicalTop);
136     }
setLogicalLeftForFloat(FloatingObject * floatingObject,LayoutUnit logicalLeft)137     void setLogicalLeftForFloat(FloatingObject* floatingObject, LayoutUnit logicalLeft)
138     {
139         if (isHorizontalWritingMode())
140             floatingObject->setX(logicalLeft);
141         else
142             floatingObject->setY(logicalLeft);
143     }
setLogicalHeightForFloat(FloatingObject * floatingObject,LayoutUnit logicalHeight)144     void setLogicalHeightForFloat(FloatingObject* floatingObject, LayoutUnit logicalHeight)
145     {
146         if (isHorizontalWritingMode())
147             floatingObject->setHeight(logicalHeight);
148         else
149             floatingObject->setWidth(logicalHeight);
150     }
setLogicalWidthForFloat(FloatingObject * floatingObject,LayoutUnit logicalWidth)151     void setLogicalWidthForFloat(FloatingObject* floatingObject, LayoutUnit logicalWidth)
152     {
153         if (isHorizontalWritingMode())
154             floatingObject->setWidth(logicalWidth);
155         else
156             floatingObject->setHeight(logicalWidth);
157     }
158 
159     LayoutUnit startAlignedOffsetForLine(LayoutUnit position, bool shouldIndentText);
160 
161     void setStaticInlinePositionForChild(RenderBox*, LayoutUnit inlinePosition);
162     void updateStaticInlinePositionForChild(RenderBox*, LayoutUnit logicalTop);
163 
shouldSkipCreatingRunsForObject(RenderObject * obj)164     static bool shouldSkipCreatingRunsForObject(RenderObject* obj)
165     {
166         return obj->isFloating() || (obj->isOutOfFlowPositioned() && !obj->style()->isOriginalDisplayInlineType() && !obj->container()->isRenderInline());
167     }
168 
multiColumnFlowThread()169     RenderMultiColumnFlowThread* multiColumnFlowThread() const { return m_rareData ? m_rareData->m_multiColumnFlowThread.get() : 0; }
resetMultiColumnFlowThread()170     void resetMultiColumnFlowThread()
171     {
172         if (m_rareData)
173             m_rareData->m_multiColumnFlowThread = nullptr;
174     }
175 
176     void addOverflowFromInlineChildren();
177 
178     // FIXME: This should be const to avoid a const_cast, but can modify child dirty bits and RenderCombineText
179     void computeInlinePreferredLogicalWidths(LayoutUnit& minLogicalWidth, LayoutUnit& maxLogicalWidth);
180 
181     GapRects inlineSelectionGaps(const RenderBlock* rootBlock, const LayoutPoint& rootBlockPhysicalPosition, const LayoutSize& offsetFromRootBlock,
182         LayoutUnit& lastLogicalTop, LayoutUnit& lastLogicalLeft, LayoutUnit& lastLogicalRight, const PaintInfo*) const;
183 
paginationStrut()184     LayoutUnit paginationStrut() const { return m_rareData ? m_rareData->m_paginationStrut : LayoutUnit(); }
185     void setPaginationStrut(LayoutUnit);
186 
187     virtual bool avoidsFloats() const OVERRIDE;
188 
xPositionForFloatIncludingMargin(const FloatingObject * child)189     LayoutUnit xPositionForFloatIncludingMargin(const FloatingObject* child) const
190     {
191         if (isHorizontalWritingMode())
192             return child->x() + child->renderer()->marginLeft();
193 
194         return child->x() + marginBeforeForChild(child->renderer());
195     }
196 
yPositionForFloatIncludingMargin(const FloatingObject * child)197     LayoutUnit yPositionForFloatIncludingMargin(const FloatingObject* child) const
198     {
199         if (isHorizontalWritingMode())
200             return child->y() + marginBeforeForChild(child->renderer());
201 
202         return child->y() + child->renderer()->marginTop();
203     }
204 
205     LayoutPoint flipFloatForWritingModeForChild(const FloatingObject*, const LayoutPoint&) const;
206 
207 protected:
208     void rebuildFloatsFromIntruding();
209     void layoutInlineChildren(bool relayoutChildren, LayoutUnit& paintInvalidationLogicalTop, LayoutUnit& paintInvalidationLogicalBottom, LayoutUnit afterEdge);
210 
211     void createFloatingObjects();
212 
213     virtual void styleWillChange(StyleDifference, const RenderStyle& newStyle) OVERRIDE;
214     virtual void styleDidChange(StyleDifference, const RenderStyle* oldStyle) OVERRIDE;
215 
216     void addOverflowFromFloats();
217 
218     LayoutUnit logicalRightOffsetForLine(LayoutUnit logicalTop, LayoutUnit fixedOffset, bool applyTextIndent, LayoutUnit logicalHeight = 0) const
219     {
220         return adjustLogicalRightOffsetForLine(logicalRightFloatOffsetForLine(logicalTop, fixedOffset, logicalHeight), applyTextIndent);
221     }
222     LayoutUnit logicalLeftOffsetForLine(LayoutUnit logicalTop, LayoutUnit fixedOffset, bool applyTextIndent, LayoutUnit logicalHeight = 0) const
223     {
224         return adjustLogicalLeftOffsetForLine(logicalLeftFloatOffsetForLine(logicalTop, fixedOffset, logicalHeight), applyTextIndent);
225     }
226 
227     virtual RenderObject* layoutSpecialExcludedChild(bool /*relayoutChildren*/, SubtreeLayoutScope&);
228     virtual bool updateLogicalWidthAndColumnWidth() OVERRIDE;
229 
230     void setLogicalLeftForChild(RenderBox* child, LayoutUnit logicalLeft);
231     void setLogicalTopForChild(RenderBox* child, LayoutUnit logicalTop);
232     void determineLogicalLeftPositionForChild(RenderBox* child);
233 
234 private:
235     bool layoutBlockFlow(bool relayoutChildren, LayoutUnit& pageLogicalHeight, SubtreeLayoutScope&);
236     void layoutBlockChildren(bool relayoutChildren, SubtreeLayoutScope&, LayoutUnit beforeEdge, LayoutUnit afterEdge);
237 
238     void layoutBlockChild(RenderBox* child, MarginInfo&, LayoutUnit& previousFloatLogicalBottom);
239     void adjustPositionedBlock(RenderBox* child, const MarginInfo&);
240     void adjustFloatingBlock(const MarginInfo&);
241 
242     LayoutPoint computeLogicalLocationForFloat(const FloatingObject*, LayoutUnit logicalTopOffset) const;
243 
244     FloatingObject* insertFloatingObject(RenderBox*);
245     void removeFloatingObject(RenderBox*);
246     void removeFloatingObjectsBelow(FloatingObject*, int logicalOffset);
247 
248     // Called from lineWidth, to position the floats added in the last line.
249     // Returns true if and only if it has positioned any floats.
250     bool positionNewFloats();
251 
252     LayoutUnit getClearDelta(RenderBox* child, LayoutUnit yPos);
253 
hasOverhangingFloats()254     bool hasOverhangingFloats() { return parent() && !hasColumns() && containsFloats() && lowestFloatLogicalBottom() > logicalHeight(); }
255     bool hasOverhangingFloat(RenderBox*);
256     void addIntrudingFloats(RenderBlockFlow* prev, LayoutUnit xoffset, LayoutUnit yoffset);
257     void addOverhangingFloats(RenderBlockFlow* child, bool makeChildPaintOtherFloats);
258 
259     LayoutUnit lowestFloatLogicalBottom(FloatingObject::Type = FloatingObject::FloatLeftRight) const;
260     LayoutUnit nextFloatLogicalBottomBelow(LayoutUnit, ShapeOutsideFloatOffsetMode = ShapeOutsideFloatMarginBoxOffset) const;
261 
262     virtual bool hitTestFloats(const HitTestRequest&, HitTestResult&, const HitTestLocation& locationInContainer, const LayoutPoint& accumulatedOffset) OVERRIDE FINAL;
263 
264     virtual void invalidatePaintForOverhangingFloats(bool paintAllDescendants) OVERRIDE FINAL;
265     virtual void invalidatePaintForOverflow() OVERRIDE FINAL;
266     virtual void paintFloats(PaintInfo&, const LayoutPoint&, bool preservePhase = false) OVERRIDE FINAL;
267     virtual void clipOutFloatingObjects(const RenderBlock*, const PaintInfo*, const LayoutPoint&, const LayoutSize&) const OVERRIDE;
268     void clearFloats(EClear);
269 
270     LayoutUnit logicalRightFloatOffsetForLine(LayoutUnit logicalTop, LayoutUnit fixedOffset, LayoutUnit logicalHeight) const;
271     LayoutUnit logicalLeftFloatOffsetForLine(LayoutUnit logicalTop, LayoutUnit fixedOffset, LayoutUnit logicalHeight) const;
272 
273     LayoutUnit logicalRightOffsetForPositioningFloat(LayoutUnit logicalTop, LayoutUnit fixedOffset, bool applyTextIndent, LayoutUnit* heightRemaining) const;
274     LayoutUnit logicalLeftOffsetForPositioningFloat(LayoutUnit logicalTop, LayoutUnit fixedOffset, bool applyTextIndent, LayoutUnit* heightRemaining) const;
275 
276     LayoutUnit adjustLogicalRightOffsetForLine(LayoutUnit offsetFromFloats, bool applyTextIndent) const;
277     LayoutUnit adjustLogicalLeftOffsetForLine(LayoutUnit offsetFromFloats, bool applyTextIndent) const;
278 
279     void fitBorderToLinesIfNeeded(); // Shrink the box in which the border paints if border-fit is set.
280     void adjustForBorderFit(LayoutUnit x, LayoutUnit& left, LayoutUnit& right) const; // Helper function for borderFitAdjust
281 
282     virtual RootInlineBox* createRootInlineBox(); // Subclassed by SVG
283 
284     bool isPagedOverflow(const RenderStyle*);
285 
286     enum FlowThreadType {
287         NoFlowThread,
288         MultiColumnFlowThread,
289         PagedFlowThread
290     };
291 
292     FlowThreadType flowThreadType(const RenderStyle*);
293 
294     RenderMultiColumnFlowThread* createMultiColumnFlowThread(FlowThreadType);
295     void createOrDestroyMultiColumnFlowThreadIfNeeded(const RenderStyle* oldStyle);
296 
297     void updateLogicalWidthForAlignment(const ETextAlign&, const RootInlineBox*, BidiRun* trailingSpaceRun, float& logicalLeft, float& totalLogicalWidth, float& availableLogicalWidth, unsigned expansionOpportunityCount);
298     void checkForPaginationLogicalHeightChange(LayoutUnit& pageLogicalHeight, bool& pageLogicalHeightChanged, bool& hasSpecifiedPageLogicalHeight);
299     bool shouldRelayoutForPagination(LayoutUnit& pageLogicalHeight, LayoutUnit layoutOverflowLogicalBottom) const;
300     void setColumnCountAndHeight(unsigned count, LayoutUnit pageLogicalHeight);
301 
shouldBreakAtLineToAvoidWidow()302     bool shouldBreakAtLineToAvoidWidow() const { return m_rareData && m_rareData->m_lineBreakToAvoidWidow >= 0; }
303     void clearShouldBreakAtLineToAvoidWidow() const;
lineBreakToAvoidWidow()304     int lineBreakToAvoidWidow() const { return m_rareData ? m_rareData->m_lineBreakToAvoidWidow : -1; }
305     void setBreakAtLineToAvoidWidow(int);
306     void clearDidBreakAtLineToAvoidWidow();
307     void setDidBreakAtLineToAvoidWidow();
didBreakAtLineToAvoidWidow()308     bool didBreakAtLineToAvoidWidow() const { return m_rareData && m_rareData->m_didBreakAtLineToAvoidWidow; }
309 
310 public:
311     struct FloatWithRect {
FloatWithRectFloatWithRect312         FloatWithRect(RenderBox* f)
313             : object(f)
314             , rect(LayoutRect(f->x() - f->marginLeft(), f->y() - f->marginTop(), f->width() + f->marginWidth(), f->height() + f->marginHeight()))
315             , everHadLayout(f->everHadLayout())
316         {
317         }
318 
319         RenderBox* object;
320         LayoutRect rect;
321         bool everHadLayout;
322     };
323 
324     class MarginValues {
325     public:
MarginValues(LayoutUnit beforePos,LayoutUnit beforeNeg,LayoutUnit afterPos,LayoutUnit afterNeg)326         MarginValues(LayoutUnit beforePos, LayoutUnit beforeNeg, LayoutUnit afterPos, LayoutUnit afterNeg)
327             : m_positiveMarginBefore(beforePos)
328             , m_negativeMarginBefore(beforeNeg)
329             , m_positiveMarginAfter(afterPos)
330             , m_negativeMarginAfter(afterNeg)
331         { }
332 
positiveMarginBefore()333         LayoutUnit positiveMarginBefore() const { return m_positiveMarginBefore; }
negativeMarginBefore()334         LayoutUnit negativeMarginBefore() const { return m_negativeMarginBefore; }
positiveMarginAfter()335         LayoutUnit positiveMarginAfter() const { return m_positiveMarginAfter; }
negativeMarginAfter()336         LayoutUnit negativeMarginAfter() const { return m_negativeMarginAfter; }
337 
setPositiveMarginBefore(LayoutUnit pos)338         void setPositiveMarginBefore(LayoutUnit pos) { m_positiveMarginBefore = pos; }
setNegativeMarginBefore(LayoutUnit neg)339         void setNegativeMarginBefore(LayoutUnit neg) { m_negativeMarginBefore = neg; }
setPositiveMarginAfter(LayoutUnit pos)340         void setPositiveMarginAfter(LayoutUnit pos) { m_positiveMarginAfter = pos; }
setNegativeMarginAfter(LayoutUnit neg)341         void setNegativeMarginAfter(LayoutUnit neg) { m_negativeMarginAfter = neg; }
342 
343     private:
344         LayoutUnit m_positiveMarginBefore;
345         LayoutUnit m_negativeMarginBefore;
346         LayoutUnit m_positiveMarginAfter;
347         LayoutUnit m_negativeMarginAfter;
348     };
349     MarginValues marginValuesForChild(RenderBox* child) const;
350 
351     // Allocated only when some of these fields have non-default values
352     struct RenderBlockFlowRareData : public NoBaseWillBeGarbageCollected<RenderBlockFlowRareData> {
353         WTF_MAKE_NONCOPYABLE(RenderBlockFlowRareData); WTF_MAKE_FAST_ALLOCATED_WILL_BE_REMOVED;
354     public:
RenderBlockFlowRareDataRenderBlockFlowRareData355         RenderBlockFlowRareData(const RenderBlockFlow* block)
356             : m_margins(positiveMarginBeforeDefault(block), negativeMarginBeforeDefault(block), positiveMarginAfterDefault(block), negativeMarginAfterDefault(block))
357             , m_paginationStrut(0)
358             , m_multiColumnFlowThread(nullptr)
359             , m_lineBreakToAvoidWidow(-1)
360             , m_didBreakAtLineToAvoidWidow(false)
361             , m_discardMarginBefore(false)
362             , m_discardMarginAfter(false)
363         {
364         }
365         void trace(Visitor*);
366 
positiveMarginBeforeDefaultRenderBlockFlowRareData367         static LayoutUnit positiveMarginBeforeDefault(const RenderBlockFlow* block)
368         {
369             return std::max<LayoutUnit>(block->marginBefore(), 0);
370         }
negativeMarginBeforeDefaultRenderBlockFlowRareData371         static LayoutUnit negativeMarginBeforeDefault(const RenderBlockFlow* block)
372         {
373             return std::max<LayoutUnit>(-block->marginBefore(), 0);
374         }
positiveMarginAfterDefaultRenderBlockFlowRareData375         static LayoutUnit positiveMarginAfterDefault(const RenderBlockFlow* block)
376         {
377             return std::max<LayoutUnit>(block->marginAfter(), 0);
378         }
negativeMarginAfterDefaultRenderBlockFlowRareData379         static LayoutUnit negativeMarginAfterDefault(const RenderBlockFlow* block)
380         {
381             return std::max<LayoutUnit>(-block->marginAfter(), 0);
382         }
383 
384         MarginValues m_margins;
385         LayoutUnit m_paginationStrut;
386 
387         RawPtrWillBeMember<RenderMultiColumnFlowThread> m_multiColumnFlowThread;
388 
389         int m_lineBreakToAvoidWidow;
390         bool m_didBreakAtLineToAvoidWidow : 1;
391         bool m_discardMarginBefore : 1;
392         bool m_discardMarginAfter : 1;
393     };
394     LayoutUnit marginOffsetForSelfCollapsingBlock();
395 
floatingObjects()396     FloatingObjects* floatingObjects() { return m_floatingObjects.get(); }
397 
398 
399 protected:
maxPositiveMarginBefore()400     LayoutUnit maxPositiveMarginBefore() const { return m_rareData ? m_rareData->m_margins.positiveMarginBefore() : RenderBlockFlowRareData::positiveMarginBeforeDefault(this); }
maxNegativeMarginBefore()401     LayoutUnit maxNegativeMarginBefore() const { return m_rareData ? m_rareData->m_margins.negativeMarginBefore() : RenderBlockFlowRareData::negativeMarginBeforeDefault(this); }
maxPositiveMarginAfter()402     LayoutUnit maxPositiveMarginAfter() const { return m_rareData ? m_rareData->m_margins.positiveMarginAfter() : RenderBlockFlowRareData::positiveMarginAfterDefault(this); }
maxNegativeMarginAfter()403     LayoutUnit maxNegativeMarginAfter() const { return m_rareData ? m_rareData->m_margins.negativeMarginAfter() : RenderBlockFlowRareData::negativeMarginAfterDefault(this); }
404 
405     void setMaxMarginBeforeValues(LayoutUnit pos, LayoutUnit neg);
406     void setMaxMarginAfterValues(LayoutUnit pos, LayoutUnit neg);
407 
408     void setMustDiscardMarginBefore(bool = true);
409     void setMustDiscardMarginAfter(bool = true);
410 
411     bool mustDiscardMarginBefore() const;
412     bool mustDiscardMarginAfter() const;
413 
414     bool mustDiscardMarginBeforeForChild(const RenderBox*) const;
415     bool mustDiscardMarginAfterForChild(const RenderBox*) const;
416 
417     bool mustSeparateMarginBeforeForChild(const RenderBox*) const;
418     bool mustSeparateMarginAfterForChild(const RenderBox*) const;
419 
initMaxMarginValues()420     void initMaxMarginValues()
421     {
422         if (m_rareData) {
423             m_rareData->m_margins = MarginValues(RenderBlockFlowRareData::positiveMarginBeforeDefault(this) , RenderBlockFlowRareData::negativeMarginBeforeDefault(this),
424                 RenderBlockFlowRareData::positiveMarginAfterDefault(this), RenderBlockFlowRareData::negativeMarginAfterDefault(this));
425 
426             m_rareData->m_discardMarginBefore = false;
427             m_rareData->m_discardMarginAfter = false;
428         }
429     }
430 
431     virtual ETextAlign textAlignmentForLine(bool endsWithSoftBreak) const;
432 private:
collapsedMarginBefore()433     virtual LayoutUnit collapsedMarginBefore() const OVERRIDE FINAL { return maxPositiveMarginBefore() - maxNegativeMarginBefore(); }
collapsedMarginAfter()434     virtual LayoutUnit collapsedMarginAfter() const OVERRIDE FINAL { return maxPositiveMarginAfter() - maxNegativeMarginAfter(); }
435 
436     LayoutUnit collapseMargins(RenderBox* child, MarginInfo&, bool childIsSelfCollapsing);
437     LayoutUnit clearFloatsIfNeeded(RenderBox* child, MarginInfo&, LayoutUnit oldTopPosMargin, LayoutUnit oldTopNegMargin, LayoutUnit yPos, bool childIsSelfCollapsing);
438     LayoutUnit estimateLogicalTopPosition(RenderBox* child, const MarginInfo&, LayoutUnit& estimateWithoutPagination);
439     void marginBeforeEstimateForChild(RenderBox*, LayoutUnit&, LayoutUnit&, bool&) const;
440     void handleAfterSideOfBlock(RenderBox* lastChild, LayoutUnit top, LayoutUnit bottom, MarginInfo&);
441     void setCollapsedBottomMargin(const MarginInfo&);
442 
443     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.
444     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.
445 
446     LayoutUnit adjustBlockChildForPagination(LayoutUnit logicalTopAfterClear, LayoutUnit estimateWithoutPagination, RenderBox* child, bool atBeforeSideOfBlock);
447     // Computes a deltaOffset value that put a line at the top of the next page if it doesn't fit on the current page.
448     void adjustLinePositionForPagination(RootInlineBox*, LayoutUnit& deltaOffset, RenderFlowThread*);
449     // If the child is unsplittable and can't fit on the current page, return the top of the next page/column.
450     LayoutUnit adjustForUnsplittableChild(RenderBox*, LayoutUnit logicalOffset, bool includeMargins = false);
451 
452     // Used to store state between styleWillChange and styleDidChange
453     static bool s_canPropagateFloatIntoSibling;
454 
455     RenderBlockFlowRareData& ensureRareData();
456 
457     LayoutUnit m_paintInvalidationLogicalTop;
458     LayoutUnit m_paintInvalidationLogicalBottom;
459 
460     virtual bool isSelfCollapsingBlock() const OVERRIDE;
461 
462 protected:
463     OwnPtrWillBeMember<RenderBlockFlowRareData> m_rareData;
464     OwnPtr<FloatingObjects> m_floatingObjects;
465 
466     friend class BreakingContext; // FIXME: It uses insertFloatingObject and positionNewFloatOnLine, if we move those out from the private scope/add a helper to LineBreaker, we can remove this friend
467     friend class MarginInfo;
468     friend class LineBreaker;
469     friend class LineWidth; // needs to know FloatingObject
470 
471 // FIXME-BLOCKFLOW: These methods have implementations in
472 // RenderBlockLineLayout. They should be moved to the proper header once the
473 // line layout code is separated from RenderBlock and RenderBlockFlow.
474 // START METHODS DEFINED IN RenderBlockLineLayout
475 private:
476     InlineFlowBox* createLineBoxes(RenderObject*, const LineInfo&, InlineBox* childBox);
477     RootInlineBox* constructLine(BidiRunList<BidiRun>&, const LineInfo&);
478     void setMarginsForRubyRun(BidiRun*, RenderRubyRun*, RenderObject*, const LineInfo&);
479     void computeInlineDirectionPositionsForLine(RootInlineBox*, const LineInfo&, BidiRun* firstRun, BidiRun* trailingSpaceRun, bool reachedEnd, GlyphOverflowAndFallbackFontsMap&, VerticalPositionCache&, WordMeasurements&);
480     BidiRun* computeInlineDirectionPositionsForSegment(RootInlineBox*, const LineInfo&, ETextAlign, float& logicalLeft,
481         float& availableLogicalWidth, BidiRun* firstRun, BidiRun* trailingSpaceRun, GlyphOverflowAndFallbackFontsMap& textBoxDataMap, VerticalPositionCache&, WordMeasurements&);
482     void computeBlockDirectionPositionsForLine(RootInlineBox*, BidiRun*, GlyphOverflowAndFallbackFontsMap&, VerticalPositionCache&);
483     BidiRun* handleTrailingSpaces(BidiRunList<BidiRun>&, BidiContext*);
484     void appendFloatingObjectToLastLine(FloatingObject*);
485     // Helper function for layoutInlineChildren()
486     RootInlineBox* createLineBoxesFromBidiRuns(unsigned bidiLevel, BidiRunList<BidiRun>&, const InlineIterator& end, LineInfo&, VerticalPositionCache&, BidiRun* trailingSpaceRun, WordMeasurements&);
487     void layoutRunsAndFloats(LineLayoutState&);
488     const InlineIterator& restartLayoutRunsAndFloatsInRange(LayoutUnit oldLogicalHeight, LayoutUnit newLogicalHeight,  FloatingObject* lastFloatFromPreviousLine, InlineBidiResolver&,  const InlineIterator&);
489     void layoutRunsAndFloatsInRange(LineLayoutState&, InlineBidiResolver&,
490         const InlineIterator& cleanLineStart, const BidiStatus& cleanLineBidiStatus);
491     void linkToEndLineIfNeeded(LineLayoutState&);
492     static void markDirtyFloatsForPaintInvalidation(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     void positionDialog();
504 
505 // END METHODS DEFINED IN RenderBlockLineLayout
506 
507 };
508 
509 DEFINE_RENDER_OBJECT_TYPE_CASTS(RenderBlockFlow, isRenderBlockFlow());
510 
511 } // namespace blink
512 
513 #endif // RenderBlockFlow_h
514