• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 "DeprecatedPtrList.h"
27 #include "GapRects.h"
28 #include "RenderBox.h"
29 #include "RenderLineBoxList.h"
30 #include "RootInlineBox.h"
31 #include <wtf/ListHashSet.h>
32 
33 namespace WebCore {
34 
35 class InlineIterator;
36 class RenderInline;
37 
38 struct BidiRun;
39 
40 template <class Iterator, class Run> class BidiResolver;
41 template <class Iterator> class MidpointState;
42 typedef BidiResolver<InlineIterator, BidiRun> InlineBidiResolver;
43 typedef MidpointState<InlineIterator> LineMidpointState;
44 
45 enum CaretType { CursorCaret, DragCaret };
46 
47 class RenderBlock : public RenderBox {
48 public:
49     RenderBlock(Node*);
50     virtual ~RenderBlock();
51 
children()52     const RenderObjectChildList* children() const { return &m_children; }
children()53     RenderObjectChildList* children() { return &m_children; }
54 
55     virtual void destroy();
56 
57     // These two functions are overridden for inline-block.
58     virtual int lineHeight(bool firstLine, bool isRootLineBox = false) const;
59     virtual int baselinePosition(bool firstLine, bool isRootLineBox = false) const;
60 
lineBoxes()61     RenderLineBoxList* lineBoxes() { return &m_lineBoxes; }
lineBoxes()62     const RenderLineBoxList* lineBoxes() const { return &m_lineBoxes; }
63 
firstLineBox()64     InlineFlowBox* firstLineBox() const { return m_lineBoxes.firstLineBox(); }
lastLineBox()65     InlineFlowBox* lastLineBox() const { return m_lineBoxes.lastLineBox(); }
66 
67     void deleteLineBoxTree();
68 
69     virtual void addChild(RenderObject* newChild, RenderObject* beforeChild = 0);
70     virtual void removeChild(RenderObject*);
71 
72     virtual void layoutBlock(bool relayoutChildren);
73 
74     void insertPositionedObject(RenderBox*);
75     void removePositionedObject(RenderBox*);
76     void removePositionedObjects(RenderBlock*);
77 
78     void addPercentHeightDescendant(RenderBox*);
79     static void removePercentHeightDescendant(RenderBox*);
80     HashSet<RenderBox*>* percentHeightDescendants() const;
81 
82     RootInlineBox* createAndAppendRootInlineBox();
83 
84     bool generatesLineBoxesForInlineChild(RenderObject*, bool isLineEmpty = true, bool previousLineBrokeCleanly = true);
85 
86     void markAllDescendantsWithFloatsForLayout(RenderBox* floatToRemove = 0, bool inLayout = true);
87     void markPositionedObjectsForLayout();
88 
containsFloats()89     bool containsFloats() { return m_floatingObjects && !m_floatingObjects->isEmpty(); }
90     bool containsFloat(RenderObject*);
91 
92     IntRect floatRect() const;
93 
94     int lineWidth(int y, bool firstLine) const;
95 
96     virtual int lowestPosition(bool includeOverflowInterior = true, bool includeSelf = true) const;
97     virtual int rightmostPosition(bool includeOverflowInterior = true, bool includeSelf = true) const;
98     virtual int leftmostPosition(bool includeOverflowInterior = true, bool includeSelf = true) const;
99 
rightOffset(int y,bool firstLine)100     int rightOffset(int y, bool firstLine) const { return rightRelOffset(y, rightOffset(), firstLine); }
leftOffset(int y,bool firstLine)101     int leftOffset(int y, bool firstLine) const { return leftRelOffset(y, leftOffset(), firstLine); }
102 
103     virtual VisiblePosition positionForPoint(const IntPoint&);
104 
105     // Block flows subclass availableWidth to handle multi column layout (shrinking the width available to children when laying out.)
106     virtual int availableWidth() const;
107 
firstRootBox()108     RootInlineBox* firstRootBox() const { return static_cast<RootInlineBox*>(firstLineBox()); }
lastRootBox()109     RootInlineBox* lastRootBox() const { return static_cast<RootInlineBox*>(lastLineBox()); }
110 
111     bool containsNonZeroBidiLevel() const;
112 
113     virtual void setSelectionState(SelectionState s);
114 
115     GapRects selectionGapRectsForRepaint(RenderBoxModelObject* repaintContainer);
116     IntRect fillLeftSelectionGap(RenderObject* selObj, int xPos, int yPos, int height, RenderBlock* rootBlock,
117                                  int blockX, int blockY, int tx, int ty, const PaintInfo*);
118     IntRect fillRightSelectionGap(RenderObject* selObj, int xPos, int yPos, int height, RenderBlock* rootBlock,
119                                   int blockX, int blockY, int tx, int ty, const PaintInfo*);
120     IntRect fillHorizontalSelectionGap(RenderObject* selObj, int xPos, int yPos, int width, int height, const PaintInfo*);
121 
122     void getHorizontalSelectionGapInfo(SelectionState, bool& leftGap, bool& rightGap);
123 
124     // Helper methods for computing line counts and heights for line counts.
125     RootInlineBox* lineAtIndex(int);
126     int lineCount();
127     int heightForLineCount(int);
128     void clearTruncation();
129 
130     void adjustRectForColumns(IntRect&) const;
131 
132     void addContinuationWithOutline(RenderInline*);
133 
inlineContinuation()134     RenderInline* inlineContinuation() const { return m_inlineContinuation; }
setInlineContinuation(RenderInline * c)135     void setInlineContinuation(RenderInline* c) { m_inlineContinuation = c; }
136 
137     // This function is a convenience helper for creating an anonymous block that inherits its
138     // style from this RenderBlock.
139     RenderBlock* createAnonymousBlock(bool isFlexibleBox = false) const;
140 
141     static void appendRunsForObject(int start, int end, RenderObject*, InlineBidiResolver&);
142     static bool requiresLineBox(const InlineIterator&, bool isLineEmpty = true, bool previousLineBrokeCleanly = true);
143 
144 protected:
145     void moveChildTo(RenderObject* to, RenderObjectChildList* toChildList, RenderObject* child);
146     void moveChildTo(RenderObject* to, RenderObjectChildList* toChildList, RenderObject* beforeChild, RenderObject* child);
147     void moveAllChildrenTo(RenderObject* to, RenderObjectChildList* toChildList);
148     void moveAllChildrenTo(RenderObject* to, RenderObjectChildList* toChildList, RenderObject* beforeChild);
149 
maxTopPosMargin()150     int maxTopPosMargin() const { return m_maxMargin ? m_maxMargin->m_topPos : MaxMargin::topPosDefault(this); }
maxTopNegMargin()151     int maxTopNegMargin() const { return m_maxMargin ? m_maxMargin->m_topNeg : MaxMargin::topNegDefault(this); }
maxBottomPosMargin()152     int maxBottomPosMargin() const { return m_maxMargin ? m_maxMargin->m_bottomPos : MaxMargin::bottomPosDefault(this); }
maxBottomNegMargin()153     int maxBottomNegMargin() const { return m_maxMargin ? m_maxMargin->m_bottomNeg : MaxMargin::bottomNegDefault(this); }
154     void setMaxTopMargins(int pos, int neg);
155     void setMaxBottomMargins(int pos, int neg);
156 
initMaxMarginValues()157     void initMaxMarginValues()
158     {
159         if (m_maxMargin) {
160             m_maxMargin->m_topPos = MaxMargin::topPosDefault(this);
161             m_maxMargin->m_topNeg = MaxMargin::topNegDefault(this);
162             m_maxMargin->m_bottomPos = MaxMargin::bottomPosDefault(this);
163             m_maxMargin->m_bottomNeg = MaxMargin::bottomNegDefault(this);
164         }
165     }
166 
167     virtual void layout();
168 
169     void layoutPositionedObjects(bool relayoutChildren);
170 
171     virtual void paint(PaintInfo&, int tx, int ty);
172     virtual void paintObject(PaintInfo&, int tx, int ty);
173 
174     int rightRelOffset(int y, int fixedOffset, bool applyTextIndent = true, int* heightRemaining = 0) const;
175     int leftRelOffset(int y, int fixedOffset, bool applyTextIndent = true, int* heightRemaining = 0) const;
176 
177     virtual bool nodeAtPoint(const HitTestRequest&, HitTestResult&, int x, int y, int tx, int ty, HitTestAction);
178 
179     virtual void calcPrefWidths();
180 
181     virtual int firstLineBoxBaseline() const;
182     virtual int lastLineBoxBaseline() const;
183 
184     virtual void updateFirstLetter();
185 
186     virtual void updateHitTestResult(HitTestResult&, const IntPoint&);
187 
188     // Delay update scrollbar until finishDelayRepaint() will be
189     // called. This function is used when a flexbox is laying out its
190     // descendant. If multiple calls are made to startDelayRepaint(),
191     // finishDelayRepaint() will do nothing until finishDelayRepaint()
192     // is called the same number of times.
193     static void startDelayUpdateScrollInfo();
194     static void finishDelayUpdateScrollInfo();
195 
196     virtual void styleWillChange(StyleDifference, const RenderStyle* newStyle);
197     virtual void styleDidChange(StyleDifference, const RenderStyle* oldStyle);
198 
199     virtual bool hasLineIfEmpty() const;
200     bool layoutOnlyPositionedObjects();
201 
202 private:
virtualChildren()203     virtual RenderObjectChildList* virtualChildren() { return children(); }
virtualChildren()204     virtual const RenderObjectChildList* virtualChildren() const { return children(); }
205 
206     virtual const char* renderName() const;
207 
isRenderBlock()208     virtual bool isRenderBlock() const { return true; }
isBlockFlow()209     virtual bool isBlockFlow() const { return (!isInline() || isReplaced()) && !isTable(); }
isInlineBlockOrInlineTable()210     virtual bool isInlineBlockOrInlineTable() const { return isInline() && isReplaced(); }
211 
212     void makeChildrenNonInline(RenderObject* insertionPoint = 0);
213     virtual void removeLeftoverAnonymousBlock(RenderBlock* child);
214 
dirtyLinesFromChangedChild(RenderObject * child)215     virtual void dirtyLinesFromChangedChild(RenderObject* child) { m_lineBoxes.dirtyLinesFromChangedChild(this, child); }
216 
217     virtual bool isSelfCollapsingBlock() const;
218 
maxTopMargin(bool positive)219     virtual int maxTopMargin(bool positive) const { return positive ? maxTopPosMargin() : maxTopNegMargin(); }
maxBottomMargin(bool positive)220     virtual int maxBottomMargin(bool positive) const { return positive ? maxBottomPosMargin() : maxBottomNegMargin(); }
221 
222     virtual void repaintOverhangingFloats(bool paintAllDescendants);
223 
224     void layoutBlockChildren(bool relayoutChildren, int& maxFloatBottom);
225     void layoutInlineChildren(bool relayoutChildren, int& repaintTop, int& repaintBottom);
226 
positionListMarker()227     virtual void positionListMarker() { }
228 
229     virtual void borderFitAdjust(int& x, int& w) const; // Shrink the box in which the border paints if border-fit is set.
230 
231     virtual void updateBeforeAfterContent(PseudoId);
232 
233     virtual RootInlineBox* createRootInlineBox(); // Subclassed by SVG and Ruby.
234 
235     // Called to lay out the legend for a fieldset.
layoutLegend(bool)236     virtual RenderObject* layoutLegend(bool /*relayoutChildren*/) { return 0; }
237 
238     struct FloatWithRect {
FloatWithRectFloatWithRect239         FloatWithRect(RenderBox* f)
240             : object(f)
241             , rect(IntRect(f->x() - f->marginLeft(), f->y() - f->marginTop(), f->width() + f->marginLeft() + f->marginRight(), f->height() + f->marginTop() + f->marginBottom()))
242             , everHadLayout(f->m_everHadLayout)
243         {
244         }
245 
246         RenderBox* object;
247         IntRect rect;
248         bool everHadLayout;
249     };
250 
251     // The following functions' implementations are in RenderBlockLineLayout.cpp.
252     void bidiReorderLine(InlineBidiResolver&, const InlineIterator& end, bool previousLineBrokeCleanly);
253     RootInlineBox* determineStartPosition(bool& firstLine, bool& fullLayout, bool& previousLineBrokeCleanly,
254                                           InlineBidiResolver&, Vector<FloatWithRect>& floats, unsigned& numCleanFloats);
255     RootInlineBox* determineEndPosition(RootInlineBox* startBox, InlineIterator& cleanLineStart,
256                                         BidiStatus& cleanLineBidiStatus,
257                                         int& yPos);
258     bool matchedEndLine(const InlineBidiResolver&, const InlineIterator& endLineStart, const BidiStatus& endLineStatus,
259                         RootInlineBox*& endLine, int& endYPos, int& repaintBottom, int& repaintTop);
260 
261     void skipTrailingWhitespace(InlineIterator&, bool isLineEmpty, bool previousLineBrokeCleanly);
262     int skipLeadingWhitespace(InlineBidiResolver&, bool firstLine, bool isLineEmpty, bool previousLineBrokeCleanly);
263     void fitBelowFloats(int widthToFit, bool firstLine, int& availableWidth);
264     InlineIterator findNextLineBreak(InlineBidiResolver&, bool firstLine, bool& isLineEmpty, bool& previousLineBrokeCleanly, EClear* clear = 0);
265     RootInlineBox* constructLine(unsigned runCount, BidiRun* firstRun, BidiRun* lastRun, bool firstLine, bool lastLine, RenderObject* endObject);
266     InlineFlowBox* createLineBoxes(RenderObject*, bool firstLine);
267     void computeHorizontalPositionsForLine(RootInlineBox*, bool firstLine, BidiRun* firstRun, BidiRun* trailingSpaceRun, bool reachedEnd);
268     void computeVerticalPositionsForLine(RootInlineBox*, BidiRun*);
269     void deleteEllipsisLineBoxes();
270     void checkLinesForTextOverflow();
271     void addOverflowFromInlineChildren();
272     // End of functions defined in RenderBlockLineLayout.cpp.
273 
274     void addOverflowFromBlockChildren();
275     void addOverflowFromFloats();
276 
277     void paintFloats(PaintInfo&, int tx, int ty, bool preservePhase = false);
278     void paintContents(PaintInfo&, int tx, int ty);
279     void paintColumnContents(PaintInfo&, int tx, int ty, bool paintFloats = false);
280     void paintColumnRules(PaintInfo&, int tx, int ty);
281     void paintChildren(PaintInfo&, int tx, int ty);
282     void paintEllipsisBoxes(PaintInfo&, int tx, int ty);
283     void paintSelection(PaintInfo&, int tx, int ty);
284     void paintCaret(PaintInfo&, int tx, int ty, CaretType);
285 
286     void insertFloatingObject(RenderBox*);
287     void removeFloatingObject(RenderBox*);
288 
289     // Called from lineWidth, to position the floats added in the last line.
290     // Returns ture if and only if it has positioned any floats.
291     bool positionNewFloats();
292     void clearFloats();
293     int getClearDelta(RenderBox* child, int yPos);
294 
295     virtual bool avoidsFloats() const;
296 
hasOverhangingFloats()297     bool hasOverhangingFloats() { return parent() && !hasColumns() && floatBottom() > height(); }
298     void addIntrudingFloats(RenderBlock* prev, int xoffset, int yoffset);
299     int addOverhangingFloats(RenderBlock* child, int xoffset, int yoffset, bool makeChildPaintOtherFloats);
300 
301     int nextFloatBottomBelow(int) const;
302     int floatBottom() const;
303     inline int leftBottom();
304     inline int rightBottom();
305 
306     int rightOffset() const;
307     int leftOffset() const;
308     virtual bool hitTestColumns(const HitTestRequest&, HitTestResult&, int x, int y, int tx, int ty, HitTestAction);
309     virtual bool hitTestContents(const HitTestRequest&, HitTestResult&, int x, int y, int tx, int ty, HitTestAction);
310 
311     virtual bool isPointInOverflowControl(HitTestResult&, int x, int y, int tx, int ty);
312 
313     void calcInlinePrefWidths();
314     void calcBlockPrefWidths();
315 
316     // Obtains the nearest enclosing block (including this block) that contributes a first-line style to our inline
317     // children.
318     virtual RenderBlock* firstLineBlock() const;
319     bool inRootBlockContext() const;
320 
321     virtual IntRect rectWithOutlineForRepaint(RenderBoxModelObject* repaintContainer, int outlineWidth);
322     virtual RenderStyle* outlineStyleForRepaint() const;
323 
324     virtual RenderObject* hoverAncestor() const;
325     virtual void updateDragState(bool dragOn);
326     virtual void childBecameNonInline(RenderObject* child);
327 
selectionRectForRepaint(RenderBoxModelObject * repaintContainer,bool)328     virtual IntRect selectionRectForRepaint(RenderBoxModelObject* repaintContainer, bool /*clipToVisibleContent*/)
329     {
330         return selectionGapRectsForRepaint(repaintContainer);
331     }
332     virtual bool shouldPaintSelectionGaps() const;
333     bool isSelectionRoot() const;
334     GapRects fillSelectionGaps(RenderBlock* rootBlock, int blockX, int blockY, int tx, int ty,
335                                int& lastTop, int& lastLeft, int& lastRight, const PaintInfo* = 0);
336     GapRects fillInlineSelectionGaps(RenderBlock* rootBlock, int blockX, int blockY, int tx, int ty,
337                                      int& lastTop, int& lastLeft, int& lastRight, const PaintInfo*);
338     GapRects fillBlockSelectionGaps(RenderBlock* rootBlock, int blockX, int blockY, int tx, int ty,
339                                     int& lastTop, int& lastLeft, int& lastRight, const PaintInfo*);
340     IntRect fillVerticalSelectionGap(int lastTop, int lastLeft, int lastRight, int bottomY, RenderBlock* rootBlock,
341                                      int blockX, int blockY, const PaintInfo*);
342     int leftSelectionOffset(RenderBlock* rootBlock, int y);
343     int rightSelectionOffset(RenderBlock* rootBlock, int y);
344 
345     virtual void absoluteRects(Vector<IntRect>&, int tx, int ty);
346     virtual void absoluteQuads(Vector<FloatQuad>&);
347 
348     int desiredColumnWidth() const;
349     unsigned desiredColumnCount() const;
350 #if PLATFORM(ANDROID)
351 public:
352 #endif
353     Vector<IntRect>* columnRects() const;
354 #if PLATFORM(ANDROID)
355 private:
356 #endif
357     void setDesiredColumnCountAndWidth(int count, int width);
358 #if PLATFORM(ANDROID)
359 public:
360 #endif
361     int columnGap() const;
362 #if PLATFORM(ANDROID)
363 private:
364 #endif
365 
366     void paintContinuationOutlines(PaintInfo&, int tx, int ty);
367 
368     virtual IntRect localCaretRect(InlineBox*, int caretOffset, int* extraWidthToEndOfLine = 0);
369 
370     virtual void addFocusRingRects(Vector<IntRect>&, int tx, int ty);
371 
372     void adjustPointToColumnContents(IntPoint&) const;
373     void adjustForBorderFit(int x, int& left, int& right) const; // Helper function for borderFitAdjust
374 
375     void markLinesDirtyInVerticalRange(int top, int bottom, RootInlineBox* highest = 0);
376 
377     void newLine(EClear);
378 
379     Position positionForBox(InlineBox*, bool start = true) const;
380     Position positionForRenderer(RenderObject*, bool start = true) const;
381     VisiblePosition positionForPointWithInlineChildren(const IntPoint&);
382 
383     // Adjust tx and ty from painting offsets to the local coords of this renderer
384     void offsetForContents(int& tx, int& ty) const;
385 
386     void calcColumnWidth();
387     int layoutColumns(int endOfContent = -1, int requestedColumnHeight = -1);
388 
389     bool expandsToEncloseOverhangingFloats() const;
390 
391     void updateScrollInfoAfterLayout();
392 
393     struct FloatingObject : Noncopyable {
394         enum Type {
395             FloatLeft,
396             FloatRight
397         };
398 
FloatingObjectFloatingObject399         FloatingObject(Type type)
400             : m_renderer(0)
401             , m_top(0)
402             , m_bottom(0)
403             , m_left(0)
404             , m_width(0)
405             , m_type(type)
406             , m_shouldPaint(true)
407             , m_isDescendant(false)
408         {
409         }
410 
typeFloatingObject411         Type type() { return static_cast<Type>(m_type); }
412 
413         RenderBox* m_renderer;
414         int m_top;
415         int m_bottom;
416         int m_left;
417         int m_width;
418         unsigned m_type : 1; // Type (left or right aligned)
419         bool m_shouldPaint : 1;
420         bool m_isDescendant : 1;
421     };
422 
423     class MarginInfo {
424         // Collapsing flags for whether we can collapse our margins with our children's margins.
425         bool m_canCollapseWithChildren : 1;
426         bool m_canCollapseTopWithChildren : 1;
427         bool m_canCollapseBottomWithChildren : 1;
428 
429         // Whether or not we are a quirky container, i.e., do we collapse away top and bottom
430         // margins in our container.  Table cells and the body are the common examples. We
431         // also have a custom style property for Safari RSS to deal with TypePad blog articles.
432         bool m_quirkContainer : 1;
433 
434         // This flag tracks whether we are still looking at child margins that can all collapse together at the beginning of a block.
435         // They may or may not collapse with the top margin of the block (|m_canCollapseTopWithChildren| tells us that), but they will
436         // always be collapsing with one another.  This variable can remain set to true through multiple iterations
437         // as long as we keep encountering self-collapsing blocks.
438         bool m_atTopOfBlock : 1;
439 
440         // This flag is set when we know we're examining bottom margins and we know we're at the bottom of the block.
441         bool m_atBottomOfBlock : 1;
442 
443         // These variables are used to detect quirky margins that we need to collapse away (in table cells
444         // and in the body element).
445         bool m_topQuirk : 1;
446         bool m_bottomQuirk : 1;
447         bool m_determinedTopQuirk : 1;
448 
449         // These flags track the previous maximal positive and negative margins.
450         int m_posMargin;
451         int m_negMargin;
452 
453     public:
454         MarginInfo(RenderBlock* b, int top, int bottom);
455 
setAtTopOfBlock(bool b)456         void setAtTopOfBlock(bool b) { m_atTopOfBlock = b; }
setAtBottomOfBlock(bool b)457         void setAtBottomOfBlock(bool b) { m_atBottomOfBlock = b; }
clearMargin()458         void clearMargin() { m_posMargin = m_negMargin = 0; }
setTopQuirk(bool b)459         void setTopQuirk(bool b) { m_topQuirk = b; }
setBottomQuirk(bool b)460         void setBottomQuirk(bool b) { m_bottomQuirk = b; }
setDeterminedTopQuirk(bool b)461         void setDeterminedTopQuirk(bool b) { m_determinedTopQuirk = b; }
setPosMargin(int p)462         void setPosMargin(int p) { m_posMargin = p; }
setNegMargin(int n)463         void setNegMargin(int n) { m_negMargin = n; }
setPosMarginIfLarger(int p)464         void setPosMarginIfLarger(int p) { if (p > m_posMargin) m_posMargin = p; }
setNegMarginIfLarger(int n)465         void setNegMarginIfLarger(int n) { if (n > m_negMargin) m_negMargin = n; }
466 
setMargin(int p,int n)467         void setMargin(int p, int n) { m_posMargin = p; m_negMargin = n; }
468 
atTopOfBlock()469         bool atTopOfBlock() const { return m_atTopOfBlock; }
canCollapseWithTop()470         bool canCollapseWithTop() const { return m_atTopOfBlock && m_canCollapseTopWithChildren; }
canCollapseWithBottom()471         bool canCollapseWithBottom() const { return m_atBottomOfBlock && m_canCollapseBottomWithChildren; }
canCollapseTopWithChildren()472         bool canCollapseTopWithChildren() const { return m_canCollapseTopWithChildren; }
canCollapseBottomWithChildren()473         bool canCollapseBottomWithChildren() const { return m_canCollapseBottomWithChildren; }
quirkContainer()474         bool quirkContainer() const { return m_quirkContainer; }
determinedTopQuirk()475         bool determinedTopQuirk() const { return m_determinedTopQuirk; }
topQuirk()476         bool topQuirk() const { return m_topQuirk; }
bottomQuirk()477         bool bottomQuirk() const { return m_bottomQuirk; }
posMargin()478         int posMargin() const { return m_posMargin; }
negMargin()479         int negMargin() const { return m_negMargin; }
margin()480         int margin() const { return m_posMargin - m_negMargin; }
481     };
482 
483     void layoutBlockChild(RenderBox* child, MarginInfo&, int& previousFloatBottom, int& maxFloatBottom);
484     void adjustPositionedBlock(RenderBox* child, const MarginInfo&);
485     void adjustFloatingBlock(const MarginInfo&);
486     bool handleSpecialChild(RenderBox* child, const MarginInfo&);
487     bool handleFloatingChild(RenderBox* child, const MarginInfo&);
488     bool handlePositionedChild(RenderBox* child, const MarginInfo&);
489     bool handleRunInChild(RenderBox* child);
490     int collapseMargins(RenderBox* child, MarginInfo&);
491     int clearFloatsIfNeeded(RenderBox* child, MarginInfo&, int oldTopPosMargin, int oldTopNegMargin, int yPos);
492     int estimateVerticalPosition(RenderBox* child, const MarginInfo&);
493     void determineHorizontalPosition(RenderBox* child);
494     void handleBottomOfBlock(int top, int bottom, MarginInfo&);
495     void setCollapsedBottomMargin(const MarginInfo&);
496     // End helper functions and structs used by layoutBlockChildren.
497 
498     typedef ListHashSet<RenderBox*>::const_iterator Iterator;
499     DeprecatedPtrList<FloatingObject>* m_floatingObjects;
500     ListHashSet<RenderBox*>* m_positionedObjects;
501 
502     // An inline can be split with blocks occurring in between the inline content.
503     // When this occurs we need a pointer to our next object.  We can basically be
504     // split into a sequence of inlines and blocks.  The continuation will either be
505     // an anonymous block (that houses other blocks) or it will be an inline flow.
506     RenderInline* m_inlineContinuation;
507 
508     // Allocated only when some of these fields have non-default values
509     struct MaxMargin : Noncopyable {
MaxMarginMaxMargin510         MaxMargin(const RenderBlock* o)
511             : m_topPos(topPosDefault(o))
512             , m_topNeg(topNegDefault(o))
513             , m_bottomPos(bottomPosDefault(o))
514             , m_bottomNeg(bottomNegDefault(o))
515         {
516         }
517 
topPosDefaultMaxMargin518         static int topPosDefault(const RenderBlock* o) { return o->marginTop() > 0 ? o->marginTop() : 0; }
topNegDefaultMaxMargin519         static int topNegDefault(const RenderBlock* o) { return o->marginTop() < 0 ? -o->marginTop() : 0; }
bottomPosDefaultMaxMargin520         static int bottomPosDefault(const RenderBlock* o) { return o->marginBottom() > 0 ? o->marginBottom() : 0; }
bottomNegDefaultMaxMargin521         static int bottomNegDefault(const RenderBlock* o) { return o->marginBottom() < 0 ? -o->marginBottom() : 0; }
522 
523         int m_topPos;
524         int m_topNeg;
525         int m_bottomPos;
526         int m_bottomNeg;
527      };
528 
529     MaxMargin* m_maxMargin;
530 
531     RenderObjectChildList m_children;
532     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>.
533 
534     mutable int m_lineHeight;
535 
536     // RenderRubyBase objects need to be able to split and merge, moving their children around
537     // (calling moveChildTo, moveAllChildrenTo, and makeChildrenNonInline).
538     friend class RenderRubyBase;
539 };
540 
toRenderBlock(RenderObject * object)541 inline RenderBlock* toRenderBlock(RenderObject* object)
542 {
543     ASSERT(!object || object->isRenderBlock());
544     return static_cast<RenderBlock*>(object);
545 }
546 
toRenderBlock(const RenderObject * object)547 inline const RenderBlock* toRenderBlock(const RenderObject* object)
548 {
549     ASSERT(!object || object->isRenderBlock());
550     return static_cast<const RenderBlock*>(object);
551 }
552 
553 // This will catch anyone doing an unnecessary cast.
554 void toRenderBlock(const RenderBlock*);
555 
556 } // namespace WebCore
557 
558 #endif // RenderBlock_h
559