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