1 /* 2 * Copyright (C) 2000 Lars Knoll (knoll (at) kde.org) 3 * (C) 2000 Antti Koivisto (koivisto (at) kde.org) 4 * (C) 2000 Dirk Mueller (mueller (at) kde.org) 5 * (C) 2004 Allan Sandfeld Jensen (kde (at) carewolf.com) 6 * Copyright (C) 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2012 Apple Inc. All rights reserved. 7 * Copyright (C) 2009 Google Inc. All rights reserved. 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., 51 Franklin Street, Fifth Floor, 22 * Boston, MA 02110-1301, USA. 23 * 24 */ 25 26 #ifndef RenderObject_h 27 #define RenderObject_h 28 29 #include "core/dom/Element.h" 30 #include "core/dom/Position.h" 31 #include "core/dom/StyleEngine.h" 32 #include "core/fetch/ImageResourceClient.h" 33 #include "core/rendering/CompositingState.h" 34 #include "core/rendering/LayoutIndicator.h" 35 #include "core/rendering/PaintPhase.h" 36 #include "core/rendering/RenderObjectChildList.h" 37 #include "core/rendering/ScrollBehavior.h" 38 #include "core/rendering/SubtreeLayoutScope.h" 39 #include "core/rendering/style/RenderStyle.h" 40 #include "core/rendering/style/StyleInheritedData.h" 41 #include "platform/geometry/FloatQuad.h" 42 #include "platform/geometry/LayoutRect.h" 43 #include "platform/transforms/TransformationMatrix.h" 44 45 namespace WebCore { 46 47 class AffineTransform; 48 class AnimationController; 49 class Cursor; 50 class Document; 51 class HitTestLocation; 52 class HitTestResult; 53 class InlineBox; 54 class InlineFlowBox; 55 class Path; 56 class Position; 57 class PseudoStyleRequest; 58 class RenderBoxModelObject; 59 class RenderInline; 60 class RenderBlock; 61 class RenderFlowThread; 62 class RenderGeometryMap; 63 class RenderLayer; 64 class RenderLayerModelObject; 65 class RenderNamedFlowThread; 66 class RenderSVGResourceContainer; 67 class RenderTable; 68 class RenderTheme; 69 class RenderView; 70 class ResourceLoadPriorityOptimizer; 71 class TransformState; 72 73 struct PaintInfo; 74 75 enum CursorDirective { 76 SetCursorBasedOnStyle, 77 SetCursor, 78 DoNotSetCursor 79 }; 80 81 enum HitTestFilter { 82 HitTestAll, 83 HitTestSelf, 84 HitTestDescendants 85 }; 86 87 enum HitTestAction { 88 HitTestBlockBackground, 89 HitTestChildBlockBackground, 90 HitTestChildBlockBackgrounds, 91 HitTestFloat, 92 HitTestForeground 93 }; 94 95 // Sides used when drawing borders and outlines. The values should run clockwise from top. 96 enum BoxSide { 97 BSTop, 98 BSRight, 99 BSBottom, 100 BSLeft 101 }; 102 103 enum MarkingBehavior { 104 MarkOnlyThis, 105 MarkContainingBlockChain, 106 }; 107 108 enum MapCoordinatesMode { 109 IsFixed = 1 << 0, 110 UseTransforms = 1 << 1, 111 ApplyContainerFlip = 1 << 2, 112 TraverseDocumentBoundaries = 1 << 3, 113 }; 114 typedef unsigned MapCoordinatesFlags; 115 116 const int caretWidth = 1; 117 118 struct AnnotatedRegionValue { 119 bool operator==(const AnnotatedRegionValue& o) const 120 { 121 return draggable == o.draggable && bounds == o.bounds; 122 } 123 124 LayoutRect bounds; 125 bool draggable; 126 }; 127 128 typedef WTF::HashMap<const RenderLayer*, Vector<LayoutRect> > LayerHitTestRects; 129 130 #ifndef NDEBUG 131 const int showTreeCharacterOffset = 39; 132 #endif 133 134 // Base class for all rendering tree objects. 135 class RenderObject : public ImageResourceClient { 136 friend class RenderBlock; 137 friend class RenderBlockFlow; 138 friend class RenderLayer; // For setParent. 139 friend class RenderLayerReflectionInfo; // For setParent 140 friend class RenderLayerScrollableArea; // For setParent. 141 friend class RenderObjectChildList; 142 public: 143 // Anonymous objects should pass the document as their node, and they will then automatically be 144 // marked as anonymous in the constructor. 145 explicit RenderObject(Node*); 146 virtual ~RenderObject(); 147 148 virtual const char* renderName() const = 0; 149 150 String debugName() const; 151 152 RenderObject* parent() const { return m_parent; } 153 bool isDescendantOf(const RenderObject*) const; 154 155 RenderObject* previousSibling() const { return m_previous; } 156 RenderObject* nextSibling() const { return m_next; } 157 158 // FIXME: These should be renamed slowFirstChild, slowLastChild, etc. 159 // to discourage their use. The virtualChildren() call inside these 160 // can be slow for hot code paths. 161 // Currently, some subclasses like RenderBlock, override these NON-virtual 162 // functions to make these fast when we already have a more specific pointer type. 163 RenderObject* firstChild() const 164 { 165 if (const RenderObjectChildList* children = virtualChildren()) 166 return children->firstChild(); 167 return 0; 168 } 169 RenderObject* lastChild() const 170 { 171 if (const RenderObjectChildList* children = virtualChildren()) 172 return children->lastChild(); 173 return 0; 174 } 175 176 virtual RenderObjectChildList* virtualChildren() { return 0; } 177 virtual const RenderObjectChildList* virtualChildren() const { return 0; } 178 179 RenderObject* nextInPreOrder() const; 180 RenderObject* nextInPreOrder(const RenderObject* stayWithin) const; 181 RenderObject* nextInPreOrderAfterChildren() const; 182 RenderObject* nextInPreOrderAfterChildren(const RenderObject* stayWithin) const; 183 RenderObject* previousInPreOrder() const; 184 RenderObject* previousInPreOrder(const RenderObject* stayWithin) const; 185 RenderObject* childAt(unsigned) const; 186 187 RenderObject* lastLeafChild() const; 188 189 // The following six functions are used when the render tree hierarchy changes to make sure layers get 190 // properly added and removed. Since containership can be implemented by any subclass, and since a hierarchy 191 // can contain a mixture of boxes and other object types, these functions need to be in the base class. 192 RenderLayer* enclosingLayer() const; 193 void addLayers(RenderLayer* parentLayer); 194 void removeLayers(RenderLayer* parentLayer); 195 void moveLayers(RenderLayer* oldParent, RenderLayer* newParent); 196 RenderLayer* findNextLayer(RenderLayer* parentLayer, RenderObject* startPoint, bool checkParent = true); 197 198 // Scrolling is a RenderBox concept, however some code just cares about recursively scrolling our enclosing ScrollableArea(s). 199 bool scrollRectToVisible(const LayoutRect&, const ScrollAlignment& alignX = ScrollAlignment::alignCenterIfNeeded, const ScrollAlignment& alignY = ScrollAlignment::alignCenterIfNeeded); 200 201 // Convenience function for getting to the nearest enclosing box of a RenderObject. 202 RenderBox* enclosingBox() const; 203 RenderBoxModelObject* enclosingBoxModelObject() const; 204 205 RenderBox* enclosingScrollableBox() const; 206 207 // Function to return our enclosing flow thread if we are contained inside one. This 208 // function follows the containing block chain. 209 RenderFlowThread* flowThreadContainingBlock() const 210 { 211 if (flowThreadState() == NotInsideFlowThread) 212 return 0; 213 return locateFlowThreadContainingBlock(); 214 } 215 216 RenderNamedFlowThread* renderNamedFlowThreadWrapper() const; 217 218 virtual bool isEmpty() const { return firstChild() == 0; } 219 220 #ifndef NDEBUG 221 void setHasAXObject(bool flag) { m_hasAXObject = flag; } 222 bool hasAXObject() const { return m_hasAXObject; } 223 224 // Helper class forbidding calls to setNeedsLayout() during its lifetime. 225 class SetLayoutNeededForbiddenScope { 226 public: 227 explicit SetLayoutNeededForbiddenScope(RenderObject*); 228 ~SetLayoutNeededForbiddenScope(); 229 private: 230 RenderObject* m_renderObject; 231 bool m_preexistingForbidden; 232 }; 233 234 void assertRendererLaidOut() const 235 { 236 if (needsLayout()) 237 showRenderTreeForThis(); 238 ASSERT_WITH_SECURITY_IMPLICATION(!needsLayout()); 239 } 240 241 void assertSubtreeIsLaidOut() const 242 { 243 for (const RenderObject* renderer = this; renderer; renderer = renderer->nextInPreOrder()) 244 renderer->assertRendererLaidOut(); 245 } 246 247 #endif 248 249 // Obtains the nearest enclosing block (including this block) that contributes a first-line style to our inline 250 // children. 251 virtual RenderBlock* firstLineBlock() const; 252 253 // Called when an object that was floating or positioned becomes a normal flow object 254 // again. We have to make sure the render tree updates as needed to accommodate the new 255 // normal flow object. 256 void handleDynamicFloatPositionChange(); 257 258 // RenderObject tree manipulation 259 ////////////////////////////////////////// 260 virtual bool canHaveChildren() const { return virtualChildren(); } 261 virtual bool canHaveGeneratedChildren() const; 262 virtual bool isChildAllowed(RenderObject*, RenderStyle*) const { return true; } 263 virtual void addChild(RenderObject* newChild, RenderObject* beforeChild = 0); 264 virtual void addChildIgnoringContinuation(RenderObject* newChild, RenderObject* beforeChild = 0) { return addChild(newChild, beforeChild); } 265 virtual void removeChild(RenderObject*); 266 virtual bool createsAnonymousWrapper() const { return false; } 267 ////////////////////////////////////////// 268 269 protected: 270 ////////////////////////////////////////// 271 // Helper functions. Dangerous to use! 272 void setPreviousSibling(RenderObject* previous) { m_previous = previous; } 273 void setNextSibling(RenderObject* next) { m_next = next; } 274 void setParent(RenderObject* parent) 275 { 276 m_parent = parent; 277 278 // Only update if our flow thread state is different from our new parent and if we're not a RenderFlowThread. 279 // A RenderFlowThread is always considered to be inside itself, so it never has to change its state 280 // in response to parent changes. 281 FlowThreadState newState = parent ? parent->flowThreadState() : NotInsideFlowThread; 282 if (newState != flowThreadState() && !isRenderFlowThread()) 283 setFlowThreadStateIncludingDescendants(newState); 284 } 285 286 ////////////////////////////////////////// 287 private: 288 #ifndef NDEBUG 289 bool isSetNeedsLayoutForbidden() const { return m_setNeedsLayoutForbidden; } 290 void setNeedsLayoutIsForbidden(bool flag) { m_setNeedsLayoutForbidden = flag; } 291 #endif 292 293 void addAbsoluteRectForLayer(LayoutRect& result); 294 void setLayerNeedsFullRepaint(); 295 void setLayerNeedsFullRepaintForPositionedMovementLayout(); 296 bool requiresAnonymousTableWrappers(const RenderObject*) const; 297 298 public: 299 #ifndef NDEBUG 300 void showTreeForThis() const; 301 void showRenderTreeForThis() const; 302 void showLineTreeForThis() const; 303 304 void showRenderObject() const; 305 // We don't make printedCharacters an optional parameter so that 306 // showRenderObject can be called from gdb easily. 307 void showRenderObject(int printedCharacters) const; 308 void showRenderTreeAndMark(const RenderObject* markedObject1 = 0, const char* markedLabel1 = 0, const RenderObject* markedObject2 = 0, const char* markedLabel2 = 0, int depth = 0) const; 309 #endif 310 311 static RenderObject* createObject(Element*, RenderStyle*); 312 313 // RenderObjects are allocated out of the rendering partition. 314 void* operator new(size_t); 315 void operator delete(void*); 316 317 public: 318 bool isPseudoElement() const { return node() && node()->isPseudoElement(); } 319 320 virtual bool isBR() const { return false; } 321 virtual bool isBoxModelObject() const { return false; } 322 virtual bool isCounter() const { return false; } 323 virtual bool isQuote() const { return false; } 324 325 virtual bool isDetailsMarker() const { return false; } 326 virtual bool isEmbeddedObject() const { return false; } 327 virtual bool isFieldset() const { return false; } 328 virtual bool isFileUploadControl() const { return false; } 329 virtual bool isFrame() const { return false; } 330 virtual bool isFrameSet() const { return false; } 331 virtual bool isImage() const { return false; } 332 virtual bool isInlineBlockOrInlineTable() const { return false; } 333 virtual bool isLayerModelObject() const { return false; } 334 virtual bool isListBox() const { return false; } 335 virtual bool isListItem() const { return false; } 336 virtual bool isListMarker() const { return false; } 337 virtual bool isMarquee() const { return false; } 338 virtual bool isMedia() const { return false; } 339 virtual bool isMenuList() const { return false; } 340 virtual bool isMeter() const { return false; } 341 virtual bool isProgress() const { return false; } 342 virtual bool isRenderBlock() const { return false; } 343 virtual bool isRenderBlockFlow() const { return false; } 344 virtual bool isRenderSVGBlock() const { return false; }; 345 virtual bool isRenderButton() const { return false; } 346 virtual bool isRenderIFrame() const { return false; } 347 virtual bool isRenderImage() const { return false; } 348 virtual bool isRenderInline() const { return false; } 349 virtual bool isRenderPart() const { return false; } 350 virtual bool isRenderRegion() const { return false; } 351 virtual bool isRenderNamedFlowFragment() const { return false; } 352 virtual bool isRenderView() const { return false; } 353 virtual bool isReplica() const { return false; } 354 355 virtual bool isRuby() const { return false; } 356 virtual bool isRubyBase() const { return false; } 357 virtual bool isRubyRun() const { return false; } 358 virtual bool isRubyText() const { return false; } 359 360 virtual bool isSlider() const { return false; } 361 virtual bool isSliderThumb() const { return false; } 362 virtual bool isTable() const { return false; } 363 virtual bool isTableCell() const { return false; } 364 virtual bool isRenderTableCol() const { return false; } 365 virtual bool isTableCaption() const { return false; } 366 virtual bool isTableRow() const { return false; } 367 virtual bool isTableSection() const { return false; } 368 virtual bool isTextControl() const { return false; } 369 virtual bool isTextArea() const { return false; } 370 virtual bool isTextField() const { return false; } 371 virtual bool isVideo() const { return false; } 372 virtual bool isWidget() const { return false; } 373 virtual bool isCanvas() const { return false; } 374 virtual bool isRenderFullScreen() const { return false; } 375 virtual bool isRenderFullScreenPlaceholder() const { return false; } 376 377 virtual bool isRenderGrid() const { return false; } 378 379 virtual bool isRenderFlowThread() const { return false; } 380 virtual bool isRenderNamedFlowThread() const { return false; } 381 bool isInFlowRenderFlowThread() const { return isRenderFlowThread() && !isOutOfFlowPositioned(); } 382 bool isOutOfFlowRenderFlowThread() const { return isRenderFlowThread() && isOutOfFlowPositioned(); } 383 bool isRenderNamedFlowFragmentContainer() const; 384 385 virtual bool isRenderMultiColumnBlock() const { return false; } 386 virtual bool isRenderMultiColumnSet() const { return false; } 387 388 virtual bool isRenderScrollbarPart() const { return false; } 389 390 bool isRoot() const { return document().documentElement() == m_node; } 391 bool isBody() const; 392 bool isHR() const; 393 bool isLegend() const; 394 395 bool isTablePart() const { return isTableCell() || isRenderTableCol() || isTableCaption() || isTableRow() || isTableSection(); } 396 397 inline bool isBeforeContent() const; 398 inline bool isAfterContent() const; 399 inline bool isBeforeOrAfterContent() const; 400 static inline bool isAfterContent(const RenderObject* obj) { return obj && obj->isAfterContent(); } 401 402 bool hasCounterNodeMap() const { return m_bitfields.hasCounterNodeMap(); } 403 void setHasCounterNodeMap(bool hasCounterNodeMap) { m_bitfields.setHasCounterNodeMap(hasCounterNodeMap); } 404 bool everHadLayout() const { return m_bitfields.everHadLayout(); } 405 406 bool childrenInline() const { return m_bitfields.childrenInline(); } 407 void setChildrenInline(bool b) { m_bitfields.setChildrenInline(b); } 408 bool hasColumns() const { return m_bitfields.hasColumns(); } 409 void setHasColumns(bool b = true) { m_bitfields.setHasColumns(b); } 410 411 bool ancestorLineBoxDirty() const { return m_bitfields.ancestorLineBoxDirty(); } 412 void setAncestorLineBoxDirty(bool value = true) 413 { 414 m_bitfields.setAncestorLineBoxDirty(value); 415 if (value) 416 setNeedsLayout(); 417 } 418 419 enum FlowThreadState { 420 NotInsideFlowThread = 0, 421 InsideOutOfFlowThread = 1, 422 InsideInFlowThread = 2, 423 }; 424 425 void setFlowThreadStateIncludingDescendants(FlowThreadState); 426 427 FlowThreadState flowThreadState() const { return m_bitfields.flowThreadState(); } 428 void setFlowThreadState(FlowThreadState state) { m_bitfields.setFlowThreadState(state); } 429 430 // FIXME: Until all SVG renders can be subclasses of RenderSVGModelObject we have 431 // to add SVG renderer methods to RenderObject with an ASSERT_NOT_REACHED() default implementation. 432 virtual bool isSVGRoot() const { return false; } 433 virtual bool isSVGContainer() const { return false; } 434 virtual bool isSVGTransformableContainer() const { return false; } 435 virtual bool isSVGViewportContainer() const { return false; } 436 virtual bool isSVGGradientStop() const { return false; } 437 virtual bool isSVGHiddenContainer() const { return false; } 438 virtual bool isSVGPath() const { return false; } 439 virtual bool isSVGShape() const { return false; } 440 virtual bool isSVGText() const { return false; } 441 virtual bool isSVGTextPath() const { return false; } 442 virtual bool isSVGInline() const { return false; } 443 virtual bool isSVGInlineText() const { return false; } 444 virtual bool isSVGImage() const { return false; } 445 virtual bool isSVGForeignObject() const { return false; } 446 virtual bool isSVGResourceContainer() const { return false; } 447 virtual bool isSVGResourceFilter() const { return false; } 448 virtual bool isSVGResourceFilterPrimitive() const { return false; } 449 450 // FIXME: Those belong into a SVG specific base-class for all renderers (see above) 451 // Unfortunately we don't have such a class yet, because it's not possible for all renderers 452 // to inherit from RenderSVGObject -> RenderObject (some need RenderBlock inheritance for instance) 453 virtual void setNeedsTransformUpdate() { } 454 virtual void setNeedsBoundariesUpdate(); 455 virtual bool needsBoundariesUpdate() { return false; } 456 457 // Per SVG 1.1 objectBoundingBox ignores clipping, masking, filter effects, opacity and stroke-width. 458 // This is used for all computation of objectBoundingBox relative units and by SVGLocatable::getBBox(). 459 // NOTE: Markers are not specifically ignored here by SVG 1.1 spec, but we ignore them 460 // since stroke-width is ignored (and marker size can depend on stroke-width). 461 // objectBoundingBox is returned local coordinates. 462 // The name objectBoundingBox is taken from the SVG 1.1 spec. 463 virtual FloatRect objectBoundingBox() const; 464 virtual FloatRect strokeBoundingBox() const; 465 466 // Returns the smallest rectangle enclosing all of the painted content 467 // respecting clipping, masking, filters, opacity, stroke-width and markers 468 virtual FloatRect repaintRectInLocalCoordinates() const; 469 470 // This only returns the transform="" value from the element 471 // most callsites want localToParentTransform() instead. 472 virtual AffineTransform localTransform() const; 473 474 // Returns the full transform mapping from local coordinates to local coords for the parent SVG renderer 475 // This includes any viewport transforms and x/y offsets as well as the transform="" value off the element. 476 virtual const AffineTransform& localToParentTransform() const; 477 478 // SVG uses FloatPoint precise hit testing, and passes the point in parent 479 // coordinates instead of in repaint container coordinates. Eventually the 480 // rest of the rendering tree will move to a similar model. 481 virtual bool nodeAtFloatPoint(const HitTestRequest&, HitTestResult&, const FloatPoint& pointInParent, HitTestAction); 482 483 virtual bool canHaveWhitespaceChildren() const 484 { 485 if (isTable() || isTableRow() || isTableSection() || isRenderTableCol() || isFrameSet() || isFlexibleBox() || isRenderGrid()) 486 return false; 487 return true; 488 } 489 490 bool isAnonymous() const { return m_bitfields.isAnonymous(); } 491 bool isAnonymousBlock() const 492 { 493 // This function is kept in sync with anonymous block creation conditions in 494 // RenderBlock::createAnonymousBlock(). This includes creating an anonymous 495 // RenderBlock having a BLOCK or BOX display. Other classes such as RenderTextFragment 496 // are not RenderBlocks and will return false. See https://bugs.webkit.org/show_bug.cgi?id=56709. 497 return isAnonymous() && (style()->display() == BLOCK || style()->display() == BOX) && style()->styleType() == NOPSEUDO && isRenderBlock() && !isListMarker() && !isRenderFlowThread() 498 && !isRenderFullScreen() 499 && !isRenderFullScreenPlaceholder(); 500 } 501 bool isAnonymousColumnsBlock() const { return style()->specifiesColumns() && isAnonymousBlock(); } 502 bool isAnonymousColumnSpanBlock() const { return style()->columnSpan() && isAnonymousBlock(); } 503 bool isElementContinuation() const { return node() && node()->renderer() != this; } 504 bool isInlineElementContinuation() const { return isElementContinuation() && isInline(); } 505 virtual RenderBoxModelObject* virtualContinuation() const { return 0; } 506 507 bool isFloating() const { return m_bitfields.floating(); } 508 509 bool isOutOfFlowPositioned() const { return m_bitfields.isOutOfFlowPositioned(); } // absolute or fixed positioning 510 bool isInFlowPositioned() const { return m_bitfields.isRelPositioned() || m_bitfields.isStickyPositioned(); } // relative or sticky positioning 511 bool isRelPositioned() const { return m_bitfields.isRelPositioned(); } // relative positioning 512 bool isStickyPositioned() const { return m_bitfields.isStickyPositioned(); } 513 bool isPositioned() const { return m_bitfields.isPositioned(); } 514 515 bool isText() const { return m_bitfields.isText(); } 516 bool isBox() const { return m_bitfields.isBox(); } 517 bool isInline() const { return m_bitfields.isInline(); } // inline object 518 bool isDragging() const { return m_bitfields.isDragging(); } 519 bool isReplaced() const { return m_bitfields.isReplaced(); } // a "replaced" element (see CSS) 520 bool isHorizontalWritingMode() const { return m_bitfields.horizontalWritingMode(); } 521 522 bool hasLayer() const { return m_bitfields.hasLayer(); } 523 524 enum BoxDecorationState { 525 NoBoxDecorations, 526 HasBoxDecorationsAndBackgroundObscurationStatusInvalid, 527 HasBoxDecorationsAndBackgroundIsKnownToBeObscured, 528 HasBoxDecorationsAndBackgroundMayBeVisible, 529 }; 530 bool hasBoxDecorations() const { return m_bitfields.boxDecorationState() != NoBoxDecorations; } 531 bool backgroundIsKnownToBeObscured(); 532 bool borderImageIsLoadedAndCanBeRendered() const; 533 bool mustRepaintBackgroundOrBorder() const; 534 bool hasBackground() const { return style()->hasBackground(); } 535 bool hasEntirelyFixedBackground() const; 536 537 bool needsLayout() const 538 { 539 return m_bitfields.selfNeedsLayout() || m_bitfields.normalChildNeedsLayout() || m_bitfields.posChildNeedsLayout() 540 || m_bitfields.needsSimplifiedNormalFlowLayout() || m_bitfields.needsPositionedMovementLayout(); 541 } 542 543 bool selfNeedsLayout() const { return m_bitfields.selfNeedsLayout(); } 544 bool needsPositionedMovementLayout() const { return m_bitfields.needsPositionedMovementLayout(); } 545 bool needsPositionedMovementLayoutOnly() const 546 { 547 return m_bitfields.needsPositionedMovementLayout() && !m_bitfields.selfNeedsLayout() && !m_bitfields.normalChildNeedsLayout() 548 && !m_bitfields.posChildNeedsLayout() && !m_bitfields.needsSimplifiedNormalFlowLayout(); 549 } 550 551 bool posChildNeedsLayout() const { return m_bitfields.posChildNeedsLayout(); } 552 bool needsSimplifiedNormalFlowLayout() const { return m_bitfields.needsSimplifiedNormalFlowLayout(); } 553 bool normalChildNeedsLayout() const { return m_bitfields.normalChildNeedsLayout(); } 554 555 bool preferredLogicalWidthsDirty() const { return m_bitfields.preferredLogicalWidthsDirty(); } 556 557 bool isSelectionBorder() const; 558 559 bool hasClip() const { return isOutOfFlowPositioned() && style()->hasClip(); } 560 bool hasOverflowClip() const { return m_bitfields.hasOverflowClip(); } 561 bool hasClipOrOverflowClip() const { return hasClip() || hasOverflowClip(); } 562 563 bool hasTransform() const { return m_bitfields.hasTransform(); } 564 bool hasMask() const { return style() && style()->hasMask(); } 565 bool hasClipPath() const { return style() && style()->clipPath(); } 566 bool hasHiddenBackface() const { return style() && style()->backfaceVisibility() == BackfaceVisibilityHidden; } 567 568 bool hasFilter() const { return style() && style()->hasFilter(); } 569 570 bool hasBlendMode() const; 571 572 inline bool preservesNewline() const; 573 574 // The pseudo element style can be cached or uncached. Use the cached method if the pseudo element doesn't respect 575 // any pseudo classes (and therefore has no concept of changing state). 576 RenderStyle* getCachedPseudoStyle(PseudoId, RenderStyle* parentStyle = 0) const; 577 PassRefPtr<RenderStyle> getUncachedPseudoStyle(const PseudoStyleRequest&, RenderStyle* parentStyle = 0, RenderStyle* ownStyle = 0) const; 578 579 virtual void updateDragState(bool dragOn); 580 581 RenderView* view() const { return document().renderView(); }; 582 FrameView* frameView() const { return document().view(); }; 583 584 // Returns true if this renderer is rooted, and optionally returns the hosting view (the root of the hierarchy). 585 bool isRooted(RenderView** = 0) const; 586 587 Node* node() const 588 { 589 return isAnonymous() ? 0 : m_node; 590 } 591 592 Node* nonPseudoNode() const 593 { 594 ASSERT(!LayoutIndicator::inLayout()); 595 return isPseudoElement() ? 0 : node(); 596 } 597 598 // FIXME: Why does RenderWidget need this? 599 void clearNode() { m_node = 0; } 600 601 // Returns the styled node that caused the generation of this renderer. 602 // This is the same as node() except for renderers of :before and :after 603 // pseudo elements for which their parent node is returned. 604 Node* generatingNode() const { return isPseudoElement() ? node()->parentOrShadowHostNode() : node(); } 605 606 Document& document() const { return m_node->document(); } 607 Frame* frame() const { return document().frame(); } 608 609 bool hasOutlineAnnotation() const; 610 bool hasOutline() const { return style()->hasOutline() || hasOutlineAnnotation(); } 611 612 // Returns the object containing this one. Can be different from parent for positioned elements. 613 // If repaintContainer and repaintContainerSkipped are not null, on return *repaintContainerSkipped 614 // is true if the renderer returned is an ancestor of repaintContainer. 615 RenderObject* container(const RenderLayerModelObject* repaintContainer = 0, bool* repaintContainerSkipped = 0) const; 616 617 virtual RenderObject* hoverAncestor() const; 618 619 Element* offsetParent() const; 620 621 void markContainingBlocksForLayout(bool scheduleRelayout = true, RenderObject* newRoot = 0, SubtreeLayoutScope* = 0); 622 void setNeedsLayout(MarkingBehavior = MarkContainingBlockChain, SubtreeLayoutScope* = 0); 623 void clearNeedsLayout(); 624 void setChildNeedsLayout(MarkingBehavior = MarkContainingBlockChain, SubtreeLayoutScope* = 0); 625 void setNeedsPositionedMovementLayout(); 626 void setNeedsSimplifiedNormalFlowLayout(); 627 void setPreferredLogicalWidthsDirty(MarkingBehavior = MarkContainingBlockChain); 628 void clearPreferredLogicalWidthsDirty(); 629 void invalidateContainerPreferredLogicalWidths(); 630 631 void setNeedsLayoutAndPrefWidthsRecalc() 632 { 633 setNeedsLayout(); 634 setPreferredLogicalWidthsDirty(); 635 } 636 637 void setPositionState(EPosition position) 638 { 639 ASSERT((position != AbsolutePosition && position != FixedPosition) || isBox()); 640 m_bitfields.setPositionedState(position); 641 } 642 void clearPositionedState() { m_bitfields.clearPositionedState(); } 643 644 void setFloating(bool isFloating) { m_bitfields.setFloating(isFloating); } 645 void setInline(bool isInline) { m_bitfields.setIsInline(isInline); } 646 647 void setHasBoxDecorations(bool); 648 void invalidateBackgroundObscurationStatus(); 649 virtual bool computeBackgroundIsKnownToBeObscured() { return false; } 650 651 void setIsText() { m_bitfields.setIsText(true); } 652 void setIsBox() { m_bitfields.setIsBox(true); } 653 void setReplaced(bool isReplaced) { m_bitfields.setIsReplaced(isReplaced); } 654 void setHorizontalWritingMode(bool hasHorizontalWritingMode) { m_bitfields.setHorizontalWritingMode(hasHorizontalWritingMode); } 655 void setHasOverflowClip(bool hasOverflowClip) { m_bitfields.setHasOverflowClip(hasOverflowClip); } 656 void setHasLayer(bool hasLayer) { m_bitfields.setHasLayer(hasLayer); } 657 void setHasTransform(bool hasTransform) { m_bitfields.setHasTransform(hasTransform); } 658 void setHasReflection(bool hasReflection) { m_bitfields.setHasReflection(hasReflection); } 659 660 void scheduleRelayout(); 661 662 void updateFillImages(const FillLayer*, const FillLayer*); 663 void updateImage(StyleImage*, StyleImage*); 664 void updateShapeImage(const ShapeValue*, const ShapeValue*); 665 666 virtual void paint(PaintInfo&, const LayoutPoint&); 667 668 // Recursive function that computes the size and position of this object and all its descendants. 669 virtual void layout(); 670 virtual void didLayout(ResourceLoadPriorityOptimizer&); 671 virtual void didScroll(ResourceLoadPriorityOptimizer&); 672 673 /* This function performs a layout only if one is needed. */ 674 void layoutIfNeeded() { if (needsLayout()) layout(); } 675 676 void forceLayout(); 677 void forceChildLayout(); 678 679 // True if we can abort layout, leaving a partially laid out tree. 680 virtual bool supportsPartialLayout() const { return false; } 681 682 // used for element state updates that cannot be fixed with a 683 // repaint and do not need a relayout 684 virtual void updateFromElement() { } 685 686 virtual void addAnnotatedRegions(Vector<AnnotatedRegionValue>&); 687 void collectAnnotatedRegions(Vector<AnnotatedRegionValue>&); 688 689 CompositingState compositingState() const; 690 691 bool hitTest(const HitTestRequest&, HitTestResult&, const HitTestLocation& locationInContainer, const LayoutPoint& accumulatedOffset, HitTestFilter = HitTestAll); 692 virtual void updateHitTestResult(HitTestResult&, const LayoutPoint&); 693 virtual bool nodeAtPoint(const HitTestRequest&, HitTestResult&, const HitTestLocation& locationInContainer, const LayoutPoint& accumulatedOffset, HitTestAction); 694 695 virtual PositionWithAffinity positionForPoint(const LayoutPoint&); 696 PositionWithAffinity createPositionWithAffinity(int offset, EAffinity); 697 PositionWithAffinity createPositionWithAffinity(const Position&); 698 699 virtual void dirtyLinesFromChangedChild(RenderObject*); 700 701 // Called to update a style that is allowed to trigger animations. 702 // FIXME: Right now this will typically be called only when updating happens from the DOM on explicit elements. 703 // We don't yet handle generated content animation such as first-letter or before/after (we'll worry about this later). 704 void setAnimatableStyle(PassRefPtr<RenderStyle>); 705 706 // Set the style of the object and update the state of the object accordingly. 707 void setStyle(PassRefPtr<RenderStyle>); 708 709 // Set the style of the object if it's generated content. 710 void setPseudoStyle(PassRefPtr<RenderStyle>); 711 712 // Updates only the local style ptr of the object. Does not update the state of the object, 713 // and so only should be called when the style is known not to have changed (or from setStyle). 714 void setStyleInternal(PassRefPtr<RenderStyle> style) { m_style = style; } 715 716 // returns the containing block level element for this element. 717 RenderBlock* containingBlock() const; 718 719 bool canContainFixedPositionObjects() const 720 { 721 return isRenderView() || (hasTransform() && isRenderBlock()) || isSVGForeignObject() || isOutOfFlowRenderFlowThread(); 722 } 723 bool canContainAbsolutePositionObjects() const 724 { 725 return isRenderView() || (hasTransform() && isRenderBlock()) || isSVGForeignObject(); 726 } 727 728 // Convert the given local point to absolute coordinates 729 // FIXME: Temporary. If UseTransforms is true, take transforms into account. Eventually localToAbsolute() will always be transform-aware. 730 FloatPoint localToAbsolute(const FloatPoint& localPoint = FloatPoint(), MapCoordinatesFlags = 0) const; 731 FloatPoint absoluteToLocal(const FloatPoint&, MapCoordinatesFlags = 0) const; 732 733 // Convert a local quad to absolute coordinates, taking transforms into account. 734 FloatQuad localToAbsoluteQuad(const FloatQuad& quad, MapCoordinatesFlags mode = 0, bool* wasFixed = 0) const 735 { 736 return localToContainerQuad(quad, 0, mode, wasFixed); 737 } 738 // Convert an absolute quad to local coordinates. 739 FloatQuad absoluteToLocalQuad(const FloatQuad&, MapCoordinatesFlags mode = 0) const; 740 741 // Convert a local quad into the coordinate system of container, taking transforms into account. 742 FloatQuad localToContainerQuad(const FloatQuad&, const RenderLayerModelObject* repaintContainer, MapCoordinatesFlags = 0, bool* wasFixed = 0) const; 743 FloatPoint localToContainerPoint(const FloatPoint&, const RenderLayerModelObject* repaintContainer, MapCoordinatesFlags = 0, bool* wasFixed = 0) const; 744 745 // Return the offset from the container() renderer (excluding transforms). In multi-column layout, 746 // different offsets apply at different points, so return the offset that applies to the given point. 747 virtual LayoutSize offsetFromContainer(RenderObject*, const LayoutPoint&, bool* offsetDependsOnPoint = 0) const; 748 // Return the offset from an object up the container() chain. Asserts that none of the intermediate objects have transforms. 749 LayoutSize offsetFromAncestorContainer(RenderObject*) const; 750 751 virtual void absoluteRects(Vector<IntRect>&, const LayoutPoint&) const { } 752 753 // FIXME: useTransforms should go away eventually 754 IntRect absoluteBoundingBoxRect(bool useTransform = true) const; 755 IntRect absoluteBoundingBoxRectIgnoringTransforms() const { return absoluteBoundingBoxRect(false); } 756 757 bool isContainedInParentBoundingBox() const; 758 759 // Build an array of quads in absolute coords for line boxes 760 virtual void absoluteQuads(Vector<FloatQuad>&, bool* /*wasFixed*/ = 0) const { } 761 762 virtual void absoluteFocusRingQuads(Vector<FloatQuad>&); 763 764 static FloatRect absoluteBoundingBoxRectForRange(const Range*); 765 766 // the rect that will be painted if this object is passed as the paintingRoot 767 LayoutRect paintingRootRect(LayoutRect& topLevelRect); 768 769 virtual LayoutUnit minPreferredLogicalWidth() const { return 0; } 770 virtual LayoutUnit maxPreferredLogicalWidth() const { return 0; } 771 772 RenderStyle* style() const { return m_style.get(); } 773 RenderStyle* firstLineStyle() const { return document().styleEngine()->usesFirstLineRules() ? cachedFirstLineStyle() : style(); } 774 RenderStyle* style(bool firstLine) const { return firstLine ? firstLineStyle() : style(); } 775 776 inline Color resolveColor(const RenderStyle* styleToUse, int colorProperty) const 777 { 778 return styleToUse->visitedDependentColor(colorProperty); 779 } 780 781 inline Color resolveColor(int colorProperty) const 782 { 783 return style()->visitedDependentColor(colorProperty); 784 } 785 786 inline Color resolveColor(int colorProperty, Color fallback) const 787 { 788 Color color = resolveColor(colorProperty); 789 return color.isValid() ? color : fallback; 790 } 791 792 inline Color resolveColor(Color color) const 793 { 794 return color; 795 } 796 797 // Used only by Element::pseudoStyleCacheIsInvalid to get a first line style based off of a 798 // given new style, without accessing the cache. 799 PassRefPtr<RenderStyle> uncachedFirstLineStyle(RenderStyle*) const; 800 801 // Anonymous blocks that are part of of a continuation chain will return their inline continuation's outline style instead. 802 // This is typically only relevant when repainting. 803 virtual RenderStyle* outlineStyleForRepaint() const { return style(); } 804 805 virtual CursorDirective getCursor(const LayoutPoint&, Cursor&) const; 806 807 void getTextDecorationColors(unsigned decorations, Color& underline, Color& overline, Color& linethrough, bool quirksMode = false, bool firstlineStyle = false); 808 809 // Return the RenderLayerModelObject in the container chain which is responsible for painting this object, or 0 810 // if painting is root-relative. This is the container that should be passed to the 'forRepaint' 811 // methods. 812 RenderLayerModelObject* containerForRepaint() const; 813 // Actually do the repaint of rect r for this object which has been computed in the coordinate space 814 // of repaintContainer. If repaintContainer is 0, repaint via the view. 815 void repaintUsingContainer(const RenderLayerModelObject* repaintContainer, const IntRect&) const; 816 817 // Repaint the entire object. Called when, e.g., the color of a border changes, or when a border 818 // style changes. 819 void repaint() const; 820 821 // Repaint a specific subrectangle within a given object. The rect |r| is in the object's coordinate space. 822 void repaintRectangle(const LayoutRect&) const; 823 824 // Repaint only if our old bounds and new bounds are different. The caller may pass in newBounds and newOutlineBox if they are known. 825 bool repaintAfterLayoutIfNeeded(const RenderLayerModelObject* repaintContainer, bool wasSelfLayout, 826 const LayoutRect& oldBounds, const LayoutRect& oldOutlineBox, const LayoutRect* newBoundsPtr = 0, const LayoutRect* newOutlineBoxPtr = 0); 827 828 virtual void repaintOverflow(); 829 830 bool checkForRepaintDuringLayout() const; 831 832 // Returns the rect that should be repainted whenever this object changes. The rect is in the view's 833 // coordinate space. This method deals with outlines and overflow. 834 LayoutRect absoluteClippedOverflowRect() const 835 { 836 return clippedOverflowRectForRepaint(0); 837 } 838 IntRect pixelSnappedAbsoluteClippedOverflowRect() const; 839 virtual LayoutRect clippedOverflowRectForRepaint(const RenderLayerModelObject* repaintContainer) const; 840 virtual LayoutRect rectWithOutlineForRepaint(const RenderLayerModelObject* repaintContainer, LayoutUnit outlineWidth) const; 841 virtual LayoutRect outlineBoundsForRepaint(const RenderLayerModelObject* /*repaintContainer*/, const RenderGeometryMap* = 0) const { return LayoutRect(); } 842 843 // Given a rect in the object's coordinate space, compute a rect suitable for repainting 844 // that rect in the coordinate space of repaintContainer. 845 virtual void computeRectForRepaint(const RenderLayerModelObject* repaintContainer, LayoutRect&, bool fixed = false) const; 846 virtual void computeFloatRectForRepaint(const RenderLayerModelObject* repaintContainer, FloatRect& repaintRect, bool fixed = false) const; 847 848 // If multiple-column layout results in applying an offset to the given point, add the same 849 // offset to the given size. 850 virtual void adjustForColumns(LayoutSize&, const LayoutPoint&) const { } 851 LayoutSize offsetForColumns(const LayoutPoint& point) const 852 { 853 LayoutSize offset; 854 adjustForColumns(offset, point); 855 return offset; 856 } 857 858 virtual unsigned int length() const { return 1; } 859 860 bool isFloatingOrOutOfFlowPositioned() const { return (isFloating() || isOutOfFlowPositioned()); } 861 862 bool isTransparent() const { return style()->opacity() < 1.0f; } 863 float opacity() const { return style()->opacity(); } 864 865 bool hasReflection() const { return m_bitfields.hasReflection(); } 866 867 // Applied as a "slop" to dirty rect checks during the outline painting phase's dirty-rect checks. 868 int maximalOutlineSize(PaintPhase) const; 869 870 enum SelectionState { 871 SelectionNone, // The object is not selected. 872 SelectionStart, // The object either contains the start of a selection run or is the start of a run 873 SelectionInside, // The object is fully encompassed by a selection run 874 SelectionEnd, // The object either contains the end of a selection run or is the end of a run 875 SelectionBoth // The object contains an entire run or is the sole selected object in that run 876 }; 877 878 // The current selection state for an object. For blocks, the state refers to the state of the leaf 879 // descendants (as described above in the SelectionState enum declaration). 880 SelectionState selectionState() const { return m_bitfields.selectionState(); } 881 virtual void setSelectionState(SelectionState state) { m_bitfields.setSelectionState(state); } 882 inline void setSelectionStateIfNeeded(SelectionState); 883 bool canUpdateSelectionOnRootLineBoxes(); 884 885 // A single rectangle that encompasses all of the selected objects within this object. Used to determine the tightest 886 // possible bounding box for the selection. 887 LayoutRect selectionRect(bool clipToVisibleContent = true) { return selectionRectForRepaint(0, clipToVisibleContent); } 888 virtual LayoutRect selectionRectForRepaint(const RenderLayerModelObject* /*repaintContainer*/, bool /*clipToVisibleContent*/ = true) { return LayoutRect(); } 889 890 virtual bool canBeSelectionLeaf() const { return false; } 891 bool hasSelectedChildren() const { return selectionState() != SelectionNone; } 892 893 bool isSelectable() const; 894 // Obtains the selection colors that should be used when painting a selection. 895 Color selectionBackgroundColor() const; 896 Color selectionForegroundColor() const; 897 Color selectionEmphasisMarkColor() const; 898 899 // Whether or not a given block needs to paint selection gaps. 900 virtual bool shouldPaintSelectionGaps() const { return false; } 901 902 /** 903 * Returns the local coordinates of the caret within this render object. 904 * @param caretOffset zero-based offset determining position within the render object. 905 * @param extraWidthToEndOfLine optional out arg to give extra width to end of line - 906 * useful for character range rect computations 907 */ 908 virtual LayoutRect localCaretRect(InlineBox*, int caretOffset, LayoutUnit* extraWidthToEndOfLine = 0); 909 910 // When performing a global document tear-down, the renderer of the document is cleared. We use this 911 // as a hook to detect the case of document destruction and don't waste time doing unnecessary work. 912 bool documentBeingDestroyed() const; 913 914 void destroyAndCleanupAnonymousWrappers(); 915 virtual void destroy(); 916 917 // Virtual function helpers for the deprecated Flexible Box Layout (display: -webkit-box). 918 virtual bool isDeprecatedFlexibleBox() const { return false; } 919 virtual bool isStretchingChildren() const { return false; } 920 921 // Virtual function helper for the new FlexibleBox Layout (display: -webkit-flex). 922 virtual bool isFlexibleBox() const { return false; } 923 924 bool isFlexibleBoxIncludingDeprecated() const 925 { 926 return isFlexibleBox() || isDeprecatedFlexibleBox(); 927 } 928 929 virtual bool isCombineText() const { return false; } 930 931 virtual int caretMinOffset() const; 932 virtual int caretMaxOffset() const; 933 934 virtual int previousOffset(int current) const; 935 virtual int previousOffsetForBackwardDeletion(int current) const; 936 virtual int nextOffset(int current) const; 937 938 virtual void imageChanged(ImageResource*, const IntRect* = 0); 939 virtual void imageChanged(WrappedImagePtr, const IntRect* = 0) { } 940 virtual bool willRenderImage(ImageResource*); 941 942 void selectionStartEnd(int& spos, int& epos) const; 943 944 void remove() { if (parent()) parent()->removeChild(this); } 945 946 AnimationController& animation() const; 947 948 bool isInert() const; 949 bool visibleToHitTestRequest(const HitTestRequest& request) const { return style()->visibility() == VISIBLE && (request.ignorePointerEventsNone() || style()->pointerEvents() != PE_NONE) && !isInert(); } 950 bool visibleToHitTesting() const { return style()->visibility() == VISIBLE && style()->pointerEvents() != PE_NONE && !isInert(); } 951 952 // Map points and quads through elements, potentially via 3d transforms. You should never need to call these directly; use 953 // localToAbsolute/absoluteToLocal methods instead. 954 virtual void mapLocalToContainer(const RenderLayerModelObject* repaintContainer, TransformState&, MapCoordinatesFlags = ApplyContainerFlip, bool* wasFixed = 0) const; 955 virtual void mapAbsoluteToLocalPoint(MapCoordinatesFlags, TransformState&) const; 956 957 // Pushes state onto RenderGeometryMap about how to map coordinates from this renderer to its container, or ancestorToStopAt (whichever is encountered first). 958 // Returns the renderer which was mapped to (container or ancestorToStopAt). 959 virtual const RenderObject* pushMappingToContainer(const RenderLayerModelObject* ancestorToStopAt, RenderGeometryMap&) const; 960 961 bool shouldUseTransformFromContainer(const RenderObject* container) const; 962 void getTransformFromContainer(const RenderObject* container, const LayoutSize& offsetInContainer, TransformationMatrix&) const; 963 964 bool createsGroup() const { return isTransparent() || hasMask() || hasFilter() || hasBlendMode(); } 965 966 virtual void addFocusRingRects(Vector<IntRect>&, const LayoutPoint& /* additionalOffset */, const RenderLayerModelObject* /* paintContainer */ = 0) { }; 967 968 // Compute a list of hit-test rectangles per layer rooted at this renderer. 969 virtual void computeLayerHitTestRects(LayerHitTestRects&) const; 970 971 LayoutRect absoluteOutlineBounds() const 972 { 973 return outlineBoundsForRepaint(0); 974 } 975 976 // Return the renderer whose background style is used to paint the root background. Should only be called on the renderer for which isRoot() is true. 977 RenderObject* rendererForRootBackground(); 978 979 RespectImageOrientationEnum shouldRespectImageOrientation() const; 980 981 bool isRelayoutBoundaryForInspector() const; 982 983 const LayoutRect& newRepaintRect() const { return m_newRepaintRect; } 984 void setNewRepaintRect(const LayoutRect& rect) { m_newRepaintRect = rect; } 985 986 const LayoutRect& oldRepaintRect() const { return m_oldRepaintRect; } 987 void setOldRepaintRect(const LayoutRect& rect) { m_oldRepaintRect = rect; } 988 989 bool shouldDoFullRepaintAfterLayout() const { return m_bitfields.shouldDoFullRepaintAfterLayout(); } 990 void setShouldDoFullRepaintAfterLayout(bool b) { m_bitfields.setShouldDoFullRepaintAfterLayout(b); } 991 bool shouldRepaintOverflowIfNeeded() const { return m_bitfields.shouldRepaintOverflowIfNeeded(); } 992 993 void clearRepaintRects() 994 { 995 setNewRepaintRect(LayoutRect()); 996 setOldRepaintRect(LayoutRect()); 997 998 setShouldDoFullRepaintAfterLayout(false); 999 setShouldRepaintOverflowIfNeeded(false); 1000 setLayoutDidGetCalled(false); 1001 } 1002 1003 // layoutDidGetCalled indicates whether this render object was re-laid-out 1004 // since the last call to setLayoutDidGetCalled(false) on this object. 1005 bool layoutDidGetCalled() { return m_bitfields.layoutDidGetCalled(); } 1006 void setLayoutDidGetCalled(bool b) { m_bitfields.setLayoutDidGetCalled(b); } 1007 1008 protected: 1009 inline bool layerCreationAllowedForSubtree() const; 1010 1011 // Overrides should call the superclass at the end 1012 virtual void styleWillChange(StyleDifference, const RenderStyle* newStyle); 1013 // Overrides should call the superclass at the start 1014 virtual void styleDidChange(StyleDifference, const RenderStyle* oldStyle); 1015 void propagateStyleToAnonymousChildren(bool blockChildrenOnly = false); 1016 1017 void drawLineForBoxSide(GraphicsContext*, int x1, int y1, int x2, int y2, BoxSide, 1018 Color, EBorderStyle, int adjbw1, int adjbw2, bool antialias = false); 1019 void drawDashedOrDottedBoxSide(GraphicsContext*, int x1, int y1, int x2, int y2, 1020 BoxSide, Color, int thickness, EBorderStyle, bool antialias); 1021 void drawDoubleBoxSide(GraphicsContext*, int x1, int y1, int x2, int y2, 1022 int length, BoxSide, Color, int thickness, int adjacentWidth1, int adjacentWidth2, bool antialias); 1023 void drawRidgeOrGrooveBoxSide(GraphicsContext*, int x1, int y1, int x2, int y2, 1024 BoxSide, Color, EBorderStyle, int adjacentWidth1, int adjacentWidth2, bool antialias); 1025 void drawSolidBoxSide(GraphicsContext*, int x1, int y1, int x2, int y2, 1026 BoxSide, Color, int adjacentWidth1, int adjacentWidth2, bool antialias); 1027 1028 void paintFocusRing(PaintInfo&, const LayoutPoint&, RenderStyle*); 1029 void paintOutline(PaintInfo&, const LayoutRect&); 1030 void addPDFURLRect(GraphicsContext*, const LayoutRect&); 1031 1032 virtual LayoutRect viewRect() const; 1033 1034 void adjustRectForOutlineAndShadow(LayoutRect&) const; 1035 1036 void clearLayoutRootIfNeeded() const; 1037 virtual void willBeDestroyed(); 1038 void postDestroy(); 1039 1040 virtual void insertedIntoTree(); 1041 virtual void willBeRemovedFromTree(); 1042 1043 void setDocumentForAnonymous(Document* document) { ASSERT(isAnonymous()); m_node = document; } 1044 1045 // Add hit-test rects for the render tree rooted at this node to the provided collection on a 1046 // per-RenderLayer basis. 1047 // currentLayer must be the enclosing layer, and layerOffset is the current offset within 1048 // this layer. Subclass implementations will add any offset for this renderer within it's 1049 // container, so callers should provide only the offset of the container within it's layer. 1050 // containerRect is a rect that has already been added for the currentLayer which is likely to 1051 // be a container for child elements. Any rect wholly contained by containerRect can be 1052 // skipped. 1053 virtual void addLayerHitTestRects(LayerHitTestRects&, const RenderLayer* currentLayer, const LayoutPoint& layerOffset, const LayoutRect& containerRect) const; 1054 1055 // Add hit-test rects for this renderer only to the provided list. layerOffset is the offset 1056 // of this renderer within the current layer that should be used for each result. 1057 virtual void computeSelfHitTestRects(Vector<LayoutRect>&, const LayoutPoint& layerOffset) const { }; 1058 1059 private: 1060 RenderBlock* containerForFixedPosition(const RenderLayerModelObject* repaintContainer = 0, bool* repaintContainerSkipped = 0) const; 1061 1062 RenderFlowThread* locateFlowThreadContainingBlock() const; 1063 void removeFromRenderFlowThread(); 1064 void removeFromRenderFlowThreadRecursive(RenderFlowThread*); 1065 1066 bool shouldRepaintForStyleDifference(StyleDifference) const; 1067 bool hasImmediateNonWhitespaceTextChildOrPropertiesDependentOnColor() const; 1068 1069 RenderStyle* cachedFirstLineStyle() const; 1070 StyleDifference adjustStyleDifference(StyleDifference, unsigned contextSensitiveProperties) const; 1071 1072 Color selectionColor(int colorProperty) const; 1073 1074 void removeShapeImageClient(ShapeValue*); 1075 1076 #ifndef NDEBUG 1077 void checkBlockPositionedObjectsNeedLayout(); 1078 void checkNotInPartialLayout(); 1079 #endif 1080 1081 RefPtr<RenderStyle> m_style; 1082 1083 Node* m_node; 1084 1085 RenderObject* m_parent; 1086 RenderObject* m_previous; 1087 RenderObject* m_next; 1088 1089 #ifndef NDEBUG 1090 unsigned m_hasAXObject : 1; 1091 unsigned m_setNeedsLayoutForbidden : 1; 1092 #endif 1093 1094 #define ADD_BOOLEAN_BITFIELD(name, Name) \ 1095 private:\ 1096 unsigned m_##name : 1;\ 1097 public:\ 1098 bool name() const { return m_##name; }\ 1099 void set##Name(bool name) { m_##name = name; }\ 1100 1101 class RenderObjectBitfields { 1102 enum PositionedState { 1103 IsStaticallyPositioned = 0, 1104 IsRelativelyPositioned = 1, 1105 IsOutOfFlowPositioned = 2, 1106 IsStickyPositioned = 3 1107 }; 1108 1109 public: 1110 RenderObjectBitfields(Node* node) 1111 : m_selfNeedsLayout(false) 1112 // FIXME: shouldDoFullRepaintAfterLayout is needed because we reset 1113 // the layout bits before repaint when doing repaintAfterLayout. 1114 // Holding the layout bits until after repaint would remove the need 1115 // for this flag. 1116 , m_shouldDoFullRepaintAfterLayout(false) 1117 , m_shouldRepaintOverflowIfNeeded(false) 1118 , m_needsPositionedMovementLayout(false) 1119 , m_normalChildNeedsLayout(false) 1120 , m_posChildNeedsLayout(false) 1121 , m_needsSimplifiedNormalFlowLayout(false) 1122 , m_preferredLogicalWidthsDirty(false) 1123 , m_floating(false) 1124 , m_isAnonymous(!node) 1125 , m_isText(false) 1126 , m_isBox(false) 1127 , m_isInline(true) 1128 , m_isReplaced(false) 1129 , m_horizontalWritingMode(true) 1130 , m_isDragging(false) 1131 , m_hasLayer(false) 1132 , m_hasOverflowClip(false) 1133 , m_hasTransform(false) 1134 , m_hasReflection(false) 1135 , m_hasCounterNodeMap(false) 1136 , m_everHadLayout(false) 1137 , m_ancestorLineBoxDirty(false) 1138 , m_childrenInline(false) 1139 , m_hasColumns(false) 1140 , m_layoutDidGetCalled(false) 1141 , m_positionedState(IsStaticallyPositioned) 1142 , m_selectionState(SelectionNone) 1143 , m_flowThreadState(NotInsideFlowThread) 1144 , m_boxDecorationState(NoBoxDecorations) 1145 { 1146 } 1147 1148 // 32 bits have been used in the first word, and 2 in the second. 1149 ADD_BOOLEAN_BITFIELD(selfNeedsLayout, SelfNeedsLayout); 1150 ADD_BOOLEAN_BITFIELD(shouldDoFullRepaintAfterLayout, ShouldDoFullRepaintAfterLayout); 1151 ADD_BOOLEAN_BITFIELD(shouldRepaintOverflowIfNeeded, ShouldRepaintOverflowIfNeeded); 1152 ADD_BOOLEAN_BITFIELD(needsPositionedMovementLayout, NeedsPositionedMovementLayout); 1153 ADD_BOOLEAN_BITFIELD(normalChildNeedsLayout, NormalChildNeedsLayout); 1154 ADD_BOOLEAN_BITFIELD(posChildNeedsLayout, PosChildNeedsLayout); 1155 ADD_BOOLEAN_BITFIELD(needsSimplifiedNormalFlowLayout, NeedsSimplifiedNormalFlowLayout); 1156 ADD_BOOLEAN_BITFIELD(preferredLogicalWidthsDirty, PreferredLogicalWidthsDirty); 1157 ADD_BOOLEAN_BITFIELD(floating, Floating); 1158 1159 ADD_BOOLEAN_BITFIELD(isAnonymous, IsAnonymous); 1160 ADD_BOOLEAN_BITFIELD(isText, IsText); 1161 ADD_BOOLEAN_BITFIELD(isBox, IsBox); 1162 ADD_BOOLEAN_BITFIELD(isInline, IsInline); 1163 ADD_BOOLEAN_BITFIELD(isReplaced, IsReplaced); 1164 ADD_BOOLEAN_BITFIELD(horizontalWritingMode, HorizontalWritingMode); 1165 ADD_BOOLEAN_BITFIELD(isDragging, IsDragging); 1166 1167 ADD_BOOLEAN_BITFIELD(hasLayer, HasLayer); 1168 ADD_BOOLEAN_BITFIELD(hasOverflowClip, HasOverflowClip); // Set in the case of overflow:auto/scroll/hidden 1169 ADD_BOOLEAN_BITFIELD(hasTransform, HasTransform); 1170 ADD_BOOLEAN_BITFIELD(hasReflection, HasReflection); 1171 1172 ADD_BOOLEAN_BITFIELD(hasCounterNodeMap, HasCounterNodeMap); 1173 ADD_BOOLEAN_BITFIELD(everHadLayout, EverHadLayout); 1174 ADD_BOOLEAN_BITFIELD(ancestorLineBoxDirty, AncestorLineBoxDirty); 1175 1176 // from RenderBlock 1177 ADD_BOOLEAN_BITFIELD(childrenInline, ChildrenInline); 1178 ADD_BOOLEAN_BITFIELD(hasColumns, HasColumns); 1179 1180 ADD_BOOLEAN_BITFIELD(layoutDidGetCalled, LayoutDidGetCalled); 1181 1182 private: 1183 unsigned m_positionedState : 2; // PositionedState 1184 unsigned m_selectionState : 3; // SelectionState 1185 unsigned m_flowThreadState : 2; // FlowThreadState 1186 unsigned m_boxDecorationState : 2; // BoxDecorationState 1187 1188 public: 1189 bool isOutOfFlowPositioned() const { return m_positionedState == IsOutOfFlowPositioned; } 1190 bool isRelPositioned() const { return m_positionedState == IsRelativelyPositioned; } 1191 bool isStickyPositioned() const { return m_positionedState == IsStickyPositioned; } 1192 bool isPositioned() const { return m_positionedState != IsStaticallyPositioned; } 1193 1194 void setPositionedState(int positionState) 1195 { 1196 // This mask maps FixedPosition and AbsolutePosition to IsOutOfFlowPositioned, saving one bit. 1197 m_positionedState = static_cast<PositionedState>(positionState & 0x3); 1198 } 1199 void clearPositionedState() { m_positionedState = StaticPosition; } 1200 1201 ALWAYS_INLINE SelectionState selectionState() const { return static_cast<SelectionState>(m_selectionState); } 1202 ALWAYS_INLINE void setSelectionState(SelectionState selectionState) { m_selectionState = selectionState; } 1203 1204 ALWAYS_INLINE FlowThreadState flowThreadState() const { return static_cast<FlowThreadState>(m_flowThreadState); } 1205 ALWAYS_INLINE void setFlowThreadState(FlowThreadState flowThreadState) { m_flowThreadState = flowThreadState; } 1206 1207 ALWAYS_INLINE BoxDecorationState boxDecorationState() const { return static_cast<BoxDecorationState>(m_boxDecorationState); } 1208 ALWAYS_INLINE void setBoxDecorationState(BoxDecorationState boxDecorationState) { m_boxDecorationState = boxDecorationState; } 1209 }; 1210 1211 #undef ADD_BOOLEAN_BITFIELD 1212 1213 RenderObjectBitfields m_bitfields; 1214 1215 void setSelfNeedsLayout(bool b) { m_bitfields.setSelfNeedsLayout(b); } 1216 void setNeedsPositionedMovementLayout(bool b) { m_bitfields.setNeedsPositionedMovementLayout(b); } 1217 void setNormalChildNeedsLayout(bool b) { m_bitfields.setNormalChildNeedsLayout(b); } 1218 void setPosChildNeedsLayout(bool b) { m_bitfields.setPosChildNeedsLayout(b); } 1219 void setNeedsSimplifiedNormalFlowLayout(bool b) { m_bitfields.setNeedsSimplifiedNormalFlowLayout(b); } 1220 void setIsDragging(bool b) { m_bitfields.setIsDragging(b); } 1221 void setEverHadLayout(bool b) { m_bitfields.setEverHadLayout(b); } 1222 void setShouldRepaintOverflowIfNeeded(bool b) { m_bitfields.setShouldRepaintOverflowIfNeeded(b); } 1223 1224 private: 1225 // Store state between styleWillChange and styleDidChange 1226 static bool s_affectsParentBlock; 1227 1228 LayoutRect m_oldRepaintRect; 1229 LayoutRect m_newRepaintRect; 1230 }; 1231 1232 inline bool RenderObject::documentBeingDestroyed() const 1233 { 1234 return !document().renderer(); 1235 } 1236 1237 inline bool RenderObject::isBeforeContent() const 1238 { 1239 if (style()->styleType() != BEFORE) 1240 return false; 1241 // Text nodes don't have their own styles, so ignore the style on a text node. 1242 if (isText() && !isBR()) 1243 return false; 1244 return true; 1245 } 1246 1247 inline bool RenderObject::isAfterContent() const 1248 { 1249 if (style()->styleType() != AFTER) 1250 return false; 1251 // Text nodes don't have their own styles, so ignore the style on a text node. 1252 if (isText() && !isBR()) 1253 return false; 1254 return true; 1255 } 1256 1257 inline bool RenderObject::isBeforeOrAfterContent() const 1258 { 1259 return isBeforeContent() || isAfterContent(); 1260 } 1261 1262 inline void RenderObject::setNeedsLayout(MarkingBehavior markParents, SubtreeLayoutScope* layouter) 1263 { 1264 #ifndef NDEBUG 1265 checkNotInPartialLayout(); 1266 #endif 1267 ASSERT(!isSetNeedsLayoutForbidden()); 1268 bool alreadyNeededLayout = m_bitfields.selfNeedsLayout(); 1269 setSelfNeedsLayout(true); 1270 if (!alreadyNeededLayout) { 1271 if (markParents == MarkContainingBlockChain && (!layouter || layouter->root() != this)) 1272 markContainingBlocksForLayout(true, 0, layouter); 1273 if (hasLayer()) 1274 setLayerNeedsFullRepaint(); 1275 } 1276 } 1277 1278 inline void RenderObject::clearNeedsLayout() 1279 { 1280 #ifndef NDEBUG 1281 checkNotInPartialLayout(); 1282 #endif 1283 setSelfNeedsLayout(false); 1284 setEverHadLayout(true); 1285 setPosChildNeedsLayout(false); 1286 setNeedsSimplifiedNormalFlowLayout(false); 1287 setNormalChildNeedsLayout(false); 1288 setNeedsPositionedMovementLayout(false); 1289 setAncestorLineBoxDirty(false); 1290 #ifndef NDEBUG 1291 checkBlockPositionedObjectsNeedLayout(); 1292 #endif 1293 } 1294 1295 inline void RenderObject::setChildNeedsLayout(MarkingBehavior markParents, SubtreeLayoutScope* layouter) 1296 { 1297 ASSERT(!isSetNeedsLayoutForbidden()); 1298 bool alreadyNeededLayout = normalChildNeedsLayout(); 1299 setNormalChildNeedsLayout(true); 1300 // FIXME: Replace MarkOnlyThis with the SubtreeLayoutScope code path and remove the MarkingBehavior argument entirely. 1301 if (!alreadyNeededLayout && markParents == MarkContainingBlockChain && (!layouter || layouter->root() != this)) 1302 markContainingBlocksForLayout(true, 0, layouter); 1303 } 1304 1305 inline void RenderObject::setNeedsPositionedMovementLayout() 1306 { 1307 bool alreadyNeededLayout = needsPositionedMovementLayout(); 1308 setNeedsPositionedMovementLayout(true); 1309 ASSERT(!isSetNeedsLayoutForbidden()); 1310 if (!alreadyNeededLayout) { 1311 markContainingBlocksForLayout(); 1312 if (hasLayer()) 1313 setLayerNeedsFullRepaintForPositionedMovementLayout(); 1314 } 1315 } 1316 1317 inline void RenderObject::setNeedsSimplifiedNormalFlowLayout() 1318 { 1319 bool alreadyNeededLayout = needsSimplifiedNormalFlowLayout(); 1320 setNeedsSimplifiedNormalFlowLayout(true); 1321 ASSERT(!isSetNeedsLayoutForbidden()); 1322 if (!alreadyNeededLayout) { 1323 markContainingBlocksForLayout(); 1324 if (hasLayer()) 1325 setLayerNeedsFullRepaint(); 1326 } 1327 } 1328 1329 inline bool RenderObject::preservesNewline() const 1330 { 1331 if (isSVGInlineText()) 1332 return false; 1333 1334 return style()->preserveNewline(); 1335 } 1336 1337 inline bool RenderObject::layerCreationAllowedForSubtree() const 1338 { 1339 RenderObject* parentRenderer = parent(); 1340 while (parentRenderer) { 1341 if (parentRenderer->isSVGHiddenContainer()) 1342 return false; 1343 parentRenderer = parentRenderer->parent(); 1344 } 1345 1346 return true; 1347 } 1348 1349 inline void RenderObject::setSelectionStateIfNeeded(SelectionState state) 1350 { 1351 if (selectionState() == state) 1352 return; 1353 1354 setSelectionState(state); 1355 } 1356 1357 inline void RenderObject::setHasBoxDecorations(bool b) 1358 { 1359 if (!b) { 1360 m_bitfields.setBoxDecorationState(NoBoxDecorations); 1361 return; 1362 } 1363 if (hasBoxDecorations()) 1364 return; 1365 m_bitfields.setBoxDecorationState(HasBoxDecorationsAndBackgroundObscurationStatusInvalid); 1366 } 1367 1368 inline void RenderObject::invalidateBackgroundObscurationStatus() 1369 { 1370 if (!hasBoxDecorations()) 1371 return; 1372 m_bitfields.setBoxDecorationState(HasBoxDecorationsAndBackgroundObscurationStatusInvalid); 1373 } 1374 1375 inline bool RenderObject::backgroundIsKnownToBeObscured() 1376 { 1377 if (m_bitfields.boxDecorationState() == HasBoxDecorationsAndBackgroundObscurationStatusInvalid) { 1378 BoxDecorationState boxDecorationState = computeBackgroundIsKnownToBeObscured() ? HasBoxDecorationsAndBackgroundIsKnownToBeObscured : HasBoxDecorationsAndBackgroundMayBeVisible; 1379 m_bitfields.setBoxDecorationState(boxDecorationState); 1380 } 1381 return m_bitfields.boxDecorationState() == HasBoxDecorationsAndBackgroundIsKnownToBeObscured; 1382 } 1383 1384 inline void makeMatrixRenderable(TransformationMatrix& matrix, bool has3DRendering) 1385 { 1386 if (!has3DRendering) 1387 matrix.makeAffine(); 1388 } 1389 1390 inline int adjustForAbsoluteZoom(int value, RenderObject* renderer) 1391 { 1392 return adjustForAbsoluteZoom(value, renderer->style()); 1393 } 1394 1395 inline LayoutUnit adjustLayoutUnitForAbsoluteZoom(LayoutUnit value, RenderObject& renderer) 1396 { 1397 ASSERT(renderer.style()); 1398 return adjustLayoutUnitForAbsoluteZoom(value, *renderer.style()); 1399 } 1400 1401 inline void adjustFloatQuadForAbsoluteZoom(FloatQuad& quad, RenderObject& renderer) 1402 { 1403 float zoom = renderer.style()->effectiveZoom(); 1404 if (zoom != 1) 1405 quad.scale(1 / zoom, 1 / zoom); 1406 } 1407 1408 inline void adjustFloatRectForAbsoluteZoom(FloatRect& rect, RenderObject& renderer) 1409 { 1410 float zoom = renderer.style()->effectiveZoom(); 1411 if (zoom != 1) 1412 rect.scale(1 / zoom, 1 / zoom); 1413 } 1414 1415 #define DEFINE_RENDER_OBJECT_TYPE_CASTS(thisType, predicate) \ 1416 DEFINE_TYPE_CASTS(thisType, RenderObject, object, object->predicate, object.predicate) 1417 1418 } // namespace WebCore 1419 1420 #ifndef NDEBUG 1421 // Outside the WebCore namespace for ease of invocation from gdb. 1422 void showTree(const WebCore::RenderObject*); 1423 void showLineTree(const WebCore::RenderObject*); 1424 void showRenderTree(const WebCore::RenderObject* object1); 1425 // We don't make object2 an optional parameter so that showRenderTree 1426 // can be called from gdb easily. 1427 void showRenderTree(const WebCore::RenderObject* object1, const WebCore::RenderObject* object2); 1428 1429 #endif 1430 1431 #endif // RenderObject_h 1432