c964bed528416dad1a6dbcac70cc9f6dd5fb09ac
[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 OVERRIDE FINAL;
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() OVERRIDE FINAL;
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 OVERRIDE FINAL;
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 OVERRIDE FINAL;
262     void adjustForColumnRect(LayoutSize& offset, const LayoutPoint& locationInContainer) const;
263
264     void addContinuationWithOutline(RenderInline*);
265     bool paintsContinuationOutline(RenderInline*);
266
267     virtual RenderBoxModelObject* virtualContinuation() const OVERRIDE FINAL { 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     int lineBreakToAvoidWidow() const { return m_rareData ? m_rareData->m_lineBreakToAvoidWidow : -1; }
330     void setBreakAtLineToAvoidWidow(int);
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) const { return isHorizontalWritingMode() ? child->width() : child->height(); }
351     LayoutUnit logicalHeightForChild(const RenderBox* child) const { return isHorizontalWritingMode() ? child->height() : child->width(); }
352     LayoutUnit logicalTopForChild(const RenderBox* child) const { 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 updateShapesBeforeBlockLayout();
596     void updateShapesAfterBlockLayout(bool heightChanged = false);
597     void computeRegionRangeForBoxChild(const RenderBox*) const;
598
599     void estimateRegionRangeForBoxChild(const RenderBox*) const;
600     bool updateRegionRangeForBoxChild(const RenderBox*) const;
601
602     void updateBlockChildDirtyBitsBeforeLayout(bool relayoutChildren, RenderBox*);
603
604     virtual void checkForPaginationLogicalHeightChange(LayoutUnit& pageLogicalHeight, bool& pageLogicalHeightChanged, bool& hasSpecifiedPageLogicalHeight);
605
606 private:
607     enum ShapeOutsideFloatOffsetMode { ShapeOutsideFloatShapeOffset, ShapeOutsideFloatMarginBoxOffset };
608
609     LayoutUnit logicalRightFloatOffsetForLine(LayoutUnit logicalTop, LayoutUnit fixedOffset, LayoutUnit* heightRemaining, LayoutUnit logicalHeight, ShapeOutsideFloatOffsetMode) const;
610     LayoutUnit logicalLeftFloatOffsetForLine(LayoutUnit logicalTop, LayoutUnit fixedOffset, LayoutUnit* heightRemaining, LayoutUnit logicalHeight, ShapeOutsideFloatOffsetMode) const;
611     LayoutUnit adjustLogicalRightOffsetForLine(LayoutUnit offsetFromFloats, bool applyTextIndent) const;
612     LayoutUnit adjustLogicalLeftOffsetForLine(LayoutUnit offsetFromFloats, bool applyTextIndent) const;
613
614 #if ENABLE(CSS_SHAPES)
615     void computeShapeSize();
616     void updateShapeInsideInfoAfterStyleChange(const ShapeValue*, const ShapeValue* oldShape);
617 #endif
618     virtual RenderObjectChildList* virtualChildren() { return children(); }
619     virtual const RenderObjectChildList* virtualChildren() const { return children(); }
620
621     virtual const char* renderName() const;
622
623     virtual bool isRenderBlock() const OVERRIDE FINAL { return true; }
624     virtual bool isBlockFlow() const OVERRIDE FINAL { return (!isInline() || isReplaced()) && !isTable(); }
625     virtual bool isInlineBlockOrInlineTable() const OVERRIDE FINAL { return isInline() && isReplaced(); }
626
627     void makeChildrenNonInline(RenderObject* insertionPoint = 0);
628     virtual void removeLeftoverAnonymousBlock(RenderBlock* child);
629
630     void moveAllChildrenIncludingFloatsTo(RenderBlock* toBlock, bool fullRemoveInsert);
631
632     virtual void dirtyLinesFromChangedChild(RenderObject* child) OVERRIDE FINAL { m_lineBoxes.dirtyLinesFromChangedChild(this, child); }
633
634     void addChildToContinuation(RenderObject* newChild, RenderObject* beforeChild);
635     void addChildIgnoringContinuation(RenderObject* newChild, RenderObject* beforeChild);
636     void addChildToAnonymousColumnBlocks(RenderObject* newChild, RenderObject* beforeChild);
637
638     void addChildIgnoringAnonymousColumnBlocks(RenderObject* newChild, RenderObject* beforeChild = 0);
639     
640     virtual bool isSelfCollapsingBlock() const OVERRIDE FINAL;
641
642     virtual LayoutUnit collapsedMarginBefore() const OVERRIDE FINAL { return maxPositiveMarginBefore() - maxNegativeMarginBefore(); }
643     virtual LayoutUnit collapsedMarginAfter() const OVERRIDE FINAL { return maxPositiveMarginAfter() - maxNegativeMarginAfter(); }
644
645     virtual void repaintOverhangingFloats(bool paintAllDescendants) OVERRIDE FINAL;
646
647     void layoutBlockChildren(bool relayoutChildren, LayoutUnit& maxFloatLogicalBottom);
648     void layoutInlineChildren(bool relayoutChildren, LayoutUnit& repaintLogicalTop, LayoutUnit& repaintLogicalBottom);
649     BidiRun* handleTrailingSpaces(BidiRunList<BidiRun>&, BidiContext*);
650
651     void insertIntoTrackedRendererMaps(RenderBox* descendant, TrackedDescendantsMap*&, TrackedContainerMap*&);
652     static void removeFromTrackedRendererMaps(RenderBox* descendant, TrackedDescendantsMap*&, TrackedContainerMap*&);
653
654     virtual RootInlineBox* createRootInlineBox(); // Subclassed by SVG and Ruby.
655
656     // Called to lay out the legend for a fieldset or the ruby text of a ruby run.
657     virtual RenderObject* layoutSpecialExcludedChild(bool /*relayoutChildren*/) { return 0; }
658
659     bool relayoutToAvoidWidows(LayoutStateMaintainer&);
660
661     void createFirstLetterRenderer(RenderObject* firstLetterBlock, RenderObject* currentChild);
662     void updateFirstLetterStyle(RenderObject* firstLetterBlock, RenderObject* firstLetterContainer);
663
664     Node* nodeForHitTest() const;
665
666     struct FloatWithRect {
667         FloatWithRect(RenderBox* f)
668             : object(f)
669             , rect(LayoutRect(f->x() - f->marginLeft(), f->y() - f->marginTop(), f->width() + f->marginWidth(), f->height() + f->marginHeight()))
670             , everHadLayout(f->everHadLayout())
671         {
672         }
673
674         RenderBox* object;
675         LayoutRect rect;
676         bool everHadLayout;
677     };
678
679     struct FloatingObject {
680         WTF_MAKE_NONCOPYABLE(FloatingObject); WTF_MAKE_FAST_ALLOCATED;
681     public:
682         // Note that Type uses bits so you can use FloatLeftRight as a mask to query for both left and right.
683         enum Type { FloatLeft = 1, FloatRight = 2, FloatLeftRight = 3 };
684
685         FloatingObject(EFloat type)
686             : m_renderer(0)
687             , m_originatingLine(0)
688             , m_paginationStrut(0)
689             , m_shouldPaint(true)
690             , m_isDescendant(false)
691             , m_isPlaced(false)
692 #ifndef NDEBUG
693             , m_isInPlacedTree(false)
694 #endif
695         {
696             ASSERT(type != NoFloat);
697             if (type == LeftFloat)
698                 m_type = FloatLeft;
699             else if (type == RightFloat)
700                 m_type = FloatRight;  
701         }
702
703         FloatingObject(Type type, const LayoutRect& frameRect)
704             : m_renderer(0)
705             , m_originatingLine(0)
706             , m_frameRect(frameRect)
707             , m_paginationStrut(0)
708             , m_type(type)
709             , m_shouldPaint(true)
710             , m_isDescendant(false)
711             , m_isPlaced(true)
712 #ifndef NDEBUG
713             , m_isInPlacedTree(false)
714 #endif
715         {
716         }
717
718         FloatingObject* clone() const
719         {
720             FloatingObject* cloneObject = new FloatingObject(type(), m_frameRect);
721             cloneObject->m_renderer = m_renderer;
722             cloneObject->m_originatingLine = m_originatingLine;
723             cloneObject->m_paginationStrut = m_paginationStrut;
724             cloneObject->m_shouldPaint = m_shouldPaint;
725             cloneObject->m_isDescendant = m_isDescendant;
726             cloneObject->m_isPlaced = m_isPlaced;
727             return cloneObject;
728         }
729
730         Type type() const { return static_cast<Type>(m_type); }
731         RenderBox* renderer() const { return m_renderer; }
732         
733         bool isPlaced() const { return m_isPlaced; }
734         void setIsPlaced(bool placed = true) { m_isPlaced = placed; }
735
736         inline LayoutUnit x() const { ASSERT(isPlaced()); return m_frameRect.x(); }
737         inline LayoutUnit maxX() const { ASSERT(isPlaced()); return m_frameRect.maxX(); }
738         inline LayoutUnit y() const { ASSERT(isPlaced()); return m_frameRect.y(); }
739         inline LayoutUnit maxY() const { ASSERT(isPlaced()); return m_frameRect.maxY(); }
740         inline LayoutUnit width() const { return m_frameRect.width(); }
741         inline LayoutUnit height() const { return m_frameRect.height(); }
742
743         void setX(LayoutUnit x) { ASSERT(!isInPlacedTree()); m_frameRect.setX(x); }
744         void setY(LayoutUnit y) { ASSERT(!isInPlacedTree()); m_frameRect.setY(y); }
745         void setWidth(LayoutUnit width) { ASSERT(!isInPlacedTree()); m_frameRect.setWidth(width); }
746         void setHeight(LayoutUnit height) { ASSERT(!isInPlacedTree()); m_frameRect.setHeight(height); }
747
748         const LayoutRect& frameRect() const { ASSERT(isPlaced()); return m_frameRect; }
749         void setFrameRect(const LayoutRect& frameRect) { ASSERT(!isInPlacedTree()); m_frameRect = frameRect; }
750
751 #ifndef NDEBUG
752         bool isInPlacedTree() const { return m_isInPlacedTree; }
753         void setIsInPlacedTree(bool value) { m_isInPlacedTree = value; }
754 #endif
755
756         bool shouldPaint() const { return m_shouldPaint; }
757         void setShouldPaint(bool shouldPaint) { m_shouldPaint = shouldPaint; }
758         bool isDescendant() const { return m_isDescendant; }
759         void setIsDescendant(bool isDescendant) { m_isDescendant = isDescendant; }
760
761         RenderBox* m_renderer;
762         RootInlineBox* m_originatingLine;
763         LayoutRect m_frameRect;
764         int m_paginationStrut;
765
766     private:
767         unsigned m_type : 2; // Type (left or right aligned)
768         unsigned m_shouldPaint : 1;
769         unsigned m_isDescendant : 1;
770         unsigned m_isPlaced : 1;
771 #ifndef NDEBUG
772         unsigned m_isInPlacedTree : 1;
773 #endif
774     };
775
776     LayoutPoint flipFloatForWritingModeForChild(const FloatingObject*, const LayoutPoint&) const;
777
778     LayoutUnit logicalTopForFloat(const FloatingObject* child) const { return isHorizontalWritingMode() ? child->y() : child->x(); }
779     LayoutUnit logicalBottomForFloat(const FloatingObject* child) const { return isHorizontalWritingMode() ? child->maxY() : child->maxX(); }
780     LayoutUnit logicalLeftForFloat(const FloatingObject* child) const { return isHorizontalWritingMode() ? child->x() : child->y(); }
781     LayoutUnit logicalRightForFloat(const FloatingObject* child) const { return isHorizontalWritingMode() ? child->maxX() : child->maxY(); }
782     LayoutUnit logicalWidthForFloat(const FloatingObject* child) const { return isHorizontalWritingMode() ? child->width() : child->height(); }
783
784     int pixelSnappedLogicalTopForFloat(const FloatingObject* child) const { return isHorizontalWritingMode() ? child->frameRect().pixelSnappedY() : child->frameRect().pixelSnappedX(); }
785     int pixelSnappedLogicalBottomForFloat(const FloatingObject* child) const { return isHorizontalWritingMode() ? child->frameRect().pixelSnappedMaxY() : child->frameRect().pixelSnappedMaxX(); }
786     int pixelSnappedLogicalLeftForFloat(const FloatingObject* child) const { return isHorizontalWritingMode() ? child->frameRect().pixelSnappedX() : child->frameRect().pixelSnappedY(); }
787     int pixelSnappedLogicalRightForFloat(const FloatingObject* child) const { return isHorizontalWritingMode() ? child->frameRect().pixelSnappedMaxX() : child->frameRect().pixelSnappedMaxY(); }
788
789     void setLogicalTopForFloat(FloatingObject* child, LayoutUnit logicalTop)
790     {
791         if (isHorizontalWritingMode())
792             child->setY(logicalTop);
793         else
794             child->setX(logicalTop);
795     }
796     void setLogicalLeftForFloat(FloatingObject* child, LayoutUnit logicalLeft)
797     {
798         if (isHorizontalWritingMode())
799             child->setX(logicalLeft);
800         else
801             child->setY(logicalLeft);
802     }
803     void setLogicalHeightForFloat(FloatingObject* child, LayoutUnit logicalHeight)
804     {
805         if (isHorizontalWritingMode())
806             child->setHeight(logicalHeight);
807         else
808             child->setWidth(logicalHeight);
809     }
810     void setLogicalWidthForFloat(FloatingObject* child, LayoutUnit logicalWidth)
811     {
812         if (isHorizontalWritingMode())
813             child->setWidth(logicalWidth);
814         else
815             child->setHeight(logicalWidth);
816     }
817
818     LayoutUnit xPositionForFloatIncludingMargin(const FloatingObject* child) const
819     {
820         if (isHorizontalWritingMode())
821             return child->x() + child->renderer()->marginLeft();
822         else
823             return child->x() + marginBeforeForChild(child->renderer());
824     }
825         
826     LayoutUnit yPositionForFloatIncludingMargin(const FloatingObject* child) const
827     {
828         if (isHorizontalWritingMode())
829             return child->y() + marginBeforeForChild(child->renderer());
830         else
831             return child->y() + child->renderer()->marginTop();
832     }
833
834     LayoutPoint computeLogicalLocationForFloat(const FloatingObject*, LayoutUnit logicalTopOffset) const;
835
836     // The following functions' implementations are in RenderBlockLineLayout.cpp.
837     struct RenderTextInfo {
838         // Destruction of m_layout requires TextLayout to be a complete type, so the constructor and destructor are made non-inline to avoid compilation errors.
839         RenderTextInfo();
840         ~RenderTextInfo();
841
842         RenderText* m_text;
843         OwnPtr<TextLayout> m_layout;
844         LazyLineBreakIterator m_lineBreakIterator;
845         const Font* m_font;
846     };
847
848     class LineBreaker {
849     public:
850         LineBreaker(RenderBlock* block)
851             : m_block(block)
852         {
853             reset();
854         }
855
856         InlineIterator nextLineBreak(InlineBidiResolver&, LineInfo&, RenderTextInfo&, FloatingObject* lastFloatFromPreviousLine, unsigned consecutiveHyphenatedLines, WordMeasurements&);
857
858         bool lineWasHyphenated() { return m_hyphenated; }
859         const Vector<RenderBox*>& positionedObjects() { return m_positionedObjects; }
860         EClear clear() { return m_clear; }
861     private:
862         void reset();
863         
864         InlineIterator nextSegmentBreak(InlineBidiResolver&, LineInfo&, RenderTextInfo&, FloatingObject* lastFloatFromPreviousLine, unsigned consecutiveHyphenatedLines, WordMeasurements&);
865         void skipTrailingWhitespace(InlineIterator&, const LineInfo&);
866         void skipLeadingWhitespace(InlineBidiResolver&, LineInfo&, FloatingObject* lastFloatFromPreviousLine, LineWidth&);
867         
868         RenderBlock* m_block;
869         bool m_hyphenated;
870         EClear m_clear;
871         Vector<RenderBox*> m_positionedObjects;
872     };
873
874     void checkFloatsInCleanLine(RootInlineBox*, Vector<FloatWithRect>&, size_t& floatIndex, bool& encounteredNewFloat, bool& dirtiedByFloat);
875     RootInlineBox* determineStartPosition(LineLayoutState&, InlineBidiResolver&);
876     void determineEndPosition(LineLayoutState&, RootInlineBox* startBox, InlineIterator& cleanLineStart, BidiStatus& cleanLineBidiStatus);
877     bool matchedEndLine(LineLayoutState&, const InlineBidiResolver&, const InlineIterator& endLineStart, const BidiStatus& endLineStatus);
878     bool checkPaginationAndFloatsAtEndLine(LineLayoutState&);
879     
880     RootInlineBox* constructLine(BidiRunList<BidiRun>&, const LineInfo&);
881     InlineFlowBox* createLineBoxes(RenderObject*, const LineInfo&, InlineBox* childBox, bool startsNewSegment);
882
883     void setMarginsForRubyRun(BidiRun*, RenderRubyRun*, RenderObject*, const LineInfo&);
884
885     BidiRun* computeInlineDirectionPositionsForSegment(RootInlineBox*, const LineInfo&, ETextAlign, float& logicalLeft,
886         float& availableLogicalWidth, BidiRun* firstRun, BidiRun* trailingSpaceRun, GlyphOverflowAndFallbackFontsMap& textBoxDataMap, VerticalPositionCache&, WordMeasurements&);
887     void computeInlineDirectionPositionsForLine(RootInlineBox*, const LineInfo&, BidiRun* firstRun, BidiRun* trailingSpaceRun, bool reachedEnd, GlyphOverflowAndFallbackFontsMap&, VerticalPositionCache&, WordMeasurements&);
888     void computeBlockDirectionPositionsForLine(RootInlineBox*, BidiRun*, GlyphOverflowAndFallbackFontsMap&, VerticalPositionCache&);
889     void deleteEllipsisLineBoxes();
890     void checkLinesForTextOverflow();
891
892     // Positions new floats and also adjust all floats encountered on the line if any of them
893     // have to move to the next page/column.
894     bool positionNewFloatOnLine(FloatingObject* newFloat, FloatingObject* lastFloatFromPreviousLine, LineInfo&, LineWidth&);
895     void appendFloatingObjectToLastLine(FloatingObject*);
896
897     // End of functions defined in RenderBlockLineLayout.cpp.
898
899     void paintFloats(PaintInfo&, const LayoutPoint&, bool preservePhase = false);
900     void paintContents(PaintInfo&, const LayoutPoint&);
901     void paintColumnContents(PaintInfo&, const LayoutPoint&, bool paintFloats = false);
902     void paintColumnRules(PaintInfo&, const LayoutPoint&);
903     void paintSelection(PaintInfo&, const LayoutPoint&);
904     void paintCaret(PaintInfo&, const LayoutPoint&, CaretType);
905
906     FloatingObject* insertFloatingObject(RenderBox*);
907     void removeFloatingObject(RenderBox*);
908     void removeFloatingObjectsBelow(FloatingObject*, int logicalOffset);
909     
910     // Called from lineWidth, to position the floats added in the last line.
911     // Returns true if and only if it has positioned any floats.
912     bool positionNewFloats();
913
914     void clearFloats();
915
916     LayoutUnit getClearDelta(RenderBox* child, LayoutUnit yPos);
917
918     virtual bool avoidsFloats() const;
919
920     bool hasOverhangingFloats() { return parent() && !hasColumns() && containsFloats() && lowestFloatLogicalBottom() > logicalHeight(); }
921     bool hasOverhangingFloat(RenderBox*);
922     void addIntrudingFloats(RenderBlock* prev, LayoutUnit xoffset, LayoutUnit yoffset);
923     LayoutUnit addOverhangingFloats(RenderBlock* child, bool makeChildPaintOtherFloats);
924
925     LayoutUnit lowestFloatLogicalBottom(FloatingObject::Type = FloatingObject::FloatLeftRight) const; 
926     LayoutUnit nextFloatLogicalBottomBelow(LayoutUnit) const;
927     
928     bool hitTestColumns(const HitTestRequest&, HitTestResult&, const HitTestLocation& locationInContainer, const LayoutPoint& accumulatedOffset, HitTestAction);
929     virtual bool hitTestContents(const HitTestRequest&, HitTestResult&, const HitTestLocation& locationInContainer, const LayoutPoint& accumulatedOffset, HitTestAction);
930     bool hitTestFloats(const HitTestRequest&, HitTestResult&, const HitTestLocation& locationInContainer, const LayoutPoint& accumulatedOffset);
931
932     virtual bool isPointInOverflowControl(HitTestResult&, const LayoutPoint& locationInContainer, const LayoutPoint& accumulatedOffset);
933
934     // FIXME: Make this method const so we can remove the const_cast in computeIntrinsicLogicalWidths.
935     void computeInlinePreferredLogicalWidths(LayoutUnit& minLogicalWidth, LayoutUnit& maxLogicalWidth);
936     void computeBlockPreferredLogicalWidths(LayoutUnit& minLogicalWidth, LayoutUnit& maxLogicalWidth) const;
937
938     // Obtains the nearest enclosing block (including this block) that contributes a first-line style to our inline
939     // children.
940     virtual RenderBlock* firstLineBlock() const OVERRIDE;
941
942     virtual LayoutRect rectWithOutlineForRepaint(const RenderLayerModelObject* repaintContainer, LayoutUnit outlineWidth) const OVERRIDE FINAL;
943     virtual RenderStyle* outlineStyleForRepaint() const OVERRIDE FINAL;
944     
945     virtual RenderObject* hoverAncestor() const OVERRIDE FINAL;
946     virtual void updateDragState(bool dragOn) OVERRIDE FINAL;
947     virtual void childBecameNonInline(RenderObject* child) OVERRIDE FINAL;
948
949     virtual LayoutRect selectionRectForRepaint(const RenderLayerModelObject* repaintContainer, bool /*clipToVisibleContent*/) OVERRIDE FINAL
950     {
951         return selectionGapRectsForRepaint(repaintContainer);
952     }
953     virtual bool shouldPaintSelectionGaps() const OVERRIDE FINAL;
954     bool isSelectionRoot() const;
955     GapRects selectionGaps(RenderBlock* rootBlock, const LayoutPoint& rootBlockPhysicalPosition, const LayoutSize& offsetFromRootBlock,
956         LayoutUnit& lastLogicalTop, LayoutUnit& lastLogicalLeft, LayoutUnit& lastLogicalRight, const LogicalSelectionOffsetCaches&, const PaintInfo* = 0);
957     GapRects inlineSelectionGaps(RenderBlock* rootBlock, const LayoutPoint& rootBlockPhysicalPosition, const LayoutSize& offsetFromRootBlock,
958         LayoutUnit& lastLogicalTop, LayoutUnit& lastLogicalLeft, LayoutUnit& lastLogicalRight, const LogicalSelectionOffsetCaches&, const PaintInfo*);
959     GapRects blockSelectionGaps(RenderBlock* rootBlock, const LayoutPoint& rootBlockPhysicalPosition, const LayoutSize& offsetFromRootBlock,
960         LayoutUnit& lastLogicalTop, LayoutUnit& lastLogicalLeft, LayoutUnit& lastLogicalRight, const LogicalSelectionOffsetCaches&, const PaintInfo*);
961     LayoutRect blockSelectionGap(RenderBlock* rootBlock, const LayoutPoint& rootBlockPhysicalPosition, const LayoutSize& offsetFromRootBlock,
962         LayoutUnit lastLogicalTop, LayoutUnit lastLogicalLeft, LayoutUnit lastLogicalRight, LayoutUnit logicalBottom, const LogicalSelectionOffsetCaches&, const PaintInfo*);
963     LayoutUnit logicalLeftSelectionOffset(RenderBlock* rootBlock, LayoutUnit position, const LogicalSelectionOffsetCaches&);
964     LayoutUnit logicalRightSelectionOffset(RenderBlock* rootBlock, LayoutUnit position, const LogicalSelectionOffsetCaches&);
965     
966     friend class LogicalSelectionOffsetCaches;
967
968     virtual void absoluteRects(Vector<IntRect>&, const LayoutPoint& accumulatedOffset) const;
969     virtual void absoluteQuads(Vector<FloatQuad>&, bool* wasFixed) const;
970
971     LayoutUnit desiredColumnWidth() const;
972     unsigned desiredColumnCount() const;
973
974     void paintContinuationOutlines(PaintInfo&, const LayoutPoint&);
975
976     virtual LayoutRect localCaretRect(InlineBox*, int caretOffset, LayoutUnit* extraWidthToEndOfLine = 0) OVERRIDE FINAL;
977
978     void adjustPointToColumnContents(LayoutPoint&) const;
979     
980     void fitBorderToLinesIfNeeded(); // Shrink the box in which the border paints if border-fit is set.
981     void adjustForBorderFit(LayoutUnit x, LayoutUnit& left, LayoutUnit& right) const; // Helper function for borderFitAdjust
982
983     void markLinesDirtyInBlockRange(LayoutUnit logicalTop, LayoutUnit logicalBottom, RootInlineBox* highest = 0);
984
985     void newLine(EClear);
986
987     Position positionForBox(InlineBox*, bool start = true) const;
988     VisiblePosition positionForPointWithInlineChildren(const LayoutPoint&);
989
990     virtual void calcColumnWidth();
991     void makeChildrenAnonymousColumnBlocks(RenderObject* beforeChild, RenderBlock* newBlockBox, RenderObject* newChild);
992
993     bool expandsToEncloseOverhangingFloats() const;
994
995     void splitBlocks(RenderBlock* fromBlock, RenderBlock* toBlock, RenderBlock* middleBlock,
996                      RenderObject* beforeChild, RenderBoxModelObject* oldCont);
997     void splitFlow(RenderObject* beforeChild, RenderBlock* newBlockBox,
998                    RenderObject* newChild, RenderBoxModelObject* oldCont);
999     RenderBlock* clone() const;
1000     RenderBlock* continuationBefore(RenderObject* beforeChild);
1001     RenderBlock* containingColumnsBlock(bool allowAnonymousColumnBlock = true);
1002     RenderBlock* columnsBlockForSpanningElement(RenderObject* newChild);
1003
1004     class MarginInfo {
1005         // Collapsing flags for whether we can collapse our margins with our children's margins.
1006         bool m_canCollapseWithChildren : 1;
1007         bool m_canCollapseMarginBeforeWithChildren : 1;
1008         bool m_canCollapseMarginAfterWithChildren : 1;
1009
1010         // Whether or not we are a quirky container, i.e., do we collapse away top and bottom
1011         // margins in our container.  Table cells and the body are the common examples. We
1012         // also have a custom style property for Safari RSS to deal with TypePad blog articles.
1013         bool m_quirkContainer : 1;
1014
1015         // This flag tracks whether we are still looking at child margins that can all collapse together at the beginning of a block.  
1016         // They may or may not collapse with the top margin of the block (|m_canCollapseTopWithChildren| tells us that), but they will
1017         // always be collapsing with one another.  This variable can remain set to true through multiple iterations 
1018         // as long as we keep encountering self-collapsing blocks.
1019         bool m_atBeforeSideOfBlock : 1;
1020
1021         // This flag is set when we know we're examining bottom margins and we know we're at the bottom of the block.
1022         bool m_atAfterSideOfBlock : 1;
1023
1024         // These variables are used to detect quirky margins that we need to collapse away (in table cells
1025         // and in the body element).
1026         bool m_hasMarginBeforeQuirk : 1;
1027         bool m_hasMarginAfterQuirk : 1;
1028         bool m_determinedMarginBeforeQuirk : 1;
1029
1030         bool m_discardMargin : 1;
1031
1032         // These flags track the previous maximal positive and negative margins.
1033         LayoutUnit m_positiveMargin;
1034         LayoutUnit m_negativeMargin;
1035
1036     public:
1037         MarginInfo(RenderBlock*, LayoutUnit beforeBorderPadding, LayoutUnit afterBorderPadding);
1038
1039         void setAtBeforeSideOfBlock(bool b) { m_atBeforeSideOfBlock = b; }
1040         void setAtAfterSideOfBlock(bool b) { m_atAfterSideOfBlock = b; }
1041         void clearMargin()
1042         {
1043             m_positiveMargin = 0;
1044             m_negativeMargin = 0;
1045         }
1046         void setHasMarginBeforeQuirk(bool b) { m_hasMarginBeforeQuirk = b; }
1047         void setHasMarginAfterQuirk(bool b) { m_hasMarginAfterQuirk = b; }
1048         void setDeterminedMarginBeforeQuirk(bool b) { m_determinedMarginBeforeQuirk = b; }
1049         void setPositiveMargin(LayoutUnit p) { ASSERT(!m_discardMargin); m_positiveMargin = p; }
1050         void setNegativeMargin(LayoutUnit n) { ASSERT(!m_discardMargin); m_negativeMargin = n; }
1051         void setPositiveMarginIfLarger(LayoutUnit p)
1052         {
1053             ASSERT(!m_discardMargin);
1054             if (p > m_positiveMargin)
1055                 m_positiveMargin = p;
1056         }
1057         void setNegativeMarginIfLarger(LayoutUnit n)
1058         {
1059             ASSERT(!m_discardMargin);
1060             if (n > m_negativeMargin)
1061                 m_negativeMargin = n;
1062         }
1063
1064         void setMargin(LayoutUnit p, LayoutUnit n) { ASSERT(!m_discardMargin); m_positiveMargin = p; m_negativeMargin = n; }
1065         void setCanCollapseMarginAfterWithChildren(bool collapse) { m_canCollapseMarginAfterWithChildren = collapse; }
1066         void setDiscardMargin(bool value) { m_discardMargin = value; }
1067
1068         bool atBeforeSideOfBlock() const { return m_atBeforeSideOfBlock; }
1069         bool canCollapseWithMarginBefore() const { return m_atBeforeSideOfBlock && m_canCollapseMarginBeforeWithChildren; }
1070         bool canCollapseWithMarginAfter() const { return m_atAfterSideOfBlock && m_canCollapseMarginAfterWithChildren; }
1071         bool canCollapseMarginBeforeWithChildren() const { return m_canCollapseMarginBeforeWithChildren; }
1072         bool canCollapseMarginAfterWithChildren() const { return m_canCollapseMarginAfterWithChildren; }
1073         bool quirkContainer() const { return m_quirkContainer; }
1074         bool determinedMarginBeforeQuirk() const { return m_determinedMarginBeforeQuirk; }
1075         bool hasMarginBeforeQuirk() const { return m_hasMarginBeforeQuirk; }
1076         bool hasMarginAfterQuirk() const { return m_hasMarginAfterQuirk; }
1077         LayoutUnit positiveMargin() const { return m_positiveMargin; }
1078         LayoutUnit negativeMargin() const { return m_negativeMargin; }
1079         bool discardMargin() const { return m_discardMargin; }
1080         LayoutUnit margin() const { return m_positiveMargin - m_negativeMargin; }
1081     };
1082
1083     void layoutBlockChild(RenderBox* child, MarginInfo&, LayoutUnit& previousFloatLogicalBottom, LayoutUnit& maxFloatLogicalBottom);
1084     void adjustPositionedBlock(RenderBox* child, const MarginInfo&);
1085     void adjustFloatingBlock(const MarginInfo&);
1086
1087     RenderBoxModelObject* createReplacementRunIn(RenderBoxModelObject* runIn);
1088     void moveRunInUnderSiblingBlockIfNeeded(RenderObject* runIn);
1089     void moveRunInToOriginalPosition(RenderObject* runIn);
1090
1091     LayoutUnit collapseMargins(RenderBox* child, MarginInfo&);
1092     LayoutUnit clearFloatsIfNeeded(RenderBox* child, MarginInfo&, LayoutUnit oldTopPosMargin, LayoutUnit oldTopNegMargin, LayoutUnit yPos);
1093     LayoutUnit estimateLogicalTopPosition(RenderBox* child, const MarginInfo&, LayoutUnit& estimateWithoutPagination);
1094     void marginBeforeEstimateForChild(RenderBox*, LayoutUnit&, LayoutUnit&, bool&) const;
1095     void handleAfterSideOfBlock(LayoutUnit top, LayoutUnit bottom, MarginInfo&);
1096     void setCollapsedBottomMargin(const MarginInfo&);
1097     // End helper functions and structs used by layoutBlockChildren.
1098
1099     // Helper function for layoutInlineChildren()
1100     RootInlineBox* createLineBoxesFromBidiRuns(BidiRunList<BidiRun>&, const InlineIterator& end, LineInfo&, VerticalPositionCache&, BidiRun* trailingSpaceRun, WordMeasurements&);
1101     void layoutRunsAndFloats(LineLayoutState&, bool hasInlineChild);
1102     void layoutRunsAndFloatsInRange(LineLayoutState&, InlineBidiResolver&, const InlineIterator& cleanLineStart, const BidiStatus& cleanLineBidiStatus, unsigned consecutiveHyphenatedLines);
1103 #if ENABLE(CSS_SHAPES)
1104     void updateShapeAndSegmentsForCurrentLine(ShapeInsideInfo*&, LayoutUnit&, LineLayoutState&);
1105     void updateShapeAndSegmentsForCurrentLineInFlowThread(ShapeInsideInfo*&, LineLayoutState&);
1106     bool adjustLogicalLineTopAndLogicalHeightIfNeeded(ShapeInsideInfo*, LayoutUnit, LineLayoutState&, InlineBidiResolver&, FloatingObject*, InlineIterator&, WordMeasurements&);
1107 #endif
1108     const InlineIterator& restartLayoutRunsAndFloatsInRange(LayoutUnit oldLogicalHeight, LayoutUnit newLogicalHeight,  FloatingObject* lastFloatFromPreviousLine, InlineBidiResolver&,  const InlineIterator&);
1109     void linkToEndLineIfNeeded(LineLayoutState&);
1110     static void repaintDirtyFloats(Vector<FloatWithRect>& floats);
1111
1112 protected:
1113     void dirtyForLayoutFromPercentageHeightDescendants();
1114     
1115     void determineLogicalLeftPositionForChild(RenderBox* child, ApplyLayoutDeltaMode = DoNotApplyLayoutDelta);
1116
1117     // Pagination routines.
1118     virtual bool relayoutForPagination(bool hasSpecifiedPageLogicalHeight, LayoutUnit pageLogicalHeight, LayoutStateMaintainer&);
1119     
1120     // Returns the logicalOffset at the top of the next page. If the offset passed in is already at the top of the current page,
1121     // then nextPageLogicalTop with ExcludePageBoundary will still move to the top of the next page. nextPageLogicalTop with
1122     // IncludePageBoundary set will not.
1123     //
1124     // 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.
1125     enum PageBoundaryRule { ExcludePageBoundary, IncludePageBoundary };
1126     LayoutUnit nextPageLogicalTop(LayoutUnit logicalOffset, PageBoundaryRule = ExcludePageBoundary) const;
1127     bool hasNextPage(LayoutUnit logicalOffset, PageBoundaryRule = ExcludePageBoundary) const;
1128
1129     virtual ColumnInfo::PaginationUnit paginationUnit() const;
1130
1131     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.
1132     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.
1133
1134 public:
1135     LayoutUnit pageLogicalTopForOffset(LayoutUnit offset) const;
1136     LayoutUnit pageLogicalHeightForOffset(LayoutUnit offset) const;
1137     LayoutUnit pageRemainingLogicalHeightForOffset(LayoutUnit offset, PageBoundaryRule = IncludePageBoundary) const;
1138     
1139 protected:
1140     bool pushToNextPageWithMinimumLogicalHeight(LayoutUnit& adjustment, LayoutUnit logicalOffset, LayoutUnit minimumLogicalHeight) const;
1141
1142     // A page break is required at some offset due to space shortage in the current fragmentainer.
1143     void setPageBreak(LayoutUnit offset, LayoutUnit spaceShortage);
1144
1145     // Update minimum page height required to avoid fragmentation where it shouldn't occur (inside
1146     // unbreakable content, between orphans and widows, etc.). This will be used as a hint to the
1147     // column balancer to help set a good minimum column height.
1148     void updateMinimumPageHeight(LayoutUnit offset, LayoutUnit minHeight);
1149
1150     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.
1151     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.
1152     LayoutUnit adjustBlockChildForPagination(LayoutUnit logicalTopAfterClear, LayoutUnit estimateWithoutPagination, RenderBox* child, bool atBeforeSideOfBlock);
1153
1154     // Adjust from painting offsets to the local coords of this renderer
1155     void offsetForContents(LayoutPoint&) const;
1156
1157     // 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
1158     // region/page/column that has a different available line width than the old one. Used to know when you have to dirty a
1159     // line, i.e., that it can't be re-used.
1160     bool lineWidthForPaginatedLineChanged(RootInlineBox*, LayoutUnit lineDelta, RenderFlowThread*) const;
1161
1162     bool logicalWidthChangedInRegions(RenderFlowThread*) const;
1163
1164     virtual bool requiresColumns(int desiredColumnCount) const;
1165
1166     virtual bool updateLogicalWidthAndColumnWidth();
1167
1168     virtual bool canCollapseAnonymousBlockChild() const { return true; }
1169
1170 public:
1171     virtual LayoutUnit offsetFromLogicalTopOfFirstPage() const;
1172     RenderRegion* regionAtBlockOffset(LayoutUnit) const;
1173
1174 protected:
1175     struct FloatingObjectHashFunctions {
1176         static unsigned hash(FloatingObject* key) { return DefaultHash<RenderBox*>::Hash::hash(key->m_renderer); }
1177         static bool equal(FloatingObject* a, FloatingObject* b) { return a->m_renderer == b->m_renderer; }
1178         static const bool safeToCompareToEmptyOrDeleted = true;
1179     };
1180     struct FloatingObjectHashTranslator {
1181         static unsigned hash(RenderBox* key) { return DefaultHash<RenderBox*>::Hash::hash(key); }
1182         static bool equal(FloatingObject* a, RenderBox* b) { return a->m_renderer == b; }
1183     };
1184     typedef ListHashSet<FloatingObject*, 4, FloatingObjectHashFunctions> FloatingObjectSet;
1185     typedef FloatingObjectSet::const_iterator FloatingObjectSetIterator;
1186     typedef PODInterval<int, FloatingObject*> FloatingObjectInterval;
1187     typedef PODIntervalTree<int, FloatingObject*> FloatingObjectTree;
1188     typedef PODFreeListArena<PODRedBlackTree<FloatingObjectInterval>::Node> IntervalArena;
1189     
1190     template <FloatingObject::Type FloatTypeValue>
1191     class FloatIntervalSearchAdapter {
1192     public:
1193         typedef FloatingObjectInterval IntervalType;
1194         
1195         FloatIntervalSearchAdapter(const RenderBlock* renderer, int lowValue, int highValue, LayoutUnit& offset, LayoutUnit* heightRemaining)
1196             : m_renderer(renderer)
1197             , m_lowValue(lowValue)
1198             , m_highValue(highValue)
1199             , m_offset(offset)
1200             , m_heightRemaining(heightRemaining)
1201 #if ENABLE(CSS_SHAPES)
1202             , m_last(0)
1203 #endif
1204         {
1205         }
1206         
1207         inline int lowValue() const { return m_lowValue; }
1208         inline int highValue() const { return m_highValue; }
1209         void collectIfNeeded(const IntervalType&) const;
1210
1211 #if ENABLE(CSS_SHAPES)
1212         // When computing the offset caused by the floats on a given line, if
1213         // the outermost float on that line has a shape-outside, the inline
1214         // content that butts up against that float must be positioned using
1215         // the contours of the shape, not the margin box of the float.
1216         // We save the last float encountered so that the offset can be
1217         // computed correctly by the code using this adapter.
1218         const FloatingObject* lastFloat() const { return m_last; }
1219 #endif
1220
1221     private:
1222         const RenderBlock* m_renderer;
1223         int m_lowValue;
1224         int m_highValue;
1225         LayoutUnit& m_offset;
1226         LayoutUnit* m_heightRemaining;
1227 #if ENABLE(CSS_SHAPES)
1228         // This member variable is mutable because the collectIfNeeded method
1229         // is declared as const, even though it doesn't actually respect that
1230         // contract. It modifies other member variables via loopholes in the
1231         // const behavior. Instead of using loopholes, I decided it was better
1232         // to make the fact that this is modified in a const method explicit.
1233         mutable const FloatingObject* m_last;
1234 #endif
1235     };
1236
1237     void createFloatingObjects();
1238
1239 public:
1240
1241     class FloatingObjects {
1242         WTF_MAKE_NONCOPYABLE(FloatingObjects); WTF_MAKE_FAST_ALLOCATED;
1243     public:
1244         void clear();
1245         void add(FloatingObject*);
1246         void remove(FloatingObject*);
1247         void addPlacedObject(FloatingObject*);
1248         void removePlacedObject(FloatingObject*);
1249         void setHorizontalWritingMode(bool b = true) { m_horizontalWritingMode = b; }
1250
1251         bool hasLeftObjects() const { return m_leftObjectsCount > 0; }
1252         bool hasRightObjects() const { return m_rightObjectsCount > 0; }
1253         const FloatingObjectSet& set() const { return m_set; }
1254         const FloatingObjectTree& placedFloatsTree()
1255         {
1256             computePlacedFloatsTreeIfNeeded();
1257             return m_placedFloatsTree; 
1258         }
1259     private:
1260         FloatingObjects(const RenderBlock*, bool horizontalWritingMode);
1261         void computePlacedFloatsTree();
1262         inline void computePlacedFloatsTreeIfNeeded()
1263         {
1264             if (!m_placedFloatsTree.isInitialized())
1265                 computePlacedFloatsTree();
1266         }
1267         void increaseObjectsCount(FloatingObject::Type);
1268         void decreaseObjectsCount(FloatingObject::Type);
1269         FloatingObjectInterval intervalForFloatingObject(FloatingObject*);
1270
1271         FloatingObjectSet m_set;
1272         FloatingObjectTree m_placedFloatsTree;
1273         unsigned m_leftObjectsCount;
1274         unsigned m_rightObjectsCount;
1275         bool m_horizontalWritingMode;
1276         const RenderBlock* m_renderer;
1277
1278         friend void RenderBlock::createFloatingObjects();
1279     };
1280
1281     // Allocated only when some of these fields have non-default values
1282     struct RenderBlockRareData {
1283         WTF_MAKE_NONCOPYABLE(RenderBlockRareData); WTF_MAKE_FAST_ALLOCATED;
1284     public:
1285         RenderBlockRareData(const RenderBlock* block) 
1286             : m_margins(positiveMarginBeforeDefault(block), negativeMarginBeforeDefault(block), positiveMarginAfterDefault(block), negativeMarginAfterDefault(block))
1287             , m_paginationStrut(0)
1288             , m_pageLogicalOffset(0)
1289             , m_lineGridBox(0)
1290             , m_lineBreakToAvoidWidow(-1)
1291             , m_shouldBreakAtLineToAvoidWidow(false)
1292             , m_discardMarginBefore(false)
1293             , m_discardMarginAfter(false)
1294         { 
1295         }
1296
1297         static LayoutUnit positiveMarginBeforeDefault(const RenderBlock* block)
1298         { 
1299             return std::max<LayoutUnit>(block->marginBefore(), 0);
1300         }
1301         static LayoutUnit negativeMarginBeforeDefault(const RenderBlock* block)
1302         { 
1303             return std::max<LayoutUnit>(-block->marginBefore(), 0);
1304         }
1305         static LayoutUnit positiveMarginAfterDefault(const RenderBlock* block)
1306         {
1307             return std::max<LayoutUnit>(block->marginAfter(), 0);
1308         }
1309         static LayoutUnit negativeMarginAfterDefault(const RenderBlock* block)
1310         {
1311             return std::max<LayoutUnit>(-block->marginAfter(), 0);
1312         }
1313         
1314         MarginValues m_margins;
1315         LayoutUnit m_paginationStrut;
1316         LayoutUnit m_pageLogicalOffset;
1317         
1318         RootInlineBox* m_lineGridBox;
1319
1320         int m_lineBreakToAvoidWidow;
1321 #if ENABLE(CSS_SHAPES)
1322         OwnPtr<ShapeInsideInfo> m_shapeInsideInfo;
1323 #endif
1324         bool m_shouldBreakAtLineToAvoidWidow : 1;
1325         bool m_discardMarginBefore : 1;
1326         bool m_discardMarginAfter : 1;
1327      };
1328
1329 protected:
1330
1331     OwnPtr<FloatingObjects> m_floatingObjects;
1332     OwnPtr<RenderBlockRareData> m_rareData;
1333
1334     RenderObjectChildList m_children;
1335     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>.
1336
1337     mutable signed m_lineHeight : 27;
1338     unsigned m_hasMarginBeforeQuirk : 1; // Note these quirk values can't be put in RenderBlockRareData since they are set too frequently.
1339     unsigned m_hasMarginAfterQuirk : 1;
1340     unsigned m_beingDestroyed : 1;
1341     unsigned m_hasMarkupTruncation : 1;
1342     unsigned m_hasBorderOrPaddingLogicalWidthChanged : 1;
1343
1344     // RenderRubyBase objects need to be able to split and merge, moving their children around
1345     // (calling moveChildTo, moveAllChildrenTo, and makeChildrenNonInline).
1346     friend class RenderRubyBase;
1347     friend class LineWidth; // Needs to know FloatingObject
1348
1349 private:
1350     // Used to store state between styleWillChange and styleDidChange
1351     static bool s_canPropagateFloatIntoSibling;
1352 };
1353
1354 inline RenderBlock* toRenderBlock(RenderObject* object)
1355
1356     ASSERT_WITH_SECURITY_IMPLICATION(!object || object->isRenderBlock());
1357     return static_cast<RenderBlock*>(object);
1358 }
1359
1360 inline const RenderBlock* toRenderBlock(const RenderObject* object)
1361
1362     ASSERT_WITH_SECURITY_IMPLICATION(!object || object->isRenderBlock());
1363     return static_cast<const RenderBlock*>(object);
1364 }
1365
1366 // This will catch anyone doing an unnecessary cast.
1367 void toRenderBlock(const RenderBlock*);
1368
1369 #ifndef NDEBUG
1370 // These structures are used by PODIntervalTree for debugging purposes.
1371 template <> struct ValueToString<int> {
1372     static String string(const int value);
1373 };
1374 template<> struct ValueToString<RenderBlock::FloatingObject*> {
1375     static String string(const RenderBlock::FloatingObject*);
1376 };
1377 #endif
1378
1379 } // namespace WebCore
1380
1381 #endif // RenderBlock_h