2 * Copyright (C) 1999 Lars Knoll (knoll@kde.org)
3 * (C) 1999 Antti Koivisto (koivisto@kde.org)
4 * Copyright (C) 2003, 2006, 2007 Apple Inc. All rights reserved.
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.
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.
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.
26 #include "RenderObject.h"
27 #include "ScrollTypes.h"
31 enum WidthType
{ Width
, MinWidth
, MaxWidth
};
33 class RenderBox
: public RenderObject
{
38 virtual const char* renderName() const { return "RenderBox"; }
40 int x() const { return m_frameRect
.x(); }
41 int y() const { return m_frameRect
.y(); }
43 int width() const { return m_frameRect
.width(); }
44 int height() const { return m_frameRect
.height(); }
46 void setX(int x
) { m_frameRect
.setX(x
); }
47 void setY(int y
) { m_frameRect
.setY(y
); }
48 void setWidth(int width
) { m_frameRect
.setWidth(width
); }
49 void setHeight(int height
) { m_frameRect
.setHeight(height
); }
51 IntPoint
location() const { return m_frameRect
.location(); }
52 IntSize
size() const { return m_frameRect
.size(); }
54 void setLocation(const IntPoint
& location
) { m_frameRect
.setLocation(location
); }
55 void setLocation(int x
, int y
) { setLocation(IntPoint(x
, y
)); }
57 void setSize(const IntSize
& size
) { m_frameRect
.setSize(size
); }
58 void move(int dx
, int dy
) { m_frameRect
.move(dx
, dy
); }
60 IntRect
frameRect() const { return m_frameRect
; }
61 void setFrameRect(const IntRect
& rect
) { m_frameRect
= rect
; }
63 IntRect
borderBoxRect() const { return IntRect(0, 0, width(), height()); }
64 virtual IntRect
borderBoundingBox() const { return borderBoxRect(); } // This will work on inlines to return the bounding box of all of the lines' border boxes.
66 // The content area of the box (excludes padding and border).
67 IntRect
contentBoxRect() const { return IntRect(borderLeft() + paddingLeft(), borderTop() + paddingTop(), contentWidth(), contentHeight()); }
68 // The content box in absolute coords. Ignores transforms.
69 IntRect
absoluteContentBox() const;
70 // The content box converted to absolute coords (taking transforms into account).
71 FloatQuad
absoluteContentQuad() const;
73 // Bounds of the outline box in absolute coords. Respects transforms
74 virtual IntRect
outlineBoundsForRepaint(RenderBox
* /*repaintContainer*/) const;
75 virtual void addFocusRingRects(GraphicsContext
*, int tx
, int ty
);
77 // Use this with caution! No type checking is done!
78 RenderBox
* previousSiblingBox() const;
79 RenderBox
* nextSiblingBox() const;
80 RenderBox
* parentBox() const;
82 // The height of a block when you include normal flow overflow spillage out of the bottom
83 // of the block (e.g., a <div style="height:25px"> that has a 100px tall image inside
84 // it would have an overflow height of borderTop() + paddingTop() + 100px.
85 virtual int overflowHeight(bool /*includeInterior*/ = true) const { return height(); }
86 virtual int overflowWidth(bool /*includeInterior*/ = true) const { return width(); }
87 virtual void setOverflowHeight(int) { }
88 virtual void setOverflowWidth(int) { }
89 virtual int overflowLeft(bool /*includeInterior*/ = true) const { return 0; }
90 virtual int overflowTop(bool /*includeInterior*/ = true) const { return 0; }
91 virtual IntRect
overflowRect(bool /*includeInterior*/ = true) const { return borderBoxRect(); }
93 int contentWidth() const { return clientWidth() - paddingLeft() - paddingRight(); }
94 int contentHeight() const { return clientHeight() - paddingTop() - paddingBottom(); }
96 // IE extensions. Used to calculate offsetWidth/Height. Overridden by inlines (RenderFlow)
97 // to return the remaining width on a given line (and the height of a single line).
98 virtual int offsetWidth() const { return width(); }
99 virtual int offsetHeight() const { return height(); }
100 virtual int offsetLeft() const;
101 virtual int offsetTop() const;
102 virtual RenderBox
* offsetParent() const;
104 // More IE extensions. clientWidth and clientHeight represent the interior of an object
105 // excluding border and scrollbar. clientLeft/Top are just the borderLeftWidth and borderTopWidth.
106 int clientLeft() const { return borderLeft(); }
107 int clientTop() const { return borderTop(); }
108 int clientWidth() const;
109 int clientHeight() const;
111 // scrollWidth/scrollHeight will be the same as clientWidth/clientHeight unless the
112 // object has overflow:hidden/scroll/auto specified and also has overflow.
113 // scrollLeft/Top return the current scroll position. These methods are virtual so that objects like
114 // textareas can scroll shadow content (but pretend that they are the objects that are
116 virtual int scrollLeft() const;
117 virtual int scrollTop() const;
118 virtual int scrollWidth() const;
119 virtual int scrollHeight() const;
120 virtual void setScrollLeft(int);
121 virtual void setScrollTop(int);
123 bool hasHorizontalBordersPaddingOrMargin() const { return hasHorizontalBordersOrPadding() || marginLeft() != 0 || marginRight() != 0; }
124 bool hasHorizontalBordersOrPadding() const { return borderLeft() != 0 || borderRight() != 0 || paddingLeft() != 0 || paddingRight() != 0; }
126 int marginTop() const { return m_marginTop
; }
127 int marginBottom() const { return m_marginBottom
; }
128 int marginLeft() const { return m_marginLeft
; }
129 int marginRight() const { return m_marginRight
; }
131 // Virtual since table cells override
132 virtual int paddingTop(bool includeIntrinsicPadding
= true) const;
133 virtual int paddingBottom(bool includeIntrinsicPadding
= true) const;
134 virtual int paddingLeft(bool includeIntrinsicPadding
= true) const;
135 virtual int paddingRight(bool includeIntrinsicPadding
= true) const;
137 virtual int borderTop() const { return style()->borderTopWidth(); }
138 virtual int borderBottom() const { return style()->borderBottomWidth(); }
139 virtual int borderLeft() const { return style()->borderLeftWidth(); }
140 virtual int borderRight() const { return style()->borderRightWidth(); }
142 // The following seven 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
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 bool isTopMarginQuirk() const { return false; }
152 virtual bool isBottomMarginQuirk() const { return false; }
153 virtual int maxTopMargin(bool positive
) const { return positive
? std::max(0, marginTop()) : -std::min(0, marginTop()); }
154 virtual int maxBottomMargin(bool positive
) const { return positive
? std::max(0, marginBottom()) : -std::min(0, marginBottom()); }
156 virtual void absoluteRects(Vector
<IntRect
>&, int tx
, int ty
, bool topLevel
= true);
157 virtual void absoluteQuads(Vector
<FloatQuad
>&, bool topLevel
= true);
159 IntRect
reflectionBox() const;
160 int reflectionOffset() const;
161 // Given a rect in the object's coordinate space, returns the corresponding rect in the reflection.
162 IntRect
reflectedRect(const IntRect
&) const;
164 virtual void paint(PaintInfo
&, int tx
, int ty
);
165 virtual bool nodeAtPoint(const HitTestRequest
&, HitTestResult
&, int x
, int y
, int tx
, int ty
, HitTestAction
);
167 virtual void destroy();
169 virtual int minPrefWidth() const;
170 virtual int maxPrefWidth() const;
172 virtual int overrideSize() const;
173 virtual int overrideWidth() const;
174 virtual int overrideHeight() const;
175 virtual void setOverrideSize(int);
177 virtual IntSize
offsetFromContainer(RenderObject
*) const;
179 int calcBorderBoxWidth(int width
) const;
180 int calcBorderBoxHeight(int height
) const;
181 int calcContentBoxWidth(int width
) const;
182 int calcContentBoxHeight(int height
) const;
184 virtual void borderFitAdjust(int& /*x*/, int& /*w*/) const { } // Shrink the box in which the border paints if border-fit is set.
186 // This method is now public so that centered objects like tables that are
187 // shifted right by left-aligned floats can recompute their left and
188 // right margins (so that they can remain centered after being
190 void calcHorizontalMargins(const Length
& marginLeft
, const Length
& marginRight
, int containerWidth
);
192 virtual void position(InlineBox
*);
194 virtual void dirtyLineBoxes(bool fullLayout
, bool isRootLineBox
= false);
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();
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;
207 virtual IntRect
clippedOverflowRectForRepaint(RenderBox
* repaintContainer
);
208 virtual void computeRectForRepaint(RenderBox
* repaintContainer
, IntRect
&, bool fixed
= false);
209 IntSize
offsetForPositionedInContainer(RenderObject
*) const;
211 virtual void repaintDuringLayoutIfMoved(const IntRect
&);
213 virtual int containingBlockWidth() const;
215 virtual void calcWidth();
216 virtual void calcHeight();
218 bool stretchesToViewHeight() const
220 return style()->htmlHacks() && style()->height().isAuto() && !isFloatingOrPositioned() && (isRoot() || isBody());
223 virtual IntSize
intrinsicSize() const { return IntSize(); }
225 // Whether or not the element shrinks to its intrinsic width (rather than filling the width
226 // of a containing block). HTML4 buttons, <select>s, <input>s, legends, and floating/compact elements do this.
227 bool sizesToIntrinsicWidth(WidthType
) const;
228 virtual bool stretchesToMinIntrinsicWidth() const { return false; }
230 int calcWidthUsing(WidthType
, int containerWidth
);
231 int calcHeightUsing(const Length
& height
);
232 int calcReplacedWidthUsing(Length width
) const;
233 int calcReplacedHeightUsing(Length height
) const;
235 virtual int calcReplacedWidth(bool includeMaxWidth
= true) const;
236 virtual int calcReplacedHeight() const;
238 int calcPercentageHeight(const Length
& height
);
240 // Block flows subclass availableWidth to handle multi column layout (shrinking the width available to children when laying out.)
241 virtual int availableWidth() const { return contentWidth(); }
242 virtual int availableHeight() const;
243 int availableHeightUsing(const Length
&) const;
245 void calcVerticalMargins();
247 int relativePositionOffsetX() const;
248 int relativePositionOffsetY() const;
249 IntSize
relativePositionOffset() const { return IntSize(relativePositionOffsetX(), relativePositionOffsetY()); }
251 bool hasSelfPaintingLayer() const;
252 RenderLayer
* layer() const { return m_layer
; }
253 virtual bool requiresLayer() const { return isRoot() || isPositioned() || isRelPositioned() || isTransparent() || hasOverflowClip() || hasTransform() || hasMask() || hasReflection(); }
255 virtual int verticalScrollbarWidth() const;
256 int horizontalScrollbarHeight() const;
257 virtual bool scroll(ScrollDirection
, ScrollGranularity
, float multiplier
= 1.0f
);
258 virtual bool canBeProgramaticallyScrolled(bool) const;
259 virtual void autoscroll();
260 virtual void stopAutoscroll() { }
261 virtual void panScroll(const IntPoint
&);
262 bool hasAutoVerticalScrollbar() const { return hasOverflowClip() && (style()->overflowY() == OAUTO
|| style()->overflowY() == OOVERLAY
); }
263 bool hasAutoHorizontalScrollbar() const { return hasOverflowClip() && (style()->overflowX() == OAUTO
|| style()->overflowX() == OOVERLAY
); }
264 bool scrollsOverflow() const { return scrollsOverflowX() || scrollsOverflowY(); }
265 bool scrollsOverflowX() const { return hasOverflowClip() && (style()->overflowX() == OSCROLL
|| hasAutoHorizontalScrollbar()); }
266 bool scrollsOverflowY() const { return hasOverflowClip() && (style()->overflowY() == OSCROLL
|| hasAutoVerticalScrollbar()); }
268 virtual IntRect
localCaretRect(InlineBox
*, int caretOffset
, int* extraWidthToEndOfLine
= 0);
270 virtual void paintFillLayerExtended(const PaintInfo
&, const Color
&, const FillLayer
*, int clipY
, int clipHeight
,
271 int tx
, int ty
, int width
, int height
, InlineFlowBox
* = 0, CompositeOperator
= CompositeSourceOver
);
272 IntSize
calculateBackgroundSize(const FillLayer
*, int scaledWidth
, int scaledHeight
) const;
274 virtual int staticX() const;
275 virtual int staticY() const;
276 virtual void setStaticX(int staticX
);
277 virtual void setStaticY(int staticY
);
279 virtual IntRect
getOverflowClipRect(int tx
, int ty
);
280 virtual IntRect
getClipRect(int tx
, int ty
);
282 bool pushContentsClip(PaintInfo
&, int tx
, int ty
);
283 void popContentsClip(PaintInfo
&, PaintPhase originalPhase
, int tx
, int ty
);
285 virtual void paintObject(PaintInfo
&, int /*tx*/, int /*ty*/) { ASSERT_NOT_REACHED(); }
286 virtual void paintBoxDecorations(PaintInfo
&, int tx
, int ty
);
287 virtual void paintMask(PaintInfo
& paintInfo
, int tx
, int ty
);
288 virtual void imageChanged(WrappedImagePtr
, const IntRect
* = 0);
290 // Called when a positioned object moves but doesn't change size. A simplified layout is done
291 // that just updates the object's position.
292 virtual void tryLayoutDoingPositionedMovementOnly()
294 int oldWidth
= width();
296 // If we shrink to fit our width may have changed, so we still need full layout.
297 if (oldWidth
!= width())
300 setNeedsLayout(false);
303 IntRect
maskClipRect();
306 virtual TransformationMatrix
localTransform() const;
310 virtual void styleWillChange(StyleDifference
, const RenderStyle
* newStyle
);
311 virtual void styleDidChange(StyleDifference
, const RenderStyle
* oldStyle
);
313 void paintFillLayer(const PaintInfo
&, const Color
&, const FillLayer
*, int clipY
, int clipHeight
, int tx
, int ty
, int width
, int height
, CompositeOperator
= CompositeSourceOver
);
314 void paintFillLayers(const PaintInfo
&, const Color
&, const FillLayer
*, int clipY
, int clipHeight
, int tx
, int ty
, int width
, int height
, CompositeOperator
= CompositeSourceOver
);
316 void paintMaskImages(const PaintInfo
&, int clipY
, int clipHeight
, int tx
, int ty
, int width
, int height
);
319 void paintCustomHighlight(int tx
, int ty
, const AtomicString
& type
, bool behindText
);
322 void calcAbsoluteHorizontal();
324 virtual bool shouldCalculateSizeAsReplaced() const { return isReplaced() && !isInlineBlockOrInlineTable(); }
326 virtual void mapLocalToContainer(RenderBox
* repaintContainer
, bool useTransforms
, bool fixed
, TransformState
&) const;
327 virtual void mapAbsoluteToLocalPoint(bool fixed
, bool useTransforms
, TransformState
&) const;
330 bool includeVerticalScrollbarSize() const { return hasOverflowClip() && (style()->overflowY() == OSCROLL
|| style()->overflowY() == OAUTO
); }
331 bool includeHorizontalScrollbarSize() const { return hasOverflowClip() && (style()->overflowX() == OSCROLL
|| style()->overflowX() == OAUTO
); }
333 void paintRootBoxDecorations(PaintInfo
&, int tx
, int ty
);
334 // Returns true if we did a full repaint
335 bool repaintLayerRectsForImage(WrappedImagePtr image
, const FillLayer
* layers
, bool drawingBackground
);
337 void calculateBackgroundImageGeometry(const FillLayer
*, int tx
, int ty
, int w
, int h
, IntRect
& destRect
, IntPoint
& phase
, IntSize
& tileSize
);
339 int containingBlockWidthForPositioned(const RenderObject
* containingBlock
) const;
340 int containingBlockHeightForPositioned(const RenderObject
* containingBlock
) const;
342 void calcAbsoluteVertical();
343 void calcAbsoluteHorizontalValues(Length width
, const RenderBox
* cb
, TextDirection containerDirection
,
344 int containerWidth
, int bordersPlusPadding
,
345 Length left
, Length right
, Length marginLeft
, Length marginRight
,
346 int& widthValue
, int& marginLeftValue
, int& marginRightValue
, int& xPos
);
347 void calcAbsoluteVerticalValues(Length height
, const RenderBox
* cb
,
348 int containerHeight
, int bordersPlusPadding
,
349 Length top
, Length bottom
, Length marginTop
, Length marginBottom
,
350 int& heightValue
, int& marginTopValue
, int& marginBottomValue
, int& yPos
);
352 void calcAbsoluteVerticalReplaced();
353 void calcAbsoluteHorizontalReplaced();
355 // This function calculates the minimum and maximum preferred widths for an object.
356 // These values are used in shrink-to-fit layout systems.
357 // These include tables, positioned objects, floats and flexible boxes.
358 virtual void calcPrefWidths() = 0;
361 // The width/height of the contents + borders + padding. The x/y location is relative to our container (which is not always our parent).
370 // The preferred width of the element if it were to break its lines at every possible opportunity.
373 // The preferred width of the element if it never breaks any lines at all.
376 // A pointer to our layer if we have one.
377 RenderLayer
* m_layer
;
379 // For inline replaced elements, the inline box that owns us.
380 InlineBox
* m_inlineBoxWrapper
;
383 // Used to store state between styleWillChange and styleDidChange
384 static bool s_wasFloating
;
385 static bool s_hadOverflowClip
;
388 inline RenderBox
* toRenderBox(RenderObject
* o
)
390 ASSERT(!o
|| o
->isBox());
391 return static_cast<RenderBox
*>(o
);
394 inline const RenderBox
* toRenderBox(const RenderObject
* o
)
396 ASSERT(!o
|| o
->isBox());
397 return static_cast<const RenderBox
*>(o
);
400 inline RenderBox
* RenderBox::previousSiblingBox() const
402 return toRenderBox(previousSibling());
405 inline RenderBox
* RenderBox::nextSiblingBox() const
407 return toRenderBox(nextSibling());
410 inline RenderBox
* RenderBox::parentBox() const
412 return toRenderBox(parent());
415 } // namespace WebCore
417 #endif // RenderBox_h