summaryrefslogtreecommitdiff
path: root/Source/WebCore/rendering/RenderBox.cpp
diff options
context:
space:
mode:
authorSimon Hausmann <simon.hausmann@nokia.com>2012-05-07 11:21:11 +0200
committerSimon Hausmann <simon.hausmann@nokia.com>2012-05-07 11:21:11 +0200
commit2cf6c8816a73e0132bd8fa3b509d62d7c51b6e47 (patch)
tree988e8c5b116dd0466244ae2fe5af8ee9be926d76 /Source/WebCore/rendering/RenderBox.cpp
parentdd91e772430dc294e3bf478c119ef8d43c0a3358 (diff)
downloadqtwebkit-2cf6c8816a73e0132bd8fa3b509d62d7c51b6e47.tar.gz
Imported WebKit commit 7e538425aa020340619e927792f3d895061fb54b (http://svn.webkit.org/repository/webkit/trunk@116286)
Diffstat (limited to 'Source/WebCore/rendering/RenderBox.cpp')
-rw-r--r--Source/WebCore/rendering/RenderBox.cpp534
1 files changed, 293 insertions, 241 deletions
diff --git a/Source/WebCore/rendering/RenderBox.cpp b/Source/WebCore/rendering/RenderBox.cpp
index bafdc376a..b906ec94d 100644
--- a/Source/WebCore/rendering/RenderBox.cpp
+++ b/Source/WebCore/rendering/RenderBox.cpp
@@ -253,19 +253,25 @@ void RenderBox::willBeDestroyed()
if (styleToUse && (styleToUse->logicalHeight().isPercent() || styleToUse->logicalMinHeight().isPercent() || styleToUse->logicalMaxHeight().isPercent()))
RenderBlock::removePercentHeightDescendant(this);
- // If this renderer is owning renderer for the frameview's custom scrollbars,
- // we need to clear it from the scrollbar. See webkit bug 64737.
- if (styleToUse && styleToUse->hasPseudoStyle(SCROLLBAR) && frame() && frame()->view())
- frame()->view()->clearOwningRendererForCustomScrollbars(this);
+ if (styleToUse) {
+ if (RenderView* view = this->view()) {
+ if (FrameView* frameView = view->frameView()) {
+ // If this renderer is owning renderer for the FrameView's custom scrollbars,
+ // we need to clear it from the scrollbar. See webkit bug 64737.
+ if (styleToUse->hasPseudoStyle(SCROLLBAR))
+ frameView->clearOwningRendererForCustomScrollbars(this);
+
+ if (styleToUse->position() == FixedPosition)
+ frameView->removeFixedObject();
+ }
+ }
+ }
// If the following assertion fails, logicalHeight()/logicalMinHeight()/
// logicalMaxHeight() values are changed from a percent value to a non-percent
// value during laying out. It causes a use-after-free bug.
ASSERT(!RenderBlock::hasPercentHeightDescendant(this));
- if (hasOverflowClip() && everHadLayout() && !hasLayer())
- clearCachedSizeForOverflowClip();
-
RenderBoxModelObject::willBeDestroyed();
}
@@ -363,7 +369,7 @@ void RenderBox::styleDidChange(StyleDifference diff, const RenderStyle* oldStyle
// 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 (hasOverflowClipWithLayer() && oldStyle && newStyle && oldStyle->effectiveZoom() != newStyle->effectiveZoom()) {
+ if (hasOverflowClip() && oldStyle && newStyle && oldStyle->effectiveZoom() != newStyle->effectiveZoom()) {
if (int left = layer()->scrollXOffset()) {
left = (left / oldStyle->effectiveZoom()) * newStyle->effectiveZoom();
layer()->scrollToXOffset(left);
@@ -419,7 +425,7 @@ void RenderBox::updateBoxModelInfoFromStyle()
setHasBoxDecorations(true);
setPositioned(styleToUse->isPositioned());
- setFloating(styleToUse->isFloating() && (!isPositioned() || styleToUse->floating() == PositionedFloat));
+ setFloating(!isPositioned() && styleToUse->isFloating());
// We also handle <body> and <html>, whose overflow applies to the viewport.
if (styleToUse->overflowX() != OVISIBLE && !isRootObject && (isRenderBlock() || isTableRow() || isTableSection())) {
@@ -466,10 +472,6 @@ void RenderBox::layout()
child = child->nextSibling();
}
statePusher.pop();
-
- if (hasOverflowClip() && !hasLayer())
- updateCachedSizeForOverflowClip();
-
setNeedsLayout(false);
}
@@ -487,53 +489,53 @@ LayoutUnit RenderBox::clientHeight() const
int RenderBox::pixelSnappedClientWidth() const
{
- return snapSizeToPixel(clientWidth(), clientLeft());
+ return snapSizeToPixel(clientWidth(), x() + clientLeft());
}
int RenderBox::pixelSnappedClientHeight() const
{
- return snapSizeToPixel(clientHeight(), clientTop());
+ return snapSizeToPixel(clientHeight(), y() + clientTop());
}
int RenderBox::scrollWidth() const
{
- if (hasOverflowClipWithLayer())
+ if (hasOverflowClip())
return layer()->scrollWidth();
// For objects with visible overflow, this matches IE.
// FIXME: Need to work right with writing modes.
if (style()->isLeftToRightDirection())
- return max(clientWidth(), maxXLayoutOverflow() - borderLeft());
- return clientWidth() - min(0, minXLayoutOverflow() - borderLeft());
+ return snapSizeToPixel(max(clientWidth(), maxXLayoutOverflow() - borderLeft()), clientLeft());
+ return clientWidth() - min(ZERO_LAYOUT_UNIT, minXLayoutOverflow() - borderLeft());
}
int RenderBox::scrollHeight() const
{
- if (hasOverflowClipWithLayer())
+ if (hasOverflowClip())
return layer()->scrollHeight();
// For objects with visible overflow, this matches IE.
// FIXME: Need to work right with writing modes.
- return max(pixelSnappedClientHeight(), maxYLayoutOverflow() - borderTop());
+ return snapSizeToPixel(max(clientHeight(), maxYLayoutOverflow() - borderTop()), clientTop());
}
int RenderBox::scrollLeft() const
{
- return hasOverflowClipWithLayer() ? layer()->scrollXOffset() : 0;
+ return hasOverflowClip() ? layer()->scrollXOffset() : 0;
}
int RenderBox::scrollTop() const
{
- return hasOverflowClipWithLayer() ? layer()->scrollYOffset() : 0;
+ return hasOverflowClip() ? layer()->scrollYOffset() : 0;
}
void RenderBox::setScrollLeft(int newLeft)
{
- if (hasOverflowClipWithLayer())
+ if (hasOverflowClip())
layer()->scrollToXOffset(newLeft, RenderLayer::ScrollOffsetClamped);
}
void RenderBox::setScrollTop(int newTop)
{
- if (hasOverflowClipWithLayer())
+ if (hasOverflowClip())
layer()->scrollToYOffset(newTop, RenderLayer::ScrollOffsetClamped);
}
@@ -554,9 +556,9 @@ void RenderBox::updateLayerTransform()
layer()->updateTransform();
}
-LayoutRect RenderBox::absoluteContentBox() const
+IntRect RenderBox::absoluteContentBox() const
{
- LayoutRect rect = contentBoxRect();
+ IntRect rect = pixelSnappedIntRect(contentBoxRect());
FloatPoint absPos = localToAbsolute(FloatPoint());
rect.move(absPos.x(), absPos.y());
return rect;
@@ -622,9 +624,10 @@ int RenderBox::reflectionOffset() const
{
if (!style()->boxReflect())
return 0;
+ RenderView* renderView = view();
if (style()->boxReflect()->direction() == ReflectionLeft || style()->boxReflect()->direction() == ReflectionRight)
- return style()->boxReflect()->offset().calcValue(borderBoxRect().width());
- return style()->boxReflect()->offset().calcValue(borderBoxRect().height());
+ return valueForLength(style()->boxReflect()->offset(), borderBoxRect().width(), renderView);
+ return valueForLength(style()->boxReflect()->offset(), borderBoxRect().height(), renderView);
}
LayoutRect RenderBox::reflectedRect(const LayoutRect& r) const
@@ -658,13 +661,13 @@ bool RenderBox::fixedElementLaysOutRelativeToFrame(Frame* frame, FrameView* fram
bool RenderBox::includeVerticalScrollbarSize() const
{
- return hasOverflowClipWithLayer() && !layer()->hasOverlayScrollbars()
+ return hasOverflowClip() && !layer()->hasOverlayScrollbars()
&& (style()->overflowY() == OSCROLL || style()->overflowY() == OAUTO);
}
bool RenderBox::includeHorizontalScrollbarSize() const
{
- return hasOverflowClipWithLayer() && !layer()->hasOverlayScrollbars()
+ return hasOverflowClip() && !layer()->hasOverlayScrollbars()
&& (style()->overflowX() == OSCROLL || style()->overflowX() == OAUTO);
}
@@ -756,56 +759,15 @@ bool RenderBox::needsPreferredWidthsRecalculation() const
IntSize RenderBox::scrolledContentOffset() const
{
ASSERT(hasOverflowClip());
-
- if (hasLayer())
- return layer()->scrolledContentOffset();
-
- // If we have no layer, it means that we have no overflowing content as we lazily
- // allocate it on demand. Thus we don't have any scroll offset.
- ASSERT(!requiresLayerForOverflowClip());
- return LayoutSize();
-}
-
-typedef HashMap<const RenderBox*, LayoutSize> RendererSizeCache;
-static RendererSizeCache& cachedSizeForOverflowClipMap()
-{
- DEFINE_STATIC_LOCAL(RendererSizeCache, cachedSizeForOverflowClipMap, ());
- return cachedSizeForOverflowClipMap;
+ ASSERT(hasLayer());
+ return layer()->scrolledContentOffset();
}
-IntSize RenderBox::cachedSizeForOverflowClip() const
+LayoutSize RenderBox::cachedSizeForOverflowClip() const
{
ASSERT(hasOverflowClip());
- if (hasLayer())
- return layer()->size();
-
- ASSERT(!requiresLayerForOverflowClip());
- RendererSizeCache::iterator it = cachedSizeForOverflowClipMap().find(this);
- if (it == cachedSizeForOverflowClipMap().end())
- return LayoutSize();
-
- return it->second;
-}
-
-void RenderBox::updateCachedSizeForOverflowClip()
-{
- ASSERT(hasOverflowClip());
- ASSERT(!requiresLayerForOverflowClip());
- ASSERT(!hasLayer());
-
- cachedSizeForOverflowClipMap().set(this, size());
-}
-
-void RenderBox::clearCachedSizeForOverflowClip()
-{
- ASSERT(hasOverflowClip());
- ASSERT(!requiresLayerForOverflowClip());
- ASSERT(!hasLayer());
-
- // FIXME: We really would like to enable this ASSERT. However the current updateScrollInfoAfterLayout
- // is not bullet-proof and it triggers in non-obvious ways under NRWT.
- // ASSERT(cachedSizeForOverflowClipMap().contains(this));
- cachedSizeForOverflowClipMap().remove(this);
+ ASSERT(hasLayer());
+ return layer()->size();
}
LayoutUnit RenderBox::minPreferredLogicalWidth() const
@@ -991,7 +953,7 @@ void RenderBox::paintBoxDecorations(PaintInfo& paintInfo, const LayoutPoint& pai
// To avoid the background color bleeding out behind the border, we'll render background and border
// into a transparency layer, and then clip that in one go (which requires setting up the clip before
// beginning the layer).
- RoundedRect border = style()->getRoundedBorderFor(paintRect);
+ RoundedRect border = style()->getRoundedBorderFor(paintRect, view());
stateSaver.save();
paintInfo.context->addRoundedRectClip(border);
paintInfo.context->beginTransparencyLayer(1);
@@ -999,17 +961,18 @@ void RenderBox::paintBoxDecorations(PaintInfo& paintInfo, const LayoutPoint& pai
// If we have a native theme appearance, paint that before painting our background.
// The theme will tell us whether or not we should also paint the CSS background.
- bool themePainted = style()->hasAppearance() && !theme()->paint(this, paintInfo, paintRect);
+ IntRect snappedPaintRect(pixelSnappedIntRect(paintRect));
+ bool themePainted = style()->hasAppearance() && !theme()->paint(this, paintInfo, snappedPaintRect);
if (!themePainted) {
paintBackground(paintInfo, paintRect, bleedAvoidance);
if (style()->hasAppearance())
- theme()->paintDecorations(this, paintInfo, pixelSnappedIntRect(paintRect));
+ theme()->paintDecorations(this, paintInfo, snappedPaintRect);
}
paintBoxShadow(paintInfo, paintRect, style(), Inset);
// The theme will tell us whether or not we should also paint the CSS border.
- if ((!style()->hasAppearance() || (!themePainted && theme()->paintBorderOnly(this, paintInfo, pixelSnappedIntRect(paintRect)))) && style()->hasBorder())
+ if ((!style()->hasAppearance() || (!themePainted && theme()->paintBorderOnly(this, paintInfo, snappedPaintRect))) && style()->hasBorder())
paintBorder(paintInfo, paintRect, style(), bleedAvoidance);
if (bleedAvoidance == BackgroundBleedUseTransparencyLayer)
@@ -1049,11 +1012,12 @@ void RenderBox::paintMaskImages(const PaintInfo& paintInfo, const LayoutRect& pa
// Figure out if we need to push a transparency layer to render our mask.
bool pushTransparencyLayer = false;
bool compositedMask = hasLayer() && layer()->hasCompositedMask();
+ bool flattenCompositingLayers = view()->frameView() && view()->frameView()->paintBehavior() & PaintBehaviorFlattenCompositingLayers;
CompositeOperator compositeOp = CompositeSourceOver;
bool allMaskImagesLoaded = true;
- if (!compositedMask) {
+ if (!compositedMask || flattenCompositingLayers) {
pushTransparencyLayer = true;
StyleImage* maskBoxImage = style()->maskBoxImage().image();
const FillLayer* maskLayers = style()->maskLayers();
@@ -1158,7 +1122,7 @@ void RenderBox::imageChanged(WrappedImagePtr image, const IntRect*)
#if USE(ACCELERATED_COMPOSITING)
if (hasLayer() && layer()->hasCompositedMask() && layersUseImage(image, style()->maskLayers()))
- layer()->contentChanged(RenderLayer::MaskImageChanged);
+ layer()->contentChanged(MaskImageChanged);
#endif
}
@@ -1237,7 +1201,7 @@ bool RenderBox::pushContentsClip(PaintInfo& paintInfo, const LayoutPoint& accumu
return false;
bool isControlClip = hasControlClip();
- bool isOverflowClip = hasOverflowClip() && !hasSelfPaintingLayer();
+ bool isOverflowClip = hasOverflowClip() && !layer()->isSelfPaintingLayer();
if (!isControlClip && !isOverflowClip)
return false;
@@ -1259,7 +1223,7 @@ bool RenderBox::pushContentsClip(PaintInfo& paintInfo, const LayoutPoint& accumu
void RenderBox::popContentsClip(PaintInfo& paintInfo, PaintPhase originalPhase, const LayoutPoint& accumulatedOffset)
{
- ASSERT(hasControlClip() || (hasOverflowClip() && !hasSelfPaintingLayer()));
+ ASSERT(hasControlClip() || (hasOverflowClip() && !layer()->isSelfPaintingLayer()));
paintInfo.context->restore();
if (originalPhase == PaintPhaseOutline) {
@@ -1292,9 +1256,10 @@ LayoutRect RenderBox::clipRect(const LayoutPoint& location, RenderRegion* region
{
LayoutRect borderBoxRect = borderBoxRectInRegion(region);
LayoutRect clipRect = LayoutRect(borderBoxRect.location() + location, borderBoxRect.size());
+ RenderView* renderView = view();
if (!style()->clipLeft().isAuto()) {
- LayoutUnit c = style()->clipLeft().calcValue(borderBoxRect.width());
+ LayoutUnit c = valueForLength(style()->clipLeft(), borderBoxRect.width(), renderView);
clipRect.move(c, 0);
clipRect.contract(c, 0);
}
@@ -1303,16 +1268,16 @@ LayoutRect RenderBox::clipRect(const LayoutPoint& location, RenderRegion* region
// from the left and top edges. Therefore it's better to avoid constraining to smaller widths and heights.
if (!style()->clipRight().isAuto())
- clipRect.contract(width() - style()->clipRight().calcValue(width()), 0);
+ clipRect.contract(width() - valueForLength(style()->clipRight(), width(), renderView), 0);
if (!style()->clipTop().isAuto()) {
- LayoutUnit c = style()->clipTop().calcValue(borderBoxRect.height());
+ LayoutUnit c = valueForLength(style()->clipTop(), borderBoxRect.height(), renderView);
clipRect.move(0, c);
clipRect.contract(0, c);
}
if (!style()->clipBottom().isAuto())
- clipRect.contract(0, height() - style()->clipBottom().calcValue(height()));
+ clipRect.contract(0, height() - valueForLength(style()->clipBottom(), height(), renderView));
return clipRect;
}
@@ -1323,7 +1288,7 @@ LayoutUnit RenderBox::shrinkLogicalWidthToAvoidFloats(LayoutUnit childMarginStar
LayoutUnit logicalTopPosition = logicalTop();
LayoutUnit adjustedPageOffsetForContainingBlock = offsetFromLogicalTopOfFirstPage - logicalTop();
if (region) {
- LayoutUnit offsetFromLogicalTopOfRegion = region ? region->offsetFromLogicalTopOfFirstPage() - offsetFromLogicalTopOfFirstPage : zeroLayoutUnit;
+ LayoutUnit offsetFromLogicalTopOfRegion = region ? region->offsetFromLogicalTopOfFirstPage() - offsetFromLogicalTopOfFirstPage : ZERO_LAYOUT_UNIT;
logicalTopPosition = max(logicalTopPosition, logicalTopPosition + offsetFromLogicalTopOfRegion);
containingBlockRegion = cb->clampToStartAndEndRegions(region);
}
@@ -1378,6 +1343,20 @@ LayoutUnit RenderBox::containingBlockLogicalWidthForContentInRegion(RenderRegion
return max<LayoutUnit>(0, result - (cb->logicalWidth() - boxInfo->logicalWidth()));
}
+LayoutUnit RenderBox::containingBlockAvailableLineWidthInRegion(RenderRegion* region, LayoutUnit offsetFromLogicalTopOfFirstPage) const
+{
+ RenderBlock* cb = containingBlock();
+ RenderRegion* containingBlockRegion = 0;
+ LayoutUnit logicalTopPosition = logicalTop();
+ LayoutUnit adjustedPageOffsetForContainingBlock = offsetFromLogicalTopOfFirstPage - logicalTop();
+ if (region) {
+ LayoutUnit offsetFromLogicalTopOfRegion = region ? region->offsetFromLogicalTopOfFirstPage() - offsetFromLogicalTopOfFirstPage : ZERO_LAYOUT_UNIT;
+ logicalTopPosition = max(logicalTopPosition, logicalTopPosition + offsetFromLogicalTopOfRegion);
+ containingBlockRegion = cb->clampToStartAndEndRegions(region);
+ }
+ return cb->availableLogicalWidthForLine(logicalTopPosition, false, containingBlockRegion, adjustedPageOffsetForContainingBlock);
+}
+
LayoutUnit RenderBox::perpendicularContainingBlockLogicalHeight() const
{
RenderBlock* cb = containingBlock();
@@ -1396,7 +1375,7 @@ LayoutUnit RenderBox::perpendicularContainingBlockLogicalHeight() const
return cb->computeContentBoxLogicalHeight(logicalHeightLength.value());
}
-void RenderBox::mapLocalToContainer(RenderBoxModelObject* repaintContainer, bool fixed, bool useTransforms, TransformState& transformState, bool* wasFixed) const
+void RenderBox::mapLocalToContainer(RenderBoxModelObject* repaintContainer, bool fixed, bool useTransforms, TransformState& transformState, ApplyContainerFlipOrNot, bool* wasFixed) const
{
if (repaintContainer == this)
return;
@@ -1450,11 +1429,11 @@ void RenderBox::mapLocalToContainer(RenderBoxModelObject* repaintContainer, bool
// Transform from render flow coordinates into region coordinates.
RenderRegion* region = toRenderFlowThread(o)->mapFromFlowToRegion(transformState);
if (region)
- region->mapLocalToContainer(region->containerForRepaint(), fixed, useTransforms, transformState, wasFixed);
+ region->mapLocalToContainer(region->containerForRepaint(), fixed, useTransforms, transformState, DoNotApplyContainerFlip, wasFixed);
return;
}
- o->mapLocalToContainer(repaintContainer, fixed, useTransforms, transformState, wasFixed);
+ o->mapLocalToContainer(repaintContainer, fixed, useTransforms, transformState, DoNotApplyContainerFlip, wasFixed);
}
void RenderBox::mapAbsoluteToLocalPoint(bool fixed, bool useTransforms, TransformState& transformState) const
@@ -1533,7 +1512,7 @@ void RenderBox::positionLineBox(InlineBox* box)
RootInlineBox* root = box->root();
root->block()->setStaticInlinePositionForChild(this, root->lineTopWithLeading(), roundedLayoutUnit(box->logicalLeft()));
if (style()->hasStaticInlinePosition(box->isHorizontal()))
- setChildNeedsLayout(true, false); // Just go ahead and mark the positioned object as needing layout, so it will update its position properly.
+ setChildNeedsLayout(true, MarkOnlyThis); // Just go ahead and mark the positioned object as needing layout, so it will update its position properly.
} else {
// 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
@@ -1541,7 +1520,7 @@ void RenderBox::positionLineBox(InlineBox* box)
// in flow). This value was cached in the y() of the box.
layer()->setStaticBlockPosition(box->logicalTop());
if (style()->hasStaticBlockPosition(box->isHorizontal()))
- setChildNeedsLayout(true, false); // Just go ahead and mark the positioned object as needing layout, so it will update its position properly.
+ setChildNeedsLayout(true, MarkOnlyThis); // Just go ahead and mark the positioned object as needing layout, so it will update its position properly.
}
// Nuke the box.
@@ -1641,18 +1620,6 @@ void RenderBox::computeRectForRepaint(RenderBoxModelObject* repaintContainer, La
if (isWritingModeRoot() && !isPositioned())
flipForWritingMode(rect);
-#if ENABLE(CSS_FILTERS)
- if (styleToUse->hasFilterOutsets()) {
- LayoutUnit topOutset;
- LayoutUnit rightOutset;
- LayoutUnit bottomOutset;
- LayoutUnit leftOutset;
- styleToUse->filter().getOutsets(topOutset, rightOutset, bottomOutset, leftOutset);
- rect.move(-leftOutset, -topOutset);
- rect.expand(leftOutset + rightOutset, topOutset + bottomOutset);
- }
-#endif
-
LayoutPoint topLeft = rect.location();
topLeft.move(locationOffset());
@@ -1779,10 +1746,11 @@ void RenderBox::computeLogicalWidthInRegion(RenderRegion* region, LayoutUnit off
if (isInline() && !isInlineBlockOrInlineTable()) {
// just calculate margins
- setMarginStart(styleToUse->marginStart().calcMinValue(containerLogicalWidth));
- setMarginEnd(styleToUse->marginEnd().calcMinValue(containerLogicalWidth));
+ RenderView* renderView = view();
+ setMarginStart(minimumValueForLength(styleToUse->marginStart(), containerLogicalWidth, renderView));
+ setMarginEnd(minimumValueForLength(styleToUse->marginEnd(), containerLogicalWidth, renderView));
if (treatAsReplaced)
- setLogicalWidth(max<LayoutUnit>(logicalWidthLength.calcFloatValue(0) + borderAndPaddingLogicalWidth(), minPreferredLogicalWidth()));
+ setLogicalWidth(max<LayoutUnit>(floatValueForLength(logicalWidthLength, 0) + borderAndPaddingLogicalWidth(), minPreferredLogicalWidth()));
return;
}
@@ -1817,12 +1785,17 @@ void RenderBox::computeLogicalWidthInRegion(RenderRegion* region, LayoutUnit off
}
// Margin calculations.
- if (logicalWidthLength.isAuto() || hasPerpendicularContainingBlock) {
- setMarginStart(styleToUse->marginStart().calcMinValue(containerLogicalWidth));
- setMarginEnd(styleToUse->marginEnd().calcMinValue(containerLogicalWidth));
- } else
- computeInlineDirectionMargins(cb, containerLogicalWidth, logicalWidth());
-
+ if (hasPerpendicularContainingBlock || isFloating() || isInline()) {
+ RenderView* renderView = view();
+ setMarginStart(minimumValueForLength(styleToUse->marginStart(), containerLogicalWidth, renderView));
+ setMarginEnd(minimumValueForLength(styleToUse->marginEnd(), containerLogicalWidth, renderView));
+ } else {
+ LayoutUnit containerLogicalWidthForAutoMargins = containerLogicalWidth;
+ if (avoidsFloats() && cb->containsFloats())
+ containerLogicalWidthForAutoMargins = containingBlockAvailableLineWidthInRegion(region, offsetFromLogicalTopOfFirstPage);
+ computeInlineDirectionMargins(cb, containerLogicalWidthForAutoMargins, logicalWidth());
+ }
+
if (!hasPerpendicularContainingBlock && containerLogicalWidth && containerLogicalWidth != (logicalWidth() + marginStart() + marginEnd())
&& !isFloating() && !isInline() && !cb->isFlexibleBoxIncludingDeprecated())
cb->setMarginEndForChild(this, containerLogicalWidth - logicalWidth() - cb->marginStartForChild(this));
@@ -1841,9 +1814,12 @@ LayoutUnit RenderBox::computeLogicalWidthInRegionUsing(LogicalWidthType widthTyp
else
logicalWidth = styleToUse->logicalMaxWidth();
+ ASSERT(!logicalWidth.isUndefined());
+
if (logicalWidth.isIntrinsicOrAuto()) {
- LayoutUnit marginStart = styleToUse->marginStart().calcMinValue(availableLogicalWidth);
- LayoutUnit marginEnd = styleToUse->marginEnd().calcMinValue(availableLogicalWidth);
+ RenderView* renderView = view();
+ LayoutUnit marginStart = minimumValueForLength(styleToUse->marginStart(), availableLogicalWidth, renderView);
+ LayoutUnit marginEnd = minimumValueForLength(styleToUse->marginEnd(), availableLogicalWidth, renderView);
logicalWidthResult = availableLogicalWidth - marginStart - marginEnd;
if (shrinkToAvoidFloats() && cb->containsFloats())
@@ -1854,7 +1830,7 @@ LayoutUnit RenderBox::computeLogicalWidthInRegionUsing(LogicalWidthType widthTyp
logicalWidthResult = min(logicalWidthResult, maxPreferredLogicalWidth());
}
} else // FIXME: If the containing block flow is perpendicular to our direction we need to use the available logical height instead.
- logicalWidthResult = computeBorderBoxLogicalWidth(logicalWidth.calcValue(availableLogicalWidth));
+ logicalWidthResult = computeBorderBoxLogicalWidth(valueForLength(logicalWidth, availableLogicalWidth, view()));
return logicalWidthResult;
}
@@ -1922,11 +1898,12 @@ void RenderBox::computeInlineDirectionMargins(RenderBlock* containingBlock, Layo
const RenderStyle* containingBlockStyle = containingBlock->style();
Length marginStartLength = style()->marginStartUsing(containingBlockStyle);
Length marginEndLength = style()->marginEndUsing(containingBlockStyle);
+ RenderView* renderView = view();
if (isFloating() || isInline()) {
// Inline blocks/tables and floats don't have their margins increased.
- containingBlock->setMarginStartForChild(this, marginStartLength.calcMinValue(containerWidth));
- containingBlock->setMarginEndForChild(this, marginEndLength.calcMinValue(containerWidth));
+ containingBlock->setMarginStartForChild(this, minimumValueForLength(marginStartLength, containerWidth, renderView));
+ containingBlock->setMarginEndForChild(this, minimumValueForLength(marginEndLength, containerWidth, renderView));
return;
}
@@ -1940,7 +1917,7 @@ void RenderBox::computeInlineDirectionMargins(RenderBlock* containingBlock, Layo
// Case Two: The object is being pushed to the start of the containing block's available logical width.
if (marginEndLength.isAuto() && childWidth < containerWidth) {
- containingBlock->setMarginStartForChild(this, marginStartLength.calcValue(containerWidth));
+ containingBlock->setMarginStartForChild(this, valueForLength(marginStartLength, containerWidth, renderView));
containingBlock->setMarginEndForChild(this, containerWidth - childWidth - containingBlock->marginStartForChild(this));
return;
}
@@ -1949,15 +1926,15 @@ void RenderBox::computeInlineDirectionMargins(RenderBlock* containingBlock, Layo
bool pushToEndFromTextAlign = !marginEndLength.isAuto() && ((!containingBlockStyle->isLeftToRightDirection() && containingBlockStyle->textAlign() == WEBKIT_LEFT)
|| (containingBlockStyle->isLeftToRightDirection() && containingBlockStyle->textAlign() == WEBKIT_RIGHT));
if ((marginStartLength.isAuto() && childWidth < containerWidth) || pushToEndFromTextAlign) {
- containingBlock->setMarginEndForChild(this, marginEndLength.calcValue(containerWidth));
+ containingBlock->setMarginEndForChild(this, valueForLength(marginEndLength, containerWidth, renderView));
containingBlock->setMarginStartForChild(this, containerWidth - childWidth - containingBlock->marginEndForChild(this));
return;
}
// Case Four: Either no auto margins, or our width is >= the container width (css2.1, 10.3.3). In that case
// auto margins will just turn into 0.
- containingBlock->setMarginStartForChild(this, marginStartLength.calcMinValue(containerWidth));
- containingBlock->setMarginEndForChild(this, marginEndLength.calcMinValue(containerWidth));
+ containingBlock->setMarginStartForChild(this, minimumValueForLength(marginStartLength, containerWidth, renderView));
+ containingBlock->setMarginEndForChild(this, minimumValueForLength(marginEndLength, containerWidth, renderView));
}
RenderBoxRegionInfo* RenderBox::renderBoxRegionInfo(RenderRegion* region, LayoutUnit offsetFromLogicalTopOfFirstPage, RenderBoxRegionInfoFlags cacheFlag) const
@@ -2022,8 +1999,7 @@ RenderBoxRegionInfo* RenderBox::renderBoxRegionInfo(RenderRegion* region, Layout
LayoutUnit logicalLeftOffset = 0;
if (!isPositioned() && avoidsFloats() && cb->containsFloats()) {
- LayoutUnit startPositionDelta = cb->computeStartPositionDeltaForChildAvoidingFloats(this, marginStartInRegion, logicalWidthInRegion,
- region, offsetFromLogicalTopOfFirstPage);
+ LayoutUnit startPositionDelta = cb->computeStartPositionDeltaForChildAvoidingFloats(this, marginStartInRegion, region, offsetFromLogicalTopOfFirstPage);
if (cb->style()->isLeftToRightDirection())
logicalLeftDelta += startPositionDelta;
else
@@ -2152,18 +2128,24 @@ void RenderBox::computeLogicalHeight()
}
}
-LayoutUnit RenderBox::computeLogicalHeightUsing(const Length& h)
+LayoutUnit RenderBox::computeLogicalHeightUsing(const Length& height)
+{
+ LayoutUnit logicalHeight = computeContentLogicalHeightUsing(height);
+ if (logicalHeight != -1)
+ logicalHeight = computeBorderBoxLogicalHeight(logicalHeight);
+ return logicalHeight;
+}
+
+LayoutUnit RenderBox::computeContentLogicalHeightUsing(const Length& height)
{
LayoutUnit logicalHeight = -1;
- if (!h.isAuto()) {
- if (h.isFixed())
- logicalHeight = h.value();
- else if (h.isPercent())
- logicalHeight = computePercentageLogicalHeight(h);
- if (logicalHeight != -1) {
- logicalHeight = computeBorderBoxLogicalHeight(logicalHeight);
- return logicalHeight;
- }
+ if (!height.isAuto()) {
+ if (height.isFixed())
+ logicalHeight = height.value();
+ else if (height.isPercent())
+ logicalHeight = computePercentageLogicalHeight(height);
+ else if (height.isViewportPercentage())
+ logicalHeight = valueForLength(height, 0, view());
}
return logicalHeight;
}
@@ -2241,7 +2223,7 @@ LayoutUnit RenderBox::computePercentageLogicalHeight(const Length& height)
result = cb->computeContentBoxLogicalHeight(cb->availableLogicalHeight());
if (result != -1) {
- result = height.calcValue(result);
+ result = valueForLength(height, result);
if (includeBorderPadding) {
// It is necessary to use the border-box to match WinIE's broken
// box model. This is essential for sizing inside
@@ -2270,13 +2252,18 @@ LayoutUnit RenderBox::computeReplacedLogicalWidthUsing(Length logicalWidth) cons
switch (logicalWidth.type()) {
case Fixed:
return computeContentBoxLogicalWidth(logicalWidth.value());
- case Percent: {
+ case ViewportPercentageWidth:
+ case ViewportPercentageHeight:
+ case ViewportPercentageMin:
+ return computeContentBoxLogicalWidth(valueForLength(logicalWidth, 0, view()));
+ case Percent:
+ case Calculated: {
// FIXME: containingBlockLogicalWidthForContent() is wrong if the replaced element's block-flow is perpendicular to the
// containing block's block-flow.
// https://bugs.webkit.org/show_bug.cgi?id=46496
const LayoutUnit cw = isPositioned() ? containingBlockLogicalWidthForPositioned(toRenderBoxModelObject(container())) : containingBlockLogicalWidthForContent();
if (cw > 0)
- return computeContentBoxLogicalWidth(logicalWidth.calcMinValue(cw));
+ return computeContentBoxLogicalWidth(minimumValueForLength(logicalWidth, cw));
}
// fall through
default:
@@ -2302,6 +2289,7 @@ LayoutUnit RenderBox::computeReplacedLogicalHeightUsing(Length logicalHeight) co
case Fixed:
return computeContentBoxLogicalHeight(logicalHeight.value());
case Percent:
+ case Calculated:
{
RenderObject* cb = isPositioned() ? container() : containingBlock();
while (cb->isAnonymous()) {
@@ -2318,7 +2306,7 @@ LayoutUnit RenderBox::computeReplacedLogicalHeightUsing(Length logicalHeight) co
block->computeLogicalHeight();
LayoutUnit newHeight = block->computeContentBoxLogicalHeight(block->contentHeight());
block->setHeight(oldHeight);
- return computeContentBoxLogicalHeight(logicalHeight.calcValue(newHeight));
+ return computeContentBoxLogicalHeight(valueForLength(logicalHeight, newHeight));
}
// FIXME: availableLogicalHeight() is wrong if the replaced element's block-flow is perpendicular to the
@@ -2339,13 +2327,18 @@ LayoutUnit RenderBox::computeReplacedLogicalHeightUsing(Length logicalHeight) co
// Don't let table cells squeeze percent-height replaced elements
// <http://bugs.webkit.org/show_bug.cgi?id=15359>
availableHeight = max(availableHeight, intrinsicLogicalHeight());
- return logicalHeight.calcValue(availableHeight - borderAndPaddingLogicalHeight());
+ return valueForLength(logicalHeight, availableHeight - borderAndPaddingLogicalHeight());
}
cb = cb->containingBlock();
+ toRenderBlock(cb)->addPercentHeightDescendant(const_cast<RenderBox*>(this));
}
}
- return computeContentBoxLogicalHeight(logicalHeight.calcValue(availableHeight));
+ return computeContentBoxLogicalHeight(valueForLength(logicalHeight, availableHeight));
}
+ case ViewportPercentageWidth:
+ case ViewportPercentageHeight:
+ case ViewportPercentageMin:
+ return computeContentBoxLogicalHeight(valueForLength(logicalHeight, 0, view()));
default:
return intrinsicLogicalHeight();
}
@@ -2379,7 +2372,7 @@ LayoutUnit RenderBox::availableLogicalHeightUsing(const Length& h) const
availableHeight = containingBlockLogicalHeightForPositioned(containingBlock());
else
availableHeight = containingBlock()->availableLogicalHeight();
- return computeContentBoxLogicalHeight(h.calcValue(availableHeight));
+ return computeContentBoxLogicalHeight(valueForLength(h, availableHeight));
}
// FIXME: We can't just check top/bottom here.
@@ -2409,10 +2402,10 @@ void RenderBox::computeBlockDirectionMargins(RenderBlock* containingBlock)
// Margins are calculated with respect to the logical width of
// the containing block (8.3)
LayoutUnit cw = containingBlockLogicalWidthForContent();
-
+ RenderView* renderView = view();
RenderStyle* containingBlockStyle = containingBlock->style();
- containingBlock->setMarginBeforeForChild(this, style()->marginBeforeUsing(containingBlockStyle).calcMinValue(cw));
- containingBlock->setMarginAfterForChild(this, style()->marginAfterUsing(containingBlockStyle).calcMinValue(cw));
+ containingBlock->setMarginBeforeForChild(this, minimumValueForLength(style()->marginBeforeUsing(containingBlockStyle), cw, renderView));
+ containingBlock->setMarginAfterForChild(this, minimumValueForLength(style()->marginAfterUsing(containingBlockStyle), cw, renderView));
}
LayoutUnit RenderBox::containingBlockLogicalWidthForPositioned(const RenderBoxModelObject* containingBlock, RenderRegion* region,
@@ -2735,6 +2728,7 @@ void RenderBox::computePositionedLogicalWidthUsing(Length logicalWidth, const Re
bool logicalWidthIsAuto = logicalWidth.isIntrinsicOrAuto();
bool logicalLeftIsAuto = logicalLeft.isAuto();
bool logicalRightIsAuto = logicalRight.isAuto();
+ RenderView* renderView = view();
if (!logicalLeftIsAuto && !logicalWidthIsAuto && !logicalRightIsAuto) {
/*-----------------------------------------------------------------------*\
@@ -2752,10 +2746,10 @@ void RenderBox::computePositionedLogicalWidthUsing(Length logicalWidth, const Re
// NOTE: It is not necessary to solve for 'right' in the over constrained
// case because the value is not used for any further calculations.
- logicalLeftValue = logicalLeft.calcValue(containerLogicalWidth);
- logicalWidthValue = computeContentBoxLogicalWidth(logicalWidth.calcValue(containerLogicalWidth));
+ logicalLeftValue = valueForLength(logicalLeft, containerLogicalWidth, renderView);
+ logicalWidthValue = computeContentBoxLogicalWidth(valueForLength(logicalWidth, containerLogicalWidth, renderView));
- const LayoutUnit availableSpace = containerLogicalWidth - (logicalLeftValue + logicalWidthValue + logicalRight.calcValue(containerLogicalWidth) + bordersPlusPadding);
+ const LayoutUnit availableSpace = containerLogicalWidth - (logicalLeftValue + logicalWidthValue + valueForLength(logicalRight, containerLogicalWidth, renderView) + bordersPlusPadding);
// Margins are now the only unknown
if (marginLogicalLeft.isAuto() && marginLogicalRight.isAuto()) {
@@ -2776,16 +2770,16 @@ void RenderBox::computePositionedLogicalWidthUsing(Length logicalWidth, const Re
}
} else if (marginLogicalLeft.isAuto()) {
// Solve for left margin
- marginLogicalRightValue = marginLogicalRight.calcValue(containerLogicalWidth);
+ marginLogicalRightValue = valueForLength(marginLogicalRight, containerLogicalWidth, renderView);
marginLogicalLeftValue = availableSpace - marginLogicalRightValue;
} else if (marginLogicalRight.isAuto()) {
// Solve for right margin
- marginLogicalLeftValue = marginLogicalLeft.calcValue(containerLogicalWidth);
+ marginLogicalLeftValue = valueForLength(marginLogicalLeft, containerLogicalWidth, renderView);
marginLogicalRightValue = availableSpace - marginLogicalLeftValue;
} else {
// Over-constrained, solve for left if direction is RTL
- marginLogicalLeftValue = marginLogicalLeft.calcValue(containerLogicalWidth);
- marginLogicalRightValue = marginLogicalRight.calcValue(containerLogicalWidth);
+ marginLogicalLeftValue = valueForLength(marginLogicalLeft, containerLogicalWidth, renderView);
+ marginLogicalRightValue = valueForLength(marginLogicalRight, containerLogicalWidth, renderView);
// Use the containing block's direction rather than the parent block's
// per CSS 2.1 reference test abspos-non-replaced-width-margin-000.
@@ -2835,8 +2829,8 @@ void RenderBox::computePositionedLogicalWidthUsing(Length logicalWidth, const Re
// because the value is not used for any further calculations.
// Calculate margins, 'auto' margins are ignored.
- marginLogicalLeftValue = marginLogicalLeft.calcMinValue(containerLogicalWidth);
- marginLogicalRightValue = marginLogicalRight.calcMinValue(containerLogicalWidth);
+ marginLogicalLeftValue = minimumValueForLength(marginLogicalLeft, containerLogicalWidth, renderView);
+ marginLogicalRightValue = minimumValueForLength(marginLogicalRight, containerLogicalWidth, renderView);
const LayoutUnit availableSpace = containerLogicalWidth - (marginLogicalLeftValue + marginLogicalRightValue + bordersPlusPadding);
@@ -2844,7 +2838,7 @@ void RenderBox::computePositionedLogicalWidthUsing(Length logicalWidth, const Re
// Use rule/case that applies.
if (logicalLeftIsAuto && logicalWidthIsAuto && !logicalRightIsAuto) {
// RULE 1: (use shrink-to-fit for width, and solve of left)
- LayoutUnit logicalRightValue = logicalRight.calcValue(containerLogicalWidth);
+ LayoutUnit logicalRightValue = valueForLength(logicalRight, containerLogicalWidth, renderView);
// FIXME: would it be better to have shrink-to-fit in one step?
LayoutUnit preferredWidth = maxPreferredLogicalWidth() - bordersPlusPadding;
@@ -2854,7 +2848,7 @@ void RenderBox::computePositionedLogicalWidthUsing(Length logicalWidth, const Re
logicalLeftValue = availableSpace - (logicalWidthValue + logicalRightValue);
} else if (!logicalLeftIsAuto && logicalWidthIsAuto && logicalRightIsAuto) {
// RULE 3: (use shrink-to-fit for width, and no need solve of right)
- logicalLeftValue = logicalLeft.calcValue(containerLogicalWidth);
+ logicalLeftValue = valueForLength(logicalLeft, containerLogicalWidth, renderView);
// FIXME: would it be better to have shrink-to-fit in one step?
LayoutUnit preferredWidth = maxPreferredLogicalWidth() - bordersPlusPadding;
@@ -2863,16 +2857,16 @@ void RenderBox::computePositionedLogicalWidthUsing(Length logicalWidth, const Re
logicalWidthValue = min(max(preferredMinWidth, availableWidth), preferredWidth);
} else if (logicalLeftIsAuto && !logicalWidthIsAuto && !logicalRightIsAuto) {
// RULE 4: (solve for left)
- logicalWidthValue = computeContentBoxLogicalWidth(logicalWidth.calcValue(containerLogicalWidth));
- logicalLeftValue = availableSpace - (logicalWidthValue + logicalRight.calcValue(containerLogicalWidth));
+ logicalWidthValue = computeContentBoxLogicalWidth(valueForLength(logicalWidth, containerLogicalWidth, renderView));
+ logicalLeftValue = availableSpace - (logicalWidthValue + valueForLength(logicalRight, containerLogicalWidth, renderView));
} else if (!logicalLeftIsAuto && logicalWidthIsAuto && !logicalRightIsAuto) {
// RULE 5: (solve for width)
- logicalLeftValue = logicalLeft.calcValue(containerLogicalWidth);
- logicalWidthValue = availableSpace - (logicalLeftValue + logicalRight.calcValue(containerLogicalWidth));
+ logicalLeftValue = valueForLength(logicalLeft, containerLogicalWidth, renderView);
+ logicalWidthValue = availableSpace - (logicalLeftValue + valueForLength(logicalRight, containerLogicalWidth, renderView));
} else if (!logicalLeftIsAuto && !logicalWidthIsAuto && logicalRightIsAuto) {
// RULE 6: (no need solve for right)
- logicalLeftValue = logicalLeft.calcValue(containerLogicalWidth);
- logicalWidthValue = computeContentBoxLogicalWidth(logicalWidth.calcValue(containerLogicalWidth));
+ logicalLeftValue = valueForLength(logicalLeft, containerLogicalWidth, renderView);
+ logicalWidthValue = computeContentBoxLogicalWidth(valueForLength(logicalWidth, containerLogicalWidth, renderView));
}
}
@@ -3068,6 +3062,7 @@ void RenderBox::computePositionedLogicalHeightUsing(Length logicalHeightLength,
bool logicalHeightIsAuto = logicalHeightLength.isAuto();
bool logicalTopIsAuto = logicalTop.isAuto();
bool logicalBottomIsAuto = logicalBottom.isAuto();
+ RenderView* renderView = view();
// Height is never unsolved for tables.
if (isTable()) {
@@ -3087,10 +3082,10 @@ void RenderBox::computePositionedLogicalHeightUsing(Length logicalHeightLength,
// NOTE: It is not necessary to solve for 'bottom' in the over constrained
// case because the value is not used for any further calculations.
- logicalHeightValue = computeContentBoxLogicalHeight(logicalHeightLength.calcValue(containerLogicalHeight));
- logicalTopValue = logicalTop.calcValue(containerLogicalHeight);
+ logicalHeightValue = computeContentBoxLogicalHeight(valueForLength(logicalHeightLength, containerLogicalHeight, renderView));
+ logicalTopValue = valueForLength(logicalTop, containerLogicalHeight, renderView);
- const LayoutUnit availableSpace = containerLogicalHeight - (logicalTopValue + logicalHeightValue + logicalBottom.calcValue(containerLogicalHeight) + bordersPlusPadding);
+ const LayoutUnit availableSpace = containerLogicalHeight - (logicalTopValue + logicalHeightValue + valueForLength(logicalBottom, containerLogicalHeight, renderView) + bordersPlusPadding);
// Margins are now the only unknown
if (marginBefore.isAuto() && marginAfter.isAuto()) {
@@ -3100,16 +3095,16 @@ void RenderBox::computePositionedLogicalHeightUsing(Length logicalHeightLength,
marginAfterValue = availableSpace - marginBeforeValue; // account for odd valued differences
} else if (marginBefore.isAuto()) {
// Solve for top margin
- marginAfterValue = marginAfter.calcValue(containerLogicalHeight);
+ marginAfterValue = valueForLength(marginAfter, containerLogicalHeight, renderView);
marginBeforeValue = availableSpace - marginAfterValue;
} else if (marginAfter.isAuto()) {
// Solve for bottom margin
- marginBeforeValue = marginBefore.calcValue(containerLogicalHeight);
+ marginBeforeValue = valueForLength(marginBefore, containerLogicalHeight, renderView);
marginAfterValue = availableSpace - marginBeforeValue;
} else {
// Over-constrained, (no need solve for bottom)
- marginBeforeValue = marginBefore.calcValue(containerLogicalHeight);
- marginAfterValue = marginAfter.calcValue(containerLogicalHeight);
+ marginBeforeValue = valueForLength(marginBefore, containerLogicalHeight, renderView);
+ marginAfterValue = valueForLength(marginAfter, containerLogicalHeight, renderView);
}
} else {
/*--------------------------------------------------------------------*\
@@ -3138,8 +3133,8 @@ void RenderBox::computePositionedLogicalHeightUsing(Length logicalHeightLength,
// because the value is not used for any further calculations.
// Calculate margins, 'auto' margins are ignored.
- marginBeforeValue = marginBefore.calcMinValue(containerLogicalHeight);
- marginAfterValue = marginAfter.calcMinValue(containerLogicalHeight);
+ marginBeforeValue = minimumValueForLength(marginBefore, containerLogicalHeight, renderView);
+ marginAfterValue = minimumValueForLength(marginAfter, containerLogicalHeight, renderView);
const LayoutUnit availableSpace = containerLogicalHeight - (marginBeforeValue + marginAfterValue + bordersPlusPadding);
@@ -3147,23 +3142,23 @@ void RenderBox::computePositionedLogicalHeightUsing(Length logicalHeightLength,
if (logicalTopIsAuto && logicalHeightIsAuto && !logicalBottomIsAuto) {
// RULE 1: (height is content based, solve of top)
logicalHeightValue = contentLogicalHeight;
- logicalTopValue = availableSpace - (logicalHeightValue + logicalBottom.calcValue(containerLogicalHeight));
+ logicalTopValue = availableSpace - (logicalHeightValue + valueForLength(logicalBottom, containerLogicalHeight, renderView));
} else if (!logicalTopIsAuto && logicalHeightIsAuto && logicalBottomIsAuto) {
// RULE 3: (height is content based, no need solve of bottom)
- logicalTopValue = logicalTop.calcValue(containerLogicalHeight);
+ logicalTopValue = valueForLength(logicalTop, containerLogicalHeight, renderView);
logicalHeightValue = contentLogicalHeight;
} else if (logicalTopIsAuto && !logicalHeightIsAuto && !logicalBottomIsAuto) {
// RULE 4: (solve of top)
- logicalHeightValue = computeContentBoxLogicalHeight(logicalHeightLength.calcValue(containerLogicalHeight));
- logicalTopValue = availableSpace - (logicalHeightValue + logicalBottom.calcValue(containerLogicalHeight));
+ logicalHeightValue = computeContentBoxLogicalHeight(valueForLength(logicalHeightLength, containerLogicalHeight, renderView));
+ logicalTopValue = availableSpace - (logicalHeightValue + valueForLength(logicalBottom, containerLogicalHeight, renderView));
} else if (!logicalTopIsAuto && logicalHeightIsAuto && !logicalBottomIsAuto) {
// RULE 5: (solve of height)
- logicalTopValue = logicalTop.calcValue(containerLogicalHeight);
- logicalHeightValue = max<LayoutUnit>(0, availableSpace - (logicalTopValue + logicalBottom.calcValue(containerLogicalHeight)));
+ logicalTopValue = valueForLength(logicalTop, containerLogicalHeight, renderView);
+ logicalHeightValue = max<LayoutUnit>(0, availableSpace - (logicalTopValue + valueForLength(logicalBottom, containerLogicalHeight, renderView)));
} else if (!logicalTopIsAuto && !logicalHeightIsAuto && logicalBottomIsAuto) {
// RULE 6: (no need solve of bottom)
- logicalHeightValue = computeContentBoxLogicalHeight(logicalHeightLength.calcValue(containerLogicalHeight));
- logicalTopValue = logicalTop.calcValue(containerLogicalHeight);
+ logicalHeightValue = computeContentBoxLogicalHeight(valueForLength(logicalHeightLength, containerLogicalHeight, renderView));
+ logicalTopValue = valueForLength(logicalTop, containerLogicalHeight, renderView);
}
}
@@ -3239,13 +3234,14 @@ void RenderBox::computePositionedLogicalWidthReplaced()
\*-----------------------------------------------------------------------*/
LayoutUnit logicalLeftValue = 0;
LayoutUnit logicalRightValue = 0;
+ RenderView* renderView = view();
if (marginLogicalLeft.isAuto() && marginLogicalRight.isAuto()) {
// 'left' and 'right' cannot be 'auto' due to step 3
ASSERT(!(logicalLeft.isAuto() && logicalRight.isAuto()));
- logicalLeftValue = logicalLeft.calcValue(containerLogicalWidth);
- logicalRightValue = logicalRight.calcValue(containerLogicalWidth);
+ logicalLeftValue = valueForLength(logicalLeft, containerLogicalWidth, renderView);
+ logicalRightValue = valueForLength(logicalRight, containerLogicalWidth, renderView);
LayoutUnit difference = availableSpace - (logicalLeftValue + logicalRightValue);
if (difference > 0) {
@@ -3268,39 +3264,39 @@ void RenderBox::computePositionedLogicalWidthReplaced()
* that value.
\*-----------------------------------------------------------------------*/
} else if (logicalLeft.isAuto()) {
- marginLogicalLeftAlias = marginLogicalLeft.calcValue(containerLogicalWidth);
- marginLogicalRightAlias = marginLogicalRight.calcValue(containerLogicalWidth);
- logicalRightValue = logicalRight.calcValue(containerLogicalWidth);
+ marginLogicalLeftAlias = valueForLength(marginLogicalLeft, containerLogicalWidth, renderView);
+ marginLogicalRightAlias = valueForLength(marginLogicalRight, containerLogicalWidth, renderView);
+ logicalRightValue = valueForLength(logicalRight, containerLogicalWidth, renderView);
// Solve for 'left'
logicalLeftValue = availableSpace - (logicalRightValue + marginLogicalLeftAlias + marginLogicalRightAlias);
} else if (logicalRight.isAuto()) {
- marginLogicalLeftAlias = marginLogicalLeft.calcValue(containerLogicalWidth);
- marginLogicalRightAlias = marginLogicalRight.calcValue(containerLogicalWidth);
- logicalLeftValue = logicalLeft.calcValue(containerLogicalWidth);
+ marginLogicalLeftAlias = valueForLength(marginLogicalLeft, containerLogicalWidth, renderView);
+ marginLogicalRightAlias = valueForLength(marginLogicalRight, containerLogicalWidth, renderView);
+ logicalLeftValue = valueForLength(logicalLeft, containerLogicalWidth, renderView);
// Solve for 'right'
logicalRightValue = availableSpace - (logicalLeftValue + marginLogicalLeftAlias + marginLogicalRightAlias);
} else if (marginLogicalLeft.isAuto()) {
- marginLogicalRightAlias = marginLogicalRight.calcValue(containerLogicalWidth);
- logicalLeftValue = logicalLeft.calcValue(containerLogicalWidth);
- logicalRightValue = logicalRight.calcValue(containerLogicalWidth);
+ marginLogicalRightAlias = valueForLength(marginLogicalRight, containerLogicalWidth, renderView);
+ logicalLeftValue = valueForLength(logicalLeft, containerLogicalWidth, renderView);
+ logicalRightValue = valueForLength(logicalRight, containerLogicalWidth, renderView);
// Solve for 'margin-left'
marginLogicalLeftAlias = availableSpace - (logicalLeftValue + logicalRightValue + marginLogicalRightAlias);
} else if (marginLogicalRight.isAuto()) {
- marginLogicalLeftAlias = marginLogicalLeft.calcValue(containerLogicalWidth);
- logicalLeftValue = logicalLeft.calcValue(containerLogicalWidth);
- logicalRightValue = logicalRight.calcValue(containerLogicalWidth);
+ marginLogicalLeftAlias = valueForLength(marginLogicalLeft, containerLogicalWidth, renderView);
+ logicalLeftValue = valueForLength(logicalLeft, containerLogicalWidth, renderView);
+ logicalRightValue = valueForLength(logicalRight, containerLogicalWidth, renderView);
// Solve for 'margin-right'
marginLogicalRightAlias = availableSpace - (logicalLeftValue + logicalRightValue + marginLogicalLeftAlias);
} else {
// Nothing is 'auto', just calculate the values.
- marginLogicalLeftAlias = marginLogicalLeft.calcValue(containerLogicalWidth);
- marginLogicalRightAlias = marginLogicalRight.calcValue(containerLogicalWidth);
- logicalRightValue = logicalRight.calcValue(containerLogicalWidth);
- logicalLeftValue = logicalLeft.calcValue(containerLogicalWidth);
+ marginLogicalLeftAlias = valueForLength(marginLogicalLeft, containerLogicalWidth, renderView);
+ marginLogicalRightAlias = valueForLength(marginLogicalRight, containerLogicalWidth, renderView);
+ logicalRightValue = valueForLength(logicalRight, containerLogicalWidth, renderView);
+ logicalLeftValue = valueForLength(logicalLeft, containerLogicalWidth, renderView);
// If the containing block is right-to-left, then push the left position as far to the right as possible
if (containerDirection == RTL) {
int totalLogicalWidth = logicalWidth() + logicalLeftValue + logicalRightValue + marginLogicalLeftAlias + marginLogicalRightAlias;
@@ -3363,6 +3359,7 @@ void RenderBox::computePositionedLogicalHeightReplaced()
Length logicalTop = style()->logicalTop();
Length logicalBottom = style()->logicalBottom();
+ RenderView* renderView = view();
/*-----------------------------------------------------------------------*\
* 1. The used value of 'height' is determined as for inline replaced
@@ -3406,8 +3403,8 @@ void RenderBox::computePositionedLogicalHeightReplaced()
// 'top' and 'bottom' cannot be 'auto' due to step 2 and 3 combined.
ASSERT(!(logicalTop.isAuto() || logicalBottom.isAuto()));
- logicalTopValue = logicalTop.calcValue(containerLogicalHeight);
- logicalBottomValue = logicalBottom.calcValue(containerLogicalHeight);
+ logicalTopValue = valueForLength(logicalTop, containerLogicalHeight, renderView);
+ logicalBottomValue = valueForLength(logicalBottom, containerLogicalHeight, renderView);
LayoutUnit difference = availableSpace - (logicalTopValue + logicalBottomValue);
// NOTE: This may result in negative values.
@@ -3419,39 +3416,39 @@ void RenderBox::computePositionedLogicalHeightReplaced()
* for that value.
\*-----------------------------------------------------------------------*/
} else if (logicalTop.isAuto()) {
- marginBeforeAlias = marginBefore.calcValue(containerLogicalHeight);
- marginAfterAlias = marginAfter.calcValue(containerLogicalHeight);
- logicalBottomValue = logicalBottom.calcValue(containerLogicalHeight);
+ marginBeforeAlias = valueForLength(marginBefore, containerLogicalHeight, renderView);
+ marginAfterAlias = valueForLength(marginAfter, containerLogicalHeight, renderView);
+ logicalBottomValue = valueForLength(logicalBottom, containerLogicalHeight, renderView);
// Solve for 'top'
logicalTopValue = availableSpace - (logicalBottomValue + marginBeforeAlias + marginAfterAlias);
} else if (logicalBottom.isAuto()) {
- marginBeforeAlias = marginBefore.calcValue(containerLogicalHeight);
- marginAfterAlias = marginAfter.calcValue(containerLogicalHeight);
- logicalTopValue = logicalTop.calcValue(containerLogicalHeight);
+ marginBeforeAlias = valueForLength(marginBefore, containerLogicalHeight, renderView);
+ marginAfterAlias = valueForLength(marginAfter, containerLogicalHeight, renderView);
+ logicalTopValue = valueForLength(logicalTop, containerLogicalHeight, renderView);
// Solve for 'bottom'
// NOTE: It is not necessary to solve for 'bottom' because we don't ever
// use the value.
} else if (marginBefore.isAuto()) {
- marginAfterAlias = marginAfter.calcValue(containerLogicalHeight);
- logicalTopValue = logicalTop.calcValue(containerLogicalHeight);
- logicalBottomValue = logicalBottom.calcValue(containerLogicalHeight);
+ marginAfterAlias = valueForLength(marginAfter, containerLogicalHeight, renderView);
+ logicalTopValue = valueForLength(logicalTop, containerLogicalHeight, renderView);
+ logicalBottomValue = valueForLength(logicalBottom, containerLogicalHeight, renderView);
// Solve for 'margin-top'
marginBeforeAlias = availableSpace - (logicalTopValue + logicalBottomValue + marginAfterAlias);
} else if (marginAfter.isAuto()) {
- marginBeforeAlias = marginBefore.calcValue(containerLogicalHeight);
- logicalTopValue = logicalTop.calcValue(containerLogicalHeight);
- logicalBottomValue = logicalBottom.calcValue(containerLogicalHeight);
+ marginBeforeAlias = valueForLength(marginBefore, containerLogicalHeight, renderView);
+ logicalTopValue = valueForLength(logicalTop, containerLogicalHeight, renderView);
+ logicalBottomValue = valueForLength(logicalBottom, containerLogicalHeight, renderView);
// Solve for 'margin-bottom'
marginAfterAlias = availableSpace - (logicalTopValue + logicalBottomValue + marginBeforeAlias);
} else {
// Nothing is 'auto', just calculate the values.
- marginBeforeAlias = marginBefore.calcValue(containerLogicalHeight);
- marginAfterAlias = marginAfter.calcValue(containerLogicalHeight);
- logicalTopValue = logicalTop.calcValue(containerLogicalHeight);
+ marginBeforeAlias = valueForLength(marginBefore, containerLogicalHeight, renderView);
+ marginAfterAlias = valueForLength(marginAfter, containerLogicalHeight, renderView);
+ logicalTopValue = valueForLength(logicalTop, containerLogicalHeight, renderView);
// NOTE: It is not necessary to solve for 'bottom' because we don't ever
// use the value.
}
@@ -3529,7 +3526,7 @@ VisiblePosition RenderBox::positionForPoint(const LayoutPoint& point)
}
// Pass off to the closest child.
- LayoutUnit minDist = numeric_limits<LayoutUnit>::max();
+ LayoutUnit minDist = MAX_LAYOUT_UNIT;
RenderBox* closestRenderer = 0;
LayoutPoint adjustedPoint = point;
if (isTableRow())
@@ -3545,9 +3542,9 @@ VisiblePosition RenderBox::positionForPoint(const LayoutPoint& point)
RenderBox* renderer = toRenderBox(renderObject);
- LayoutUnit top = renderer->borderTop() + renderer->paddingTop() + (isTableRow() ? zeroLayoutUnit : renderer->y());
+ LayoutUnit top = renderer->borderTop() + renderer->paddingTop() + (isTableRow() ? ZERO_LAYOUT_UNIT : renderer->y());
LayoutUnit bottom = top + renderer->contentHeight();
- LayoutUnit left = renderer->borderLeft() + renderer->paddingLeft() + (isTableRow() ? zeroLayoutUnit : renderer->x());
+ LayoutUnit left = renderer->borderLeft() + renderer->paddingLeft() + (isTableRow() ? ZERO_LAYOUT_UNIT : renderer->x());
LayoutUnit right = left + renderer->contentWidth();
if (point.x() <= right && point.x() >= left && point.y() <= top && point.y() >= bottom) {
@@ -3600,9 +3597,9 @@ bool RenderBox::shrinkToAvoidFloats() const
// Floating objects don't shrink. Objects that don't avoid floats don't shrink. Marquees don't shrink.
if ((isInline() && !isHTMLMarquee()) || !avoidsFloats() || isFloating())
return false;
-
- // All auto-width objects that avoid floats should always use lineWidth.
- return style()->width().isAuto();
+
+ // Only auto width objects can possibly shrink to avoid floats.
+ return style()->width().isAuto();
}
bool RenderBox::avoidsFloats() const
@@ -3612,7 +3609,7 @@ bool RenderBox::avoidsFloats() const
void RenderBox::addVisualEffectOverflow()
{
- if (!style()->boxShadow() && !style()->hasBorderImageOutsets() && !style()->hasFilterOutsets())
+ if (!style()->boxShadow() && !style()->hasBorderImageOutsets())
return;
bool isFlipped = style()->isFlippedBlocksWritingMode();
@@ -3655,21 +3652,6 @@ void RenderBox::addVisualEffectOverflow()
overflowMaxY = max(overflowMaxY, borderBox.maxY() + ((!isFlipped || !isHorizontal) ? borderOutsetBottom : borderOutsetTop));
}
-#if ENABLE(CSS_FILTERS)
- // Compute any filter outset overflow.
- if (style()->hasFilterOutsets()) {
- LayoutUnit filterOutsetLeft;
- LayoutUnit filterOutsetRight;
- LayoutUnit filterOutsetTop;
- LayoutUnit filterOutsetBottom;
- style()->getFilterOutsets(filterOutsetTop, filterOutsetRight, filterOutsetBottom, filterOutsetLeft);
-
- overflowMinX = min(overflowMinX, borderBox.x() - filterOutsetLeft);
- overflowMaxX = max(overflowMaxX, borderBox.maxX() + filterOutsetRight);
- overflowMinY = min(overflowMinY, borderBox.y() - filterOutsetTop);
- overflowMaxY = max(overflowMaxY, borderBox.maxY() + filterOutsetBottom);
- }
-#endif
// Add in the final overflow with shadows and outsets combined.
addVisualOverflow(LayoutRect(overflowMinX, overflowMinY, overflowMaxX - overflowMinX, overflowMaxY - overflowMinY));
}
@@ -3733,10 +3715,6 @@ void RenderBox::addLayoutOverflow(const LayoutRect& rect)
if (!m_overflow)
m_overflow = adoptPtr(new RenderOverflow(clientBox, borderBoxRect()));
- // Lazily allocate our layer as we will need it to hold our scroll information.
- if (hasOverflowClip())
- ensureLayer();
-
m_overflow->addLayoutOverflow(overflowRect);
}
@@ -4029,4 +4007,78 @@ bool RenderBox::hasRelativeDimensions() const
|| style()->minHeight().isPercent() || style()->minWidth().isPercent();
}
+bool RenderBox::hasRelativeLogicalHeight() const
+{
+ return style()->logicalHeight().isPercent()
+ || style()->logicalMinHeight().isPercent()
+ || style()->logicalMaxHeight().isPercent();
+}
+
+void RenderBox::moveChildTo(RenderBox* toBox, RenderObject* child, RenderObject* beforeChild, bool fullRemoveInsert)
+{
+ ASSERT(this == child->parent());
+ ASSERT(!beforeChild || toBox == beforeChild->parent());
+ if (fullRemoveInsert && toBox->isRenderBlock()) {
+ // Takes care of adding the new child correctly if toBlock and fromBlock
+ // have different kind of children (block vs inline).
+ toBox->addChild(virtualChildren()->removeChildNode(this, child), beforeChild);
+ } else
+ toBox->virtualChildren()->insertChildNode(toBox, virtualChildren()->removeChildNode(this, child, fullRemoveInsert), beforeChild, fullRemoveInsert);
+}
+
+void RenderBox::moveChildrenTo(RenderBox* toBox, RenderObject* startChild, RenderObject* endChild, RenderObject* beforeChild, bool fullRemoveInsert)
+{
+ ASSERT(!beforeChild || toBox == beforeChild->parent());
+ for (RenderObject* child = startChild; child && child != endChild; ) {
+ // Save our next sibling as moveChildTo will clear it.
+ RenderObject* nextSibling = child->nextSibling();
+ moveChildTo(toBox, child, beforeChild, fullRemoveInsert);
+ child = nextSibling;
+ }
+}
+
+static void markBoxForRelayoutAfterSplit(RenderBox* box)
+{
+ // FIXME: The table code should handle that automatically. If not,
+ // we should fix it and remove the table part checks.
+ if (box->isTable())
+ toRenderTable(box)->setNeedsSectionRecalc();
+ else if (box->isTableSection())
+ toRenderTableSection(box)->setNeedsCellRecalc();
+
+ box->setNeedsLayoutAndPrefWidthsRecalc();
+}
+
+RenderObject* RenderBox::splitAnonymousBoxesAroundChild(RenderObject* beforeChild)
+{
+ bool didSplitParentAnonymousBoxes = false;
+
+ while (beforeChild->parent() != this) {
+ RenderBox* boxToSplit = toRenderBox(beforeChild->parent());
+ if (boxToSplit->firstChild() != beforeChild && boxToSplit->isAnonymous()) {
+ didSplitParentAnonymousBoxes = true;
+
+ // We have to split the parent box into two boxes and move children
+ // from |beforeChild| to end into the new post box.
+ RenderBox* postBox = boxToSplit->createAnonymousBoxWithSameTypeAs(this);
+ postBox->setChildrenInline(boxToSplit->childrenInline());
+ RenderBox* parentBox = toRenderBox(boxToSplit->parent());
+ parentBox->virtualChildren()->insertChildNode(parentBox, postBox, boxToSplit->nextSibling());
+ boxToSplit->moveChildrenTo(postBox, beforeChild, 0, boxToSplit->hasLayer());
+
+ markBoxForRelayoutAfterSplit(boxToSplit);
+ markBoxForRelayoutAfterSplit(postBox);
+
+ beforeChild = postBox;
+ } else
+ beforeChild = boxToSplit;
+ }
+
+ if (didSplitParentAnonymousBoxes)
+ markBoxForRelayoutAfterSplit(this);
+
+ ASSERT(beforeChild->parent() == this);
+ return beforeChild;
+}
+
} // namespace WebCore