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