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