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 Apple Inc. All rights reserved.
8 * This library is free software; you can redistribute it and/or
9 * modify it under the terms of the GNU Library General Public
10 * License as published by the Free Software Foundation; either
11 * version 2 of the License, or (at your option) any later version.
13 * This library is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 * Library General Public License for more details.
18 * You should have received a copy of the GNU Library General Public License
19 * along with this library; see the file COPYING.LIB. If not, write to
20 * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
21 * Boston, MA 02110-1301, USA.
25 #ifndef RenderObject_h
26 #define RenderObject_h
28 #include "CachedResourceClient.h"
29 #include "FloatQuad.h"
31 #include "RenderObjectChildList.h"
32 #include "RenderStyle.h"
33 #include "TransformationMatrix.h"
37 class AnimationController;
41 class RenderBoxModelObject;
47 class VisiblePosition;
50 * The painting of a layer occurs in three distinct phases. Each phase involves
51 * a recursive descent into the layer's render objects. The first phase is the background phase.
52 * The backgrounds and borders of all blocks are painted. Inlines are not painted at all.
53 * Floats must paint above block backgrounds but entirely below inline content that can overlap them.
54 * In the foreground phase, all inlines are fully painted. Inline replaced elements will get all
55 * three phases invoked on them during this phase.
59 PaintPhaseBlockBackground,
60 PaintPhaseChildBlockBackground,
61 PaintPhaseChildBlockBackgrounds,
65 PaintPhaseChildOutlines,
66 PaintPhaseSelfOutline,
68 PaintPhaseCollapsedTableBorders,
73 enum PaintRestriction {
75 PaintRestrictionSelectionOnly,
76 PaintRestrictionSelectionOnlyBlackText
86 HitTestBlockBackground,
87 HitTestChildBlockBackground,
88 HitTestChildBlockBackgrounds,
93 // Sides used when drawing borders and outlines. This is in RenderObject rather than RenderBoxModelObject since outlines can
94 // be drawn by SVG around bounding boxes.
102 const int caretWidth = 1;
104 #if ENABLE(DASHBOARD_SUPPORT)
105 struct DashboardRegionValue {
106 bool operator==(const DashboardRegionValue& o) const
108 return type == o.type && bounds == o.bounds && clip == o.clip && label == o.label;
110 bool operator!=(const DashboardRegionValue& o) const
112 return !(*this == o);
122 // Base class for all rendering tree objects.
123 class RenderObject : public CachedResourceClient {
124 friend class RenderBlock;
125 friend class RenderBox;
126 friend class RenderLayer;
127 friend class RenderObjectChildList;
128 friend class RenderSVGContainer;
130 // Anonymous objects should pass the document as their node, and they will then automatically be
131 // marked as anonymous in the constructor.
133 virtual ~RenderObject();
135 virtual const char* renderName() const = 0;
137 RenderObject* parent() const { return m_parent; }
138 bool isDescendantOf(const RenderObject*) const;
140 RenderObject* previousSibling() const { return m_previous; }
141 RenderObject* nextSibling() const { return m_next; }
143 RenderObject* firstChild() const
145 if (const RenderObjectChildList* children = virtualChildren())
146 return children->firstChild();
149 RenderObject* lastChild() const
151 if (const RenderObjectChildList* children = virtualChildren())
152 return children->lastChild();
155 virtual RenderObjectChildList* virtualChildren() { return 0; }
156 virtual const RenderObjectChildList* virtualChildren() const { return 0; }
158 RenderObject* nextInPreOrder() const;
159 RenderObject* nextInPreOrder(RenderObject* stayWithin) const;
160 RenderObject* nextInPreOrderAfterChildren() const;
161 RenderObject* nextInPreOrderAfterChildren(RenderObject* stayWithin) const;
162 RenderObject* previousInPreOrder() const;
163 RenderObject* childAt(unsigned) const;
165 RenderObject* firstLeafChild() const;
166 RenderObject* lastLeafChild() const;
168 // The following five functions are used when the render tree hierarchy changes to make sure layers get
169 // properly added and removed. Since containership can be implemented by any subclass, and since a hierarchy
170 // can contain a mixture of boxes and other object types, these functions need to be in the base class.
171 RenderLayer* enclosingLayer() const;
173 void addLayers(RenderLayer* parentLayer, RenderObject* newObject);
174 void removeLayers(RenderLayer* parentLayer);
175 void moveLayers(RenderLayer* oldParent, RenderLayer* newParent);
176 RenderLayer* findNextLayer(RenderLayer* parentLayer, RenderObject* startPoint, bool checkParent = true);
178 // Convenience function for getting to the nearest enclosing box of a RenderObject.
179 RenderBox* enclosingBox() const;
181 virtual bool isEmpty() const { return firstChild() == 0; }
184 void setHasAXObject(bool flag) { m_hasAXObject = flag; }
185 bool hasAXObject() const { return m_hasAXObject; }
186 bool isSetNeedsLayoutForbidden() const { return m_setNeedsLayoutForbidden; }
187 void setNeedsLayoutIsForbidden(bool flag) { m_setNeedsLayoutForbidden = flag; }
190 // Obtains the nearest enclosing block (including this block) that contributes a first-line style to our inline
192 virtual RenderBlock* firstLineBlock() const;
194 // Called when an object that was floating or positioned becomes a normal flow object
195 // again. We have to make sure the render tree updates as needed to accommodate the new
196 // normal flow object.
197 void handleDynamicFloatPositionChange();
199 // RenderObject tree manipulation
200 //////////////////////////////////////////
201 virtual bool canHaveChildren() const { return virtualChildren(); }
202 virtual bool isChildAllowed(RenderObject*, RenderStyle*) const { return true; }
203 virtual void addChild(RenderObject* newChild, RenderObject* beforeChild = 0);
204 virtual void addChildIgnoringContinuation(RenderObject* newChild, RenderObject* beforeChild = 0) { return addChild(newChild, beforeChild); }
205 virtual void removeChild(RenderObject*);
206 virtual bool createsAnonymousWrapper() const { return false; }
207 //////////////////////////////////////////
210 //////////////////////////////////////////
211 // Helper functions. Dangerous to use!
212 void setPreviousSibling(RenderObject* previous) { m_previous = previous; }
213 void setNextSibling(RenderObject* next) { m_next = next; }
214 void setParent(RenderObject* parent) { m_parent = parent; }
215 //////////////////////////////////////////
217 void addAbsoluteRectForLayer(IntRect& result);
218 void setLayerNeedsFullRepaint();
222 void showTreeForThis() const;
225 static RenderObject* createObject(Node*, RenderStyle*);
227 // Overloaded new operator. Derived classes must override operator new
228 // in order to allocate out of the RenderArena.
229 void* operator new(size_t, RenderArena*) throw();
231 // Overridden to prevent the normal delete from being called.
232 void operator delete(void*, size_t);
235 // The normal operator new is disallowed on all render objects.
236 void* operator new(size_t) throw();
239 RenderArena* renderArena() const { return document()->renderArena(); }
241 virtual bool isApplet() const { return false; }
242 virtual bool isBR() const { return false; }
243 virtual bool isBlockFlow() const { return false; }
244 virtual bool isBoxModelObject() const { return false; }
245 virtual bool isCounter() const { return false; }
246 virtual bool isFieldset() const { return false; }
247 virtual bool isFrame() const { return false; }
248 virtual bool isFrameSet() const { return false; }
249 virtual bool isImage() const { return false; }
250 virtual bool isInlineBlockOrInlineTable() const { return false; }
251 virtual bool isListBox() const { return false; }
252 virtual bool isListItem() const { return false; }
253 virtual bool isListMarker() const { return false; }
254 virtual bool isMedia() const { return false; }
255 virtual bool isMenuList() const { return false; }
256 virtual bool isRenderBlock() const { return false; }
257 virtual bool isRenderButton() const { return false; }
258 virtual bool isRenderImage() const { return false; }
259 virtual bool isRenderInline() const { return false; }
260 virtual bool isRenderPart() const { return false; }
261 virtual bool isRenderView() const { return false; }
262 virtual bool isSlider() const { return false; }
263 virtual bool isTable() const { return false; }
264 virtual bool isTableCell() const { return false; }
265 virtual bool isTableCol() const { return false; }
266 virtual bool isTableRow() const { return false; }
267 virtual bool isTableSection() const { return false; }
268 virtual bool isTextControl() const { return false; }
269 virtual bool isTextArea() const { return false; }
270 virtual bool isTextField() const { return false; }
271 virtual bool isWidget() const { return false; }
273 bool isRoot() const { return document()->documentElement() == m_node; }
277 bool isHTMLMarquee() const;
279 bool childrenInline() const { return m_childrenInline; }
280 void setChildrenInline(bool b = true) { m_childrenInline = b; }
281 bool hasColumns() const { return m_hasColumns; }
282 void setHasColumns(bool b = true) { m_hasColumns = b; }
283 bool cellWidthChanged() const { return m_cellWidthChanged; }
284 void setCellWidthChanged(bool b = true) { m_cellWidthChanged = b; }
287 virtual bool isSVGRoot() const { return false; }
288 virtual bool isSVGContainer() const { return false; }
289 virtual bool isSVGHiddenContainer() const { return false; }
290 virtual bool isRenderPath() const { return false; }
291 virtual bool isSVGText() const { return false; }
293 virtual FloatRect relativeBBox(bool includeStroke = true) const;
295 virtual TransformationMatrix localTransform() const;
296 virtual TransformationMatrix absoluteTransform() const;
299 bool isAnonymous() const { return m_isAnonymous; }
300 void setIsAnonymous(bool b) { m_isAnonymous = b; }
301 bool isAnonymousBlock() const
303 return m_isAnonymous && style()->display() == BLOCK && style()->styleType() == NOPSEUDO && !isListMarker();
305 bool isInlineContinuation() const { return (node() ? node()->renderer() != this : false) && isRenderInline(); }
306 bool isFloating() const { return m_floating; }
307 bool isPositioned() const { return m_positioned; } // absolute or fixed positioning
308 bool isRelPositioned() const { return m_relPositioned; } // relative positioning
309 bool isText() const { return m_isText; }
310 bool isBox() const { return m_isBox; }
311 bool isInline() const { return m_inline; } // inline object
312 bool isRunIn() const { return style()->display() == RUN_IN; } // run-in object
313 bool isDragging() const { return m_isDragging; }
314 bool isReplaced() const { return m_replaced; } // a "replaced" element (see CSS)
316 bool hasLayer() const { return m_hasLayer; }
318 bool hasBoxDecorations() const { return m_paintBackground; }
319 bool mustRepaintBackgroundOrBorder() const;
321 bool needsLayout() const { return m_needsLayout || m_normalChildNeedsLayout || m_posChildNeedsLayout || m_needsPositionedMovementLayout; }
322 bool selfNeedsLayout() const { return m_needsLayout; }
323 bool needsPositionedMovementLayout() const { return m_needsPositionedMovementLayout; }
324 bool needsPositionedMovementLayoutOnly() const { return m_needsPositionedMovementLayout && !m_needsLayout && !m_normalChildNeedsLayout && !m_posChildNeedsLayout; }
325 bool posChildNeedsLayout() const { return m_posChildNeedsLayout; }
326 bool normalChildNeedsLayout() const { return m_normalChildNeedsLayout; }
328 bool prefWidthsDirty() const { return m_prefWidthsDirty; }
330 bool isSelectionBorder() const;
332 bool hasClip() const { return isPositioned() && style()->hasClip(); }
333 bool hasOverflowClip() const { return m_hasOverflowClip; }
335 bool hasTransform() const { return m_hasTransform; }
336 bool hasMask() const { return style() && style()->hasMask(); }
338 void drawLineForBoxSide(GraphicsContext*, int x1, int y1, int x2, int y2, BoxSide,
339 Color, const Color& textcolor, EBorderStyle, int adjbw1, int adjbw2);
340 void drawArcForBoxSide(GraphicsContext*, int x, int y, float thickness, IntSize radius, int angleStart,
341 int angleSpan, BoxSide, Color, const Color& textcolor, EBorderStyle, bool firstCorner);
344 // The pseudo element style can be cached or uncached. Use the cached method if the pseudo element doesn't respect
345 // any pseudo classes (and therefore has no concept of changing state).
346 RenderStyle* getCachedPseudoStyle(PseudoId, RenderStyle* parentStyle = 0) const;
347 PassRefPtr<RenderStyle> getUncachedPseudoStyle(PseudoId, RenderStyle* parentStyle = 0) const;
349 virtual void updateDragState(bool dragOn);
351 RenderView* view() const;
353 // Returns true if this renderer is rooted, and optionally returns the hosting view (the root of the hierarchy).
354 bool isRooted(RenderView** = 0);
356 Node* node() const { return m_isAnonymous ? 0 : m_node; }
357 Document* document() const { return m_node->document(); }
358 void setNode(Node* node) { m_node = node; }
360 bool hasOutlineAnnotation() const;
361 bool hasOutline() const { return style()->hasOutline() || hasOutlineAnnotation(); }
364 * returns the object containing this one. can be different from parent for
365 * positioned elements
367 RenderObject* container() const;
368 virtual RenderObject* hoverAncestor() const { return parent(); }
370 // IE Extension that can be called on any RenderObject. See the implementation for the details.
371 RenderBoxModelObject* offsetParent() const;
373 void markContainingBlocksForLayout(bool scheduleRelayout = true, RenderObject* newRoot = 0);
374 void setNeedsLayout(bool b, bool markParents = true);
375 void setChildNeedsLayout(bool b, bool markParents = true);
376 void setNeedsPositionedMovementLayout();
377 void setPrefWidthsDirty(bool, bool markParents = true);
378 void invalidateContainerPrefWidths();
380 void setNeedsLayoutAndPrefWidthsRecalc()
382 setNeedsLayout(true);
383 setPrefWidthsDirty(true);
386 void setPositioned(bool b = true) { m_positioned = b; }
387 void setRelPositioned(bool b = true) { m_relPositioned = b; }
388 void setFloating(bool b = true) { m_floating = b; }
389 void setInline(bool b = true) { m_inline = b; }
390 void setHasBoxDecorations(bool b = true) { m_paintBackground = b; }
391 void setIsText() { m_isText = true; }
392 void setIsBox() { m_isBox = true; }
393 void setReplaced(bool b = true) { m_replaced = b; }
394 void setHasOverflowClip(bool b = true) { m_hasOverflowClip = b; }
395 void setHasLayer(bool b = true) { m_hasLayer = b; }
396 void setHasTransform(bool b = true) { m_hasTransform = b; }
397 void setHasReflection(bool b = true) { m_hasReflection = b; }
399 void scheduleRelayout();
401 void updateFillImages(const FillLayer*, const FillLayer*);
402 void updateImage(StyleImage*, StyleImage*);
404 // for discussion of lineHeight see CSS2 spec
405 virtual int lineHeight(bool firstLine, bool isRootLineBox = false) const;
406 // for the vertical-align property of inline elements
407 // the offset of baseline from the top of the object.
408 virtual int baselinePosition(bool firstLine, bool isRootLineBox = false) const;
411 * Paint the object and its children, clipped by (x|y|w|h).
412 * (tx|ty) is the calculated position of the parent
415 PaintInfo(GraphicsContext* newContext, const IntRect& newRect, PaintPhase newPhase, bool newForceBlackText,
416 RenderObject* newPaintingRoot, ListHashSet<RenderInline*>* newOutlineObjects)
417 : context(newContext)
420 , forceBlackText(newForceBlackText)
421 , paintingRoot(newPaintingRoot)
422 , outlineObjects(newOutlineObjects)
426 GraphicsContext* context;
430 RenderObject* paintingRoot; // used to draw just one element and its visual kids
431 ListHashSet<RenderInline*>* outlineObjects; // used to list outlines that should be painted by a block with inline children
434 virtual void paint(PaintInfo&, int tx, int ty);
436 // Recursive function that computes the size and position of this object and all its descendants.
437 virtual void layout();
439 /* This function performs a layout only if one is needed. */
440 void layoutIfNeeded() { if (needsLayout()) layout(); }
442 // Called when a positioned object moves but doesn't necessarily change size. A simplified layout is attempted
443 // that just updates the object's position. If the size does change, the object remains dirty.
444 virtual void tryLayoutDoingPositionedMovementOnly() { }
446 // used for element state updates that cannot be fixed with a
447 // repaint and do not need a relayout
448 virtual void updateFromElement() { }
450 #if ENABLE(DASHBOARD_SUPPORT)
451 virtual void addDashboardRegions(Vector<DashboardRegionValue>&);
452 void collectDashboardRegions(Vector<DashboardRegionValue>&);
455 bool hitTest(const HitTestRequest&, HitTestResult&, const IntPoint&, int tx, int ty, HitTestFilter = HitTestAll);
456 virtual bool nodeAtPoint(const HitTestRequest&, HitTestResult&, int x, int y, int tx, int ty, HitTestAction);
457 virtual void updateHitTestResult(HitTestResult&, const IntPoint&);
459 VisiblePosition positionForCoordinates(int x, int y);
460 virtual VisiblePosition positionForPoint(const IntPoint&);
462 virtual void dirtyLinesFromChangedChild(RenderObject*);
464 // Called to update a style that is allowed to trigger animations.
465 // FIXME: Right now this will typically be called only when updating happens from the DOM on explicit elements.
466 // We don't yet handle generated content animation such as first-letter or before/after (we'll worry about this later).
467 void setAnimatableStyle(PassRefPtr<RenderStyle>);
469 // Set the style of the object and update the state of the object accordingly.
470 virtual void setStyle(PassRefPtr<RenderStyle>);
472 // Updates only the local style ptr of the object. Does not update the state of the object,
473 // and so only should be called when the style is known not to have changed (or from setStyle).
474 void setStyleInternal(PassRefPtr<RenderStyle>);
476 // returns the containing block level element for this element.
477 RenderBlock* containingBlock() const;
479 // Convert the given local point to absolute coordinates
480 // FIXME: Temporary. If useTransforms is true, take transforms into account. Eventually localToAbsolute() will always be transform-aware.
481 FloatPoint localToAbsolute(FloatPoint localPoint = FloatPoint(), bool fixed = false, bool useTransforms = false) const;
482 FloatPoint absoluteToLocal(FloatPoint, bool fixed = false, bool useTransforms = false) const;
484 // Convert a local quad to absolute coordinates, taking transforms into account.
485 FloatQuad localToAbsoluteQuad(const FloatQuad& quad, bool fixed = false) const
487 return localToContainerQuad(quad, 0, fixed);
489 // Convert a local quad into the coordinate system of container, taking transforms into account.
490 FloatQuad localToContainerQuad(const FloatQuad&, RenderBoxModelObject* repaintContainer, bool fixed = false) const;
492 // Return the offset from the container() renderer (excluding transforms)
493 virtual IntSize offsetFromContainer(RenderObject*) const;
495 virtual void absoluteRectsForRange(Vector<IntRect>&, unsigned startOffset = 0, unsigned endOffset = UINT_MAX, bool useSelectionHeight = false);
497 virtual void absoluteRects(Vector<IntRect>&, int, int, bool = true) { }
498 // FIXME: useTransforms should go away eventually
499 IntRect absoluteBoundingBoxRect(bool useTransforms = false);
501 // Build an array of quads in absolute coords for line boxes
502 virtual void absoluteQuadsForRange(Vector<FloatQuad>&, unsigned startOffset = 0, unsigned endOffset = UINT_MAX, bool useSelectionHeight = false);
503 virtual void absoluteQuads(Vector<FloatQuad>&, bool /*topLevel*/ = true) { }
505 // the rect that will be painted if this object is passed as the paintingRoot
506 IntRect paintingRootRect(IntRect& topLevelRect);
508 virtual int minPrefWidth() const { return 0; }
509 virtual int maxPrefWidth() const { return 0; }
511 RenderStyle* style() const { return m_style.get(); }
512 RenderStyle* firstLineStyle() const { return document()->usesFirstLineRules() ? firstLineStyleSlowCase() : style(); }
513 RenderStyle* style(bool firstLine) const { return firstLine ? firstLineStyle() : style(); }
515 // Anonymous blocks that are part of of a continuation chain will return their inline continuation's outline style instead.
516 // This is typically only relevant when repainting.
517 virtual RenderStyle* outlineStyleForRepaint() const { return style(); }
519 void getTextDecorationColors(int decorations, Color& underline, Color& overline,
520 Color& linethrough, bool quirksMode = false);
522 // Return the RenderBox in the container chain which is responsible for painting this object, or 0
523 // if painting is root-relative. This is the container that should be passed to the 'forRepaint'
525 RenderBoxModelObject* containerForRepaint() const;
526 // Actually do the repaint of rect r for this object which has been computed in the coordinate space
527 // of repaintContainer. If repaintContainer is 0, repaint via the view.
528 void repaintUsingContainer(RenderBoxModelObject* repaintContainer, const IntRect& r, bool immediate = false);
530 // Repaint the entire object. Called when, e.g., the color of a border changes, or when a border
532 void repaint(bool immediate = false);
534 // Repaint a specific subrectangle within a given object. The rect |r| is in the object's coordinate space.
535 void repaintRectangle(const IntRect&, bool immediate = false);
537 // Repaint only if our old bounds and new bounds are different.
538 bool repaintAfterLayoutIfNeeded(RenderBoxModelObject* repaintContainer, const IntRect& oldBounds, const IntRect& oldOutlineBox);
540 // Repaint only if the object moved.
541 virtual void repaintDuringLayoutIfMoved(const IntRect& rect);
543 // Called to repaint a block's floats.
544 virtual void repaintOverhangingFloats(bool paintAllDescendants = false);
546 bool checkForRepaintDuringLayout() const;
548 // Returns the rect that should be repainted whenever this object changes. The rect is in the view's
549 // coordinate space. This method deals with outlines and overflow.
550 IntRect absoluteClippedOverflowRect()
552 return clippedOverflowRectForRepaint(0);
554 virtual IntRect clippedOverflowRectForRepaint(RenderBoxModelObject* repaintContainer);
555 virtual IntRect rectWithOutlineForRepaint(RenderBoxModelObject* repaintContainer, int outlineWidth);
557 // Given a rect in the object's coordinate space, compute a rect suitable for repainting
558 // that rect in view coordinates.
559 void computeAbsoluteRepaintRect(IntRect& r, bool fixed = false)
561 return computeRectForRepaint(0, r, fixed);
563 // Given a rect in the object's coordinate space, compute a rect suitable for repainting
564 // that rect in the coordinate space of repaintContainer.
565 virtual void computeRectForRepaint(RenderBoxModelObject* repaintContainer, IntRect&, bool fixed = false);
567 virtual unsigned int length() const { return 1; }
569 bool isFloatingOrPositioned() const { return (isFloating() || isPositioned()); }
571 bool isTransparent() const { return style()->opacity() < 1.0f; }
572 float opacity() const { return style()->opacity(); }
574 bool hasReflection() const { return m_hasReflection; }
576 // Applied as a "slop" to dirty rect checks during the outline painting phase's dirty-rect checks.
577 int maximalOutlineSize(PaintPhase) const;
579 void setHasMarkupTruncation(bool b = true) { m_hasMarkupTruncation = b; }
580 bool hasMarkupTruncation() const { return m_hasMarkupTruncation; }
582 enum SelectionState {
583 SelectionNone, // The object is not selected.
584 SelectionStart, // The object either contains the start of a selection run or is the start of a run
585 SelectionInside, // The object is fully encompassed by a selection run
586 SelectionEnd, // The object either contains the end of a selection run or is the end of a run
587 SelectionBoth // The object contains an entire run or is the sole selected object in that run
590 // The current selection state for an object. For blocks, the state refers to the state of the leaf
591 // descendants (as described above in the SelectionState enum declaration).
592 SelectionState selectionState() const { return static_cast<SelectionState>(m_selectionState);; }
594 // Sets the selection state for an object.
595 virtual void setSelectionState(SelectionState state) { m_selectionState = state; }
597 // A single rectangle that encompasses all of the selected objects within this object. Used to determine the tightest
598 // possible bounding box for the selection.
599 IntRect selectionRect(bool clipToVisibleContent = true) { return selectionRectForRepaint(0, clipToVisibleContent); }
600 virtual IntRect selectionRectForRepaint(RenderBoxModelObject* /*repaintContainer*/, bool /*clipToVisibleContent*/ = true) { return IntRect(); }
602 // Whether or not an object can be part of the leaf elements of the selection.
603 virtual bool canBeSelectionLeaf() const { return false; }
605 // Whether or not a block has selected children.
606 bool hasSelectedChildren() const { return m_selectionState != SelectionNone; }
608 // Obtains the selection colors that should be used when painting a selection.
609 Color selectionBackgroundColor() const;
610 Color selectionForegroundColor() const;
612 // Whether or not a given block needs to paint selection gaps.
613 virtual bool shouldPaintSelectionGaps() const { return false; }
615 Node* draggableNode(bool dhtmlOK, bool uaOK, int x, int y, bool& dhtmlWillDrag) const;
618 * Returns the local coordinates of the caret within this render object.
619 * @param caretOffset zero-based offset determining position within the render object.
620 * @param extraWidthToEndOfLine optional out arg to give extra width to end of line -
621 * useful for character range rect computations
623 virtual IntRect localCaretRect(InlineBox*, int caretOffset, int* extraWidthToEndOfLine = 0);
625 virtual void calcVerticalMargins() { }
626 bool isTopMarginQuirk() const { return m_topMarginQuirk; }
627 bool isBottomMarginQuirk() const { return m_bottomMarginQuirk; }
628 void setTopMarginQuirk(bool b = true) { m_topMarginQuirk = b; }
629 void setBottomMarginQuirk(bool b = true) { m_bottomMarginQuirk = b; }
631 // When performing a global document tear-down, the renderer of the document is cleared. We use this
632 // as a hook to detect the case of document destruction and don't waste time doing unnecessary work.
633 bool documentBeingDestroyed() const;
635 virtual void destroy();
637 // Virtual function helpers for CSS3 Flexible Box Layout
638 virtual bool isFlexibleBox() const { return false; }
639 virtual bool isFlexingChildren() const { return false; }
640 virtual bool isStretchingChildren() const { return false; }
642 virtual int caretMinOffset() const;
643 virtual int caretMaxOffset() const;
644 virtual unsigned caretMaxRenderedOffset() const;
646 virtual int previousOffset(int current) const;
647 virtual int previousOffsetForBackwardDeletion(int current) const;
648 virtual int nextOffset(int current) const;
650 virtual void imageChanged(CachedImage*, const IntRect* = 0);
651 virtual void imageChanged(WrappedImagePtr, const IntRect* = 0) { }
652 virtual bool willRenderImage(CachedImage*);
654 void selectionStartEnd(int& spos, int& epos) const;
656 RenderObject* paintingRootForChildren(PaintInfo& paintInfo) const
658 // if we're the painting root, kids draw normally, and see root of 0
659 return (!paintInfo.paintingRoot || paintInfo.paintingRoot == this) ? 0 : paintInfo.paintingRoot;
662 bool shouldPaintWithinRoot(PaintInfo& paintInfo) const
664 return !paintInfo.paintingRoot || paintInfo.paintingRoot == this;
667 bool hasOverrideSize() const { return m_hasOverrideSize; }
668 void setHasOverrideSize(bool b) { m_hasOverrideSize = b; }
670 void remove() { if (parent()) parent()->removeChild(this); }
672 AnimationController* animation() const;
674 bool visibleToHitTesting() const { return style()->visibility() == VISIBLE && style()->pointerEvents() != PE_NONE; }
676 // Map points and quads through elements, potentially via 3d transforms. You should never need to call these directly; use
677 // localToAbsolute/absoluteToLocal methods instead.
678 virtual void mapLocalToContainer(RenderBoxModelObject* repaintContainer, bool useTransforms, bool fixed, TransformState&) const;
679 virtual void mapAbsoluteToLocalPoint(bool fixed, bool useTransforms, TransformState&) const;
681 TransformationMatrix transformFromContainer(const RenderObject* container, const IntSize& offsetInContainer) const;
683 virtual void addFocusRingRects(GraphicsContext*, int /*tx*/, int /*ty*/) { };
685 IntRect absoluteOutlineBounds() const
687 return outlineBoundsForRepaint(0);
690 bool replacedHasOverflow() const { return m_replacedHasOverflow; }
691 void setReplacedHasOverflow(bool b = true) { m_replacedHasOverflow = b; }
694 // Overrides should call the superclass at the end
695 virtual void styleWillChange(StyleDifference, const RenderStyle* newStyle);
696 // Overrides should call the superclass at the start
697 virtual void styleDidChange(StyleDifference, const RenderStyle* oldStyle);
699 void paintOutline(GraphicsContext*, int tx, int ty, int w, int h, const RenderStyle*);
700 void addPDFURLRect(GraphicsContext*, const IntRect&);
702 virtual IntRect viewRect() const;
704 void adjustRectForOutlineAndShadow(IntRect&) const;
706 void arenaDelete(RenderArena*, void* objectBase);
708 virtual IntRect outlineBoundsForRepaint(RenderBoxModelObject* /*repaintContainer*/) const { return IntRect(); }
710 class LayoutRepainter {
712 LayoutRepainter(RenderObject& object, bool checkForRepaint, const IntRect* oldBounds = 0)
714 , m_repaintContainer(0)
715 , m_checkForRepaint(checkForRepaint)
717 if (m_checkForRepaint) {
718 m_repaintContainer = m_object.containerForRepaint();
719 m_oldBounds = oldBounds ? *oldBounds : m_object.clippedOverflowRectForRepaint(m_repaintContainer);
720 m_oldOutlineBox = m_object.outlineBoundsForRepaint(m_repaintContainer);
724 // Return true if it repainted.
725 bool repaintAfterLayout()
727 return m_checkForRepaint ? m_object.repaintAfterLayoutIfNeeded(m_repaintContainer, m_oldBounds, m_oldOutlineBox) : false;
730 bool checkForRepaint() const { return m_checkForRepaint; }
733 RenderObject& m_object;
734 RenderBoxModelObject* m_repaintContainer;
736 IntRect m_oldOutlineBox;
737 bool m_checkForRepaint;
741 RenderStyle* firstLineStyleSlowCase() const;
742 StyleDifference adjustStyleDifference(StyleDifference, unsigned contextSensitiveProperties) const;
744 RefPtr<RenderStyle> m_style;
748 RenderObject* m_parent;
749 RenderObject* m_previous;
750 RenderObject* m_next;
754 bool m_setNeedsLayoutForbidden : 1;
757 // 32 bits have been used here. THERE ARE NO FREE BITS AVAILABLE.
758 bool m_needsLayout : 1;
759 bool m_needsPositionedMovementLayout :1;
760 bool m_normalChildNeedsLayout : 1;
761 bool m_posChildNeedsLayout : 1;
762 bool m_prefWidthsDirty : 1;
765 bool m_positioned : 1;
766 bool m_relPositioned : 1;
767 bool m_paintBackground : 1; // if the box has something to paint in the
768 // background painting phase (background, border, etc)
770 bool m_isAnonymous : 1;
775 bool m_isDragging : 1;
778 bool m_hasOverflowClip : 1;
779 bool m_hasTransform : 1;
780 bool m_hasReflection : 1;
782 bool m_hasOverrideSize : 1;
785 bool m_hasCounterNodeMap : 1;
786 bool m_everHadLayout : 1;
789 // These bitfields are moved here from subclasses to pack them together
791 bool m_childrenInline : 1;
792 bool m_topMarginQuirk : 1;
793 bool m_bottomMarginQuirk : 1;
794 bool m_hasMarkupTruncation : 1;
795 unsigned m_selectionState : 3; // SelectionState
796 bool m_hasColumns : 1;
798 // from RenderTableCell
799 bool m_cellWidthChanged : 1;
801 // from RenderReplaced
802 bool m_replacedHasOverflow : 1;
805 // Store state between styleWillChange and styleDidChange
806 static bool s_affectsParentBlock;
809 inline bool RenderObject::documentBeingDestroyed() const
811 return !document()->renderer();
814 inline void RenderObject::setNeedsLayout(bool b, bool markParents)
816 bool alreadyNeededLayout = m_needsLayout;
819 ASSERT(!isSetNeedsLayoutForbidden());
820 if (!alreadyNeededLayout) {
822 markContainingBlocksForLayout();
824 setLayerNeedsFullRepaint();
827 m_everHadLayout = true;
828 m_posChildNeedsLayout = false;
829 m_normalChildNeedsLayout = false;
830 m_needsPositionedMovementLayout = false;
834 inline void RenderObject::setChildNeedsLayout(bool b, bool markParents)
836 bool alreadyNeededLayout = m_normalChildNeedsLayout;
837 m_normalChildNeedsLayout = b;
839 ASSERT(!isSetNeedsLayoutForbidden());
840 if (!alreadyNeededLayout && markParents)
841 markContainingBlocksForLayout();
843 m_posChildNeedsLayout = false;
844 m_normalChildNeedsLayout = false;
845 m_needsPositionedMovementLayout = false;
849 inline void RenderObject::setNeedsPositionedMovementLayout()
851 bool alreadyNeededLayout = needsLayout();
852 m_needsPositionedMovementLayout = true;
853 if (!alreadyNeededLayout) {
854 markContainingBlocksForLayout();
856 setLayerNeedsFullRepaint();
860 inline bool objectIsRelayoutBoundary(const RenderObject *obj)
862 // FIXME: In future it may be possible to broaden this condition in order to improve performance.
863 // Table cells are excluded because even when their CSS height is fixed, their height()
864 // may depend on their contents.
865 return obj->isTextControl()
866 || obj->hasOverflowClip() && !obj->style()->width().isIntrinsicOrAuto() && !obj->style()->height().isIntrinsicOrAuto() && !obj->style()->height().isPercent() && !obj->isTableCell()
873 inline void RenderObject::markContainingBlocksForLayout(bool scheduleRelayout, RenderObject* newRoot)
875 ASSERT(!scheduleRelayout || !newRoot);
877 RenderObject* o = container();
878 RenderObject* last = this;
881 if (!last->isText() && (last->style()->position() == FixedPosition || last->style()->position() == AbsolutePosition)) {
882 if ((last->style()->top().isAuto() && last->style()->bottom().isAuto()) || last->style()->top().isStatic()) {
883 RenderObject* parent = last->parent();
884 if (!parent->normalChildNeedsLayout()) {
885 parent->setChildNeedsLayout(true, false);
886 if (parent != newRoot)
887 parent->markContainingBlocksForLayout(scheduleRelayout, newRoot);
890 if (o->m_posChildNeedsLayout)
892 o->m_posChildNeedsLayout = true;
893 ASSERT(!o->isSetNeedsLayoutForbidden());
895 if (o->m_normalChildNeedsLayout)
897 o->m_normalChildNeedsLayout = true;
898 ASSERT(!o->isSetNeedsLayoutForbidden());
905 if (scheduleRelayout && objectIsRelayoutBoundary(last))
910 if (scheduleRelayout)
911 last->scheduleRelayout();
914 } // namespace WebCore
917 // Outside the WebCore namespace for ease of invocation from gdb.
918 void showTree(const WebCore::RenderObject*);
921 #endif // RenderObject_h