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, 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 "CachedImageClient.h" 30#include "DocumentStyleSheetCollection.h" 31#include "Element.h" 32#include "FloatQuad.h" 33#include "Frame.h" 34#include "LayoutRect.h" 35#include "PaintPhase.h" 36#include "RenderStyle.h" 37#include "ScrollBehavior.h" 38#include "StyleInheritedData.h" 39#include "TextAffinity.h" 40#include <wtf/HashSet.h> 41 42namespace WebCore { 43 44class AffineTransform; 45class AnimationController; 46class Cursor; 47class Document; 48class HitTestLocation; 49class HitTestResult; 50class InlineBox; 51class Path; 52class Position; 53class PseudoStyleRequest; 54class RenderBoxModelObject; 55class RenderInline; 56class RenderBlock; 57class RenderElement; 58class RenderFlowThread; 59class RenderGeometryMap; 60class RenderLayer; 61class RenderLayerModelObject; 62class RenderNamedFlowThread; 63class RenderRegion; 64class RenderTheme; 65class SelectionSubtreeRoot; 66class TransformState; 67class VisiblePosition; 68#if PLATFORM(IOS) 69class SelectionRect; 70#endif 71 72struct PaintInfo; 73 74enum CursorDirective { 75 SetCursorBasedOnStyle, 76 SetCursor, 77 DoNotSetCursor 78}; 79 80enum HitTestFilter { 81 HitTestAll, 82 HitTestSelf, 83 HitTestDescendants 84}; 85 86enum HitTestAction { 87 HitTestBlockBackground, 88 HitTestChildBlockBackground, 89 HitTestChildBlockBackgrounds, 90 HitTestFloat, 91 HitTestForeground 92}; 93 94// Sides used when drawing borders and outlines. The values should run clockwise from top. 95enum BoxSide { 96 BSTop, 97 BSRight, 98 BSBottom, 99 BSLeft 100}; 101 102enum MarkingBehavior { 103 MarkOnlyThis, 104 MarkContainingBlockChain, 105}; 106 107enum MapCoordinatesMode { 108 IsFixed = 1 << 0, 109 UseTransforms = 1 << 1, 110 ApplyContainerFlip = 1 << 2 111}; 112typedef unsigned MapCoordinatesFlags; 113 114#if PLATFORM(IOS) 115const int caretWidth = 2; // This value should be kept in sync with UIKit. See <rdar://problem/15580601>. 116#else 117const int caretWidth = 1; 118#endif 119 120#if ENABLE(DASHBOARD_SUPPORT) 121struct AnnotatedRegionValue { 122 bool operator==(const AnnotatedRegionValue& o) const 123 { 124 return type == o.type && bounds == o.bounds && clip == o.clip && label == o.label; 125 } 126 bool operator!=(const AnnotatedRegionValue& o) const 127 { 128 return !(*this == o); 129 } 130 131 LayoutRect bounds; 132 String label; 133 LayoutRect clip; 134 int type; 135}; 136#endif 137 138#ifndef NDEBUG 139const int showTreeCharacterOffset = 39; 140#endif 141 142// Base class for all rendering tree objects. 143class RenderObject : public CachedImageClient { 144 WTF_MAKE_FAST_ALLOCATED; 145 friend class RenderBlock; 146 friend class RenderBlockFlow; 147 friend class RenderElement; 148 friend class RenderLayer; 149public: 150 // Anonymous objects should pass the document as their node, and they will then automatically be 151 // marked as anonymous in the constructor. 152 explicit RenderObject(Node&); 153 virtual ~RenderObject(); 154 155 RenderTheme& theme() const; 156 157 virtual const char* renderName() const = 0; 158 159 RenderElement* parent() const { return m_parent; } 160 bool isDescendantOf(const RenderObject*) const; 161 162 RenderObject* previousSibling() const { return m_previous; } 163 RenderObject* nextSibling() const { return m_next; } 164 165 // Use RenderElement versions instead. 166 virtual RenderObject* firstChildSlow() const { return nullptr; } 167 virtual RenderObject* lastChildSlow() const { return nullptr; } 168 169 RenderObject* nextInPreOrder() const; 170 RenderObject* nextInPreOrder(const RenderObject* stayWithin) const; 171 RenderObject* nextInPreOrderAfterChildren() const; 172 RenderObject* nextInPreOrderAfterChildren(const RenderObject* stayWithin) const; 173 RenderObject* previousInPreOrder() const; 174 RenderObject* previousInPreOrder(const RenderObject* stayWithin) const; 175 RenderObject* childAt(unsigned) const; 176 177 RenderObject* firstLeafChild() const; 178 RenderObject* lastLeafChild() const; 179 180#if ENABLE(IOS_TEXT_AUTOSIZING) 181 // Minimal distance between the block with fixed height and overflowing content and the text block to apply text autosizing. 182 // The greater this constant is the more potential places we have where autosizing is turned off. 183 // So it should be as low as possible. There are sites that break at 2. 184 static const int TextAutoSizingFixedHeightDepth = 3; 185 186 enum BlockContentHeightType { 187 FixedHeight, 188 FlexibleHeight, 189 OverflowHeight 190 }; 191 192 RenderObject* traverseNext(const RenderObject* stayWithin) const; 193 typedef bool (*TraverseNextInclusionFunction)(const RenderObject*); 194 typedef BlockContentHeightType (*HeightTypeTraverseNextInclusionFunction)(const RenderObject*); 195 196 RenderObject* traverseNext(const RenderObject* stayWithin, TraverseNextInclusionFunction) const; 197 RenderObject* traverseNext(const RenderObject* stayWithin, HeightTypeTraverseNextInclusionFunction, int& currentDepth, int& newFixedDepth) const; 198 199 void adjustComputedFontSizesOnBlocks(float size, float visibleWidth); 200 void resetTextAutosizing(); 201#endif 202 203 RenderLayer* enclosingLayer() const; 204 205 // Scrolling is a RenderBox concept, however some code just cares about recursively scrolling our enclosing ScrollableArea(s). 206 bool scrollRectToVisible(const LayoutRect&, const ScrollAlignment& alignX = ScrollAlignment::alignCenterIfNeeded, const ScrollAlignment& alignY = ScrollAlignment::alignCenterIfNeeded); 207 208 // Convenience function for getting to the nearest enclosing box of a RenderObject. 209 RenderBox& enclosingBox() const; 210 RenderBoxModelObject& enclosingBoxModelObject() const; 211 212 bool fixedPositionedWithNamedFlowContainingBlock() const; 213 214 enum ShouldUseFlowThreadCache { 215 UseFlowThreadCache, 216 SkipFlowThreadCache 217 }; 218 219 // Function to return our enclosing flow thread if we are contained inside one. This 220 // function follows the containing block chain. 221 RenderFlowThread* flowThreadContainingBlock(ShouldUseFlowThreadCache useCache = UseFlowThreadCache) const 222 { 223 if (flowThreadState() == NotInsideFlowThread) 224 return 0; 225 return (useCache == SkipFlowThreadCache) ? locateFlowThreadContainingBlockNoCache() : locateFlowThreadContainingBlock(); 226 } 227 228 RenderNamedFlowFragment* currentRenderNamedFlowFragment() const; 229 230 // FIXME: The meaning of this function is unclear. 231 virtual bool isEmpty() const { return !firstChildSlow(); } 232 233#ifndef NDEBUG 234 void setHasAXObject(bool flag) { m_hasAXObject = flag; } 235 bool hasAXObject() const { return m_hasAXObject; } 236 237 // Helper class forbidding calls to setNeedsLayout() during its lifetime. 238 class SetLayoutNeededForbiddenScope { 239 public: 240 explicit SetLayoutNeededForbiddenScope(RenderObject*, bool isForbidden = true); 241 ~SetLayoutNeededForbiddenScope(); 242 private: 243 RenderObject* m_renderObject; 244 bool m_preexistingForbidden; 245 }; 246#endif 247 248 // Obtains the nearest enclosing block (including this block) that contributes a first-line style to our inline 249 // children. 250 virtual RenderBlock* firstLineBlock() const; 251 252 // Called when an object that was floating or positioned becomes a normal flow object 253 // again. We have to make sure the render tree updates as needed to accommodate the new 254 // normal flow object. 255 void handleDynamicFloatPositionChange(); 256 void removeAnonymousWrappersForInlinesIfNecessary(); 257 258 // RenderObject tree manipulation 259 ////////////////////////////////////////// 260 virtual bool canHaveChildren() const = 0; 261 virtual bool canHaveGeneratedChildren() const; 262 virtual bool createsAnonymousWrapper() const { return false; } 263 ////////////////////////////////////////// 264 265protected: 266 ////////////////////////////////////////// 267 // Helper functions. Dangerous to use! 268 void setPreviousSibling(RenderObject* previous) { m_previous = previous; } 269 void setNextSibling(RenderObject* next) { m_next = next; } 270 void setParent(RenderElement*); 271 ////////////////////////////////////////// 272private: 273#ifndef NDEBUG 274 bool isSetNeedsLayoutForbidden() const { return m_setNeedsLayoutForbidden; } 275 void setNeedsLayoutIsForbidden(bool flag) { m_setNeedsLayoutForbidden = flag; } 276#endif 277 278 void addAbsoluteRectForLayer(LayoutRect& result); 279 void setLayerNeedsFullRepaint(); 280 void setLayerNeedsFullRepaintForPositionedMovementLayout(); 281 282public: 283#ifndef NDEBUG 284 void showTreeForThis() const; 285 void showRenderTreeForThis() const; 286 void showLineTreeForThis() const; 287 288 void showRenderObject() const; 289 // We don't make printedCharacters an optional parameter so that 290 // showRenderObject can be called from gdb easily. 291 void showRenderObject(int) const; 292 void showRenderTreeAndMark(const RenderObject* = 0, const char* = 0, const RenderObject* = 0, const char* = 0, int = 0) const; 293 void showRegionsInformation(int&) const; 294#endif 295 296public: 297 bool isPseudoElement() const { return node() && node()->isPseudoElement(); } 298 299 bool isRenderElement() const { return !isText(); } 300 bool isRenderReplaced() const; 301 bool isBoxModelObject() const; 302 bool isRenderBlock() const; 303 bool isRenderBlockFlow() const; 304 bool isRenderInline() const; 305 bool isRenderLayerModelObject() const; 306 307 virtual bool isCounter() const { return false; } 308 virtual bool isQuote() const { return false; } 309 310#if ENABLE(DETAILS_ELEMENT) 311 virtual bool isDetailsMarker() const { return false; } 312#endif 313 virtual bool isEmbeddedObject() const { return false; } 314 virtual bool isFieldset() const { return false; } 315 virtual bool isFileUploadControl() const { return false; } 316 virtual bool isFrame() const { return false; } 317 virtual bool isFrameSet() const { return false; } 318 virtual bool isImage() const { return false; } 319 virtual bool isInlineBlockOrInlineTable() const { return false; } 320 virtual bool isListBox() const { return false; } 321 virtual bool isListItem() const { return false; } 322 virtual bool isListMarker() const { return false; } 323 virtual bool isMedia() const { return false; } 324 virtual bool isMenuList() const { return false; } 325#if ENABLE(METER_ELEMENT) 326 virtual bool isMeter() const { return false; } 327#endif 328 virtual bool isSnapshottedPlugIn() const { return false; } 329 virtual bool isProgress() const { return false; } 330 virtual bool isRenderSVGBlock() const { return false; }; 331 virtual bool isRenderButton() const { return false; } 332 virtual bool isRenderIFrame() const { return false; } 333 virtual bool isRenderImage() const { return false; } 334 virtual bool isRenderRegion() const { return false; } 335 virtual bool isRenderNamedFlowFragment() const { return false; } 336 virtual bool isReplica() const { return false; } 337 338 virtual bool isRuby() const { return false; } 339 virtual bool isRubyBase() const { return false; } 340 virtual bool isRubyRun() const { return false; } 341 virtual bool isRubyText() const { return false; } 342 343 virtual bool isSlider() const { return false; } 344 virtual bool isSliderThumb() const { return false; } 345 virtual bool isTable() const { return false; } 346 virtual bool isTableCell() const { return false; } 347 virtual bool isRenderTableCol() const { return false; } 348 virtual bool isTableCaption() const { return false; } 349 virtual bool isTableRow() const { return false; } 350 virtual bool isTableSection() const { return false; } 351 virtual bool isTextControl() const { return false; } 352 virtual bool isTextArea() const { return false; } 353 virtual bool isTextField() const { return false; } 354 virtual bool isTextControlInnerBlock() const { return false; } 355 virtual bool isVideo() const { return false; } 356 virtual bool isWidget() const { return false; } 357 virtual bool isCanvas() const { return false; } 358#if ENABLE(FULLSCREEN_API) 359 virtual bool isRenderFullScreen() const { return false; } 360 virtual bool isRenderFullScreenPlaceholder() const { return false; } 361#endif 362#if ENABLE(CSS_GRID_LAYOUT) 363 virtual bool isRenderGrid() const { return false; } 364#endif 365 virtual bool isRenderFlowThread() const { return false; } 366 virtual bool isRenderNamedFlowThread() const { return false; } 367 bool isInFlowRenderFlowThread() const { return isRenderFlowThread() && !isOutOfFlowPositioned(); } 368 bool isOutOfFlowRenderFlowThread() const { return isRenderFlowThread() && isOutOfFlowPositioned(); } 369 370 virtual bool isMultiColumnBlockFlow() const { return false; } 371 virtual bool isRenderMultiColumnSet() const { return false; } 372 virtual bool isRenderMultiColumnFlowThread() const { return false; } 373 virtual bool isRenderMultiColumnSpannerPlaceholder() const { return false; } 374 375 virtual bool isRenderScrollbarPart() const { return false; } 376 377 bool isRoot() const { return document().documentElement() == &m_node; } 378 bool isBody() const { return node() && node()->hasTagName(HTMLNames::bodyTag); } 379 bool isHR() const { return node() && node()->hasTagName(HTMLNames::hrTag); } 380 bool isLegend() const; 381 382 bool isHTMLMarquee() const; 383 384 bool isTablePart() const { return isTableCell() || isRenderTableCol() || isTableCaption() || isTableRow() || isTableSection(); } 385 386 inline bool isBeforeContent() const; 387 inline bool isAfterContent() const; 388 inline bool isBeforeOrAfterContent() const; 389 static inline bool isBeforeContent(const RenderObject* obj) { return obj && obj->isBeforeContent(); } 390 static inline bool isAfterContent(const RenderObject* obj) { return obj && obj->isAfterContent(); } 391 static inline bool isBeforeOrAfterContent(const RenderObject* obj) { return obj && obj->isBeforeOrAfterContent(); } 392 393 bool hasCounterNodeMap() const { return m_bitfields.hasCounterNodeMap(); } 394 void setHasCounterNodeMap(bool hasCounterNodeMap) { m_bitfields.setHasCounterNodeMap(hasCounterNodeMap); } 395 bool everHadLayout() const { return m_bitfields.everHadLayout(); } 396 397 bool childrenInline() const { return m_bitfields.childrenInline(); } 398 void setChildrenInline(bool b) { m_bitfields.setChildrenInline(b); } 399 400 enum FlowThreadState { 401 NotInsideFlowThread = 0, 402 InsideOutOfFlowThread = 1, 403 InsideInFlowThread = 2, 404 }; 405 406 void setFlowThreadStateIncludingDescendants(FlowThreadState); 407 408 FlowThreadState flowThreadState() const { return m_bitfields.flowThreadState(); } 409 void setFlowThreadState(FlowThreadState state) { m_bitfields.setFlowThreadState(state); } 410 411 virtual bool requiresForcedStyleRecalcPropagation() const { return false; } 412 413#if ENABLE(MATHML) 414 virtual bool isRenderMathMLBlock() const { return false; } 415 virtual bool isRenderMathMLTable() const { return false; } 416 virtual bool isRenderMathMLOperator() const { return false; } 417 virtual bool isRenderMathMLRadicalOperator() const { return false; } 418 virtual bool isRenderMathMLRow() const { return false; } 419 virtual bool isRenderMathMLMath() const { return false; } 420 virtual bool isRenderMathMLFenced() const { return false; } 421 virtual bool isRenderMathMLFraction() const { return false; } 422 virtual bool isRenderMathMLRoot() const { return false; } 423 virtual bool isRenderMathMLRootWrapper() const { return false; } 424 virtual bool isRenderMathMLSpace() const { return false; } 425 virtual bool isRenderMathMLSquareRoot() const { return false; } 426 virtual bool isRenderMathMLScripts() const { return false; } 427 virtual bool isRenderMathMLScriptsWrapper() const { return false; } 428 virtual bool isRenderMathMLToken() const { return false; } 429 virtual bool isRenderMathMLUnderOver() const { return false; } 430#endif // ENABLE(MATHML) 431 432 // FIXME: Until all SVG renders can be subclasses of RenderSVGModelObject we have 433 // to add SVG renderer methods to RenderObject with an ASSERT_NOT_REACHED() default implementation. 434 virtual bool isRenderSVGModelObject() const { return false; } 435 virtual bool isSVGRoot() const { return false; } 436 virtual bool isSVGContainer() const { return false; } 437 virtual bool isSVGTransformableContainer() const { return false; } 438 virtual bool isSVGViewportContainer() const { return false; } 439 virtual bool isSVGGradientStop() const { return false; } 440 virtual bool isSVGHiddenContainer() const { return false; } 441 virtual bool isSVGPath() const { return false; } 442 virtual bool isSVGShape() const { return false; } 443 virtual bool isSVGText() const { return false; } 444 virtual bool isSVGTextPath() const { return false; } 445 virtual bool isSVGInline() const { return false; } 446 virtual bool isSVGInlineText() const { return false; } 447 virtual bool isSVGImage() const { return false; } 448 virtual bool isSVGForeignObject() const { return false; } 449 virtual bool isSVGResourceContainer() const { return false; } 450 virtual bool isSVGResourceFilter() const { return false; } 451 virtual bool isSVGResourceFilterPrimitive() const { return false; } 452 453 // FIXME: Those belong into a SVG specific base-class for all renderers (see above) 454 // Unfortunately we don't have such a class yet, because it's not possible for all renderers 455 // to inherit from RenderSVGObject -> RenderObject (some need RenderBlock inheritance for instance) 456 virtual void setNeedsTransformUpdate() { } 457 virtual void setNeedsBoundariesUpdate(); 458 virtual bool needsBoundariesUpdate() { return false; } 459 460 // Per SVG 1.1 objectBoundingBox ignores clipping, masking, filter effects, opacity and stroke-width. 461 // This is used for all computation of objectBoundingBox relative units and by SVGLocatable::getBBox(). 462 // NOTE: Markers are not specifically ignored here by SVG 1.1 spec, but we ignore them 463 // since stroke-width is ignored (and marker size can depend on stroke-width). 464 // objectBoundingBox is returned local coordinates. 465 // The name objectBoundingBox is taken from the SVG 1.1 spec. 466 virtual FloatRect objectBoundingBox() const; 467 virtual FloatRect strokeBoundingBox() const; 468 469 // Returns the smallest rectangle enclosing all of the painted content 470 // respecting clipping, masking, filters, opacity, stroke-width and markers 471 virtual FloatRect repaintRectInLocalCoordinates() const; 472 473 // This only returns the transform="" value from the element 474 // most callsites want localToParentTransform() instead. 475 virtual AffineTransform localTransform() const; 476 477 // Returns the full transform mapping from local coordinates to local coords for the parent SVG renderer 478 // This includes any viewport transforms and x/y offsets as well as the transform="" value off the element. 479 virtual const AffineTransform& localToParentTransform() const; 480 481 // SVG uses FloatPoint precise hit testing, and passes the point in parent 482 // coordinates instead of in repaint container coordinates. Eventually the 483 // rest of the rendering tree will move to a similar model. 484 virtual bool nodeAtFloatPoint(const HitTestRequest&, HitTestResult&, const FloatPoint& pointInParent, HitTestAction); 485 486 bool hasAspectRatio() const { return isReplaced() && (isImage() || isVideo() || isCanvas()); } 487 bool isAnonymous() const { return m_bitfields.isAnonymous(); } 488 bool isAnonymousBlock() const 489 { 490 // This function is kept in sync with anonymous block creation conditions in 491 // RenderBlock::createAnonymousBlock(). This includes creating an anonymous 492 // RenderBlock having a BLOCK or BOX display. Other classes such as RenderTextFragment 493 // are not RenderBlocks and will return false. See https://bugs.webkit.org/show_bug.cgi?id=56709. 494 return isAnonymous() && (style().display() == BLOCK || style().display() == BOX) && style().styleType() == NOPSEUDO && isRenderBlock() && !isListMarker() && !isRenderFlowThread() && !isRenderMultiColumnSet() && !isRenderView() 495#if ENABLE(FULLSCREEN_API) 496 && !isRenderFullScreen() 497 && !isRenderFullScreenPlaceholder() 498#endif 499#if ENABLE(MATHML) 500 && !isRenderMathMLBlock() 501#endif 502 ; 503 } 504 bool isElementContinuation() const { return node() && node()->renderer() != this; } 505 bool isInlineElementContinuation() const { return isElementContinuation() && isInline(); } 506 bool isBlockElementContinuation() const { return isElementContinuation() && !isInline(); } 507 virtual RenderBoxModelObject* virtualContinuation() const { return 0; } 508 509 bool isFloating() const { return m_bitfields.floating(); } 510 511 bool isOutOfFlowPositioned() const { return m_bitfields.isOutOfFlowPositioned(); } // absolute or fixed positioning 512 bool isInFlowPositioned() const { return m_bitfields.isRelPositioned() || m_bitfields.isStickyPositioned(); } // relative or sticky positioning 513 bool isRelPositioned() const { return m_bitfields.isRelPositioned(); } // relative positioning 514 bool isStickyPositioned() const { return m_bitfields.isStickyPositioned(); } 515 bool isPositioned() const { return m_bitfields.isPositioned(); } 516 517 bool isText() const { return !m_bitfields.isBox() && m_bitfields.isTextOrRenderView(); } 518 bool isLineBreak() const { return m_bitfields.isLineBreak(); } 519 bool isBR() const { return isLineBreak() && !isWBR(); } 520 bool isLineBreakOpportunity() const { return isLineBreak() && isWBR(); } 521 bool isTextOrLineBreak() const { return isText() || isLineBreak(); } 522 bool isBox() const { return m_bitfields.isBox(); } 523 bool isRenderView() const { return m_bitfields.isBox() && m_bitfields.isTextOrRenderView(); } 524 bool isInline() const { return m_bitfields.isInline(); } // inline object 525 bool isDragging() const { return m_bitfields.isDragging(); } 526 bool isReplaced() const { return m_bitfields.isReplaced(); } // a "replaced" element (see CSS) 527 bool isHorizontalWritingMode() const { return m_bitfields.horizontalWritingMode(); } 528 529 bool hasLayer() const { return m_bitfields.hasLayer(); } 530 531 enum BoxDecorationState { 532 NoBoxDecorations, 533 HasBoxDecorationsAndBackgroundObscurationStatusInvalid, 534 HasBoxDecorationsAndBackgroundIsKnownToBeObscured, 535 HasBoxDecorationsAndBackgroundMayBeVisible, 536 }; 537 bool hasBoxDecorations() const { return m_bitfields.boxDecorationState() != NoBoxDecorations; } 538 bool backgroundIsKnownToBeObscured(); 539 bool hasEntirelyFixedBackground() const; 540 541 bool needsLayout() const 542 { 543 return m_bitfields.needsLayout() || m_bitfields.normalChildNeedsLayout() || m_bitfields.posChildNeedsLayout() 544 || m_bitfields.needsSimplifiedNormalFlowLayout() || m_bitfields.needsPositionedMovementLayout(); 545 } 546 547 bool selfNeedsLayout() const { return m_bitfields.needsLayout(); } 548 bool needsPositionedMovementLayout() const { return m_bitfields.needsPositionedMovementLayout(); } 549 bool needsPositionedMovementLayoutOnly() const 550 { 551 return m_bitfields.needsPositionedMovementLayout() && !m_bitfields.needsLayout() && !m_bitfields.normalChildNeedsLayout() 552 && !m_bitfields.posChildNeedsLayout() && !m_bitfields.needsSimplifiedNormalFlowLayout(); 553 } 554 555 bool posChildNeedsLayout() const { return m_bitfields.posChildNeedsLayout(); } 556 bool needsSimplifiedNormalFlowLayout() const { return m_bitfields.needsSimplifiedNormalFlowLayout(); } 557 bool normalChildNeedsLayout() const { return m_bitfields.normalChildNeedsLayout(); } 558 559 bool preferredLogicalWidthsDirty() const { return m_bitfields.preferredLogicalWidthsDirty(); } 560 561 bool isSelectionBorder() const; 562 563 bool hasOverflowClip() const { return m_bitfields.hasOverflowClip(); } 564 565 bool hasTransform() const { return m_bitfields.hasTransform(); } 566 567 inline bool preservesNewline() const; 568 569 // The pseudo element style can be cached or uncached. Use the cached method if the pseudo element doesn't respect 570 // any pseudo classes (and therefore has no concept of changing state). 571 RenderStyle* getCachedPseudoStyle(PseudoId, RenderStyle* parentStyle = 0) const; 572 PassRefPtr<RenderStyle> getUncachedPseudoStyle(const PseudoStyleRequest&, RenderStyle* parentStyle = 0, RenderStyle* ownStyle = 0) const; 573 574 virtual void updateDragState(bool dragOn); 575 576 RenderView& view() const { return *document().renderView(); }; 577 578 // Returns true if this renderer is rooted, and optionally returns the hosting view (the root of the hierarchy). 579 bool isRooted(RenderView** = 0) const; 580 581 Node* node() const { return isAnonymous() ? 0 : &m_node; } 582 Node* nonPseudoNode() const { return isPseudoElement() ? 0 : node(); } 583 584 // Returns the styled node that caused the generation of this renderer. 585 // This is the same as node() except for renderers of :before and :after 586 // pseudo elements for which their parent node is returned. 587 Node* generatingNode() const { return isPseudoElement() ? generatingPseudoHostElement() : node(); } 588 589 Document& document() const { return m_node.document(); } 590 Frame& frame() const; // Defined in RenderView.h 591 592 bool hasOutlineAnnotation() const; 593 bool hasOutline() const { return style().hasOutline() || hasOutlineAnnotation(); } 594 595 // Returns the object containing this one. Can be different from parent for positioned elements. 596 // If repaintContainer and repaintContainerSkipped are not null, on return *repaintContainerSkipped 597 // is true if the renderer returned is an ancestor of repaintContainer. 598 RenderElement* container(const RenderLayerModelObject* repaintContainer = 0, bool* repaintContainerSkipped = 0) const; 599 600 RenderBoxModelObject* offsetParent() const; 601 602 void markContainingBlocksForLayout(bool scheduleRelayout = true, RenderElement* newRoot = 0); 603 void setNeedsLayout(MarkingBehavior = MarkContainingBlockChain); 604 void clearNeedsLayout(); 605 void setPreferredLogicalWidthsDirty(bool, MarkingBehavior = MarkContainingBlockChain); 606 void invalidateContainerPreferredLogicalWidths(); 607 608 void setNeedsLayoutAndPrefWidthsRecalc() 609 { 610 setNeedsLayout(); 611 setPreferredLogicalWidthsDirty(true); 612 } 613 614 void setPositionState(EPosition position) 615 { 616 ASSERT((position != AbsolutePosition && position != FixedPosition) || isBox()); 617 m_bitfields.setPositionedState(position); 618 } 619 void clearPositionedState() { m_bitfields.clearPositionedState(); } 620 621 void setFloating(bool b = true) { m_bitfields.setFloating(b); } 622 void setInline(bool b = true) { m_bitfields.setIsInline(b); } 623 624 void setHasBoxDecorations(bool = true); 625 void invalidateBackgroundObscurationStatus(); 626 virtual bool computeBackgroundIsKnownToBeObscured() { return false; } 627 628 void setIsText() { ASSERT(!isBox()); m_bitfields.setIsTextOrRenderView(true); } 629 void setIsLineBreak() { m_bitfields.setIsLineBreak(true); } 630 void setIsBox() { m_bitfields.setIsBox(true); } 631 void setIsRenderView() { ASSERT(isBox()); m_bitfields.setIsTextOrRenderView(true); } 632 void setReplaced(bool b = true) { m_bitfields.setIsReplaced(b); } 633 void setHorizontalWritingMode(bool b = true) { m_bitfields.setHorizontalWritingMode(b); } 634 void setHasOverflowClip(bool b = true) { m_bitfields.setHasOverflowClip(b); } 635 void setHasLayer(bool b = true) { m_bitfields.setHasLayer(b); } 636 void setHasTransform(bool b = true) { m_bitfields.setHasTransform(b); } 637 void setHasReflection(bool b = true) { m_bitfields.setHasReflection(b); } 638 639 // Hook so that RenderTextControl can return the line height of its inner renderer. 640 // For other renderers, the value is the same as lineHeight(false). 641 virtual int innerLineHeight() const; 642 643 // used for element state updates that cannot be fixed with a 644 // repaint and do not need a relayout 645 virtual void updateFromElement() { } 646 647#if ENABLE(DASHBOARD_SUPPORT) 648 virtual void addAnnotatedRegions(Vector<AnnotatedRegionValue>&); 649 void collectAnnotatedRegions(Vector<AnnotatedRegionValue>&); 650#endif 651 652 bool isComposited() const; 653 654 bool hitTest(const HitTestRequest&, HitTestResult&, const HitTestLocation& locationInContainer, const LayoutPoint& accumulatedOffset, HitTestFilter = HitTestAll); 655 virtual void updateHitTestResult(HitTestResult&, const LayoutPoint&); 656 virtual bool nodeAtPoint(const HitTestRequest&, HitTestResult&, const HitTestLocation& locationInContainer, const LayoutPoint& accumulatedOffset, HitTestAction); 657 658 virtual VisiblePosition positionForPoint(const LayoutPoint&, const RenderRegion*); 659 VisiblePosition createVisiblePosition(int offset, EAffinity) const; 660 VisiblePosition createVisiblePosition(const Position&) const; 661 662 // returns the containing block level element for this element. 663 RenderBlock* containingBlock() const; 664 665 bool canContainFixedPositionObjects() const 666 { 667 return isRenderView() || (hasTransform() && isRenderBlock()) 668 || isSVGForeignObject() 669 || isOutOfFlowRenderFlowThread(); 670 } 671 672 // Convert the given local point to absolute coordinates 673 // FIXME: Temporary. If UseTransforms is true, take transforms into account. Eventually localToAbsolute() will always be transform-aware. 674 FloatPoint localToAbsolute(const FloatPoint& localPoint = FloatPoint(), MapCoordinatesFlags = 0) const; 675 FloatPoint absoluteToLocal(const FloatPoint&, MapCoordinatesFlags = 0) const; 676 677 // Convert a local quad to absolute coordinates, taking transforms into account. 678 FloatQuad localToAbsoluteQuad(const FloatQuad& quad, MapCoordinatesFlags mode = 0, bool* wasFixed = 0) const 679 { 680 return localToContainerQuad(quad, 0, mode, wasFixed); 681 } 682 // Convert an absolute quad to local coordinates. 683 FloatQuad absoluteToLocalQuad(const FloatQuad&, MapCoordinatesFlags mode = 0) const; 684 685 // Convert a local quad into the coordinate system of container, taking transforms into account. 686 FloatQuad localToContainerQuad(const FloatQuad&, const RenderLayerModelObject* repaintContainer, MapCoordinatesFlags = 0, bool* wasFixed = 0) const; 687 FloatPoint localToContainerPoint(const FloatPoint&, const RenderLayerModelObject* repaintContainer, MapCoordinatesFlags = 0, bool* wasFixed = 0) const; 688 689 // Return the offset from the container() renderer (excluding transforms). In multi-column layout, 690 // different offsets apply at different points, so return the offset that applies to the given point. 691 virtual LayoutSize offsetFromContainer(RenderObject*, const LayoutPoint&, bool* offsetDependsOnPoint = 0) const; 692 // Return the offset from an object up the container() chain. Asserts that none of the intermediate objects have transforms. 693 LayoutSize offsetFromAncestorContainer(RenderObject*) const; 694 695#if PLATFORM(IOS) 696 virtual void collectSelectionRects(Vector<SelectionRect>&, unsigned startOffset = 0, unsigned endOffset = std::numeric_limits<unsigned>::max()); 697 virtual void absoluteQuadsForSelection(Vector<FloatQuad>& quads) const { absoluteQuads(quads); } 698#endif 699 700 virtual void absoluteRects(Vector<IntRect>&, const LayoutPoint&) const { } 701 702 // FIXME: useTransforms should go away eventually 703 IntRect absoluteBoundingBoxRect(bool useTransform = true) const; 704 IntRect absoluteBoundingBoxRectIgnoringTransforms() const { return absoluteBoundingBoxRect(false); } 705 706 // Build an array of quads in absolute coords for line boxes 707 virtual void absoluteQuads(Vector<FloatQuad>&, bool* /*wasFixed*/ = 0) const { } 708 709 virtual void absoluteFocusRingQuads(Vector<FloatQuad>&); 710 711 static FloatRect absoluteBoundingBoxRectForRange(const Range*); 712 713 // the rect that will be painted if this object is passed as the paintingRoot 714 LayoutRect paintingRootRect(LayoutRect& topLevelRect); 715 716 virtual LayoutUnit minPreferredLogicalWidth() const { return 0; } 717 virtual LayoutUnit maxPreferredLogicalWidth() const { return 0; } 718 719 RenderStyle& style() const; 720 RenderStyle& firstLineStyle() const; 721 722 // Anonymous blocks that are part of of a continuation chain will return their inline continuation's outline style instead. 723 // This is typically only relevant when repainting. 724 virtual const RenderStyle& outlineStyleForRepaint() const { return style(); } 725 726 virtual CursorDirective getCursor(const LayoutPoint&, Cursor&) const; 727 728 void getTextDecorationColors(int decorations, Color& underline, Color& overline, Color& linethrough, bool quirksMode = false, bool firstlineStyle = false); 729 730 // Return the RenderLayerModelObject in the container chain which is responsible for painting this object, or 0 731 // if painting is root-relative. This is the container that should be passed to the 'forRepaint' 732 // methods. 733 RenderLayerModelObject* containerForRepaint() const; 734 // Actually do the repaint of rect r for this object which has been computed in the coordinate space 735 // of repaintContainer. If repaintContainer is 0, repaint via the view. 736 void repaintUsingContainer(const RenderLayerModelObject* repaintContainer, const LayoutRect&, bool shouldClipToLayer = true) const; 737 738 // Repaint the entire object. Called when, e.g., the color of a border changes, or when a border 739 // style changes. 740 void repaint() const; 741 742 // Repaint a specific subrectangle within a given object. The rect |r| is in the object's coordinate space. 743 void repaintRectangle(const LayoutRect&, bool shouldClipToLayer = true) const; 744 745 // Repaint a slow repaint object, which, at this time, means we are repainting an object with background-attachment:fixed. 746 void repaintSlowRepaintObject() const; 747 748 bool checkForRepaintDuringLayout() const; 749 750 // Returns the rect that should be repainted whenever this object changes. The rect is in the view's 751 // coordinate space. This method deals with outlines and overflow. 752 LayoutRect absoluteClippedOverflowRect() const 753 { 754 return clippedOverflowRectForRepaint(0); 755 } 756 IntRect pixelSnappedAbsoluteClippedOverflowRect() const; 757 virtual LayoutRect clippedOverflowRectForRepaint(const RenderLayerModelObject* repaintContainer) const; 758 virtual LayoutRect rectWithOutlineForRepaint(const RenderLayerModelObject* repaintContainer, LayoutUnit outlineWidth) const; 759 virtual LayoutRect outlineBoundsForRepaint(const RenderLayerModelObject* /*repaintContainer*/, const RenderGeometryMap* = 0) const { return LayoutRect(); } 760 761 // Given a rect in the object's coordinate space, compute a rect suitable for repainting 762 // that rect in view coordinates. 763 void computeAbsoluteRepaintRect(LayoutRect& r, bool fixed = false) const 764 { 765 computeRectForRepaint(0, r, fixed); 766 } 767 // Given a rect in the object's coordinate space, compute a rect suitable for repainting 768 // that rect in the coordinate space of repaintContainer. 769 virtual void computeRectForRepaint(const RenderLayerModelObject* repaintContainer, LayoutRect&, bool fixed = false) const; 770 virtual void computeFloatRectForRepaint(const RenderLayerModelObject* repaintContainer, FloatRect& repaintRect, bool fixed = false) const; 771 772 virtual unsigned int length() const { return 1; } 773 774 bool isFloatingOrOutOfFlowPositioned() const { return (isFloating() || isOutOfFlowPositioned()); } 775 776 bool hasReflection() const { return m_bitfields.hasReflection(); } 777 778 // Applied as a "slop" to dirty rect checks during the outline painting phase's dirty-rect checks. 779 int maximalOutlineSize(PaintPhase) const; 780 781 enum SelectionState { 782 SelectionNone, // The object is not selected. 783 SelectionStart, // The object either contains the start of a selection run or is the start of a run 784 SelectionInside, // The object is fully encompassed by a selection run 785 SelectionEnd, // The object either contains the end of a selection run or is the end of a run 786 SelectionBoth // The object contains an entire run or is the sole selected object in that run 787 }; 788 789 // The current selection state for an object. For blocks, the state refers to the state of the leaf 790 // descendants (as described above in the SelectionState enum declaration). 791 SelectionState selectionState() const { return m_bitfields.selectionState(); } 792 virtual void setSelectionState(SelectionState state) { m_bitfields.setSelectionState(state); } 793 inline void setSelectionStateIfNeeded(SelectionState); 794 bool canUpdateSelectionOnRootLineBoxes(); 795 796 // A single rectangle that encompasses all of the selected objects within this object. Used to determine the tightest 797 // possible bounding box for the selection. 798 LayoutRect selectionRect(bool clipToVisibleContent = true) { return selectionRectForRepaint(0, clipToVisibleContent); } 799 virtual LayoutRect selectionRectForRepaint(const RenderLayerModelObject* /*repaintContainer*/, bool /*clipToVisibleContent*/ = true) { return LayoutRect(); } 800 801 virtual bool canBeSelectionLeaf() const { return false; } 802 bool hasSelectedChildren() const { return selectionState() != SelectionNone; } 803 804 // Obtains the selection colors that should be used when painting a selection. 805 Color selectionBackgroundColor() const; 806 Color selectionForegroundColor() const; 807 Color selectionEmphasisMarkColor() const; 808 809 // Whether or not a given block needs to paint selection gaps. 810 virtual bool shouldPaintSelectionGaps() const { return false; } 811 812 /** 813 * Returns the local coordinates of the caret within this render object. 814 * @param caretOffset zero-based offset determining position within the render object. 815 * @param extraWidthToEndOfLine optional out arg to give extra width to end of line - 816 * useful for character range rect computations 817 */ 818 virtual LayoutRect localCaretRect(InlineBox*, int caretOffset, LayoutUnit* extraWidthToEndOfLine = 0); 819 820 // When performing a global document tear-down, the renderer of the document is cleared. We use this 821 // as a hook to detect the case of document destruction and don't waste time doing unnecessary work. 822 bool documentBeingDestroyed() const; 823 824 void destroyAndCleanupAnonymousWrappers(); 825 void destroy(); 826 827 // Virtual function helpers for the deprecated Flexible Box Layout (display: -webkit-box). 828 virtual bool isDeprecatedFlexibleBox() const { return false; } 829 virtual bool isStretchingChildren() const { return false; } 830 831 // Virtual function helper for the new FlexibleBox Layout (display: -webkit-flex). 832 virtual bool isFlexibleBox() const { return false; } 833 834 bool isFlexibleBoxIncludingDeprecated() const 835 { 836 return isFlexibleBox() || isDeprecatedFlexibleBox(); 837 } 838 839 virtual bool isCombineText() const { return false; } 840 841 virtual int caretMinOffset() const; 842 virtual int caretMaxOffset() const; 843 844 virtual int previousOffset(int current) const; 845 virtual int previousOffsetForBackwardDeletion(int current) const; 846 virtual int nextOffset(int current) const; 847 848 virtual void imageChanged(CachedImage*, const IntRect* = 0) override; 849 virtual void imageChanged(WrappedImagePtr, const IntRect* = 0) { } 850 851 SelectionSubtreeRoot& selectionRoot() const; 852 void selectionStartEnd(int& spos, int& epos) const; 853 854 void removeFromParent(); 855 856 AnimationController& animation() const; 857 858 // Map points and quads through elements, potentially via 3d transforms. You should never need to call these directly; use 859 // localToAbsolute/absoluteToLocal methods instead. 860 virtual void mapLocalToContainer(const RenderLayerModelObject* repaintContainer, TransformState&, MapCoordinatesFlags = ApplyContainerFlip, bool* wasFixed = 0) const; 861 virtual void mapAbsoluteToLocalPoint(MapCoordinatesFlags, TransformState&) const; 862 863 // Pushes state onto RenderGeometryMap about how to map coordinates from this renderer to its container, or ancestorToStopAt (whichever is encountered first). 864 // Returns the renderer which was mapped to (container or ancestorToStopAt). 865 virtual const RenderObject* pushMappingToContainer(const RenderLayerModelObject* ancestorToStopAt, RenderGeometryMap&) const; 866 867 bool shouldUseTransformFromContainer(const RenderObject* container) const; 868 void getTransformFromContainer(const RenderObject* container, const LayoutSize& offsetInContainer, TransformationMatrix&) const; 869 870 virtual void addFocusRingRects(Vector<IntRect>&, const LayoutPoint& /* additionalOffset */, const RenderLayerModelObject* /* paintContainer */ = 0) { }; 871 872 LayoutRect absoluteOutlineBounds() const 873 { 874 return outlineBoundsForRepaint(0); 875 } 876 877 RespectImageOrientationEnum shouldRespectImageOrientation() const; 878 879 void drawLineForBoxSide(GraphicsContext*, float x1, float y1, float x2, float y2, BoxSide, Color, EBorderStyle, float adjbw1, float adjbw2, bool antialias = false) const; 880protected: 881 void paintFocusRing(PaintInfo&, const LayoutPoint&, RenderStyle*); 882 void paintOutline(PaintInfo&, const LayoutRect&); 883 void addPDFURLRect(PaintInfo&, const LayoutPoint&); 884 Node& nodeForNonAnonymous() const { ASSERT(!isAnonymous()); return m_node; } 885 886 void adjustRectForOutlineAndShadow(LayoutRect&) const; 887 888 void clearLayoutRootIfNeeded() const; 889 virtual void willBeDestroyed(); 890 891 virtual void insertedIntoTree(); 892 virtual void willBeRemovedFromTree(); 893 894 void setNeedsPositionedMovementLayoutBit(bool b) { m_bitfields.setNeedsPositionedMovementLayout(b); } 895 void setNormalChildNeedsLayoutBit(bool b) { m_bitfields.setNormalChildNeedsLayout(b); } 896 void setPosChildNeedsLayoutBit(bool b) { m_bitfields.setPosChildNeedsLayout(b); } 897 void setNeedsSimplifiedNormalFlowLayoutBit(bool b) { m_bitfields.setNeedsSimplifiedNormalFlowLayout(b); } 898 899private: 900 RenderFlowThread* locateFlowThreadContainingBlock() const; 901 RenderFlowThread* locateFlowThreadContainingBlockNoCache() const; 902 903 void removeFromRenderFlowThread(); 904 void removeFromRenderFlowThreadRecursive(RenderFlowThread*); 905 906 Color selectionColor(int colorProperty) const; 907 PassRefPtr<RenderStyle> selectionPseudoStyle() const; 908 909 Node* generatingPseudoHostElement() const; 910 911 virtual bool isWBR() const { ASSERT_NOT_REACHED(); return false; } 912 913#ifndef NDEBUG 914 void checkBlockPositionedObjectsNeedLayout(); 915#endif 916 917 Node& m_node; 918 919 RenderElement* m_parent; 920 RenderObject* m_previous; 921 RenderObject* m_next; 922 923#ifndef NDEBUG 924 bool m_hasAXObject : 1; 925 bool m_setNeedsLayoutForbidden : 1; 926#endif 927 928#define ADD_BOOLEAN_BITFIELD(name, Name) \ 929 private:\ 930 unsigned m_##name : 1;\ 931 public:\ 932 bool name() const { return m_##name; }\ 933 void set##Name(bool name) { m_##name = name; }\ 934 935 class RenderObjectBitfields { 936 enum PositionedState { 937 IsStaticallyPositioned = 0, 938 IsRelativelyPositioned = 1, 939 IsOutOfFlowPositioned = 2, 940 IsStickyPositioned = 3 941 }; 942 943 public: 944 RenderObjectBitfields(const Node& node) 945 : m_needsLayout(false) 946 , m_needsPositionedMovementLayout(false) 947 , m_normalChildNeedsLayout(false) 948 , m_posChildNeedsLayout(false) 949 , m_needsSimplifiedNormalFlowLayout(false) 950 , m_preferredLogicalWidthsDirty(false) 951 , m_floating(false) 952 , m_isAnonymous(node.isDocumentNode()) 953 , m_isTextOrRenderView(false) 954 , m_isBox(false) 955 , m_isInline(true) 956 , m_isReplaced(false) 957 , m_isLineBreak(false) 958 , m_horizontalWritingMode(true) 959 , m_isDragging(false) 960 , m_hasLayer(false) 961 , m_hasOverflowClip(false) 962 , m_hasTransform(false) 963 , m_hasReflection(false) 964 , m_hasCounterNodeMap(false) 965 , m_everHadLayout(false) 966 , m_childrenInline(false) 967 , m_positionedState(IsStaticallyPositioned) 968 , m_selectionState(SelectionNone) 969 , m_flowThreadState(NotInsideFlowThread) 970 , m_boxDecorationState(NoBoxDecorations) 971 { 972 } 973 974 // 32 bits have been used here. There are no bits available. 975 ADD_BOOLEAN_BITFIELD(needsLayout, NeedsLayout); 976 ADD_BOOLEAN_BITFIELD(needsPositionedMovementLayout, NeedsPositionedMovementLayout); 977 ADD_BOOLEAN_BITFIELD(normalChildNeedsLayout, NormalChildNeedsLayout); 978 ADD_BOOLEAN_BITFIELD(posChildNeedsLayout, PosChildNeedsLayout); 979 ADD_BOOLEAN_BITFIELD(needsSimplifiedNormalFlowLayout, NeedsSimplifiedNormalFlowLayout); 980 ADD_BOOLEAN_BITFIELD(preferredLogicalWidthsDirty, PreferredLogicalWidthsDirty); 981 ADD_BOOLEAN_BITFIELD(floating, Floating); 982 983 ADD_BOOLEAN_BITFIELD(isAnonymous, IsAnonymous); 984 ADD_BOOLEAN_BITFIELD(isTextOrRenderView, IsTextOrRenderView); 985 ADD_BOOLEAN_BITFIELD(isBox, IsBox); 986 ADD_BOOLEAN_BITFIELD(isInline, IsInline); 987 ADD_BOOLEAN_BITFIELD(isReplaced, IsReplaced); 988 ADD_BOOLEAN_BITFIELD(isLineBreak, IsLineBreak); 989 ADD_BOOLEAN_BITFIELD(horizontalWritingMode, HorizontalWritingMode); 990 ADD_BOOLEAN_BITFIELD(isDragging, IsDragging); 991 992 ADD_BOOLEAN_BITFIELD(hasLayer, HasLayer); 993 ADD_BOOLEAN_BITFIELD(hasOverflowClip, HasOverflowClip); // Set in the case of overflow:auto/scroll/hidden 994 ADD_BOOLEAN_BITFIELD(hasTransform, HasTransform); 995 ADD_BOOLEAN_BITFIELD(hasReflection, HasReflection); 996 997 ADD_BOOLEAN_BITFIELD(hasCounterNodeMap, HasCounterNodeMap); 998 ADD_BOOLEAN_BITFIELD(everHadLayout, EverHadLayout); 999 1000 // from RenderBlock 1001 ADD_BOOLEAN_BITFIELD(childrenInline, ChildrenInline); 1002 1003 private: 1004 unsigned m_positionedState : 2; // PositionedState 1005 unsigned m_selectionState : 3; // SelectionState 1006 unsigned m_flowThreadState : 2; // FlowThreadState 1007 unsigned m_boxDecorationState : 2; // BoxDecorationState 1008 1009 public: 1010 bool isOutOfFlowPositioned() const { return m_positionedState == IsOutOfFlowPositioned; } 1011 bool isRelPositioned() const { return m_positionedState == IsRelativelyPositioned; } 1012 bool isStickyPositioned() const { return m_positionedState == IsStickyPositioned; } 1013 bool isPositioned() const { return m_positionedState != IsStaticallyPositioned; } 1014 1015 void setPositionedState(int positionState) 1016 { 1017 // This mask maps FixedPosition and AbsolutePosition to IsOutOfFlowPositioned, saving one bit. 1018 m_positionedState = static_cast<PositionedState>(positionState & 0x3); 1019 } 1020 void clearPositionedState() { m_positionedState = StaticPosition; } 1021 1022 ALWAYS_INLINE SelectionState selectionState() const { return static_cast<SelectionState>(m_selectionState); } 1023 ALWAYS_INLINE void setSelectionState(SelectionState selectionState) { m_selectionState = selectionState; } 1024 1025 ALWAYS_INLINE FlowThreadState flowThreadState() const { return static_cast<FlowThreadState>(m_flowThreadState); } 1026 ALWAYS_INLINE void setFlowThreadState(FlowThreadState flowThreadState) { m_flowThreadState = flowThreadState; } 1027 1028 ALWAYS_INLINE BoxDecorationState boxDecorationState() const { return static_cast<BoxDecorationState>(m_boxDecorationState); } 1029 ALWAYS_INLINE void setBoxDecorationState(BoxDecorationState boxDecorationState) { m_boxDecorationState = boxDecorationState; } 1030 }; 1031 1032#undef ADD_BOOLEAN_BITFIELD 1033 1034 RenderObjectBitfields m_bitfields; 1035 1036 void setIsDragging(bool b) { m_bitfields.setIsDragging(b); } 1037 void setEverHadLayout(bool b) { m_bitfields.setEverHadLayout(b); } 1038}; 1039 1040template <typename Type> bool isRendererOfType(const RenderObject&); 1041template <> inline bool isRendererOfType<const RenderObject>(const RenderObject&) { return true; } 1042 1043inline Frame& RenderObject::frame() const 1044{ 1045 return *document().frame(); 1046} 1047 1048inline AnimationController& RenderObject::animation() const 1049{ 1050 return frame().animation(); 1051} 1052 1053inline bool RenderObject::documentBeingDestroyed() const 1054{ 1055 return document().renderTreeBeingDestroyed(); 1056} 1057 1058inline bool RenderObject::isBeforeContent() const 1059{ 1060 // Text nodes don't have their own styles, so ignore the style on a text node. 1061 if (isText()) 1062 return false; 1063 if (style().styleType() != BEFORE) 1064 return false; 1065 return true; 1066} 1067 1068inline bool RenderObject::isAfterContent() const 1069{ 1070 // Text nodes don't have their own styles, so ignore the style on a text node. 1071 if (isText()) 1072 return false; 1073 if (style().styleType() != AFTER) 1074 return false; 1075 return true; 1076} 1077 1078inline bool RenderObject::isBeforeOrAfterContent() const 1079{ 1080 return isBeforeContent() || isAfterContent(); 1081} 1082 1083inline void RenderObject::setNeedsLayout(MarkingBehavior markParents) 1084{ 1085 ASSERT(!isSetNeedsLayoutForbidden()); 1086 if (m_bitfields.needsLayout()) 1087 return; 1088 m_bitfields.setNeedsLayout(true); 1089 if (markParents == MarkContainingBlockChain) 1090 markContainingBlocksForLayout(); 1091 if (hasLayer()) 1092 setLayerNeedsFullRepaint(); 1093} 1094 1095inline bool RenderObject::preservesNewline() const 1096{ 1097 if (isSVGInlineText()) 1098 return false; 1099 1100 return style().preserveNewline(); 1101} 1102 1103inline void RenderObject::setSelectionStateIfNeeded(SelectionState state) 1104{ 1105 if (selectionState() == state) 1106 return; 1107 1108 setSelectionState(state); 1109} 1110 1111inline void RenderObject::setHasBoxDecorations(bool b) 1112{ 1113 if (!b) { 1114 m_bitfields.setBoxDecorationState(NoBoxDecorations); 1115 return; 1116 } 1117 if (hasBoxDecorations()) 1118 return; 1119 m_bitfields.setBoxDecorationState(HasBoxDecorationsAndBackgroundObscurationStatusInvalid); 1120} 1121 1122inline void RenderObject::invalidateBackgroundObscurationStatus() 1123{ 1124 if (!hasBoxDecorations()) 1125 return; 1126 m_bitfields.setBoxDecorationState(HasBoxDecorationsAndBackgroundObscurationStatusInvalid); 1127} 1128 1129inline bool RenderObject::backgroundIsKnownToBeObscured() 1130{ 1131 if (m_bitfields.boxDecorationState() == HasBoxDecorationsAndBackgroundObscurationStatusInvalid) { 1132 BoxDecorationState boxDecorationState = computeBackgroundIsKnownToBeObscured() ? HasBoxDecorationsAndBackgroundIsKnownToBeObscured : HasBoxDecorationsAndBackgroundMayBeVisible; 1133 m_bitfields.setBoxDecorationState(boxDecorationState); 1134 } 1135 return m_bitfields.boxDecorationState() == HasBoxDecorationsAndBackgroundIsKnownToBeObscured; 1136} 1137 1138#define RENDER_OBJECT_TYPE_CASTS(ToValueTypeName, predicate) \ 1139 template <> inline bool isRendererOfType<const ToValueTypeName>(const RenderObject& renderer) { return renderer.predicate; } \ 1140 TYPE_CASTS_BASE(ToValueTypeName, RenderObject, renderer, isRendererOfType<const ToValueTypeName>(*renderer), isRendererOfType<const ToValueTypeName>(renderer)) 1141 1142} // namespace WebCore 1143 1144#ifndef NDEBUG 1145// Outside the WebCore namespace for ease of invocation from gdb. 1146void showTree(const WebCore::RenderObject*); 1147void showLineTree(const WebCore::RenderObject*); 1148void showRenderTree(const WebCore::RenderObject* object1); 1149// We don't make object2 an optional parameter so that showRenderTree 1150// can be called from gdb easily. 1151void showRenderTree(const WebCore::RenderObject* object1, const WebCore::RenderObject* object2); 1152#endif 1153 1154#endif // RenderObject_h 1155