khtml Library API Documentation

render_object.h

00001 /*
00002  * This file is part of the html renderer for KDE.
00003  *
00004  * Copyright (C) 2000 Lars Knoll (knoll@kde.org)
00005  *           (C) 2000 Antti Koivisto (koivisto@kde.org)
00006  *           (C) 2000 Dirk Mueller (mueller@kde.org)
00007  *
00008  * This library is free software; you can redistribute it and/or
00009  * modify it under the terms of the GNU Library General Public
00010  * License as published by the Free Software Foundation; either
00011  * version 2 of the License, or (at your option) any later version.
00012  *
00013  * This library is distributed in the hope that it will be useful,
00014  * but WITHOUT ANY WARRANTY; without even the implied warranty of
00015  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00016  * Library General Public License for more details.
00017  *
00018  * You should have received a copy of the GNU Library General Public License
00019  * along with this library; see the file COPYING.LIB.  If not, write to
00020  * the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
00021  * Boston, MA 02111-1307, USA.
00022  *
00023  * $Id: render_object.h,v 1.137.2.2 2003/01/13 22:13:19 mueller Exp $
00024  */
00025 #ifndef render_object_h
00026 #define render_object_h
00027 
00028 #include <qcolor.h>
00029 #include <qrect.h>
00030 #include <assert.h>
00031 
00032 #include "misc/khtmllayout.h"
00033 #include "misc/loader_client.h"
00034 #include "misc/helper.h"
00035 #include "rendering/render_style.h"
00036 
00037 class QPainter;
00038 class QTextStream;
00039 class CSSStyle;
00040 class KHTMLView;
00041 
00042 #ifndef NDEBUG
00043 #define KHTMLAssert( x ) if( !(x) ) { \
00044     const RenderObject *o = this; while( o->parent() ) o = o->parent(); \
00045     o->printTree(); \
00046     qDebug(" this object = %p", (void*) this ); \
00047     assert( false ); \
00048 }
00049 #else
00050 #define KHTMLAssert( x )
00051 #endif
00052 
00053 namespace DOM {
00054     class HTMLAreaElementImpl;
00055     class DOMString;
00056     class NodeImpl;
00057     class ElementImpl;
00058     class EventImpl;
00059 };
00060 
00061 namespace khtml {
00062     class RenderFlow;
00063     class RenderStyle;
00064     class RenderTable;
00065     class CachedObject;
00066     class RenderRoot;
00067     class RenderText;
00068     class RenderFrameSet;
00069 
00073 class RenderObject : public CachedObjectClient
00074 {
00075 public:
00076 
00077     RenderObject(DOM::NodeImpl* node);
00078     virtual ~RenderObject();
00079 
00080     RenderObject *parent() const { return m_parent; }
00081 
00082     RenderObject *previousSibling() const { return m_previous; }
00083     RenderObject *nextSibling() const { return m_next; }
00084 
00085     virtual RenderObject *firstChild() const { return 0; }
00086     virtual RenderObject *lastChild() const { return 0; }
00087 
00088     // Linear tree traversal
00089     RenderObject *objectBelow() const;
00090     RenderObject *objectAbove() const;
00091 
00092     // RenderObject tree manipulation
00094     virtual void addChild(RenderObject *newChild, RenderObject *beforeChild = 0);
00095     void removeChild(RenderObject *oldChild);
00096 
00097     // raw tree manipulation
00098     virtual RenderObject* removeChildNode(RenderObject* child);
00099     virtual void appendChildNode(RenderObject* child);
00100     virtual void insertChildNode(RenderObject* child, RenderObject* before);
00102 
00103 private:
00105     // Helper functions. Dangerous to use!
00106     void setPreviousSibling(RenderObject *previous) { m_previous = previous; }
00107     void setNextSibling(RenderObject *next) { m_next = next; }
00108     void setParent(RenderObject *parent) { m_parent = parent; }
00110 
00111 public:
00112     virtual const char *renderName() const { return "RenderObject"; }
00113 #ifndef NDEBUG
00114     QString information() const;
00115     virtual void printTree(int indent=0) const;
00116     virtual void dump(QTextStream *stream, QString ind = "") const;
00117 #endif
00118 
00119     static RenderObject *createObject(DOM::NodeImpl* node, RenderStyle* style);
00120 
00121     // some helper functions...
00122     virtual bool childrenInline() const { return false; }
00123     virtual bool isRendered() const { return false; }
00124     virtual bool isFlow() const { return false; }
00125 
00126     virtual bool isListItem() const { return false; }
00127     virtual bool isRoot() const { return false; }
00128     virtual bool isBR() const { return false; }
00129     virtual bool isHtml() const { return false; }
00130     virtual bool isTableCell() const { return false; }
00131     virtual bool isTableRow() const { return false; }
00132     virtual bool isTableSection() const { return false; }
00133     virtual bool isTableCol() const { return false; }
00134     virtual bool isTable() const { return false; }
00135     virtual bool isWidget() const { return false; }
00136     virtual bool isBody() const { return false; }
00137     virtual bool isFormElement() const { return false; }
00138     virtual bool isFrameSet() const { return false; }
00139     virtual bool isApplet() const { return false; }
00140 
00141     bool isAnonymousBox() const { return m_isAnonymous; }
00142     void setIsAnonymousBox(bool b) { m_isAnonymous = b; }
00143 
00144     bool isFloating() const { return m_floating; }
00145     bool isPositioned() const { return m_positioned; } // absolute or fixed positioning
00146     bool isRelPositioned() const { return m_relPositioned; } // relative positioning
00147     bool isText() const  { return m_isText; }
00148     bool isInline() const { return m_inline; }  // inline object
00149     bool mouseInside() const { return m_mouseInside; }
00150     bool isReplaced() const { return m_replaced; } // a "replaced" element (see CSS)
00151     bool hasSpecialObjects() const { return m_paintSpecial; }
00152     bool layouted() const   { return m_layouted; }
00153     bool minMaxKnown() const{ return m_minMaxKnown; }
00154     bool overhangingContents() const { return m_overhangingContents; }
00155     bool hasFirstLine() const { return m_hasFirstLine; }
00156     bool isSelectionBorder() const { return m_isSelectionBorder; }
00157     bool recalcMinMax() const { return m_recalcMinMax; }
00158 
00159     RenderRoot* root() const;
00160     // don't even think about making this method virtual!
00161     DOM::NodeImpl* element() const { return m_node; }
00162 
00167     RenderObject *container() const;
00168 
00169     void setOverhangingContents(bool p=true);
00170     void setLayouted() {
00171     m_layouted = true;
00172     }
00173     void setLayouted(bool b) {
00174     m_layouted = b;
00175     if(!b) {
00176         RenderObject *o = m_parent;
00177         RenderObject *root = this;
00178         while( o ) {
00179         o->m_layouted = false;
00180         root = o;
00181         o = o->m_parent;
00182         }
00183         root->scheduleRelayout();
00184     }
00185     }
00186     void setLayoutedLocal(bool b) {
00187     m_layouted = b;
00188     }
00189     void setMinMaxKnown(bool b=true) {
00190     m_minMaxKnown = b;
00191     if ( !b ) {
00192         RenderObject *o = this;
00193         RenderObject *root = this;
00194         while( o ) { // ### && !o->m_recalcMinMax ) {
00195         o->m_recalcMinMax = true;
00196         root = o;
00197         o = o->m_parent;
00198         }
00199     }
00200     }
00201     void setPositioned(bool b=true)  { m_positioned = b;  }
00202     void setRelPositioned(bool b=true) { m_relPositioned = b; }
00203     void setFloating(bool b=true) { m_floating = b; }
00204     void setInline(bool b=true) { m_inline = b; }
00205     void setMouseInside(bool b=true) { m_mouseInside = b; }
00206     void setSpecialObjects(bool b=true) { m_paintSpecial = b; }
00207     void setRenderText() { m_isText = true; }
00208     void setReplaced(bool b=true) { m_replaced = b; }
00209     void setIsSelectionBorder(bool b=true) { m_isSelectionBorder = b; }
00210 
00211     void scheduleRelayout();
00212 
00213     // for discussion of lineHeight see CSS2 spec
00214     virtual short lineHeight( bool firstLine ) const;
00215     // for the vertical-align property of inline elements
00216     // the difference between this objects baseline position and the lines baseline position.
00217     virtual short verticalPositionHint( bool firstLine ) const;
00218     // the offset of baseline from the top of the object.
00219     virtual short baselinePosition( bool firstLine ) const;
00220 
00221     /*
00222      * Print the object and its children, clipped by (x|y|w|h).
00223      * (tx|ty) is the calculated position of the parent
00224      */
00225     virtual void paint( QPainter *p, int x, int y, int w, int h, int tx, int ty);
00226 
00227     virtual void paintObject( QPainter */*p*/, int /*x*/, int /*y*/,
00228                         int /*w*/, int /*h*/, int /*tx*/, int /*ty*/) {}
00229     void paintBorder(QPainter *p, int _tx, int _ty, int w, int h, const RenderStyle* style, bool begin=true, bool end=true);
00230     void paintOutline(QPainter *p, int _tx, int _ty, int w, int h, const RenderStyle* style);
00231 
00232 
00233     /*
00234      * This function calculates the minimum & maximum width that the object
00235      * can be set to.
00236      *
00237      * when the Element calls setMinMaxKnown(true), calcMinMaxWidth() will
00238      * be no longer called.
00239      *
00240      * when a element has a fixed size, m_minWidth and m_maxWidth should be
00241      * set to the same value. This has the special meaning that m_width,
00242      * contains the actual value.
00243      *
00244      * assumes calcMinMaxWidth has already been called for all children.
00245      */
00246     virtual void calcMinMaxWidth() { }
00247 
00248     /*
00249      * Does the min max width recalculations after changes.
00250      */
00251     void recalcMinMaxWidths();
00252 
00253     /*
00254      * Calculates the actual width of the object (only for non inline
00255      * objects)
00256      */
00257     virtual void calcWidth() {}
00258 
00259     /*
00260      * This function should cause the Element to calculate its
00261      * width and height and the layout of its content
00262      *
00263      * when the Element calls setLayouted(true), layout() is no
00264      * longer called during relayouts, as long as there is no
00265      * style sheet change. When that occurs, isLayouted will be
00266      * set to false and the Element receives layout() calls
00267      * again.
00268      */
00269     virtual void layout() = 0;
00270 
00271     // used for element state updates that can not be fixed with a
00272     // repaint and do not need a relayout
00273     virtual void updateFromElement() {};
00274 
00275     // The corresponding closing element has been parsed. ### remove me
00276     virtual void close() { }
00277 
00278     virtual int availableHeight() const { return 0; }
00279 
00280     // does a query on the rendertree and finds the innernode
00281     // and overURL for the given position
00282     // if readonly == false, it will recalc hover styles accordingly
00283     class NodeInfo
00284     {
00285         friend class RenderImage;
00286         friend class RenderFlow;
00287         friend class RenderText;
00288         friend class RenderObject;
00289         friend class RenderFrameSet;
00290         friend class DOM::HTMLAreaElementImpl;
00291     public:
00292         NodeInfo(bool readonly, bool active)
00293             : m_innerNode(0), m_innerURLElement(0), m_readonly(readonly), m_active(active)
00294             { }
00295 
00296         DOM::NodeImpl* innerNode() const { return m_innerNode; }
00297         DOM::NodeImpl* URLElement() const { return m_innerURLElement; }
00298         bool readonly() const { return m_readonly; }
00299         bool active() const { return m_active; }
00300 
00301     private:
00302         void setInnerNode(DOM::NodeImpl* n) { m_innerNode = n; }
00303         void setURLElement(DOM::NodeImpl* n) { m_innerURLElement = n; }
00304 
00305         DOM::NodeImpl* m_innerNode;
00306         DOM::NodeImpl* m_innerURLElement;
00307         bool m_readonly;
00308         bool m_active;
00309     };
00310 
00311     virtual FindSelectionResult checkSelectionPoint( int _x, int _y, int _tx, int _ty,
00312                                                      DOM::NodeImpl*&, int & offset );
00313     virtual bool nodeAtPoint(NodeInfo& info, int x, int y, int tx, int ty);
00314 
00315     // set the style of the object.
00316     virtual void setStyle(RenderStyle *style);
00317 
00318     // returns the containing block level element for this element.
00319     RenderObject *containingBlock() const;
00320 
00321     // return just the width of the containing block
00322     virtual short containingBlockWidth() const;
00323     // return just the height of the containing block
00324     virtual int containingBlockHeight() const;
00325 
00326     // size of the content area (box size minus padding/border)
00327     virtual short contentWidth() const { return 0; }
00328     virtual int contentHeight() const { return 0; }
00329 
00330     // intrinsic extend of replaced elements. undefined otherwise
00331     virtual short intrinsicWidth() const { return 0; }
00332     virtual int intrinsicHeight() const { return 0; }
00333 
00334     // relative to parent node
00335     virtual void setPos( int /*xPos*/, int /*yPos*/ ) { }
00336     virtual void setWidth( int /*width*/ ) { }
00337     virtual void setHeight( int /*height*/ ) { }
00338 
00339     virtual int xPos() const { return 0; }
00340     virtual int yPos() const { return 0; }
00341 
00342     // calculate client position of box
00343     virtual bool absolutePosition(int &/*xPos*/, int &/*yPos*/, bool fixed = false);
00344 
00345     // width and height are without margins but include paddings and borders
00346     virtual short width() const { return 0; }
00347     virtual int height() const { return 0; }
00348 
00349     virtual short marginTop() const { return 0; }
00350     virtual short marginBottom() const { return 0; }
00351     virtual short marginLeft() const { return 0; }
00352     virtual short marginRight() const { return 0; }
00353 
00354     int paddingTop() const;
00355     int paddingBottom() const;
00356     int paddingLeft() const;
00357     int paddingRight() const;
00358 
00359     int borderTop() const { return style()->borderTopWidth(); }
00360     int borderBottom() const { return style()->borderBottomWidth(); }
00361     int borderLeft() const { return style()->borderLeftWidth(); }
00362     int borderRight() const { return style()->borderRightWidth(); }
00363 
00364     virtual short minWidth() const { return 0; }
00365     virtual short maxWidth() const { return 0; }
00366 
00367     RenderStyle* style() const { return m_style; }
00368     RenderStyle* style( bool firstLine ) const {
00369     RenderStyle *s = m_style;
00370     if( firstLine && hasFirstLine() ) {
00371         RenderStyle *pseudoStyle  = style()->getPseudoStyle(RenderStyle::FIRST_LINE);
00372         if ( pseudoStyle )
00373         s = pseudoStyle;
00374     }
00375     return s;
00376     }
00377 
00378     enum BorderSide {
00379         BSTop, BSBottom, BSLeft, BSRight
00380     };
00381     void drawBorder(QPainter *p, int x1, int y1, int x2, int y2, BorderSide s,
00382                     QColor c, const QColor& textcolor, EBorderStyle style,
00383                     int adjbw1, int adjbw2, bool invalidisInvert = false);
00384 
00385     // force a complete repaint
00386     virtual void repaint() { if(m_parent) m_parent->repaint(); }
00387     virtual void repaintRectangle(int x, int y, int w, int h, bool f=false);
00388 
00389     virtual unsigned int length() const { return 1; }
00390 
00391     virtual bool isHidden() const { return isFloating() || isPositioned(); }
00392 
00393     // Special objects are objects that are neither really inline nor blocklevel
00394     bool isSpecial() const { return (isFloating() || isPositioned()); };
00395     virtual bool containsSpecial() { return false; }
00396     virtual bool hasOverhangingFloats() { return false; }
00397 
00398     // positioning of inline childs (bidi)
00399     virtual void position(int, int, int, int, int, bool, bool, int) {}
00400 
00401     enum SelectionState {
00402         SelectionNone,
00403         SelectionStart,
00404         SelectionInside,
00405         SelectionEnd,
00406         SelectionBoth
00407     };
00408 
00409     virtual SelectionState selectionState() const { return SelectionNone;}
00410     virtual void setSelectionState(SelectionState) {}
00411 
00412     virtual void cursorPos(int /*offset*/, int &/*_x*/, int &/*_y*/, int &/*height*/);
00413 
00414     // returns the lowest position of the lowest object in that particular object.
00415     // This 'height' is relative to the topleft of the margin box of the object.
00416     // Implemented in RenderFlow.
00417     virtual int lowestPosition() const {return 0;}
00418 
00419     virtual int rightmostPosition() const {return 0;}
00420 
00421     // recursively invalidate current layout
00422     // unused: void invalidateLayout();
00423 
00424     virtual void calcVerticalMargins() {}
00425     void removeFromSpecialObjects();
00426 
00427     virtual void detach();
00428 
00429     const QFont &font(bool firstLine) const {
00430     return style( firstLine )->font();
00431     }
00432 
00433     const QFontMetrics &fontMetrics(bool firstLine) const {
00434     return style( firstLine )->fontMetrics();
00435     }
00436 protected:
00437     virtual void selectionStartEnd(int& spos, int& epos);
00438 
00439     virtual void paintBoxDecorations(QPainter* /*p*/, int /*_x*/, int /*_y*/,
00440                                      int /*_w*/, int /*_h*/, int /*_tx*/, int /*_ty*/) {}
00441 
00442     virtual QRect viewRect() const;
00443     void remove() {
00444         removeFromSpecialObjects();
00445 
00446         if ( parent() )
00447             //have parent, take care of the tree integrity
00448             parent()->removeChild(this);
00449     }
00450 
00451     void invalidateVerticalPositions();
00452     short getVerticalPosition( bool firstLine ) const;
00453 
00454     virtual void removeLeftoverAnonymousBoxes();
00455 
00456 private:
00457     RenderStyle* m_style;
00458     DOM::NodeImpl* m_node;
00459     RenderObject *m_parent;
00460     RenderObject *m_previous;
00461     RenderObject *m_next;
00462 
00463     short m_verticalPosition;
00464 
00465     bool m_layouted                  : 1;
00466     bool m_unused                   : 1;
00467     bool m_minMaxKnown               : 1;
00468     bool m_floating                  : 1;
00469 
00470     bool m_positioned                : 1;
00471     bool m_overhangingContents : 1;
00472     bool m_relPositioned             : 1;
00473     bool m_paintSpecial              : 1; // if the box has something special to print (background, border, etc)
00474 
00475     bool m_isAnonymous               : 1;
00476     bool m_recalcMinMax          : 1;
00477     bool m_isText                    : 1;
00478     bool m_inline                    : 1;
00479 
00480     bool m_replaced                  : 1;
00481     bool m_mouseInside : 1;
00482     bool m_hasFirstLine              : 1;
00483     bool m_isSelectionBorder          : 1;
00484 
00485     // note: do not add unnecessary bitflags, we have 32 bit already!
00486     friend class RenderListItem;
00487     friend class RenderContainer;
00488     friend class RenderRoot;
00489 };
00490 
00491 
00492 enum VerticalPositionHint {
00493     PositionTop = -0x4000,
00494     PositionBottom = 0x4000,
00495     PositionUndefined = 0x3fff
00496 };
00497 
00498 }; //namespace
00499 #endif
KDE Logo
This file is part of the documentation for kdelibs Version 3.1.0.
Documentation copyright © 1996-2002 the KDE developers.
Generated on Wed Oct 8 12:22:43 2003 by doxygen 1.2.18 written by Dimitri van Heesch, © 1997-2001