Back out my changes to the fix for my previous checkin, since it broke the inline...
[WebKit-https.git] / WebCore / khtml / rendering / render_block.h
1 /*
2  * This file is part of the render object implementation for KHTML.
3  *
4  * Copyright (C) 1999 Lars Knoll (knoll@kde.org)
5  *           (C) 1999 Antti Koivisto (koivisto@kde.org)
6  * Copyright (C) 2003 Apple Computer, Inc.
7  *
8  * This library is free software; you can redistribute it and/or
9  * modify it under the terms of the GNU Library General Public
10  * License as published by the Free Software Foundation; either
11  * version 2 of the License, or (at your option) any later version.
12  *
13  * This library is distributed in the hope that it will be useful,
14  * but WITHOUT ANY WARRANTY; without even the implied warranty of
15  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
16  * Library General Public License for more details.
17  *
18  * You should have received a copy of the GNU Library General Public License
19  * along with this library; see the file COPYING.LIB.  If not, write to
20  * the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
21  * Boston, MA 02111-1307, USA.
22  *
23  */
24
25 #ifndef RENDER_BLOCK_H
26 #define RENDER_BLOCK_H
27
28 #include <qptrlist.h>
29
30 #include "render_flow.h"
31
32 namespace DOM {
33     class Position;
34 }
35
36 namespace khtml {
37
38 class RenderBlock : public RenderFlow
39 {
40 public:
41     RenderBlock(DOM::NodeImpl* node);
42     virtual ~RenderBlock();
43
44     virtual const char *renderName() const;
45
46     // These two functions are overridden for inline-block.
47     virtual short lineHeight(bool b, bool isRootLineBox=false) const;
48     virtual short baselinePosition(bool b, bool isRootLineBox=false) const;
49     
50     virtual bool isRenderBlock() const { return true; }
51     virtual bool isBlockFlow() const { return (!isInline() || isReplaced()) && !isTable(); }
52     virtual bool isInlineFlow() const { return isInline() && !isReplaced(); }
53     virtual bool isInlineBlockOrInlineTable() const { return isInline() && isReplaced(); }
54     
55     virtual bool childrenInline() const { return m_childrenInline; }
56     virtual void setChildrenInline(bool b) { m_childrenInline = b; }
57     void makeChildrenNonInline(RenderObject* insertionPoint = 0);
58
59     // The height (and width) of a block when you include overflow spillage out of the bottom
60     // of the block (e.g., a <div style="height:25px"> that has a 100px tall image inside
61     // it would have an overflow height of borderTop() + paddingTop() + 100px.
62     virtual int overflowHeight(bool includeInterior=true) const
63     { return (!includeInterior && hasOverflowClip()) ? m_height : m_overflowHeight; }
64     virtual int overflowWidth(bool includeInterior=true) const
65     { return (!includeInterior && hasOverflowClip()) ? m_width : m_overflowWidth; }
66     virtual void setOverflowHeight(int h) { m_overflowHeight = h; }
67     virtual void setOverflowWidth(int w) { m_overflowWidth = w; }
68
69     virtual bool isSelfCollapsingBlock() const;
70     virtual bool isTopMarginQuirk() const { return m_topMarginQuirk; }
71     virtual bool isBottomMarginQuirk() const { return m_bottomMarginQuirk; }
72
73     virtual short maxTopMargin(bool positive) const {
74         if (positive)
75             return m_maxTopPosMargin;
76         else
77             return m_maxTopNegMargin;
78     }
79     virtual short maxBottomMargin(bool positive) const {
80         if (positive)
81             return m_maxBottomPosMargin;
82         else
83             return m_maxBottomNegMargin;
84     }
85
86     void initMaxMarginValues() {
87         if (m_marginTop >= 0)
88             m_maxTopPosMargin = m_marginTop;
89         else
90             m_maxTopNegMargin = -m_marginTop;
91         if (m_marginBottom >= 0)
92             m_maxBottomPosMargin = m_marginBottom;
93         else
94             m_maxBottomNegMargin = -m_marginBottom;
95     }
96
97     virtual void addChildToFlow(RenderObject* newChild, RenderObject* beforeChild);
98     virtual void removeChild(RenderObject *oldChild);
99
100     virtual void repaintObjectsBeforeLayout();
101     virtual void repaintFloatingDescendants();
102     virtual void getAbsoluteRepaintRectIncludingFloats(QRect& bounds, QRect& fullBounds);
103
104     virtual void setStyle(RenderStyle* _style);
105
106     virtual void layout();
107     virtual void layoutBlock( bool relayoutChildren );
108     void layoutBlockChildren( bool relayoutChildren );
109     QRect layoutInlineChildren( bool relayoutChildren );
110
111     void layoutPositionedObjects( bool relayoutChildren );
112     void insertPositionedObject(RenderObject *o);
113     void removePositionedObject(RenderObject *o);
114
115     // Called to lay out the legend for a fieldset.
116     virtual RenderObject* layoutLegend(bool relayoutChildren) { return 0; };
117     
118     // the implementation of the following functions is in bidi.cpp
119     void bidiReorderLine(const BidiIterator &start, const BidiIterator &end, BidiState &bidi );
120     RootInlineBox* determineStartPosition(bool fullLayout, BidiIterator &start, BidiState &bidi);
121     RootInlineBox* determineEndPosition(RootInlineBox* startBox, BidiIterator& cleanLineStart, int& yPos);
122     bool matchedEndLine(const BidiIterator& start, const BidiIterator& endLineStart, 
123                         RootInlineBox*& endLine, int& endYPos);
124     BidiIterator findNextLineBreak(BidiIterator &start, BidiState &info );
125     RootInlineBox* constructLine(const BidiIterator& start, const BidiIterator& end);
126     InlineFlowBox* createLineBoxes(RenderObject* obj);
127     void computeHorizontalPositionsForLine(RootInlineBox* lineBox, BidiState &bidi);
128     void computeVerticalPositionsForLine(RootInlineBox* lineBox);
129     void deleteEllipsisLineBoxes();
130     void checkLinesForTextOverflow();
131     // end bidi.cpp functions
132     
133     virtual void paint(PaintInfo& i, int tx, int ty);
134     void paintObject(PaintInfo& i, int tx, int ty);
135     void paintFloats(PaintInfo& i, int _tx, int _ty, bool paintSelection = false);
136     void paintEllipsisBoxes(PaintInfo& i, int _tx, int _ty);
137
138     void insertFloatingObject(RenderObject *o);
139     void removeFloatingObject(RenderObject *o);
140
141     // called from lineWidth, to position the floats added in the last line.
142     void positionNewFloats();
143     void clearFloats();
144     int getClearDelta(RenderObject *child);
145     virtual void markAllDescendantsWithFloatsForLayout(RenderObject* floatToRemove = 0);
146     void markPositionedObjectsForLayout();
147
148     virtual bool containsFloats() { return m_floatingObjects!=0; }
149     virtual bool containsFloat(RenderObject* o);
150
151     virtual bool hasOverhangingFloats() { return floatBottom() > m_height; }
152     void addOverHangingFloats( RenderBlock *block, int xoffset, int yoffset, bool child = false );
153     
154     int nearestFloatBottom(int height) const;
155     int floatBottom() const;
156     inline int leftBottom();
157     inline int rightBottom();
158
159     virtual int lineWidth(int y) const;
160     virtual int lowestPosition(bool includeOverflowInterior=true, bool includeSelf=true) const;
161     virtual int rightmostPosition(bool includeOverflowInterior=true, bool includeSelf=true) const;
162     virtual int leftmostPosition(bool includeOverflowInterior=true, bool includeSelf=true) const;
163
164     int rightOffset() const;
165     int rightRelOffset(int y, int fixedOffset, bool applyTextIndent = true,
166                        int *heightRemaining = 0) const;
167     int rightOffset(int y) const { return rightRelOffset(y, rightOffset(), true); }
168
169     int leftOffset() const;
170     int leftRelOffset(int y, int fixedOffset, bool applyTextIndent = true,
171                       int *heightRemaining = 0) const;
172     int leftOffset(int y) const { return leftRelOffset(y, leftOffset(), true); }
173
174     virtual bool nodeAtPoint(NodeInfo& info, int x, int y, int tx, int ty,
175                              HitTestAction hitTestAction = HitTestAll, bool inside=false);
176
177     bool isPointInScrollbar(int x, int y, int tx, int ty);
178
179     virtual DOM::Position positionForCoordinates(int x, int y);
180     
181     virtual void calcMinMaxWidth();
182     void calcInlineMinMaxWidth();
183     void calcBlockMinMaxWidth();
184
185     virtual int getBaselineOfFirstLineBox() const;
186
187     RootInlineBox* firstRootBox() { return static_cast<RootInlineBox*>(m_firstLineBox); }
188     RootInlineBox* lastRootBox() { return static_cast<RootInlineBox*>(m_lastLineBox); }
189
190     // Obtains the nearest enclosing block (including this block) that contributes a first-line style to our inline
191     // children.
192     virtual RenderBlock* firstLineBlock() const;
193     virtual void updateFirstLetter();
194     
195     bool inRootBlockContext() const;
196     
197     void setLinesAppended(bool b=true) { m_linesAppended = b; }
198     bool linesAppended() const { return m_linesAppended; }
199
200     void setHasMarkupTruncation(bool b=true) { m_hasMarkupTruncation = b; }
201     bool hasMarkupTruncation() const { return m_hasMarkupTruncation; }
202
203 #ifndef NDEBUG
204     virtual void printTree(int indent=0) const;
205     virtual void dump(QTextStream *stream, QString ind = "") const;
206 #endif
207
208     // Helper methods for computing line counts and heights for line counts.
209     RootInlineBox* lineAtIndex(int i);
210     int lineCount();
211     int heightForLineCount(int l);
212     void clearTruncation();
213
214 protected:
215     void newLine();
216     void removeChildrenFromLineBoxes();
217
218 private:
219     DOM::Position positionForBox(InlineBox *box, bool start=true) const;
220     DOM::Position positionForRenderer(RenderObject *renderer, bool start=true) const;
221     
222 protected:
223     struct FloatingObject {
224         enum Type {
225             FloatLeft,
226             FloatRight
227         };
228
229         FloatingObject(Type _type) {
230             node = 0;
231             startY = 0;
232             endY = 0;
233             type = _type;
234             left = 0;
235             width = 0;
236             noPaint = false;
237
238         }
239         RenderObject* node;
240         int startY;
241         int endY;
242         int left;
243         int width;
244         Type type : 1; // left or right aligned
245         bool noPaint : 1;
246     };
247     
248 protected:
249     QPtrList<FloatingObject>* m_floatingObjects;
250     QPtrList<RenderObject>* m_positionedObjects;
251     
252     bool m_childrenInline : 1;
253     bool m_pre            : 1;
254     bool m_firstLine      : 1; // used in inline layouting
255     EClear m_clearStatus  : 2; // used during layuting of paragraphs
256     bool m_topMarginQuirk : 1;
257     bool m_bottomMarginQuirk : 1;
258     bool m_linesAppended : 1; // Whether or not a block with inline children has had lines appended.
259     bool m_hasMarkupTruncation : 1;
260
261     short m_maxTopPosMargin;
262     short m_maxTopNegMargin;
263     short m_maxBottomPosMargin;
264     short m_maxBottomNegMargin;
265
266     // How much content overflows out of our block vertically or horizontally (all we support
267     // for now is spillage out of the bottom and the right, which are the common cases).
268     // XXX Generalize to work with top and left as well.
269     int m_overflowHeight;
270     int m_overflowWidth;
271 };
272
273 }; // namespace
274
275 #endif // RENDER_BLOCK_H
276