• 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/style/RenderStyleConstants.h"
42 
43 namespace WebCore {
44 
45 class MarginInfo;
46 class LineBreaker;
47 class LineWidth;
48 class RenderNamedFlowFragment;
49 
50 class RenderBlockFlow : public RenderBlock {
51 public:
52     explicit RenderBlockFlow(ContainerNode*);
53     virtual ~RenderBlockFlow();
54 
55     static RenderBlockFlow* createAnonymous(Document*);
56     RenderBlockFlow* createAnonymousBlockFlow() const;
57 
isRenderBlockFlow()58     virtual bool isRenderBlockFlow() const OVERRIDE FINAL { return true; }
59 
60     virtual void layoutBlock(bool relayoutChildren, LayoutUnit pageLogicalHeight = 0) OVERRIDE;
61 
62     virtual void computeOverflow(LayoutUnit oldClientAfterEdge, bool recomputeFloats = false) OVERRIDE;
63     virtual void deleteLineBoxTree() OVERRIDE FINAL;
64 
65     void markAllDescendantsWithFloatsForLayout(RenderBox* floatToRemove = 0, bool inLayout = true);
66     void markSiblingsWithFloatsForLayout(RenderBox* floatToRemove = 0);
67 
containsFloats()68     virtual bool containsFloats() const OVERRIDE FINAL { return m_floatingObjects && !m_floatingObjects->set().isEmpty(); }
69     bool containsFloat(RenderBox*) const;
70 
71     void removeFloatingObjects();
72 
73     bool generatesLineBoxesForInlineChild(RenderObject*);
74 
logicalTopForFloat(const FloatingObject * floatingObject)75     LayoutUnit logicalTopForFloat(const FloatingObject* floatingObject) const { return isHorizontalWritingMode() ? floatingObject->y() : floatingObject->x(); }
logicalBottomForFloat(const FloatingObject * floatingObject)76     LayoutUnit logicalBottomForFloat(const FloatingObject* floatingObject) const { return isHorizontalWritingMode() ? floatingObject->maxY() : floatingObject->maxX(); }
logicalLeftForFloat(const FloatingObject * floatingObject)77     LayoutUnit logicalLeftForFloat(const FloatingObject* floatingObject) const { return isHorizontalWritingMode() ? floatingObject->x() : floatingObject->y(); }
logicalRightForFloat(const FloatingObject * floatingObject)78     LayoutUnit logicalRightForFloat(const FloatingObject* floatingObject) const { return isHorizontalWritingMode() ? floatingObject->maxX() : floatingObject->maxY(); }
logicalWidthForFloat(const FloatingObject * floatingObject)79     LayoutUnit logicalWidthForFloat(const FloatingObject* floatingObject) const { return isHorizontalWritingMode() ? floatingObject->width() : floatingObject->height(); }
logicalHeightForFloat(const FloatingObject * floatingObject)80     LayoutUnit logicalHeightForFloat(const FloatingObject* floatingObject) const { return isHorizontalWritingMode() ? floatingObject->height() : floatingObject->width(); }
logicalSizeForFloat(const FloatingObject * floatingObject)81     LayoutSize logicalSizeForFloat(const FloatingObject* floatingObject) const { return isHorizontalWritingMode() ? LayoutSize(floatingObject->width(), floatingObject->height()) : LayoutSize(floatingObject->height(), floatingObject->width()); }
82 
pixelSnappedLogicalTopForFloat(const FloatingObject * floatingObject)83     int pixelSnappedLogicalTopForFloat(const FloatingObject* floatingObject) const { return isHorizontalWritingMode() ? floatingObject->frameRect().pixelSnappedY() : floatingObject->frameRect().pixelSnappedX(); }
pixelSnappedLogicalBottomForFloat(const FloatingObject * floatingObject)84     int pixelSnappedLogicalBottomForFloat(const FloatingObject* floatingObject) const { return isHorizontalWritingMode() ? floatingObject->frameRect().pixelSnappedMaxY() : floatingObject->frameRect().pixelSnappedMaxX(); }
pixelSnappedLogicalLeftForFloat(const FloatingObject * floatingObject)85     int pixelSnappedLogicalLeftForFloat(const FloatingObject* floatingObject) const { return isHorizontalWritingMode() ? floatingObject->frameRect().pixelSnappedX() : floatingObject->frameRect().pixelSnappedY(); }
pixelSnappedLogicalRightForFloat(const FloatingObject * floatingObject)86     int pixelSnappedLogicalRightForFloat(const FloatingObject* floatingObject) const { return isHorizontalWritingMode() ? floatingObject->frameRect().pixelSnappedMaxX() : floatingObject->frameRect().pixelSnappedMaxY(); }
87 
setLogicalTopForFloat(FloatingObject * floatingObject,LayoutUnit logicalTop)88     void setLogicalTopForFloat(FloatingObject* floatingObject, LayoutUnit logicalTop)
89     {
90         if (isHorizontalWritingMode())
91             floatingObject->setY(logicalTop);
92         else
93             floatingObject->setX(logicalTop);
94     }
setLogicalLeftForFloat(FloatingObject * floatingObject,LayoutUnit logicalLeft)95     void setLogicalLeftForFloat(FloatingObject* floatingObject, LayoutUnit logicalLeft)
96     {
97         if (isHorizontalWritingMode())
98             floatingObject->setX(logicalLeft);
99         else
100             floatingObject->setY(logicalLeft);
101     }
setLogicalHeightForFloat(FloatingObject * floatingObject,LayoutUnit logicalHeight)102     void setLogicalHeightForFloat(FloatingObject* floatingObject, LayoutUnit logicalHeight)
103     {
104         if (isHorizontalWritingMode())
105             floatingObject->setHeight(logicalHeight);
106         else
107             floatingObject->setWidth(logicalHeight);
108     }
setLogicalWidthForFloat(FloatingObject * floatingObject,LayoutUnit logicalWidth)109     void setLogicalWidthForFloat(FloatingObject* floatingObject, LayoutUnit logicalWidth)
110     {
111         if (isHorizontalWritingMode())
112             floatingObject->setWidth(logicalWidth);
113         else
114             floatingObject->setHeight(logicalWidth);
115     }
116 
117     LayoutUnit startAlignedOffsetForLine(LayoutUnit position, bool shouldIndentText);
118 
119     void setStaticInlinePositionForChild(RenderBox*, LayoutUnit blockOffset, LayoutUnit inlinePosition);
120     void updateStaticInlinePositionForChild(RenderBox*, LayoutUnit logicalTop);
121 
shouldSkipCreatingRunsForObject(RenderObject * obj)122     static bool shouldSkipCreatingRunsForObject(RenderObject* obj)
123     {
124         return obj->isFloating() || (obj->isOutOfFlowPositioned() && !obj->style()->isOriginalDisplayInlineType() && !obj->container()->isRenderInline());
125     }
126 
127     static TextRun constructTextRun(RenderObject* context, const Font&, const String&, RenderStyle*,
128         TextRun::ExpansionBehavior = TextRun::AllowTrailingExpansion | TextRun::ForbidLeadingExpansion, TextRunFlags = DefaultTextRunFlags);
129 
130     static TextRun constructTextRun(RenderObject* context, const Font&, const RenderText*, RenderStyle*,
131         TextRun::ExpansionBehavior = TextRun::AllowTrailingExpansion | TextRun::ForbidLeadingExpansion);
132 
133     static TextRun constructTextRun(RenderObject* context, const Font&, const RenderText*, unsigned offset, unsigned length, RenderStyle*,
134         TextRun::ExpansionBehavior = TextRun::AllowTrailingExpansion | TextRun::ForbidLeadingExpansion);
135 
136     static TextRun constructTextRun(RenderObject* context, const Font&, const RenderText*, unsigned offset, RenderStyle*,
137         TextRun::ExpansionBehavior = TextRun::AllowTrailingExpansion | TextRun::ForbidLeadingExpansion);
138 
139     static TextRun constructTextRun(RenderObject* context, const Font&, const LChar* characters, int length, RenderStyle*,
140         TextRun::ExpansionBehavior = TextRun::AllowTrailingExpansion | TextRun::ForbidLeadingExpansion);
141 
142     static TextRun constructTextRun(RenderObject* context, const Font&, const UChar* characters, int length, RenderStyle*,
143         TextRun::ExpansionBehavior = TextRun::AllowTrailingExpansion | TextRun::ForbidLeadingExpansion);
144 
lineGridBox()145     RootInlineBox* lineGridBox() const { return m_rareData ? m_rareData->m_lineGridBox : 0; }
setLineGridBox(RootInlineBox * box)146     void setLineGridBox(RootInlineBox* box)
147     {
148         RenderBlockFlow::RenderBlockFlowRareData& rareData = ensureRareData();
149         if (rareData.m_lineGridBox)
150             rareData.m_lineGridBox->destroy();
151         rareData.m_lineGridBox = box;
152     }
153     void layoutLineGridBox();
154 
155     void addOverflowFromInlineChildren();
156 
157     GapRects inlineSelectionGaps(RenderBlock* rootBlock, const LayoutPoint& rootBlockPhysicalPosition, const LayoutSize& offsetFromRootBlock,
158         LayoutUnit& lastLogicalTop, LayoutUnit& lastLogicalLeft, LayoutUnit& lastLogicalRight, const PaintInfo*);
159 protected:
160     // Only used by RenderSVGText, which explicitly overrides RenderBlock::layoutBlock(), do NOT use for anything else.
forceLayoutInlineChildren()161     void forceLayoutInlineChildren()
162     {
163         LayoutUnit repaintLogicalTop = 0;
164         LayoutUnit repaintLogicalBottom = 0;
165         rebuildFloatsFromIntruding();
166         layoutInlineChildren(true, repaintLogicalTop, repaintLogicalBottom);
167     }
168 
169     void createFloatingObjects();
170 
171     virtual void styleWillChange(StyleDifference, const RenderStyle* newStyle) OVERRIDE;
172     virtual void styleDidChange(StyleDifference, const RenderStyle* oldStyle) OVERRIDE;
173 
174     void addOverflowFromFloats();
175 
176     virtual void insertedIntoTree() OVERRIDE;
177     virtual void willBeDestroyed() OVERRIDE;
178 private:
179     void layoutBlockChildren(bool relayoutChildren, LayoutUnit& maxFloatLogicalBottom, SubtreeLayoutScope&);
180     void layoutInlineChildren(bool relayoutChildren, LayoutUnit& repaintLogicalTop, LayoutUnit& repaintLogicalBottom);
181 
182     void layoutBlockChild(RenderBox* child, MarginInfo&, LayoutUnit& previousFloatLogicalBottom, LayoutUnit& maxFloatLogicalBottom);
183     void adjustPositionedBlock(RenderBox* child, const MarginInfo&);
184     void adjustFloatingBlock(const MarginInfo&);
185 
186     void rebuildFloatsFromIntruding();
187 
188     LayoutPoint flipFloatForWritingModeForChild(const FloatingObject*, const LayoutPoint&) const;
189 
xPositionForFloatIncludingMargin(const FloatingObject * child)190     LayoutUnit xPositionForFloatIncludingMargin(const FloatingObject* child) const
191     {
192         if (isHorizontalWritingMode())
193             return child->x() + child->renderer()->marginLeft();
194 
195         return child->x() + marginBeforeForChild(child->renderer());
196     }
197 
yPositionForFloatIncludingMargin(const FloatingObject * child)198     LayoutUnit yPositionForFloatIncludingMargin(const FloatingObject* child) const
199     {
200         if (isHorizontalWritingMode())
201             return child->y() + marginBeforeForChild(child->renderer());
202 
203         return child->y() + child->renderer()->marginTop();
204     }
205 
206     LayoutPoint computeLogicalLocationForFloat(const FloatingObject*, LayoutUnit logicalTopOffset) const;
207 
208     FloatingObject* insertFloatingObject(RenderBox*);
209     void removeFloatingObject(RenderBox*);
210     void removeFloatingObjectsBelow(FloatingObject*, int logicalOffset);
211 
212     // Called from lineWidth, to position the floats added in the last line.
213     // Returns true if and only if it has positioned any floats.
214     bool positionNewFloats();
215 
216     LayoutUnit getClearDelta(RenderBox* child, LayoutUnit yPos);
217 
hasOverhangingFloats()218     bool hasOverhangingFloats() { return parent() && !hasColumns() && containsFloats() && lowestFloatLogicalBottom() > logicalHeight(); }
219     bool hasOverhangingFloat(RenderBox*);
220     void addIntrudingFloats(RenderBlockFlow* prev, LayoutUnit xoffset, LayoutUnit yoffset);
221     LayoutUnit addOverhangingFloats(RenderBlockFlow* child, bool makeChildPaintOtherFloats);
222 
223     LayoutUnit lowestFloatLogicalBottom(FloatingObject::Type = FloatingObject::FloatLeftRight) const;
224     LayoutUnit nextFloatLogicalBottomBelow(LayoutUnit, ShapeOutsideFloatOffsetMode = ShapeOutsideFloatMarginBoxOffset) const;
225 
226     virtual bool hitTestFloats(const HitTestRequest&, HitTestResult&, const HitTestLocation& locationInContainer, const LayoutPoint& accumulatedOffset) OVERRIDE FINAL;
227 
228     virtual void moveAllChildrenIncludingFloatsTo(RenderBlock* toBlock, bool fullRemoveInsert) OVERRIDE;
229     virtual void repaintOverhangingFloats(bool paintAllDescendants) OVERRIDE FINAL;
230     virtual void repaintOverflow() OVERRIDE;
231     virtual void paintFloats(PaintInfo&, const LayoutPoint&, bool preservePhase = false) OVERRIDE FINAL;
232     virtual void clipOutFloatingObjects(RenderBlock*, const PaintInfo*, const LayoutPoint&, const LayoutSize&) OVERRIDE;
233     void clearFloats(EClear);
234 
235     virtual LayoutUnit logicalRightFloatOffsetForLine(LayoutUnit logicalTop, LayoutUnit fixedOffset, LayoutUnit logicalHeight) const OVERRIDE;
236     virtual LayoutUnit logicalLeftFloatOffsetForLine(LayoutUnit logicalTop, LayoutUnit fixedOffset, LayoutUnit logicalHeight) const OVERRIDE;
237 
238     LayoutUnit logicalRightOffsetForPositioningFloat(LayoutUnit logicalTop, LayoutUnit fixedOffset, bool applyTextIndent, LayoutUnit* heightRemaining) const;
239     LayoutUnit logicalLeftOffsetForPositioningFloat(LayoutUnit logicalTop, LayoutUnit fixedOffset, bool applyTextIndent, LayoutUnit* heightRemaining) const;
240 
241     virtual void adjustForBorderFit(LayoutUnit x, LayoutUnit& left, LayoutUnit& right) const OVERRIDE; // Helper function for borderFitAdjust
242 
243     virtual RootInlineBox* createRootInlineBox() OVERRIDE;
244 
245     void updateLogicalWidthForAlignment(const ETextAlign&, const RootInlineBox*, BidiRun* trailingSpaceRun, float& logicalLeft, float& totalLogicalWidth, float& availableLogicalWidth, int expansionOpportunityCount);
246     virtual bool relayoutForPagination(bool hasSpecifiedPageLogicalHeight, LayoutUnit pageLogicalHeight, LayoutStateMaintainer&);
247 public:
248     struct FloatWithRect {
FloatWithRectFloatWithRect249         FloatWithRect(RenderBox* f)
250             : object(f)
251             , rect(LayoutRect(f->x() - f->marginLeft(), f->y() - f->marginTop(), f->width() + f->marginWidth(), f->height() + f->marginHeight()))
252             , everHadLayout(f->everHadLayout())
253         {
254         }
255 
256         RenderBox* object;
257         LayoutRect rect;
258         bool everHadLayout;
259     };
260 
261     class MarginValues {
262     public:
MarginValues(LayoutUnit beforePos,LayoutUnit beforeNeg,LayoutUnit afterPos,LayoutUnit afterNeg)263         MarginValues(LayoutUnit beforePos, LayoutUnit beforeNeg, LayoutUnit afterPos, LayoutUnit afterNeg)
264             : m_positiveMarginBefore(beforePos)
265             , m_negativeMarginBefore(beforeNeg)
266             , m_positiveMarginAfter(afterPos)
267             , m_negativeMarginAfter(afterNeg)
268         { }
269 
positiveMarginBefore()270         LayoutUnit positiveMarginBefore() const { return m_positiveMarginBefore; }
negativeMarginBefore()271         LayoutUnit negativeMarginBefore() const { return m_negativeMarginBefore; }
positiveMarginAfter()272         LayoutUnit positiveMarginAfter() const { return m_positiveMarginAfter; }
negativeMarginAfter()273         LayoutUnit negativeMarginAfter() const { return m_negativeMarginAfter; }
274 
setPositiveMarginBefore(LayoutUnit pos)275         void setPositiveMarginBefore(LayoutUnit pos) { m_positiveMarginBefore = pos; }
setNegativeMarginBefore(LayoutUnit neg)276         void setNegativeMarginBefore(LayoutUnit neg) { m_negativeMarginBefore = neg; }
setPositiveMarginAfter(LayoutUnit pos)277         void setPositiveMarginAfter(LayoutUnit pos) { m_positiveMarginAfter = pos; }
setNegativeMarginAfter(LayoutUnit neg)278         void setNegativeMarginAfter(LayoutUnit neg) { m_negativeMarginAfter = neg; }
279 
280     private:
281         LayoutUnit m_positiveMarginBefore;
282         LayoutUnit m_negativeMarginBefore;
283         LayoutUnit m_positiveMarginAfter;
284         LayoutUnit m_negativeMarginAfter;
285     };
286     MarginValues marginValuesForChild(RenderBox* child) const;
287 
288     virtual void updateLogicalHeight() OVERRIDE;
289 
290     // Allocated only when some of these fields have non-default values
291     struct RenderBlockFlowRareData {
292         WTF_MAKE_NONCOPYABLE(RenderBlockFlowRareData); WTF_MAKE_FAST_ALLOCATED;
293     public:
RenderBlockFlowRareDataRenderBlockFlowRareData294         RenderBlockFlowRareData(const RenderBlockFlow* block)
295             : m_margins(positiveMarginBeforeDefault(block), negativeMarginBeforeDefault(block), positiveMarginAfterDefault(block), negativeMarginAfterDefault(block))
296             , m_lineGridBox(0)
297             , m_discardMarginBefore(false)
298             , m_discardMarginAfter(false)
299             , m_renderNamedFlowFragment(0)
300         {
301         }
302 
positiveMarginBeforeDefaultRenderBlockFlowRareData303         static LayoutUnit positiveMarginBeforeDefault(const RenderBlockFlow* block)
304         {
305             return std::max<LayoutUnit>(block->marginBefore(), 0);
306         }
negativeMarginBeforeDefaultRenderBlockFlowRareData307         static LayoutUnit negativeMarginBeforeDefault(const RenderBlockFlow* block)
308         {
309             return std::max<LayoutUnit>(-block->marginBefore(), 0);
310         }
positiveMarginAfterDefaultRenderBlockFlowRareData311         static LayoutUnit positiveMarginAfterDefault(const RenderBlockFlow* block)
312         {
313             return std::max<LayoutUnit>(block->marginAfter(), 0);
314         }
negativeMarginAfterDefaultRenderBlockFlowRareData315         static LayoutUnit negativeMarginAfterDefault(const RenderBlockFlow* block)
316         {
317             return std::max<LayoutUnit>(-block->marginAfter(), 0);
318         }
319 
320         MarginValues m_margins;
321 
322         RootInlineBox* m_lineGridBox;
323 
324         bool m_discardMarginBefore : 1;
325         bool m_discardMarginAfter : 1;
326         RenderNamedFlowFragment* m_renderNamedFlowFragment;
327     };
328     LayoutUnit marginOffsetForSelfCollapsingBlock();
329 
renderNamedFlowFragment()330     RenderNamedFlowFragment* renderNamedFlowFragment() const { return m_rareData ? m_rareData->m_renderNamedFlowFragment : 0; }
331     void setRenderNamedFlowFragment(RenderNamedFlowFragment*);
332 
333 protected:
maxPositiveMarginBefore()334     LayoutUnit maxPositiveMarginBefore() const { return m_rareData ? m_rareData->m_margins.positiveMarginBefore() : RenderBlockFlowRareData::positiveMarginBeforeDefault(this); }
maxNegativeMarginBefore()335     LayoutUnit maxNegativeMarginBefore() const { return m_rareData ? m_rareData->m_margins.negativeMarginBefore() : RenderBlockFlowRareData::negativeMarginBeforeDefault(this); }
maxPositiveMarginAfter()336     LayoutUnit maxPositiveMarginAfter() const { return m_rareData ? m_rareData->m_margins.positiveMarginAfter() : RenderBlockFlowRareData::positiveMarginAfterDefault(this); }
maxNegativeMarginAfter()337     LayoutUnit maxNegativeMarginAfter() const { return m_rareData ? m_rareData->m_margins.negativeMarginAfter() : RenderBlockFlowRareData::negativeMarginAfterDefault(this); }
338 
339     void setMaxMarginBeforeValues(LayoutUnit pos, LayoutUnit neg);
340     void setMaxMarginAfterValues(LayoutUnit pos, LayoutUnit neg);
341 
342     void setMustDiscardMarginBefore(bool = true);
343     void setMustDiscardMarginAfter(bool = true);
344 
345     bool mustDiscardMarginBefore() const;
346     bool mustDiscardMarginAfter() const;
347 
348     bool mustDiscardMarginBeforeForChild(const RenderBox*) const;
349     bool mustDiscardMarginAfterForChild(const RenderBox*) const;
350 
351     bool mustSeparateMarginBeforeForChild(const RenderBox*) const;
352     bool mustSeparateMarginAfterForChild(const RenderBox*) const;
353 
initMaxMarginValues()354     void initMaxMarginValues()
355     {
356         if (m_rareData) {
357             m_rareData->m_margins = MarginValues(RenderBlockFlowRareData::positiveMarginBeforeDefault(this) , RenderBlockFlowRareData::negativeMarginBeforeDefault(this),
358                 RenderBlockFlowRareData::positiveMarginAfterDefault(this), RenderBlockFlowRareData::negativeMarginAfterDefault(this));
359 
360             m_rareData->m_discardMarginBefore = false;
361             m_rareData->m_discardMarginAfter = false;
362         }
363     }
364 
365     virtual ETextAlign textAlignmentForLine(bool endsWithSoftBreak) const;
366 private:
collapsedMarginBefore()367     virtual LayoutUnit collapsedMarginBefore() const OVERRIDE FINAL { return maxPositiveMarginBefore() - maxNegativeMarginBefore(); }
collapsedMarginAfter()368     virtual LayoutUnit collapsedMarginAfter() const OVERRIDE FINAL { return maxPositiveMarginAfter() - maxNegativeMarginAfter(); }
369 
370     LayoutUnit collapseMargins(RenderBox* child, MarginInfo&);
371     LayoutUnit clearFloatsIfNeeded(RenderBox* child, MarginInfo&, LayoutUnit oldTopPosMargin, LayoutUnit oldTopNegMargin, LayoutUnit yPos);
372     LayoutUnit estimateLogicalTopPosition(RenderBox* child, const MarginInfo&, LayoutUnit& estimateWithoutPagination);
373     void marginBeforeEstimateForChild(RenderBox*, LayoutUnit&, LayoutUnit&, bool&) const;
374     void handleAfterSideOfBlock(LayoutUnit top, LayoutUnit bottom, MarginInfo&);
375     void setCollapsedBottomMargin(const MarginInfo&);
376 
377     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.
378     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.
379 
380     LayoutUnit adjustBlockChildForPagination(LayoutUnit logicalTopAfterClear, LayoutUnit estimateWithoutPagination, RenderBox* child, bool atBeforeSideOfBlock);
381 
382     // Used to store state between styleWillChange and styleDidChange
383     static bool s_canPropagateFloatIntoSibling;
384 
385     virtual bool canHaveChildren() const OVERRIDE;
386     virtual bool canHaveGeneratedChildren() const OVERRIDE;
387 
388     void createRenderNamedFlowFragmentIfNeeded();
389 
390     RenderBlockFlowRareData& ensureRareData();
391 
392     LayoutUnit m_repaintLogicalTop;
393     LayoutUnit m_repaintLogicalBottom;
394 
395 protected:
396     OwnPtr<RenderBlockFlowRareData> m_rareData;
397     OwnPtr<FloatingObjects> m_floatingObjects;
398 
399     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
400     friend class MarginInfo;
401     friend class LineBreaker;
402     friend class LineWidth; // needs to know FloatingObject
403 
404 // FIXME-BLOCKFLOW: These methods have implementations in
405 // RenderBlockLineLayout. They should be moved to the proper header once the
406 // line layout code is separated from RenderBlock and RenderBlockFlow.
407 // START METHODS DEFINED IN RenderBlockLineLayout
408 private:
409     InlineFlowBox* createLineBoxes(RenderObject*, const LineInfo&, InlineBox* childBox, bool startsNewSegment);
410     RootInlineBox* constructLine(BidiRunList<BidiRun>&, const LineInfo&);
411     void setMarginsForRubyRun(BidiRun*, RenderRubyRun*, RenderObject*, const LineInfo&);
412     void computeInlineDirectionPositionsForLine(RootInlineBox*, const LineInfo&, BidiRun* firstRun, BidiRun* trailingSpaceRun, bool reachedEnd, GlyphOverflowAndFallbackFontsMap&, VerticalPositionCache&, WordMeasurements&);
413     BidiRun* computeInlineDirectionPositionsForSegment(RootInlineBox*, const LineInfo&, ETextAlign, float& logicalLeft,
414         float& availableLogicalWidth, BidiRun* firstRun, BidiRun* trailingSpaceRun, GlyphOverflowAndFallbackFontsMap& textBoxDataMap, VerticalPositionCache&, WordMeasurements&);
415     void computeBlockDirectionPositionsForLine(RootInlineBox*, BidiRun*, GlyphOverflowAndFallbackFontsMap&, VerticalPositionCache&);
416     BidiRun* handleTrailingSpaces(BidiRunList<BidiRun>&, BidiContext*);
417     void appendFloatingObjectToLastLine(FloatingObject*);
418     // Helper function for layoutInlineChildren()
419     RootInlineBox* createLineBoxesFromBidiRuns(unsigned bidiLevel, BidiRunList<BidiRun>&, const InlineIterator& end, LineInfo&, VerticalPositionCache&, BidiRun* trailingSpaceRun, WordMeasurements&);
420     void layoutRunsAndFloats(LineLayoutState&, bool hasInlineChild);
421     const InlineIterator& restartLayoutRunsAndFloatsInRange(LayoutUnit oldLogicalHeight, LayoutUnit newLogicalHeight,  FloatingObject* lastFloatFromPreviousLine, InlineBidiResolver&,  const InlineIterator&);
422     void layoutRunsAndFloatsInRange(LineLayoutState&, InlineBidiResolver&, const InlineIterator& cleanLineStart, const BidiStatus& cleanLineBidiStatus, unsigned consecutiveHyphenatedLines);
423     void updateShapeAndSegmentsForCurrentLine(ShapeInsideInfo*&, const LayoutSize&, LineLayoutState&);
424     void updateShapeAndSegmentsForCurrentLineInFlowThread(ShapeInsideInfo*&, LineLayoutState&);
425     bool adjustLogicalLineTopAndLogicalHeightIfNeeded(ShapeInsideInfo*, LayoutUnit, LineLayoutState&, InlineBidiResolver&, FloatingObject*, InlineIterator&, WordMeasurements&);
426     void linkToEndLineIfNeeded(LineLayoutState&);
427     static void repaintDirtyFloats(Vector<FloatWithRect>& floats);
428     void checkFloatsInCleanLine(RootInlineBox*, Vector<FloatWithRect>&, size_t& floatIndex, bool& encounteredNewFloat, bool& dirtiedByFloat);
429     RootInlineBox* determineStartPosition(LineLayoutState&, InlineBidiResolver&);
430     void determineEndPosition(LineLayoutState&, RootInlineBox* startBox, InlineIterator& cleanLineStart, BidiStatus& cleanLineBidiStatus);
431     bool checkPaginationAndFloatsAtEndLine(LineLayoutState&);
432     bool matchedEndLine(LineLayoutState&, const InlineBidiResolver&, const InlineIterator& endLineStart, const BidiStatus& endLineStatus);
433     void deleteEllipsisLineBoxes();
434     void checkLinesForTextOverflow();
435     // Positions new floats and also adjust all floats encountered on the line if any of them
436     // have to move to the next page/column.
437     bool positionNewFloatOnLine(FloatingObject* newFloat, FloatingObject* lastFloatFromPreviousLine, LineInfo&, LineWidth&);
438 
439 
440 // END METHODS DEFINED IN RenderBlockLineLayout
441 
442 };
443 
444 DEFINE_RENDER_OBJECT_TYPE_CASTS(RenderBlockFlow, isRenderBlockFlow());
445 
446 } // namespace WebCore
447 
448 #endif // RenderBlockFlow_h
449