Home | History | Annotate | Download | only in rendering
      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