summaryrefslogtreecommitdiffstats
path: root/WebCore/rendering/RenderBox.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'WebCore/rendering/RenderBox.cpp')
-rw-r--r--WebCore/rendering/RenderBox.cpp1207
1 files changed, 408 insertions, 799 deletions
diff --git a/WebCore/rendering/RenderBox.cpp b/WebCore/rendering/RenderBox.cpp
index 7711f5e..5827f00 100644
--- a/WebCore/rendering/RenderBox.cpp
+++ b/WebCore/rendering/RenderBox.cpp
@@ -30,6 +30,7 @@
#include "Document.h"
#include "FrameView.h"
#include "GraphicsContext.h"
+#include "htmlediting.h"
#include "HTMLElement.h"
#include "HTMLNames.h"
#include "ImageBuffer.h"
@@ -40,13 +41,13 @@
#include "RenderFlexibleBox.h"
#include "RenderInline.h"
#include "RenderLayer.h"
-#include "RenderReplica.h"
#include "RenderTableCell.h"
#include "RenderTheme.h"
#ifdef ANDROID_LAYOUT
#include "Settings.h"
#endif
#include "RenderView.h"
+#include "TransformState.h"
#include <algorithm>
#include <math.h>
@@ -64,11 +65,10 @@ using namespace HTMLNames;
typedef WTF::HashMap<const RenderBox*, int> OverrideSizeMap;
static OverrideSizeMap* gOverrideSizeMap = 0;
-bool RenderBox::s_wasFloating = false;
bool RenderBox::s_hadOverflowClip = false;
RenderBox::RenderBox(Node* node)
- : RenderObject(node)
+ : RenderBoxModelObject(node)
#ifdef ANDROID_LAYOUT
, m_visibleWidth(0)
#endif
@@ -78,7 +78,6 @@ RenderBox::RenderBox(Node* node)
, m_marginBottom(0)
, m_minPrefWidth(-1)
, m_maxPrefWidth(-1)
- , m_layer(0)
, m_inlineBoxWrapper(0)
{
setIsBox();
@@ -96,51 +95,61 @@ void RenderBox::destroy()
if (hasOverrideSize())
gOverrideSizeMap->remove(this);
- // This must be done before we destroy the RenderObject.
- if (m_layer)
- m_layer->clearClipRects();
-
if (style() && (style()->height().isPercent() || style()->minHeight().isPercent() || style()->maxHeight().isPercent()))
RenderBlock::removePercentHeightDescendant(this);
- RenderObject::destroy();
+ RenderBoxModelObject::destroy();
+}
+
+void RenderBox::removeFloatingOrPositionedChildFromBlockLists()
+{
+ ASSERT(isFloatingOrPositioned());
+
+ if (documentBeingDestroyed())
+ return;
+
+ if (isFloating()) {
+ RenderBlock* outermostBlock = containingBlock();
+ for (RenderBlock* p = outermostBlock; p && !p->isRenderView(); p = p->containingBlock()) {
+ if (p->containsFloat(this))
+ outermostBlock = p;
+ }
+
+ if (outermostBlock)
+ outermostBlock->markAllDescendantsWithFloatsForLayout(this, false);
+ }
+
+ if (isPositioned()) {
+ RenderObject* p;
+ for (p = parent(); p; p = p->parent()) {
+ if (p->isRenderBlock())
+ toRenderBlock(p)->removePositionedObject(this);
+ }
+ }
}
-void RenderBox::styleWillChange(RenderStyle::Diff diff, const RenderStyle* newStyle)
+void RenderBox::styleWillChange(StyleDifference diff, const RenderStyle* newStyle)
{
- s_wasFloating = isFloating();
s_hadOverflowClip = hasOverflowClip();
if (style()) {
- // If our z-index changes value or our visibility changes,
- // we need to dirty our stacking context's z-order list.
- if (newStyle) {
- if (hasLayer() && (style()->hasAutoZIndex() != newStyle->hasAutoZIndex() ||
- style()->zIndex() != newStyle->zIndex() ||
- style()->visibility() != newStyle->visibility())) {
- layer()->dirtyStackingContextZOrderLists();
- if (style()->hasAutoZIndex() != newStyle->hasAutoZIndex() || style()->visibility() != newStyle->visibility())
- layer()->dirtyZOrderLists();
- }
- }
-
// The background of the root element or the body element could propagate up to
// the canvas. Just dirty the entire canvas when our style changes substantially.
- if (diff >= RenderStyle::Repaint && element() &&
- (element()->hasTagName(htmlTag) || element()->hasTagName(bodyTag)))
+ if (diff >= StyleDifferenceRepaint && node() &&
+ (node()->hasTagName(htmlTag) || node()->hasTagName(bodyTag)))
view()->repaint();
else if (parent() && !isText()) {
// Do a repaint with the old style first, e.g., for example if we go from
// having an outline to not having an outline.
- if (diff == RenderStyle::RepaintLayer) {
+ if (diff == StyleDifferenceRepaintLayer) {
layer()->repaintIncludingDescendants();
if (!(style()->clip() == newStyle->clip()))
layer()->clearClipRectsIncludingDescendants();
- } else if (diff == RenderStyle::Repaint || newStyle->outlineSize() < style()->outlineSize())
+ } else if (diff == StyleDifferenceRepaint || newStyle->outlineSize() < style()->outlineSize())
repaint();
}
- if (diff == RenderStyle::Layout) {
+ if (diff == StyleDifferenceLayout) {
// When a layout hint happens, we go ahead and do a repaint of the layer, since the layer could
// end up being destroyed.
if (hasLayer()) {
@@ -165,26 +174,45 @@ void RenderBox::styleWillChange(RenderStyle::Diff diff, const RenderStyle* newSt
if (style()->position() == StaticPosition)
repaint();
if (isFloating() && !isPositioned() && (newStyle->position() == AbsolutePosition || newStyle->position() == FixedPosition))
- removeFromObjectLists();
+ removeFloatingOrPositionedChildFromBlockLists();
}
}
}
- RenderObject::styleWillChange(diff, newStyle);
+ RenderBoxModelObject::styleWillChange(diff, newStyle);
}
-void RenderBox::styleDidChange(RenderStyle::Diff diff, const RenderStyle* oldStyle)
+void RenderBox::styleDidChange(StyleDifference diff, const RenderStyle* oldStyle)
{
- // We need to ensure that view->maximalOutlineSize() is valid for any repaints that happen
- // during the style change (it's used by clippedOverflowRectForRepaint()).
- if (style()->outlineWidth() > 0 && style()->outlineSize() > maximalOutlineSize(PaintPhaseOutline))
- static_cast<RenderView*>(document()->renderer())->setMaximalOutlineSize(style()->outlineSize());
-
- RenderObject::styleDidChange(diff, oldStyle);
+ RenderBoxModelObject::styleDidChange(diff, oldStyle);
if (needsLayout() && oldStyle && (oldStyle->height().isPercent() || oldStyle->minHeight().isPercent() || oldStyle->maxHeight().isPercent()))
RenderBlock::removePercentHeightDescendant(this);
+ // If our zoom factor changes and we have a defined scrollLeft/Top, we need to adjust that value into the
+ // new zoomed coordinate space.
+ if (hasOverflowClip() && oldStyle && style() && oldStyle->effectiveZoom() != style()->effectiveZoom()) {
+ int left = scrollLeft();
+ if (left) {
+ left = (left / oldStyle->effectiveZoom()) * style()->effectiveZoom();
+ setScrollLeft(left);
+ }
+ int top = scrollTop();
+ if (top) {
+ top = (top / oldStyle->effectiveZoom()) * style()->effectiveZoom();
+ setScrollTop(top);
+ }
+ }
+
+ // Set the text color if we're the body.
+ if (isBody())
+ document()->setTextColor(style()->color());
+}
+
+void RenderBox::updateBoxModelInfoFromStyle()
+{
+ RenderBoxModelObject::updateBoxModelInfoFromStyle();
+
bool isRootObject = isRoot();
bool isViewObject = isRenderView();
@@ -192,23 +220,8 @@ void RenderBox::styleDidChange(RenderStyle::Diff diff, const RenderStyle* oldSty
if (isRootObject || isViewObject)
setHasBoxDecorations(true);
- setInline(style()->isDisplayInlineType());
-
- switch (style()->position()) {
- case AbsolutePosition:
- case FixedPosition:
- setPositioned(true);
- break;
- default:
- setPositioned(false);
-
- if (style()->isFloating())
- setFloating(true);
-
- if (style()->position() == RelativePosition)
- setRelPositioned(true);
- break;
- }
+ setPositioned(style()->position() == AbsolutePosition || style()->position() == FixedPosition);
+ setFloating(!isPositioned() && style()->isFloating());
// We also handle <body> and <html>, whose overflow applies to the viewport.
if (style()->overflowX() != OVISIBLE && !isRootObject && (isRenderBlock() || isTableRow() || isTableSection())) {
@@ -219,7 +232,7 @@ void RenderBox::styleDidChange(RenderStyle::Diff diff, const RenderStyle* oldSty
// (2) We are the primary <body> (can be checked by looking at document.body).
// (3) The root element has visible overflow.
if (document()->documentElement()->hasTagName(htmlTag) &&
- document()->body() == element() &&
+ document()->body() == node() &&
document()->documentElement()->renderer()->style()->overflowX() == OVISIBLE)
boxHasOverflowClip = false;
}
@@ -234,133 +247,28 @@ void RenderBox::styleDidChange(RenderStyle::Diff diff, const RenderStyle* oldSty
}
}
- setHasTransform(style()->hasTransform());
+ setHasTransform(style()->hasTransformRelatedProperty());
setHasReflection(style()->boxReflect());
-
- if (requiresLayer()) {
- if (!m_layer) {
- if (s_wasFloating && isFloating())
- setChildNeedsLayout(true);
- m_layer = new (renderArena()) RenderLayer(this);
- setHasLayer(true);
- m_layer->insertOnlyThisLayer();
- if (parent() && !needsLayout() && containingBlock())
- m_layer->updateLayerPositions();
- }
- } else if (m_layer && !isRootObject && !isViewObject) {
- ASSERT(m_layer->parent());
- RenderLayer* layer = m_layer;
- m_layer = 0;
- setHasLayer(false);
- setHasTransform(false); // Either a transform wasn't specified or the object doesn't support transforms, so just null out the bit.
- setHasReflection(false);
- layer->removeOnlyThisLayer();
- if (s_wasFloating && isFloating())
- setChildNeedsLayout(true);
- }
-
- // If our zoom factor changes and we have a defined scrollLeft/Top, we need to adjust that value into the
- // new zoomed coordinate space.
- if (hasOverflowClip() && oldStyle && style() && oldStyle->effectiveZoom() != style()->effectiveZoom()) {
- int left = scrollLeft();
- if (left) {
- left = (left / oldStyle->effectiveZoom()) * style()->effectiveZoom();
- setScrollLeft(left);
- }
- int top = scrollTop();
- if (top) {
- top = (top / oldStyle->effectiveZoom()) * style()->effectiveZoom();
- setScrollTop(top);
- }
- }
-
- if (m_layer)
- m_layer->styleChanged(diff, oldStyle);
-
- // Set the text color if we're the body.
- if (isBody())
- document()->setTextColor(style()->color());
}
-
-int RenderBox::offsetLeft() const
+void RenderBox::layout()
{
- RenderBox* offsetPar = offsetParent();
- if (!offsetPar)
- return 0;
- int xPos = x() - offsetPar->borderLeft();
- if (!isPositioned()) {
- if (isRelPositioned())
- xPos += relativePositionOffsetX();
- RenderObject* curr = parent();
- while (curr && curr != offsetPar) {
- // FIXME: What are we supposed to do inside SVG content?
- if (curr->isBox() && !curr->isTableRow())
- xPos += toRenderBox(curr)->x();
- curr = curr->parent();
- }
- if (offsetPar->isBody() && !offsetPar->isRelPositioned() && !offsetPar->isPositioned())
- xPos += offsetPar->x();
- }
- return xPos;
-}
+ ASSERT(needsLayout());
-int RenderBox::offsetTop() const
-{
- RenderBox* offsetPar = offsetParent();
- if (!offsetPar)
- return 0;
- int yPos = y() - offsetPar->borderTop();
- if (!isPositioned()) {
- if (isRelPositioned())
- yPos += relativePositionOffsetY();
- RenderObject* curr = parent();
- while (curr && curr != offsetPar) {
- // FIXME: What are we supposed to do inside SVG content?
- if (curr->isBox() && !curr->isTableRow())
- yPos += toRenderBox(curr)->y();
- curr = curr->parent();
- }
- if (offsetPar->isBody() && !offsetPar->isRelPositioned() && !offsetPar->isPositioned())
- yPos += offsetPar->y();
+ RenderObject* child = firstChild();
+ if (!child) {
+ setNeedsLayout(false);
+ return;
}
- return yPos;
-}
-
-RenderBox* RenderBox::offsetParent() const
-{
- // FIXME: It feels like this function could almost be written using containing blocks.
- if (isBody())
- return 0;
-
- bool skipTables = isPositioned() || isRelPositioned();
- float currZoom = style()->effectiveZoom();
- RenderObject* curr = parent();
- while (curr && (!curr->element() ||
- (!curr->isPositioned() && !curr->isRelPositioned() && !curr->isBody()))) {
- Node* element = curr->element();
- if (!skipTables && element) {
- bool isTableElement = element->hasTagName(tableTag) ||
- element->hasTagName(tdTag) ||
- element->hasTagName(thTag);
-
-#if ENABLE(WML)
- if (!isTableElement && element->isWMLElement())
- isTableElement = element->hasTagName(WMLNames::tableTag) ||
- element->hasTagName(WMLNames::tdTag);
-#endif
-
- if (isTableElement)
- break;
- }
- float newZoom = curr->style()->effectiveZoom();
- if (currZoom != newZoom)
- break;
- currZoom = newZoom;
- curr = curr->parent();
+ LayoutStateMaintainer statePusher(view(), this, IntSize(x(), y()));
+ while (child) {
+ child->layoutIfNeeded();
+ ASSERT(!child->needsLayout());
+ child = child->nextSibling();
}
- return curr && curr->isBox() ? toRenderBox(curr) : 0;
+ statePusher.pop();
+ setNeedsLayout(false);
}
// More IE extensions. clientWidth and clientHeight represent the interior of an object
@@ -382,104 +290,47 @@ int RenderBox::clientHeight() const
int RenderBox::scrollWidth() const
{
if (hasOverflowClip())
- return m_layer->scrollWidth();
+ return layer()->scrollWidth();
return overflowWidth();
}
int RenderBox::scrollHeight() const
{
if (hasOverflowClip())
- return m_layer->scrollHeight();
+ return layer()->scrollHeight();
return overflowHeight();
}
int RenderBox::scrollLeft() const
{
- return hasOverflowClip() ? m_layer->scrollXOffset() : 0;
+ return hasOverflowClip() ? layer()->scrollXOffset() : 0;
}
int RenderBox::scrollTop() const
{
- return hasOverflowClip() ? m_layer->scrollYOffset() : 0;
+ return hasOverflowClip() ? layer()->scrollYOffset() : 0;
}
void RenderBox::setScrollLeft(int newLeft)
{
if (hasOverflowClip())
- m_layer->scrollToXOffset(newLeft);
+ layer()->scrollToXOffset(newLeft);
}
void RenderBox::setScrollTop(int newTop)
{
if (hasOverflowClip())
- m_layer->scrollToYOffset(newTop);
-}
-
-int RenderBox::paddingTop(bool) const
-{
- int w = 0;
- Length padding = style()->paddingTop();
- if (padding.isPercent())
- w = containingBlock()->availableWidth();
- return padding.calcMinValue(w);
-}
-
-int RenderBox::paddingBottom(bool) const
-{
- int w = 0;
- Length padding = style()->paddingBottom();
- if (padding.isPercent())
- w = containingBlock()->availableWidth();
- return padding.calcMinValue(w);
-}
-
-int RenderBox::paddingLeft(bool) const
-{
- int w = 0;
- Length padding = style()->paddingLeft();
- if (padding.isPercent())
- w = containingBlock()->availableWidth();
- return padding.calcMinValue(w);
+ layer()->scrollToYOffset(newTop);
}
-int RenderBox::paddingRight(bool) const
+void RenderBox::absoluteRects(Vector<IntRect>& rects, int tx, int ty, bool)
{
- int w = 0;
- Length padding = style()->paddingRight();
- if (padding.isPercent())
- w = containingBlock()->availableWidth();
- return padding.calcMinValue(w);
+ rects.append(IntRect(tx, ty, width(), height()));
}
-void RenderBox::absoluteRects(Vector<IntRect>& rects, int tx, int ty, bool topLevel)
+void RenderBox::absoluteQuads(Vector<FloatQuad>& quads, bool)
{
- // For blocks inside inlines, we go ahead and include margins so that we run right up to the
- // inline boxes above and below us (thus getting merged with them to form a single irregular
- // shape).
- RenderFlow* continuation = virtualContinuation();
- if (topLevel && continuation) {
- rects.append(IntRect(tx, ty - collapsedMarginTop(),
- width(), height() + collapsedMarginTop() + collapsedMarginBottom()));
- continuation->absoluteRects(rects,
- tx - x() + continuation->containingBlock()->x(),
- ty - y() + continuation->containingBlock()->y(), topLevel);
- } else
- rects.append(IntRect(tx, ty, width(), height()));
-}
-
-void RenderBox::absoluteQuads(Vector<FloatQuad>& quads, bool topLevel)
-{
- // For blocks inside inlines, we go ahead and include margins so that we run right up to the
- // inline boxes above and below us (thus getting merged with them to form a single irregular
- // shape).
- RenderFlow* continuation = virtualContinuation();
- if (topLevel && continuation) {
- FloatRect localRect(0, -collapsedMarginTop(),
- width(), height() + collapsedMarginTop() + collapsedMarginBottom());
- quads.append(localToAbsoluteQuad(localRect));
- continuation->absoluteQuads(quads, topLevel);
- } else
- quads.append(localToAbsoluteQuad(FloatRect(0, 0, width(), height())));
+ quads.append(localToAbsoluteQuad(FloatRect(0, 0, width(), height())));
}
IntRect RenderBox::absoluteContentBox() const
@@ -497,7 +348,7 @@ FloatQuad RenderBox::absoluteContentQuad() const
}
-IntRect RenderBox::outlineBoundsForRepaint(RenderBox* /*repaintContainer*/) const
+IntRect RenderBox::outlineBoundsForRepaint(RenderBoxModelObject* /*repaintContainer*/) const
{
IntRect box = borderBoundingBox();
adjustRectForOutlineAndShadow(box);
@@ -514,17 +365,7 @@ IntRect RenderBox::outlineBoundsForRepaint(RenderBox* /*repaintContainer*/) cons
void RenderBox::addFocusRingRects(GraphicsContext* graphicsContext, int tx, int ty)
{
- // For blocks inside inlines, we go ahead and include margins so that we run right up to the
- // inline boxes above and below us (thus getting merged with them to form a single irregular
- // shape).
- RenderFlow* continuation = virtualContinuation();
- if (continuation) {
- graphicsContext->addFocusRingRect(IntRect(tx, ty - collapsedMarginTop(), width(), height() + collapsedMarginTop() + collapsedMarginBottom()));
- continuation->addFocusRingRects(graphicsContext,
- tx - x() + continuation->containingBlock()->x(),
- ty - y() + continuation->containingBlock()->y());
- } else
- graphicsContext->addFocusRingRect(IntRect(tx, ty, width(), height()));
+ graphicsContext->addFocusRingRect(IntRect(tx, ty, width(), height()));
}
@@ -709,11 +550,7 @@ bool RenderBox::nodeAtPoint(const HitTestRequest& request, HitTestResult& result
// Check kids first.
for (RenderObject* child = lastChild(); child; child = child->previousSibling()) {
- // FIXME: We have to skip over inline flows, since they can show up inside table rows
- // at the moment (a demoted inline <form> for example). If we ever implement a
- // table-specific hit-test method (which we should do for performance reasons anyway),
- // then we can remove this check.
- if (!child->hasLayer() && !child->isRenderInline() && child->nodeAtPoint(request, result, xPos, yPos, tx, ty, action)) {
+ if (!child->hasLayer() && child->nodeAtPoint(request, result, xPos, yPos, tx, ty, action)) {
updateHitTestResult(result, IntPoint(xPos - tx, yPos - ty));
return true;
}
@@ -747,7 +584,7 @@ void RenderBox::paintRootBoxDecorations(PaintInfo& paintInfo, int tx, int ty)
{
const FillLayer* bgLayer = style()->backgroundLayers();
Color bgColor = style()->backgroundColor();
- if (!style()->hasBackground() && element() && element()->hasTagName(HTMLNames::htmlTag)) {
+ if (!style()->hasBackground() && node() && node()->hasTagName(HTMLNames::htmlTag)) {
// Locate the <body> element using the DOM. This is easier than trying
// to crawl around a render tree with potential :before/:after content and
// anonymous blocks created by inline <body> tags etc. We can locate the <body>
@@ -919,60 +756,20 @@ void RenderBox::paintFillLayer(const PaintInfo& paintInfo, const Color& c, const
paintFillLayerExtended(paintInfo, c, fillLayer, clipY, clipH, tx, ty, width, height, 0, op);
}
-IntSize RenderBox::calculateBackgroundSize(const FillLayer* bgLayer, int scaledWidth, int scaledHeight) const
-{
- StyleImage* bg = bgLayer->image();
- bg->setImageContainerSize(IntSize(scaledWidth, scaledHeight)); // Use the box established by background-origin.
-
- if (bgLayer->isSizeSet()) {
- int w = scaledWidth;
- int h = scaledHeight;
- Length bgWidth = bgLayer->size().width();
- Length bgHeight = bgLayer->size().height();
-
- if (bgWidth.isFixed())
- w = bgWidth.value();
- else if (bgWidth.isPercent())
- w = bgWidth.calcValue(scaledWidth);
-
- if (bgHeight.isFixed())
- h = bgHeight.value();
- else if (bgHeight.isPercent())
- h = bgHeight.calcValue(scaledHeight);
-
- // If one of the values is auto we have to use the appropriate
- // scale to maintain our aspect ratio.
- if (bgWidth.isAuto() && !bgHeight.isAuto())
- w = bg->imageSize(this, style()->effectiveZoom()).width() * h / bg->imageSize(this, style()->effectiveZoom()).height();
- else if (!bgWidth.isAuto() && bgHeight.isAuto())
- h = bg->imageSize(this, style()->effectiveZoom()).height() * w / bg->imageSize(this, style()->effectiveZoom()).width();
- else if (bgWidth.isAuto() && bgHeight.isAuto()) {
- // If both width and height are auto, we just want to use the image's
- // intrinsic size.
- w = bg->imageSize(this, style()->effectiveZoom()).width();
- h = bg->imageSize(this, style()->effectiveZoom()).height();
- }
-
- return IntSize(max(1, w), max(1, h));
- } else
- return bg->imageSize(this, style()->effectiveZoom());
-}
-
void RenderBox::imageChanged(WrappedImagePtr image, const IntRect*)
{
if (!parent())
return;
- if (isRenderInline() || style()->borderImage().image() && style()->borderImage().image()->data() == image ||
- style()->maskBoxImage().image() && style()->maskBoxImage().image()->data() == image) {
+ if ((style()->borderImage().image() && style()->borderImage().image()->data() == image) ||
+ (style()->maskBoxImage().image() && style()->maskBoxImage().image()->data() == image)) {
repaint();
return;
}
bool didFullRepaint = repaintLayerRectsForImage(image, style()->backgroundLayers(), true);
- if (!didFullRepaint) {
+ if (!didFullRepaint)
repaintLayerRectsForImage(image, style()->maskLayers(), false);
- }
}
bool RenderBox::repaintLayerRectsForImage(WrappedImagePtr image, const FillLayer* layers, bool drawingBackground)
@@ -992,7 +789,7 @@ bool RenderBox::repaintLayerRectsForImage(WrappedImagePtr image, const FillLayer
int rw;
int rh;
- if (FrameView* frameView = static_cast<RenderView*>(layerRenderer)->frameView()) {
+ if (FrameView* frameView = toRenderView(layerRenderer)->frameView()) {
rw = frameView->contentsWidth();
rh = frameView->contentsHeight();
} else {
@@ -1021,260 +818,6 @@ bool RenderBox::repaintLayerRectsForImage(WrappedImagePtr image, const FillLayer
return false;
}
-void RenderBox::calculateBackgroundImageGeometry(const FillLayer* bgLayer, int tx, int ty, int w, int h, IntRect& destRect, IntPoint& phase, IntSize& tileSize)
-{
- int pw;
- int ph;
- int left = 0;
- int right = 0;
- int top = 0;
- int bottom = 0;
- int cx;
- int cy;
- int rw = 0;
- int rh = 0;
-
- // CSS2 chapter 14.2.1
-
- if (bgLayer->attachment()) {
- // Scroll
- if (bgLayer->origin() != BorderFillBox) {
- left = borderLeft();
- right = borderRight();
- top = borderTop();
- bottom = borderBottom();
- if (bgLayer->origin() == ContentFillBox) {
- left += paddingLeft();
- right += paddingRight();
- top += paddingTop();
- bottom += paddingBottom();
- }
- }
-
- // The background of the box generated by the root element covers the entire canvas including
- // its margins. Since those were added in already, we have to factor them out when computing the
- // box used by background-origin/size/position.
- if (isRoot()) {
- rw = width() - left - right;
- rh = height() - top - bottom;
- left += marginLeft();
- right += marginRight();
- top += marginTop();
- bottom += marginBottom();
- }
- cx = tx;
- cy = ty;
- pw = w - left - right;
- ph = h - top - bottom;
- } else {
- // Fixed
- IntRect vr = viewRect();
- cx = vr.x();
- cy = vr.y();
- pw = vr.width();
- ph = vr.height();
- }
-
- int sx = 0;
- int sy = 0;
- int cw;
- int ch;
-
- IntSize scaledImageSize;
- if (isRoot() && bgLayer->attachment())
- scaledImageSize = calculateBackgroundSize(bgLayer, rw, rh);
- else
- scaledImageSize = calculateBackgroundSize(bgLayer, pw, ph);
-
- int scaledImageWidth = scaledImageSize.width();
- int scaledImageHeight = scaledImageSize.height();
-
- EFillRepeat backgroundRepeat = bgLayer->repeat();
-
- int xPosition;
- if (isRoot() && bgLayer->attachment())
- xPosition = bgLayer->xPosition().calcMinValue(rw - scaledImageWidth, true);
- else
- xPosition = bgLayer->xPosition().calcMinValue(pw - scaledImageWidth, true);
- if (backgroundRepeat == RepeatFill || backgroundRepeat == RepeatXFill) {
- cw = pw + left + right;
- sx = scaledImageWidth ? scaledImageWidth - (xPosition + left) % scaledImageWidth : 0;
- } else {
- cx += max(xPosition + left, 0);
- sx = -min(xPosition + left, 0);
- cw = scaledImageWidth + min(xPosition + left, 0);
- }
-
- int yPosition;
- if (isRoot() && bgLayer->attachment())
- yPosition = bgLayer->yPosition().calcMinValue(rh - scaledImageHeight, true);
- else
- yPosition = bgLayer->yPosition().calcMinValue(ph - scaledImageHeight, true);
- if (backgroundRepeat == RepeatFill || backgroundRepeat == RepeatYFill) {
- ch = ph + top + bottom;
- sy = scaledImageHeight ? scaledImageHeight - (yPosition + top) % scaledImageHeight : 0;
- } else {
- cy += max(yPosition + top, 0);
- sy = -min(yPosition + top, 0);
- ch = scaledImageHeight + min(yPosition + top, 0);
- }
-
- if (!bgLayer->attachment()) {
- sx += max(tx - cx, 0);
- sy += max(ty - cy, 0);
- }
-
- destRect = IntRect(cx, cy, cw, ch);
- destRect.intersect(IntRect(tx, ty, w, h));
- phase = IntPoint(sx, sy);
- tileSize = IntSize(scaledImageWidth, scaledImageHeight);
-}
-
-void RenderBox::paintFillLayerExtended(const PaintInfo& paintInfo, const Color& c, const FillLayer* bgLayer, int clipY, int clipH,
- int tx, int ty, int w, int h, InlineFlowBox* box, CompositeOperator op)
-{
- GraphicsContext* context = paintInfo.context;
- bool includeLeftEdge = box ? box->includeLeftEdge() : true;
- bool includeRightEdge = box ? box->includeRightEdge() : true;
- int bLeft = includeLeftEdge ? borderLeft() : 0;
- int bRight = includeRightEdge ? borderRight() : 0;
- int pLeft = includeLeftEdge ? paddingLeft() : 0;
- int pRight = includeRightEdge ? paddingRight() : 0;
-
- bool clippedToBorderRadius = false;
- if (style()->hasBorderRadius() && (includeLeftEdge || includeRightEdge)) {
- context->save();
- context->addRoundedRectClip(IntRect(tx, ty, w, h),
- includeLeftEdge ? style()->borderTopLeftRadius() : IntSize(),
- includeRightEdge ? style()->borderTopRightRadius() : IntSize(),
- includeLeftEdge ? style()->borderBottomLeftRadius() : IntSize(),
- includeRightEdge ? style()->borderBottomRightRadius() : IntSize());
- clippedToBorderRadius = true;
- }
-
- if (bgLayer->clip() == PaddingFillBox || bgLayer->clip() == ContentFillBox) {
- // Clip to the padding or content boxes as necessary.
- bool includePadding = bgLayer->clip() == ContentFillBox;
- int x = tx + bLeft + (includePadding ? pLeft : 0);
- int y = ty + borderTop() + (includePadding ? paddingTop() : 0);
- int width = w - bLeft - bRight - (includePadding ? pLeft + pRight : 0);
- int height = h - borderTop() - borderBottom() - (includePadding ? paddingTop() + paddingBottom() : 0);
- context->save();
- context->clip(IntRect(x, y, width, height));
- } else if (bgLayer->clip() == TextFillBox) {
- // We have to draw our text into a mask that can then be used to clip background drawing.
- // First figure out how big the mask has to be. It should be no bigger than what we need
- // to actually render, so we should intersect the dirty rect with the border box of the background.
- IntRect maskRect(tx, ty, w, h);
- maskRect.intersect(paintInfo.rect);
-
- // Now create the mask.
- auto_ptr<ImageBuffer> maskImage = ImageBuffer::create(maskRect.size(), false);
- if (!maskImage.get())
- return;
-
- GraphicsContext* maskImageContext = maskImage->context();
- maskImageContext->translate(-maskRect.x(), -maskRect.y());
-
- // Now add the text to the clip. We do this by painting using a special paint phase that signals to
- // InlineTextBoxes that they should just add their contents to the clip.
- PaintInfo info(maskImageContext, maskRect, PaintPhaseTextClip, true, 0, 0);
- if (box)
- box->paint(info, tx - box->xPos(), ty - box->yPos());
- else
- paint(info, tx, ty);
-
- // The mask has been created. Now we just need to clip to it.
- context->save();
- context->clipToImageBuffer(maskRect, maskImage.get());
- }
-
- StyleImage* bg = bgLayer->image();
- bool shouldPaintBackgroundImage = bg && bg->canRender(style()->effectiveZoom());
- Color bgColor = c;
-
- // When this style flag is set, change existing background colors and images to a solid white background.
- // If there's no bg color or image, leave it untouched to avoid affecting transparency.
- // We don't try to avoid loading the background images, because this style flag is only set
- // when printing, and at that point we've already loaded the background images anyway. (To avoid
- // loading the background images we'd have to do this check when applying styles rather than
- // while rendering.)
- if (style()->forceBackgroundsToWhite()) {
- // Note that we can't reuse this variable below because the bgColor might be changed
- bool shouldPaintBackgroundColor = !bgLayer->next() && bgColor.isValid() && bgColor.alpha() > 0;
- if (shouldPaintBackgroundImage || shouldPaintBackgroundColor) {
- bgColor = Color::white;
- shouldPaintBackgroundImage = false;
- }
- }
-
- // Only fill with a base color (e.g., white) if we're the root document, since iframes/frames with
- // no background in the child document should show the parent's background.
- bool isTransparent = false;
- if (!bgLayer->next() && isRoot() && !(bgColor.isValid() && bgColor.alpha() > 0) && view()->frameView()) {
- Node* elt = document()->ownerElement();
- if (elt) {
- if (!elt->hasTagName(frameTag)) {
- // Locate the <body> element using the DOM. This is easier than trying
- // to crawl around a render tree with potential :before/:after content and
- // anonymous blocks created by inline <body> tags etc. We can locate the <body>
- // render object very easily via the DOM.
- HTMLElement* body = document()->body();
- isTransparent = !body || !body->hasLocalName(framesetTag); // Can't scroll a frameset document anyway.
- }
- } else
- isTransparent = view()->frameView()->isTransparent();
-
- // FIXME: This needs to be dynamic. We should be able to go back to blitting if we ever stop being transparent.
- if (isTransparent)
- view()->frameView()->setUseSlowRepaints(); // The parent must show behind the child.
- }
-
- // Paint the color first underneath all images.
- if (!bgLayer->next()) {
- IntRect rect(tx, clipY, w, clipH);
- // If we have an alpha and we are painting the root element, go ahead and blend with the base background color.
- if (isRoot() && (!bgColor.isValid() || bgColor.alpha() < 0xFF) && !isTransparent) {
- Color baseColor = view()->frameView()->baseBackgroundColor();
- if (baseColor.alpha() > 0) {
- context->save();
- context->setCompositeOperation(CompositeCopy);
- context->fillRect(rect, baseColor);
- context->restore();
-#ifdef ANDROID_ALLOW_TRANSPARENT_BACKGROUNDS
- }
-#else
- } else
- context->clearRect(rect);
-#endif
- }
-
- if (bgColor.isValid() && bgColor.alpha() > 0)
- context->fillRect(rect, bgColor);
- }
-
- // no progressive loading of the background image
- if (shouldPaintBackgroundImage) {
- IntRect destRect;
- IntPoint phase;
- IntSize tileSize;
-
- calculateBackgroundImageGeometry(bgLayer, tx, ty, w, h, destRect, phase, tileSize);
- if (!destRect.isEmpty()) {
- CompositeOperator compositeOp = op == CompositeSourceOver ? bgLayer->composite() : op;
- context->drawTiledImage(bg->image(this, tileSize), destRect, phase, tileSize, compositeOp);
- }
- }
-
- if (bgLayer->clip() != BorderFillBox)
- // Undo the background clip
- context->restore();
-
- if (clippedToBorderRadius)
- // Undo the border radius clip
- context->restore();
-}
-
#if PLATFORM(MAC)
void RenderBox::paintCustomHighlight(int tx, int ty, const AtomicString& type, bool behindText)
@@ -1289,7 +832,7 @@ void RenderBox::paintCustomHighlight(int tx, int ty, const AtomicString& type, b
InlineBox* boxWrap = inlineBoxWrapper();
RootInlineBox* r = boxWrap ? boxWrap->root() : 0;
if (r) {
- FloatRect rootRect(tx + r->xPos(), ty + r->selectionTop(), r->width(), r->selectionHeight());
+ FloatRect rootRect(tx + r->x(), ty + r->selectionTop(), r->width(), r->selectionHeight());
FloatRect imageRect(tx + x(), rootRect.y(), width(), rootRect.height());
page->chrome()->client()->paintCustomHighlight(node(), type, imageRect, rootRect, behindText, false);
} else {
@@ -1300,7 +843,50 @@ void RenderBox::paintCustomHighlight(int tx, int ty, const AtomicString& type, b
#endif
-IntRect RenderBox::getOverflowClipRect(int tx, int ty)
+bool RenderBox::pushContentsClip(PaintInfo& paintInfo, int tx, int ty)
+{
+ if (paintInfo.phase == PaintPhaseBlockBackground || paintInfo.phase == PaintPhaseSelfOutline || paintInfo.phase == PaintPhaseMask)
+ return false;
+
+ bool isControlClip = hasControlClip();
+ bool isOverflowClip = hasOverflowClip() && !layer()->isSelfPaintingLayer();
+
+ if (!isControlClip && !isOverflowClip)
+ return false;
+
+ if (paintInfo.phase == PaintPhaseOutline)
+ paintInfo.phase = PaintPhaseChildOutlines;
+ else if (paintInfo.phase == PaintPhaseChildBlockBackground) {
+ paintInfo.phase = PaintPhaseBlockBackground;
+ paintObject(paintInfo, tx, ty);
+ paintInfo.phase = PaintPhaseChildBlockBackgrounds;
+ }
+ IntRect clipRect(isControlClip ? controlClipRect(tx, ty) : overflowClipRect(tx, ty));
+ paintInfo.context->save();
+ if (style()->hasBorderRadius())
+ paintInfo.context->addRoundedRectClip(clipRect, style()->borderTopLeftRadius(),
+ style()->borderTopRightRadius(),
+ style()->borderBottomLeftRadius(),
+ style()->borderBottomRightRadius());
+ else
+ paintInfo.context->clip(clipRect);
+ return true;
+}
+
+void RenderBox::popContentsClip(PaintInfo& paintInfo, PaintPhase originalPhase, int tx, int ty)
+{
+ ASSERT(hasControlClip() || (hasOverflowClip() && !layer()->isSelfPaintingLayer()));
+
+ paintInfo.context->restore();
+ if (originalPhase == PaintPhaseOutline) {
+ paintInfo.phase = PaintPhaseSelfOutline;
+ paintObject(paintInfo, tx, ty);
+ paintInfo.phase = originalPhase;
+ } else if (originalPhase == PaintPhaseChildBlockBackground)
+ paintInfo.phase = originalPhase;
+}
+
+IntRect RenderBox::overflowClipRect(int tx, int ty)
{
// FIXME: When overflow-clip (CSS3) is implemented, we'll obtain the property
// here.
@@ -1314,15 +900,15 @@ IntRect RenderBox::getOverflowClipRect(int tx, int ty)
int clipHeight = height() - bTop - borderBottom();
// Subtract out scrollbars if we have them.
- if (m_layer) {
- clipWidth -= m_layer->verticalScrollbarWidth();
- clipHeight -= m_layer->horizontalScrollbarHeight();
+ if (layer()) {
+ clipWidth -= layer()->verticalScrollbarWidth();
+ clipHeight -= layer()->horizontalScrollbarHeight();
}
return IntRect(clipX, clipY, clipWidth, clipHeight);
}
-IntRect RenderBox::getClipRect(int tx, int ty)
+IntRect RenderBox::clipRect(int tx, int ty)
{
int clipX = tx;
int clipY = ty;
@@ -1350,64 +936,28 @@ IntRect RenderBox::getClipRect(int tx, int ty)
return IntRect(clipX, clipY, clipWidth, clipHeight);
}
-int RenderBox::containingBlockWidth() const
+int RenderBox::containingBlockWidthForContent() const
{
RenderBlock* cb = containingBlock();
- if (!cb)
- return 0;
if (shrinkToAvoidFloats())
- return cb->lineWidth(y());
+ return cb->lineWidth(y(), false);
return cb->availableWidth();
}
-IntSize RenderBox::offsetForPositionedInContainer(RenderObject* container) const
+void RenderBox::mapLocalToContainer(RenderBoxModelObject* repaintContainer, bool fixed, bool useTransforms, TransformState& transformState) const
{
- if (!container->isRelPositioned() || !container->isRenderInline())
- return IntSize();
-
- // When we have an enclosing relpositioned inline, we need to add in the offset of the first line
- // box from the rest of the content, but only in the cases where we know we're positioned
- // relative to the inline itself.
-
- IntSize offset;
- RenderFlow* flow = static_cast<RenderFlow*>(container);
- int sx;
- int sy;
- if (flow->firstLineBox()) {
- sx = flow->firstLineBox()->xPos();
- sy = flow->firstLineBox()->yPos();
- } else {
- sx = flow->staticX();
- sy = flow->staticY();
- }
-
- if (!hasStaticX())
- offset.setWidth(sx);
- // This is not terribly intuitive, but we have to match other browsers. Despite being a block display type inside
- // an inline, we still keep our x locked to the left of the relative positioned inline. Arguably the correct
- // behavior would be to go flush left to the block that contains the inline, but that isn't what other browsers
- // do.
- else if (!style()->isOriginalDisplayInlineType())
- // Avoid adding in the left border/padding of the containing block twice. Subtract it out.
- offset.setWidth(sx - (containingBlock()->borderLeft() + containingBlock()->paddingLeft()));
-
- if (!hasStaticY())
- offset.setHeight(sy);
-
- return offset;
-}
+ if (repaintContainer == this)
+ return;
-FloatPoint RenderBox::localToAbsolute(FloatPoint localPoint, bool fixed, bool useTransforms) const
-{
if (RenderView* v = view()) {
if (v->layoutStateEnabled()) {
LayoutState* layoutState = v->layoutState();
IntSize offset = layoutState->m_offset;
offset.expand(x(), y());
- localPoint += offset;
- if (style()->position() == RelativePosition && m_layer)
- localPoint += m_layer->relativePositionOffset();
- return localPoint;
+ if (style()->position() == RelativePosition && layer())
+ offset += layer()->relativePositionOffset();
+ transformState.move(offset);
+ return;
}
}
@@ -1415,21 +965,25 @@ FloatPoint RenderBox::localToAbsolute(FloatPoint localPoint, bool fixed, bool us
fixed = true;
RenderObject* o = container();
- if (o) {
- if (useTransforms && m_layer && m_layer->transform()) {
- fixed = false; // Elements with transforms act as a containing block for fixed position descendants
- localPoint = m_layer->transform()->mapPoint(localPoint);
- }
+ if (!o)
+ return;
- localPoint += offsetFromContainer(o);
+ bool hasTransform = hasLayer() && layer()->transform();
+ if (hasTransform)
+ fixed = false; // Elements with transforms act as a containing block for fixed position descendants
- return o->localToAbsolute(localPoint, fixed, useTransforms);
- }
-
- return FloatPoint();
+ IntSize containerOffset = offsetFromContainer(o);
+
+ bool preserve3D = useTransforms && (o->style()->preserves3D() || style()->preserves3D());
+ if (useTransforms && hasTransform)
+ transformState.applyTransform(transformFromContainer(o, containerOffset), preserve3D);
+ else
+ transformState.move(containerOffset.width(), containerOffset.height(), preserve3D);
+
+ o->mapLocalToContainer(repaintContainer, fixed, useTransforms, transformState);
}
-FloatPoint RenderBox::absoluteToLocal(FloatPoint containerPoint, bool fixed, bool useTransforms) const
+void RenderBox::mapAbsoluteToLocalPoint(bool fixed, bool useTransforms, TransformState& transformState) const
{
// We don't expect absoluteToLocal() to be called during layout (yet)
ASSERT(!view() || !view()->layoutStateEnabled());
@@ -1437,41 +991,23 @@ FloatPoint RenderBox::absoluteToLocal(FloatPoint containerPoint, bool fixed, boo
if (style()->position() == FixedPosition)
fixed = true;
- if (useTransforms && m_layer && m_layer->transform())
- fixed = false;
+ bool hasTransform = hasLayer() && layer()->transform();
+ if (hasTransform)
+ fixed = false; // Elements with transforms act as a containing block for fixed position descendants
RenderObject* o = container();
- if (o) {
- FloatPoint localPoint = o->absoluteToLocal(containerPoint, fixed, useTransforms);
- localPoint -= offsetFromContainer(o);
- if (useTransforms && m_layer && m_layer->transform())
- localPoint = m_layer->transform()->inverse().mapPoint(localPoint);
- return localPoint;
- }
-
- return FloatPoint();
-}
+ if (!o)
+ return;
-FloatQuad RenderBox::localToContainerQuad(const FloatQuad& localQuad, RenderBox* repaintContainer, bool fixed) const
-{
- if (repaintContainer == this)
- return localQuad;
+ o->mapAbsoluteToLocalPoint(fixed, useTransforms, transformState);
- if (style()->position() == FixedPosition)
- fixed = true;
+ IntSize containerOffset = offsetFromContainer(o);
- RenderObject* o = container();
- if (o) {
- FloatQuad quad = localQuad;
- if (m_layer && m_layer->transform()) {
- fixed = false; // Elements with transforms act as a containing block for fixed position descendants
- quad = m_layer->transform()->mapQuad(quad);
- }
- quad += offsetFromContainer(o);
- return o->localToContainerQuad(quad, repaintContainer, fixed);
- }
-
- return FloatQuad();
+ bool preserve3D = useTransforms && (o->style()->preserves3D() || style()->preserves3D());
+ if (useTransforms && hasTransform)
+ transformState.applyTransform(transformFromContainer(o, containerOffset), preserve3D);
+ else
+ transformState.move(-containerOffset.width(), -containerOffset.height(), preserve3D);
}
IntSize RenderBox::offsetFromContainer(RenderObject* o) const
@@ -1485,7 +1021,7 @@ IntSize RenderBox::offsetFromContainer(RenderObject* o) const
if (!isInline() || isReplaced()) {
RenderBlock* cb;
if (o->isBlockFlow() && style()->position() != AbsolutePosition && style()->position() != FixedPosition
- && (cb = static_cast<RenderBlock*>(o))->hasColumns()) {
+ && (cb = toRenderBlock(o))->hasColumns()) {
IntRect rect(x(), y(), 1, 1);
cb->adjustRectForColumns(rect);
offset.expand(rect.x(), rect.y());
@@ -1496,13 +1032,18 @@ IntSize RenderBox::offsetFromContainer(RenderObject* o) const
if (o->hasOverflowClip())
offset -= toRenderBox(o)->layer()->scrolledContentOffset();
- if (style()->position() == AbsolutePosition)
- offset += offsetForPositionedInContainer(o);
+ if (style()->position() == AbsolutePosition && o->isRelPositioned() && o->isRenderInline())
+ offset += toRenderInline(o)->relativePositionedInlineOffset(this);
return offset;
}
-void RenderBox::dirtyLineBoxes(bool fullLayout, bool /*isRootLineBox*/)
+InlineBox* RenderBox::createInlineBox()
+{
+ return new (renderArena()) InlineBox(this);
+}
+
+void RenderBox::dirtyLineBoxes(bool fullLayout)
{
if (m_inlineBoxWrapper) {
if (fullLayout) {
@@ -1513,23 +1054,23 @@ void RenderBox::dirtyLineBoxes(bool fullLayout, bool /*isRootLineBox*/)
}
}
-void RenderBox::position(InlineBox* box)
+void RenderBox::positionLineBox(InlineBox* box)
{
if (isPositioned()) {
// Cache the x position only if we were an INLINE type originally.
bool wasInline = style()->isOriginalDisplayInlineType();
- if (wasInline && hasStaticX()) {
+ if (wasInline && style()->hasStaticX()) {
// The value is cached in the xPos of the box. We only need this value if
// our object was inline originally, since otherwise it would have ended up underneath
// the inlines.
- setStaticX(box->xPos());
+ layer()->setStaticX(box->x());
setChildNeedsLayout(true, false); // Just go ahead and mark the positioned object as needing layout, so it will update its position properly.
- } else if (!wasInline && hasStaticY()) {
+ } else if (!wasInline && style()->hasStaticY()) {
// Our object was a block originally, so we make our normal flow position be
// just below the line box (as though all the inlines that came before us got
// wrapped in an anonymous block, which is what would have happened had we been
- // in flow). This value was cached in the yPos() of the box.
- setStaticY(box->yPos());
+ // in flow). This value was cached in the y() of the box.
+ layer()->setStaticY(box->y());
setChildNeedsLayout(true, false); // Just go ahead and mark the positioned object as needing layout, so it will update its position properly.
}
@@ -1537,7 +1078,7 @@ void RenderBox::position(InlineBox* box)
box->remove();
box->destroy(renderArena());
} else if (isReplaced()) {
- setLocation(box->xPos(), box->yPos());
+ setLocation(box->x(), box->y());
m_inlineBoxWrapper = box;
}
}
@@ -1552,7 +1093,7 @@ void RenderBox::deleteLineBoxWrapper()
}
}
-IntRect RenderBox::clippedOverflowRectForRepaint(RenderBox* repaintContainer)
+IntRect RenderBox::clippedOverflowRectForRepaint(RenderBoxModelObject* repaintContainer)
{
if (style()->visibility() != VISIBLE && !enclosingLayer()->hasVisibleContent())
return IntRect();
@@ -1578,18 +1119,18 @@ IntRect RenderBox::clippedOverflowRectForRepaint(RenderBox* repaintContainer)
r.inflate(v->maximalOutlineSize());
}
}
- computeRectForRepaint(r, repaintContainer);
+ computeRectForRepaint(repaintContainer, r);
return r;
}
-void RenderBox::computeRectForRepaint(IntRect& rect, RenderBox* repaintContainer, bool fixed)
+void RenderBox::computeRectForRepaint(RenderBoxModelObject* repaintContainer, IntRect& rect, bool fixed)
{
if (RenderView* v = view()) {
// LayoutState is only valid for root-relative repainting
if (v->layoutStateEnabled() && !repaintContainer) {
LayoutState* layoutState = v->layoutState();
- if (style()->position() == RelativePosition && m_layer)
- rect.move(m_layer->relativePositionOffset());
+ if (style()->position() == RelativePosition && layer())
+ rect.move(layer()->relativePositionOffset());
rect.move(x(), y());
rect.move(layoutState->m_offset);
@@ -1616,7 +1157,7 @@ void RenderBox::computeRectForRepaint(IntRect& rect, RenderBox* repaintContainer
fixed = true;
if (o->isBlockFlow() && style()->position() != AbsolutePosition && style()->position() != FixedPosition) {
- RenderBlock* cb = static_cast<RenderBlock*>(o);
+ RenderBlock* cb = toRenderBlock(o);
if (cb->hasColumns()) {
IntRect repaintRect(topLeft, rect.size());
cb->adjustRectForColumns(repaintRect);
@@ -1627,22 +1168,22 @@ void RenderBox::computeRectForRepaint(IntRect& rect, RenderBox* repaintContainer
// We are now in our parent container's coordinate space. Apply our transform to obtain a bounding box
// in the parent's coordinate space that encloses us.
- if (m_layer && m_layer->transform()) {
+ if (layer() && layer()->transform()) {
fixed = false;
- rect = m_layer->transform()->mapRect(rect);
+ rect = layer()->transform()->mapRect(rect);
// FIXME: this clobbers topLeft adjustment done for multicol above
topLeft = rect.location();
topLeft.move(x(), y());
}
- if (style()->position() == AbsolutePosition)
- topLeft += offsetForPositionedInContainer(o);
- else if (style()->position() == RelativePosition && m_layer) {
+ if (style()->position() == AbsolutePosition && o->isRelPositioned() && o->isRenderInline())
+ topLeft += toRenderInline(o)->relativePositionedInlineOffset(this);
+ else if (style()->position() == RelativePosition && layer()) {
// Apply the relative position offset when invalidating a rectangle. The layer
// is translated, but the render box isn't, so we need to do this to get the
// right dirty rect. Since this is called from RenderObject::setStyle, the relative position
// flag on the RenderObject has been cleared, so use the one on the style().
- topLeft += m_layer->relativePositionOffset();
+ topLeft += layer()->relativePositionOffset();
}
// FIXME: We ignore the lightweight clipping rect that controls use, since if |o| is in mid-layout,
@@ -1663,7 +1204,7 @@ void RenderBox::computeRectForRepaint(IntRect& rect, RenderBox* repaintContainer
} else
rect.setLocation(topLeft);
- o->computeRectForRepaint(rect, repaintContainer, fixed);
+ o->computeRectForRepaint(repaintContainer, rect, fixed);
}
void RenderBox::repaintDuringLayoutIfMoved(const IntRect& rect)
@@ -1684,30 +1225,6 @@ void RenderBox::repaintDuringLayoutIfMoved(const IntRect& rect)
}
}
-int RenderBox::relativePositionOffsetX() const
-{
- if (!style()->left().isAuto()) {
- if (!style()->right().isAuto() && containingBlock()->style()->direction() == RTL)
- return -style()->right().calcValue(containingBlockWidth());
- return style()->left().calcValue(containingBlockWidth());
- }
- if (!style()->right().isAuto())
- return -style()->right().calcValue(containingBlockWidth());
- return 0;
-}
-
-int RenderBox::relativePositionOffsetY() const
-{
- if (!style()->top().isAuto()) {
- if (!style()->top().isPercent() || containingBlock()->style()->height().isFixed())
- return style()->top().calcValue(containingBlockHeight());
- } else if (!style()->bottom().isAuto()) {
- if (!style()->bottom().isPercent() || containingBlock()->style()->height().isFixed())
- return -style()->bottom().calcValue(containingBlockHeight());
- }
- return 0;
-}
-
void RenderBox::calcWidth()
{
#ifdef ANDROID_LAYOUT
@@ -1744,7 +1261,7 @@ void RenderBox::calcWidth()
Length w = (treatAsReplaced) ? Length(calcReplacedWidth(), Fixed) : style()->width();
RenderBlock* cb = containingBlock();
- int containerWidth = max(0, containingBlockWidth());
+ int containerWidth = max(0, containingBlockWidthForContent());
Length marginLeft = style()->marginLeft();
Length marginRight = style()->marginRight();
@@ -2110,7 +1627,7 @@ int RenderBox::calcReplacedWidthUsing(Length width) const
case Fixed:
return calcContentBoxWidth(width.value());
case Percent: {
- const int cw = isPositioned() ? containingBlockWidthForPositioned(container()) : containingBlockWidth();
+ const int cw = isPositioned() ? containingBlockWidthForPositioned(toRenderBoxModelObject(container())) : containingBlockWidthForContent();
if (cw > 0)
return calcContentBoxWidth(width.calcMinValue(cw));
}
@@ -2139,12 +1656,12 @@ int RenderBox::calcReplacedHeightUsing(Length height) const
RenderObject* cb = isPositioned() ? container() : containingBlock();
while (cb->isAnonymous()) {
cb = cb->containingBlock();
- static_cast<RenderBlock*>(cb)->addPercentHeightDescendant(const_cast<RenderBox*>(this));
+ toRenderBlock(cb)->addPercentHeightDescendant(const_cast<RenderBox*>(this));
}
if (cb->isPositioned() && cb->style()->height().isAuto() && !(cb->style()->top().isAuto() || cb->style()->bottom().isAuto())) {
ASSERT(cb->isRenderBlock());
- RenderBlock* block = static_cast<RenderBlock*>(cb);
+ RenderBlock* block = toRenderBlock(cb);
int oldHeight = block->height();
block->calcHeight();
int newHeight = block->calcContentBoxHeight(block->contentHeight());
@@ -2152,7 +1669,7 @@ int RenderBox::calcReplacedHeightUsing(Length height) const
return calcContentBoxHeight(height.calcValue(newHeight));
}
- int availableHeight = isPositioned() ? containingBlockHeightForPositioned(cb) : toRenderBox(cb)->availableHeight();
+ int availableHeight = isPositioned() ? containingBlockHeightForPositioned(toRenderBoxModelObject(cb)) : toRenderBox(cb)->availableHeight();
// It is necessary to use the border-box to match WinIE's broken
// box model. This is essential for sizing inside
@@ -2183,7 +1700,7 @@ int RenderBox::availableHeightUsing(const Length& h) const
return calcContentBoxHeight(h.value());
if (isRenderView())
- return static_cast<const RenderView*>(this)->frameView()->visibleHeight();
+ return toRenderView(this)->frameView()->visibleHeight();
// We need to stop here, since we don't want to increase the height of the table
// artificially. We're going to rely on this cell getting expanded to some new
@@ -2195,7 +1712,7 @@ int RenderBox::availableHeightUsing(const Length& h) const
return calcContentBoxHeight(h.calcValue(containingBlock()->availableHeight()));
if (isRenderBlock() && isPositioned() && style()->height().isAuto() && !(style()->top().isAuto() || style()->bottom().isAuto())) {
- RenderBlock* block = const_cast<RenderBlock*>(static_cast<const RenderBlock*>(this));
+ RenderBlock* block = const_cast<RenderBlock*>(toRenderBlock(this));
int oldHeight = block->height();
block->calcHeight();
int newHeight = block->calcContentBoxHeight(block->contentHeight());
@@ -2222,75 +1739,46 @@ void RenderBox::calcVerticalMargins()
m_marginBottom = style()->marginBottom().calcMinValue(cw);
}
-int RenderBox::staticX() const
-{
- return m_layer ? m_layer->staticX() : 0;
-}
-
-int RenderBox::staticY() const
-{
- return m_layer ? m_layer->staticY() : 0;
-}
-
-void RenderBox::setStaticX(int staticX)
+int RenderBox::containingBlockWidthForPositioned(const RenderBoxModelObject* containingBlock) const
{
- ASSERT(isPositioned() || isRelPositioned());
- m_layer->setStaticX(staticX);
-}
-
-void RenderBox::setStaticY(int staticY)
-{
- ASSERT(isPositioned() || isRelPositioned());
-
- if (staticY == m_layer->staticY())
- return;
+ if (containingBlock->isBox()) {
+ const RenderBox* containingBlockBox = toRenderBox(containingBlock);
+ return containingBlockBox->width() - containingBlockBox->borderLeft() - containingBlockBox->borderRight() - containingBlockBox->verticalScrollbarWidth();
+ }
- m_layer->setStaticY(staticY);
- setChildNeedsLayout(true, false);
-}
-
-int RenderBox::containingBlockWidthForPositioned(const RenderObject* containingBlock) const
-{
- if (containingBlock->isRenderInline()) {
- ASSERT(containingBlock->isRelPositioned());
-
- const RenderFlow* flow = static_cast<const RenderFlow*>(containingBlock);
- InlineFlowBox* first = flow->firstLineBox();
- InlineFlowBox* last = flow->lastLineBox();
+ ASSERT(containingBlock->isRenderInline() && containingBlock->isRelPositioned());
- // If the containing block is empty, return a width of 0.
- if (!first || !last)
- return 0;
+ const RenderInline* flow = toRenderInline(containingBlock);
+ InlineFlowBox* first = flow->firstLineBox();
+ InlineFlowBox* last = flow->lastLineBox();
- int fromLeft;
- int fromRight;
- if (containingBlock->style()->direction() == LTR) {
- fromLeft = first->xPos() + first->borderLeft();
- fromRight = last->xPos() + last->width() - last->borderRight();
- } else {
- fromRight = first->xPos() + first->width() - first->borderRight();
- fromLeft = last->xPos() + last->borderLeft();
- }
+ // If the containing block is empty, return a width of 0.
+ if (!first || !last)
+ return 0;
- return max(0, (fromRight - fromLeft));
+ int fromLeft;
+ int fromRight;
+ if (containingBlock->style()->direction() == LTR) {
+ fromLeft = first->x() + first->borderLeft();
+ fromRight = last->x() + last->width() - last->borderRight();
+ } else {
+ fromRight = first->x() + first->width() - first->borderRight();
+ fromLeft = last->x() + last->borderLeft();
}
- const RenderBox* containingBlockBox = toRenderBox(containingBlock);
- return containingBlockBox->width() - containingBlockBox->borderLeft() - containingBlockBox->borderRight() - containingBlockBox->verticalScrollbarWidth();
+ return max(0, (fromRight - fromLeft));
}
-int RenderBox::containingBlockHeightForPositioned(const RenderObject* containingBlock) const
-{
- const RenderBox* containingBlockBox = toRenderBox(containingBlock);
-
- int heightResult;
- if (containingBlock->isRenderInline()) {
+int RenderBox::containingBlockHeightForPositioned(const RenderBoxModelObject* containingBlock) const
+{
+ int heightResult = 0;
+ if (containingBlock->isBox())
+ heightResult = toRenderBox(containingBlock)->height();
+ else if (containingBlock->isRenderInline()) {
ASSERT(containingBlock->isRelPositioned());
- heightResult = static_cast<const RenderInline*>(containingBlock)->linesBoundingBox().height();
- } else
- heightResult = containingBlockBox->height();
-
- return heightResult - containingBlockBox->borderTop() - containingBlockBox->borderBottom();
+ heightResult = toRenderInline(containingBlock)->linesBoundingBox().height();
+ }
+ return heightResult - containingBlock->borderTop() - containingBlock->borderBottom();
}
void RenderBox::calcAbsoluteHorizontal()
@@ -2327,7 +1815,7 @@ void RenderBox::calcAbsoluteHorizontal()
// We don't use containingBlock(), since we may be positioned by an enclosing
// relative positioned inline.
- const RenderBox* containerBlock = toRenderBox(container());
+ const RenderBoxModelObject* containerBlock = toRenderBoxModelObject(container());
const int containerWidth = containingBlockWidthForPositioned(containerBlock);
@@ -2370,16 +1858,22 @@ void RenderBox::calcAbsoluteHorizontal()
if (left.isAuto() && right.isAuto()) {
if (containerDirection == LTR) {
// 'staticX' should already have been set through layout of the parent.
- int staticPosition = staticX() - containerBlock->borderLeft();
- for (RenderBox* po = parentBox(); po && po != containerBlock; po = po->parentBox())
- staticPosition += po->x();
+ int staticPosition = layer()->staticX() - containerBlock->borderLeft();
+ for (RenderObject* po = parent(); po && po != containerBlock; po = po->parent()) {
+ if (po->isBox())
+ staticPosition += toRenderBox(po)->x();
+ }
left.setValue(Fixed, staticPosition);
} else {
- RenderBox* po = parentBox();
+ RenderObject* po = parent();
// 'staticX' should already have been set through layout of the parent.
- int staticPosition = staticX() + containerWidth + containerBlock->borderRight() - po->width();
- for (; po && po != containerBlock; po = po->parentBox())
- staticPosition -= po->x();
+ int staticPosition = layer()->staticX() + containerWidth + containerBlock->borderRight();
+ if (po->isBox())
+ staticPosition -= toRenderBox(po)->width();
+ for (; po && po != containerBlock; po = po->parent()) {
+ if (po->isBox())
+ staticPosition -= toRenderBox(po)->x();
+ }
right.setValue(Fixed, staticPosition);
}
}
@@ -2447,7 +1941,7 @@ void RenderBox::calcAbsoluteHorizontal()
setWidth(width() + bordersPlusPadding);
}
-void RenderBox::calcAbsoluteHorizontalValues(Length width, const RenderBox* containerBlock, TextDirection containerDirection,
+void RenderBox::calcAbsoluteHorizontalValues(Length width, const RenderBoxModelObject* containerBlock, TextDirection containerDirection,
const int containerWidth, const int bordersPlusPadding,
const Length left, const Length right, const Length marginLeft, const Length marginRight,
int& widthValue, int& marginLeftValue, int& marginRightValue, int& xPos)
@@ -2603,15 +2097,15 @@ void RenderBox::calcAbsoluteHorizontalValues(Length width, const RenderBox* cont
// Use computed values to calculate the horizontal position.
// FIXME: This hack is needed to calculate the xPos for a 'rtl' relatively
- // positioned, inline containing block because right now, it is using the xPos
+ // positioned, inline because right now, it is using the xPos
// of the first line box when really it should use the last line box. When
// this is fixed elsewhere, this block should be removed.
- if (containerBlock->isInline() && containerBlock->style()->direction() == RTL) {
- const RenderFlow* flow = static_cast<const RenderFlow*>(containerBlock);
+ if (containerBlock->isRenderInline() && containerBlock->style()->direction() == RTL) {
+ const RenderInline* flow = toRenderInline(containerBlock);
InlineFlowBox* firstLine = flow->firstLineBox();
InlineFlowBox* lastLine = flow->lastLineBox();
if (firstLine && lastLine && firstLine != lastLine) {
- xPos = leftValue + marginLeftValue + lastLine->borderLeft() + (lastLine->xPos() - firstLine->xPos());
+ xPos = leftValue + marginLeftValue + lastLine->borderLeft() + (lastLine->x() - firstLine->x());
return;
}
}
@@ -2634,7 +2128,7 @@ void RenderBox::calcAbsoluteVertical()
// We don't use containingBlock(), since we may be positioned by an enclosing relpositioned inline.
- const RenderBox* containerBlock = toRenderBox(container());
+ const RenderBoxModelObject* containerBlock = toRenderBoxModelObject(container());
const int containerHeight = containingBlockHeightForPositioned(containerBlock);
@@ -2665,10 +2159,10 @@ void RenderBox::calcAbsoluteVertical()
// Calculate the static distance if needed.
if (top.isAuto() && bottom.isAuto()) {
// staticY should already have been set through layout of the parent()
- int staticTop = staticY() - containerBlock->borderTop();
- for (RenderBox* po = parentBox(); po && po != containerBlock; po = po->parentBox()) {
- if (!po->isTableRow())
- staticTop += po->y();
+ int staticTop = layer()->staticY() - containerBlock->borderTop();
+ for (RenderObject* po = parent(); po && po != containerBlock; po = po->parent()) {
+ if (po->isBox() && !po->isTableRow())
+ staticTop += toRenderBox(po)->y();
}
top.setValue(Fixed, staticTop);
}
@@ -2728,7 +2222,7 @@ void RenderBox::calcAbsoluteVertical()
setHeight(h + bordersPlusPadding);
}
-void RenderBox::calcAbsoluteVerticalValues(Length h, const RenderBox* containerBlock,
+void RenderBox::calcAbsoluteVerticalValues(Length h, const RenderBoxModelObject* containerBlock,
const int containerHeight, const int bordersPlusPadding,
const Length top, const Length bottom, const Length marginTop, const Length marginBottom,
int& heightValue, int& marginTopValue, int& marginBottomValue, int& yPos)
@@ -2857,7 +2351,7 @@ void RenderBox::calcAbsoluteHorizontalReplaced()
// We don't use containingBlock(), since we may be positioned by an enclosing
// relative positioned inline.
- const RenderBox* containerBlock = toRenderBox(container());
+ const RenderBoxModelObject* containerBlock = toRenderBoxModelObject(container());
const int containerWidth = containingBlockWidthForPositioned(containerBlock);
@@ -2892,16 +2386,20 @@ void RenderBox::calcAbsoluteHorizontalReplaced()
// see FIXME 1
if (containerDirection == LTR) {
// 'staticX' should already have been set through layout of the parent.
- int staticPosition = staticX() - containerBlock->borderLeft();
- for (RenderBox* po = parentBox(); po && po != containerBlock; po = po->parentBox())
- staticPosition += po->x();
+ int staticPosition = layer()->staticX() - containerBlock->borderLeft();
+ for (RenderObject* po = parent(); po && po != containerBlock; po = po->parent()) {
+ if (po->isBox())
+ staticPosition += toRenderBox(po)->x();
+ }
left.setValue(Fixed, staticPosition);
} else {
- RenderBox* po = parentBox();
+ RenderObject* po = parent();
// 'staticX' should already have been set through layout of the parent.
- int staticPosition = staticX() + containerWidth + containerBlock->borderRight() - po->width();
- for (; po && po != containerBlock; po = po->parentBox())
- staticPosition -= po->x();
+ int staticPosition = layer()->staticX() + containerWidth + containerBlock->borderRight();
+ for ( ; po && po != containerBlock; po = po->parent()) {
+ if (po->isBox())
+ staticPosition += toRenderBox(po)->x();
+ }
right.setValue(Fixed, staticPosition);
}
}
@@ -3009,11 +2507,11 @@ void RenderBox::calcAbsoluteHorizontalReplaced()
// of the first line box when really it should use the last line box. When
// this is fixed elsewhere, this block should be removed.
if (containerBlock->isInline() && containerBlock->style()->direction() == RTL) {
- const RenderFlow* flow = static_cast<const RenderFlow*>(containerBlock);
+ const RenderInline* flow = toRenderInline(containerBlock);
InlineFlowBox* firstLine = flow->firstLineBox();
InlineFlowBox* lastLine = flow->lastLineBox();
if (firstLine && lastLine && firstLine != lastLine) {
- m_frameRect.setX(leftValue + m_marginLeft + lastLine->borderLeft() + (lastLine->xPos() - firstLine->xPos()));
+ m_frameRect.setX(leftValue + m_marginLeft + lastLine->borderLeft() + (lastLine->x() - firstLine->x()));
return;
}
}
@@ -3030,7 +2528,7 @@ void RenderBox::calcAbsoluteVerticalReplaced()
// the numbers correspond to numbers in spec)
// We don't use containingBlock(), since we may be positioned by an enclosing relpositioned inline.
- const RenderBox* containerBlock = toRenderBox(container());
+ const RenderBoxModelObject* containerBlock = toRenderBoxModelObject(container());
const int containerHeight = containingBlockHeightForPositioned(containerBlock);
@@ -3058,10 +2556,10 @@ void RenderBox::calcAbsoluteVerticalReplaced()
// see FIXME 2
if (top.isAuto() && bottom.isAuto()) {
// staticY should already have been set through layout of the parent().
- int staticTop = staticY() - containerBlock->borderTop();
- for (RenderBox* po = parentBox(); po && po != containerBlock; po = po->parentBox()) {
- if (!po->isTableRow())
- staticTop += po->y();
+ int staticTop = layer()->staticY() - containerBlock->borderTop();
+ for (RenderObject* po = parent(); po && po != containerBlock; po = po->parent()) {
+ if (po->isBox() && !po->isTableRow())
+ staticTop += toRenderBox(po)->y();
}
top.setValue(Fixed, staticTop);
}
@@ -3161,7 +2659,6 @@ IntRect RenderBox::localCaretRect(InlineBox* box, int caretOffset, int* extraWid
// FIXME: Paint the carets inside empty blocks differently than the carets before/after elements.
// FIXME: What about border and padding?
- const int caretWidth = 1;
IntRect rect(x(), y(), caretWidth, height());
TextDirection direction = box ? box->direction() : style()->direction();
@@ -3184,7 +2681,7 @@ IntRect RenderBox::localCaretRect(InlineBox* box, int caretOffset, int* extraWid
//
// FIXME: ignoring :first-line, missing good reason to take care of
int fontHeight = style()->font().height();
- if (fontHeight > rect.height() || !isReplaced() && !isTable())
+ if (fontHeight > rect.height() || (!isReplaced() && !isTable()))
rect.setHeight(fontHeight);
if (extraWidthToEndOfLine)
@@ -3225,6 +2722,118 @@ int RenderBox::leftmostPosition(bool /*includeOverflowInterior*/, bool includeSe
return left;
}
+bool RenderBox::isAfterContent(RenderObject* child) const
+{
+ return (child && child->style()->styleType() == AFTER && (!child->isText() || child->isBR()));
+}
+
+VisiblePosition RenderBox::positionForPoint(const IntPoint& point)
+{
+ // no children...return this render object's element, if there is one, and offset 0
+ if (!firstChild())
+ return createVisiblePosition(firstDeepEditingPositionForNode(node()));
+
+ int xPos = point.x();
+ int yPos = point.y();
+
+ if (isTable() && node()) {
+ int right = contentWidth() + borderRight() + paddingRight() + borderLeft() + paddingLeft();
+ int bottom = contentHeight() + borderTop() + paddingTop() + borderBottom() + paddingBottom();
+
+ if (xPos < 0 || xPos > right || yPos < 0 || yPos > bottom) {
+ if (xPos <= right / 2)
+ return createVisiblePosition(firstDeepEditingPositionForNode(node()));
+ return createVisiblePosition(lastDeepEditingPositionForNode(node()));
+ }
+ }
+
+ // Pass off to the closest child.
+ int minDist = INT_MAX;
+ RenderBox* closestRenderer = 0;
+ int newX = xPos;
+ int newY = yPos;
+ if (isTableRow()) {
+ newX += x();
+ newY += y();
+ }
+ for (RenderObject* renderObject = firstChild(); renderObject; renderObject = renderObject->nextSibling()) {
+ if ((!renderObject->firstChild() && !renderObject->isInline() && !renderObject->isBlockFlow() )
+ || renderObject->style()->visibility() != VISIBLE)
+ continue;
+
+ if (!renderObject->isBox())
+ continue;
+
+ RenderBox* renderer = toRenderBox(renderObject);
+
+ int top = renderer->borderTop() + renderer->paddingTop() + (isTableRow() ? 0 : renderer->y());
+ int bottom = top + renderer->contentHeight();
+ int left = renderer->borderLeft() + renderer->paddingLeft() + (isTableRow() ? 0 : renderer->x());
+ int right = left + renderer->contentWidth();
+
+ if (xPos <= right && xPos >= left && yPos <= top && yPos >= bottom) {
+ if (renderer->isTableRow())
+ return renderer->positionForCoordinates(xPos + newX - renderer->x(), yPos + newY - renderer->y());
+ return renderer->positionForCoordinates(xPos - renderer->x(), yPos - renderer->y());
+ }
+
+ // Find the distance from (x, y) to the box. Split the space around the box into 8 pieces
+ // and use a different compare depending on which piece (x, y) is in.
+ IntPoint cmp;
+ if (xPos > right) {
+ if (yPos < top)
+ cmp = IntPoint(right, top);
+ else if (yPos > bottom)
+ cmp = IntPoint(right, bottom);
+ else
+ cmp = IntPoint(right, yPos);
+ } else if (xPos < left) {
+ if (yPos < top)
+ cmp = IntPoint(left, top);
+ else if (yPos > bottom)
+ cmp = IntPoint(left, bottom);
+ else
+ cmp = IntPoint(left, yPos);
+ } else {
+ if (yPos < top)
+ cmp = IntPoint(xPos, top);
+ else
+ cmp = IntPoint(xPos, bottom);
+ }
+
+ int x1minusx2 = cmp.x() - xPos;
+ int y1minusy2 = cmp.y() - yPos;
+
+ int dist = x1minusx2 * x1minusx2 + y1minusy2 * y1minusy2;
+ if (dist < minDist) {
+ closestRenderer = renderer;
+ minDist = dist;
+ }
+ }
+
+ if (closestRenderer)
+ return closestRenderer->positionForCoordinates(newX - closestRenderer->x(), newY - closestRenderer->y());
+
+ return createVisiblePosition(firstDeepEditingPositionForNode(node()));
+}
+
+bool RenderBox::shrinkToAvoidFloats() const
+{
+ // FIXME: Technically we should be able to shrink replaced elements on a line, but this is difficult to accomplish, since this
+ // involves doing a relayout during findNextLineBreak and somehow overriding the containingBlockWidth method to return the
+ // current remaining width on a line.
+ if ((isInline() && !isHTMLMarquee()) || !avoidsFloats())
+ return false;
+
+ // All auto-width objects that avoid floats should always use lineWidth.
+ return style()->width().isAuto();
+}
+
+bool RenderBox::avoidsFloats() const
+{
+ return isReplaced() || hasOverflowClip() || isHR();
+}
+
#if ENABLE(SVG)
TransformationMatrix RenderBox::localTransform() const