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