45ab9135e4af175ba4ea6dc352879e4788c49e1e
[WebKit-https.git] / Source / WebCore / rendering / RenderBlock.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, 2004, 2005, 2006, 2007, 2008, 2009, 2010 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 RenderBlock_h
24 #define RenderBlock_h
25
26 #include "ColumnInfo.h"
27 #include "GapRects.h"
28 #include "PODIntervalTree.h"
29 #include "RenderBox.h"
30 #include "RenderLineBoxList.h"
31 #include "RootInlineBox.h"
32 #include "TextBreakIterator.h"
33 #include "TextRun.h"
34 #include <wtf/OwnPtr.h>
35 #include <wtf/ListHashSet.h>
36
37 #if ENABLE(CSS_EXCLUSIONS)
38 #include "ExclusionShapeInsideInfo.h"
39 #include "ExclusionShapeValue.h"
40 #endif
41
42 namespace WebCore {
43
44 class BidiContext;
45 class InlineIterator;
46 class LayoutStateMaintainer;
47 class LineLayoutState;
48 class LineWidth;
49 class RenderInline;
50 class RenderText;
51
52 struct BidiRun;
53 struct PaintInfo;
54 class LineInfo;
55 class RenderRubyRun;
56 #if ENABLE(CSS_EXCLUSIONS)
57 class BasicShape;
58 #endif
59 class TextLayout;
60 class WordMeasurement;
61
62 template <class Iterator, class Run> class BidiResolver;
63 template <class Run> class BidiRunList;
64 template <class Iterator> struct MidpointState;
65 typedef BidiResolver<InlineIterator, BidiRun> InlineBidiResolver;
66 typedef MidpointState<InlineIterator> LineMidpointState;
67 typedef WTF::ListHashSet<RenderBox*, 16> TrackedRendererListHashSet;
68 typedef WTF::HashMap<const RenderBlock*, OwnPtr<TrackedRendererListHashSet> > TrackedDescendantsMap;
69 typedef WTF::HashMap<const RenderBox*, OwnPtr<HashSet<RenderBlock*> > > TrackedContainerMap;
70 typedef Vector<WordMeasurement, 64> WordMeasurements;
71
72 enum CaretType { CursorCaret, DragCaret };
73 enum ContainingBlockState { NewContainingBlock, SameContainingBlock };
74 enum ShapeOutsideFloatOffsetMode { ShapeOutsideFloatShapeOffset, ShapeOutsideFloatBoundingBoxOffset };
75
76 enum TextRunFlag {
77     DefaultTextRunFlags = 0,
78     RespectDirection = 1 << 0,
79     RespectDirectionOverride = 1 << 1
80 };
81
82 typedef unsigned TextRunFlags;
83
84 class RenderBlock : public RenderBox {
85 public:
86     friend class LineLayoutState;
87 #ifndef NDEBUG
88     // Used by the PODIntervalTree for debugging the FloatingObject.
89     template <class> friend struct ValueToString;
90 #endif
91
92     explicit RenderBlock(ContainerNode*);
93     virtual ~RenderBlock();
94
95     static RenderBlock* createAnonymous(Document*);
96
97     RenderObject* firstChild() const { ASSERT(children() == virtualChildren()); return children()->firstChild(); }
98     RenderObject* lastChild() const { ASSERT(children() == virtualChildren()); return children()->lastChild(); }
99
100     const RenderObjectChildList* children() const { return &m_children; }
101     RenderObjectChildList* children() { return &m_children; }
102
103     bool beingDestroyed() const { return m_beingDestroyed; }
104
105     // These two functions are overridden for inline-block.
106     virtual LayoutUnit lineHeight(bool firstLine, LineDirectionMode, LinePositionMode = PositionOnContainingLine) const;
107     virtual int baselinePosition(FontBaseline, bool firstLine, LineDirectionMode, LinePositionMode = PositionOnContainingLine) const;
108
109     RenderLineBoxList* lineBoxes() { return &m_lineBoxes; }
110     const RenderLineBoxList* lineBoxes() const { return &m_lineBoxes; }
111
112     InlineFlowBox* firstLineBox() const { return m_lineBoxes.firstLineBox(); }
113     InlineFlowBox* lastLineBox() const { return m_lineBoxes.lastLineBox(); }
114
115     void deleteLineBoxTree();
116
117     virtual void addChild(RenderObject* newChild, RenderObject* beforeChild = 0);
118     virtual void removeChild(RenderObject*);
119
120     virtual void layoutBlock(bool relayoutChildren, LayoutUnit pageLogicalHeight = 0);
121
122     void insertPositionedObject(RenderBox*);
123     static void removePositionedObject(RenderBox*);
124     void removePositionedObjects(RenderBlock*, ContainingBlockState = SameContainingBlock);
125
126     void removeFloatingObjects();
127
128     TrackedRendererListHashSet* positionedObjects() const;
129     bool hasPositionedObjects() const
130     {
131         TrackedRendererListHashSet* objects = positionedObjects();
132         return objects && !objects->isEmpty();
133     }
134
135     void addPercentHeightDescendant(RenderBox*);
136     static void removePercentHeightDescendant(RenderBox*);
137     TrackedRendererListHashSet* percentHeightDescendants() const;
138     static bool hasPercentHeightContainerMap();
139     static bool hasPercentHeightDescendant(RenderBox*);
140     static void clearPercentHeightDescendantsFrom(RenderBox*);
141     static void removePercentHeightDescendantIfNeeded(RenderBox*);
142
143     void setHasMarkupTruncation(bool b) { m_hasMarkupTruncation = b; }
144     bool hasMarkupTruncation() const { return m_hasMarkupTruncation; }
145
146     void setHasMarginBeforeQuirk(bool b) { m_hasMarginBeforeQuirk = b; }
147     void setHasMarginAfterQuirk(bool b) { m_hasMarginAfterQuirk = b; }
148
149     bool hasMarginBeforeQuirk() const { return m_hasMarginBeforeQuirk; }
150     bool hasMarginAfterQuirk() const { return m_hasMarginAfterQuirk; }
151
152     bool hasMarginBeforeQuirk(const RenderBox* child) const;
153     bool hasMarginAfterQuirk(const RenderBox* child) const;
154
155     RootInlineBox* createAndAppendRootInlineBox();
156
157     bool generatesLineBoxesForInlineChild(RenderObject*);
158
159     void markAllDescendantsWithFloatsForLayout(RenderBox* floatToRemove = 0, bool inLayout = true);
160     void markSiblingsWithFloatsForLayout(RenderBox* floatToRemove = 0);
161     void markPositionedObjectsForLayout();
162     virtual void markForPaginationRelayoutIfNeeded();
163     
164     bool containsFloats() const { return m_floatingObjects && !m_floatingObjects->set().isEmpty(); }
165     bool containsFloat(RenderBox*) const;
166
167     // Versions that can compute line offsets with the region and page offset passed in. Used for speed to avoid having to
168     // compute the region all over again when you already know it.
169     LayoutUnit availableLogicalWidthForLine(LayoutUnit position, bool shouldIndentText, RenderRegion* region, LayoutUnit offsetFromLogicalTopOfFirstPage, LayoutUnit logicalHeight = 0) const
170     {
171         return max<LayoutUnit>(0, logicalRightOffsetForLine(position, shouldIndentText, region, offsetFromLogicalTopOfFirstPage, logicalHeight)
172             - logicalLeftOffsetForLine(position, shouldIndentText, region, offsetFromLogicalTopOfFirstPage, logicalHeight));
173     }
174     LayoutUnit logicalRightOffsetForLine(LayoutUnit position, bool shouldIndentText, RenderRegion* region, LayoutUnit offsetFromLogicalTopOfFirstPage, LayoutUnit logicalHeight = 0, ShapeOutsideFloatOffsetMode offsetMode = ShapeOutsideFloatShapeOffset) const 
175     {
176         return logicalRightOffsetForLine(position, logicalRightOffsetForContent(region, offsetFromLogicalTopOfFirstPage), shouldIndentText, 0, logicalHeight, offsetMode);
177     }
178     LayoutUnit logicalLeftOffsetForLine(LayoutUnit position, bool shouldIndentText, RenderRegion* region, LayoutUnit offsetFromLogicalTopOfFirstPage, LayoutUnit logicalHeight = 0, ShapeOutsideFloatOffsetMode offsetMode = ShapeOutsideFloatShapeOffset) const 
179     {
180         return logicalLeftOffsetForLine(position, logicalLeftOffsetForContent(region, offsetFromLogicalTopOfFirstPage), shouldIndentText, 0, logicalHeight, offsetMode);
181     }
182     LayoutUnit startOffsetForLine(LayoutUnit position, bool shouldIndentText, RenderRegion* region, LayoutUnit offsetFromLogicalTopOfFirstPage, LayoutUnit logicalHeight = 0) const
183     {
184         return style()->isLeftToRightDirection() ? logicalLeftOffsetForLine(position, shouldIndentText, region, offsetFromLogicalTopOfFirstPage, logicalHeight)
185             : logicalWidth() - logicalRightOffsetForLine(position, shouldIndentText, region, offsetFromLogicalTopOfFirstPage, logicalHeight);
186     }
187     LayoutUnit endOffsetForLine(LayoutUnit position, bool shouldIndentText, RenderRegion* region, LayoutUnit offsetFromLogicalTopOfFirstPage, LayoutUnit logicalHeight = 0) const
188     {
189         return !style()->isLeftToRightDirection() ? logicalLeftOffsetForLine(position, shouldIndentText, region, offsetFromLogicalTopOfFirstPage, logicalHeight)
190             : logicalWidth() - logicalRightOffsetForLine(position, shouldIndentText, region, offsetFromLogicalTopOfFirstPage, logicalHeight);
191     }
192
193     LayoutUnit availableLogicalWidthForLine(LayoutUnit position, bool shouldIndentText, LayoutUnit logicalHeight = 0) const
194     {
195         return availableLogicalWidthForLine(position, shouldIndentText, regionAtBlockOffset(position), offsetFromLogicalTopOfFirstPage(), logicalHeight);
196     }
197     LayoutUnit logicalRightOffsetForLine(LayoutUnit position, bool shouldIndentText, LayoutUnit logicalHeight = 0, ShapeOutsideFloatOffsetMode offsetMode = ShapeOutsideFloatShapeOffset) const 
198     {
199         return logicalRightOffsetForLine(position, logicalRightOffsetForContent(position), shouldIndentText, 0, logicalHeight, offsetMode);
200     }
201     LayoutUnit logicalLeftOffsetForLine(LayoutUnit position, bool shouldIndentText, LayoutUnit logicalHeight = 0, ShapeOutsideFloatOffsetMode offsetMode = ShapeOutsideFloatShapeOffset) const 
202     {
203         return logicalLeftOffsetForLine(position, logicalLeftOffsetForContent(position), shouldIndentText, 0, logicalHeight, offsetMode);
204     }
205     LayoutUnit pixelSnappedLogicalLeftOffsetForLine(LayoutUnit position, bool shouldIndentText, LayoutUnit logicalHeight = 0) const 
206     {
207         return roundToInt(logicalLeftOffsetForLine(position, shouldIndentText, logicalHeight));
208     }
209     LayoutUnit pixelSnappedLogicalRightOffsetForLine(LayoutUnit position, bool shouldIndentText, LayoutUnit logicalHeight = 0) const 
210     {
211         // FIXME: Multicolumn layouts break carrying over subpixel values to the logical right offset because the lines may be shifted
212         // by a subpixel value for all but the first column. This can lead to the actual pixel snapped width of the column being off
213         // by one pixel when rendered versus layed out, which can result in the line being clipped. For now, we have to floor.
214         // https://bugs.webkit.org/show_bug.cgi?id=105461
215         return floorToInt(logicalRightOffsetForLine(position, shouldIndentText, logicalHeight));
216     }
217     LayoutUnit startOffsetForLine(LayoutUnit position, bool shouldIndentText, LayoutUnit logicalHeight = 0) const
218     {
219         return style()->isLeftToRightDirection() ? logicalLeftOffsetForLine(position, shouldIndentText, logicalHeight)
220             : logicalWidth() - logicalRightOffsetForLine(position, shouldIndentText, logicalHeight);
221     }
222     LayoutUnit endOffsetForLine(LayoutUnit position, bool shouldIndentText, LayoutUnit logicalHeight = 0) const
223     {
224         return !style()->isLeftToRightDirection() ? logicalLeftOffsetForLine(position, shouldIndentText, logicalHeight)
225             : logicalWidth() - logicalRightOffsetForLine(position, shouldIndentText, logicalHeight);
226     }
227
228     LayoutUnit startAlignedOffsetForLine(LayoutUnit position, bool shouldIndentText);
229     LayoutUnit textIndentOffset() const;
230
231     virtual VisiblePosition positionForPoint(const LayoutPoint&);
232     
233     // Block flows subclass availableWidth to handle multi column layout (shrinking the width available to children when laying out.)
234     virtual LayoutUnit availableLogicalWidth() const;
235
236     LayoutPoint flipForWritingModeIncludingColumns(const LayoutPoint&) const;
237     void adjustStartEdgeForWritingModeIncludingColumns(LayoutRect&) const;
238
239     RootInlineBox* firstRootBox() const { return static_cast<RootInlineBox*>(firstLineBox()); }
240     RootInlineBox* lastRootBox() const { return static_cast<RootInlineBox*>(lastLineBox()); }
241
242     bool containsNonZeroBidiLevel() const;
243
244     GapRects selectionGapRectsForRepaint(const RenderLayerModelObject* repaintContainer);
245     LayoutRect logicalLeftSelectionGap(RenderBlock* rootBlock, const LayoutPoint& rootBlockPhysicalPosition, const LayoutSize& offsetFromRootBlock,
246                                        RenderObject* selObj, LayoutUnit logicalLeft, LayoutUnit logicalTop, LayoutUnit logicalHeight, const PaintInfo*);
247     LayoutRect logicalRightSelectionGap(RenderBlock* rootBlock, const LayoutPoint& rootBlockPhysicalPosition, const LayoutSize& offsetFromRootBlock,
248                                         RenderObject* selObj, LayoutUnit logicalRight, LayoutUnit logicalTop, LayoutUnit logicalHeight, const PaintInfo*);
249     void getSelectionGapInfo(SelectionState, bool& leftGap, bool& rightGap);
250     RenderBlock* blockBeforeWithinSelectionRoot(LayoutSize& offset) const;
251
252     LayoutRect logicalRectToPhysicalRect(const LayoutPoint& physicalPosition, const LayoutRect& logicalRect);
253
254     // Helper methods for computing line counts and heights for line counts.
255     RootInlineBox* lineAtIndex(int) const;
256     int lineCount(const RootInlineBox* = 0, bool* = 0) const;
257     int heightForLineCount(int);
258     void clearTruncation();
259
260     void adjustRectForColumns(LayoutRect&) const;
261     virtual void adjustForColumns(LayoutSize&, const LayoutPoint&) const;
262     void adjustForColumnRect(LayoutSize& offset, const LayoutPoint& locationInContainer) const;
263
264     void addContinuationWithOutline(RenderInline*);
265     bool paintsContinuationOutline(RenderInline*);
266
267     virtual RenderBoxModelObject* virtualContinuation() const { return continuation(); }
268     bool isAnonymousBlockContinuation() const { return continuation() && isAnonymousBlock(); }
269     RenderInline* inlineElementContinuation() const;
270     RenderBlock* blockElementContinuation() const;
271
272     using RenderBoxModelObject::continuation;
273     using RenderBoxModelObject::setContinuation;
274
275     static RenderBlock* createAnonymousWithParentRendererAndDisplay(const RenderObject*, EDisplay = BLOCK);
276     static RenderBlock* createAnonymousColumnsWithParentRenderer(const RenderObject*);
277     static RenderBlock* createAnonymousColumnSpanWithParentRenderer(const RenderObject*);
278     RenderBlock* createAnonymousBlock(EDisplay display = BLOCK) const { return createAnonymousWithParentRendererAndDisplay(this, display); }
279     RenderBlock* createAnonymousColumnsBlock() const { return createAnonymousColumnsWithParentRenderer(this); }
280     RenderBlock* createAnonymousColumnSpanBlock() const { return createAnonymousColumnSpanWithParentRenderer(this); }
281
282     virtual RenderBox* createAnonymousBoxWithSameTypeAs(const RenderObject* parent) const OVERRIDE;
283
284     static bool shouldSkipCreatingRunsForObject(RenderObject* obj)
285     {
286         return obj->isFloating() || (obj->isOutOfFlowPositioned() && !obj->style()->isOriginalDisplayInlineType() && !obj->container()->isRenderInline());
287     }
288     
289     static void appendRunsForObject(BidiRunList<BidiRun>&, int start, int end, RenderObject*, InlineBidiResolver&);
290
291     static TextRun constructTextRun(RenderObject* context, const Font& font, const String& string, RenderStyle* style,
292         TextRun::ExpansionBehavior = TextRun::AllowTrailingExpansion | TextRun::ForbidLeadingExpansion, TextRunFlags = DefaultTextRunFlags);
293
294     static TextRun constructTextRun(RenderObject* context, const Font& font, const RenderText* text, RenderStyle* style,
295         TextRun::ExpansionBehavior = TextRun::AllowTrailingExpansion | TextRun::ForbidLeadingExpansion);
296
297     static TextRun constructTextRun(RenderObject* context, const Font& font, const RenderText* text, unsigned offset, unsigned length, RenderStyle* style,
298         TextRun::ExpansionBehavior = TextRun::AllowTrailingExpansion | TextRun::ForbidLeadingExpansion);
299
300     static TextRun constructTextRun(RenderObject* context, const Font& font, const RenderText* text, unsigned offset, RenderStyle* style,
301         TextRun::ExpansionBehavior = TextRun::AllowTrailingExpansion | TextRun::ForbidLeadingExpansion);
302
303 #if ENABLE(8BIT_TEXTRUN)
304     static TextRun constructTextRun(RenderObject* context, const Font& font, const LChar* characters, int length, RenderStyle* style,
305         TextRun::ExpansionBehavior = TextRun::AllowTrailingExpansion | TextRun::ForbidLeadingExpansion);
306 #endif
307
308     static TextRun constructTextRun(RenderObject* context, const Font& font, const UChar* characters, int length, RenderStyle* style,
309         TextRun::ExpansionBehavior = TextRun::AllowTrailingExpansion | TextRun::ForbidLeadingExpansion);
310
311     ColumnInfo* columnInfo() const;
312     int columnGap() const;
313
314     void updateColumnInfoFromStyle(RenderStyle*);
315     
316     // These two functions take the ColumnInfo* to avoid repeated lookups of the info in the global HashMap.
317     unsigned columnCount(ColumnInfo*) const;
318     LayoutRect columnRectAt(ColumnInfo*, unsigned) const;
319
320     LayoutUnit paginationStrut() const { return m_rareData ? m_rareData->m_paginationStrut : LayoutUnit(); }
321     void setPaginationStrut(LayoutUnit);
322
323     bool shouldBreakAtLineToAvoidWidow() const { return m_rareData && m_rareData->m_shouldBreakAtLineToAvoidWidow; }
324     void clearShouldBreakAtLineToAvoidWidow() const;
325     RootInlineBox* lineBreakToAvoidWidow() const { return m_rareData ? m_rareData->m_lineBreakToAvoidWidow : 0; }
326     void setBreakAtLineToAvoidWidow(RootInlineBox*);
327
328     // The page logical offset is the object's offset from the top of the page in the page progression
329     // direction (so an x-offset in vertical text and a y-offset for horizontal text).
330     LayoutUnit pageLogicalOffset() const { return m_rareData ? m_rareData->m_pageLogicalOffset : LayoutUnit(); }
331     void setPageLogicalOffset(LayoutUnit);
332
333     RootInlineBox* lineGridBox() const { return m_rareData ? m_rareData->m_lineGridBox : 0; }
334     void setLineGridBox(RootInlineBox* box)
335     {
336         if (!m_rareData)
337             m_rareData = adoptPtr(new RenderBlockRareData(this));
338         if (m_rareData->m_lineGridBox)
339             m_rareData->m_lineGridBox->destroy(renderArena());
340         m_rareData->m_lineGridBox = box;
341     }
342     void layoutLineGridBox();
343
344     // Accessors for logical width/height and margins in the containing block's block-flow direction.
345     enum ApplyLayoutDeltaMode { ApplyLayoutDelta, DoNotApplyLayoutDelta };
346     LayoutUnit logicalWidthForChild(const RenderBox* child) { return isHorizontalWritingMode() ? child->width() : child->height(); }
347     LayoutUnit logicalHeightForChild(const RenderBox* child) { return isHorizontalWritingMode() ? child->height() : child->width(); }
348     LayoutUnit logicalTopForChild(const RenderBox* child) { return isHorizontalWritingMode() ? child->y() : child->x(); }
349     void setLogicalLeftForChild(RenderBox* child, LayoutUnit logicalLeft, ApplyLayoutDeltaMode = DoNotApplyLayoutDelta);
350     void setLogicalTopForChild(RenderBox* child, LayoutUnit logicalTop, ApplyLayoutDeltaMode = DoNotApplyLayoutDelta);
351     LayoutUnit marginBeforeForChild(const RenderBoxModelObject* child) const { return child->marginBefore(style()); }
352     LayoutUnit marginAfterForChild(const RenderBoxModelObject* child) const { return child->marginAfter(style()); }
353     LayoutUnit marginStartForChild(const RenderBoxModelObject* child) const { return child->marginStart(style()); }
354     LayoutUnit marginEndForChild(const RenderBoxModelObject* child) const { return child->marginEnd(style()); }
355     void setMarginStartForChild(RenderBox* child, LayoutUnit value) const { child->setMarginStart(value, style()); }
356     void setMarginEndForChild(RenderBox* child, LayoutUnit value) const { child->setMarginEnd(value, style()); }
357     void setMarginBeforeForChild(RenderBox* child, LayoutUnit value) const { child->setMarginBefore(value, style()); }
358     void setMarginAfterForChild(RenderBox* child, LayoutUnit value) const { child->setMarginAfter(value, style()); }
359     LayoutUnit collapsedMarginBeforeForChild(const RenderBox* child) const;
360     LayoutUnit collapsedMarginAfterForChild(const RenderBox* child) const;
361
362     void updateLogicalWidthForAlignment(const ETextAlign&, BidiRun* trailingSpaceRun, float& logicalLeft, float& totalLogicalWidth, float& availableLogicalWidth, int expansionOpportunityCount);
363
364     virtual void updateFirstLetter();
365
366     class MarginValues {
367     public:
368         MarginValues(LayoutUnit beforePos, LayoutUnit beforeNeg, LayoutUnit afterPos, LayoutUnit afterNeg)
369             : m_positiveMarginBefore(beforePos)
370             , m_negativeMarginBefore(beforeNeg)
371             , m_positiveMarginAfter(afterPos)
372             , m_negativeMarginAfter(afterNeg)
373         { }
374         
375         LayoutUnit positiveMarginBefore() const { return m_positiveMarginBefore; }
376         LayoutUnit negativeMarginBefore() const { return m_negativeMarginBefore; }
377         LayoutUnit positiveMarginAfter() const { return m_positiveMarginAfter; }
378         LayoutUnit negativeMarginAfter() const { return m_negativeMarginAfter; }
379         
380         void setPositiveMarginBefore(LayoutUnit pos) { m_positiveMarginBefore = pos; }
381         void setNegativeMarginBefore(LayoutUnit neg) { m_negativeMarginBefore = neg; }
382         void setPositiveMarginAfter(LayoutUnit pos) { m_positiveMarginAfter = pos; }
383         void setNegativeMarginAfter(LayoutUnit neg) { m_negativeMarginAfter = neg; }
384     
385     private:
386         LayoutUnit m_positiveMarginBefore;
387         LayoutUnit m_negativeMarginBefore;
388         LayoutUnit m_positiveMarginAfter;
389         LayoutUnit m_negativeMarginAfter;
390     };
391     MarginValues marginValuesForChild(RenderBox* child) const;
392
393     virtual void scrollbarsChanged(bool /*horizontalScrollbarChanged*/, bool /*verticalScrollbarChanged*/) { };
394
395     LayoutUnit logicalLeftOffsetForContent(RenderRegion*, LayoutUnit offsetFromLogicalTopOfFirstPage) const;
396     LayoutUnit logicalRightOffsetForContent(RenderRegion*, LayoutUnit offsetFromLogicalTopOfFirstPage) const;
397     LayoutUnit availableLogicalWidthForContent(RenderRegion* region, LayoutUnit offsetFromLogicalTopOfFirstPage) const
398     { 
399         return max<LayoutUnit>(0, logicalRightOffsetForContent(region, offsetFromLogicalTopOfFirstPage) -
400             logicalLeftOffsetForContent(region, offsetFromLogicalTopOfFirstPage)); }
401     LayoutUnit startOffsetForContent(RenderRegion* region, LayoutUnit offsetFromLogicalTopOfFirstPage) const
402     {
403         return style()->isLeftToRightDirection() ? logicalLeftOffsetForContent(region, offsetFromLogicalTopOfFirstPage)
404             : logicalWidth() - logicalRightOffsetForContent(region, offsetFromLogicalTopOfFirstPage);
405     }
406     LayoutUnit endOffsetForContent(RenderRegion* region, LayoutUnit offsetFromLogicalTopOfFirstPage) const
407     {
408         return !style()->isLeftToRightDirection() ? logicalLeftOffsetForContent(region, offsetFromLogicalTopOfFirstPage)
409             : logicalWidth() - logicalRightOffsetForContent(region, offsetFromLogicalTopOfFirstPage);
410     }
411     LayoutUnit logicalLeftOffsetForContent(LayoutUnit blockOffset) const
412     {
413         return logicalLeftOffsetForContent(regionAtBlockOffset(blockOffset), offsetFromLogicalTopOfFirstPage());
414     }
415     LayoutUnit logicalRightOffsetForContent(LayoutUnit blockOffset) const
416     {
417         return logicalRightOffsetForContent(regionAtBlockOffset(blockOffset), offsetFromLogicalTopOfFirstPage());
418     }
419     LayoutUnit availableLogicalWidthForContent(LayoutUnit blockOffset) const
420     {
421         return availableLogicalWidthForContent(regionAtBlockOffset(blockOffset), offsetFromLogicalTopOfFirstPage());
422     }
423     LayoutUnit startOffsetForContent(LayoutUnit blockOffset) const
424     {
425         return startOffsetForContent(regionAtBlockOffset(blockOffset), offsetFromLogicalTopOfFirstPage());
426     }
427     LayoutUnit endOffsetForContent(LayoutUnit blockOffset) const
428     {
429         return endOffsetForContent(regionAtBlockOffset(blockOffset), offsetFromLogicalTopOfFirstPage());
430     }
431     LayoutUnit logicalLeftOffsetForContent() const { return isHorizontalWritingMode() ? borderLeft() + paddingLeft() : borderTop() + paddingTop(); }
432     LayoutUnit logicalRightOffsetForContent() const { return logicalLeftOffsetForContent() + availableLogicalWidth(); }
433     LayoutUnit startOffsetForContent() const { return style()->isLeftToRightDirection() ? logicalLeftOffsetForContent() : logicalWidth() - logicalRightOffsetForContent(); }
434     LayoutUnit endOffsetForContent() const { return !style()->isLeftToRightDirection() ? logicalLeftOffsetForContent() : logicalWidth() - logicalRightOffsetForContent(); }
435     
436     void setStaticInlinePositionForChild(RenderBox*, LayoutUnit blockOffset, LayoutUnit inlinePosition);
437     void updateStaticInlinePositionForChild(RenderBox*, LayoutUnit logicalTop);
438
439     LayoutUnit computeStartPositionDeltaForChildAvoidingFloats(const RenderBox* child, LayoutUnit childMarginStart, RenderRegion* = 0, LayoutUnit offsetFromLogicalTopOfFirstPage = 0);
440
441     void placeRunInIfNeeded(RenderObject* newChild);
442     bool runInIsPlacedIntoSiblingBlock(RenderObject* runIn);
443
444 #ifndef NDEBUG
445     void checkPositionedObjectsNeedLayout();
446     void showLineTreeAndMark(const InlineBox* = 0, const char* = 0, const InlineBox* = 0, const char* = 0, const RenderObject* = 0) const;
447 #endif
448
449 #if ENABLE(CSS_EXCLUSIONS)
450     ExclusionShapeInsideInfo* ensureExclusionShapeInsideInfo()
451     {
452         if (!m_rareData || !m_rareData->m_shapeInsideInfo)
453             setExclusionShapeInsideInfo(ExclusionShapeInsideInfo::createInfo(this));
454         return m_rareData->m_shapeInsideInfo.get();
455     }
456
457     enum ExclusionShapeStatus { ShapePresent, ShapePresentOrRemoved };
458     ExclusionShapeInsideInfo* exclusionShapeInsideInfo(ExclusionShapeStatus exclusionShapeStatus = ShapePresent) const
459     {
460         if (!m_rareData || !m_rareData->m_shapeInsideInfo)
461             return 0;
462         return ExclusionShapeInsideInfo::isEnabledFor(this) || (exclusionShapeStatus == ShapePresentOrRemoved) ? m_rareData->m_shapeInsideInfo.get() : 0;
463     }
464     void setExclusionShapeInsideInfo(PassOwnPtr<ExclusionShapeInsideInfo> value)
465     {
466         if (!m_rareData)
467             m_rareData = adoptPtr(new RenderBlockRareData(this));
468         m_rareData->m_shapeInsideInfo = value;
469     }
470     ExclusionShapeInsideInfo* layoutExclusionShapeInsideInfo(ExclusionShapeStatus = ShapePresent) const;
471     bool allowsExclusionShapeInsideInfoSharing() const { return !isInline() && !isFloating(); }
472 #endif
473
474 protected:
475     virtual void willBeDestroyed();
476
477     LayoutUnit maxPositiveMarginBefore() const { return m_rareData ? m_rareData->m_margins.positiveMarginBefore() : RenderBlockRareData::positiveMarginBeforeDefault(this); }
478     LayoutUnit maxNegativeMarginBefore() const { return m_rareData ? m_rareData->m_margins.negativeMarginBefore() : RenderBlockRareData::negativeMarginBeforeDefault(this); }
479     LayoutUnit maxPositiveMarginAfter() const { return m_rareData ? m_rareData->m_margins.positiveMarginAfter() : RenderBlockRareData::positiveMarginAfterDefault(this); }
480     LayoutUnit maxNegativeMarginAfter() const { return m_rareData ? m_rareData->m_margins.negativeMarginAfter() : RenderBlockRareData::negativeMarginAfterDefault(this); }
481     
482     void setMaxMarginBeforeValues(LayoutUnit pos, LayoutUnit neg);
483     void setMaxMarginAfterValues(LayoutUnit pos, LayoutUnit neg);
484
485     void setMustDiscardMarginBefore(bool = true);
486     void setMustDiscardMarginAfter(bool = true);
487
488     bool mustDiscardMarginBefore() const;
489     bool mustDiscardMarginAfter() const;
490
491     bool mustDiscardMarginBeforeForChild(const RenderBox*) const;
492     bool mustDiscardMarginAfterForChild(const RenderBox*) const;
493
494     bool mustSeparateMarginBeforeForChild(const RenderBox*) const;
495     bool mustSeparateMarginAfterForChild(const RenderBox*) const;
496
497     void initMaxMarginValues()
498     {
499         if (m_rareData) {
500             m_rareData->m_margins = MarginValues(RenderBlockRareData::positiveMarginBeforeDefault(this) , RenderBlockRareData::negativeMarginBeforeDefault(this),
501                                                  RenderBlockRareData::positiveMarginAfterDefault(this), RenderBlockRareData::negativeMarginAfterDefault(this));
502             m_rareData->m_paginationStrut = 0;
503
504             m_rareData->m_discardMarginBefore = false;
505             m_rareData->m_discardMarginAfter = false;
506         }
507     }
508
509     virtual void layout();
510
511     void layoutPositionedObjects(bool relayoutChildren, bool fixedPositionObjectsOnly = false);
512     void markFixedPositionObjectForLayoutIfNeeded(RenderObject* child);
513
514     virtual void paint(PaintInfo&, const LayoutPoint&);
515     virtual void paintObject(PaintInfo&, const LayoutPoint&);
516     virtual void paintChildren(PaintInfo& forSelf, const LayoutPoint&, PaintInfo& forChild, bool usePrintRect);
517     bool paintChild(RenderBox*, PaintInfo& forSelf, const LayoutPoint&, PaintInfo& forChild, bool usePrintRect);
518    
519     LayoutUnit logicalRightOffsetForLine(LayoutUnit position, LayoutUnit fixedOffset, bool applyTextIndent, LayoutUnit* logicalHeightRemaining = 0, LayoutUnit logicalHeight = 0, ShapeOutsideFloatOffsetMode = ShapeOutsideFloatShapeOffset) const;
520     LayoutUnit logicalLeftOffsetForLine(LayoutUnit position, LayoutUnit fixedOffset, bool applyTextIndent, LayoutUnit* logicalHeightRemaining = 0, LayoutUnit logicalHeight = 0, ShapeOutsideFloatOffsetMode = ShapeOutsideFloatShapeOffset) const;
521
522     virtual ETextAlign textAlignmentForLine(bool endsWithSoftBreak) const;
523     virtual void adjustInlineDirectionLineBounds(int /* expansionOpportunityCount */, float& /* logicalLeft */, float& /* logicalWidth */) const { }
524
525     virtual bool nodeAtPoint(const HitTestRequest&, HitTestResult&, const HitTestLocation& locationInContainer, const LayoutPoint& accumulatedOffset, HitTestAction) OVERRIDE;
526
527     virtual void computeIntrinsicLogicalWidths(LayoutUnit& minLogicalWidth, LayoutUnit& maxLogicalWidth) const OVERRIDE;
528     virtual void computePreferredLogicalWidths() OVERRIDE;
529
530     virtual int firstLineBoxBaseline() const;
531     virtual int inlineBlockBaseline(LineDirectionMode) const OVERRIDE;
532     int lastLineBoxBaseline(LineDirectionMode) const;
533
534     virtual void updateHitTestResult(HitTestResult&, const LayoutPoint&);
535
536     // Delay update scrollbar until finishDelayRepaint() will be
537     // called. This function is used when a flexbox is laying out its
538     // descendant. If multiple calls are made to startDelayRepaint(),
539     // finishDelayRepaint() will do nothing until finishDelayRepaint()
540     // is called the same number of times.
541     static void startDelayUpdateScrollInfo();
542     static void finishDelayUpdateScrollInfo();
543
544     void updateScrollInfoAfterLayout();
545
546     virtual void styleWillChange(StyleDifference, const RenderStyle* newStyle);
547     virtual void styleDidChange(StyleDifference, const RenderStyle* oldStyle);
548
549     virtual bool hasLineIfEmpty() const;
550     
551     bool simplifiedLayout();
552     virtual void simplifiedNormalFlowLayout();
553
554     void setDesiredColumnCountAndWidth(int, LayoutUnit);
555
556 public:
557     void computeOverflow(LayoutUnit oldClientAfterEdge, bool recomputeFloats = false);
558 protected:
559     virtual void addOverflowFromChildren();
560     void addOverflowFromFloats();
561     void addOverflowFromPositionedObjects();
562     void addOverflowFromBlockChildren();
563     void addOverflowFromInlineChildren();
564     void addVisualOverflowFromTheme();
565
566     virtual void addFocusRingRects(Vector<IntRect>&, const LayoutPoint& additionalOffset, const RenderLayerModelObject* paintContainer = 0) OVERRIDE;
567
568 #if ENABLE(SVG)
569     // Only used by RenderSVGText, which explicitely overrides RenderBlock::layoutBlock(), do NOT use for anything else.
570     void forceLayoutInlineChildren()
571     {
572         LayoutUnit repaintLogicalTop = 0;
573         LayoutUnit repaintLogicalBottom = 0;
574         clearFloats();
575         layoutInlineChildren(true, repaintLogicalTop, repaintLogicalBottom);
576     }
577 #endif
578
579     bool updateRegionsAndExclusionsBeforeChildLayout(RenderFlowThread*);
580     void updateRegionsAndExclusionsAfterChildLayout(RenderFlowThread*, bool heightChanged = false);
581     void computeRegionRangeForBlock(RenderFlowThread*);
582
583     void updateBlockChildDirtyBitsBeforeLayout(bool relayoutChildren, RenderBox*);
584
585     virtual void checkForPaginationLogicalHeightChange(LayoutUnit& pageLogicalHeight, bool& pageLogicalHeightChanged, bool& hasSpecifiedPageLogicalHeight);
586
587 private:
588 #if ENABLE(CSS_EXCLUSIONS)
589     void computeExclusionShapeSize();
590     void updateExclusionShapeInsideInfoAfterStyleChange(const ExclusionShapeValue*, const ExclusionShapeValue* oldExclusionShape);
591 #endif
592     virtual RenderObjectChildList* virtualChildren() { return children(); }
593     virtual const RenderObjectChildList* virtualChildren() const { return children(); }
594
595     virtual const char* renderName() const;
596
597     virtual bool isRenderBlock() const { return true; }
598     virtual bool isBlockFlow() const { return (!isInline() || isReplaced()) && !isTable(); }
599     virtual bool isInlineBlockOrInlineTable() const { return isInline() && isReplaced(); }
600
601     void makeChildrenNonInline(RenderObject* insertionPoint = 0);
602     virtual void removeLeftoverAnonymousBlock(RenderBlock* child);
603
604     static void collapseAnonymousBoxChild(RenderBlock* parent, RenderObject* child);
605
606     virtual void dirtyLinesFromChangedChild(RenderObject* child) { m_lineBoxes.dirtyLinesFromChangedChild(this, child); }
607
608     void addChildToContinuation(RenderObject* newChild, RenderObject* beforeChild);
609     void addChildIgnoringContinuation(RenderObject* newChild, RenderObject* beforeChild);
610     void addChildToAnonymousColumnBlocks(RenderObject* newChild, RenderObject* beforeChild);
611
612     virtual void addChildIgnoringAnonymousColumnBlocks(RenderObject* newChild, RenderObject* beforeChild = 0);
613     
614     virtual bool isSelfCollapsingBlock() const;
615
616     virtual LayoutUnit collapsedMarginBefore() const { return maxPositiveMarginBefore() - maxNegativeMarginBefore(); }
617     virtual LayoutUnit collapsedMarginAfter() const { return maxPositiveMarginAfter() - maxNegativeMarginAfter(); }
618
619     virtual void repaintOverhangingFloats(bool paintAllDescendants) OVERRIDE;
620
621     void layoutBlockChildren(bool relayoutChildren, LayoutUnit& maxFloatLogicalBottom);
622     void layoutInlineChildren(bool relayoutChildren, LayoutUnit& repaintLogicalTop, LayoutUnit& repaintLogicalBottom);
623     BidiRun* handleTrailingSpaces(BidiRunList<BidiRun>&, BidiContext*);
624
625     void insertIntoTrackedRendererMaps(RenderBox* descendant, TrackedDescendantsMap*&, TrackedContainerMap*&);
626     static void removeFromTrackedRendererMaps(RenderBox* descendant, TrackedDescendantsMap*&, TrackedContainerMap*&);
627
628     virtual RootInlineBox* createRootInlineBox(); // Subclassed by SVG and Ruby.
629
630     // Called to lay out the legend for a fieldset or the ruby text of a ruby run.
631     virtual RenderObject* layoutSpecialExcludedChild(bool /*relayoutChildren*/) { return 0; }
632
633     void createFirstLetterRenderer(RenderObject* firstLetterBlock, RenderObject* currentChild);
634     void updateFirstLetterStyle(RenderObject* firstLetterBlock, RenderObject* firstLetterContainer);
635
636     Node* nodeForHitTest() const;
637
638     struct FloatWithRect {
639         FloatWithRect(RenderBox* f)
640             : object(f)
641             , rect(LayoutRect(f->x() - f->marginLeft(), f->y() - f->marginTop(), f->width() + f->marginWidth(), f->height() + f->marginHeight()))
642             , everHadLayout(f->everHadLayout())
643         {
644         }
645
646         RenderBox* object;
647         LayoutRect rect;
648         bool everHadLayout;
649     };
650
651     struct FloatingObject {
652         WTF_MAKE_NONCOPYABLE(FloatingObject); WTF_MAKE_FAST_ALLOCATED;
653     public:
654         // Note that Type uses bits so you can use FloatLeftRight as a mask to query for both left and right.
655         enum Type { FloatLeft = 1, FloatRight = 2, FloatLeftRight = 3 };
656
657         FloatingObject(EFloat type)
658             : m_renderer(0)
659             , m_originatingLine(0)
660             , m_paginationStrut(0)
661             , m_shouldPaint(true)
662             , m_isDescendant(false)
663             , m_isPlaced(false)
664 #ifndef NDEBUG
665             , m_isInPlacedTree(false)
666 #endif
667         {
668             ASSERT(type != NoFloat);
669             if (type == LeftFloat)
670                 m_type = FloatLeft;
671             else if (type == RightFloat)
672                 m_type = FloatRight;  
673         }
674
675         FloatingObject(Type type, const LayoutRect& frameRect)
676             : m_renderer(0)
677             , m_originatingLine(0)
678             , m_frameRect(frameRect)
679             , m_paginationStrut(0)
680             , m_type(type)
681             , m_shouldPaint(true)
682             , m_isDescendant(false)
683             , m_isPlaced(true)
684 #ifndef NDEBUG
685             , m_isInPlacedTree(false)
686 #endif
687         {
688         }
689
690         Type type() const { return static_cast<Type>(m_type); }
691         RenderBox* renderer() const { return m_renderer; }
692         
693         bool isPlaced() const { return m_isPlaced; }
694         void setIsPlaced(bool placed = true) { m_isPlaced = placed; }
695
696         inline LayoutUnit x() const { ASSERT(isPlaced()); return m_frameRect.x(); }
697         inline LayoutUnit maxX() const { ASSERT(isPlaced()); return m_frameRect.maxX(); }
698         inline LayoutUnit y() const { ASSERT(isPlaced()); return m_frameRect.y(); }
699         inline LayoutUnit maxY() const { ASSERT(isPlaced()); return m_frameRect.maxY(); }
700         inline LayoutUnit width() const { return m_frameRect.width(); }
701         inline LayoutUnit height() const { return m_frameRect.height(); }
702
703         void setX(LayoutUnit x) { ASSERT(!isInPlacedTree()); m_frameRect.setX(x); }
704         void setY(LayoutUnit y) { ASSERT(!isInPlacedTree()); m_frameRect.setY(y); }
705         void setWidth(LayoutUnit width) { ASSERT(!isInPlacedTree()); m_frameRect.setWidth(width); }
706         void setHeight(LayoutUnit height) { ASSERT(!isInPlacedTree()); m_frameRect.setHeight(height); }
707
708         const LayoutRect& frameRect() const { ASSERT(isPlaced()); return m_frameRect; }
709         void setFrameRect(const LayoutRect& frameRect) { ASSERT(!isInPlacedTree()); m_frameRect = frameRect; }
710
711 #ifndef NDEBUG
712         bool isInPlacedTree() const { return m_isInPlacedTree; }
713         void setIsInPlacedTree(bool value) { m_isInPlacedTree = value; }
714 #endif
715
716         bool shouldPaint() const { return m_shouldPaint; }
717         void setShouldPaint(bool shouldPaint) { m_shouldPaint = shouldPaint; }
718         bool isDescendant() const { return m_isDescendant; }
719         void setIsDescendant(bool isDescendant) { m_isDescendant = isDescendant; }
720
721         RenderBox* m_renderer;
722         RootInlineBox* m_originatingLine;
723         LayoutRect m_frameRect;
724         int m_paginationStrut;
725
726     private:
727         unsigned m_type : 2; // Type (left or right aligned)
728         unsigned m_shouldPaint : 1;
729         unsigned m_isDescendant : 1;
730         unsigned m_isPlaced : 1;
731 #ifndef NDEBUG
732         unsigned m_isInPlacedTree : 1;
733 #endif
734     };
735
736     LayoutPoint flipFloatForWritingModeForChild(const FloatingObject*, const LayoutPoint&) const;
737
738     LayoutUnit logicalTopForFloat(const FloatingObject* child) const { return isHorizontalWritingMode() ? child->y() : child->x(); }
739     LayoutUnit logicalBottomForFloat(const FloatingObject* child) const { return isHorizontalWritingMode() ? child->maxY() : child->maxX(); }
740     LayoutUnit logicalLeftForFloat(const FloatingObject* child) const { return isHorizontalWritingMode() ? child->x() : child->y(); }
741     LayoutUnit logicalRightForFloat(const FloatingObject* child) const { return isHorizontalWritingMode() ? child->maxX() : child->maxY(); }
742     LayoutUnit logicalWidthForFloat(const FloatingObject* child) const { return isHorizontalWritingMode() ? child->width() : child->height(); }
743
744     int pixelSnappedLogicalTopForFloat(const FloatingObject* child) const { return isHorizontalWritingMode() ? child->frameRect().pixelSnappedY() : child->frameRect().pixelSnappedX(); }
745     int pixelSnappedLogicalBottomForFloat(const FloatingObject* child) const { return isHorizontalWritingMode() ? child->frameRect().pixelSnappedMaxY() : child->frameRect().pixelSnappedMaxX(); }
746     int pixelSnappedLogicalLeftForFloat(const FloatingObject* child) const { return isHorizontalWritingMode() ? child->frameRect().pixelSnappedX() : child->frameRect().pixelSnappedY(); }
747     int pixelSnappedLogicalRightForFloat(const FloatingObject* child) const { return isHorizontalWritingMode() ? child->frameRect().pixelSnappedMaxX() : child->frameRect().pixelSnappedMaxY(); }
748
749     void setLogicalTopForFloat(FloatingObject* child, LayoutUnit logicalTop)
750     {
751         if (isHorizontalWritingMode())
752             child->setY(logicalTop);
753         else
754             child->setX(logicalTop);
755     }
756     void setLogicalLeftForFloat(FloatingObject* child, LayoutUnit logicalLeft)
757     {
758         if (isHorizontalWritingMode())
759             child->setX(logicalLeft);
760         else
761             child->setY(logicalLeft);
762     }
763     void setLogicalHeightForFloat(FloatingObject* child, LayoutUnit logicalHeight)
764     {
765         if (isHorizontalWritingMode())
766             child->setHeight(logicalHeight);
767         else
768             child->setWidth(logicalHeight);
769     }
770     void setLogicalWidthForFloat(FloatingObject* child, LayoutUnit logicalWidth)
771     {
772         if (isHorizontalWritingMode())
773             child->setWidth(logicalWidth);
774         else
775             child->setHeight(logicalWidth);
776     }
777
778     LayoutUnit xPositionForFloatIncludingMargin(const FloatingObject* child) const
779     {
780 #if ENABLE(CSS_EXCLUSIONS)
781         ExclusionShapeOutsideInfo *shapeOutside = child->renderer()->exclusionShapeOutsideInfo();
782         if (shapeOutside)
783             return child->x();
784 #endif
785
786         if (isHorizontalWritingMode())
787             return child->x() + child->renderer()->marginLeft();
788         else
789             return child->x() + marginBeforeForChild(child->renderer());
790     }
791         
792     LayoutUnit yPositionForFloatIncludingMargin(const FloatingObject* child) const
793     {
794 #if ENABLE(CSS_EXCLUSIONS)
795         ExclusionShapeOutsideInfo *shapeOutside = child->renderer()->exclusionShapeOutsideInfo();
796         if (shapeOutside)
797             return child->y();
798 #endif
799
800         if (isHorizontalWritingMode())
801             return child->y() + marginBeforeForChild(child->renderer());
802         else
803             return child->y() + child->renderer()->marginTop();
804     }
805
806     LayoutPoint computeLogicalLocationForFloat(const FloatingObject*, LayoutUnit logicalTopOffset) const;
807
808     // The following functions' implementations are in RenderBlockLineLayout.cpp.
809     struct RenderTextInfo {
810         // Destruction of m_layout requires TextLayout to be a complete type, so the constructor and destructor are made non-inline to avoid compilation errors.
811         RenderTextInfo();
812         ~RenderTextInfo();
813
814         RenderText* m_text;
815         OwnPtr<TextLayout> m_layout;
816         LazyLineBreakIterator m_lineBreakIterator;
817         const Font* m_font;
818     };
819
820     class LineBreaker {
821     public:
822         LineBreaker(RenderBlock* block)
823             : m_block(block)
824         {
825             reset();
826         }
827
828         InlineIterator nextLineBreak(InlineBidiResolver&, LineInfo&, RenderTextInfo&, FloatingObject* lastFloatFromPreviousLine, unsigned consecutiveHyphenatedLines, WordMeasurements&);
829
830         bool lineWasHyphenated() { return m_hyphenated; }
831         const Vector<RenderBox*>& positionedObjects() { return m_positionedObjects; }
832         EClear clear() { return m_clear; }
833     private:
834         void reset();
835         
836         InlineIterator nextSegmentBreak(InlineBidiResolver&, LineInfo&, RenderTextInfo&, FloatingObject* lastFloatFromPreviousLine, unsigned consecutiveHyphenatedLines, WordMeasurements&);
837         void skipTrailingWhitespace(InlineIterator&, const LineInfo&);
838         void skipLeadingWhitespace(InlineBidiResolver&, LineInfo&, FloatingObject* lastFloatFromPreviousLine, LineWidth&);
839         
840         RenderBlock* m_block;
841         bool m_hyphenated;
842         EClear m_clear;
843         Vector<RenderBox*> m_positionedObjects;
844     };
845
846     void checkFloatsInCleanLine(RootInlineBox*, Vector<FloatWithRect>&, size_t& floatIndex, bool& encounteredNewFloat, bool& dirtiedByFloat);
847     RootInlineBox* determineStartPosition(LineLayoutState&, InlineBidiResolver&);
848     void determineEndPosition(LineLayoutState&, RootInlineBox* startBox, InlineIterator& cleanLineStart, BidiStatus& cleanLineBidiStatus);
849     bool matchedEndLine(LineLayoutState&, const InlineBidiResolver&, const InlineIterator& endLineStart, const BidiStatus& endLineStatus);
850     bool checkPaginationAndFloatsAtEndLine(LineLayoutState&);
851     
852     RootInlineBox* constructLine(BidiRunList<BidiRun>&, const LineInfo&);
853     InlineFlowBox* createLineBoxes(RenderObject*, const LineInfo&, InlineBox* childBox, bool startsNewSegment);
854
855     void setMarginsForRubyRun(BidiRun*, RenderRubyRun*, RenderObject*, const LineInfo&);
856
857     BidiRun* computeInlineDirectionPositionsForSegment(RootInlineBox*, const LineInfo&, ETextAlign, float& logicalLeft,
858         float& availableLogicalWidth, BidiRun* firstRun, BidiRun* trailingSpaceRun, GlyphOverflowAndFallbackFontsMap& textBoxDataMap, VerticalPositionCache&, WordMeasurements&);
859     void computeInlineDirectionPositionsForLine(RootInlineBox*, const LineInfo&, BidiRun* firstRun, BidiRun* trailingSpaceRun, bool reachedEnd, GlyphOverflowAndFallbackFontsMap&, VerticalPositionCache&, WordMeasurements&);
860     void computeBlockDirectionPositionsForLine(RootInlineBox*, BidiRun*, GlyphOverflowAndFallbackFontsMap&, VerticalPositionCache&);
861     void deleteEllipsisLineBoxes();
862     void checkLinesForTextOverflow();
863
864     // Positions new floats and also adjust all floats encountered on the line if any of them
865     // have to move to the next page/column.
866     bool positionNewFloatOnLine(FloatingObject* newFloat, FloatingObject* lastFloatFromPreviousLine, LineInfo&, LineWidth&);
867     void appendFloatingObjectToLastLine(FloatingObject*);
868
869     // End of functions defined in RenderBlockLineLayout.cpp.
870
871     void paintFloats(PaintInfo&, const LayoutPoint&, bool preservePhase = false);
872     void paintContents(PaintInfo&, const LayoutPoint&);
873     void paintColumnContents(PaintInfo&, const LayoutPoint&, bool paintFloats = false);
874     void paintColumnRules(PaintInfo&, const LayoutPoint&);
875     void paintSelection(PaintInfo&, const LayoutPoint&);
876     void paintCaret(PaintInfo&, const LayoutPoint&, CaretType);
877
878     FloatingObject* insertFloatingObject(RenderBox*);
879     void removeFloatingObject(RenderBox*);
880     void removeFloatingObjectsBelow(FloatingObject*, int logicalOffset);
881     
882     // Called from lineWidth, to position the floats added in the last line.
883     // Returns true if and only if it has positioned any floats.
884     bool positionNewFloats();
885
886     void clearFloats();
887
888     LayoutUnit getClearDelta(RenderBox* child, LayoutUnit yPos);
889
890     virtual bool avoidsFloats() const;
891
892     bool hasOverhangingFloats() { return parent() && !hasColumns() && containsFloats() && lowestFloatLogicalBottom() > logicalHeight(); }
893     bool hasOverhangingFloat(RenderBox*);
894     void addIntrudingFloats(RenderBlock* prev, LayoutUnit xoffset, LayoutUnit yoffset);
895     LayoutUnit addOverhangingFloats(RenderBlock* child, bool makeChildPaintOtherFloats);
896
897     LayoutUnit lowestFloatLogicalBottom(FloatingObject::Type = FloatingObject::FloatLeftRight) const; 
898     LayoutUnit nextFloatLogicalBottomBelow(LayoutUnit) const;
899     
900     virtual bool hitTestColumns(const HitTestRequest&, HitTestResult&, const HitTestLocation& locationInContainer, const LayoutPoint& accumulatedOffset, HitTestAction);
901     virtual bool hitTestContents(const HitTestRequest&, HitTestResult&, const HitTestLocation& locationInContainer, const LayoutPoint& accumulatedOffset, HitTestAction);
902     bool hitTestFloats(const HitTestRequest&, HitTestResult&, const HitTestLocation& locationInContainer, const LayoutPoint& accumulatedOffset);
903
904     virtual bool isPointInOverflowControl(HitTestResult&, const LayoutPoint& locationInContainer, const LayoutPoint& accumulatedOffset);
905
906     // FIXME: Make this method const so we can remove the const_cast in computeIntrinsicLogicalWidths.
907     void computeInlinePreferredLogicalWidths(LayoutUnit& minLogicalWidth, LayoutUnit& maxLogicalWidth);
908     void computeBlockPreferredLogicalWidths(LayoutUnit& minLogicalWidth, LayoutUnit& maxLogicalWidth) const;
909
910     // Obtains the nearest enclosing block (including this block) that contributes a first-line style to our inline
911     // children.
912     virtual RenderBlock* firstLineBlock() const;
913
914     virtual LayoutRect rectWithOutlineForRepaint(const RenderLayerModelObject* repaintContainer, LayoutUnit outlineWidth) const OVERRIDE;
915     virtual RenderStyle* outlineStyleForRepaint() const;
916     
917     virtual RenderObject* hoverAncestor() const;
918     virtual void updateDragState(bool dragOn);
919     virtual void childBecameNonInline(RenderObject* child);
920
921     virtual LayoutRect selectionRectForRepaint(const RenderLayerModelObject* repaintContainer, bool /*clipToVisibleContent*/) OVERRIDE
922     {
923         return selectionGapRectsForRepaint(repaintContainer);
924     }
925     virtual bool shouldPaintSelectionGaps() const;
926     bool isSelectionRoot() const;
927     GapRects selectionGaps(RenderBlock* rootBlock, const LayoutPoint& rootBlockPhysicalPosition, const LayoutSize& offsetFromRootBlock,
928                            LayoutUnit& lastLogicalTop, LayoutUnit& lastLogicalLeft, LayoutUnit& lastLogicalRight, const PaintInfo* = 0);
929     GapRects inlineSelectionGaps(RenderBlock* rootBlock, const LayoutPoint& rootBlockPhysicalPosition, const LayoutSize& offsetFromRootBlock,
930                                  LayoutUnit& lastLogicalTop, LayoutUnit& lastLogicalLeft, LayoutUnit& lastLogicalRight, const PaintInfo*);
931     GapRects blockSelectionGaps(RenderBlock* rootBlock, const LayoutPoint& rootBlockPhysicalPosition, const LayoutSize& offsetFromRootBlock,
932                                 LayoutUnit& lastLogicalTop, LayoutUnit& lastLogicalLeft, LayoutUnit& lastLogicalRight, const PaintInfo*);
933     LayoutRect blockSelectionGap(RenderBlock* rootBlock, const LayoutPoint& rootBlockPhysicalPosition, const LayoutSize& offsetFromRootBlock,
934                                  LayoutUnit lastLogicalTop, LayoutUnit lastLogicalLeft, LayoutUnit lastLogicalRight, LayoutUnit logicalBottom, const PaintInfo*);
935     LayoutUnit logicalLeftSelectionOffset(RenderBlock* rootBlock, LayoutUnit position);
936     LayoutUnit logicalRightSelectionOffset(RenderBlock* rootBlock, LayoutUnit position);
937
938     virtual void absoluteRects(Vector<IntRect>&, const LayoutPoint& accumulatedOffset) const;
939     virtual void absoluteQuads(Vector<FloatQuad>&, bool* wasFixed) const;
940
941     LayoutUnit desiredColumnWidth() const;
942     unsigned desiredColumnCount() const;
943
944     void paintContinuationOutlines(PaintInfo&, const LayoutPoint&);
945
946     virtual LayoutRect localCaretRect(InlineBox*, int caretOffset, LayoutUnit* extraWidthToEndOfLine = 0);
947
948     void adjustPointToColumnContents(LayoutPoint&) const;
949     
950     void fitBorderToLinesIfNeeded(); // Shrink the box in which the border paints if border-fit is set.
951     void adjustForBorderFit(LayoutUnit x, LayoutUnit& left, LayoutUnit& right) const; // Helper function for borderFitAdjust
952
953     void markLinesDirtyInBlockRange(LayoutUnit logicalTop, LayoutUnit logicalBottom, RootInlineBox* highest = 0);
954
955     void newLine(EClear);
956
957     Position positionForBox(InlineBox*, bool start = true) const;
958     VisiblePosition positionForPointWithInlineChildren(const LayoutPoint&);
959
960     virtual void calcColumnWidth();
961     void makeChildrenAnonymousColumnBlocks(RenderObject* beforeChild, RenderBlock* newBlockBox, RenderObject* newChild);
962
963     bool expandsToEncloseOverhangingFloats() const;
964
965     void splitBlocks(RenderBlock* fromBlock, RenderBlock* toBlock, RenderBlock* middleBlock,
966                      RenderObject* beforeChild, RenderBoxModelObject* oldCont);
967     void splitFlow(RenderObject* beforeChild, RenderBlock* newBlockBox,
968                    RenderObject* newChild, RenderBoxModelObject* oldCont);
969     RenderBlock* clone() const;
970     RenderBlock* continuationBefore(RenderObject* beforeChild);
971     RenderBlock* containingColumnsBlock(bool allowAnonymousColumnBlock = true);
972     RenderBlock* columnsBlockForSpanningElement(RenderObject* newChild);
973
974     class MarginInfo {
975         // Collapsing flags for whether we can collapse our margins with our children's margins.
976         bool m_canCollapseWithChildren : 1;
977         bool m_canCollapseMarginBeforeWithChildren : 1;
978         bool m_canCollapseMarginAfterWithChildren : 1;
979
980         // Whether or not we are a quirky container, i.e., do we collapse away top and bottom
981         // margins in our container.  Table cells and the body are the common examples. We
982         // also have a custom style property for Safari RSS to deal with TypePad blog articles.
983         bool m_quirkContainer : 1;
984
985         // This flag tracks whether we are still looking at child margins that can all collapse together at the beginning of a block.  
986         // They may or may not collapse with the top margin of the block (|m_canCollapseTopWithChildren| tells us that), but they will
987         // always be collapsing with one another.  This variable can remain set to true through multiple iterations 
988         // as long as we keep encountering self-collapsing blocks.
989         bool m_atBeforeSideOfBlock : 1;
990
991         // This flag is set when we know we're examining bottom margins and we know we're at the bottom of the block.
992         bool m_atAfterSideOfBlock : 1;
993
994         // These variables are used to detect quirky margins that we need to collapse away (in table cells
995         // and in the body element).
996         bool m_hasMarginBeforeQuirk : 1;
997         bool m_hasMarginAfterQuirk : 1;
998         bool m_determinedMarginBeforeQuirk : 1;
999
1000         bool m_discardMargin : 1;
1001
1002         // These flags track the previous maximal positive and negative margins.
1003         LayoutUnit m_positiveMargin;
1004         LayoutUnit m_negativeMargin;
1005
1006     public:
1007         MarginInfo(RenderBlock*, LayoutUnit beforeBorderPadding, LayoutUnit afterBorderPadding);
1008
1009         void setAtBeforeSideOfBlock(bool b) { m_atBeforeSideOfBlock = b; }
1010         void setAtAfterSideOfBlock(bool b) { m_atAfterSideOfBlock = b; }
1011         void clearMargin()
1012         {
1013             m_positiveMargin = 0;
1014             m_negativeMargin = 0;
1015         }
1016         void setHasMarginBeforeQuirk(bool b) { m_hasMarginBeforeQuirk = b; }
1017         void setHasMarginAfterQuirk(bool b) { m_hasMarginAfterQuirk = b; }
1018         void setDeterminedMarginBeforeQuirk(bool b) { m_determinedMarginBeforeQuirk = b; }
1019         void setPositiveMargin(LayoutUnit p) { ASSERT(!m_discardMargin); m_positiveMargin = p; }
1020         void setNegativeMargin(LayoutUnit n) { ASSERT(!m_discardMargin); m_negativeMargin = n; }
1021         void setPositiveMarginIfLarger(LayoutUnit p)
1022         {
1023             ASSERT(!m_discardMargin);
1024             if (p > m_positiveMargin)
1025                 m_positiveMargin = p;
1026         }
1027         void setNegativeMarginIfLarger(LayoutUnit n)
1028         {
1029             ASSERT(!m_discardMargin);
1030             if (n > m_negativeMargin)
1031                 m_negativeMargin = n;
1032         }
1033
1034         void setMargin(LayoutUnit p, LayoutUnit n) { ASSERT(!m_discardMargin); m_positiveMargin = p; m_negativeMargin = n; }
1035         void setCanCollapseMarginAfterWithChildren(bool collapse) { m_canCollapseMarginAfterWithChildren = collapse; }
1036         void setDiscardMargin(bool value) { m_discardMargin = value; }
1037
1038         bool atBeforeSideOfBlock() const { return m_atBeforeSideOfBlock; }
1039         bool canCollapseWithMarginBefore() const { return m_atBeforeSideOfBlock && m_canCollapseMarginBeforeWithChildren; }
1040         bool canCollapseWithMarginAfter() const { return m_atAfterSideOfBlock && m_canCollapseMarginAfterWithChildren; }
1041         bool canCollapseMarginBeforeWithChildren() const { return m_canCollapseMarginBeforeWithChildren; }
1042         bool canCollapseMarginAfterWithChildren() const { return m_canCollapseMarginAfterWithChildren; }
1043         bool quirkContainer() const { return m_quirkContainer; }
1044         bool determinedMarginBeforeQuirk() const { return m_determinedMarginBeforeQuirk; }
1045         bool hasMarginBeforeQuirk() const { return m_hasMarginBeforeQuirk; }
1046         bool hasMarginAfterQuirk() const { return m_hasMarginAfterQuirk; }
1047         LayoutUnit positiveMargin() const { return m_positiveMargin; }
1048         LayoutUnit negativeMargin() const { return m_negativeMargin; }
1049         bool discardMargin() const { return m_discardMargin; }
1050         LayoutUnit margin() const { return m_positiveMargin - m_negativeMargin; }
1051     };
1052
1053     void layoutBlockChild(RenderBox* child, MarginInfo&, LayoutUnit& previousFloatLogicalBottom, LayoutUnit& maxFloatLogicalBottom);
1054     void adjustPositionedBlock(RenderBox* child, const MarginInfo&);
1055     void adjustFloatingBlock(const MarginInfo&);
1056
1057     RenderBoxModelObject* createReplacementRunIn(RenderBoxModelObject* runIn);
1058     void moveRunInUnderSiblingBlockIfNeeded(RenderObject* runIn);
1059     void moveRunInToOriginalPosition(RenderObject* runIn);
1060
1061     LayoutUnit collapseMargins(RenderBox* child, MarginInfo&);
1062     LayoutUnit clearFloatsIfNeeded(RenderBox* child, MarginInfo&, LayoutUnit oldTopPosMargin, LayoutUnit oldTopNegMargin, LayoutUnit yPos);
1063     LayoutUnit estimateLogicalTopPosition(RenderBox* child, const MarginInfo&, LayoutUnit& estimateWithoutPagination);
1064     void marginBeforeEstimateForChild(RenderBox*, LayoutUnit&, LayoutUnit&, bool&) const;
1065     void handleAfterSideOfBlock(LayoutUnit top, LayoutUnit bottom, MarginInfo&);
1066     void setCollapsedBottomMargin(const MarginInfo&);
1067     // End helper functions and structs used by layoutBlockChildren.
1068
1069     // Helper function for layoutInlineChildren()
1070     RootInlineBox* createLineBoxesFromBidiRuns(BidiRunList<BidiRun>&, const InlineIterator& end, LineInfo&, VerticalPositionCache&, BidiRun* trailingSpaceRun, WordMeasurements&);
1071     void layoutRunsAndFloats(LineLayoutState&, bool hasInlineChild);
1072     void layoutRunsAndFloatsInRange(LineLayoutState&, InlineBidiResolver&, const InlineIterator& cleanLineStart, const BidiStatus& cleanLineBidiStatus, unsigned consecutiveHyphenatedLines);
1073     const InlineIterator& restartLayoutRunsAndFloatsInRange(LayoutUnit oldLogicalHeight, LayoutUnit newLogicalHeight,  FloatingObject* lastFloatFromPreviousLine, InlineBidiResolver&,  const InlineIterator&);
1074     void linkToEndLineIfNeeded(LineLayoutState&);
1075     static void repaintDirtyFloats(Vector<FloatWithRect>& floats);
1076
1077 protected:
1078     void determineLogicalLeftPositionForChild(RenderBox* child, ApplyLayoutDeltaMode = DoNotApplyLayoutDelta);
1079
1080     // Pagination routines.
1081     virtual bool relayoutForPagination(bool hasSpecifiedPageLogicalHeight, LayoutUnit pageLogicalHeight, LayoutStateMaintainer&);
1082     
1083     // Returns the logicalOffset at the top of the next page. If the offset passed in is already at the top of the current page,
1084     // then nextPageLogicalTop with ExcludePageBoundary will still move to the top of the next page. nextPageLogicalTop with
1085     // IncludePageBoundary set will not.
1086     //
1087     // 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.
1088     enum PageBoundaryRule { ExcludePageBoundary, IncludePageBoundary };
1089     LayoutUnit nextPageLogicalTop(LayoutUnit logicalOffset, PageBoundaryRule = ExcludePageBoundary) const;
1090     bool hasNextPage(LayoutUnit logicalOffset, PageBoundaryRule = ExcludePageBoundary) const;
1091
1092     virtual ColumnInfo::PaginationUnit paginationUnit() const;
1093
1094     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.
1095     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.
1096
1097 public:
1098     LayoutUnit pageLogicalTopForOffset(LayoutUnit offset) const;
1099     LayoutUnit pageLogicalHeightForOffset(LayoutUnit offset) const;
1100     LayoutUnit pageRemainingLogicalHeightForOffset(LayoutUnit offset, PageBoundaryRule = IncludePageBoundary) const;
1101     
1102 protected:
1103     bool pushToNextPageWithMinimumLogicalHeight(LayoutUnit& adjustment, LayoutUnit logicalOffset, LayoutUnit minimumLogicalHeight) const;
1104
1105     LayoutUnit adjustForUnsplittableChild(RenderBox* child, LayoutUnit logicalOffset, bool includeMargins = false); // If the child is unsplittable and can't fit on the current page, return the top of the next page/column.
1106     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.
1107     LayoutUnit adjustBlockChildForPagination(LayoutUnit logicalTopAfterClear, LayoutUnit estimateWithoutPagination, RenderBox* child, bool atBeforeSideOfBlock);
1108
1109     // Adjust from painting offsets to the local coords of this renderer
1110     void offsetForContents(LayoutPoint&) const;
1111
1112     // 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
1113     // region/page/column that has a different available line width than the old one. Used to know when you have to dirty a
1114     // line, i.e., that it can't be re-used.
1115     bool lineWidthForPaginatedLineChanged(RootInlineBox*, LayoutUnit lineDelta, RenderFlowThread*) const;
1116
1117     bool logicalWidthChangedInRegions(RenderFlowThread*) const;
1118
1119     virtual bool requiresColumns(int desiredColumnCount) const;
1120
1121     virtual bool updateLogicalWidthAndColumnWidth();
1122
1123     virtual bool canCollapseAnonymousBlockChild() const { return true; }
1124
1125 public:
1126     LayoutUnit offsetFromLogicalTopOfFirstPage() const;
1127     RenderRegion* regionAtBlockOffset(LayoutUnit) const;
1128     RenderRegion* clampToStartAndEndRegions(RenderRegion*) const;
1129
1130 protected:
1131     struct FloatingObjectHashFunctions {
1132         static unsigned hash(FloatingObject* key) { return DefaultHash<RenderBox*>::Hash::hash(key->m_renderer); }
1133         static bool equal(FloatingObject* a, FloatingObject* b) { return a->m_renderer == b->m_renderer; }
1134         static const bool safeToCompareToEmptyOrDeleted = true;
1135     };
1136     struct FloatingObjectHashTranslator {
1137         static unsigned hash(RenderBox* key) { return DefaultHash<RenderBox*>::Hash::hash(key); }
1138         static bool equal(FloatingObject* a, RenderBox* b) { return a->m_renderer == b; }
1139     };
1140     typedef ListHashSet<FloatingObject*, 4, FloatingObjectHashFunctions> FloatingObjectSet;
1141     typedef FloatingObjectSet::const_iterator FloatingObjectSetIterator;
1142     typedef PODInterval<int, FloatingObject*> FloatingObjectInterval;
1143     typedef PODIntervalTree<int, FloatingObject*> FloatingObjectTree;
1144     typedef PODFreeListArena<PODRedBlackTree<FloatingObjectInterval>::Node> IntervalArena;
1145     
1146     template <FloatingObject::Type FloatTypeValue>
1147     class FloatIntervalSearchAdapter {
1148     public:
1149         typedef FloatingObjectInterval IntervalType;
1150         
1151         FloatIntervalSearchAdapter(const RenderBlock* renderer, int lowValue, int highValue, LayoutUnit& offset, LayoutUnit* heightRemaining)
1152             : m_renderer(renderer)
1153             , m_lowValue(lowValue)
1154             , m_highValue(highValue)
1155             , m_offset(offset)
1156             , m_heightRemaining(heightRemaining)
1157 #if ENABLE(CSS_EXCLUSIONS)
1158             , m_last(0)
1159 #endif
1160         {
1161         }
1162         
1163         inline int lowValue() const { return m_lowValue; }
1164         inline int highValue() const { return m_highValue; }
1165         void collectIfNeeded(const IntervalType&) const;
1166
1167 #if ENABLE(CSS_EXCLUSIONS)
1168         // When computing the offset caused by the floats on a given line, if
1169         // the outermost float on that line has a shape-outside, the inline
1170         // content that butts up against that float must be positioned using
1171         // the contours of the shape, not the shape's bounding box. We save the
1172         // last float encountered so that the offset can be computed correctly
1173         // by the code using this adapter.
1174         const FloatingObject* lastFloat() const { return m_last; }
1175 #endif
1176
1177     private:
1178         const RenderBlock* m_renderer;
1179         int m_lowValue;
1180         int m_highValue;
1181         LayoutUnit& m_offset;
1182         LayoutUnit* m_heightRemaining;
1183 #if ENABLE(CSS_EXCLUSIONS)
1184         // This member variable is mutable because the collectIfNeeded method
1185         // is declared as const, even though it doesn't actually respect that
1186         // contract. It modifies other member variables via loopholes in the
1187         // const behavior. Instead of using loopholes, I decided it was better
1188         // to make the fact that this is modified in a const method explicit.
1189         mutable const FloatingObject* m_last;
1190 #endif
1191     };
1192
1193     void createFloatingObjects();
1194
1195 public:
1196
1197     class FloatingObjects {
1198         WTF_MAKE_NONCOPYABLE(FloatingObjects); WTF_MAKE_FAST_ALLOCATED;
1199     public:
1200         void clear();
1201         void add(FloatingObject*);
1202         void remove(FloatingObject*);
1203         void addPlacedObject(FloatingObject*);
1204         void removePlacedObject(FloatingObject*);
1205         void setHorizontalWritingMode(bool b = true) { m_horizontalWritingMode = b; }
1206
1207         bool hasLeftObjects() const { return m_leftObjectsCount > 0; }
1208         bool hasRightObjects() const { return m_rightObjectsCount > 0; }
1209         const FloatingObjectSet& set() const { return m_set; }
1210         const FloatingObjectTree& placedFloatsTree()
1211         {
1212             computePlacedFloatsTreeIfNeeded();
1213             return m_placedFloatsTree; 
1214         }
1215     private:
1216         FloatingObjects(const RenderBlock*, bool horizontalWritingMode);
1217         void computePlacedFloatsTree();
1218         inline void computePlacedFloatsTreeIfNeeded()
1219         {
1220             if (!m_placedFloatsTree.isInitialized())
1221                 computePlacedFloatsTree();
1222         }
1223         void increaseObjectsCount(FloatingObject::Type);
1224         void decreaseObjectsCount(FloatingObject::Type);
1225         FloatingObjectInterval intervalForFloatingObject(FloatingObject*);
1226
1227         FloatingObjectSet m_set;
1228         FloatingObjectTree m_placedFloatsTree;
1229         unsigned m_leftObjectsCount;
1230         unsigned m_rightObjectsCount;
1231         bool m_horizontalWritingMode;
1232         const RenderBlock* m_renderer;
1233
1234         friend void RenderBlock::createFloatingObjects();
1235     };
1236
1237     // Allocated only when some of these fields have non-default values
1238     struct RenderBlockRareData {
1239         WTF_MAKE_NONCOPYABLE(RenderBlockRareData); WTF_MAKE_FAST_ALLOCATED;
1240     public:
1241         RenderBlockRareData(const RenderBlock* block) 
1242             : m_margins(positiveMarginBeforeDefault(block), negativeMarginBeforeDefault(block), positiveMarginAfterDefault(block), negativeMarginAfterDefault(block))
1243             , m_paginationStrut(0)
1244             , m_pageLogicalOffset(0)
1245             , m_lineGridBox(0)
1246             , m_lineBreakToAvoidWidow(0)
1247             , m_shouldBreakAtLineToAvoidWidow(false)
1248             , m_discardMarginBefore(false)
1249             , m_discardMarginAfter(false)
1250         { 
1251         }
1252
1253         static LayoutUnit positiveMarginBeforeDefault(const RenderBlock* block)
1254         { 
1255             return std::max<LayoutUnit>(block->marginBefore(), 0);
1256         }
1257         static LayoutUnit negativeMarginBeforeDefault(const RenderBlock* block)
1258         { 
1259             return std::max<LayoutUnit>(-block->marginBefore(), 0);
1260         }
1261         static LayoutUnit positiveMarginAfterDefault(const RenderBlock* block)
1262         {
1263             return std::max<LayoutUnit>(block->marginAfter(), 0);
1264         }
1265         static LayoutUnit negativeMarginAfterDefault(const RenderBlock* block)
1266         {
1267             return std::max<LayoutUnit>(-block->marginAfter(), 0);
1268         }
1269         
1270         MarginValues m_margins;
1271         LayoutUnit m_paginationStrut;
1272         LayoutUnit m_pageLogicalOffset;
1273         
1274         RootInlineBox* m_lineGridBox;
1275
1276         RootInlineBox* m_lineBreakToAvoidWidow;
1277 #if ENABLE(CSS_EXCLUSIONS)
1278         OwnPtr<ExclusionShapeInsideInfo> m_shapeInsideInfo;
1279 #endif
1280         bool m_shouldBreakAtLineToAvoidWidow : 1;
1281         bool m_discardMarginBefore : 1;
1282         bool m_discardMarginAfter : 1;
1283      };
1284
1285 protected:
1286
1287     OwnPtr<FloatingObjects> m_floatingObjects;
1288     OwnPtr<RenderBlockRareData> m_rareData;
1289
1290     RenderObjectChildList m_children;
1291     RenderLineBoxList m_lineBoxes;   // All of the root line boxes created for this block flow.  For example, <div>Hello<br>world.</div> will have two total lines for the <div>.
1292
1293     mutable signed m_lineHeight : 27;
1294     unsigned m_hasMarginBeforeQuirk : 1; // Note these quirk values can't be put in RenderBlockRareData since they are set too frequently.
1295     unsigned m_hasMarginAfterQuirk : 1;
1296     unsigned m_beingDestroyed : 1;
1297     unsigned m_hasMarkupTruncation : 1;
1298     unsigned m_hasBorderOrPaddingLogicalWidthChanged : 1;
1299
1300     // RenderRubyBase objects need to be able to split and merge, moving their children around
1301     // (calling moveChildTo, moveAllChildrenTo, and makeChildrenNonInline).
1302     friend class RenderRubyBase;
1303     friend class LineWidth; // Needs to know FloatingObject
1304
1305 private:
1306     // Used to store state between styleWillChange and styleDidChange
1307     static bool s_canPropagateFloatIntoSibling;
1308 };
1309
1310 inline RenderBlock* toRenderBlock(RenderObject* object)
1311
1312     ASSERT_WITH_SECURITY_IMPLICATION(!object || object->isRenderBlock());
1313     return static_cast<RenderBlock*>(object);
1314 }
1315
1316 inline const RenderBlock* toRenderBlock(const RenderObject* object)
1317
1318     ASSERT_WITH_SECURITY_IMPLICATION(!object || object->isRenderBlock());
1319     return static_cast<const RenderBlock*>(object);
1320 }
1321
1322 // This will catch anyone doing an unnecessary cast.
1323 void toRenderBlock(const RenderBlock*);
1324
1325 #ifndef NDEBUG
1326 // These structures are used by PODIntervalTree for debugging purposes.
1327 template <> struct ValueToString<int> {
1328     static String string(const int value);
1329 };
1330 template<> struct ValueToString<RenderBlock::FloatingObject*> {
1331     static String string(const RenderBlock::FloatingObject*);
1332 };
1333 #endif
1334
1335 } // namespace WebCore
1336
1337 #endif // RenderBlock_h