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