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