diff -r 000000000000 -r 4f2f89ce4247 WebCore/rendering/RenderBox.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/WebCore/rendering/RenderBox.h Fri Sep 17 09:02:29 2010 +0300 @@ -0,0 +1,420 @@ +/* + * Copyright (C) 1999 Lars Knoll (knoll@kde.org) + * (C) 1999 Antti Koivisto (koivisto@kde.org) + * Copyright (C) 2003, 2006, 2007 Apple Inc. All rights reserved. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public License + * along with this library; see the file COPYING.LIB. If not, write to + * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301, USA. + * + */ + +#ifndef RenderBox_h +#define RenderBox_h + +#include "RenderBoxModelObject.h" +#include "RenderOverflow.h" +#include "ScrollTypes.h" + +namespace WebCore { + +enum WidthType { Width, MinWidth, MaxWidth }; + +class RenderBox : public RenderBoxModelObject { +public: + RenderBox(Node*); + virtual ~RenderBox(); + + // Use this with caution! No type checking is done! + RenderBox* firstChildBox() const; + RenderBox* lastChildBox() const; + + int x() const { return m_frameRect.x(); } + int y() const { return m_frameRect.y(); } + int width() const { return m_frameRect.width(); } + int height() const { return m_frameRect.height(); } + + void setX(int x) { m_frameRect.setX(x); } + void setY(int y) { m_frameRect.setY(y); } + void setWidth(int width) { m_frameRect.setWidth(width); } + void setHeight(int height) { m_frameRect.setHeight(height); } + + IntPoint location() const { return m_frameRect.location(); } + IntSize locationOffset() const { return IntSize(x(), y()); } + IntSize size() const { return m_frameRect.size(); } + + void setLocation(const IntPoint& location) { m_frameRect.setLocation(location); } + void setLocation(int x, int y) { setLocation(IntPoint(x, y)); } + + void setSize(const IntSize& size) { m_frameRect.setSize(size); } + void move(int dx, int dy) { m_frameRect.move(dx, dy); } + + IntRect frameRect() const { return m_frameRect; } + void setFrameRect(const IntRect& rect) { m_frameRect = rect; } + + IntRect borderBoxRect() const { return IntRect(0, 0, width(), height()); } + virtual IntRect borderBoundingBox() const { return borderBoxRect(); } + + // The content area of the box (excludes padding and border). + IntRect contentBoxRect() const { return IntRect(borderLeft() + paddingLeft(), borderTop() + paddingTop(), contentWidth(), contentHeight()); } + // The content box in absolute coords. Ignores transforms. + IntRect absoluteContentBox() const; + // The content box converted to absolute coords (taking transforms into account). + FloatQuad absoluteContentQuad() const; + + // Bounds of the outline box in absolute coords. Respects transforms + virtual IntRect outlineBoundsForRepaint(RenderBoxModelObject* /*repaintContainer*/, IntPoint* cachedOffsetToRepaintContainer) const; + virtual void addFocusRingRects(Vector&, int tx, int ty); + + // Use this with caution! No type checking is done! + RenderBox* previousSiblingBox() const; + RenderBox* nextSiblingBox() const; + RenderBox* parentBox() const; + + IntRect visibleOverflowRect() const { return hasOverflowClip() ? visualOverflowRect() : (m_overflow ? m_overflow->visibleOverflowRect() : borderBoxRect()); } + int topVisibleOverflow() const { return hasOverflowClip() ? topVisualOverflow() : std::min(topLayoutOverflow(), topVisualOverflow()); } + int bottomVisibleOverflow() const { return hasOverflowClip() ? bottomVisualOverflow() : std::max(bottomLayoutOverflow(), bottomVisualOverflow()); } + int leftVisibleOverflow() const { return hasOverflowClip() ? leftVisualOverflow() : std::min(leftLayoutOverflow(), leftVisualOverflow()); } + int rightVisibleOverflow() const { return hasOverflowClip() ? rightVisualOverflow() : std::max(rightLayoutOverflow(), rightVisualOverflow()); } + + IntRect layoutOverflowRect() const { return m_overflow ? m_overflow->layoutOverflowRect() : borderBoxRect(); } + int topLayoutOverflow() const { return m_overflow? m_overflow->topLayoutOverflow() : 0; } + int bottomLayoutOverflow() const { return m_overflow ? m_overflow->bottomLayoutOverflow() : height(); } + int leftLayoutOverflow() const { return m_overflow ? m_overflow->leftLayoutOverflow() : 0; } + int rightLayoutOverflow() const { return m_overflow ? m_overflow->rightLayoutOverflow() : width(); } + + IntRect visualOverflowRect() const { return m_overflow ? m_overflow->visualOverflowRect() : borderBoxRect(); } + int topVisualOverflow() const { return m_overflow? m_overflow->topVisualOverflow() : 0; } + int bottomVisualOverflow() const { return m_overflow ? m_overflow->bottomVisualOverflow() : height(); } + int leftVisualOverflow() const { return m_overflow ? m_overflow->leftVisualOverflow() : 0; } + int rightVisualOverflow() const { return m_overflow ? m_overflow->rightVisualOverflow() : width(); } + + void addLayoutOverflow(const IntRect&); + void addVisualOverflow(const IntRect&); + + void addShadowOverflow(); + void addOverflowFromChild(RenderBox* child) { addOverflowFromChild(child, IntSize(child->x(), child->y())); } + void addOverflowFromChild(RenderBox* child, const IntSize& delta); + void clearLayoutOverflow(); + + int contentWidth() const { return clientWidth() - paddingLeft() - paddingRight(); } + int contentHeight() const { return clientHeight() - paddingTop() - paddingBottom(); } + + // IE extensions. Used to calculate offsetWidth/Height. Overridden by inlines (RenderFlow) + // to return the remaining width on a given line (and the height of a single line). + virtual int offsetWidth() const { return width(); } + virtual int offsetHeight() const { return height(); } + + // More IE extensions. clientWidth and clientHeight represent the interior of an object + // excluding border and scrollbar. clientLeft/Top are just the borderLeftWidth and borderTopWidth. + int clientLeft() const { return borderLeft(); } + int clientTop() const { return borderTop(); } + int clientWidth() const; + int clientHeight() const; + + // scrollWidth/scrollHeight will be the same as clientWidth/clientHeight unless the + // object has overflow:hidden/scroll/auto specified and also has overflow. + // scrollLeft/Top return the current scroll position. These methods are virtual so that objects like + // textareas can scroll shadow content (but pretend that they are the objects that are + // scrolling). + virtual int scrollLeft() const; + virtual int scrollTop() const; + virtual int scrollWidth() const; + virtual int scrollHeight() const; + virtual void setScrollLeft(int); + virtual void setScrollTop(int); + + virtual int marginTop() const { return m_marginTop; } + virtual int marginBottom() const { return m_marginBottom; } + virtual int marginLeft() const { return m_marginLeft; } + virtual int marginRight() const { return m_marginRight; } + + // The following five functions are used to implement collapsing margins. + // All objects know their maximal positive and negative margins. The + // formula for computing a collapsed margin is |maxPosMargin| - |maxNegmargin|. + // For a non-collapsing box, such as a leaf element, this formula will simply return + // the margin of the element. Blocks override the maxTopMargin and maxBottomMargin + // methods. + virtual bool isSelfCollapsingBlock() const { return false; } + int collapsedMarginTop() const { return maxTopMargin(true) - maxTopMargin(false); } + int collapsedMarginBottom() const { return maxBottomMargin(true) - maxBottomMargin(false); } + virtual int maxTopMargin(bool positive) const { return positive ? std::max(0, marginTop()) : -std::min(0, marginTop()); } + virtual int maxBottomMargin(bool positive) const { return positive ? std::max(0, marginBottom()) : -std::min(0, marginBottom()); } + + virtual void absoluteRects(Vector&, int tx, int ty); + virtual void absoluteQuads(Vector&); + + IntRect reflectionBox() const; + int reflectionOffset() const; + // Given a rect in the object's coordinate space, returns the corresponding rect in the reflection. + IntRect reflectedRect(const IntRect&) const; + + virtual void layout(); + virtual void paint(PaintInfo&, int tx, int ty); + virtual bool nodeAtPoint(const HitTestRequest&, HitTestResult&, int x, int y, int tx, int ty, HitTestAction); + + virtual void destroy(); + + virtual int minPrefWidth() const; + virtual int maxPrefWidth() const; + + int overrideSize() const; + int overrideWidth() const; + int overrideHeight() const; + virtual void setOverrideSize(int); + + virtual IntSize offsetFromContainer(RenderObject*, const IntPoint&) const; + + int calcBorderBoxWidth(int width) const; + int calcBorderBoxHeight(int height) const; + int calcContentBoxWidth(int width) const; + int calcContentBoxHeight(int height) const; + + virtual void borderFitAdjust(int& /*x*/, int& /*w*/) const { } // Shrink the box in which the border paints if border-fit is set. + + // This method is now public so that centered objects like tables that are + // shifted right by left-aligned floats can recompute their left and + // right margins (so that they can remain centered after being + // shifted. -dwh + void calcHorizontalMargins(const Length& marginLeft, const Length& marginRight, int containerWidth); + + void positionLineBox(InlineBox*); + + virtual InlineBox* createInlineBox(); + void dirtyLineBoxes(bool fullLayout); + + // For inline replaced elements, this function returns the inline box that owns us. Enables + // the replaced RenderObject to quickly determine what line it is contained on and to easily + // iterate over structures on the line. + InlineBox* inlineBoxWrapper() const { return m_inlineBoxWrapper; } + void setInlineBoxWrapper(InlineBox* boxWrapper) { m_inlineBoxWrapper = boxWrapper; } + void deleteLineBoxWrapper(); + + virtual int lowestPosition(bool includeOverflowInterior = true, bool includeSelf = true) const; + virtual int rightmostPosition(bool includeOverflowInterior = true, bool includeSelf = true) const; + virtual int leftmostPosition(bool includeOverflowInterior = true, bool includeSelf = true) const; + + virtual IntRect clippedOverflowRectForRepaint(RenderBoxModelObject* repaintContainer); + virtual void computeRectForRepaint(RenderBoxModelObject* repaintContainer, IntRect&, bool fixed = false); + + virtual void repaintDuringLayoutIfMoved(const IntRect&); + + virtual int containingBlockWidthForContent() const; + + virtual void calcWidth(); + virtual void calcHeight(); + + bool stretchesToViewHeight() const + { + return style()->htmlHacks() && style()->height().isAuto() && !isFloatingOrPositioned() && (isRoot() || isBody()); + } + + virtual IntSize intrinsicSize() const { return IntSize(); } + + // Whether or not the element shrinks to its intrinsic width (rather than filling the width + // of a containing block). HTML4 buttons, s, legends, and floating/compact elements do this. + bool sizesToIntrinsicWidth(WidthType) const; + virtual bool stretchesToMinIntrinsicWidth() const { return false; } + + int calcWidthUsing(WidthType, int containerWidth); + int calcHeightUsing(const Length& height); + int calcReplacedWidthUsing(Length width) const; + int calcReplacedHeightUsing(Length height) const; + + virtual int calcReplacedWidth(bool includeMaxWidth = true) const; + virtual int calcReplacedHeight() const; + + int calcPercentageHeight(const Length& height); + + // Block flows subclass availableWidth to handle multi column layout (shrinking the width available to children when laying out.) + virtual int availableWidth() const { return contentWidth(); } + virtual int availableHeight() const; + int availableHeightUsing(const Length&) const; + + void calcVerticalMargins(); + + virtual int verticalScrollbarWidth() const; + int horizontalScrollbarHeight() const; + virtual bool scroll(ScrollDirection, ScrollGranularity, float multiplier = 1.0f, Node** stopNode = 0); + bool canBeScrolledAndHasScrollableArea() const; + virtual bool canBeProgramaticallyScrolled(bool) const; + virtual void autoscroll(); + virtual void stopAutoscroll() { } + virtual void panScroll(const IntPoint&); + bool hasAutoVerticalScrollbar() const { return hasOverflowClip() && (style()->overflowY() == OAUTO || style()->overflowY() == OOVERLAY); } + bool hasAutoHorizontalScrollbar() const { return hasOverflowClip() && (style()->overflowX() == OAUTO || style()->overflowX() == OOVERLAY); } + bool scrollsOverflow() const { return scrollsOverflowX() || scrollsOverflowY(); } + bool scrollsOverflowX() const { return hasOverflowClip() && (style()->overflowX() == OSCROLL || hasAutoHorizontalScrollbar()); } + bool scrollsOverflowY() const { return hasOverflowClip() && (style()->overflowY() == OSCROLL || hasAutoVerticalScrollbar()); } + + virtual IntRect localCaretRect(InlineBox*, int caretOffset, int* extraWidthToEndOfLine = 0); + + virtual IntRect overflowClipRect(int tx, int ty); + IntRect clipRect(int tx, int ty); + virtual bool hasControlClip() const { return false; } + virtual IntRect controlClipRect(int /*tx*/, int /*ty*/) const { return IntRect(); } + bool pushContentsClip(PaintInfo&, int tx, int ty); + void popContentsClip(PaintInfo&, PaintPhase originalPhase, int tx, int ty); + + virtual void paintObject(PaintInfo&, int /*tx*/, int /*ty*/) { ASSERT_NOT_REACHED(); } + virtual void paintBoxDecorations(PaintInfo&, int tx, int ty); + virtual void paintMask(PaintInfo&, int tx, int ty); + virtual void imageChanged(WrappedImagePtr, const IntRect* = 0); + + // Called when a positioned object moves but doesn't necessarily change size. A simplified layout is attempted + // that just updates the object's position. If the size does change, the object remains dirty. + void tryLayoutDoingPositionedMovementOnly() + { + int oldWidth = width(); + calcWidth(); + // If we shrink to fit our width may have changed, so we still need full layout. + if (oldWidth != width()) + return; + calcHeight(); + setNeedsLayout(false); + } + + IntRect maskClipRect(); + + virtual VisiblePosition positionForPoint(const IntPoint&); + + void removeFloatingOrPositionedChildFromBlockLists(); + + virtual int firstLineBoxBaseline() const { return -1; } + virtual int lastLineBoxBaseline() const { return -1; } + + bool shrinkToAvoidFloats() const; + virtual bool avoidsFloats() const; + +protected: + virtual void styleWillChange(StyleDifference, const RenderStyle* newStyle); + virtual void styleDidChange(StyleDifference, const RenderStyle* oldStyle); + virtual void updateBoxModelInfoFromStyle(); + + void paintFillLayer(const PaintInfo&, const Color&, const FillLayer*, int tx, int ty, int width, int height, CompositeOperator op, RenderObject* backgroundObject); + void paintFillLayers(const PaintInfo&, const Color&, const FillLayer*, int tx, int ty, int width, int height, CompositeOperator = CompositeSourceOver, RenderObject* backgroundObject = 0); + + void paintBoxDecorationsWithSize(PaintInfo&, int tx, int ty, int width, int height); + void paintMaskImages(const PaintInfo&, int tx, int ty, int width, int height); + +#if PLATFORM(MAC) + void paintCustomHighlight(int tx, int ty, const AtomicString& type, bool behindText); +#endif + + void calcAbsoluteHorizontal(); + + virtual bool shouldCalculateSizeAsReplaced() const { return isReplaced() && !isInlineBlockOrInlineTable(); } + + virtual void mapLocalToContainer(RenderBoxModelObject* repaintContainer, bool fixed, bool useTransforms, TransformState&) const; + virtual void mapAbsoluteToLocalPoint(bool fixed, bool useTransforms, TransformState&) const; + +private: + bool includeVerticalScrollbarSize() const { return hasOverflowClip() && (style()->overflowY() == OSCROLL || style()->overflowY() == OAUTO); } + bool includeHorizontalScrollbarSize() const { return hasOverflowClip() && (style()->overflowX() == OSCROLL || style()->overflowX() == OAUTO); } + + void paintRootBoxDecorations(PaintInfo&, int tx, int ty); + // Returns true if we did a full repaint + bool repaintLayerRectsForImage(WrappedImagePtr image, const FillLayer* layers, bool drawingBackground); + + int containingBlockWidthForPositioned(const RenderBoxModelObject* containingBlock) const; + int containingBlockHeightForPositioned(const RenderBoxModelObject* containingBlock) const; + + void calcAbsoluteVertical(); + void calcAbsoluteHorizontalValues(Length width, const RenderBoxModelObject* cb, TextDirection containerDirection, + int containerWidth, int bordersPlusPadding, + Length left, Length right, Length marginLeft, Length marginRight, + int& widthValue, int& marginLeftValue, int& marginRightValue, int& xPos); + void calcAbsoluteVerticalValues(Length height, const RenderBoxModelObject* cb, + int containerHeight, int bordersPlusPadding, + Length top, Length bottom, Length marginTop, Length marginBottom, + int& heightValue, int& marginTopValue, int& marginBottomValue, int& yPos); + + void calcAbsoluteVerticalReplaced(); + void calcAbsoluteHorizontalReplaced(); + + // This function calculates the minimum and maximum preferred widths for an object. + // These values are used in shrink-to-fit layout systems. + // These include tables, positioned objects, floats and flexible boxes. + virtual void calcPrefWidths() { setPrefWidthsDirty(false); } + +private: + // The width/height of the contents + borders + padding. The x/y location is relative to our container (which is not always our parent). + IntRect m_frameRect; + +protected: + int m_marginLeft; + int m_marginRight; + int m_marginTop; + int m_marginBottom; + + // The preferred width of the element if it were to break its lines at every possible opportunity. + int m_minPrefWidth; + + // The preferred width of the element if it never breaks any lines at all. + int m_maxPrefWidth; + + // For inline replaced elements, the inline box that owns us. + InlineBox* m_inlineBoxWrapper; + + // Our overflow information. + OwnPtr m_overflow; + +private: + // Used to store state between styleWillChange and styleDidChange + static bool s_hadOverflowClip; +}; + +inline RenderBox* toRenderBox(RenderObject* object) +{ + ASSERT(!object || object->isBox()); + return static_cast(object); +} + +inline const RenderBox* toRenderBox(const RenderObject* object) +{ + ASSERT(!object || object->isBox()); + return static_cast(object); +} + +// This will catch anyone doing an unnecessary cast. +void toRenderBox(const RenderBox*); + +inline RenderBox* RenderBox::previousSiblingBox() const +{ + return toRenderBox(previousSibling()); +} + +inline RenderBox* RenderBox::nextSiblingBox() const +{ + return toRenderBox(nextSibling()); +} + +inline RenderBox* RenderBox::parentBox() const +{ + return toRenderBox(parent()); +} + +inline RenderBox* RenderBox::firstChildBox() const +{ + return toRenderBox(firstChild()); +} + +inline RenderBox* RenderBox::lastChildBox() const +{ + return toRenderBox(lastChild()); +} + +} // namespace WebCore + +#endif // RenderBox_h