925e26327c90bfd6ee415dc288b96fc9a532dc6b
[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_docimpl.h"
38
39 class QPainter;
40 class QTextStream;
41 class CSSStyle;
42 class KHTMLView;
43 class RenderArena;
44
45 #ifndef NDEBUG
46 #define KHTMLAssert( x ) if( !(x) ) { \
47     const RenderObject *o = this; while( o->parent() ) o = o->parent(); \
48     o->printTree(); \
49     qDebug(" this object = %p", this ); \
50     assert( false ); \
51 }
52 #else
53 #define KHTMLAssert( x )
54 #endif
55
56 /*
57  *      The painting of a layer occurs in three distinct phases.  Each phase involves
58  *      a recursive descent into the layer's render objects. The first phase is the background phase.
59  *      The backgrounds and borders of all blocks are painted.  Inlines are not painted at all.
60  *      Floats must paint above block backgrounds but entirely below inline content that can overlap them.
61  *      In the foreground phase, all inlines are fully painted.  Inline replaced elements will get all
62  *      three phases invoked on them during this phase.
63  */
64
65 typedef enum {
66     PaintActionElementBackground = 0,
67     PaintActionChildBackground,
68     PaintActionChildBackgrounds,
69     PaintActionFloat,
70     PaintActionForeground,
71     PaintActionOutline,
72     PaintActionSelection,
73     PaintActionCollapsedTableBorders
74 } PaintAction;
75
76 typedef enum {
77     HitTestAll = 0,
78     HitTestSelfOnly = 1,
79     HitTestChildrenOnly = 2
80 } HitTestAction;
81
82 namespace DOM {
83     class HTMLAreaElementImpl;
84     class DOMString;
85     class DocumentImpl;
86     class ElementImpl;
87     class EventImpl;
88     class Position;
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     class CollapsedBorderValue;
104
105 /**
106  * Base Class for all rendering tree objects.
107  */
108 class RenderObject : public CachedObjectClient
109 {
110 public:
111     // Anonymous objects should pass the document as their node, and they will then automatically be
112     // marked as anonymous in the constructor.
113     RenderObject(DOM::NodeImpl* node);
114     virtual ~RenderObject();
115
116     RenderObject *parent() const { return m_parent; }
117     bool hasAncestor(const RenderObject *obj) const;
118
119     RenderObject *previousSibling() const { return m_previous; }
120     RenderObject *nextSibling() const { return m_next; }
121
122     virtual RenderObject *firstChild() const { return 0; }
123     virtual RenderObject *lastChild() const { return 0; }
124
125     RenderObject *nextRenderer() const; 
126     RenderObject *previousRenderer() const; 
127
128     RenderObject *nextEditable() const; 
129     RenderObject *previousEditable() const; 
130
131     RenderObject *firstLeafChild() const;
132     RenderObject *lastLeafChild() const;
133     
134     virtual RenderLayer* layer() const { return 0; }
135     RenderLayer* enclosingLayer();
136     void addLayers(RenderLayer* parentLayer, RenderObject* newObject);
137     void removeLayers(RenderLayer* parentLayer);
138     void moveLayers(RenderLayer* oldParent, RenderLayer* newParent);
139     RenderLayer* findNextLayer(RenderLayer* parentLayer, RenderObject* startPoint,
140                                bool checkParent=true);
141     virtual void positionChildLayers() { }
142     virtual bool requiresLayer();
143     
144     virtual QRect getOverflowClipRect(int tx, int ty) { return QRect(0,0,0,0); }
145     virtual QRect getClipRect(int tx, int ty) { return QRect(0,0,0,0); }
146     bool hasClip() { return isPositioned() &&  style()->hasClip(); }
147     
148     virtual int getBaselineOfFirstLineBox() const { return -1; } 
149     
150     // Obtains the nearest enclosing block (including this block) that contributes a first-line style to our inline
151     // children.
152     virtual RenderBlock* firstLineBlock() const;
153     virtual void updateFirstLetter();
154     
155     // Called when an object that was floating or positioned becomes a normal flow object
156     // again.  We have to make sure the render tree updates as needed to accommodate the new
157     // normal flow object.
158     void handleDynamicFloatPositionChange();
159
160     // This function is a convenience helper for creating an anonymous block that inherits its
161     // style from this RenderObject.
162     RenderBlock* createAnonymousBlock();
163     
164     // Whether or not a positioned element requires normal flow x/y to be computed
165     // to determine its position.
166     bool hasStaticX() const;
167     bool hasStaticY() const;
168     virtual void setStaticX(int staticX) {};
169     virtual void setStaticY(int staticY) {};
170     
171     // RenderObject tree manipulation
172     //////////////////////////////////////////
173     virtual bool canHaveChildren() const;
174     virtual void addChild(RenderObject *newChild, RenderObject *beforeChild = 0);
175     virtual void removeChild(RenderObject *oldChild);
176
177     // raw tree manipulation
178     virtual RenderObject* removeChildNode(RenderObject* child);
179     virtual void appendChildNode(RenderObject* child);
180     virtual void insertChildNode(RenderObject* child, RenderObject* before);
181     //////////////////////////////////////////
182
183 private:
184     //////////////////////////////////////////
185     // Helper functions. Dangerous to use!
186     void setPreviousSibling(RenderObject *previous) { m_previous = previous; }
187     void setNextSibling(RenderObject *next) { m_next = next; }
188     void setParent(RenderObject *parent) { m_parent = parent; }
189     //////////////////////////////////////////
190     
191     QRect absoluteBoundingBoxRect();
192     void addAbsoluteRectForLayer(QRect& result);
193
194 public:
195     virtual const char *renderName() const { return "RenderObject"; }
196 #ifndef NDEBUG
197     QString information() const;
198     virtual void printTree(int indent=0) const;
199     virtual void dump(QTextStream *stream, QString ind = "") const;
200 #endif
201
202     static RenderObject *createObject(DOM::NodeImpl* node, RenderStyle* style);
203
204     // Overloaded new operator.  Derived classes must override operator new
205     // in order to allocate out of the RenderArena.
206     void* operator new(size_t sz, RenderArena* renderArena) throw();    
207
208     // Overridden to prevent the normal delete from being called.
209     void operator delete(void* ptr, size_t sz);
210         
211 private:
212     // The normal operator new is disallowed on all render objects.
213     void* operator new(size_t sz) throw();
214     
215 public:
216     RenderArena* renderArena() const;
217     
218     // some helper functions...
219     virtual bool isRenderBlock() const { return false; }
220     virtual bool isRenderInline() const { return false; }
221     virtual bool isInlineFlow() const { return false; }
222     virtual bool isBlockFlow() const { return false; }
223     virtual bool isInlineBlockOrInlineTable() const { return false; }
224     virtual bool childrenInline() const { return false; }
225     virtual void setChildrenInline(bool b) { };
226
227     virtual RenderFlow* continuation() const;
228     virtual bool isInlineContinuation() const;
229     
230     virtual bool isListItem() const { return false; }
231     virtual bool isListMarker() const { return false; }
232     virtual bool isCanvas() const { return false; }
233     bool isRoot() const;
234     bool isBody() const;
235     bool isHR() const;
236     virtual bool isBR() const { return false; }
237     virtual bool isTableCell() const { return false; }
238     virtual bool isTableRow() const { return false; }
239     virtual bool isTableSection() const { return false; }
240     virtual bool isTableCol() const { return false; }
241     virtual bool isTable() const { return false; }
242     virtual bool isWidget() const { return false; }
243     virtual bool isFormElement() const { return false; }
244     virtual bool isImage() const { return false; }
245     virtual bool isTextArea() const { return false; }
246     virtual bool isFrameSet() const { return false; }
247     virtual bool isApplet() const { return false; }
248     
249     virtual bool isEditable() const;
250
251     bool isHTMLMarquee() const;
252     
253     bool isAnonymous() const { return m_isAnonymous; }
254     void setIsAnonymous(bool b) { m_isAnonymous = b; }
255     bool isAnonymousBlock() const { return m_isAnonymous && 
256                                            style()->display() == BLOCK && 
257                                            style()->styleType() == RenderStyle::NOPSEUDO &&
258                                            !isListMarker(); }
259     
260     bool isFloating() const { return m_floating; }
261     bool isPositioned() const { return m_positioned; } // absolute or fixed positioning
262     bool isRelPositioned() const { return m_relPositioned; } // relative positioning
263     bool isText() const  { return m_isText; }
264     bool isInline() const { return m_inline; }  // inline object
265     bool isCompact() const { return style()->display() == COMPACT; } // compact object
266     bool isRunIn() const { return style()->display() == RUN_IN; } // run-in object
267     bool mouseInside() const;
268     bool isDragging() const;
269     bool isReplaced() const { return m_replaced; } // a "replaced" element (see CSS)
270     bool shouldPaintBackgroundOrBorder() const { return m_paintBackground; }
271     bool needsLayout() const   { return m_needsLayout || m_normalChildNeedsLayout || m_posChildNeedsLayout; }
272     bool selfNeedsLayout() const { return m_needsLayout; }
273     bool posChildNeedsLayout() const { return m_posChildNeedsLayout; }
274     bool normalChildNeedsLayout() const { return m_normalChildNeedsLayout; }
275     bool minMaxKnown() const{ return m_minMaxKnown; }
276     bool isSelectionBorder() const { return m_isSelectionBorder; }
277     bool recalcMinMax() const { return m_recalcMinMax; }
278
279     bool hasOverflowClip() const { return m_hasOverflowClip; }
280     bool hasAutoScrollbars() const { return hasOverflowClip() && 
281         (style()->overflow() == OAUTO || style()->overflow() == OOVERLAY); }
282     bool scrollsOverflow() const { return hasOverflowClip() &&
283         (style()->overflow() == OSCROLL || hasAutoScrollbars()); }
284     bool includeScrollbarSize() const { return hasOverflowClip() &&
285         (style()->overflow() == OSCROLL || style()->overflow() == OAUTO); }
286
287     RenderStyle* getPseudoStyle(RenderStyle::PseudoId pseudo, RenderStyle* parentStyle = 0) const;
288     
289     void updateDragState(bool dragOn);
290
291     RenderCanvas* canvas() const;
292
293     // don't even think about making this method virtual!
294     DOM::NodeImpl* element() const { return m_isAnonymous ? 0 : m_node; }
295     DOM::DocumentImpl* document() const { return m_node->getDocument(); }
296     void setNode(DOM::NodeImpl* node) { m_node = node; }
297     DOM::NodeImpl* node() const { return m_node; }
298     
299    /**
300      * returns the object containing this one. can be different from parent for
301      * positioned elements
302      */
303     RenderObject *container() const;
304
305     virtual void markAllDescendantsWithFloatsForLayout(RenderObject* floatToRemove = 0);
306     void markContainingBlocksForLayout();
307     void setNeedsLayout(bool b, bool markParents = true);
308     void setChildNeedsLayout(bool b, bool markParents = true);
309     void setMinMaxKnown(bool b=true) {
310         m_minMaxKnown = b;
311         if ( !b ) {
312             RenderObject *o = this;
313             RenderObject *root = this;
314             while( o ) { // ### && !o->m_recalcMinMax ) {
315                 o->m_recalcMinMax = true;
316                 root = o;
317                 o = o->m_parent;
318             }
319         }
320     }
321
322     void setNeedsLayoutAndMinMaxRecalc() {
323         setMinMaxKnown(false);
324         setNeedsLayout(true);
325     }
326     
327     void setPositioned(bool b=true)  { m_positioned = b;  }
328     void setRelPositioned(bool b=true) { m_relPositioned = b; }
329     void setFloating(bool b=true) { m_floating = b; }
330     void setInline(bool b=true) { m_inline = b; }
331     void setMouseInside(bool b=true) { m_mouseInside = b; }
332     void setShouldPaintBackgroundOrBorder(bool b=true) { m_paintBackground = b; }
333     void setRenderText() { m_isText = true; }
334     void setReplaced(bool b=true) { m_replaced = b; }
335     void setIsSelectionBorder(bool b=true) { m_isSelectionBorder = b; }
336     void setHasOverflowClip(bool b = true) { m_hasOverflowClip = b; }
337
338     void scheduleRelayout();
339     
340     virtual InlineBox* createInlineBox(bool makePlaceHolderBox, bool isRootLineBox, bool isOnlyRun=false);
341     virtual void dirtyLineBoxes(bool fullLayout, bool isRootLineBox=false);
342     
343     // For inline replaced elements, this function returns the inline box that owns us.  Enables
344     // the replaced RenderObject to quickly determine what line it is contained on and to easily
345     // iterate over structures on the line.
346     virtual InlineBox* inlineBoxWrapper() const;
347     virtual void setInlineBoxWrapper(InlineBox* b);
348     void deleteLineBoxWrapper();
349
350     virtual InlineBox *inlineBox(long offset=0);
351     
352     // for discussion of lineHeight see CSS2 spec
353     virtual short lineHeight( bool firstLine, bool isRootLineBox=false ) const;
354     // for the vertical-align property of inline elements
355     // the difference between this objects baseline position and the lines baseline position.
356     virtual short verticalPositionHint( bool firstLine ) const;
357     // the offset of baseline from the top of the object.
358     virtual short baselinePosition( bool firstLine, bool isRootLineBox=false ) const;
359
360     /*
361      * Paint the object and its children, clipped by (x|y|w|h).
362      * (tx|ty) is the calculated position of the parent
363      */
364     struct PaintInfo {
365         PaintInfo(QPainter* _p, const QRect& _r, PaintAction _phase, RenderObject *_paintingRoot)
366         : p(_p), r(_r), phase(_phase), paintingRoot(_paintingRoot) {}
367         QPainter* p;
368         QRect     r;
369         PaintAction phase;
370         RenderObject *paintingRoot;      // used to draw just one element and its visual kids
371     };
372     virtual void paint(PaintInfo& i, int tx, int ty);
373     void paintBorder(QPainter *p, int _tx, int _ty, int w, int h, const RenderStyle* style, bool begin=true, bool end=true);
374     void paintOutline(QPainter *p, int _tx, int _ty, int w, int h, const RenderStyle* style);
375
376     // RenderBox implements this.
377     virtual void paintBoxDecorations(PaintInfo& i, int _tx, int _ty) {};
378
379     virtual void paintBackgroundExtended(QPainter *p, const QColor &c, CachedImage *bg, int clipy, int cliph,
380                                          int _tx, int _ty, int w, int height,
381                                          int bleft, int bright) {};
382
383     /*
384      * This function calculates the minimum & maximum width that the object
385      * can be set to.
386      *
387      * when the Element calls setMinMaxKnown(true), calcMinMaxWidth() will
388      * be no longer called.
389      *
390      * when a element has a fixed size, m_minWidth and m_maxWidth should be
391      * set to the same value. This has the special meaning that m_width,
392      * contains the actual value.
393      *
394      * assumes calcMinMaxWidth has already been called for all children.
395      */
396     virtual void calcMinMaxWidth() { }
397
398     /*
399      * Does the min max width recalculations after changes.
400      */
401     void recalcMinMaxWidths();
402
403     /*
404      * Calculates the actual width of the object (only for non inline
405      * objects)
406      */
407     virtual void calcWidth() {}
408
409     /*
410      * This function should cause the Element to calculate its
411      * width and height and the layout of its content
412      *
413      * when the Element calls setNeedsLayout(false), layout() is no
414      * longer called during relayouts, as long as there is no
415      * style sheet change. When that occurs, m_needsLayout will be
416      * set to true and the Element receives layout() calls
417      * again.
418      */
419     virtual void layout() = 0;
420
421     /* This function performs a layout only if one is needed. */
422     void layoutIfNeeded() { if (needsLayout()) layout(); }
423
424     // used for element state updates that can not be fixed with a
425     // repaint and do not need a relayout
426     virtual void updateFromElement() {};
427
428     // The corresponding closing element has been parsed. ### remove me
429     virtual void close() { }
430
431     virtual int availableHeight() const { return 0; }
432
433     // Whether or not the element shrinks to its max width (rather than filling the width
434     // of a containing block).  HTML4 buttons, legends, and floating/compact elements do this.
435     bool sizesToMaxWidth() const;
436
437 #if APPLE_CHANGES
438     // Called recursively to update the absolute positions of all widgets.
439     virtual void updateWidgetPositions();
440 #endif
441
442     // does a query on the rendertree and finds the innernode
443     // and overURL for the given position
444     // if readonly == false, it will recalc hover styles accordingly
445     class NodeInfo
446     {
447         friend class RenderLayer;
448         friend class RenderImage;
449         friend class RenderText;
450         friend class RenderInline;
451         friend class RenderObject;
452         friend class RenderFrameSet;
453         friend class DOM::HTMLAreaElementImpl;
454     public:
455         NodeInfo(bool readonly, bool active)
456             : m_innerNode(0), m_innerNonSharedNode(0), m_innerURLElement(0), m_readonly(readonly), m_active(active)
457             { }
458
459         DOM::NodeImpl* innerNode() const { return m_innerNode; }
460         DOM::NodeImpl* innerNonSharedNode() const { return m_innerNonSharedNode; }
461         DOM::NodeImpl* URLElement() const { return m_innerURLElement; }
462         bool readonly() const { return m_readonly; }
463         bool active() const { return m_active; }
464
465     private:
466         void setInnerNode(DOM::NodeImpl* n) { m_innerNode = n; }
467         void setInnerNonSharedNode(DOM::NodeImpl* n) { m_innerNonSharedNode = n; }
468         void setURLElement(DOM::NodeImpl* n) { m_innerURLElement = n; }
469
470         DOM::NodeImpl* m_innerNode;
471         DOM::NodeImpl* m_innerNonSharedNode;
472         DOM::NodeImpl* m_innerURLElement;
473         bool m_readonly;
474         bool m_active;
475     };
476
477     // Used to signal a specific subrect within an object that must be repainted after
478     // layout is complete.
479     struct RepaintInfo {
480         RenderObject* m_object;
481         QRect m_repaintRect;
482     
483         RepaintInfo(RenderObject* o, const QRect& r) :m_object(o), m_repaintRect(r) {}
484     };
485     
486     virtual bool nodeAtPoint(NodeInfo& info, int x, int y, int tx, int ty,
487                              HitTestAction hitTestAction = HitTestAll, bool inside=false);
488     
489     virtual DOM::Position positionForCoordinates(int x, int y);
490     
491     virtual void dirtyLinesFromChangedChild(RenderObject* child);
492     
493     // set the style of the object.
494     virtual void setStyle(RenderStyle *style);
495
496     // returns the containing block level element for this element.
497     RenderBlock *containingBlock() const;
498
499     // return just the width of the containing block
500     virtual int containingBlockWidth() const;
501     // return just the height of the containing block
502     virtual int containingBlockHeight() const;
503
504     // size of the content area (box size minus padding/border)
505     virtual int contentWidth() const { return 0; }
506     virtual int contentHeight() const { return 0; }
507
508     // intrinsic extend of replaced elements. undefined otherwise
509     virtual int intrinsicWidth() const { return 0; }
510     virtual int intrinsicHeight() const { return 0; }
511
512     // used by flexible boxes to impose a flexed width/height override
513     virtual int overrideSize() const { return 0; }
514     virtual int overrideWidth() const { return 0; }
515     virtual int overrideHeight() const { return 0; }
516     virtual void setOverrideSize(int s) {}
517
518     // relative to parent node
519     virtual void setPos( int /*xPos*/, int /*yPos*/ ) { }
520     virtual void setWidth( int /*width*/ ) { }
521     virtual void setHeight( int /*height*/ ) { }
522
523     virtual int xPos() const { return 0; }
524     virtual int yPos() const { return 0; }
525
526     // calculate client position of box
527     virtual bool absolutePosition(int &/*xPos*/, int &/*yPos*/, bool fixed = false);
528
529     // width and height are without margins but include paddings and borders
530     virtual int width() const { return 0; }
531     virtual int height() const { return 0; }
532
533     // The height of a block when you include normal flow overflow spillage out of the bottom
534     // of the block (e.g., a <div style="height:25px"> that has a 100px tall image inside
535     // it would have an overflow height of borderTop() + paddingTop() + 100px.
536     virtual int overflowHeight(bool includeInterior=true) const { return height(); }
537     virtual int overflowWidth(bool includeInterior=true) const { return width(); }
538     virtual void setOverflowHeight(int) {}
539     virtual void setOverflowWidth(int) {}
540
541     // IE extensions. Used to calculate offsetWidth/Height.  Overridden by inlines (render_flow) 
542     // to return the remaining width on a given line (and the height of a single line). -dwh
543     virtual int offsetWidth() const { return width(); }
544     virtual int offsetHeight() const { return height(); }
545     
546     // IE exxtensions.  Also supported by Gecko.  We override in render flow to get the
547     // left and top correct. -dwh
548     virtual int offsetLeft() const;
549     virtual int offsetTop() const;
550     virtual RenderObject* offsetParent() const;
551
552     // More IE extensions.  clientWidth and clientHeight represent the interior of an object
553     // excluding border and scrollbar.
554     int clientWidth() const;
555     int clientHeight() const;
556
557     // scrollWidth/scrollHeight will be the same as clientWidth/clientHeight unless the
558     // object has overflow:hidden/scroll/auto specified and also has overflow.
559     int scrollWidth() const;
560     int scrollHeight() const;
561
562     // The following seven functions are used to implement collapsing margins.
563     // All objects know their maximal positive and negative margins.  The
564     // formula for computing a collapsed margin is |maxPosMargin|-|maxNegmargin|.
565     // For a non-collapsing, e.g., a leaf element, this formula will simply return
566     // the margin of the element.  Blocks override the maxTopMargin and maxBottomMargin
567     // methods.
568     virtual bool isSelfCollapsingBlock() const { return false; }
569     virtual short collapsedMarginTop() const 
570         { return maxTopMargin(true)-maxTopMargin(false); }
571     virtual short collapsedMarginBottom() const 
572         { return maxBottomMargin(true)-maxBottomMargin(false); }
573     virtual bool isTopMarginQuirk() const { return false; }
574     virtual bool isBottomMarginQuirk() const { return false; }
575     virtual short maxTopMargin(bool positive) const {
576         if (positive)
577             if (marginTop() > 0)
578                 return marginTop();
579             else
580                 return 0;
581         else
582             if (marginTop() < 0)
583                 return 0 - marginTop();
584             else
585                 return 0;
586     }
587     virtual short maxBottomMargin(bool positive) const {
588         if (positive)
589             if (marginBottom() > 0)
590                 return marginBottom();
591             else
592                 return 0;
593         else
594             if (marginBottom() < 0)
595                 return 0 - marginBottom();
596             else
597                 return 0;
598     }
599
600     virtual short marginTop() const { return 0; }
601     virtual short marginBottom() const { return 0; }
602     virtual short marginLeft() const { return 0; }
603     virtual short marginRight() const { return 0; }
604
605     // Virtual since table cells override 
606     virtual int paddingTop() const;
607     virtual int paddingBottom() const;
608     virtual int paddingLeft() const;
609     virtual int paddingRight() const;
610     
611     virtual int borderTop() const { return style()->borderTopWidth(); }
612     virtual int borderBottom() const { return style()->borderBottomWidth(); }
613     virtual int borderLeft() const { return style()->borderLeftWidth(); }
614     virtual int borderRight() const { return style()->borderRightWidth(); }
615
616     virtual void absoluteRects(QValueList<QRect>& rects, int _tx, int _ty);
617
618     // the rect that will be painted if this object is passed as the paintingRoot
619     QRect paintingRootRect(QRect& topLevelRect);
620
621 #if APPLE_CHANGES
622     virtual void addFocusRingRects(QPainter *painter, int _tx, int _ty);
623 #endif
624
625     virtual int minWidth() const { return 0; }
626     virtual int maxWidth() const { return 0; }
627
628     RenderStyle* style() const { return m_style; }
629     RenderStyle* style( bool firstLine ) const;
630
631     void getTextDecorationColors(int decorations, QColor& underline, QColor& overline,
632                                  QColor& linethrough, bool quirksMode=false);
633
634     enum BorderSide {
635         BSTop, BSBottom, BSLeft, BSRight
636     };
637     void drawBorder(QPainter *p, int x1, int y1, int x2, int y2, BorderSide s,
638                     QColor c, const QColor& textcolor, EBorderStyle style,
639                     int adjbw1, int adjbw2, bool invalidisInvert = false);
640
641     virtual void setTable(RenderTable*) {};
642
643     // Used by collapsed border tables.
644     virtual void collectBorders(QValueList<CollapsedBorderValue>& borderStyles);
645
646     // Repaint the entire object.  Called when, e.g., the color of a border changes, or when a border
647     // style changes.
648     void repaint(bool immediate = false);
649
650     // Repaint a specific subrectangle within a given object.  The rect |r| is in the object's coordinate space.
651     void repaintRectangle(const QRect& r, bool immediate = false);
652     
653     // Repaint only if our old bounds and new bounds are different.
654     bool repaintAfterLayoutIfNeeded(const QRect& oldBounds, const QRect& oldFullBounds);
655
656     // Repaint only if the object moved.
657     virtual void repaintDuringLayoutIfMoved(int oldX, int oldY);
658
659     // Called to repaint a block's floats.
660     virtual void repaintFloatingDescendants();
661
662     // Called before layout to repaint all dirty children (with selfNeedsLayout() set).
663     virtual void repaintObjectsBeforeLayout();
664
665     bool checkForRepaintDuringLayout() const;
666
667     // Returns the rect that should be repainted whenever this object changes.  The rect is in the view's
668     // coordinate space.  This method deals with outlines and overflow.
669     virtual QRect getAbsoluteRepaintRect();
670
671     QRect getAbsoluteRepaintRectWithOutline(int ow);
672
673     virtual void getAbsoluteRepaintRectIncludingFloats(QRect& bounds, QRect& boundsWithChildren);
674
675     // Given a rect in the object's coordinate space, this method converts the rectangle to the view's
676     // coordinate space.
677     virtual void computeAbsoluteRepaintRect(QRect& r, bool f=false);
678     
679     virtual unsigned int length() const { return 1; }
680
681     bool isFloatingOrPositioned() const { return (isFloating() || isPositioned()); };
682     virtual bool containsFloats() { return false; }
683     virtual bool containsFloat(RenderObject* o) { return false; }
684     virtual bool hasOverhangingFloats() { return false; }
685
686     bool avoidsFloats() const;
687     bool usesLineWidth() const;
688
689     // positioning of inline children (bidi)
690     virtual void position(InlineBox*, int, int, bool) {}
691
692     // Applied as a "slop" to dirty rect checks during the outline painting phase's dirty-rect checks.
693     int maximalOutlineSize(PaintAction p) const;
694
695     enum SelectionState {
696         SelectionNone,
697         SelectionStart,
698         SelectionInside,
699         SelectionEnd,
700         SelectionBoth
701     };
702
703     virtual SelectionState selectionState() const { return SelectionNone;}
704     virtual void setSelectionState(SelectionState) {}
705     bool shouldSelect() const;
706
707     DOM::NodeImpl* draggableNode(bool dhtmlOK, bool uaOK, int x, int y, bool& dhtmlWillDrag) const;
708
709     /**
710      * Returns the content coordinates of the caret within this render object.
711      * @param offset zero-based offset determining position within the render object.
712      * @param override @p true if input overrides existing characters,
713      * @p false if it inserts them. The width of the caret depends on this one.
714      * @param _x returns the left coordinate
715      * @param _y returns the top coordinate
716      * @param width returns the caret's width
717      * @param height returns the caret's height
718      */
719     virtual void caretPos(int offset, bool override, int &_x, int &_y, int &width, int &height);
720
721     virtual int lowestPosition(bool includeOverflowInterior=true, bool includeSelf=true) const { return 0; }
722     virtual int rightmostPosition(bool includeOverflowInterior=true, bool includeSelf=true) const { return 0; }
723     virtual int leftmostPosition(bool includeOverflowInterior=true, bool includeSelf=true) const { return 0; }
724     
725     virtual void calcVerticalMargins() {}
726     void removeFromObjectLists();
727
728     // When performing a global document tear-down, the renderer of the document is cleared.  We use this
729     // as a hook to detect the case of document destruction and don't waste time doing unnecessary work.
730     bool documentBeingDestroyed() const { return !document()->renderer(); }
731
732     virtual void detach();
733
734     const QFont &font(bool firstLine) const {
735         return style( firstLine )->font();
736     }
737
738     const QFontMetrics &fontMetrics(bool firstLine) const {
739         return style( firstLine )->fontMetrics();
740     }
741
742     // Virtual function helpers for CSS3 Flexible Box Layout
743     virtual bool isFlexibleBox() const { return false; }
744     virtual bool isFlexingChildren() const { return false; }
745     virtual bool isStretchingChildren() const { return false; }
746
747     // Convenience, to avoid repeating the code to dig down to get this.
748     QChar backslashAsCurrencySymbol() const;
749
750     virtual long caretMinOffset() const;
751     virtual long caretMaxOffset() const;
752     virtual unsigned long caretMaxRenderedOffset() const;
753
754     virtual void setPixmap(const QPixmap&, const QRect&, CachedImage *);
755
756 protected:
757     virtual void selectionStartEnd(int& spos, int& epos);
758
759     virtual void printBoxDecorations(QPainter* /*p*/, int /*_x*/, int /*_y*/,
760                                      int /*_w*/, int /*_h*/, int /*_tx*/, int /*_ty*/) {}
761
762     virtual QRect viewRect() const;
763
764     void remove();
765
766     void invalidateVerticalPositions();
767     short getVerticalPosition( bool firstLine ) const;
768
769     virtual void removeLeftoverAnonymousBoxes();
770     
771     void arenaDelete(RenderArena *arena);
772
773     RenderObject *paintingRootForChildren(PaintInfo &i) const {
774         // if we're the painting root, kids draw normally, and see root of 0
775         return (!i.paintingRoot || i.paintingRoot == this) ? 0 : i.paintingRoot;
776     }
777     bool shouldPaintWithinRoot(PaintInfo &i) const {
778         return !i.paintingRoot || i.paintingRoot == this;
779     }
780
781 private:
782     RenderStyle* m_style;
783
784     DOM::NodeImpl* m_node;
785
786     RenderObject *m_parent;
787     RenderObject *m_previous;
788     RenderObject *m_next;
789
790     mutable short m_verticalPosition;
791
792     bool m_needsLayout               : 1;
793     bool m_normalChildNeedsLayout    : 1;
794     bool m_posChildNeedsLayout       : 1;
795     bool m_minMaxKnown               : 1;
796     bool m_floating                  : 1;
797
798     bool m_positioned                : 1;
799     bool m_relPositioned             : 1;
800     bool m_paintBackground           : 1; // if the box has something to paint in the
801                                           // background painting phase (background, border, etc)
802
803     bool m_isAnonymous               : 1;
804     bool m_recalcMinMax              : 1;
805     bool m_isText                    : 1;
806     bool m_inline                    : 1;
807     bool m_replaced                  : 1;
808     bool m_mouseInside               : 1;
809     bool m_isDragging                : 1;
810     bool m_isSelectionBorder         : 1;
811
812     bool m_hasOverflowClip           : 1;
813
814     void arenaDelete(RenderArena *arena, void *objectBase);
815
816     // note: do not add unnecessary bitflags, we have 32 bit already!
817     friend class RenderListItem;
818     friend class RenderContainer;
819     friend class RenderCanvas;
820 };
821
822
823 enum VerticalPositionHint {
824     PositionTop = -0x4000,
825     PositionBottom = 0x4000,
826     PositionUndefined = 0x3fff
827 };
828
829 }; //namespace
830 #endif