1 /* 2 * Copyright (C) 1999 Lars Knoll (knoll (at) kde.org) 3 * (C) 1999 Antti Koivisto (koivisto (at) kde.org) 4 * Copyright (C) 2003, 2006, 2007 Apple Inc. All rights reserved. 5 * 6 * This library is free software; you can redistribute it and/or 7 * modify it under the terms of the GNU Library General Public 8 * License as published by the Free Software Foundation; either 9 * version 2 of the License, or (at your option) any later version. 10 * 11 * This library is distributed in the hope that it will be useful, 12 * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 14 * Library General Public License for more details. 15 * 16 * You should have received a copy of the GNU Library General Public License 17 * along with this library; see the file COPYING.LIB. If not, write to 18 * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, 19 * Boston, MA 02110-1301, USA. 20 * 21 */ 22 23 #ifndef RenderBox_h 24 #define RenderBox_h 25 26 #include "RenderBoxModelObject.h" 27 #include "RenderOverflow.h" 28 #include "ScrollTypes.h" 29 30 namespace WebCore { 31 32 enum WidthType { Width, MinWidth, MaxWidth }; 33 34 class RenderBox : public RenderBoxModelObject { 35 public: 36 RenderBox(Node*); 37 virtual ~RenderBox(); 38 39 // Use this with caution! No type checking is done! 40 RenderBox* firstChildBox() const; 41 RenderBox* lastChildBox() const; 42 43 int x() const { return m_frameRect.x(); } 44 int y() const { return m_frameRect.y(); } 45 int width() const { return m_frameRect.width(); } 46 int height() const { return m_frameRect.height(); } 47 48 void setX(int x) { m_frameRect.setX(x); } 49 void setY(int y) { m_frameRect.setY(y); } 50 void setWidth(int width) { m_frameRect.setWidth(width); } 51 void setHeight(int height) { m_frameRect.setHeight(height); } 52 53 IntPoint location() const { return m_frameRect.location(); } 54 IntSize size() const { return m_frameRect.size(); } 55 56 void setLocation(const IntPoint& location) { m_frameRect.setLocation(location); } 57 void setLocation(int x, int y) { setLocation(IntPoint(x, y)); } 58 59 void setSize(const IntSize& size) { m_frameRect.setSize(size); } 60 void move(int dx, int dy) { m_frameRect.move(dx, dy); } 61 62 IntRect frameRect() const { return m_frameRect; } 63 void setFrameRect(const IntRect& rect) { m_frameRect = rect; } 64 65 IntRect borderBoxRect() const { return IntRect(0, 0, width(), height()); } 66 virtual IntRect borderBoundingBox() const { return borderBoxRect(); } 67 68 // The content area of the box (excludes padding and border). 69 IntRect contentBoxRect() const { return IntRect(borderLeft() + paddingLeft(), borderTop() + paddingTop(), contentWidth(), contentHeight()); } 70 // The content box in absolute coords. Ignores transforms. 71 IntRect absoluteContentBox() const; 72 // The content box converted to absolute coords (taking transforms into account). 73 FloatQuad absoluteContentQuad() const; 74 75 // Bounds of the outline box in absolute coords. Respects transforms 76 virtual IntRect outlineBoundsForRepaint(RenderBoxModelObject* /*repaintContainer*/) const; 77 virtual void addFocusRingRects(Vector<IntRect>&, int tx, int ty); 78 79 // Use this with caution! No type checking is done! 80 RenderBox* previousSiblingBox() const; 81 RenderBox* nextSiblingBox() const; 82 RenderBox* parentBox() const; 83 84 IntRect visibleOverflowRect() const { return hasOverflowClip() ? visualOverflowRect() : (m_overflow ? m_overflow->visibleOverflowRect() : borderBoxRect()); } 85 int topVisibleOverflow() const { return hasOverflowClip() ? topVisualOverflow() : std::min(topLayoutOverflow(), topVisualOverflow()); } 86 int bottomVisibleOverflow() const { return hasOverflowClip() ? bottomVisualOverflow() : std::max(bottomLayoutOverflow(), bottomVisualOverflow()); } 87 int leftVisibleOverflow() const { return hasOverflowClip() ? leftVisualOverflow() : std::min(leftLayoutOverflow(), leftVisualOverflow()); } 88 int rightVisibleOverflow() const { return hasOverflowClip() ? rightVisualOverflow() : std::max(rightLayoutOverflow(), rightVisualOverflow()); } 89 90 IntRect layoutOverflowRect() const { return m_overflow ? m_overflow->layoutOverflowRect() : borderBoxRect(); } 91 int topLayoutOverflow() const { return m_overflow? m_overflow->topLayoutOverflow() : 0; } 92 int bottomLayoutOverflow() const { return m_overflow ? m_overflow->bottomLayoutOverflow() : height(); } 93 int leftLayoutOverflow() const { return m_overflow ? m_overflow->leftLayoutOverflow() : 0; } 94 int rightLayoutOverflow() const { return m_overflow ? m_overflow->rightLayoutOverflow() : width(); } 95 96 IntRect visualOverflowRect() const { return m_overflow ? m_overflow->visualOverflowRect() : borderBoxRect(); } 97 int topVisualOverflow() const { return m_overflow? m_overflow->topVisualOverflow() : 0; } 98 int bottomVisualOverflow() const { return m_overflow ? m_overflow->bottomVisualOverflow() : height(); } 99 int leftVisualOverflow() const { return m_overflow ? m_overflow->leftVisualOverflow() : 0; } 100 int rightVisualOverflow() const { return m_overflow ? m_overflow->rightVisualOverflow() : width(); } 101 102 void addLayoutOverflow(const IntRect&); 103 void addVisualOverflow(const IntRect&); 104 105 void addShadowOverflow(); 106 void addOverflowFromChild(RenderBox* child) { addOverflowFromChild(child, IntSize(child->x(), child->y())); } 107 void addOverflowFromChild(RenderBox* child, const IntSize& delta); 108 void clearLayoutOverflow(); 109 110 int contentWidth() const { return clientWidth() - paddingLeft() - paddingRight(); } 111 int contentHeight() const { return clientHeight() - paddingTop() - paddingBottom(); } 112 113 // IE extensions. Used to calculate offsetWidth/Height. Overridden by inlines (RenderFlow) 114 // to return the remaining width on a given line (and the height of a single line). 115 virtual int offsetWidth() const { return width(); } 116 virtual int offsetHeight() const { return height(); } 117 118 // More IE extensions. clientWidth and clientHeight represent the interior of an object 119 // excluding border and scrollbar. clientLeft/Top are just the borderLeftWidth and borderTopWidth. 120 int clientLeft() const { return borderLeft(); } 121 int clientTop() const { return borderTop(); } 122 int clientWidth() const; 123 int clientHeight() const; 124 125 // scrollWidth/scrollHeight will be the same as clientWidth/clientHeight unless the 126 // object has overflow:hidden/scroll/auto specified and also has overflow. 127 // scrollLeft/Top return the current scroll position. These methods are virtual so that objects like 128 // textareas can scroll shadow content (but pretend that they are the objects that are 129 // scrolling). 130 virtual int scrollLeft() const; 131 virtual int scrollTop() const; 132 virtual int scrollWidth() const; 133 virtual int scrollHeight() const; 134 virtual void setScrollLeft(int); 135 virtual void setScrollTop(int); 136 137 virtual int marginTop() const { return m_marginTop; } 138 virtual int marginBottom() const { return m_marginBottom; } 139 virtual int marginLeft() const { return m_marginLeft; } 140 virtual int marginRight() const { return m_marginRight; } 141 142 // The following five functions are used to implement collapsing margins. 143 // All objects know their maximal positive and negative margins. The 144 // formula for computing a collapsed margin is |maxPosMargin| - |maxNegmargin|. 145 // For a non-collapsing box, such as a leaf element, this formula will simply return 146 // the margin of the element. Blocks override the maxTopMargin and maxBottomMargin 147 // methods. 148 virtual bool isSelfCollapsingBlock() const { return false; } 149 int collapsedMarginTop() const { return maxTopMargin(true) - maxTopMargin(false); } 150 int collapsedMarginBottom() const { return maxBottomMargin(true) - maxBottomMargin(false); } 151 virtual int maxTopMargin(bool positive) const { return positive ? std::max(0, marginTop()) : -std::min(0, marginTop()); } 152 virtual int maxBottomMargin(bool positive) const { return positive ? std::max(0, marginBottom()) : -std::min(0, marginBottom()); } 153 154 virtual void absoluteRects(Vector<IntRect>&, int tx, int ty); 155 virtual void absoluteQuads(Vector<FloatQuad>&); 156 157 IntRect reflectionBox() const; 158 int reflectionOffset() const; 159 // Given a rect in the object's coordinate space, returns the corresponding rect in the reflection. 160 IntRect reflectedRect(const IntRect&) const; 161 162 virtual void layout(); 163 virtual void paint(PaintInfo&, int tx, int ty); 164 virtual bool nodeAtPoint(const HitTestRequest&, HitTestResult&, int x, int y, int tx, int ty, HitTestAction); 165 166 virtual void destroy(); 167 168 virtual int minPrefWidth() const; 169 virtual int maxPrefWidth() const; 170 171 int overrideSize() const; 172 int overrideWidth() const; 173 int overrideHeight() const; 174 virtual void setOverrideSize(int); 175 176 virtual IntSize offsetFromContainer(RenderObject*) const; 177 178 int calcBorderBoxWidth(int width) const; 179 int calcBorderBoxHeight(int height) const; 180 int calcContentBoxWidth(int width) const; 181 int calcContentBoxHeight(int height) const; 182 183 virtual void borderFitAdjust(int& /*x*/, int& /*w*/) const { } // Shrink the box in which the border paints if border-fit is set. 184 185 // This method is now public so that centered objects like tables that are 186 // shifted right by left-aligned floats can recompute their left and 187 // right margins (so that they can remain centered after being 188 // shifted. -dwh 189 void calcHorizontalMargins(const Length& marginLeft, const Length& marginRight, int containerWidth); 190 191 void positionLineBox(InlineBox*); 192 193 virtual InlineBox* createInlineBox(); 194 void dirtyLineBoxes(bool fullLayout); 195 196 // For inline replaced elements, this function returns the inline box that owns us. Enables 197 // the replaced RenderObject to quickly determine what line it is contained on and to easily 198 // iterate over structures on the line. 199 InlineBox* inlineBoxWrapper() const { return m_inlineBoxWrapper; } 200 void setInlineBoxWrapper(InlineBox* boxWrapper) { m_inlineBoxWrapper = boxWrapper; } 201 void deleteLineBoxWrapper(); 202 203 virtual int lowestPosition(bool includeOverflowInterior = true, bool includeSelf = true) const; 204 virtual int rightmostPosition(bool includeOverflowInterior = true, bool includeSelf = true) const; 205 virtual int leftmostPosition(bool includeOverflowInterior = true, bool includeSelf = true) const; 206 207 virtual IntRect clippedOverflowRectForRepaint(RenderBoxModelObject* repaintContainer); 208 virtual void computeRectForRepaint(RenderBoxModelObject* repaintContainer, IntRect&, bool fixed = false); 209 210 virtual void repaintDuringLayoutIfMoved(const IntRect&); 211 212 virtual int containingBlockWidthForContent() const; 213 214 virtual void calcWidth(); 215 virtual void calcHeight(); 216 217 bool stretchesToViewHeight() const 218 { 219 return style()->htmlHacks() && style()->height().isAuto() && !isFloatingOrPositioned() && (isRoot() || isBody()); 220 } 221 222 virtual IntSize intrinsicSize() const { return IntSize(); } 223 224 // Whether or not the element shrinks to its intrinsic width (rather than filling the width 225 // of a containing block). HTML4 buttons, <select>s, <input>s, legends, and floating/compact elements do this. 226 bool sizesToIntrinsicWidth(WidthType) const; 227 virtual bool stretchesToMinIntrinsicWidth() const { return false; } 228 229 int calcWidthUsing(WidthType, int containerWidth); 230 int calcHeightUsing(const Length& height); 231 int calcReplacedWidthUsing(Length width) const; 232 int calcReplacedHeightUsing(Length height) const; 233 234 virtual int calcReplacedWidth(bool includeMaxWidth = true) const; 235 virtual int calcReplacedHeight() const; 236 237 int calcPercentageHeight(const Length& height); 238 239 // Block flows subclass availableWidth to handle multi column layout (shrinking the width available to children when laying out.) 240 virtual int availableWidth() const { return contentWidth(); } 241 virtual int availableHeight() const; 242 int availableHeightUsing(const Length&) const; 243 244 void calcVerticalMargins(); 245 246 virtual int verticalScrollbarWidth() const; 247 int horizontalScrollbarHeight() const; 248 virtual bool scroll(ScrollDirection, ScrollGranularity, float multiplier = 1.0f, Node** stopNode = 0); 249 bool canBeScrolledAndHasScrollableArea() const; 250 virtual bool canBeProgramaticallyScrolled(bool) const; 251 virtual void autoscroll(); 252 virtual void stopAutoscroll() { } 253 virtual void panScroll(const IntPoint&); 254 bool hasAutoVerticalScrollbar() const { return hasOverflowClip() && (style()->overflowY() == OAUTO || style()->overflowY() == OOVERLAY); } 255 bool hasAutoHorizontalScrollbar() const { return hasOverflowClip() && (style()->overflowX() == OAUTO || style()->overflowX() == OOVERLAY); } 256 bool scrollsOverflow() const { return scrollsOverflowX() || scrollsOverflowY(); } 257 bool scrollsOverflowX() const { return hasOverflowClip() && (style()->overflowX() == OSCROLL || hasAutoHorizontalScrollbar()); } 258 bool scrollsOverflowY() const { return hasOverflowClip() && (style()->overflowY() == OSCROLL || hasAutoVerticalScrollbar()); } 259 260 virtual IntRect localCaretRect(InlineBox*, int caretOffset, int* extraWidthToEndOfLine = 0); 261 262 virtual IntRect overflowClipRect(int tx, int ty); 263 IntRect clipRect(int tx, int ty); 264 virtual bool hasControlClip() const { return false; } 265 virtual IntRect controlClipRect(int /*tx*/, int /*ty*/) const { return IntRect(); } 266 bool pushContentsClip(PaintInfo&, int tx, int ty); 267 void popContentsClip(PaintInfo&, PaintPhase originalPhase, int tx, int ty); 268 269 virtual void paintObject(PaintInfo&, int /*tx*/, int /*ty*/) { ASSERT_NOT_REACHED(); } 270 virtual void paintBoxDecorations(PaintInfo&, int tx, int ty); 271 virtual void paintMask(PaintInfo&, int tx, int ty); 272 virtual void imageChanged(WrappedImagePtr, const IntRect* = 0); 273 274 // Called when a positioned object moves but doesn't change size. A simplified layout is done 275 // that just updates the object's position. 276 virtual void tryLayoutDoingPositionedMovementOnly() 277 { 278 int oldWidth = width(); 279 calcWidth(); 280 // If we shrink to fit our width may have changed, so we still need full layout. 281 if (oldWidth != width()) 282 return; 283 calcHeight(); 284 setNeedsLayout(false); 285 } 286 287 IntRect maskClipRect(); 288 289 virtual VisiblePosition positionForPoint(const IntPoint&); 290 291 void removeFloatingOrPositionedChildFromBlockLists(); 292 293 virtual int firstLineBoxBaseline() const { return -1; } 294 virtual int lastLineBoxBaseline() const { return -1; } 295 296 bool shrinkToAvoidFloats() const; 297 virtual bool avoidsFloats() const; 298 299 #if ENABLE(SVG) 300 virtual AffineTransform localTransform() const; 301 #endif 302 303 protected: 304 virtual void styleWillChange(StyleDifference, const RenderStyle* newStyle); 305 virtual void styleDidChange(StyleDifference, const RenderStyle* oldStyle); 306 virtual void updateBoxModelInfoFromStyle(); 307 308 void paintFillLayer(const PaintInfo&, const Color&, const FillLayer*, int tx, int ty, int width, int height, CompositeOperator op, RenderObject* backgroundObject); 309 void paintFillLayers(const PaintInfo&, const Color&, const FillLayer*, int tx, int ty, int width, int height, CompositeOperator = CompositeSourceOver, RenderObject* backgroundObject = 0); 310 311 void paintMaskImages(const PaintInfo&, int tx, int ty, int width, int height); 312 313 #if PLATFORM(MAC) 314 void paintCustomHighlight(int tx, int ty, const AtomicString& type, bool behindText); 315 #endif 316 317 void calcAbsoluteHorizontal(); 318 319 virtual bool shouldCalculateSizeAsReplaced() const { return isReplaced() && !isInlineBlockOrInlineTable(); } 320 321 virtual void mapLocalToContainer(RenderBoxModelObject* repaintContainer, bool fixed, bool useTransforms, TransformState&) const; 322 virtual void mapAbsoluteToLocalPoint(bool fixed, bool useTransforms, TransformState&) const; 323 324 private: 325 bool includeVerticalScrollbarSize() const { return hasOverflowClip() && (style()->overflowY() == OSCROLL || style()->overflowY() == OAUTO); } 326 bool includeHorizontalScrollbarSize() const { return hasOverflowClip() && (style()->overflowX() == OSCROLL || style()->overflowX() == OAUTO); } 327 328 void paintRootBoxDecorations(PaintInfo&, int tx, int ty); 329 // Returns true if we did a full repaint 330 bool repaintLayerRectsForImage(WrappedImagePtr image, const FillLayer* layers, bool drawingBackground); 331 332 int containingBlockWidthForPositioned(const RenderBoxModelObject* containingBlock) const; 333 int containingBlockHeightForPositioned(const RenderBoxModelObject* containingBlock) const; 334 335 void calcAbsoluteVertical(); 336 void calcAbsoluteHorizontalValues(Length width, const RenderBoxModelObject* cb, TextDirection containerDirection, 337 int containerWidth, int bordersPlusPadding, 338 Length left, Length right, Length marginLeft, Length marginRight, 339 int& widthValue, int& marginLeftValue, int& marginRightValue, int& xPos); 340 void calcAbsoluteVerticalValues(Length height, const RenderBoxModelObject* cb, 341 int containerHeight, int bordersPlusPadding, 342 Length top, Length bottom, Length marginTop, Length marginBottom, 343 int& heightValue, int& marginTopValue, int& marginBottomValue, int& yPos); 344 345 void calcAbsoluteVerticalReplaced(); 346 void calcAbsoluteHorizontalReplaced(); 347 348 // This function calculates the minimum and maximum preferred widths for an object. 349 // These values are used in shrink-to-fit layout systems. 350 // These include tables, positioned objects, floats and flexible boxes. 351 virtual void calcPrefWidths() { setPrefWidthsDirty(false); } 352 353 private: 354 // The width/height of the contents + borders + padding. The x/y location is relative to our container (which is not always our parent). 355 IntRect m_frameRect; 356 357 protected: 358 359 #ifdef ANDROID_LAYOUT 360 int m_visibleWidth; 361 #endif 362 363 int m_marginLeft; 364 int m_marginRight; 365 int m_marginTop; 366 int m_marginBottom; 367 368 // The preferred width of the element if it were to break its lines at every possible opportunity. 369 int m_minPrefWidth; 370 371 // The preferred width of the element if it never breaks any lines at all. 372 int m_maxPrefWidth; 373 374 // For inline replaced elements, the inline box that owns us. 375 InlineBox* m_inlineBoxWrapper; 376 377 // Our overflow information. 378 OwnPtr<RenderOverflow> m_overflow; 379 380 private: 381 // Used to store state between styleWillChange and styleDidChange 382 static bool s_hadOverflowClip; 383 }; 384 385 inline RenderBox* toRenderBox(RenderObject* object) 386 { 387 ASSERT(!object || object->isBox()); 388 return static_cast<RenderBox*>(object); 389 } 390 391 inline const RenderBox* toRenderBox(const RenderObject* object) 392 { 393 ASSERT(!object || object->isBox()); 394 return static_cast<const RenderBox*>(object); 395 } 396 397 // This will catch anyone doing an unnecessary cast. 398 void toRenderBox(const RenderBox*); 399 400 inline RenderBox* RenderBox::previousSiblingBox() const 401 { 402 return toRenderBox(previousSibling()); 403 } 404 405 inline RenderBox* RenderBox::nextSiblingBox() const 406 { 407 return toRenderBox(nextSibling()); 408 } 409 410 inline RenderBox* RenderBox::parentBox() const 411 { 412 return toRenderBox(parent()); 413 } 414 415 inline RenderBox* RenderBox::firstChildBox() const 416 { 417 return toRenderBox(firstChild()); 418 } 419 420 inline RenderBox* RenderBox::lastChildBox() const 421 { 422 return toRenderBox(lastChild()); 423 } 424 425 } // namespace WebCore 426 427 #endif // RenderBox_h 428