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