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