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