2009-01-31 David Hyatt <hyatt@apple.com>
[WebKit-https.git] / WebCore / rendering / RenderBox.h
1 /*
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.
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 "RenderObject.h"
27 #include "ScrollTypes.h"
28
29 namespace WebCore {
30
31 enum WidthType { Width, MinWidth, MaxWidth };
32
33 class RenderBox : public RenderObject {
34 public:
35     RenderBox(Node*);
36     virtual ~RenderBox();
37
38     virtual const char* renderName() const { return "RenderBox"; }
39
40     // Use this with caution! No type checking is done!
41     RenderBox* firstChildBox() const;
42     RenderBox* lastChildBox() const;
43
44     int x() const { return m_frameRect.x(); }
45     int y() const { return m_frameRect.y(); }
46     int width() const { ASSERT(!isRenderInline()); return m_frameRect.width(); }
47     int height() const { ASSERT(!isRenderInline()); return m_frameRect.height(); }
48     
49     void setX(int x) { m_frameRect.setX(x); }
50     void setY(int y) { m_frameRect.setY(y); }
51     void setWidth(int width) { m_frameRect.setWidth(width); }
52     void setHeight(int height) { m_frameRect.setHeight(height); }
53     
54     IntPoint location() const { return m_frameRect.location(); }
55     IntSize size() const { ASSERT(!isRenderInline()); return m_frameRect.size(); }
56
57     void setLocation(const IntPoint& location) { m_frameRect.setLocation(location); }
58     void setLocation(int x, int y) { setLocation(IntPoint(x, y)); }
59     
60     void setSize(const IntSize& size) { m_frameRect.setSize(size); }
61     void move(int dx, int dy) { m_frameRect.move(dx, dy); }
62
63     IntRect frameRect() const { ASSERT(!isRenderInline()); return m_frameRect; }
64     void setFrameRect(const IntRect& rect) { m_frameRect = rect; }
65
66     IntRect borderBoxRect() const { return IntRect(0, 0, width(), height()); }
67     virtual IntRect borderBoundingBox() const { return borderBoxRect(); } // This will work on inlines to return the bounding box of all of the lines' border boxes.
68
69     // The content area of the box (excludes padding and border).
70     IntRect contentBoxRect() const { return IntRect(borderLeft() + paddingLeft(), borderTop() + paddingTop(), contentWidth(), contentHeight()); }
71     // The content box in absolute coords. Ignores transforms.
72     IntRect absoluteContentBox() const;
73     // The content box converted to absolute coords (taking transforms into account).
74     FloatQuad absoluteContentQuad() const;
75
76     // Bounds of the outline box in absolute coords. Respects transforms
77     virtual IntRect outlineBoundsForRepaint(RenderBox* /*repaintContainer*/) const;
78     virtual void addFocusRingRects(GraphicsContext*, int tx, int ty);
79
80     // Use this with caution! No type checking is done!
81     RenderBox* previousSiblingBox() const;
82     RenderBox* nextSiblingBox() const;
83     RenderBox* parentBox() const;
84
85     // The height of a block when you include normal flow overflow spillage out of the bottom
86     // of the block (e.g., a <div style="height:25px"> that has a 100px tall image inside
87     // it would have an overflow height of borderTop() + paddingTop() + 100px.
88     virtual int overflowHeight(bool /*includeInterior*/ = true) const { return height(); }
89     virtual int overflowWidth(bool /*includeInterior*/ = true) const { return width(); }
90     virtual void setOverflowHeight(int) { }
91     virtual void setOverflowWidth(int) { }
92     virtual int overflowLeft(bool /*includeInterior*/ = true) const { return 0; }
93     virtual int overflowTop(bool /*includeInterior*/ = true) const { return 0; }
94     virtual IntRect overflowRect(bool /*includeInterior*/ = true) const { return borderBoxRect(); }
95
96     int contentWidth() const { return clientWidth() - paddingLeft() - paddingRight(); }
97     int contentHeight() const { return clientHeight() - paddingTop() - paddingBottom(); }
98
99     // IE extensions. Used to calculate offsetWidth/Height.  Overridden by inlines (RenderFlow)
100     // to return the remaining width on a given line (and the height of a single line).
101     virtual int offsetWidth() const { return width(); }
102     virtual int offsetHeight() const { return height(); }
103     virtual int offsetLeft() const;
104     virtual int offsetTop() const;
105     virtual RenderBox* offsetParent() const;
106
107     // More IE extensions.  clientWidth and clientHeight represent the interior of an object
108     // excluding border and scrollbar.  clientLeft/Top are just the borderLeftWidth and borderTopWidth.
109     int clientLeft() const { return borderLeft(); }
110     int clientTop() const { return borderTop(); }
111     int clientWidth() const;
112     int clientHeight() const;
113
114     // scrollWidth/scrollHeight will be the same as clientWidth/clientHeight unless the
115     // object has overflow:hidden/scroll/auto specified and also has overflow.
116     // scrollLeft/Top return the current scroll position.  These methods are virtual so that objects like
117     // textareas can scroll shadow content (but pretend that they are the objects that are
118     // scrolling).
119     virtual int scrollLeft() const;
120     virtual int scrollTop() const;
121     virtual int scrollWidth() const;
122     virtual int scrollHeight() const;
123     virtual void setScrollLeft(int);
124     virtual void setScrollTop(int);
125
126     bool hasHorizontalBordersPaddingOrMargin() const { return hasHorizontalBordersOrPadding() || marginLeft() != 0 || marginRight() != 0; }
127     bool hasHorizontalBordersOrPadding() const { return borderLeft() != 0 || borderRight() != 0 || paddingLeft() != 0 || paddingRight() != 0; }
128
129     int marginTop() const { return m_marginTop; }
130     int marginBottom() const { return m_marginBottom; }
131     int marginLeft() const { return m_marginLeft; }
132     int marginRight() const { return m_marginRight; }
133
134     // Virtual since table cells override
135     virtual int paddingTop(bool includeIntrinsicPadding = true) const;
136     virtual int paddingBottom(bool includeIntrinsicPadding = true) const;
137     virtual int paddingLeft(bool includeIntrinsicPadding = true) const;
138     virtual int paddingRight(bool includeIntrinsicPadding = true) const;
139
140     virtual int borderTop() const { return style()->borderTopWidth(); }
141     virtual int borderBottom() const { return style()->borderBottomWidth(); }
142     virtual int borderLeft() const { return style()->borderLeftWidth(); }
143     virtual int borderRight() const { return style()->borderRightWidth(); }
144
145     // The following five functions are used to implement collapsing margins.
146     // All objects know their maximal positive and negative margins.  The
147     // formula for computing a collapsed margin is |maxPosMargin| - |maxNegmargin|.
148     // For a non-collapsing box, such as a leaf element, this formula will simply return
149     // the margin of the element.  Blocks override the maxTopMargin and maxBottomMargin
150     // methods.
151     virtual bool isSelfCollapsingBlock() const { return false; }
152     int collapsedMarginTop() const { return maxTopMargin(true) - maxTopMargin(false); }
153     int collapsedMarginBottom() const { return maxBottomMargin(true) - maxBottomMargin(false); }
154     virtual int maxTopMargin(bool positive) const { return positive ? std::max(0, marginTop()) : -std::min(0, marginTop()); }
155     virtual int maxBottomMargin(bool positive) const { return positive ? std::max(0, marginBottom()) : -std::min(0, marginBottom()); }
156
157     virtual void absoluteRects(Vector<IntRect>&, int tx, int ty, bool topLevel = true);
158     virtual void absoluteQuads(Vector<FloatQuad>&, bool topLevel = true);
159     
160     IntRect reflectionBox() const;
161     int reflectionOffset() const;
162     // Given a rect in the object's coordinate space, returns the corresponding rect in the reflection.
163     IntRect reflectedRect(const IntRect&) const;
164
165     virtual void layout();
166     virtual void paint(PaintInfo&, int tx, int ty);
167     virtual bool nodeAtPoint(const HitTestRequest&, HitTestResult&, int x, int y, int tx, int ty, HitTestAction);
168
169     virtual void destroy();
170
171     virtual int minPrefWidth() const;
172     virtual int maxPrefWidth() const;
173
174     virtual int overrideSize() const;
175     virtual int overrideWidth() const;
176     virtual int overrideHeight() const;
177     virtual void setOverrideSize(int);
178
179     virtual FloatPoint localToAbsolute(FloatPoint localPoint = FloatPoint(), bool fixed = false, bool useTransforms = false) const;
180     virtual FloatPoint absoluteToLocal(FloatPoint containerPoint, bool fixed = false, bool useTransforms = false) const;
181
182     virtual IntSize offsetFromContainer(RenderObject*) const;
183     
184     int calcBorderBoxWidth(int width) const;
185     int calcBorderBoxHeight(int height) const;
186     int calcContentBoxWidth(int width) const;
187     int calcContentBoxHeight(int height) const;
188
189     virtual void borderFitAdjust(int& /*x*/, int& /*w*/) const { } // Shrink the box in which the border paints if border-fit is set.
190
191     // This method is now public so that centered objects like tables that are
192     // shifted right by left-aligned floats can recompute their left and
193     // right margins (so that they can remain centered after being
194     // shifted. -dwh
195     void calcHorizontalMargins(const Length& marginLeft, const Length& marginRight, int containerWidth);
196
197     virtual void position(InlineBox*);
198
199     virtual void dirtyLineBoxes(bool fullLayout, bool isRootLineBox = false);
200
201     // For inline replaced elements, this function returns the inline box that owns us.  Enables
202     // the replaced RenderObject to quickly determine what line it is contained on and to easily
203     // iterate over structures on the line.
204     virtual InlineBox* inlineBoxWrapper() const { return m_inlineBoxWrapper; }
205     virtual void setInlineBoxWrapper(InlineBox* boxWrapper) { m_inlineBoxWrapper = boxWrapper; }
206     virtual void deleteLineBoxWrapper();
207
208     virtual int lowestPosition(bool includeOverflowInterior = true, bool includeSelf = true) const;
209     virtual int rightmostPosition(bool includeOverflowInterior = true, bool includeSelf = true) const;
210     virtual int leftmostPosition(bool includeOverflowInterior = true, bool includeSelf = true) const;
211
212     virtual IntRect clippedOverflowRectForRepaint(RenderBox* repaintContainer);
213     virtual void computeRectForRepaint(RenderBox* repaintContainer, IntRect&, bool fixed = false);
214     virtual FloatQuad localToContainerQuad(const FloatQuad&, RenderBox* repaintContainer, bool fixed = false) const;
215
216     virtual void repaintDuringLayoutIfMoved(const IntRect&);
217
218     virtual int containingBlockWidth() const;
219
220     virtual void calcWidth();
221     virtual void calcHeight();
222
223     bool stretchesToViewHeight() const
224     {
225         return style()->htmlHacks() && style()->height().isAuto() && !isFloatingOrPositioned() && (isRoot() || isBody());
226     }
227
228     virtual IntSize intrinsicSize() const { return IntSize(); }
229
230     // Whether or not the element shrinks to its intrinsic width (rather than filling the width
231     // of a containing block).  HTML4 buttons, <select>s, <input>s, legends, and floating/compact elements do this.
232     bool sizesToIntrinsicWidth(WidthType) const;
233     virtual bool stretchesToMinIntrinsicWidth() const { return false; }
234
235     int calcWidthUsing(WidthType, int containerWidth);
236     int calcHeightUsing(const Length& height);
237     int calcReplacedWidthUsing(Length width) const;
238     int calcReplacedHeightUsing(Length height) const;
239
240     virtual int calcReplacedWidth(bool includeMaxWidth = true) const;
241     virtual int calcReplacedHeight() const;
242
243     int calcPercentageHeight(const Length& height);
244
245     // Block flows subclass availableWidth to handle multi column layout (shrinking the width available to children when laying out.)
246     virtual int availableWidth() const { return contentWidth(); }
247     virtual int availableHeight() const;
248     int availableHeightUsing(const Length&) const;
249
250     void calcVerticalMargins();
251
252     int relativePositionOffsetX() const;
253     int relativePositionOffsetY() const;
254     IntSize relativePositionOffset() const { return IntSize(relativePositionOffsetX(), relativePositionOffsetY()); }
255     
256     RenderLayer* layer() const { return m_layer; }
257     virtual bool requiresLayer() const { return isRoot() || isPositioned() || isRelPositioned() || isTransparent() || hasOverflowClip() || hasTransform() || hasMask() || hasReflection(); }
258
259     virtual int verticalScrollbarWidth() const;
260     int horizontalScrollbarHeight() const;
261     virtual bool scroll(ScrollDirection, ScrollGranularity, float multiplier = 1.0f);
262     virtual bool canBeProgramaticallyScrolled(bool) const;
263     virtual void autoscroll();
264     virtual void stopAutoscroll() { }
265     virtual void panScroll(const IntPoint&);
266     bool hasAutoVerticalScrollbar() const { return hasOverflowClip() && (style()->overflowY() == OAUTO || style()->overflowY() == OOVERLAY); }
267     bool hasAutoHorizontalScrollbar() const { return hasOverflowClip() && (style()->overflowX() == OAUTO || style()->overflowX() == OOVERLAY); }
268     bool scrollsOverflow() const { return scrollsOverflowX() || scrollsOverflowY(); }
269     bool scrollsOverflowX() const { return hasOverflowClip() && (style()->overflowX() == OSCROLL || hasAutoHorizontalScrollbar()); }
270     bool scrollsOverflowY() const { return hasOverflowClip() && (style()->overflowY() == OSCROLL || hasAutoVerticalScrollbar()); }
271     
272     virtual IntRect localCaretRect(InlineBox*, int caretOffset, int* extraWidthToEndOfLine = 0);
273
274     virtual void paintFillLayerExtended(const PaintInfo&, const Color&, const FillLayer*, int clipY, int clipHeight,
275                                         int tx, int ty, int width, int height, InlineFlowBox* = 0, CompositeOperator = CompositeSourceOver);
276     IntSize calculateBackgroundSize(const FillLayer*, int scaledWidth, int scaledHeight) const;
277
278     virtual int staticX() const;
279     virtual int staticY() const;
280     virtual void setStaticX(int staticX);
281     virtual void setStaticY(int staticY);
282
283     virtual IntRect getOverflowClipRect(int tx, int ty);
284     virtual IntRect getClipRect(int tx, int ty);
285
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);
289
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()
293     {
294         int oldWidth = width();
295         calcWidth();
296         // If we shrink to fit our width may have changed, so we still need full layout.
297         if (oldWidth != width())
298             return;
299         calcHeight();
300         setNeedsLayout(false);
301     }
302
303     IntRect maskClipRect();
304
305     virtual void childBecameNonInline(RenderObject* /*child*/) { }
306
307 #if ENABLE(SVG)
308     virtual TransformationMatrix localTransform() const;
309 #endif
310
311 protected:
312     virtual void styleWillChange(RenderStyle::Diff, const RenderStyle* newStyle);
313     virtual void styleDidChange(RenderStyle::Diff, const RenderStyle* oldStyle);
314
315     void paintFillLayer(const PaintInfo&, const Color&, const FillLayer*, int clipY, int clipHeight, int tx, int ty, int width, int height, CompositeOperator = CompositeSourceOver);
316     void paintFillLayers(const PaintInfo&, const Color&, const FillLayer*, int clipY, int clipHeight, int tx, int ty, int width, int height, CompositeOperator = CompositeSourceOver);
317
318     void paintMaskImages(const PaintInfo&, int clipY, int clipHeight, int tx, int ty, int width, int height);
319
320 #if PLATFORM(MAC)
321     void paintCustomHighlight(int tx, int ty, const AtomicString& type, bool behindText);
322 #endif
323
324     void calcAbsoluteHorizontal();
325     
326     virtual bool shouldCalculateSizeAsReplaced() const { return isReplaced() && !isInlineBlockOrInlineTable(); }
327
328 private:
329     bool includeVerticalScrollbarSize() const { return hasOverflowClip() && (style()->overflowY() == OSCROLL || style()->overflowY() == OAUTO); }
330     bool includeHorizontalScrollbarSize() const { return hasOverflowClip() && (style()->overflowX() == OSCROLL || style()->overflowX() == OAUTO); }
331
332     void paintRootBoxDecorations(PaintInfo&, int tx, int ty);
333     // Returns true if we did a full repaint
334     bool repaintLayerRectsForImage(WrappedImagePtr image, const FillLayer* layers, bool drawingBackground);
335
336     void calculateBackgroundImageGeometry(const FillLayer*, int tx, int ty, int w, int h, IntRect& destRect, IntPoint& phase, IntSize& tileSize);
337     
338     int containingBlockWidthForPositioned(const RenderObject* containingBlock) const;
339     int containingBlockHeightForPositioned(const RenderObject* containingBlock) const;
340
341     void calcAbsoluteVertical();
342     void calcAbsoluteHorizontalValues(Length width, const RenderBox* cb, TextDirection containerDirection,
343                                       int containerWidth, int bordersPlusPadding,
344                                       Length left, Length right, Length marginLeft, Length marginRight,
345                                       int& widthValue, int& marginLeftValue, int& marginRightValue, int& xPos);
346     void calcAbsoluteVerticalValues(Length height, const RenderBox* cb,
347                                     int containerHeight, int bordersPlusPadding,
348                                     Length top, Length bottom, Length marginTop, Length marginBottom,
349                                     int& heightValue, int& marginTopValue, int& marginBottomValue, int& yPos);
350
351     void calcAbsoluteVerticalReplaced();
352     void calcAbsoluteHorizontalReplaced();
353
354     // This function calculates the minimum and maximum preferred widths for an object.
355     // These values are used in shrink-to-fit layout systems.
356     // These include tables, positioned objects, floats and flexible boxes.
357     virtual void calcPrefWidths() = 0;
358
359 private:
360     // The width/height of the contents + borders + padding.  The x/y location is relative to our container (which is not always our parent).
361     IntRect m_frameRect;
362
363 protected:
364     int m_marginLeft;
365     int m_marginRight;
366     int m_marginTop;
367     int m_marginBottom;
368
369     // The preferred width of the element if it were to break its lines at every possible opportunity.
370     int m_minPrefWidth;
371     
372     // The preferred width of the element if it never breaks any lines at all.
373     int m_maxPrefWidth;
374
375     // A pointer to our layer if we have one.
376     RenderLayer* m_layer;
377
378     // For inline replaced elements, the inline box that owns us.
379     InlineBox* m_inlineBoxWrapper;
380
381 private:
382     // Used to store state between styleWillChange and styleDidChange
383     static bool s_wasFloating;
384     static bool s_hadOverflowClip;
385 };
386
387 inline RenderBox* toRenderBox(RenderObject* o)
388
389     ASSERT(!o || o->isBox());
390     return static_cast<RenderBox*>(o);
391 }
392
393 inline const RenderBox* toRenderBox(const RenderObject* o)
394
395     ASSERT(!o || o->isBox());
396     return static_cast<const RenderBox*>(o);
397 }
398
399 // This will catch anyone doing an unnecessary cast.
400 void toRenderBox(const RenderBox*);
401
402 inline RenderBox* RenderBox::previousSiblingBox() const
403 {
404     return toRenderBox(previousSibling());
405 }
406
407 inline RenderBox* RenderBox::nextSiblingBox() const
408
409     return toRenderBox(nextSibling());
410 }
411
412 inline RenderBox* RenderBox::parentBox() const
413 {
414     return toRenderBox(parent());
415 }
416
417 inline RenderBox* RenderBox::firstChildBox() const
418 {
419     return toRenderBox(firstChild());
420 }
421
422 inline RenderBox* RenderBox::lastChildBox() const
423 {
424     return toRenderBox(lastChild());
425 }
426
427 } // namespace WebCore
428
429 #endif // RenderBox_h