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