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.
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.
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.
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.
26 #ifndef RenderObject_h
27 #define RenderObject_h
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/PaintPhase.h"
35 #include "core/rendering/RenderObjectChildList.h"
36 #include "core/rendering/ScrollAlignment.h"
37 #include "core/rendering/SubtreeLayoutScope.h"
38 #include "core/rendering/style/RenderStyle.h"
39 #include "core/rendering/style/StyleInheritedData.h"
40 #include "platform/geometry/FloatQuad.h"
41 #include "platform/geometry/LayoutRect.h"
42 #include "platform/transforms/TransformationMatrix.h"
46 class AffineTransform;
49 class HitTestLocation;
55 class PseudoStyleRequest;
56 class RenderBoxModelObject;
59 class RenderFlowThread;
60 class RenderGeometryMap;
62 class RenderLayerModelObject;
63 class RenderSVGResourceContainer;
67 class ResourceLoadPriorityOptimizer;
72 enum CursorDirective {
73 SetCursorBasedOnStyle,
85 HitTestBlockBackground,
86 HitTestChildBlockBackground,
87 HitTestChildBlockBackgrounds,
92 // Sides used when drawing borders and outlines. The values should run clockwise from top.
100 enum MarkingBehavior {
102 MarkContainingBlockChain,
105 enum MapCoordinatesMode {
107 UseTransforms = 1 << 1,
108 ApplyContainerFlip = 1 << 2,
109 TraverseDocumentBoundaries = 1 << 3,
111 typedef unsigned MapCoordinatesFlags;
113 const int caretWidth = 1;
115 struct AnnotatedRegionValue {
116 bool operator==(const AnnotatedRegionValue& o) const
118 return draggable == o.draggable && bounds == o.bounds;
125 typedef WTF::HashMap<const RenderLayer*, Vector<LayoutRect> > LayerHitTestRects;
128 const int showTreeCharacterOffset = 39;
131 // Base class for all rendering tree objects.
132 class RenderObject : public ImageResourceClient {
133 friend class RenderBlock;
134 friend class RenderBlockFlow;
135 friend class RenderLayer; // For setParent.
136 friend class RenderLayerReflectionInfo; // For setParent
137 friend class RenderLayerScrollableArea; // For setParent.
138 friend class RenderObjectChildList;
140 // Anonymous objects should pass the document as their node, and they will then automatically be
141 // marked as anonymous in the constructor.
142 explicit RenderObject(Node*);
143 virtual ~RenderObject();
145 virtual const char* renderName() const = 0;
147 String debugName() const;
149 RenderObject* parent() const { return m_parent; }
150 bool isDescendantOf(const RenderObject*) const;
152 RenderObject* previousSibling() const { return m_previous; }
153 RenderObject* nextSibling() const { return m_next; }
155 // FIXME: These should be renamed slowFirstChild, slowLastChild, etc.
156 // to discourage their use. The virtualChildren() call inside these
157 // can be slow for hot code paths.
158 // Currently, some subclasses like RenderBlock, override these NON-virtual
159 // functions to make these fast when we already have a more specific pointer type.
160 RenderObject* firstChild() const
162 if (const RenderObjectChildList* children = virtualChildren())
163 return children->firstChild();
166 RenderObject* lastChild() const
168 if (const RenderObjectChildList* children = virtualChildren())
169 return children->lastChild();
173 virtual RenderObjectChildList* virtualChildren() { return 0; }
174 virtual const RenderObjectChildList* virtualChildren() const { return 0; }
176 RenderObject* nextInPreOrder() const;
177 RenderObject* nextInPreOrder(const RenderObject* stayWithin) const;
178 RenderObject* nextInPreOrderAfterChildren() const;
179 RenderObject* nextInPreOrderAfterChildren(const RenderObject* stayWithin) const;
180 RenderObject* previousInPreOrder() const;
181 RenderObject* previousInPreOrder(const RenderObject* stayWithin) const;
182 RenderObject* childAt(unsigned) const;
184 RenderObject* lastLeafChild() const;
186 // The following six functions are used when the render tree hierarchy changes to make sure layers get
187 // properly added and removed. Since containership can be implemented by any subclass, and since a hierarchy
188 // can contain a mixture of boxes and other object types, these functions need to be in the base class.
189 RenderLayer* enclosingLayer() const;
190 void addLayers(RenderLayer* parentLayer);
191 void removeLayers(RenderLayer* parentLayer);
192 void moveLayers(RenderLayer* oldParent, RenderLayer* newParent);
193 RenderLayer* findNextLayer(RenderLayer* parentLayer, RenderObject* startPoint, bool checkParent = true);
195 // Scrolling is a RenderBox concept, however some code just cares about recursively scrolling our enclosing ScrollableArea(s).
196 bool scrollRectToVisible(const LayoutRect&, const ScrollAlignment& alignX = ScrollAlignment::alignCenterIfNeeded, const ScrollAlignment& alignY = ScrollAlignment::alignCenterIfNeeded);
198 // Convenience function for getting to the nearest enclosing box of a RenderObject.
199 RenderBox* enclosingBox() const;
200 RenderBoxModelObject* enclosingBoxModelObject() const;
202 RenderBox* enclosingScrollableBox() const;
204 // Function to return our enclosing flow thread if we are contained inside one. This
205 // function follows the containing block chain.
206 RenderFlowThread* flowThreadContainingBlock() const
208 if (flowThreadState() == NotInsideFlowThread)
210 return locateFlowThreadContainingBlock();
213 virtual bool isEmpty() const { return firstChild() == 0; }
216 void setHasAXObject(bool flag) { m_hasAXObject = flag; }
217 bool hasAXObject() const { return m_hasAXObject; }
219 // Helper class forbidding calls to setNeedsLayout() during its lifetime.
220 class SetLayoutNeededForbiddenScope {
222 explicit SetLayoutNeededForbiddenScope(RenderObject*);
223 ~SetLayoutNeededForbiddenScope();
225 RenderObject* m_renderObject;
226 bool m_preexistingForbidden;
229 void assertRendererLaidOut() const
232 showRenderTreeForThis();
233 ASSERT_WITH_SECURITY_IMPLICATION(!needsLayout());
236 void assertSubtreeIsLaidOut() const
238 for (const RenderObject* renderer = this; renderer; renderer = renderer->nextInPreOrder())
239 renderer->assertRendererLaidOut();
244 // Obtains the nearest enclosing block (including this block) that contributes a first-line style to our inline
246 virtual RenderBlock* firstLineBlock() const;
248 // Called when an object that was floating or positioned becomes a normal flow object
249 // again. We have to make sure the render tree updates as needed to accommodate the new
250 // normal flow object.
251 void handleDynamicFloatPositionChange();
253 // RenderObject tree manipulation
254 //////////////////////////////////////////
255 virtual bool canHaveChildren() const { return virtualChildren(); }
256 virtual bool canHaveGeneratedChildren() const;
257 virtual bool isChildAllowed(RenderObject*, RenderStyle*) const { return true; }
258 virtual void addChild(RenderObject* newChild, RenderObject* beforeChild = 0);
259 virtual void addChildIgnoringContinuation(RenderObject* newChild, RenderObject* beforeChild = 0) { return addChild(newChild, beforeChild); }
260 virtual void removeChild(RenderObject*);
261 virtual bool createsAnonymousWrapper() const { return false; }
262 //////////////////////////////////////////
265 //////////////////////////////////////////
266 // Helper functions. Dangerous to use!
267 void setPreviousSibling(RenderObject* previous) { m_previous = previous; }
268 void setNextSibling(RenderObject* next) { m_next = next; }
269 void setParent(RenderObject* parent)
273 // Only update if our flow thread state is different from our new parent and if we're not a RenderFlowThread.
274 // A RenderFlowThread is always considered to be inside itself, so it never has to change its state
275 // in response to parent changes.
276 FlowThreadState newState = parent ? parent->flowThreadState() : NotInsideFlowThread;
277 if (newState != flowThreadState() && !isRenderFlowThread())
278 setFlowThreadStateIncludingDescendants(newState);
281 //////////////////////////////////////////
284 bool isSetNeedsLayoutForbidden() const { return m_setNeedsLayoutForbidden; }
285 void setNeedsLayoutIsForbidden(bool flag) { m_setNeedsLayoutForbidden = flag; }
288 void addAbsoluteRectForLayer(LayoutRect& result);
289 void setLayerNeedsFullRepaint();
290 void setLayerNeedsFullRepaintForPositionedMovementLayout();
291 bool requiresAnonymousTableWrappers(const RenderObject*) const;
295 void showTreeForThis() const;
296 void showRenderTreeForThis() const;
297 void showLineTreeForThis() const;
299 void showRenderObject() const;
300 // We don't make printedCharacters an optional parameter so that
301 // showRenderObject can be called from gdb easily.
302 void showRenderObject(int printedCharacters) const;
303 void showRenderTreeAndMark(const RenderObject* markedObject1 = 0, const char* markedLabel1 = 0, const RenderObject* markedObject2 = 0, const char* markedLabel2 = 0, int depth = 0) const;
306 static RenderObject* createObject(Element*, RenderStyle*);
308 // RenderObjects are allocated out of the rendering partition.
309 void* operator new(size_t);
310 void operator delete(void*);
313 bool isPseudoElement() const { return node() && node()->isPseudoElement(); }
315 virtual bool isBR() const { return false; }
316 virtual bool isBoxModelObject() const { return false; }
317 virtual bool isCounter() const { return false; }
318 virtual bool isQuote() const { return false; }
320 virtual bool isDetailsMarker() const { return false; }
321 virtual bool isEmbeddedObject() const { return false; }
322 virtual bool isFieldset() const { return false; }
323 virtual bool isFileUploadControl() const { return false; }
324 virtual bool isFrame() const { return false; }
325 virtual bool isFrameSet() const { return false; }
326 virtual bool isImage() const { return false; }
327 virtual bool isInlineBlockOrInlineTable() const { return false; }
328 virtual bool isLayerModelObject() const { return false; }
329 virtual bool isListBox() const { return false; }
330 virtual bool isListItem() const { return false; }
331 virtual bool isListMarker() const { return false; }
332 virtual bool isMarquee() const { return false; }
333 virtual bool isMedia() const { return false; }
334 virtual bool isMenuList() const { return false; }
335 virtual bool isMeter() const { return false; }
336 virtual bool isProgress() const { return false; }
337 virtual bool isRenderBlock() const { return false; }
338 virtual bool isRenderBlockFlow() const { return false; }
339 virtual bool isRenderButton() const { return false; }
340 virtual bool isRenderIFrame() const { return false; }
341 virtual bool isRenderImage() const { return false; }
342 virtual bool isRenderInline() const { return false; }
343 virtual bool isRenderPart() const { return false; }
344 virtual bool isRenderRegion() const { return false; }
345 virtual bool isRenderView() const { return false; }
346 virtual bool isReplica() const { return false; }
348 virtual bool isRuby() const { return false; }
349 virtual bool isRubyBase() const { return false; }
350 virtual bool isRubyRun() const { return false; }
351 virtual bool isRubyText() const { return false; }
353 virtual bool isSlider() const { return false; }
354 virtual bool isSliderThumb() const { return false; }
355 virtual bool isTable() const { return false; }
356 virtual bool isTableCell() const { return false; }
357 virtual bool isRenderTableCol() const { return false; }
358 virtual bool isTableCaption() const { return false; }
359 virtual bool isTableRow() const { return false; }
360 virtual bool isTableSection() const { return false; }
361 virtual bool isTextControl() const { return false; }
362 virtual bool isTextArea() const { return false; }
363 virtual bool isTextField() const { return false; }
364 virtual bool isVideo() const { return false; }
365 virtual bool isWidget() const { return false; }
366 virtual bool isCanvas() const { return false; }
367 virtual bool isRenderFullScreen() const { return false; }
368 virtual bool isRenderFullScreenPlaceholder() const { return false; }
370 virtual bool isRenderGrid() const { return false; }
372 virtual bool isRenderFlowThread() const { return false; }
373 bool isInFlowRenderFlowThread() const { return isRenderFlowThread() && !isOutOfFlowPositioned(); }
374 bool isOutOfFlowRenderFlowThread() const { return isRenderFlowThread() && isOutOfFlowPositioned(); }
376 virtual bool isRenderMultiColumnBlock() const { return false; }
377 virtual bool isRenderMultiColumnSet() const { return false; }
379 virtual bool isRenderScrollbarPart() const { return false; }
381 bool isRoot() const { return document().documentElement() == m_node; }
384 bool isLegend() const;
386 bool isTablePart() const { return isTableCell() || isRenderTableCol() || isTableCaption() || isTableRow() || isTableSection(); }
388 inline bool isBeforeContent() const;
389 inline bool isAfterContent() const;
390 inline bool isBeforeOrAfterContent() const;
391 static inline bool isAfterContent(const RenderObject* obj) { return obj && obj->isAfterContent(); }
393 bool hasCounterNodeMap() const { return m_bitfields.hasCounterNodeMap(); }
394 void setHasCounterNodeMap(bool hasCounterNodeMap) { m_bitfields.setHasCounterNodeMap(hasCounterNodeMap); }
395 bool everHadLayout() const { return m_bitfields.everHadLayout(); }
397 bool childrenInline() const { return m_bitfields.childrenInline(); }
398 void setChildrenInline(bool b) { m_bitfields.setChildrenInline(b); }
399 bool hasColumns() const { return m_bitfields.hasColumns(); }
400 void setHasColumns(bool b = true) { m_bitfields.setHasColumns(b); }
402 bool ancestorLineBoxDirty() const { return m_bitfields.ancestorLineBoxDirty(); }
403 void setAncestorLineBoxDirty(bool value = true)
405 m_bitfields.setAncestorLineBoxDirty(value);
410 enum FlowThreadState {
411 NotInsideFlowThread = 0,
412 InsideOutOfFlowThread = 1,
413 InsideInFlowThread = 2,
416 void setFlowThreadStateIncludingDescendants(FlowThreadState);
418 FlowThreadState flowThreadState() const { return m_bitfields.flowThreadState(); }
419 void setFlowThreadState(FlowThreadState state) { m_bitfields.setFlowThreadState(state); }
421 // FIXME: Until all SVG renders can be subclasses of RenderSVGModelObject we have
422 // to add SVG renderer methods to RenderObject with an ASSERT_NOT_REACHED() default implementation.
423 virtual bool isSVG() const { return false; }
424 virtual bool isSVGRoot() const { return false; }
425 virtual bool isSVGContainer() const { return false; }
426 virtual bool isSVGTransformableContainer() const { return false; }
427 virtual bool isSVGViewportContainer() const { return false; }
428 virtual bool isSVGGradientStop() const { return false; }
429 virtual bool isSVGHiddenContainer() const { return false; }
430 virtual bool isSVGPath() const { return false; }
431 virtual bool isSVGShape() const { return false; }
432 virtual bool isSVGText() const { return false; }
433 virtual bool isSVGTextPath() const { return false; }
434 virtual bool isSVGInline() const { return false; }
435 virtual bool isSVGInlineText() const { return false; }
436 virtual bool isSVGImage() const { return false; }
437 virtual bool isSVGForeignObject() const { return false; }
438 virtual bool isSVGResourceContainer() const { return false; }
439 virtual bool isSVGResourceFilter() const { return false; }
440 virtual bool isSVGResourceFilterPrimitive() const { return false; }
442 // FIXME: Those belong into a SVG specific base-class for all renderers (see above)
443 // Unfortunately we don't have such a class yet, because it's not possible for all renderers
444 // to inherit from RenderSVGObject -> RenderObject (some need RenderBlock inheritance for instance)
445 virtual void setNeedsTransformUpdate() { }
446 virtual void setNeedsBoundariesUpdate();
448 // Per SVG 1.1 objectBoundingBox ignores clipping, masking, filter effects, opacity and stroke-width.
449 // This is used for all computation of objectBoundingBox relative units and by SVGLocatable::getBBox().
450 // NOTE: Markers are not specifically ignored here by SVG 1.1 spec, but we ignore them
451 // since stroke-width is ignored (and marker size can depend on stroke-width).
452 // objectBoundingBox is returned local coordinates.
453 // The name objectBoundingBox is taken from the SVG 1.1 spec.
454 virtual FloatRect objectBoundingBox() const;
455 virtual FloatRect strokeBoundingBox() const;
457 // Returns the smallest rectangle enclosing all of the painted content
458 // respecting clipping, masking, filters, opacity, stroke-width and markers
459 virtual FloatRect repaintRectInLocalCoordinates() const;
461 // This only returns the transform="" value from the element
462 // most callsites want localToParentTransform() instead.
463 virtual AffineTransform localTransform() const;
465 // Returns the full transform mapping from local coordinates to local coords for the parent SVG renderer
466 // This includes any viewport transforms and x/y offsets as well as the transform="" value off the element.
467 virtual const AffineTransform& localToParentTransform() const;
469 // SVG uses FloatPoint precise hit testing, and passes the point in parent
470 // coordinates instead of in repaint container coordinates. Eventually the
471 // rest of the rendering tree will move to a similar model.
472 virtual bool nodeAtFloatPoint(const HitTestRequest&, HitTestResult&, const FloatPoint& pointInParent, HitTestAction);
474 virtual bool canHaveWhitespaceChildren() const
476 if (isTable() || isTableRow() || isTableSection() || isRenderTableCol() || isFrameSet() || isFlexibleBox() || isRenderGrid())
481 bool isAnonymous() const { return m_bitfields.isAnonymous(); }
482 bool isAnonymousBlock() const
484 // This function is kept in sync with anonymous block creation conditions in
485 // RenderBlock::createAnonymousBlock(). This includes creating an anonymous
486 // RenderBlock having a BLOCK or BOX display. Other classes such as RenderTextFragment
487 // are not RenderBlocks and will return false. See https://bugs.webkit.org/show_bug.cgi?id=56709.
488 return isAnonymous() && (style()->display() == BLOCK || style()->display() == BOX) && style()->styleType() == NOPSEUDO && isRenderBlock() && !isListMarker() && !isRenderFlowThread()
489 && !isRenderFullScreen()
490 && !isRenderFullScreenPlaceholder();
492 bool isAnonymousColumnsBlock() const { return style()->specifiesColumns() && isAnonymousBlock(); }
493 bool isAnonymousColumnSpanBlock() const { return style()->columnSpan() && isAnonymousBlock(); }
494 bool isElementContinuation() const { return node() && node()->renderer() != this; }
495 bool isInlineElementContinuation() const { return isElementContinuation() && isInline(); }
496 virtual RenderBoxModelObject* virtualContinuation() const { return 0; }
498 bool isFloating() const { return m_bitfields.floating(); }
500 bool isOutOfFlowPositioned() const { return m_bitfields.isOutOfFlowPositioned(); } // absolute or fixed positioning
501 bool isInFlowPositioned() const { return m_bitfields.isRelPositioned() || m_bitfields.isStickyPositioned(); } // relative or sticky positioning
502 bool isRelPositioned() const { return m_bitfields.isRelPositioned(); } // relative positioning
503 bool isStickyPositioned() const { return m_bitfields.isStickyPositioned(); }
504 bool isPositioned() const { return m_bitfields.isPositioned(); }
506 bool isText() const { return m_bitfields.isText(); }
507 bool isBox() const { return m_bitfields.isBox(); }
508 bool isInline() const { return m_bitfields.isInline(); } // inline object
509 bool isDragging() const { return m_bitfields.isDragging(); }
510 bool isReplaced() const { return m_bitfields.isReplaced(); } // a "replaced" element (see CSS)
511 bool isHorizontalWritingMode() const { return m_bitfields.horizontalWritingMode(); }
513 bool hasLayer() const { return m_bitfields.hasLayer(); }
515 enum BoxDecorationState {
517 HasBoxDecorationsAndBackgroundObscurationStatusInvalid,
518 HasBoxDecorationsAndBackgroundIsKnownToBeObscured,
519 HasBoxDecorationsAndBackgroundMayBeVisible,
521 bool hasBoxDecorations() const { return m_bitfields.boxDecorationState() != NoBoxDecorations; }
522 bool backgroundIsKnownToBeObscured();
523 bool borderImageIsLoadedAndCanBeRendered() const;
524 bool mustRepaintBackgroundOrBorder() const;
525 bool hasBackground() const { return style()->hasBackground(); }
526 bool hasEntirelyFixedBackground() const;
528 bool needsLayout() const
530 return m_bitfields.selfNeedsLayout() || m_bitfields.normalChildNeedsLayout() || m_bitfields.posChildNeedsLayout()
531 || m_bitfields.needsSimplifiedNormalFlowLayout() || m_bitfields.needsPositionedMovementLayout();
534 bool selfNeedsLayout() const { return m_bitfields.selfNeedsLayout(); }
535 bool needsPositionedMovementLayout() const { return m_bitfields.needsPositionedMovementLayout(); }
536 bool needsPositionedMovementLayoutOnly() const
538 return m_bitfields.needsPositionedMovementLayout() && !m_bitfields.selfNeedsLayout() && !m_bitfields.normalChildNeedsLayout()
539 && !m_bitfields.posChildNeedsLayout() && !m_bitfields.needsSimplifiedNormalFlowLayout();
542 bool posChildNeedsLayout() const { return m_bitfields.posChildNeedsLayout(); }
543 bool needsSimplifiedNormalFlowLayout() const { return m_bitfields.needsSimplifiedNormalFlowLayout(); }
544 bool normalChildNeedsLayout() const { return m_bitfields.normalChildNeedsLayout(); }
546 bool preferredLogicalWidthsDirty() const { return m_bitfields.preferredLogicalWidthsDirty(); }
548 bool isSelectionBorder() const;
550 bool hasClip() const { return isOutOfFlowPositioned() && style()->hasClip(); }
551 bool hasOverflowClip() const { return m_bitfields.hasOverflowClip(); }
552 bool hasClipOrOverflowClip() const { return hasClip() || hasOverflowClip(); }
554 bool hasTransform() const { return m_bitfields.hasTransform(); }
555 bool hasMask() const { return style() && style()->hasMask(); }
556 bool hasClipPath() const { return style() && style()->clipPath(); }
557 bool hasHiddenBackface() const { return style() && style()->backfaceVisibility() == BackfaceVisibilityHidden; }
559 bool hasFilter() const { return style() && style()->hasFilter(); }
561 bool hasBlendMode() const;
563 inline bool preservesNewline() const;
565 // The pseudo element style can be cached or uncached. Use the cached method if the pseudo element doesn't respect
566 // any pseudo classes (and therefore has no concept of changing state).
567 RenderStyle* getCachedPseudoStyle(PseudoId, RenderStyle* parentStyle = 0) const;
568 PassRefPtr<RenderStyle> getUncachedPseudoStyle(const PseudoStyleRequest&, RenderStyle* parentStyle = 0, RenderStyle* ownStyle = 0) const;
570 virtual void updateDragState(bool dragOn);
572 RenderView* view() const { return document().renderView(); };
573 FrameView* frameView() const { return document().view(); };
575 // Returns true if this renderer is rooted, and optionally returns the hosting view (the root of the hierarchy).
576 bool isRooted(RenderView** = 0) const;
580 return isAnonymous() ? 0 : m_node;
583 Node* nonPseudoNode() const
585 return isPseudoElement() ? 0 : node();
588 // FIXME: Why does RenderWidget need this?
589 void clearNode() { m_node = 0; }
591 // Returns the styled node that caused the generation of this renderer.
592 // This is the same as node() except for renderers of :before and :after
593 // pseudo elements for which their parent node is returned.
594 Node* generatingNode() const { return isPseudoElement() ? node()->parentOrShadowHostNode() : node(); }
596 Document& document() const { return m_node->document(); }
597 Frame* frame() const { return document().frame(); }
599 bool hasOutlineAnnotation() const;
600 bool hasOutline() const { return style()->hasOutline() || hasOutlineAnnotation(); }
602 // Returns the object containing this one. Can be different from parent for positioned elements.
603 // If repaintContainer and repaintContainerSkipped are not null, on return *repaintContainerSkipped
604 // is true if the renderer returned is an ancestor of repaintContainer.
605 RenderObject* container(const RenderLayerModelObject* repaintContainer = 0, bool* repaintContainerSkipped = 0) const;
607 virtual RenderObject* hoverAncestor() const { return parent(); }
609 Element* offsetParent() const;
611 void markContainingBlocksForLayout(bool scheduleRelayout = true, RenderObject* newRoot = 0, SubtreeLayoutScope* = 0);
612 void setNeedsLayout(MarkingBehavior = MarkContainingBlockChain, SubtreeLayoutScope* = 0);
613 void clearNeedsLayout();
614 void setChildNeedsLayout(MarkingBehavior = MarkContainingBlockChain, SubtreeLayoutScope* = 0);
615 void setNeedsPositionedMovementLayout();
616 void setNeedsSimplifiedNormalFlowLayout();
617 void setPreferredLogicalWidthsDirty(MarkingBehavior = MarkContainingBlockChain);
618 void clearPreferredLogicalWidthsDirty();
619 void invalidateContainerPreferredLogicalWidths();
621 void setNeedsLayoutAndPrefWidthsRecalc()
624 setPreferredLogicalWidthsDirty();
627 void setPositionState(EPosition position)
629 ASSERT((position != AbsolutePosition && position != FixedPosition) || isBox());
630 m_bitfields.setPositionedState(position);
632 void clearPositionedState() { m_bitfields.clearPositionedState(); }
634 void setFloating(bool isFloating) { m_bitfields.setFloating(isFloating); }
635 void setInline(bool isInline) { m_bitfields.setIsInline(isInline); }
637 void setHasBoxDecorations(bool);
638 void invalidateBackgroundObscurationStatus();
639 virtual bool computeBackgroundIsKnownToBeObscured() { return false; }
641 void setIsText() { m_bitfields.setIsText(true); }
642 void setIsBox() { m_bitfields.setIsBox(true); }
643 void setReplaced(bool isReplaced) { m_bitfields.setIsReplaced(isReplaced); }
644 void setHorizontalWritingMode(bool hasHorizontalWritingMode) { m_bitfields.setHorizontalWritingMode(hasHorizontalWritingMode); }
645 void setHasOverflowClip(bool hasOverflowClip) { m_bitfields.setHasOverflowClip(hasOverflowClip); }
646 void setHasLayer(bool hasLayer) { m_bitfields.setHasLayer(hasLayer); }
647 void setHasTransform(bool hasTransform) { m_bitfields.setHasTransform(hasTransform); }
648 void setHasReflection(bool hasReflection) { m_bitfields.setHasReflection(hasReflection); }
650 void scheduleRelayout();
652 void updateFillImages(const FillLayer*, const FillLayer*);
653 void updateImage(StyleImage*, StyleImage*);
654 void updateShapeImage(const ShapeValue*, const ShapeValue*);
656 virtual void paint(PaintInfo&, const LayoutPoint&);
658 // Subclasses must reimplement this method to compute the size and position
659 // of this object and all its descendants.
660 virtual void layout() = 0;
661 virtual bool updateImageLoadingPriorities() { return false; }
662 void setHasPendingResourceUpdate(bool hasPendingResourceUpdate) { m_bitfields.setHasPendingResourceUpdate(hasPendingResourceUpdate); }
663 bool hasPendingResourceUpdate() const { return m_bitfields.hasPendingResourceUpdate(); }
665 /* This function performs a layout only if one is needed. */
666 void layoutIfNeeded() { if (needsLayout()) layout(); }
669 void forceChildLayout();
671 // True if we can abort layout, leaving a partially laid out tree.
672 virtual bool supportsPartialLayout() const { return false; }
674 // used for element state updates that cannot be fixed with a
675 // repaint and do not need a relayout
676 virtual void updateFromElement() { }
678 virtual void addAnnotatedRegions(Vector<AnnotatedRegionValue>&);
679 void collectAnnotatedRegions(Vector<AnnotatedRegionValue>&);
681 CompositingState compositingState() const;
682 bool acceleratedCompositingForOverflowScrollEnabled() const;
683 // FIXME: This is a temporary flag and should be removed once accelerated
684 // overflow scroll is ready (crbug.com/254111).
685 bool compositorDrivenAcceleratedScrollingEnabled() const;
687 bool hitTest(const HitTestRequest&, HitTestResult&, const HitTestLocation& locationInContainer, const LayoutPoint& accumulatedOffset, HitTestFilter = HitTestAll);
688 virtual void updateHitTestResult(HitTestResult&, const LayoutPoint&);
689 virtual bool nodeAtPoint(const HitTestRequest&, HitTestResult&, const HitTestLocation& locationInContainer, const LayoutPoint& accumulatedOffset, HitTestAction);
691 virtual PositionWithAffinity positionForPoint(const LayoutPoint&);
692 PositionWithAffinity createPositionWithAffinity(int offset, EAffinity);
693 PositionWithAffinity createPositionWithAffinity(const Position&);
695 virtual void dirtyLinesFromChangedChild(RenderObject*);
697 // Set the style of the object and update the state of the object accordingly.
698 void setStyle(PassRefPtr<RenderStyle>);
700 // Set the style of the object if it's generated content.
701 void setPseudoStyle(PassRefPtr<RenderStyle>);
703 // Updates only the local style ptr of the object. Does not update the state of the object,
704 // and so only should be called when the style is known not to have changed (or from setStyle).
705 void setStyleInternal(PassRefPtr<RenderStyle> style) { m_style = style; }
707 // returns the containing block level element for this element.
708 RenderBlock* containingBlock() const;
710 bool canContainFixedPositionObjects() const
712 return isRenderView() || (hasTransform() && isRenderBlock()) || isSVGForeignObject() || isOutOfFlowRenderFlowThread();
714 bool canContainAbsolutePositionObjects() const
716 return isRenderView() || (hasTransform() && isRenderBlock()) || isSVGForeignObject();
719 // Convert the given local point to absolute coordinates
720 // FIXME: Temporary. If UseTransforms is true, take transforms into account. Eventually localToAbsolute() will always be transform-aware.
721 FloatPoint localToAbsolute(const FloatPoint& localPoint = FloatPoint(), MapCoordinatesFlags = 0) const;
722 FloatPoint absoluteToLocal(const FloatPoint&, MapCoordinatesFlags = 0) const;
724 // Convert a local quad to absolute coordinates, taking transforms into account.
725 FloatQuad localToAbsoluteQuad(const FloatQuad& quad, MapCoordinatesFlags mode = 0, bool* wasFixed = 0) const
727 return localToContainerQuad(quad, 0, mode, wasFixed);
729 // Convert an absolute quad to local coordinates.
730 FloatQuad absoluteToLocalQuad(const FloatQuad&, MapCoordinatesFlags mode = 0) const;
732 // Convert a local quad into the coordinate system of container, taking transforms into account.
733 FloatQuad localToContainerQuad(const FloatQuad&, const RenderLayerModelObject* repaintContainer, MapCoordinatesFlags = 0, bool* wasFixed = 0) const;
734 FloatPoint localToContainerPoint(const FloatPoint&, const RenderLayerModelObject* repaintContainer, MapCoordinatesFlags = 0, bool* wasFixed = 0) const;
736 // Return the offset from the container() renderer (excluding transforms). In multi-column layout,
737 // different offsets apply at different points, so return the offset that applies to the given point.
738 virtual LayoutSize offsetFromContainer(RenderObject*, const LayoutPoint&, bool* offsetDependsOnPoint = 0) const;
739 // Return the offset from an object up the container() chain. Asserts that none of the intermediate objects have transforms.
740 LayoutSize offsetFromAncestorContainer(RenderObject*) const;
742 virtual void absoluteRects(Vector<IntRect>&, const LayoutPoint&) const { }
744 // FIXME: useTransforms should go away eventually
745 IntRect absoluteBoundingBoxRect(bool useTransform = true) const;
746 IntRect absoluteBoundingBoxRectIgnoringTransforms() const { return absoluteBoundingBoxRect(false); }
748 // Build an array of quads in absolute coords for line boxes
749 virtual void absoluteQuads(Vector<FloatQuad>&, bool* /*wasFixed*/ = 0) const { }
751 virtual void absoluteFocusRingQuads(Vector<FloatQuad>&);
753 static FloatRect absoluteBoundingBoxRectForRange(const Range*);
755 // the rect that will be painted if this object is passed as the paintingRoot
756 LayoutRect paintingRootRect(LayoutRect& topLevelRect);
758 virtual LayoutUnit minPreferredLogicalWidth() const { return 0; }
759 virtual LayoutUnit maxPreferredLogicalWidth() const { return 0; }
761 RenderStyle* style() const { return m_style.get(); }
762 RenderStyle* firstLineStyle() const { return document().styleEngine()->usesFirstLineRules() ? cachedFirstLineStyle() : style(); }
763 RenderStyle* style(bool firstLine) const { return firstLine ? firstLineStyle() : style(); }
765 inline Color resolveColor(const RenderStyle* styleToUse, int colorProperty) const
767 return styleToUse->visitedDependentColor(colorProperty);
770 inline Color resolveColor(int colorProperty) const
772 return style()->visitedDependentColor(colorProperty);
775 // Used only by Element::pseudoStyleCacheIsInvalid to get a first line style based off of a
776 // given new style, without accessing the cache.
777 PassRefPtr<RenderStyle> uncachedFirstLineStyle(RenderStyle*) const;
779 // Anonymous blocks that are part of of a continuation chain will return their inline continuation's outline style instead.
780 // This is typically only relevant when repainting.
781 virtual RenderStyle* outlineStyleForRepaint() const { return style(); }
783 virtual CursorDirective getCursor(const LayoutPoint&, Cursor&) const;
785 void getTextDecorationColors(unsigned decorations, Color& underline, Color& overline, Color& linethrough, bool quirksMode = false, bool firstlineStyle = false);
787 // Return the RenderLayerModelObject in the container chain which is responsible for painting this object, or 0
788 // if painting is root-relative. This is the container that should be passed to the 'forRepaint'
790 RenderLayerModelObject* containerForRepaint() const;
791 // Actually do the repaint of rect r for this object which has been computed in the coordinate space
792 // of repaintContainer. If repaintContainer is 0, repaint via the view.
793 void repaintUsingContainer(const RenderLayerModelObject* repaintContainer, const IntRect&) const;
795 // Repaint the entire object. Called when, e.g., the color of a border changes, or when a border
797 void repaint() const;
799 // Repaint a specific subrectangle within a given object. The rect |r| is in the object's coordinate space.
800 void repaintRectangle(const LayoutRect&) const;
802 // Repaint only if our old bounds and new bounds are different. The caller may pass in newBounds and newOutlineBox if they are known.
803 bool repaintAfterLayoutIfNeeded(const RenderLayerModelObject* repaintContainer, bool wasSelfLayout,
804 const LayoutRect& oldBounds, const LayoutRect& oldOutlineBox, const LayoutRect* newBoundsPtr = 0, const LayoutRect* newOutlineBoxPtr = 0);
806 virtual void repaintOverflow();
808 bool checkForRepaint() const;
809 bool checkForRepaintDuringLayout() const;
811 // Returns the rect that should be repainted whenever this object changes. The rect is in the view's
812 // coordinate space. This method deals with outlines and overflow.
813 LayoutRect absoluteClippedOverflowRect() const
815 return clippedOverflowRectForRepaint(0);
817 IntRect pixelSnappedAbsoluteClippedOverflowRect() const;
818 virtual LayoutRect clippedOverflowRectForRepaint(const RenderLayerModelObject* repaintContainer) const;
819 virtual LayoutRect rectWithOutlineForRepaint(const RenderLayerModelObject* repaintContainer, LayoutUnit outlineWidth) const;
820 virtual LayoutRect outlineBoundsForRepaint(const RenderLayerModelObject* /*repaintContainer*/, const RenderGeometryMap* = 0) const { return LayoutRect(); }
822 // Given a rect in the object's coordinate space, compute a rect suitable for repainting
823 // that rect in the coordinate space of repaintContainer.
824 virtual void computeRectForRepaint(const RenderLayerModelObject* repaintContainer, LayoutRect&, bool fixed = false) const;
825 virtual void computeFloatRectForRepaint(const RenderLayerModelObject* repaintContainer, FloatRect& repaintRect, bool fixed = false) const;
827 // If multiple-column layout results in applying an offset to the given point, add the same
828 // offset to the given size.
829 virtual void adjustForColumns(LayoutSize&, const LayoutPoint&) const { }
830 LayoutSize offsetForColumns(const LayoutPoint& point) const
833 adjustForColumns(offset, point);
837 virtual unsigned int length() const { return 1; }
839 bool isFloatingOrOutOfFlowPositioned() const { return (isFloating() || isOutOfFlowPositioned()); }
841 bool isTransparent() const { return style()->opacity() < 1.0f; }
842 float opacity() const { return style()->opacity(); }
844 bool hasReflection() const { return m_bitfields.hasReflection(); }
846 // Applied as a "slop" to dirty rect checks during the outline painting phase's dirty-rect checks.
847 int maximalOutlineSize(PaintPhase) const;
849 enum SelectionState {
850 SelectionNone, // The object is not selected.
851 SelectionStart, // The object either contains the start of a selection run or is the start of a run
852 SelectionInside, // The object is fully encompassed by a selection run
853 SelectionEnd, // The object either contains the end of a selection run or is the end of a run
854 SelectionBoth // The object contains an entire run or is the sole selected object in that run
857 // The current selection state for an object. For blocks, the state refers to the state of the leaf
858 // descendants (as described above in the SelectionState enum declaration).
859 SelectionState selectionState() const { return m_bitfields.selectionState(); }
860 virtual void setSelectionState(SelectionState state) { m_bitfields.setSelectionState(state); }
861 inline void setSelectionStateIfNeeded(SelectionState);
862 bool canUpdateSelectionOnRootLineBoxes();
864 // A single rectangle that encompasses all of the selected objects within this object. Used to determine the tightest
865 // possible bounding box for the selection.
866 LayoutRect selectionRect(bool clipToVisibleContent = true) { return selectionRectForRepaint(0, clipToVisibleContent); }
867 virtual LayoutRect selectionRectForRepaint(const RenderLayerModelObject* /*repaintContainer*/, bool /*clipToVisibleContent*/ = true) { return LayoutRect(); }
869 virtual bool canBeSelectionLeaf() const { return false; }
870 bool hasSelectedChildren() const { return selectionState() != SelectionNone; }
872 bool isSelectable() const;
873 // Obtains the selection colors that should be used when painting a selection.
874 Color selectionBackgroundColor() const;
875 Color selectionForegroundColor() const;
876 Color selectionEmphasisMarkColor() const;
878 // Whether or not a given block needs to paint selection gaps.
879 virtual bool shouldPaintSelectionGaps() const { return false; }
882 * Returns the local coordinates of the caret within this render object.
883 * @param caretOffset zero-based offset determining position within the render object.
884 * @param extraWidthToEndOfLine optional out arg to give extra width to end of line -
885 * useful for character range rect computations
887 virtual LayoutRect localCaretRect(InlineBox*, int caretOffset, LayoutUnit* extraWidthToEndOfLine = 0);
889 // When performing a global document tear-down, the renderer of the document is cleared. We use this
890 // as a hook to detect the case of document destruction and don't waste time doing unnecessary work.
891 bool documentBeingDestroyed() const;
893 void destroyAndCleanupAnonymousWrappers();
894 virtual void destroy();
896 // Virtual function helpers for the deprecated Flexible Box Layout (display: -webkit-box).
897 virtual bool isDeprecatedFlexibleBox() const { return false; }
899 // Virtual function helper for the new FlexibleBox Layout (display: -webkit-flex).
900 virtual bool isFlexibleBox() const { return false; }
902 bool isFlexibleBoxIncludingDeprecated() const
904 return isFlexibleBox() || isDeprecatedFlexibleBox();
907 virtual bool isCombineText() const { return false; }
909 virtual int caretMinOffset() const;
910 virtual int caretMaxOffset() const;
912 virtual int previousOffset(int current) const;
913 virtual int previousOffsetForBackwardDeletion(int current) const;
914 virtual int nextOffset(int current) const;
916 virtual void imageChanged(ImageResource*, const IntRect* = 0) OVERRIDE FINAL;
917 virtual void imageChanged(WrappedImagePtr, const IntRect* = 0) { }
918 virtual bool willRenderImage(ImageResource*) OVERRIDE FINAL;
920 void selectionStartEnd(int& spos, int& epos) const;
922 void remove() { if (parent()) parent()->removeChild(this); }
924 bool isInert() const;
925 bool visibleToHitTestRequest(const HitTestRequest& request) const { return style()->visibility() == VISIBLE && (request.ignorePointerEventsNone() || style()->pointerEvents() != PE_NONE) && !isInert(); }
926 bool visibleToHitTesting() const { return style()->visibility() == VISIBLE && style()->pointerEvents() != PE_NONE && !isInert(); }
928 // Map points and quads through elements, potentially via 3d transforms. You should never need to call these directly; use
929 // localToAbsolute/absoluteToLocal methods instead.
930 virtual void mapLocalToContainer(const RenderLayerModelObject* repaintContainer, TransformState&, MapCoordinatesFlags = ApplyContainerFlip, bool* wasFixed = 0) const;
931 virtual void mapAbsoluteToLocalPoint(MapCoordinatesFlags, TransformState&) const;
933 // Pushes state onto RenderGeometryMap about how to map coordinates from this renderer to its container, or ancestorToStopAt (whichever is encountered first).
934 // Returns the renderer which was mapped to (container or ancestorToStopAt).
935 virtual const RenderObject* pushMappingToContainer(const RenderLayerModelObject* ancestorToStopAt, RenderGeometryMap&) const;
937 bool shouldUseTransformFromContainer(const RenderObject* container) const;
938 void getTransformFromContainer(const RenderObject* container, const LayoutSize& offsetInContainer, TransformationMatrix&) const;
940 bool createsGroup() const { return isTransparent() || hasMask() || hasFilter() || hasBlendMode(); }
942 virtual void addFocusRingRects(Vector<IntRect>&, const LayoutPoint& /* additionalOffset */, const RenderLayerModelObject* /* paintContainer */ = 0) { };
944 // Compute a list of hit-test rectangles per layer rooted at this renderer.
945 virtual void computeLayerHitTestRects(LayerHitTestRects&) const;
947 LayoutRect absoluteOutlineBounds() const
949 return outlineBoundsForRepaint(0);
952 // 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.
953 RenderObject* rendererForRootBackground();
955 RespectImageOrientationEnum shouldRespectImageOrientation() const;
957 bool isRelayoutBoundaryForInspector() const;
959 const LayoutRect& newRepaintRect() const { return m_newRepaintRect; }
960 void setNewRepaintRect(const LayoutRect& rect) { m_newRepaintRect = rect; }
962 const LayoutRect& oldRepaintRect() const { return m_oldRepaintRect; }
963 void setOldRepaintRect(const LayoutRect& rect) { m_oldRepaintRect = rect; }
965 bool shouldDoFullRepaintAfterLayout() const { return m_bitfields.shouldDoFullRepaintAfterLayout(); }
966 void setShouldDoFullRepaintAfterLayout(bool b) { m_bitfields.setShouldDoFullRepaintAfterLayout(b); }
967 bool shouldRepaintOverflowIfNeeded() const { return m_bitfields.shouldRepaintOverflowIfNeeded(); }
969 void clearRepaintRects()
971 setNewRepaintRect(LayoutRect());
972 setOldRepaintRect(LayoutRect());
974 setShouldDoFullRepaintAfterLayout(false);
975 setShouldRepaintOverflowIfNeeded(false);
976 setLayoutDidGetCalled(false);
979 // layoutDidGetCalled indicates whether this render object was re-laid-out
980 // since the last call to setLayoutDidGetCalled(false) on this object.
981 bool layoutDidGetCalled() { return m_bitfields.layoutDidGetCalled(); }
982 void setLayoutDidGetCalled(bool b) { m_bitfields.setLayoutDidGetCalled(b); }
985 inline bool layerCreationAllowedForSubtree() const;
987 // Overrides should call the superclass at the end
988 virtual void styleWillChange(StyleDifference, const RenderStyle* newStyle);
989 // Overrides should call the superclass at the start
990 virtual void styleDidChange(StyleDifference, const RenderStyle* oldStyle);
991 void propagateStyleToAnonymousChildren(bool blockChildrenOnly = false);
993 void drawLineForBoxSide(GraphicsContext*, int x1, int y1, int x2, int y2, BoxSide,
994 Color, EBorderStyle, int adjbw1, int adjbw2, bool antialias = false);
995 void drawDashedOrDottedBoxSide(GraphicsContext*, int x1, int y1, int x2, int y2,
996 BoxSide, Color, int thickness, EBorderStyle, bool antialias);
997 void drawDoubleBoxSide(GraphicsContext*, int x1, int y1, int x2, int y2,
998 int length, BoxSide, Color, int thickness, int adjacentWidth1, int adjacentWidth2, bool antialias);
999 void drawRidgeOrGrooveBoxSide(GraphicsContext*, int x1, int y1, int x2, int y2,
1000 BoxSide, Color, EBorderStyle, int adjacentWidth1, int adjacentWidth2, bool antialias);
1001 void drawSolidBoxSide(GraphicsContext*, int x1, int y1, int x2, int y2,
1002 BoxSide, Color, int adjacentWidth1, int adjacentWidth2, bool antialias);
1004 void paintFocusRing(PaintInfo&, const LayoutPoint&, RenderStyle*);
1005 void paintOutline(PaintInfo&, const LayoutRect&);
1006 void addPDFURLRect(GraphicsContext*, const LayoutRect&);
1008 virtual LayoutRect viewRect() const;
1010 void adjustRectForOutlineAndShadow(LayoutRect&) const;
1012 void clearLayoutRootIfNeeded() const;
1013 virtual void willBeDestroyed();
1016 virtual void insertedIntoTree();
1017 virtual void willBeRemovedFromTree();
1019 void setDocumentForAnonymous(Document* document) { ASSERT(isAnonymous()); m_node = document; }
1021 // Add hit-test rects for the render tree rooted at this node to the provided collection on a
1022 // per-RenderLayer basis.
1023 // currentLayer must be the enclosing layer, and layerOffset is the current offset within
1024 // this layer. Subclass implementations will add any offset for this renderer within it's
1025 // container, so callers should provide only the offset of the container within it's layer.
1026 // containerRect is a rect that has already been added for the currentLayer which is likely to
1027 // be a container for child elements. Any rect wholly contained by containerRect can be
1029 virtual void addLayerHitTestRects(LayerHitTestRects&, const RenderLayer* currentLayer, const LayoutPoint& layerOffset, const LayoutRect& containerRect) const;
1031 // Add hit-test rects for this renderer only to the provided list. layerOffset is the offset
1032 // of this renderer within the current layer that should be used for each result.
1033 virtual void computeSelfHitTestRects(Vector<LayoutRect>&, const LayoutPoint& layerOffset) const { };
1036 RenderBlock* containerForFixedPosition(const RenderLayerModelObject* repaintContainer = 0, bool* repaintContainerSkipped = 0) const;
1038 RenderFlowThread* locateFlowThreadContainingBlock() const;
1039 void removeFromRenderFlowThread();
1040 void removeFromRenderFlowThreadRecursive(RenderFlowThread*);
1042 bool shouldRepaintForStyleDifference(StyleDifference) const;
1043 bool hasImmediateNonWhitespaceTextChildOrPropertiesDependentOnColor() const;
1045 RenderStyle* cachedFirstLineStyle() const;
1046 StyleDifference adjustStyleDifference(StyleDifference, unsigned contextSensitiveProperties) const;
1048 Color selectionColor(int colorProperty) const;
1050 void removeShapeImageClient(ShapeValue*);
1053 void checkBlockPositionedObjectsNeedLayout();
1054 void checkNotInPartialLayout();
1057 RefPtr<RenderStyle> m_style;
1061 RenderObject* m_parent;
1062 RenderObject* m_previous;
1063 RenderObject* m_next;
1066 unsigned m_hasAXObject : 1;
1067 unsigned m_setNeedsLayoutForbidden : 1;
1070 #define ADD_BOOLEAN_BITFIELD(name, Name) \
1072 unsigned m_##name : 1;\
1074 bool name() const { return m_##name; }\
1075 void set##Name(bool name) { m_##name = name; }\
1077 class RenderObjectBitfields {
1078 enum PositionedState {
1079 IsStaticallyPositioned = 0,
1080 IsRelativelyPositioned = 1,
1081 IsOutOfFlowPositioned = 2,
1082 IsStickyPositioned = 3
1086 RenderObjectBitfields(Node* node)
1087 : m_selfNeedsLayout(false)
1088 // FIXME: shouldDoFullRepaintAfterLayout is needed because we reset
1089 // the layout bits before repaint when doing repaintAfterLayout.
1090 // Holding the layout bits until after repaint would remove the need
1092 , m_shouldDoFullRepaintAfterLayout(false)
1093 , m_shouldRepaintOverflowIfNeeded(false)
1094 , m_needsPositionedMovementLayout(false)
1095 , m_normalChildNeedsLayout(false)
1096 , m_posChildNeedsLayout(false)
1097 , m_needsSimplifiedNormalFlowLayout(false)
1098 , m_preferredLogicalWidthsDirty(false)
1100 , m_isAnonymous(!node)
1104 , m_isReplaced(false)
1105 , m_horizontalWritingMode(true)
1106 , m_isDragging(false)
1108 , m_hasOverflowClip(false)
1109 , m_hasTransform(false)
1110 , m_hasReflection(false)
1111 , m_hasCounterNodeMap(false)
1112 , m_everHadLayout(false)
1113 , m_ancestorLineBoxDirty(false)
1114 , m_childrenInline(false)
1115 , m_hasColumns(false)
1116 , m_layoutDidGetCalled(false)
1117 , m_positionedState(IsStaticallyPositioned)
1118 , m_selectionState(SelectionNone)
1119 , m_flowThreadState(NotInsideFlowThread)
1120 , m_boxDecorationState(NoBoxDecorations)
1121 , m_hasPendingResourceUpdate(false)
1125 // 32 bits have been used in the first word, and 3 in the second.
1126 ADD_BOOLEAN_BITFIELD(selfNeedsLayout, SelfNeedsLayout);
1127 ADD_BOOLEAN_BITFIELD(shouldDoFullRepaintAfterLayout, ShouldDoFullRepaintAfterLayout);
1128 ADD_BOOLEAN_BITFIELD(shouldRepaintOverflowIfNeeded, ShouldRepaintOverflowIfNeeded);
1129 ADD_BOOLEAN_BITFIELD(needsPositionedMovementLayout, NeedsPositionedMovementLayout);
1130 ADD_BOOLEAN_BITFIELD(normalChildNeedsLayout, NormalChildNeedsLayout);
1131 ADD_BOOLEAN_BITFIELD(posChildNeedsLayout, PosChildNeedsLayout);
1132 ADD_BOOLEAN_BITFIELD(needsSimplifiedNormalFlowLayout, NeedsSimplifiedNormalFlowLayout);
1133 ADD_BOOLEAN_BITFIELD(preferredLogicalWidthsDirty, PreferredLogicalWidthsDirty);
1134 ADD_BOOLEAN_BITFIELD(floating, Floating);
1136 ADD_BOOLEAN_BITFIELD(isAnonymous, IsAnonymous);
1137 ADD_BOOLEAN_BITFIELD(isText, IsText);
1138 ADD_BOOLEAN_BITFIELD(isBox, IsBox);
1139 ADD_BOOLEAN_BITFIELD(isInline, IsInline);
1140 ADD_BOOLEAN_BITFIELD(isReplaced, IsReplaced);
1141 ADD_BOOLEAN_BITFIELD(horizontalWritingMode, HorizontalWritingMode);
1142 ADD_BOOLEAN_BITFIELD(isDragging, IsDragging);
1144 ADD_BOOLEAN_BITFIELD(hasLayer, HasLayer);
1145 ADD_BOOLEAN_BITFIELD(hasOverflowClip, HasOverflowClip); // Set in the case of overflow:auto/scroll/hidden
1146 ADD_BOOLEAN_BITFIELD(hasTransform, HasTransform);
1147 ADD_BOOLEAN_BITFIELD(hasReflection, HasReflection);
1149 ADD_BOOLEAN_BITFIELD(hasCounterNodeMap, HasCounterNodeMap);
1150 ADD_BOOLEAN_BITFIELD(everHadLayout, EverHadLayout);
1151 ADD_BOOLEAN_BITFIELD(ancestorLineBoxDirty, AncestorLineBoxDirty);
1154 ADD_BOOLEAN_BITFIELD(childrenInline, ChildrenInline);
1155 ADD_BOOLEAN_BITFIELD(hasColumns, HasColumns);
1157 ADD_BOOLEAN_BITFIELD(layoutDidGetCalled, LayoutDidGetCalled);
1160 unsigned m_positionedState : 2; // PositionedState
1161 unsigned m_selectionState : 3; // SelectionState
1162 unsigned m_flowThreadState : 2; // FlowThreadState
1163 unsigned m_boxDecorationState : 2; // BoxDecorationState
1167 ADD_BOOLEAN_BITFIELD(hasPendingResourceUpdate, HasPendingResourceUpdate);
1169 bool isOutOfFlowPositioned() const { return m_positionedState == IsOutOfFlowPositioned; }
1170 bool isRelPositioned() const { return m_positionedState == IsRelativelyPositioned; }
1171 bool isStickyPositioned() const { return m_positionedState == IsStickyPositioned; }
1172 bool isPositioned() const { return m_positionedState != IsStaticallyPositioned; }
1174 void setPositionedState(int positionState)
1176 // This mask maps FixedPosition and AbsolutePosition to IsOutOfFlowPositioned, saving one bit.
1177 m_positionedState = static_cast<PositionedState>(positionState & 0x3);
1179 void clearPositionedState() { m_positionedState = StaticPosition; }
1181 ALWAYS_INLINE SelectionState selectionState() const { return static_cast<SelectionState>(m_selectionState); }
1182 ALWAYS_INLINE void setSelectionState(SelectionState selectionState) { m_selectionState = selectionState; }
1184 ALWAYS_INLINE FlowThreadState flowThreadState() const { return static_cast<FlowThreadState>(m_flowThreadState); }
1185 ALWAYS_INLINE void setFlowThreadState(FlowThreadState flowThreadState) { m_flowThreadState = flowThreadState; }
1187 ALWAYS_INLINE BoxDecorationState boxDecorationState() const { return static_cast<BoxDecorationState>(m_boxDecorationState); }
1188 ALWAYS_INLINE void setBoxDecorationState(BoxDecorationState boxDecorationState) { m_boxDecorationState = boxDecorationState; }
1191 #undef ADD_BOOLEAN_BITFIELD
1193 RenderObjectBitfields m_bitfields;
1195 void setSelfNeedsLayout(bool b) { m_bitfields.setSelfNeedsLayout(b); }
1196 void setNeedsPositionedMovementLayout(bool b) { m_bitfields.setNeedsPositionedMovementLayout(b); }
1197 void setNormalChildNeedsLayout(bool b) { m_bitfields.setNormalChildNeedsLayout(b); }
1198 void setPosChildNeedsLayout(bool b) { m_bitfields.setPosChildNeedsLayout(b); }
1199 void setNeedsSimplifiedNormalFlowLayout(bool b) { m_bitfields.setNeedsSimplifiedNormalFlowLayout(b); }
1200 void setIsDragging(bool b) { m_bitfields.setIsDragging(b); }
1201 void setEverHadLayout(bool b) { m_bitfields.setEverHadLayout(b); }
1202 void setShouldRepaintOverflowIfNeeded(bool b) { m_bitfields.setShouldRepaintOverflowIfNeeded(b); }
1205 // Store state between styleWillChange and styleDidChange
1206 static bool s_affectsParentBlock;
1208 LayoutRect m_oldRepaintRect;
1209 LayoutRect m_newRepaintRect;
1212 inline bool RenderObject::documentBeingDestroyed() const
1214 return !document().renderer();
1217 inline bool RenderObject::isBeforeContent() const
1219 if (style()->styleType() != BEFORE)
1221 // Text nodes don't have their own styles, so ignore the style on a text node.
1222 if (isText() && !isBR())
1227 inline bool RenderObject::isAfterContent() const
1229 if (style()->styleType() != AFTER)
1231 // Text nodes don't have their own styles, so ignore the style on a text node.
1232 if (isText() && !isBR())
1237 inline bool RenderObject::isBeforeOrAfterContent() const
1239 return isBeforeContent() || isAfterContent();
1242 inline void RenderObject::setNeedsLayout(MarkingBehavior markParents, SubtreeLayoutScope* layouter)
1245 checkNotInPartialLayout();
1247 ASSERT(!isSetNeedsLayoutForbidden());
1248 bool alreadyNeededLayout = m_bitfields.selfNeedsLayout();
1249 setSelfNeedsLayout(true);
1250 if (!alreadyNeededLayout) {
1251 if (markParents == MarkContainingBlockChain && (!layouter || layouter->root() != this))
1252 markContainingBlocksForLayout(true, 0, layouter);
1254 setLayerNeedsFullRepaint();
1258 inline void RenderObject::clearNeedsLayout()
1261 checkNotInPartialLayout();
1263 setSelfNeedsLayout(false);
1264 setEverHadLayout(true);
1265 setPosChildNeedsLayout(false);
1266 setNeedsSimplifiedNormalFlowLayout(false);
1267 setNormalChildNeedsLayout(false);
1268 setNeedsPositionedMovementLayout(false);
1269 setAncestorLineBoxDirty(false);
1271 checkBlockPositionedObjectsNeedLayout();
1275 inline void RenderObject::setChildNeedsLayout(MarkingBehavior markParents, SubtreeLayoutScope* layouter)
1277 ASSERT(!isSetNeedsLayoutForbidden());
1278 bool alreadyNeededLayout = normalChildNeedsLayout();
1279 setNormalChildNeedsLayout(true);
1280 // FIXME: Replace MarkOnlyThis with the SubtreeLayoutScope code path and remove the MarkingBehavior argument entirely.
1281 if (!alreadyNeededLayout && markParents == MarkContainingBlockChain && (!layouter || layouter->root() != this))
1282 markContainingBlocksForLayout(true, 0, layouter);
1285 inline void RenderObject::setNeedsPositionedMovementLayout()
1287 bool alreadyNeededLayout = needsPositionedMovementLayout();
1288 setNeedsPositionedMovementLayout(true);
1289 ASSERT(!isSetNeedsLayoutForbidden());
1290 if (!alreadyNeededLayout) {
1291 markContainingBlocksForLayout();
1293 setLayerNeedsFullRepaintForPositionedMovementLayout();
1297 inline void RenderObject::setNeedsSimplifiedNormalFlowLayout()
1299 bool alreadyNeededLayout = needsSimplifiedNormalFlowLayout();
1300 setNeedsSimplifiedNormalFlowLayout(true);
1301 ASSERT(!isSetNeedsLayoutForbidden());
1302 if (!alreadyNeededLayout) {
1303 markContainingBlocksForLayout();
1305 setLayerNeedsFullRepaint();
1309 inline bool RenderObject::preservesNewline() const
1311 if (isSVGInlineText())
1314 return style()->preserveNewline();
1317 inline bool RenderObject::layerCreationAllowedForSubtree() const
1319 RenderObject* parentRenderer = parent();
1320 while (parentRenderer) {
1321 if (parentRenderer->isSVGHiddenContainer())
1323 parentRenderer = parentRenderer->parent();
1329 inline void RenderObject::setSelectionStateIfNeeded(SelectionState state)
1331 if (selectionState() == state)
1334 setSelectionState(state);
1337 inline void RenderObject::setHasBoxDecorations(bool b)
1340 m_bitfields.setBoxDecorationState(NoBoxDecorations);
1343 if (hasBoxDecorations())
1345 m_bitfields.setBoxDecorationState(HasBoxDecorationsAndBackgroundObscurationStatusInvalid);
1348 inline void RenderObject::invalidateBackgroundObscurationStatus()
1350 if (!hasBoxDecorations())
1352 m_bitfields.setBoxDecorationState(HasBoxDecorationsAndBackgroundObscurationStatusInvalid);
1355 inline bool RenderObject::backgroundIsKnownToBeObscured()
1357 if (m_bitfields.boxDecorationState() == HasBoxDecorationsAndBackgroundObscurationStatusInvalid) {
1358 BoxDecorationState boxDecorationState = computeBackgroundIsKnownToBeObscured() ? HasBoxDecorationsAndBackgroundIsKnownToBeObscured : HasBoxDecorationsAndBackgroundMayBeVisible;
1359 m_bitfields.setBoxDecorationState(boxDecorationState);
1361 return m_bitfields.boxDecorationState() == HasBoxDecorationsAndBackgroundIsKnownToBeObscured;
1364 inline void makeMatrixRenderable(TransformationMatrix& matrix, bool has3DRendering)
1366 if (!has3DRendering)
1367 matrix.makeAffine();
1370 inline int adjustForAbsoluteZoom(int value, RenderObject* renderer)
1372 return adjustForAbsoluteZoom(value, renderer->style());
1375 inline LayoutUnit adjustLayoutUnitForAbsoluteZoom(LayoutUnit value, RenderObject& renderer)
1377 ASSERT(renderer.style());
1378 return adjustLayoutUnitForAbsoluteZoom(value, *renderer.style());
1381 inline void adjustFloatQuadForAbsoluteZoom(FloatQuad& quad, RenderObject& renderer)
1383 float zoom = renderer.style()->effectiveZoom();
1385 quad.scale(1 / zoom, 1 / zoom);
1388 inline void adjustFloatRectForAbsoluteZoom(FloatRect& rect, RenderObject& renderer)
1390 float zoom = renderer.style()->effectiveZoom();
1392 rect.scale(1 / zoom, 1 / zoom);
1395 #define DEFINE_RENDER_OBJECT_TYPE_CASTS(thisType, predicate) \
1396 DEFINE_TYPE_CASTS(thisType, RenderObject, object, object->predicate, object.predicate)
1398 } // namespace WebCore
1401 // Outside the WebCore namespace for ease of invocation from gdb.
1402 void showTree(const WebCore::RenderObject*);
1403 void showLineTree(const WebCore::RenderObject*);
1404 void showRenderTree(const WebCore::RenderObject* object1);
1405 // We don't make object2 an optional parameter so that showRenderTree
1406 // can be called from gdb easily.
1407 void showRenderTree(const WebCore::RenderObject* object1, const WebCore::RenderObject* object2);
1411 #endif // RenderObject_h