root/trunk/WebCore/rendering/RenderBlock.h

Revision 50869, 23.9 KB (checked in by hamaji@chromium.org, 10 days ago)

2009-11-12 Yuta Kitamura < yutak@chromium.org>

Reviewed by Eric Seidel.

Prevent text inside a multi-column block from being split into columns.

If the tentative height of a multi-column block was too small, we need to
expand the block height and try to layout again, in order to prevent text
from being split into different columns.

CSS Multicolumn text is split awkwardly
 https://bugs.webkit.org/show_bug.cgi?id=22249

  • fast/multicol/single-line.html: Added.
  • fast/multicol/single-line-expected.checksum: Added.
  • fast/multicol/single-line-expected.png: Added.
  • fast/multicol/single-line-expected.txt: Added.

2009-11-12 Yuta Kitamura < yutak@chromium.org>

Reviewed by Eric Seidel.

Prevent text inside a multi-column block from being split into columns.

If the tentative height of a multi-column block was too small, we need to
expand the block height and try to layout again, in order to prevent text
from being split into different columns.

CSS Multicolumn text is split awkwardly
 https://bugs.webkit.org/show_bug.cgi?id=22249

Test: fast/multicol/single-line.html

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