1 /* 2 * Copyright (C) 2000 Lars Knoll (knoll@kde.org) 3 * (C) 2000 Antti Koivisto (koivisto@kde.org) 4 * (C) 2000 Dirk Mueller (mueller@kde.org) 5 * (C) 2004 Allan Sandfeld Jensen (kde@carewolf.com) 6 * Copyright (C) 2003, 2004, 2005, 2006, 2007, 2008, 2009 Apple Inc. All rights reserved. 7 * 8 * This library is free software; you can redistribute it and/or 9 * modify it under the terms of the GNU Library General Public 10 * License as published by the Free Software Foundation; either 11 * version 2 of the License, or (at your option) any later version. 12 * 13 * This library is distributed in the hope that it will be useful, 14 * but WITHOUT ANY WARRANTY; without even the implied warranty of 15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 16 * Library General Public License for more details. 17 * 18 * You should have received a copy of the GNU Library General Public License 19 * along with this library; see the file COPYING.LIB. If not, write to 20 * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, 21 * Boston, MA 02110-1301, USA. 22 * 23 */ 24 25 #ifndef RenderObject_h 26 #define RenderObject_h 27 28 #include "CachedResourceClient.h" 29 #include "FloatQuad.h" 30 #include "Document.h" 31 #include "RenderStyle.h" 32 33 namespace WebCore { 34 35 class AnimationController; 36 class HitTestResult; 37 class InlineBox; 38 class InlineFlowBox; 39 class RenderBlock; 40 class RenderFlow; 41 class RenderLayer; 42 class VisiblePosition; 43 44 /* 45 * The painting of a layer occurs in three distinct phases. Each phase involves 46 * a recursive descent into the layer's render objects. The first phase is the background phase. 47 * The backgrounds and borders of all blocks are painted. Inlines are not painted at all. 48 * Floats must paint above block backgrounds but entirely below inline content that can overlap them. 49 * In the foreground phase, all inlines are fully painted. Inline replaced elements will get all 50 * three phases invoked on them during this phase. 51 */ 52 53 enum PaintPhase { 54 PaintPhaseBlockBackground, 55 PaintPhaseChildBlockBackground, 56 PaintPhaseChildBlockBackgrounds, 57 PaintPhaseFloat, 58 PaintPhaseForeground, 59 PaintPhaseOutline, 60 PaintPhaseChildOutlines, 61 PaintPhaseSelfOutline, 62 PaintPhaseSelection, 63 PaintPhaseCollapsedTableBorders, 64 PaintPhaseTextClip, 65 PaintPhaseMask 66 }; 67 68 enum PaintRestriction { 69 PaintRestrictionNone, 70 PaintRestrictionSelectionOnly, 71 PaintRestrictionSelectionOnlyBlackText 72 }; 73 74 enum HitTestFilter { 75 HitTestAll, 76 HitTestSelf, 77 HitTestDescendants 78 }; 79 80 enum HitTestAction { 81 HitTestBlockBackground, 82 HitTestChildBlockBackground, 83 HitTestChildBlockBackgrounds, 84 HitTestFloat, 85 HitTestForeground 86 }; 87 88 // Values for verticalPosition. 89 const int PositionTop = -0x7fffffff; 90 const int PositionBottom = 0x7fffffff; 91 const int PositionUndefined = 0x80000000; 92 93 #if ENABLE(DASHBOARD_SUPPORT) 94 struct DashboardRegionValue { 95 bool operator==(const DashboardRegionValue& o) const 96 { 97 return type == o.type && bounds == o.bounds && clip == o.clip && label == o.label; 98 } 99 bool operator!=(const DashboardRegionValue& o) const 100 { 101 return !(*this == o); 102 } 103 104 String label; 105 IntRect bounds; 106 IntRect clip; 107 int type; 108 }; 109 #endif 110 111 // Base class for all rendering tree objects. 112 class RenderObject : public CachedResourceClient { 113 friend class RenderContainer; 114 friend class RenderLayer; 115 friend class RenderSVGContainer; 116 public: 117 // Anonymous objects should pass the document as their node, and they will then automatically be 118 // marked as anonymous in the constructor. 119 RenderObject(Node*); 120 virtual ~RenderObject(); 121 renderName()122 virtual const char* renderName() const { return "RenderObject"; } 123 parent()124 RenderObject* parent() const { return m_parent; } 125 bool isDescendantOf(const RenderObject*) const; 126 previousSibling()127 RenderObject* previousSibling() const { return m_previous; } nextSibling()128 RenderObject* nextSibling() const { return m_next; } 129 firstChild()130 virtual RenderObject* firstChild() const { return 0; } lastChild()131 virtual RenderObject* lastChild() const { return 0; } 132 133 RenderObject* nextInPreOrder() const; 134 RenderObject* nextInPreOrder(RenderObject* stayWithin) const; 135 RenderObject* nextInPreOrderAfterChildren() const; 136 RenderObject* nextInPreOrderAfterChildren(RenderObject* stayWithin) const; 137 RenderObject* previousInPreOrder() const; 138 RenderObject* childAt(unsigned) const; 139 140 RenderObject* firstLeafChild() const; 141 RenderObject* lastLeafChild() const; 142 143 // The following five functions are used when the render tree hierarchy changes to make sure layers get 144 // properly added and removed. Since containership can be implemented by any subclass, and since a hierarchy 145 // can contain a mixture of boxes and other object types, these functions need to be in the base class. 146 RenderLayer* enclosingLayer() const; 147 void addLayers(RenderLayer* parentLayer, RenderObject* newObject); 148 void removeLayers(RenderLayer* parentLayer); 149 void moveLayers(RenderLayer* oldParent, RenderLayer* newParent); 150 RenderLayer* findNextLayer(RenderLayer* parentLayer, RenderObject* startPoint, bool checkParent = true); 151 152 // Convenience function for getting to the nearest enclosing box of a RenderObject. 153 RenderBox* enclosingBox() const; 154 getOverflowClipRect(int,int)155 virtual IntRect getOverflowClipRect(int /*tx*/, int /*ty*/) { return IntRect(0, 0, 0, 0); } getClipRect(int,int)156 virtual IntRect getClipRect(int /*tx*/, int /*ty*/) { return IntRect(0, 0, 0, 0); } hasClip()157 bool hasClip() { return isPositioned() && style()->hasClip(); } 158 getBaselineOfFirstLineBox()159 virtual int getBaselineOfFirstLineBox() const { return -1; } getBaselineOfLastLineBox()160 virtual int getBaselineOfLastLineBox() const { return -1; } 161 isEmpty()162 virtual bool isEmpty() const { return firstChild() == 0; } 163 isEdited()164 virtual bool isEdited() const { return false; } setEdited(bool)165 virtual void setEdited(bool) { } 166 167 #ifndef NDEBUG setHasAXObject(bool flag)168 void setHasAXObject(bool flag) { m_hasAXObject = flag; } hasAXObject()169 bool hasAXObject() const { return m_hasAXObject; } isSetNeedsLayoutForbidden()170 bool isSetNeedsLayoutForbidden() const { return m_setNeedsLayoutForbidden; } setNeedsLayoutIsForbidden(bool flag)171 void setNeedsLayoutIsForbidden(bool flag) { m_setNeedsLayoutForbidden = flag; } 172 #endif 173 174 // Obtains the nearest enclosing block (including this block) that contributes a first-line style to our inline 175 // children. 176 virtual RenderBlock* firstLineBlock() const; 177 178 // Called when an object that was floating or positioned becomes a normal flow object 179 // again. We have to make sure the render tree updates as needed to accommodate the new 180 // normal flow object. 181 void handleDynamicFloatPositionChange(); 182 183 // This function is a convenience helper for creating an anonymous block that inherits its 184 // style from this RenderObject. 185 RenderBlock* createAnonymousBlock(); 186 187 // Whether or not a positioned element requires normal flow x/y to be computed 188 // to determine its position. 189 bool hasStaticX() const; 190 bool hasStaticY() const; setStaticX(int)191 virtual void setStaticX(int /*staticX*/) { } setStaticY(int)192 virtual void setStaticY(int /*staticY*/) { } staticX()193 virtual int staticX() const { return 0; } staticY()194 virtual int staticY() const { return 0; } 195 196 // RenderObject tree manipulation 197 ////////////////////////////////////////// 198 virtual bool canHaveChildren() const; isChildAllowed(RenderObject *,RenderStyle *)199 virtual bool isChildAllowed(RenderObject*, RenderStyle*) const { return true; } 200 virtual void addChild(RenderObject* newChild, RenderObject* beforeChild = 0); 201 virtual void removeChild(RenderObject*); createsAnonymousWrapper()202 virtual bool createsAnonymousWrapper() const { return false; } 203 204 // raw tree manipulation 205 virtual RenderObject* removeChildNode(RenderObject*, bool fullRemove = true); 206 virtual void appendChildNode(RenderObject*, bool fullAppend = true); 207 virtual void insertChildNode(RenderObject* child, RenderObject* before, bool fullInsert = true); 208 // Designed for speed. Don't waste time doing a bunch of work like layer updating and repainting when we know that our 209 // change in parentage is not going to affect anything. 210 virtual void moveChildNode(RenderObject*); 211 ////////////////////////////////////////// 212 213 protected: 214 ////////////////////////////////////////// 215 // Helper functions. Dangerous to use! setPreviousSibling(RenderObject * previous)216 void setPreviousSibling(RenderObject* previous) { m_previous = previous; } setNextSibling(RenderObject * next)217 void setNextSibling(RenderObject* next) { m_next = next; } setParent(RenderObject * parent)218 void setParent(RenderObject* parent) { m_parent = parent; } 219 ////////////////////////////////////////// 220 private: 221 void addAbsoluteRectForLayer(IntRect& result); 222 223 public: 224 #ifndef NDEBUG 225 void showTreeForThis() const; 226 #endif 227 228 static RenderObject* createObject(Node*, RenderStyle*); 229 230 // Overloaded new operator. Derived classes must override operator new 231 // in order to allocate out of the RenderArena. 232 void* operator new(size_t, RenderArena*) throw(); 233 234 // Overridden to prevent the normal delete from being called. 235 void operator delete(void*, size_t); 236 237 private: 238 // The normal operator new is disallowed on all render objects. 239 void* operator new(size_t) throw(); 240 241 public: renderArena()242 RenderArena* renderArena() const { return document()->renderArena(); } 243 isApplet()244 virtual bool isApplet() const { return false; } isBR()245 virtual bool isBR() const { return false; } isBlockFlow()246 virtual bool isBlockFlow() const { return false; } isCounter()247 virtual bool isCounter() const { return false; } isFieldset()248 virtual bool isFieldset() const { return false; } isFrame()249 virtual bool isFrame() const { return false; } isFrameSet()250 virtual bool isFrameSet() const { return false; } isImage()251 virtual bool isImage() const { return false; } isInlineBlockOrInlineTable()252 virtual bool isInlineBlockOrInlineTable() const { return false; } 253 virtual bool isInlineContinuation() const; isListBox()254 virtual bool isListBox() const { return false; } isListItem()255 virtual bool isListItem() const { return false; } isListMarker()256 virtual bool isListMarker() const { return false; } isMedia()257 virtual bool isMedia() const { return false; } isMenuList()258 virtual bool isMenuList() const { return false; } isRenderBlock()259 virtual bool isRenderBlock() const { return false; } isRenderImage()260 virtual bool isRenderImage() const { return false; } isRenderInline()261 virtual bool isRenderInline() const { return false; } isRenderPart()262 virtual bool isRenderPart() const { return false; } isRenderView()263 virtual bool isRenderView() const { return false; } isSlider()264 virtual bool isSlider() const { return false; } isTable()265 virtual bool isTable() const { return false; } isTableCell()266 virtual bool isTableCell() const { return false; } isTableCol()267 virtual bool isTableCol() const { return false; } isTableRow()268 virtual bool isTableRow() const { return false; } isTableSection()269 virtual bool isTableSection() const { return false; } isTextArea()270 virtual bool isTextArea() const { return false; } isTextField()271 virtual bool isTextField() const { return false; } isWidget()272 virtual bool isWidget() const { return false; } 273 isRoot()274 bool isRoot() const { return document()->documentElement() == node(); } 275 bool isBody() const; 276 bool isHR() const; 277 278 bool isHTMLMarquee() const; 279 childrenInline()280 virtual bool childrenInline() const { return false; } setChildrenInline(bool)281 virtual void setChildrenInline(bool) { } 282 virtualContinuation()283 virtual RenderFlow* virtualContinuation() const { return 0; } 284 285 #if ENABLE(SVG) isSVGRoot()286 virtual bool isSVGRoot() const { return false; } isSVGContainer()287 virtual bool isSVGContainer() const { return false; } isSVGHiddenContainer()288 virtual bool isSVGHiddenContainer() const { return false; } isRenderPath()289 virtual bool isRenderPath() const { return false; } isSVGText()290 virtual bool isSVGText() const { return false; } 291 292 virtual FloatRect relativeBBox(bool includeStroke = true) const; 293 294 virtual TransformationMatrix localTransform() const; 295 virtual TransformationMatrix absoluteTransform() const; 296 #endif 297 298 virtual bool isEditable() const; 299 isAnonymous()300 bool isAnonymous() const { return m_isAnonymous; } setIsAnonymous(bool b)301 void setIsAnonymous(bool b) { m_isAnonymous = b; } isAnonymousBlock()302 bool isAnonymousBlock() const 303 { 304 return m_isAnonymous && style()->display() == BLOCK && style()->styleType() == RenderStyle::NOPSEUDO && !isListMarker(); 305 } 306 isFloating()307 bool isFloating() const { return m_floating; } isPositioned()308 bool isPositioned() const { return m_positioned; } // absolute or fixed positioning isRelPositioned()309 bool isRelPositioned() const { return m_relPositioned; } // relative positioning isText()310 bool isText() const { return m_isText; } isBox()311 bool isBox() const { return m_isBox; } isInline()312 bool isInline() const { return m_inline; } // inline object isRunIn()313 bool isRunIn() const { return style()->display() == RUN_IN; } // run-in object isDragging()314 bool isDragging() const { return m_isDragging; } isReplaced()315 bool isReplaced() const { return m_replaced; } // a "replaced" element (see CSS) 316 hasLayer()317 bool hasLayer() const { return m_hasLayer; } 318 hasBoxDecorations()319 bool hasBoxDecorations() const { return m_paintBackground; } 320 bool mustRepaintBackgroundOrBorder() const; 321 needsLayout()322 bool needsLayout() const { return m_needsLayout || m_normalChildNeedsLayout || m_posChildNeedsLayout || m_needsPositionedMovementLayout; } selfNeedsLayout()323 bool selfNeedsLayout() const { return m_needsLayout; } needsPositionedMovementLayout()324 bool needsPositionedMovementLayout() const { return m_needsPositionedMovementLayout; } needsPositionedMovementLayoutOnly()325 bool needsPositionedMovementLayoutOnly() const { return m_needsPositionedMovementLayout && !m_needsLayout && !m_normalChildNeedsLayout && !m_posChildNeedsLayout; } posChildNeedsLayout()326 bool posChildNeedsLayout() const { return m_posChildNeedsLayout; } normalChildNeedsLayout()327 bool normalChildNeedsLayout() const { return m_normalChildNeedsLayout; } 328 prefWidthsDirty()329 bool prefWidthsDirty() const { return m_prefWidthsDirty; } 330 331 bool isSelectionBorder() const; 332 hasOverflowClip()333 bool hasOverflowClip() const { return m_hasOverflowClip; } hasControlClip()334 virtual bool hasControlClip() const { return false; } controlClipRect(int,int)335 virtual IntRect controlClipRect(int /*tx*/, int /*ty*/) const { return IntRect(); } 336 hasTransform()337 bool hasTransform() const { return m_hasTransform; } hasMask()338 bool hasMask() const { return style() && style()->hasMask(); } 339 340 public: 341 // The pseudo element style can be cached or uncached. Use the cached method if the pseudo element doesn't respect 342 // any pseudo classes (and therefore has no concept of changing state). 343 RenderStyle* getCachedPseudoStyle(RenderStyle::PseudoId, RenderStyle* parentStyle = 0) const; 344 PassRefPtr<RenderStyle> getUncachedPseudoStyle(RenderStyle::PseudoId, RenderStyle* parentStyle = 0) const; 345 346 void updateDragState(bool dragOn); 347 348 RenderView* view() const; 349 350 // don't even think about making this method virtual! element()351 Node* element() const { return m_isAnonymous ? 0 : m_node; } document()352 Document* document() const { return m_node->document(); } setNode(Node * node)353 void setNode(Node* node) { m_node = node; } node()354 Node* node() const { return m_node; } 355 356 bool hasOutlineAnnotation() const; hasOutline()357 bool hasOutline() const { return style()->hasOutline() || hasOutlineAnnotation(); } 358 359 /** 360 * returns the object containing this one. can be different from parent for 361 * positioned elements 362 */ 363 RenderObject* container() const; 364 RenderObject* hoverAncestor() const; 365 366 void markContainingBlocksForLayout(bool scheduleRelayout = true, RenderObject* newRoot = 0); 367 void setNeedsLayout(bool b, bool markParents = true); 368 void setChildNeedsLayout(bool b, bool markParents = true); 369 void setNeedsPositionedMovementLayout(); 370 void setPrefWidthsDirty(bool, bool markParents = true); 371 void invalidateContainerPrefWidths(); invalidateCounters()372 virtual void invalidateCounters() { } 373 setNeedsLayoutAndPrefWidthsRecalc()374 void setNeedsLayoutAndPrefWidthsRecalc() 375 { 376 setNeedsLayout(true); 377 setPrefWidthsDirty(true); 378 } 379 380 void setPositioned(bool b = true) { m_positioned = b; } 381 void setRelPositioned(bool b = true) { m_relPositioned = b; } 382 void setFloating(bool b = true) { m_floating = b; } 383 void setInline(bool b = true) { m_inline = b; } 384 void setHasBoxDecorations(bool b = true) { m_paintBackground = b; } setIsText()385 void setIsText() { m_isText = true; } setIsBox()386 void setIsBox() { m_isBox = true; } 387 void setReplaced(bool b = true) { m_replaced = b; } 388 void setHasOverflowClip(bool b = true) { m_hasOverflowClip = b; } 389 void setHasLayer(bool b = true) { m_hasLayer = b; } 390 void setHasTransform(bool b = true) { m_hasTransform = b; } 391 void setHasReflection(bool b = true) { m_hasReflection = b; } 392 393 void scheduleRelayout(); 394 395 void updateFillImages(const FillLayer*, const FillLayer*); 396 void updateImage(StyleImage*, StyleImage*); 397 398 virtual InlineBox* createInlineBox(bool makePlaceHolderBox, bool isRootLineBox, bool isOnlyRun = false); 399 virtual void dirtyLineBoxes(bool fullLayout, bool isRootLineBox = false); 400 401 // For inline replaced elements, this function returns the inline box that owns us. Enables 402 // the replaced RenderObject to quickly determine what line it is contained on and to easily 403 // iterate over structures on the line. 404 virtual InlineBox* inlineBoxWrapper() const; 405 virtual void setInlineBoxWrapper(InlineBox*); 406 virtual void deleteLineBoxWrapper(); 407 408 // for discussion of lineHeight see CSS2 spec 409 virtual int lineHeight(bool firstLine, bool isRootLineBox = false) const; 410 // for the vertical-align property of inline elements 411 // the difference between this objects baseline position and the lines baseline position. 412 virtual int verticalPositionHint(bool firstLine) const; 413 // the offset of baseline from the top of the object. 414 virtual int baselinePosition(bool firstLine, bool isRootLineBox = false) const; 415 416 /* 417 * Paint the object and its children, clipped by (x|y|w|h). 418 * (tx|ty) is the calculated position of the parent 419 */ 420 struct PaintInfo { PaintInfoPaintInfo421 PaintInfo(GraphicsContext* newContext, const IntRect& newRect, PaintPhase newPhase, bool newForceBlackText, 422 RenderObject* newPaintingRoot, ListHashSet<RenderFlow*>* newOutlineObjects) 423 : context(newContext) 424 , rect(newRect) 425 , phase(newPhase) 426 , forceBlackText(newForceBlackText) 427 , paintingRoot(newPaintingRoot) 428 , outlineObjects(newOutlineObjects) 429 { 430 } 431 432 GraphicsContext* context; 433 IntRect rect; 434 PaintPhase phase; 435 bool forceBlackText; 436 RenderObject* paintingRoot; // used to draw just one element and its visual kids 437 ListHashSet<RenderFlow*>* outlineObjects; // used to list outlines that should be painted by a block with inline children 438 }; 439 440 virtual void paint(PaintInfo&, int tx, int ty); 441 void paintBorder(GraphicsContext*, int tx, int ty, int w, int h, const RenderStyle*, bool begin = true, bool end = true); 442 bool paintNinePieceImage(GraphicsContext*, int tx, int ty, int w, int h, const RenderStyle*, const NinePieceImage&, CompositeOperator = CompositeSourceOver); 443 void paintBoxShadow(GraphicsContext*, int tx, int ty, int w, int h, const RenderStyle*, bool begin = true, bool end = true); 444 445 // RenderBox implements this. paintBoxDecorations(PaintInfo &,int,int)446 virtual void paintBoxDecorations(PaintInfo&, int /*tx*/, int /*ty*/) { } paintMask(PaintInfo &,int,int)447 virtual void paintMask(PaintInfo&, int /*tx*/, int /*ty*/) { } 448 virtual void paintFillLayerExtended(const PaintInfo&, const Color&, const FillLayer*, 449 int /*clipY*/, int /*clipH*/, int /*tx*/, int /*ty*/, int /*width*/, int /*height*/, 450 InlineFlowBox* = 0, CompositeOperator = CompositeSourceOver) { } 451 452 /* 453 * Calculates the actual width of the object (only for non inline 454 * objects) 455 */ calcWidth()456 virtual void calcWidth() { } 457 458 /* 459 * This function should cause the Element to calculate its 460 * width and height and the layout of its content 461 * 462 * when the Element calls setNeedsLayout(false), layout() is no 463 * longer called during relayouts, as long as there is no 464 * style sheet change. When that occurs, m_needsLayout will be 465 * set to true and the Element receives layout() calls 466 * again. 467 */ 468 virtual void layout() = 0; 469 470 /* This function performs a layout only if one is needed. */ layoutIfNeeded()471 void layoutIfNeeded() { if (needsLayout()) layout(); } 472 473 // Called when a positioned object moves but doesn't necessarily change size. A simplified layout is attempted 474 // that just updates the object's position. If the size does change, the object remains dirty. tryLayoutDoingPositionedMovementOnly()475 virtual void tryLayoutDoingPositionedMovementOnly() { } 476 477 // used for element state updates that cannot be fixed with a 478 // repaint and do not need a relayout updateFromElement()479 virtual void updateFromElement() { } 480 481 virtual void updateWidgetPosition(); 482 483 #if ENABLE(DASHBOARD_SUPPORT) 484 void addDashboardRegions(Vector<DashboardRegionValue>&); 485 void collectDashboardRegions(Vector<DashboardRegionValue>&); 486 #endif 487 488 bool hitTest(const HitTestRequest&, HitTestResult&, const IntPoint&, int tx, int ty, HitTestFilter = HitTestAll); 489 virtual bool nodeAtPoint(const HitTestRequest&, HitTestResult&, int x, int y, int tx, int ty, HitTestAction); 490 void updateHitTestResult(HitTestResult&, const IntPoint&); 491 492 virtual VisiblePosition positionForCoordinates(int x, int y); 493 VisiblePosition positionForPoint(const IntPoint&); 494 495 virtual void dirtyLinesFromChangedChild(RenderObject*); 496 497 // Called to update a style that is allowed to trigger animations. 498 // FIXME: Right now this will typically be called only when updating happens from the DOM on explicit elements. 499 // We don't yet handle generated content animation such as first-letter or before/after (we'll worry about this later). 500 void setAnimatableStyle(PassRefPtr<RenderStyle>); 501 502 // Set the style of the object and update the state of the object accordingly. 503 virtual void setStyle(PassRefPtr<RenderStyle>); 504 505 // Updates only the local style ptr of the object. Does not update the state of the object, 506 // and so only should be called when the style is known not to have changed (or from setStyle). 507 void setStyleInternal(PassRefPtr<RenderStyle>); 508 509 // returns the containing block level element for this element. 510 RenderBlock* containingBlock() const; 511 512 // return just the width of the containing block 513 virtual int containingBlockWidth() const; 514 // return just the height of the containing block 515 virtual int containingBlockHeight() const; 516 517 // used by flexible boxes to impose a flexed width/height override overrideSize()518 virtual int overrideSize() const { return 0; } overrideWidth()519 virtual int overrideWidth() const { return 0; } overrideHeight()520 virtual int overrideHeight() const { return 0; } setOverrideSize(int)521 virtual void setOverrideSize(int /*overrideSize*/) { } 522 523 // Convert the given local point to absolute coordinates 524 // FIXME: Temporary. If useTransforms is true, take transforms into account. Eventually localToAbsolute() will always be transform-aware. 525 virtual FloatPoint localToAbsolute(FloatPoint localPoint = FloatPoint(), bool fixed = false, bool useTransforms = false) const; 526 virtual FloatPoint absoluteToLocal(FloatPoint, bool fixed = false, bool useTransforms = false) const; 527 528 // Convert a local quad to absolute coordinates, taking transforms into account. 529 FloatQuad localToAbsoluteQuad(const FloatQuad& quad, bool fixed = false) const 530 { 531 return localToContainerQuad(quad, 0, fixed); 532 } 533 // Convert a local quad into the coordinate system of container, taking transforms into account. 534 virtual FloatQuad localToContainerQuad(const FloatQuad&, RenderBox* repaintContainer, bool fixed = false) const; 535 536 // Return the offset from the container() renderer (excluding transforms) 537 virtual IntSize offsetFromContainer(RenderObject*) const; 538 539 virtual void addLineBoxRects(Vector<IntRect>&, unsigned startOffset = 0, unsigned endOffset = UINT_MAX, bool useSelectionHeight = false); 540 541 virtual void absoluteRects(Vector<IntRect>&, int, int, bool = true) { } 542 // FIXME: useTransforms should go away eventually 543 IntRect absoluteBoundingBoxRect(bool useTransforms = false); 544 545 // Build an array of quads in absolute coords for line boxes 546 virtual void collectAbsoluteLineBoxQuads(Vector<FloatQuad>&, unsigned /*startOffset*/ = 0, unsigned /*endOffset*/ = UINT_MAX, bool /*useSelectionHeight*/ = false) { } 547 virtual void absoluteQuads(Vector<FloatQuad>&, bool /*topLevel*/ = true) { } 548 549 // the rect that will be painted if this object is passed as the paintingRoot 550 IntRect paintingRootRect(IntRect& topLevelRect); 551 minPrefWidth()552 virtual int minPrefWidth() const { return 0; } maxPrefWidth()553 virtual int maxPrefWidth() const { return 0; } 554 style()555 RenderStyle* style() const { return m_style.get(); } 556 RenderStyle* firstLineStyle() const; style(bool firstLine)557 RenderStyle* style(bool firstLine) const { return firstLine ? firstLineStyle() : style(); } 558 559 void getTextDecorationColors(int decorations, Color& underline, Color& overline, 560 Color& linethrough, bool quirksMode = false); 561 562 enum BorderSide { 563 BSTop, 564 BSBottom, 565 BSLeft, 566 BSRight 567 }; 568 569 void drawBorderArc(GraphicsContext*, int x, int y, float thickness, IntSize radius, int angleStart, 570 int angleSpan, BorderSide, Color, const Color& textcolor, EBorderStyle, bool firstCorner); 571 void drawBorder(GraphicsContext*, int x1, int y1, int x2, int y2, BorderSide, 572 Color, const Color& textcolor, EBorderStyle, int adjbw1, int adjbw2); 573 574 // Return the RenderBox in the container chain which is responsible for painting this object, or 0 575 // if painting is root-relative. This is the container that should be passed to the 'forRepaint' 576 // methods. 577 RenderBox* containerForRepaint() const; 578 579 // Repaint the entire object. Called when, e.g., the color of a border changes, or when a border 580 // style changes. 581 void repaint(bool immediate = false); 582 583 // Repaint a specific subrectangle within a given object. The rect |r| is in the object's coordinate space. 584 void repaintRectangle(const IntRect&, bool immediate = false); 585 586 // Repaint only if our old bounds and new bounds are different. 587 bool repaintAfterLayoutIfNeeded(const IntRect& oldBounds, const IntRect& oldOutlineBox); 588 589 // Repaint only if the object moved. 590 virtual void repaintDuringLayoutIfMoved(const IntRect& rect); 591 592 // Called to repaint a block's floats. 593 virtual void repaintOverhangingFloats(bool paintAllDescendants = false); 594 595 bool checkForRepaintDuringLayout() const; 596 597 // Returns the rect that should be repainted whenever this object changes. The rect is in the view's 598 // coordinate space. This method deals with outlines and overflow. absoluteClippedOverflowRect()599 IntRect absoluteClippedOverflowRect() 600 { 601 return clippedOverflowRectForRepaint(0); 602 } 603 virtual IntRect clippedOverflowRectForRepaint(RenderBox* repaintContainer); 604 605 IntRect rectWithOutlineForRepaint(RenderBox* repaintContainer, int outlineWidth); 606 607 // Given a rect in the object's coordinate space, compute a rect suitable for repainting 608 // that rect in view coordinates. 609 void computeAbsoluteRepaintRect(IntRect& r, bool fixed = false) 610 { 611 return computeRectForRepaint(r, 0, fixed); 612 } 613 // Given a rect in the object's coordinate space, compute a rect suitable for repainting 614 // that rect in the coordinate space of repaintContainer. 615 virtual void computeRectForRepaint(IntRect&, RenderBox* repaintContainer, bool fixed = false); 616 length()617 virtual unsigned int length() const { return 1; } 618 isFloatingOrPositioned()619 bool isFloatingOrPositioned() const { return (isFloating() || isPositioned()); } containsFloats()620 virtual bool containsFloats() { return false; } containsFloat(RenderObject *)621 virtual bool containsFloat(RenderObject*) { return false; } hasOverhangingFloats()622 virtual bool hasOverhangingFloats() { return false; } 623 624 virtual bool avoidsFloats() const; 625 bool shrinkToAvoidFloats() const; 626 627 // positioning of inline children (bidi) position(InlineBox *)628 virtual void position(InlineBox*) { } 629 isTransparent()630 bool isTransparent() const { return style()->opacity() < 1.0f; } opacity()631 float opacity() const { return style()->opacity(); } 632 hasReflection()633 bool hasReflection() const { return m_hasReflection; } 634 635 // Applied as a "slop" to dirty rect checks during the outline painting phase's dirty-rect checks. 636 int maximalOutlineSize(PaintPhase) const; 637 638 enum SelectionState { 639 SelectionNone, // The object is not selected. 640 SelectionStart, // The object either contains the start of a selection run or is the start of a run 641 SelectionInside, // The object is fully encompassed by a selection run 642 SelectionEnd, // The object either contains the end of a selection run or is the end of a run 643 SelectionBoth // The object contains an entire run or is the sole selected object in that run 644 }; 645 646 // The current selection state for an object. For blocks, the state refers to the state of the leaf 647 // descendants (as described above in the SelectionState enum declaration). selectionState()648 virtual SelectionState selectionState() const { return SelectionNone; } 649 650 // Sets the selection state for an object. setSelectionState(SelectionState state)651 virtual void setSelectionState(SelectionState state) { if (parent()) parent()->setSelectionState(state); } 652 653 // A single rectangle that encompasses all of the selected objects within this object. Used to determine the tightest 654 // possible bounding box for the selection. selectionRect(bool)655 virtual IntRect selectionRect(bool) { return IntRect(); } 656 657 // Whether or not an object can be part of the leaf elements of the selection. canBeSelectionLeaf()658 virtual bool canBeSelectionLeaf() const { return false; } 659 660 // Whether or not a block has selected children. hasSelectedChildren()661 virtual bool hasSelectedChildren() const { return false; } 662 663 // Obtains the selection colors that should be used when painting a selection. 664 Color selectionBackgroundColor() const; 665 Color selectionForegroundColor() const; 666 667 // Whether or not a given block needs to paint selection gaps. shouldPaintSelectionGaps()668 virtual bool shouldPaintSelectionGaps() const { return false; } 669 670 // This struct is used when the selection changes to cache the old and new state of the selection for each RenderObject. 671 struct SelectionInfo { SelectionInfoSelectionInfo672 SelectionInfo() 673 : m_object(0) 674 , m_state(SelectionNone) 675 { 676 } 677 SelectionInfoSelectionInfo678 SelectionInfo(RenderObject* o, bool clipToVisibleContent) 679 : m_object(o) 680 , m_rect(o->needsLayout() ? IntRect() : o->selectionRect(clipToVisibleContent)) 681 , m_state(o->selectionState()) 682 { 683 } 684 objectSelectionInfo685 RenderObject* object() const { return m_object; } rectSelectionInfo686 IntRect rect() const { return m_rect; } stateSelectionInfo687 SelectionState state() const { return m_state; } 688 689 RenderObject* m_object; 690 IntRect m_rect; 691 SelectionState m_state; 692 }; 693 694 Node* draggableNode(bool dhtmlOK, bool uaOK, int x, int y, bool& dhtmlWillDrag) const; 695 696 /** 697 * Returns the local coordinates of the caret within this render object. 698 * @param caretOffset zero-based offset determining position within the render object. 699 * @param extraWidthToEndOfLine optional out arg to give extra width to end of line - 700 * useful for character range rect computations 701 */ 702 virtual IntRect localCaretRect(InlineBox*, int caretOffset, int* extraWidthToEndOfLine = 0); 703 704 virtual int lowestPosition(bool /*includeOverflowInterior*/ = true, bool /*includeSelf*/ = true) const { return 0; } 705 virtual int rightmostPosition(bool /*includeOverflowInterior*/ = true, bool /*includeSelf*/ = true) const { return 0; } 706 virtual int leftmostPosition(bool /*includeOverflowInterior*/ = true, bool /*includeSelf*/ = true) const { return 0; } 707 calcVerticalMargins()708 virtual void calcVerticalMargins() { } 709 void removeFromObjectLists(); 710 711 // When performing a global document tear-down, the renderer of the document is cleared. We use this 712 // as a hook to detect the case of document destruction and don't waste time doing unnecessary work. 713 bool documentBeingDestroyed() const; 714 715 virtual void destroy(); 716 717 // Virtual function helpers for CSS3 Flexible Box Layout isFlexibleBox()718 virtual bool isFlexibleBox() const { return false; } isFlexingChildren()719 virtual bool isFlexingChildren() const { return false; } isStretchingChildren()720 virtual bool isStretchingChildren() const { return false; } 721 722 virtual int caretMinOffset() const; 723 virtual int caretMaxOffset() const; 724 virtual unsigned caretMaxRenderedOffset() const; 725 726 virtual int previousOffset(int current) const; 727 virtual int nextOffset(int current) const; 728 729 virtual void imageChanged(CachedImage*, const IntRect* = 0); 730 virtual void imageChanged(WrappedImagePtr, const IntRect* = 0) { } 731 virtual bool willRenderImage(CachedImage*); 732 733 virtual void selectionStartEnd(int& spos, int& epos) const; 734 paintingRootForChildren(PaintInfo & paintInfo)735 RenderObject* paintingRootForChildren(PaintInfo& paintInfo) const 736 { 737 // if we're the painting root, kids draw normally, and see root of 0 738 return (!paintInfo.paintingRoot || paintInfo.paintingRoot == this) ? 0 : paintInfo.paintingRoot; 739 } 740 shouldPaintWithinRoot(PaintInfo & paintInfo)741 bool shouldPaintWithinRoot(PaintInfo& paintInfo) const 742 { 743 return !paintInfo.paintingRoot || paintInfo.paintingRoot == this; 744 } 745 #ifdef ANDROID_LAYOUT hasChildTable()746 virtual bool hasChildTable() const { return false; } 747 #endif 748 hasOverrideSize()749 bool hasOverrideSize() const { return m_hasOverrideSize; } setHasOverrideSize(bool b)750 void setHasOverrideSize(bool b) { m_hasOverrideSize = b; } 751 remove()752 void remove() { if (parent()) parent()->removeChild(this); } 753 invalidateVerticalPosition()754 void invalidateVerticalPosition() { m_verticalPosition = PositionUndefined; } 755 756 virtual void removeLeftoverAnonymousBlock(RenderBlock* child); 757 capsLockStateMayHaveChanged()758 virtual void capsLockStateMayHaveChanged() { } 759 760 AnimationController* animation() const; 761 visibleToHitTesting()762 bool visibleToHitTesting() const { return style()->visibility() == VISIBLE && style()->pointerEvents() != PE_NONE; } 763 addFocusRingRects(GraphicsContext *,int,int)764 virtual void addFocusRingRects(GraphicsContext*, int /*tx*/, int /*ty*/) { }; 765 absoluteOutlineBounds()766 IntRect absoluteOutlineBounds() const 767 { 768 return outlineBoundsForRepaint(0); 769 } 770 771 protected: 772 // Overrides should call the superclass at the end 773 virtual void styleWillChange(RenderStyle::Diff, const RenderStyle* newStyle); 774 // Overrides should call the superclass at the start 775 virtual void styleDidChange(RenderStyle::Diff, const RenderStyle* oldStyle); 776 printBoxDecorations(GraphicsContext *,int,int,int,int,int,int)777 virtual void printBoxDecorations(GraphicsContext*, int /*x*/, int /*y*/, int /*w*/, int /*h*/, int /*tx*/, int /*ty*/) { } 778 779 void paintOutline(GraphicsContext*, int tx, int ty, int w, int h, const RenderStyle*); 780 void addPDFURLRect(GraphicsContext*, const IntRect&); 781 782 virtual IntRect viewRect() const; 783 784 int getVerticalPosition(bool firstLine) const; 785 786 void adjustRectForOutlineAndShadow(IntRect&) const; 787 788 void arenaDelete(RenderArena*, void* objectBase); 789 outlineBoundsForRepaint(RenderBox *)790 virtual IntRect outlineBoundsForRepaint(RenderBox* /*repaintContainer*/) const { return IntRect(); } 791 792 private: 793 RefPtr<RenderStyle> m_style; 794 795 Node* m_node; 796 797 RenderObject* m_parent; 798 RenderObject* m_previous; 799 RenderObject* m_next; 800 801 #ifndef NDEBUG 802 bool m_hasAXObject; 803 bool m_setNeedsLayoutForbidden : 1; 804 #endif 805 mutable int m_verticalPosition; 806 807 bool m_needsLayout : 1; 808 bool m_needsPositionedMovementLayout :1; 809 bool m_normalChildNeedsLayout : 1; 810 bool m_posChildNeedsLayout : 1; 811 bool m_prefWidthsDirty : 1; 812 bool m_floating : 1; 813 814 bool m_positioned : 1; 815 bool m_relPositioned : 1; 816 bool m_paintBackground : 1; // if the box has something to paint in the 817 // background painting phase (background, border, etc) 818 819 bool m_isAnonymous : 1; 820 bool m_isText : 1; 821 bool m_isBox : 1; 822 bool m_inline : 1; 823 bool m_replaced : 1; 824 bool m_isDragging : 1; 825 826 bool m_hasLayer : 1; 827 bool m_hasOverflowClip : 1; 828 bool m_hasTransform : 1; 829 bool m_hasReflection : 1; 830 831 bool m_hasOverrideSize : 1; 832 833 public: 834 bool m_hasCounterNodeMap : 1; 835 bool m_everHadLayout : 1; 836 837 private: 838 // Store state between styleWillChange and styleDidChange 839 static bool s_affectsParentBlock; 840 }; 841 842 } // namespace WebCore 843 844 #ifndef NDEBUG 845 // Outside the WebCore namespace for ease of invocation from gdb. 846 void showTree(const WebCore::RenderObject*); 847 #endif 848 849 #endif // RenderObject_h 850