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