Clean up our detach model so that you can always get to a document, even for
[WebKit-https.git] / WebCore / khtml / rendering / render_object.h
1 /*
2  * This file is part of the html renderer for KDE.
3  *
4  * Copyright (C) 2000 Lars Knoll (knoll@kde.org)
5  *           (C) 2000 Antti Koivisto (koivisto@kde.org)
6  *           (C) 2000 Dirk Mueller (mueller@kde.org)
7  * Copyright (C) 2003 Apple Computer, Inc.
8  *
9  * This library is free software; you can redistribute it and/or
10  * modify it under the terms of the GNU Library General Public
11  * License as published by the Free Software Foundation; either
12  * version 2 of the License, or (at your option) any later version.
13  *
14  * This library is distributed in the hope that it will be useful,
15  * but WITHOUT ANY WARRANTY; without even the implied warranty of
16  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
17  * Library General Public License for more details.
18  *
19  * You should have received a copy of the GNU Library General Public License
20  * along with this library; see the file COPYING.LIB.  If not, write to
21  * the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
22  * Boston, MA 02111-1307, USA.
23  *
24  */
25 #ifndef render_object_h
26 #define render_object_h
27
28 #include <qcolor.h>
29 #include <qrect.h>
30 #include <assert.h>
31
32 #include "misc/khtmllayout.h"
33 #include "misc/loader_client.h"
34 #include "misc/helper.h"
35 #include "rendering/render_style.h"
36 #include "khtml_events.h"
37 #include "xml/dom_nodeimpl.h"
38
39 // Uncomment to turn on incremental repainting.
40 // #define INCREMENTAL_REPAINTING 1
41
42 class QPainter;
43 class QTextStream;
44 class CSSStyle;
45 class KHTMLView;
46 class RenderArena;
47
48 #ifndef NDEBUG
49 #define KHTMLAssert( x ) if( !(x) ) { \
50     const RenderObject *o = this; while( o->parent() ) o = o->parent(); \
51     o->printTree(); \
52     qDebug(" this object = %p", this ); \
53     assert( false ); \
54 }
55 #else
56 #define KHTMLAssert( x )
57 #endif
58
59 /*
60  *      The painting of a layer occurs in three distinct phases.  Each phase involves
61  *      a recursive descent into the layer's render objects. The first phase is the background phase.
62  *      The backgrounds and borders of all blocks are painted.  Inlines are not painted at all.
63  *      Floats must paint above block backgrounds but entirely below inline content that can overlap them.
64  *      In the foreground phase, all inlines are fully painted.  Inline replaced elements will get all
65  *      three phases invoked on them during this phase.
66  */
67
68 typedef enum {
69     PaintActionElementBackground = 0,
70     PaintActionChildBackground,
71     PaintActionChildBackgrounds,
72     PaintActionFloat,
73     PaintActionForeground,
74     PaintActionSelection
75 } PaintAction;
76
77 typedef enum {
78     HitTestAll = 0,
79     HitTestSelfOnly = 1,
80     HitTestChildrenOnly = 2
81 } HitTestAction;
82
83 namespace DOM {
84     class HTMLAreaElementImpl;
85     class DOMString;
86     class DocumentImpl;
87     class ElementImpl;
88     class EventImpl;
89 };
90
91 namespace khtml {
92     class RenderFlow;
93     class RenderBlock;
94     class RenderStyle;
95     class RenderTable;
96     class CachedObject;
97     class RenderCanvas;
98     class RenderText;
99     class RenderFrameSet;
100     class RenderLayer;
101     class InlineBox;
102     class InlineFlowBox;
103
104 /**
105  * Base Class for all rendering tree objects.
106  */
107 class RenderObject : public CachedObjectClient
108 {
109 public:
110     // Anonymous objects should pass the document as their node, and they will then automatically be
111     // marked as anonymous in the constructor.
112     RenderObject(DOM::NodeImpl* node);
113     virtual ~RenderObject();
114
115     RenderObject *parent() const { return m_parent; }
116
117     RenderObject *previousSibling() const { return m_previous; }
118     RenderObject *nextSibling() const { return m_next; }
119
120     virtual RenderObject *firstChild() const { return 0; }
121     virtual RenderObject *lastChild() const { return 0; }
122
123     virtual RenderLayer* layer() const { return 0; }
124     RenderLayer* enclosingLayer();
125     void addLayers(RenderLayer* parentLayer, RenderObject* newObject);
126     void removeLayers(RenderLayer* parentLayer);
127     void moveLayers(RenderLayer* oldParent, RenderLayer* newParent);
128     RenderLayer* findNextLayer(RenderLayer* parentLayer, RenderObject* startPoint,
129                                bool checkParent=true);
130     virtual void positionChildLayers() { }
131     virtual bool requiresLayer();
132     
133     virtual QRect getOverflowClipRect(int tx, int ty) { return QRect(0,0,0,0); }
134     virtual QRect getClipRect(int tx, int ty) { return QRect(0,0,0,0); }
135     bool hasClip() { return isPositioned() &&  style()->hasClip(); }
136     bool hasOverflowClip() { return style()->hidesOverflow(); }
137
138     virtual int getBaselineOfFirstLineBox() { return -1; } // Tables and blocks implement this.
139     virtual InlineFlowBox* getFirstLineBox() { return 0; } // Tables and blocks implement this.
140
141     // Called when an object that was floating or positioned becomes a normal flow object
142     // again.  We have to make sure the render tree updates as needed to accommodate the new
143     // normal flow object.
144     void handleDynamicFloatPositionChange();
145
146     // This function is a convenience helper for creating an anonymous block that inherits its
147     // style from this RenderObject.
148     RenderBlock* createAnonymousBlock();
149     
150     // Whether or not a positioned element requires normal flow x/y to be computed
151     // to determine its position.
152     bool hasStaticX() const;
153     bool hasStaticY() const;
154     virtual void setStaticX(short staticX) {};
155     virtual void setStaticY(int staticY) {};
156     
157     // RenderObject tree manipulation
158     //////////////////////////////////////////
159     virtual bool canHaveChildren() const;
160     virtual void addChild(RenderObject *newChild, RenderObject *beforeChild = 0);
161     virtual void removeChild(RenderObject *oldChild);
162
163     // raw tree manipulation
164     virtual RenderObject* removeChildNode(RenderObject* child);
165     virtual void appendChildNode(RenderObject* child);
166     virtual void insertChildNode(RenderObject* child, RenderObject* before);
167     //////////////////////////////////////////
168
169 private:
170     //////////////////////////////////////////
171     // Helper functions. Dangerous to use!
172     void setPreviousSibling(RenderObject *previous) { m_previous = previous; }
173     void setNextSibling(RenderObject *next) { m_next = next; }
174     void setParent(RenderObject *parent) { m_parent = parent; }
175     //////////////////////////////////////////
176
177 public:
178     virtual const char *renderName() const { return "RenderObject"; }
179 #ifndef NDEBUG
180     QString information() const;
181     virtual void printTree(int indent=0) const;
182     virtual void dump(QTextStream *stream, QString ind = "") const;
183 #endif
184
185     static RenderObject *createObject(DOM::NodeImpl* node, RenderStyle* style);
186
187     // Overloaded new operator.  Derived classes must override operator new
188     // in order to allocate out of the RenderArena.
189     void* operator new(size_t sz, RenderArena* renderArena) throw();    
190
191     // Overridden to prevent the normal delete from being called.
192     void operator delete(void* ptr, size_t sz);
193         
194 private:
195     // The normal operator new is disallowed on all render objects.
196     void* operator new(size_t sz) throw();
197     
198 public:
199     RenderArena* renderArena() const;
200     
201     // some helper functions...
202     virtual bool isRenderBlock() const { return false; }
203     virtual bool isRenderInline() const { return false; }
204     virtual bool isInlineFlow() const { return false; }
205     virtual bool isBlockFlow() const { return false; }
206     virtual bool isInlineBlockOrInlineTable() const { return false; }
207     virtual bool childrenInline() const { return false; }
208     virtual void setChildrenInline(bool b) { };
209
210     virtual RenderFlow* continuation() const;
211     virtual bool isInlineContinuation() const;
212     
213     virtual bool isListItem() const { return false; }
214     virtual bool isListMarker() const { return false; }
215     virtual bool isCanvas() const { return false; }
216     bool isRoot() const;
217     bool isBody() const;
218     virtual bool isBR() const { return false; }
219     virtual bool isTableCell() const { return false; }
220     virtual bool isTableRow() const { return false; }
221     virtual bool isTableSection() const { return false; }
222     virtual bool isTableCol() const { return false; }
223     virtual bool isTable() const { return false; }
224     virtual bool isWidget() const { return false; }
225     virtual bool isFormElement() const { return false; }
226     virtual bool isImage() const { return false; }
227     virtual bool isTextArea() const { return false; }
228     virtual bool isFrameSet() const { return false; }
229     virtual bool isApplet() const { return false; }
230
231     bool isAnonymous() const { return m_isAnonymous; }
232     void setIsAnonymous(bool b) { m_isAnonymous = b; }
233     
234     bool isFloating() const { return m_floating; }
235     bool isPositioned() const { return m_positioned; } // absolute or fixed positioning
236     bool isRelPositioned() const { return m_relPositioned; } // relative positioning
237     bool isText() const  { return m_isText; }
238     bool isInline() const { return m_inline; }  // inline object
239     bool isCompact() const { return style()->display() == COMPACT; } // compact object
240     bool isRunIn() const { return style()->display() == RUN_IN; } // run-in object
241     bool mouseInside() const;
242     bool isReplaced() const { return m_replaced; } // a "replaced" element (see CSS)
243     bool shouldPaintBackgroundOrBorder() const { return m_paintBackground; }
244     bool needsLayout() const   { return m_needsLayout || m_normalChildNeedsLayout || m_posChildNeedsLayout; }
245     bool selfNeedsLayout() const { return m_needsLayout; }
246     bool posChildNeedsLayout() const { return m_posChildNeedsLayout; }
247     bool normalChildNeedsLayout() const { return m_normalChildNeedsLayout; }
248     bool minMaxKnown() const{ return m_minMaxKnown; }
249     bool overhangingContents() const { return m_overhangingContents; }
250     bool hasFirstLine() const { return m_hasFirstLine; }
251     bool isSelectionBorder() const { return m_isSelectionBorder; }
252     bool recalcMinMax() const { return m_recalcMinMax; }
253
254     RenderCanvas* canvas() const;
255
256     // don't even think about making this method virtual!
257     DOM::NodeImpl* element() const { return m_isAnonymous ? 0 : m_node; }
258     DOM::DocumentImpl* document() const { return m_node->getDocument(); }
259     void setNode(DOM::NodeImpl* node) { m_node = node; }
260     DOM::NodeImpl* node() const { return m_node; }
261     
262    /**
263      * returns the object containing this one. can be different from parent for
264      * positioned elements
265      */
266     RenderObject *container() const;
267
268     void setOverhangingContents(bool p=true);
269
270     virtual void markAllDescendantsWithFloatsForLayout(RenderObject* floatToRemove = 0);
271     void markContainingBlocksForLayout();
272     void setNeedsLayout(bool b);
273     void setChildNeedsLayout(bool b);
274     void setMinMaxKnown(bool b=true) {
275         m_minMaxKnown = b;
276         if ( !b ) {
277             RenderObject *o = this;
278             RenderObject *root = this;
279             while( o ) { // ### && !o->m_recalcMinMax ) {
280                 o->m_recalcMinMax = true;
281                 root = o;
282                 o = o->m_parent;
283             }
284         }
285     }
286
287     void setNeedsLayoutAndMinMaxRecalc() {
288         setMinMaxKnown(false);
289         setNeedsLayout(true);
290     }
291     
292     void setPositioned(bool b=true)  { m_positioned = b;  }
293     void setRelPositioned(bool b=true) { m_relPositioned = b; }
294     void setFloating(bool b=true) { m_floating = b; }
295     void setInline(bool b=true) { m_inline = b; }
296     void setMouseInside(bool b=true) { m_mouseInside = b; }
297     void setShouldPaintBackgroundOrBorder(bool b=true) { m_paintBackground = b; }
298     void setRenderText() { m_isText = true; }
299     void setReplaced(bool b=true) { m_replaced = b; }
300     void setIsSelectionBorder(bool b=true) { m_isSelectionBorder = b; }
301
302 #ifdef INCREMENTAL_REPAINTING
303     void scheduleRelayout();
304 #else
305     void scheduleRelayout(RenderObject* clippedObj);
306 #endif
307     
308     virtual InlineBox* createInlineBox(bool makePlaceHolderBox, bool isRootLineBox);
309     
310     // for discussion of lineHeight see CSS2 spec
311     virtual short lineHeight( bool firstLine, bool isRootLineBox=false ) const;
312     // for the vertical-align property of inline elements
313     // the difference between this objects baseline position and the lines baseline position.
314     virtual short verticalPositionHint( bool firstLine ) const;
315     // the offset of baseline from the top of the object.
316     virtual short baselinePosition( bool firstLine, bool isRootLineBox=false ) const;
317
318     /*
319      * Paint the object and its children, clipped by (x|y|w|h).
320      * (tx|ty) is the calculated position of the parent
321      */
322     virtual void paint(QPainter *p, int x, int y, int w, int h, int tx, int ty, 
323                        PaintAction paintAction);
324
325     virtual void paintObject( QPainter */*p*/, int /*x*/, int /*y*/,
326                               int /*w*/, int /*h*/, int /*tx*/, int /*ty*/,
327                               PaintAction paintAction /*paintAction*/) {}
328     void paintBorder(QPainter *p, int _tx, int _ty, int w, int h, const RenderStyle* style, bool begin=true, bool end=true);
329     void paintOutline(QPainter *p, int _tx, int _ty, int w, int h, const RenderStyle* style);
330
331     // RenderBox implements this.
332     virtual void paintBoxDecorations(QPainter *p,int _x, int _y,
333                                      int _w, int _h, int _tx, int _ty) {};
334
335     virtual void paintBackgroundExtended(QPainter *p, const QColor &c, CachedImage *bg, int clipy, int cliph,
336                                          int _tx, int _ty, int w, int height,
337                                          int bleft, int bright) {};
338
339     /*
340      * This function calculates the minimum & maximum width that the object
341      * can be set to.
342      *
343      * when the Element calls setMinMaxKnown(true), calcMinMaxWidth() will
344      * be no longer called.
345      *
346      * when a element has a fixed size, m_minWidth and m_maxWidth should be
347      * set to the same value. This has the special meaning that m_width,
348      * contains the actual value.
349      *
350      * assumes calcMinMaxWidth has already been called for all children.
351      */
352     virtual void calcMinMaxWidth() { }
353
354     /*
355      * Does the min max width recalculations after changes.
356      */
357     void recalcMinMaxWidths();
358
359     /*
360      * Calculates the actual width of the object (only for non inline
361      * objects)
362      */
363     virtual void calcWidth() {}
364
365     /*
366      * This function should cause the Element to calculate its
367      * width and height and the layout of its content
368      *
369      * when the Element calls setNeedsLayout(false), layout() is no
370      * longer called during relayouts, as long as there is no
371      * style sheet change. When that occurs, m_needsLayout will be
372      * set to true and the Element receives layout() calls
373      * again.
374      */
375     virtual void layout() = 0;
376
377     /* This function performs a layout only if one is needed. */
378     void layoutIfNeeded() { if (needsLayout()) layout(); }
379
380     // used for element state updates that can not be fixed with a
381     // repaint and do not need a relayout
382     virtual void updateFromElement() {};
383
384     // The corresponding closing element has been parsed. ### remove me
385     virtual void close() { }
386
387     virtual int availableHeight() const { return 0; }
388
389     // Whether or not the element shrinks to its max width (rather than filling the width
390     // of a containing block).  HTML4 buttons, legends, and floating/compact elements do this.
391     bool sizesToMaxWidth() const;
392     
393     // does a query on the rendertree and finds the innernode
394     // and overURL for the given position
395     // if readonly == false, it will recalc hover styles accordingly
396     class NodeInfo
397     {
398         friend class RenderLayer;
399         friend class RenderImage;
400         friend class RenderText;
401         friend class RenderInline;
402         friend class RenderObject;
403         friend class RenderFrameSet;
404         friend class DOM::HTMLAreaElementImpl;
405     public:
406         NodeInfo(bool readonly, bool active)
407             : m_innerNode(0), m_innerNonSharedNode(0), m_innerURLElement(0), m_readonly(readonly), m_active(active)
408             { }
409
410         DOM::NodeImpl* innerNode() const { return m_innerNode; }
411         DOM::NodeImpl* innerNonSharedNode() const { return m_innerNonSharedNode; }
412         DOM::NodeImpl* URLElement() const { return m_innerURLElement; }
413         bool readonly() const { return m_readonly; }
414         bool active() const { return m_active; }
415
416     private:
417         void setInnerNode(DOM::NodeImpl* n) { m_innerNode = n; }
418         void setInnerNonSharedNode(DOM::NodeImpl* n) { m_innerNonSharedNode = n; }
419         void setURLElement(DOM::NodeImpl* n) { m_innerURLElement = n; }
420
421         DOM::NodeImpl* m_innerNode;
422         DOM::NodeImpl* m_innerNonSharedNode;
423         DOM::NodeImpl* m_innerURLElement;
424         bool m_readonly;
425         bool m_active;
426     };
427
428     FindSelectionResult checkSelectionPoint(int x, int y, int tx, int ty, DOM::NodeImpl*&, int& offset);
429     virtual FindSelectionResult checkSelectionPointIgnoringContinuations(int x, int y, int tx, int ty, DOM::NodeImpl*&, int& offset);
430     virtual bool nodeAtPoint(NodeInfo& info, int x, int y, int tx, int ty,
431                              HitTestAction hitTestAction = HitTestAll, bool inside=false);
432     
433     // set the style of the object.
434     virtual void setStyle(RenderStyle *style);
435
436     // returns the containing block level element for this element.
437     RenderBlock *containingBlock() const;
438
439     // return just the width of the containing block
440     virtual short containingBlockWidth() const;
441     // return just the height of the containing block
442     virtual int containingBlockHeight() const;
443
444     // size of the content area (box size minus padding/border)
445     virtual short contentWidth() const { return 0; }
446     virtual int contentHeight() const { return 0; }
447
448     // intrinsic extend of replaced elements. undefined otherwise
449     virtual short intrinsicWidth() const { return 0; }
450     virtual int intrinsicHeight() const { return 0; }
451
452     // relative to parent node
453     virtual void setPos( int /*xPos*/, int /*yPos*/ ) { }
454     virtual void setWidth( int /*width*/ ) { }
455     virtual void setHeight( int /*height*/ ) { }
456
457     virtual int xPos() const { return 0; }
458     virtual int yPos() const { return 0; }
459
460     // calculate client position of box
461     virtual bool absolutePosition(int &/*xPos*/, int &/*yPos*/, bool fixed = false);
462
463     // width and height are without margins but include paddings and borders
464     virtual short width() const { return 0; }
465     virtual int height() const { return 0; }
466
467     // The height of a block when you include normal flow overflow spillage out of the bottom
468     // of the block (e.g., a <div style="height:25px"> that has a 100px tall image inside
469     // it would have an overflow height of borderTop() + paddingTop() + 100px.
470     virtual int overflowHeight(bool includeInterior=true) const { return height(); }
471     virtual int overflowWidth(bool includeInterior=true) const { return width(); }
472     virtual void setOverflowHeight(int) {}
473     virtual void setOverflowWidth(int) {}
474
475     // IE extensions. Used to calculate offsetWidth/Height.  Overridden by inlines (render_flow) 
476     // to return the remaining width on a given line (and the height of a single line). -dwh
477     virtual short offsetWidth() const { return width(); }
478     virtual int offsetHeight() const { return height(); }
479     
480     // IE exxtensions.  Also supported by Gecko.  We override in render flow to get the
481     // left and top correct. -dwh
482     virtual int offsetLeft() const;
483     virtual int offsetTop() const;
484     virtual RenderObject* offsetParent() const;
485
486     // More IE extensions.  clientWidth and clientHeight represent the interior of an object
487     // excluding border and scrollbar.
488     short clientWidth() const;
489     short clientHeight() const;
490
491     // scrollWidth/scrollHeight will be the same as clientWidth/clientHeight unless the
492     // object has overflow:hidden/scroll/auto specified and also has overflow.
493     short scrollWidth() const;
494     short scrollHeight() const;
495
496     // The following seven functions are used to implement collapsing margins.
497     // All objects know their maximal positive and negative margins.  The
498     // formula for computing a collapsed margin is |maxPosMargin|-|maxNegmargin|.
499     // For a non-collapsing, e.g., a leaf element, this formula will simply return
500     // the margin of the element.  Blocks override the maxTopMargin and maxBottomMargin
501     // methods.
502     virtual bool isSelfCollapsingBlock() const { return false; }
503     virtual short collapsedMarginTop() const 
504         { return maxTopMargin(true)-maxTopMargin(false); }
505     virtual short collapsedMarginBottom() const 
506         { return maxBottomMargin(true)-maxBottomMargin(false); }
507     virtual bool isTopMarginQuirk() const { return false; }
508     virtual bool isBottomMarginQuirk() const { return false; }
509     virtual short maxTopMargin(bool positive) const {
510         if (positive)
511             if (marginTop() > 0)
512                 return marginTop();
513             else
514                 return 0;
515         else
516             if (marginTop() < 0)
517                 return 0 - marginTop();
518             else
519                 return 0;
520     }
521     virtual short maxBottomMargin(bool positive) const {
522         if (positive)
523             if (marginBottom() > 0)
524                 return marginBottom();
525             else
526                 return 0;
527         else
528             if (marginBottom() < 0)
529                 return 0 - marginBottom();
530             else
531                 return 0;
532     }
533
534     virtual short marginTop() const { return 0; }
535     virtual short marginBottom() const { return 0; }
536     virtual short marginLeft() const { return 0; }
537     virtual short marginRight() const { return 0; }
538
539     // Virtual since table cells override 
540     virtual int paddingTop() const;
541     virtual int paddingBottom() const;
542     virtual int paddingLeft() const;
543     virtual int paddingRight() const;
544     
545     virtual int borderTop() const { return style()->borderTopWidth(); }
546     virtual int borderBottom() const { return style()->borderBottomWidth(); }
547     virtual int borderLeft() const { return style()->borderLeftWidth(); }
548     virtual int borderRight() const { return style()->borderRightWidth(); }
549
550     virtual short minWidth() const { return 0; }
551     virtual short maxWidth() const { return 0; }
552
553     RenderStyle* style() const { return m_style; }
554     RenderStyle* style( bool firstLine ) const {
555         RenderStyle *s = m_style;
556         if( firstLine && hasFirstLine() ) {
557             RenderStyle *pseudoStyle  = style()->getPseudoStyle(RenderStyle::FIRST_LINE);
558             if ( pseudoStyle )
559                 s = pseudoStyle;
560         }
561         return s;
562     }
563
564     void getTextDecorationColors(int decorations, QColor& underline, QColor& overline,
565                                  QColor& linethrough, bool quirksMode=false);
566
567     enum BorderSide {
568         BSTop, BSBottom, BSLeft, BSRight
569     };
570     void drawBorder(QPainter *p, int x1, int y1, int x2, int y2, BorderSide s,
571                     QColor c, const QColor& textcolor, EBorderStyle style,
572                     int adjbw1, int adjbw2, bool invalidisInvert = false);
573
574     virtual void setTable(RenderTable*) {};
575
576     // Repaint the entire object.  Called when, e.g., the color of a border changes, or when a border
577     // style changes.
578     void repaint(bool immediate = false);
579
580     // Repaint a specific subrectangle within a given object.  The rect |r| is in the object's coordinate space.
581     void repaintRectangle(const QRect& r, bool immediate = false);
582
583 #ifdef INCREMENTAL_REPAINTING
584     // Repaint only if our old bounds and new bounds are different.
585     virtual void repaintAfterLayoutIfNeeded(const QRect& oldBounds, const QRect& oldFullBounds);
586
587     // Repaint only if the object moved.
588     virtual void repaintIfMoved(int oldX, int oldY);
589
590     // Called to repaint a block's positioned objects and floats.
591     virtual void repaintPositionedAndFloatingDescendants();
592 #endif
593
594     // Returns the rect that should be repainted whenever this object changes.  The rect is in the view's
595     // coordinate space.  This method deals with outlines and overflow.
596     virtual QRect getAbsoluteRepaintRect();
597
598 #ifdef INCREMENTAL_REPAINTING
599     virtual void getAbsoluteRepaintRectIncludingDescendants(QRect& bounds, QRect& boundsWithChildren);
600 #endif
601
602     // Given a rect in the object's coordinate space, this method converts the rectangle to the view's
603     // coordinate space.
604     virtual void computeAbsoluteRepaintRect(QRect& r, bool f=false);
605     
606     virtual unsigned int length() const { return 1; }
607
608     bool isFloatingOrPositioned() const { return (isFloating() || isPositioned()); };
609     virtual bool containsFloats() { return false; }
610     virtual bool containsFloat(RenderObject* o) { return false; }
611     virtual bool hasOverhangingFloats() { return false; }
612
613     // positioning of inline childs (bidi)
614     virtual void position(InlineBox*, int, int, bool) {}
615
616     enum SelectionState {
617         SelectionNone,
618         SelectionStart,
619         SelectionInside,
620         SelectionEnd,
621         SelectionBoth
622     };
623
624     virtual SelectionState selectionState() const { return SelectionNone;}
625     virtual void setSelectionState(SelectionState) {}
626
627     virtual void cursorPos(int /*offset*/, int &/*_x*/, int &/*_y*/, int &/*height*/);
628
629     virtual int lowestPosition(bool includeOverflowInterior=true) const {return 0;}
630
631     virtual int rightmostPosition(bool includeOverflowInterior=true) const {return 0;}
632
633     // recursively invalidate current layout
634     // unused: void invalidateLayout();
635
636     virtual void calcVerticalMargins() {}
637     void removeFromObjectLists();
638
639     virtual void detach();
640
641     const QFont &font(bool firstLine) const {
642         return style( firstLine )->font();
643     }
644
645     const QFontMetrics &fontMetrics(bool firstLine) const {
646         return style( firstLine )->fontMetrics();
647     }
648
649     // Virtual function helpers for CSS3 Flexible Box Layout
650     virtual bool isFlexibleBox() const { return false; }
651     virtual bool isFlexingChildren() const { return false; }
652     virtual bool isStretchingChildren() const { return false; }
653
654     // Convenience, to avoid repeating the code to dig down to get this.
655     QChar backslashAsCurrencySymbol() const;
656
657 protected:
658     virtual void selectionStartEnd(int& spos, int& epos);
659
660     virtual void printBoxDecorations(QPainter* /*p*/, int /*_x*/, int /*_y*/,
661                                      int /*_w*/, int /*_h*/, int /*_tx*/, int /*_ty*/) {}
662
663     virtual QRect viewRect() const;
664
665     void remove();
666
667     void invalidateVerticalPositions();
668     short getVerticalPosition( bool firstLine ) const;
669
670     virtual void removeLeftoverAnonymousBoxes();
671     
672     void arenaDelete(RenderArena *arena);
673
674 private:
675     RenderStyle* m_style;
676
677     DOM::NodeImpl* m_node;
678
679     RenderObject *m_parent;
680     RenderObject *m_previous;
681     RenderObject *m_next;
682
683     short m_verticalPosition;
684
685     bool m_needsLayout               : 1;
686     bool m_normalChildNeedsLayout    : 1;
687     bool m_posChildNeedsLayout       : 1;
688     bool m_minMaxKnown               : 1;
689     bool m_floating                  : 1;
690
691     bool m_positioned                : 1;
692     bool m_overhangingContents       : 1;
693     bool m_relPositioned             : 1;
694     bool m_paintBackground           : 1; // if the box has something to paint in the
695                                           // background painting phase (background, border, etc)
696
697     bool m_isAnonymous               : 1;
698     bool m_recalcMinMax              : 1;
699     bool m_isText                    : 1;
700     bool m_inline                    : 1;
701     bool m_replaced                  : 1;
702     bool m_mouseInside               : 1;
703     bool m_hasFirstLine              : 1;
704     bool m_isSelectionBorder         : 1;
705
706     void arenaDelete(RenderArena *arena, void *objectBase);
707
708     // note: do not add unnecessary bitflags, we have 32 bit already!
709     friend class RenderListItem;
710     friend class RenderContainer;
711     friend class RenderCanvas;
712 };
713
714
715 enum VerticalPositionHint {
716     PositionTop = -0x4000,
717     PositionBottom = 0x4000,
718     PositionUndefined = 0x3fff
719 };
720
721 }; //namespace
722 #endif