| 1 | /* |
|---|
| 2 | * Copyright (C) 2000 Lars Knoll (knoll@kde.org) |
|---|
| 3 | * (C) 2000 Antti Koivisto (koivisto@kde.org) |
|---|
| 4 | * (C) 2000 Dirk Mueller (mueller@kde.org) |
|---|
| 5 | * (C) 2004 Allan Sandfeld Jensen (kde@carewolf.com) |
|---|
| 6 | * Copyright (C) 2003, 2004, 2005, 2006, 2007, 2008 Apple Inc. All rights reserved. |
|---|
| 7 | * |
|---|
| 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. |
|---|
| 12 | * |
|---|
| 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. |
|---|
| 17 | * |
|---|
| 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. |
|---|
| 22 | * |
|---|
| 23 | */ |
|---|
| 24 | |
|---|
| 25 | #ifndef RenderObject_h |
|---|
| 26 | #define RenderObject_h |
|---|
| 27 | |
|---|
| 28 | #include "CachedResourceClient.h" |
|---|
| 29 | #include "Document.h" |
|---|
| 30 | #include "FloatQuad.h" |
|---|
| 31 | #include "RenderStyle.h" |
|---|
| 32 | #include "ScrollTypes.h" |
|---|
| 33 | #include "VisiblePosition.h" |
|---|
| 34 | #include <wtf/HashMap.h> |
|---|
| 35 | |
|---|
| 36 | namespace WebCore { |
|---|
| 37 | |
|---|
| 38 | class AffineTransform; |
|---|
| 39 | class AnimationController; |
|---|
| 40 | class Color; |
|---|
| 41 | class Document; |
|---|
| 42 | class Element; |
|---|
| 43 | class Event; |
|---|
| 44 | class FloatRect; |
|---|
| 45 | class FrameView; |
|---|
| 46 | class HTMLAreaElement; |
|---|
| 47 | class HitTestResult; |
|---|
| 48 | class InlineBox; |
|---|
| 49 | class InlineFlowBox; |
|---|
| 50 | class Position; |
|---|
| 51 | class RenderArena; |
|---|
| 52 | class RenderBlock; |
|---|
| 53 | class RenderFlow; |
|---|
| 54 | class RenderFrameSet; |
|---|
| 55 | class RenderLayer; |
|---|
| 56 | class RenderTable; |
|---|
| 57 | class RenderText; |
|---|
| 58 | class RenderView; |
|---|
| 59 | class String; |
|---|
| 60 | |
|---|
| 61 | struct HitTestRequest; |
|---|
| 62 | |
|---|
| 63 | /* |
|---|
| 64 | * The painting of a layer occurs in three distinct phases. Each phase involves |
|---|
| 65 | * a recursive descent into the layer's render objects. The first phase is the background phase. |
|---|
| 66 | * The backgrounds and borders of all blocks are painted. Inlines are not painted at all. |
|---|
| 67 | * Floats must paint above block backgrounds but entirely below inline content that can overlap them. |
|---|
| 68 | * In the foreground phase, all inlines are fully painted. Inline replaced elements will get all |
|---|
| 69 | * three phases invoked on them during this phase. |
|---|
| 70 | */ |
|---|
| 71 | |
|---|
| 72 | enum PaintPhase { |
|---|
| 73 | PaintPhaseBlockBackground, |
|---|
| 74 | PaintPhaseChildBlockBackground, |
|---|
| 75 | PaintPhaseChildBlockBackgrounds, |
|---|
| 76 | PaintPhaseFloat, |
|---|
| 77 | PaintPhaseForeground, |
|---|
| 78 | PaintPhaseOutline, |
|---|
| 79 | PaintPhaseChildOutlines, |
|---|
| 80 | PaintPhaseSelfOutline, |
|---|
| 81 | PaintPhaseSelection, |
|---|
| 82 | PaintPhaseCollapsedTableBorders, |
|---|
| 83 | PaintPhaseTextClip, |
|---|
| 84 | PaintPhaseMask |
|---|
| 85 | }; |
|---|
| 86 | |
|---|
| 87 | enum PaintRestriction { |
|---|
| 88 | PaintRestrictionNone, |
|---|
| 89 | PaintRestrictionSelectionOnly, |
|---|
| 90 | PaintRestrictionSelectionOnlyBlackText |
|---|
| 91 | }; |
|---|
| 92 | |
|---|
| 93 | enum HitTestFilter { |
|---|
| 94 | HitTestAll, |
|---|
| 95 | HitTestSelf, |
|---|
| 96 | HitTestDescendants |
|---|
| 97 | }; |
|---|
| 98 | |
|---|
| 99 | enum HitTestAction { |
|---|
| 100 | HitTestBlockBackground, |
|---|
| 101 | HitTestChildBlockBackground, |
|---|
| 102 | HitTestChildBlockBackgrounds, |
|---|
| 103 | HitTestFloat, |
|---|
| 104 | HitTestForeground |
|---|
| 105 | }; |
|---|
| 106 | |
|---|
| 107 | enum VerticalPositionHint { |
|---|
| 108 | PositionTop = -0x7fffffff, |
|---|
| 109 | PositionBottom = 0x7fffffff, |
|---|
| 110 | PositionUndefined = static_cast<int>(0x80000000) |
|---|
| 111 | }; |
|---|
| 112 | |
|---|
| 113 | #if ENABLE(DASHBOARD_SUPPORT) |
|---|
| 114 | struct DashboardRegionValue { |
|---|
| 115 | bool operator==(const DashboardRegionValue& o) const |
|---|
| 116 | { |
|---|
| 117 | return type == o.type && bounds == o.bounds && clip == o.clip && label == o.label; |
|---|
| 118 | } |
|---|
| 119 | bool operator!=(const DashboardRegionValue& o) const |
|---|
| 120 | { |
|---|
| 121 | return !(*this == o); |
|---|
| 122 | } |
|---|
| 123 | |
|---|
| 124 | String label; |
|---|
| 125 | IntRect bounds; |
|---|
| 126 | IntRect clip; |
|---|
| 127 | int type; |
|---|
| 128 | }; |
|---|
| 129 | #endif |
|---|
| 130 | |
|---|
| 131 | // FIXME: This should be a HashSequencedSet, but we don't have that data structure yet. |
|---|
| 132 | // This means the paint order of outlines will be wrong, although this is a minor issue. |
|---|
| 133 | typedef HashSet<RenderFlow*> RenderFlowSequencedSet; |
|---|
| 134 | |
|---|
| 135 | // Base class for all rendering tree objects. |
|---|
| 136 | class RenderObject : public CachedResourceClient { |
|---|
| 137 | friend class RenderContainer; |
|---|
| 138 | friend class RenderSVGContainer; |
|---|
| 139 | friend class RenderLayer; |
|---|
| 140 | public: |
|---|
| 141 | // Anonymous objects should pass the document as their node, and they will then automatically be |
|---|
| 142 | // marked as anonymous in the constructor. |
|---|
| 143 | RenderObject(Node*); |
|---|
| 144 | virtual ~RenderObject(); |
|---|
| 145 | |
|---|
| 146 | virtual const char* renderName() const { return "RenderObject"; } |
|---|
| 147 | |
|---|
| 148 | RenderObject* parent() const { return m_parent; } |
|---|
| 149 | bool isDescendantOf(const RenderObject*) const; |
|---|
| 150 | |
|---|
| 151 | RenderObject* previousSibling() const { return m_previous; } |
|---|
| 152 | RenderObject* nextSibling() const { return m_next; } |
|---|
| 153 | |
|---|
| 154 | virtual RenderObject* firstChild() const { return 0; } |
|---|
| 155 | virtual RenderObject* lastChild() const { return 0; } |
|---|
| 156 | |
|---|
| 157 | RenderObject* nextInPreOrder() const; |
|---|
| 158 | RenderObject* nextInPreOrder(RenderObject* stayWithin) const; |
|---|
| 159 | RenderObject* nextInPreOrderAfterChildren() const; |
|---|
| 160 | RenderObject* nextInPreOrderAfterChildren(RenderObject* stayWithin) const; |
|---|
| 161 | RenderObject* previousInPreOrder() const; |
|---|
| 162 | RenderObject* childAt(unsigned) const; |
|---|
| 163 | |
|---|
| 164 | RenderObject* firstLeafChild() const; |
|---|
| 165 | RenderObject* lastLeafChild() const; |
|---|
| 166 | |
|---|
| 167 | virtual RenderLayer* layer() const { return 0; } |
|---|
| 168 | RenderLayer* enclosingLayer() const; |
|---|
| 169 | void addLayers(RenderLayer* parentLayer, RenderObject* newObject); |
|---|
| 170 | void removeLayers(RenderLayer* parentLayer); |
|---|
| 171 | void moveLayers(RenderLayer* oldParent, RenderLayer* newParent); |
|---|
| 172 | RenderLayer* findNextLayer(RenderLayer* parentLayer, RenderObject* startPoint, bool checkParent = true); |
|---|
| 173 | virtual void positionChildLayers() { } |
|---|
| 174 | virtual bool requiresLayer(); |
|---|
| 175 | |
|---|
| 176 | virtual IntRect getOverflowClipRect(int /*tx*/, int /*ty*/) { return IntRect(0, 0, 0, 0); } |
|---|
| 177 | virtual IntRect getClipRect(int /*tx*/, int /*ty*/) { return IntRect(0, 0, 0, 0); } |
|---|
| 178 | bool hasClip() { return isPositioned() && style()->hasClip(); } |
|---|
| 179 | |
|---|
| 180 | virtual int getBaselineOfFirstLineBox() const { return -1; } |
|---|
| 181 | virtual int getBaselineOfLastLineBox() const { return -1; } |
|---|
| 182 | |
|---|
| 183 | virtual bool isEmpty() const { return firstChild() == 0; } |
|---|
| 184 | |
|---|
| 185 | virtual bool isEdited() const { return false; } |
|---|
| 186 | virtual void setEdited(bool) { } |
|---|
| 187 | |
|---|
| 188 | #ifndef NDEBUG |
|---|
| 189 | void setHasAXObject(bool flag) { m_hasAXObject = flag; } |
|---|
| 190 | bool hasAXObject() const { return m_hasAXObject; } |
|---|
| 191 | #endif |
|---|
| 192 | |
|---|
| 193 | // Obtains the nearest enclosing block (including this block) that contributes a first-line style to our inline |
|---|
| 194 | // children. |
|---|
| 195 | virtual RenderBlock* firstLineBlock() const; |
|---|
| 196 | |
|---|
| 197 | // Called when an object that was floating or positioned becomes a normal flow object |
|---|
| 198 | // again. We have to make sure the render tree updates as needed to accommodate the new |
|---|
| 199 | // normal flow object. |
|---|
| 200 | void handleDynamicFloatPositionChange(); |
|---|
| 201 | |
|---|
| 202 | // This function is a convenience helper for creating an anonymous block that inherits its |
|---|
| 203 | // style from this RenderObject. |
|---|
| 204 | RenderBlock* createAnonymousBlock(); |
|---|
| 205 | |
|---|
| 206 | // Whether or not a positioned element requires normal flow x/y to be computed |
|---|
| 207 | // to determine its position. |
|---|
| 208 | bool hasStaticX() const; |
|---|
| 209 | bool hasStaticY() const; |
|---|
| 210 | virtual void setStaticX(int /*staticX*/) { } |
|---|
| 211 | virtual void setStaticY(int /*staticY*/) { } |
|---|
| 212 | virtual int staticX() const { return 0; } |
|---|
| 213 | virtual int staticY() const { return 0; } |
|---|
| 214 | |
|---|
| 215 | // RenderObject tree manipulation |
|---|
| 216 | ////////////////////////////////////////// |
|---|
| 217 | virtual bool canHaveChildren() const; |
|---|
| 218 | virtual bool isChildAllowed(RenderObject*, RenderStyle*) const { return true; } |
|---|
| 219 | virtual void addChild(RenderObject* newChild, RenderObject* beforeChild = 0); |
|---|
| 220 | virtual void removeChild(RenderObject*); |
|---|
| 221 | virtual bool createsAnonymousWrapper() const { return false; } |
|---|
| 222 | |
|---|
| 223 | // raw tree manipulation |
|---|
| 224 | virtual RenderObject* removeChildNode(RenderObject*, bool fullRemove = true); |
|---|
| 225 | virtual void appendChildNode(RenderObject*, bool fullAppend = true); |
|---|
| 226 | virtual void insertChildNode(RenderObject* child, RenderObject* before, bool fullInsert = true); |
|---|
| 227 | // Designed for speed. Don't waste time doing a bunch of work like layer updating and repainting when we know that our |
|---|
| 228 | // change in parentage is not going to affect anything. |
|---|
| 229 | virtual void moveChildNode(RenderObject*); |
|---|
| 230 | ////////////////////////////////////////// |
|---|
| 231 | |
|---|
| 232 | protected: |
|---|
| 233 | ////////////////////////////////////////// |
|---|
| 234 | // Helper functions. Dangerous to use! |
|---|
| 235 | void setPreviousSibling(RenderObject* previous) { m_previous = previous; } |
|---|
| 236 | void setNextSibling(RenderObject* next) { m_next = next; } |
|---|
| 237 | void setParent(RenderObject* parent) { m_parent = parent; } |
|---|
| 238 | ////////////////////////////////////////// |
|---|
| 239 | private: |
|---|
| 240 | void addAbsoluteRectForLayer(IntRect& result); |
|---|
| 241 | |
|---|
| 242 | public: |
|---|
| 243 | #ifndef NDEBUG |
|---|
| 244 | void showTreeForThis() const; |
|---|
| 245 | #endif |
|---|
| 246 | |
|---|
| 247 | static RenderObject* createObject(Node*, RenderStyle*); |
|---|
| 248 | |
|---|
| 249 | // Overloaded new operator. Derived classes must override operator new |
|---|
| 250 | // in order to allocate out of the RenderArena. |
|---|
| 251 | void* operator new(size_t, RenderArena*) throw(); |
|---|
| 252 | |
|---|
| 253 | // Overridden to prevent the normal delete from being called. |
|---|
| 254 | void operator delete(void*, size_t); |
|---|
| 255 | |
|---|
| 256 | private: |
|---|
| 257 | // The normal operator new is disallowed on all render objects. |
|---|
| 258 | void* operator new(size_t) throw(); |
|---|
| 259 | |
|---|
| 260 | public: |
|---|
| 261 | RenderArena* renderArena() const { return document()->renderArena(); } |
|---|
| 262 | |
|---|
| 263 | virtual bool isApplet() const { return false; } |
|---|
| 264 | virtual bool isBR() const { return false; } |
|---|
| 265 | virtual bool isBlockFlow() const { return false; } |
|---|
| 266 | virtual bool isCounter() const { return false; } |
|---|
| 267 | virtual bool isFieldset() const { return false; } |
|---|
| 268 | virtual bool isFrame() const { return false; } |
|---|
| 269 | virtual bool isFrameSet() const { return false; } |
|---|
| 270 | virtual bool isImage() const { return false; } |
|---|
| 271 | virtual bool isInlineBlockOrInlineTable() const { return false; } |
|---|
| 272 | virtual bool isInlineContinuation() const; |
|---|
| 273 | virtual bool isInlineFlow() const { return false; } |
|---|
| 274 | virtual bool isListBox() const { return false; } |
|---|
| 275 | virtual bool isListItem() const { return false; } |
|---|
| 276 | virtual bool isListMarker() const { return false; } |
|---|
| 277 | virtual bool isMedia() const { return false; } |
|---|
| 278 | virtual bool isMenuList() const { return false; } |
|---|
| 279 | virtual bool isRenderBlock() const { return false; } |
|---|
| 280 | virtual bool isRenderImage() const { return false; } |
|---|
| 281 | virtual bool isRenderInline() const { return false; } |
|---|
| 282 | virtual bool isRenderPart() const { return false; } |
|---|
| 283 | virtual bool isRenderView() const { return false; } |
|---|
| 284 | virtual bool isSlider() const { return false; } |
|---|
| 285 | virtual bool isTable() const { return false; } |
|---|
| 286 | virtual bool isTableCell() const { return false; } |
|---|
| 287 | virtual bool isTableCol() const { return false; } |
|---|
| 288 | virtual bool isTableRow() const { return false; } |
|---|
| 289 | virtual bool isTableSection() const { return false; } |
|---|
| 290 | virtual bool isTextArea() const { return false; } |
|---|
| 291 | virtual bool isTextField() const { return false; } |
|---|
| 292 | virtual bool isWidget() const { return false; } |
|---|
| 293 | |
|---|
| 294 | |
|---|
| 295 | bool isRoot() const { return document()->documentElement() == node(); } |
|---|
| 296 | bool isBody() const; |
|---|
| 297 | bool isHR() const; |
|---|
| 298 | |
|---|
| 299 | bool isHTMLMarquee() const; |
|---|
| 300 | |
|---|
| 301 | virtual bool childrenInline() const { return false; } |
|---|
| 302 | virtual void setChildrenInline(bool) { } |
|---|
| 303 | |
|---|
| 304 | virtual RenderFlow* continuation() const; |
|---|
| 305 | |
|---|
| 306 | #if ENABLE(SVG) |
|---|
| 307 | virtual bool isSVGRoot() const { return false; } |
|---|
| 308 | virtual bool isSVGContainer() const { return false; } |
|---|
| 309 | virtual bool isSVGHiddenContainer() const { return false; } |
|---|
| 310 | virtual bool isRenderPath() const { return false; } |
|---|
| 311 | virtual bool isSVGText() const { return false; } |
|---|
| 312 | |
|---|
| 313 | virtual FloatRect relativeBBox(bool includeStroke = true) const; |
|---|
| 314 | |
|---|
| 315 | virtual AffineTransform localTransform() const; |
|---|
| 316 | virtual AffineTransform absoluteTransform() const; |
|---|
| 317 | #endif |
|---|
| 318 | |
|---|
| 319 | virtual bool isEditable() const; |
|---|
| 320 | |
|---|
| 321 | bool isAnonymous() const { return m_isAnonymous; } |
|---|
| 322 | void setIsAnonymous(bool b) { m_isAnonymous = b; } |
|---|
| 323 | bool isAnonymousBlock() const |
|---|
| 324 | { |
|---|
| 325 | return m_isAnonymous && style()->display() == BLOCK && style()->styleType() == RenderStyle::NOPSEUDO && !isListMarker(); |
|---|
| 326 | } |
|---|
| 327 | |
|---|
| 328 | bool isFloating() const { return m_floating; } |
|---|
| 329 | bool isPositioned() const { return m_positioned; } // absolute or fixed positioning |
|---|
| 330 | bool isRelPositioned() const { return m_relPositioned; } // relative positioning |
|---|
| 331 | bool isText() const { return m_isText; } |
|---|
| 332 | bool isInline() const { return m_inline; } // inline object |
|---|
| 333 | bool isCompact() const { return style()->display() == COMPACT; } // compact object |
|---|
| 334 | bool isRunIn() const { return style()->display() == RUN_IN; } // run-in object |
|---|
| 335 | bool isDragging() const { return m_isDragging; } |
|---|
| 336 | bool isReplaced() const { return m_replaced; } // a "replaced" element (see CSS) |
|---|
| 337 | |
|---|
| 338 | bool hasLayer() const { return m_hasLayer; } |
|---|
| 339 | |
|---|
| 340 | bool hasBoxDecorations() const { return m_paintBackground; } |
|---|
| 341 | bool mustRepaintBackgroundOrBorder() const; |
|---|
| 342 | |
|---|
| 343 | bool hasHorizontalBordersPaddingOrMargin() const { return hasHorizontalBordersOrPadding() || marginLeft() != 0 || marginRight() != 0; } |
|---|
| 344 | bool hasHorizontalBordersOrPadding() const { return borderLeft() != 0 || borderRight() != 0 || paddingLeft() != 0 || paddingRight() != 0; } |
|---|
| 345 | |
|---|
| 346 | bool needsLayout() const { return m_needsLayout || m_normalChildNeedsLayout || m_posChildNeedsLayout || m_needsPositionedMovementLayout; } |
|---|
| 347 | bool selfNeedsLayout() const { return m_needsLayout; } |
|---|
| 348 | bool needsPositionedMovementLayout() const { return m_needsPositionedMovementLayout; } |
|---|
| 349 | bool needsPositionedMovementLayoutOnly() const { return m_needsPositionedMovementLayout && !m_needsLayout && !m_normalChildNeedsLayout && !m_posChildNeedsLayout; } |
|---|
| 350 | bool posChildNeedsLayout() const { return m_posChildNeedsLayout; } |
|---|
| 351 | bool normalChildNeedsLayout() const { return m_normalChildNeedsLayout; } |
|---|
| 352 | |
|---|
| 353 | bool prefWidthsDirty() const { return m_prefWidthsDirty; } |
|---|
| 354 | |
|---|
| 355 | bool isSelectionBorder() const; |
|---|
| 356 | |
|---|
| 357 | bool hasOverflowClip() const { return m_hasOverflowClip; } |
|---|
| 358 | virtual bool hasControlClip() const { return false; } |
|---|
| 359 | virtual IntRect controlClipRect(int /*tx*/, int /*ty*/) const { return IntRect(); } |
|---|
| 360 | |
|---|
| 361 | bool hasAutoVerticalScrollbar() const { return hasOverflowClip() && (style()->overflowY() == OAUTO || style()->overflowY() == OOVERLAY); } |
|---|
| 362 | bool hasAutoHorizontalScrollbar() const { return hasOverflowClip() && (style()->overflowX() == OAUTO || style()->overflowX() == OOVERLAY); } |
|---|
| 363 | |
|---|
| 364 | bool scrollsOverflow() const { return scrollsOverflowX() || scrollsOverflowY(); } |
|---|
| 365 | bool scrollsOverflowX() const { return hasOverflowClip() && (style()->overflowX() == OSCROLL || hasAutoHorizontalScrollbar()); } |
|---|
| 366 | bool scrollsOverflowY() const { return hasOverflowClip() && (style()->overflowY() == OSCROLL || hasAutoVerticalScrollbar()); } |
|---|
| 367 | |
|---|
| 368 | virtual int verticalScrollbarWidth() const; |
|---|
| 369 | virtual int horizontalScrollbarHeight() const; |
|---|
| 370 | |
|---|
| 371 | bool hasTransform() const { return m_hasTransform; } |
|---|
| 372 | bool hasMask() const { return style() && style()->hasMask(); } |
|---|
| 373 | virtual IntRect maskClipRect() { return borderBox(); } |
|---|
| 374 | |
|---|
| 375 | private: |
|---|
| 376 | bool includeVerticalScrollbarSize() const { return hasOverflowClip() && (style()->overflowY() == OSCROLL || style()->overflowY() == OAUTO); } |
|---|
| 377 | bool includeHorizontalScrollbarSize() const { return hasOverflowClip() && (style()->overflowX() == OSCROLL || style()->overflowX() == OAUTO); } |
|---|
| 378 | |
|---|
| 379 | public: |
|---|
| 380 | // The pseudo element style can be cached or uncached. Use the cached method if the pseudo element doesn't respect |
|---|
| 381 | // any pseudo classes (and therefore has no concept of changing state). |
|---|
| 382 | RenderStyle* getCachedPseudoStyle(RenderStyle::PseudoId, RenderStyle* parentStyle = 0) const; |
|---|
| 383 | PassRefPtr<RenderStyle> getUncachedPseudoStyle(RenderStyle::PseudoId, RenderStyle* parentStyle = 0) const; |
|---|
| 384 | |
|---|
| 385 | void updateDragState(bool dragOn); |
|---|
| 386 | |
|---|
| 387 | RenderView* view() const; |
|---|
| 388 | |
|---|
| 389 | // don't even think about making this method virtual! |
|---|
| 390 | Node* element() const { return m_isAnonymous ? 0 : m_node; } |
|---|
| 391 | Document* document() const { return m_node->document(); } |
|---|
| 392 | void setNode(Node* node) { m_node = node; } |
|---|
| 393 | Node* node() const { return m_node; } |
|---|
| 394 | |
|---|
| 395 | bool hasOutlineAnnotation() const; |
|---|
| 396 | bool hasOutline() const { return style()->hasOutline() || hasOutlineAnnotation(); } |
|---|
| 397 | |
|---|
| 398 | /** |
|---|
| 399 | * returns the object containing this one. can be different from parent for |
|---|
| 400 | * positioned elements |
|---|
| 401 | */ |
|---|
| 402 | RenderObject* container() const; |
|---|
| 403 | RenderObject* hoverAncestor() const; |
|---|
| 404 | |
|---|
| 405 | virtual void markAllDescendantsWithFloatsForLayout(RenderObject* floatToRemove = 0); |
|---|
| 406 | void markContainingBlocksForLayout(bool scheduleRelayout = true, RenderObject* newRoot = 0); |
|---|
| 407 | void setNeedsLayout(bool b, bool markParents = true); |
|---|
| 408 | void setChildNeedsLayout(bool b, bool markParents = true); |
|---|
| 409 | void setNeedsPositionedMovementLayout(); |
|---|
| 410 | void setPrefWidthsDirty(bool, bool markParents = true); |
|---|
| 411 | void invalidateContainerPrefWidths(); |
|---|
| 412 | virtual void invalidateCounters() { } |
|---|
| 413 | |
|---|
| 414 | void setNeedsLayoutAndPrefWidthsRecalc() |
|---|
| 415 | { |
|---|
| 416 | setNeedsLayout(true); |
|---|
| 417 | setPrefWidthsDirty(true); |
|---|
| 418 | } |
|---|
| 419 | |
|---|
| 420 | void setPositioned(bool b = true) { m_positioned = b; } |
|---|
| 421 | void setRelPositioned(bool b = true) { m_relPositioned = b; } |
|---|
| 422 | void setFloating(bool b = true) { m_floating = b; } |
|---|
| 423 | void setInline(bool b = true) { m_inline = b; } |
|---|
| 424 | void setHasBoxDecorations(bool b = true) { m_paintBackground = b; } |
|---|
| 425 | void setRenderText() { m_isText = true; } |
|---|
| 426 | void setReplaced(bool b = true) { m_replaced = b; } |
|---|
| 427 | void setHasOverflowClip(bool b = true) { m_hasOverflowClip = b; } |
|---|
| 428 | void setHasLayer(bool b = true) { m_hasLayer = b; } |
|---|
| 429 | void setHasTransform(bool b = true) { m_hasTransform = b; } |
|---|
| 430 | void setHasReflection(bool b = true) { m_hasReflection = b; } |
|---|
| 431 | |
|---|
| 432 | void scheduleRelayout(); |
|---|
| 433 | |
|---|
| 434 | void updateFillImages(const FillLayer*, const FillLayer*); |
|---|
| 435 | void updateImage(StyleImage*, StyleImage*); |
|---|
| 436 | |
|---|
| 437 | virtual InlineBox* createInlineBox(bool makePlaceHolderBox, bool isRootLineBox, bool isOnlyRun = false); |
|---|
| 438 | virtual void dirtyLineBoxes(bool fullLayout, bool isRootLineBox = false); |
|---|
| 439 | |
|---|
| 440 | // For inline replaced elements, this function returns the inline box that owns us. Enables |
|---|
| 441 | // the replaced RenderObject to quickly determine what line it is contained on and to easily |
|---|
| 442 | // iterate over structures on the line. |
|---|
| 443 | virtual InlineBox* inlineBoxWrapper() const; |
|---|
| 444 | virtual void setInlineBoxWrapper(InlineBox*); |
|---|
| 445 | virtual void deleteLineBoxWrapper(); |
|---|
| 446 | |
|---|
| 447 | // for discussion of lineHeight see CSS2 spec |
|---|
| 448 | virtual int lineHeight(bool firstLine, bool isRootLineBox = false) const; |
|---|
| 449 | // for the vertical-align property of inline elements |
|---|
| 450 | // the difference between this objects baseline position and the lines baseline position. |
|---|
| 451 | virtual int verticalPositionHint(bool firstLine) const; |
|---|
| 452 | // the offset of baseline from the top of the object. |
|---|
| 453 | virtual int baselinePosition(bool firstLine, bool isRootLineBox = false) const; |
|---|
| 454 | |
|---|
| 455 | /* |
|---|
| 456 | * Paint the object and its children, clipped by (x|y|w|h). |
|---|
| 457 | * (tx|ty) is the calculated position of the parent |
|---|
| 458 | */ |
|---|
| 459 | struct PaintInfo { |
|---|
| 460 | PaintInfo(GraphicsContext* newContext, const IntRect& newRect, PaintPhase newPhase, bool newForceBlackText, |
|---|
| 461 | RenderObject* newPaintingRoot, RenderFlowSequencedSet* newOutlineObjects) |
|---|
| 462 | : context(newContext) |
|---|
| 463 | , rect(newRect) |
|---|
| 464 | , phase(newPhase) |
|---|
| 465 | , forceBlackText(newForceBlackText) |
|---|
| 466 | , paintingRoot(newPaintingRoot) |
|---|
| 467 | , outlineObjects(newOutlineObjects) |
|---|
| 468 | { |
|---|
| 469 | } |
|---|
| 470 | |
|---|
| 471 | GraphicsContext* context; |
|---|
| 472 | IntRect rect; |
|---|
| 473 | PaintPhase phase; |
|---|
| 474 | bool forceBlackText; |
|---|
| 475 | RenderObject* paintingRoot; // used to draw just one element and its visual kids |
|---|
| 476 | RenderFlowSequencedSet* outlineObjects; // used to list outlines that should be painted by a block with inline children |
|---|
| 477 | }; |
|---|
| 478 | |
|---|
| 479 | virtual void paint(PaintInfo&, int tx, int ty); |
|---|
| 480 | void paintBorder(GraphicsContext*, int tx, int ty, int w, int h, const RenderStyle*, bool begin = true, bool end = true); |
|---|
| 481 | bool paintNinePieceImage(GraphicsContext*, int tx, int ty, int w, int h, const RenderStyle*, const NinePieceImage&, CompositeOperator = CompositeSourceOver); |
|---|
| 482 | void paintOutline(GraphicsContext*, int tx, int ty, int w, int h, const RenderStyle*); |
|---|
| 483 | void paintBoxShadow(GraphicsContext*, int tx, int ty, int w, int h, const RenderStyle*, bool begin = true, bool end = true); |
|---|
| 484 | |
|---|
| 485 | // RenderBox implements this. |
|---|
| 486 | virtual void paintBoxDecorations(PaintInfo&, int tx, int ty) { } |
|---|
| 487 | virtual void paintMask(PaintInfo&, int tx, int ty) { } |
|---|
| 488 | virtual void paintFillLayerExtended(const PaintInfo&, const Color&, const FillLayer*, |
|---|
| 489 | int clipy, int cliph, int tx, int ty, int width, int height, |
|---|
| 490 | InlineFlowBox* box = 0, CompositeOperator = CompositeSourceOver) { } |
|---|
| 491 | |
|---|
| 492 | |
|---|
| 493 | /* |
|---|
| 494 | * Calculates the actual width of the object (only for non inline |
|---|
| 495 | * objects) |
|---|
| 496 | */ |
|---|
| 497 | virtual void calcWidth() { } |
|---|
| 498 | |
|---|
| 499 | /* |
|---|
| 500 | * This function should cause the Element to calculate its |
|---|
| 501 | * width and height and the layout of its content |
|---|
| 502 | * |
|---|
| 503 | * when the Element calls setNeedsLayout(false), layout() is no |
|---|
| 504 | * longer called during relayouts, as long as there is no |
|---|
| 505 | * style sheet change. When that occurs, m_needsLayout will be |
|---|
| 506 | * set to true and the Element receives layout() calls |
|---|
| 507 | * again. |
|---|
| 508 | */ |
|---|
| 509 | virtual void layout() = 0; |
|---|
| 510 | |
|---|
| 511 | /* This function performs a layout only if one is needed. */ |
|---|
| 512 | void layoutIfNeeded() { if (needsLayout()) layout(); } |
|---|
| 513 | |
|---|
| 514 | // Called when a positioned object moves but doesn't necessarily change size. A simplified layout is attempted |
|---|
| 515 | // that just updates the object's position. If the size does change, the object remains dirty. |
|---|
| 516 | virtual void tryLayoutDoingPositionedMovementOnly() { } |
|---|
| 517 | |
|---|
| 518 | // used for element state updates that cannot be fixed with a |
|---|
| 519 | // repaint and do not need a relayout |
|---|
| 520 | virtual void updateFromElement() { } |
|---|
| 521 | |
|---|
| 522 | // Block flows subclass availableWidth to handle multi column layout (shrinking the width available to children when laying out.) |
|---|
| 523 | virtual int availableWidth() const { return contentWidth(); } |
|---|
| 524 | |
|---|
| 525 | virtual int availableHeight() const { return 0; } |
|---|
| 526 | |
|---|
| 527 | virtual void updateWidgetPosition(); |
|---|
| 528 | |
|---|
| 529 | #if ENABLE(DASHBOARD_SUPPORT) |
|---|
| 530 | void addDashboardRegions(Vector<DashboardRegionValue>&); |
|---|
| 531 | void collectDashboardRegions(Vector<DashboardRegionValue>&); |
|---|
| 532 | #endif |
|---|
| 533 | |
|---|
| 534 | bool hitTest(const HitTestRequest&, HitTestResult&, const IntPoint&, int tx, int ty, HitTestFilter = HitTestAll); |
|---|
| 535 | virtual bool nodeAtPoint(const HitTestRequest&, HitTestResult&, int x, int y, int tx, int ty, HitTestAction); |
|---|
| 536 | void updateHitTestResult(HitTestResult&, const IntPoint&); |
|---|
| 537 | |
|---|
| 538 | virtual VisiblePosition positionForCoordinates(int x, int y); |
|---|
| 539 | VisiblePosition positionForPoint(const IntPoint& point) { return positionForCoordinates(point.x(), point.y()); } |
|---|
| 540 | |
|---|
| 541 | virtual void dirtyLinesFromChangedChild(RenderObject*); |
|---|
| 542 | |
|---|
| 543 | // Called to update a style that is allowed to trigger animations. |
|---|
| 544 | // FIXME: Right now this will typically be called only when updating happens from the DOM on explicit elements. |
|---|
| 545 | // We don't yet handle generated content animation such as first-letter or before/after (we'll worry about this later). |
|---|
| 546 | void setAnimatableStyle(PassRefPtr<RenderStyle>); |
|---|
| 547 | |
|---|
| 548 | // Set the style of the object and update the state of the object accordingly. |
|---|
| 549 | virtual void setStyle(PassRefPtr<RenderStyle>); |
|---|
| 550 | |
|---|
| 551 | // Updates only the local style ptr of the object. Does not update the state of the object, |
|---|
| 552 | // and so only should be called when the style is known not to have changed (or from setStyle). |
|---|
| 553 | void setStyleInternal(PassRefPtr<RenderStyle>); |
|---|
| 554 | |
|---|
| 555 | // returns the containing block level element for this element. |
|---|
| 556 | RenderBlock* containingBlock() const; |
|---|
| 557 | |
|---|
| 558 | |
|---|