summaryrefslogtreecommitdiff
path: root/Source/WebCore/rendering/RenderBox.cpp
diff options
context:
space:
mode:
authorSimon Hausmann <simon.hausmann@nokia.com>2012-09-10 19:10:20 +0200
committerSimon Hausmann <simon.hausmann@nokia.com>2012-09-10 19:10:20 +0200
commit284837daa07b29d6a63a748544a90b1f5842ac5c (patch)
treeecd258180bde91fe741e0cfd2638beb3c6da7e8e /Source/WebCore/rendering/RenderBox.cpp
parent2e2ba8ff45915f40ed3e014101269c175f2a89a0 (diff)
downloadqtwebkit-284837daa07b29d6a63a748544a90b1f5842ac5c.tar.gz
Imported WebKit commit 68645295d2e3e09af2c942f092556f06aa5f8b0d (http://svn.webkit.org/repository/webkit/trunk@128073)
New snapshot
Diffstat (limited to 'Source/WebCore/rendering/RenderBox.cpp')
-rw-r--r--Source/WebCore/rendering/RenderBox.cpp494
1 files changed, 253 insertions, 241 deletions
diff --git a/Source/WebCore/rendering/RenderBox.cpp b/Source/WebCore/rendering/RenderBox.cpp
index f16457b5e..792b9c28b 100644
--- a/Source/WebCore/rendering/RenderBox.cpp
+++ b/Source/WebCore/rendering/RenderBox.cpp
@@ -134,16 +134,7 @@ void RenderBox::willBeDestroyed()
{
clearOverrideSize();
- if (style()) {
- RenderBlock::removePercentHeightDescendantIfNeeded(this);
-
- if (RenderView* view = this->view()) {
- if (FrameView* frameView = view->frameView()) {
- if (style()->position() == FixedPosition)
- frameView->removeFixedObject(this);
- }
- }
- }
+ RenderBlock::removePercentHeightDescendantIfNeeded(this);
RenderBoxModelObject::willBeDestroyed();
}
@@ -205,17 +196,6 @@ void RenderBox::styleWillChange(StyleDifference diff, const RenderStyle* newStyl
} else if (newStyle && isBody())
view()->repaint();
- if (FrameView *frameView = view()->frameView()) {
- bool newStyleIsFixed = newStyle && newStyle->position() == FixedPosition;
- bool oldStyleIsFixed = oldStyle && oldStyle->position() == FixedPosition;
- if (newStyleIsFixed != oldStyleIsFixed) {
- if (newStyleIsFixed)
- frameView->addFixedObject(this);
- else
- frameView->removeFixedObject(this);
- }
- }
-
RenderBoxModelObject::styleWillChange(diff, newStyle);
}
@@ -433,7 +413,7 @@ void RenderBox::updateLayerTransform()
layer()->updateTransform();
}
-LayoutUnit RenderBox::constrainLogicalWidthInRegionByMinMax(LayoutUnit logicalWidth, LayoutUnit availableWidth, RenderBlock* cb, RenderRegion* region, LayoutUnit offsetFromLogicalTopOfFirstPage)
+LayoutUnit RenderBox::constrainLogicalWidthInRegionByMinMax(LayoutUnit logicalWidth, LayoutUnit availableWidth, RenderBlock* cb, RenderRegion* region, LayoutUnit offsetFromLogicalTopOfFirstPage) const
{
RenderStyle* styleToUse = style();
if (!styleToUse->logicalMaxWidth().isUndefined())
@@ -441,7 +421,7 @@ LayoutUnit RenderBox::constrainLogicalWidthInRegionByMinMax(LayoutUnit logicalWi
return max(logicalWidth, computeLogicalWidthInRegionUsing(MinSize, availableWidth, cb, region, offsetFromLogicalTopOfFirstPage));
}
-LayoutUnit RenderBox::constrainLogicalHeightByMinMax(LayoutUnit logicalHeight)
+LayoutUnit RenderBox::constrainLogicalHeightByMinMax(LayoutUnit logicalHeight) const
{
RenderStyle* styleToUse = style();
if (!styleToUse->logicalMaxHeight().isUndefined()) {
@@ -758,25 +738,25 @@ LayoutUnit RenderBox::computeContentBoxLogicalHeight(LayoutUnit height) const
}
// Hit Testing
-bool RenderBox::nodeAtPoint(const HitTestRequest& request, HitTestResult& result, const HitTestPoint& pointInContainer, const LayoutPoint& accumulatedOffset, HitTestAction action)
+bool RenderBox::nodeAtPoint(const HitTestRequest& request, HitTestResult& result, const HitTestLocation& locationInContainer, const LayoutPoint& accumulatedOffset, HitTestAction action)
{
LayoutPoint adjustedLocation = accumulatedOffset + location();
// Check kids first.
for (RenderObject* child = lastChild(); child; child = child->previousSibling()) {
- if (!child->hasLayer() && child->nodeAtPoint(request, result, pointInContainer, adjustedLocation, action)) {
- updateHitTestResult(result, pointInContainer.point() - toLayoutSize(adjustedLocation));
+ if (!child->hasLayer() && child->nodeAtPoint(request, result, locationInContainer, adjustedLocation, action)) {
+ updateHitTestResult(result, locationInContainer.point() - toLayoutSize(adjustedLocation));
return true;
}
}
// Check our bounds next. For this purpose always assume that we can only be hit in the
// foreground phase (which is true for replaced elements like images).
- LayoutRect boundsRect = borderBoxRectInRegion(pointInContainer.region());
+ LayoutRect boundsRect = borderBoxRectInRegion(locationInContainer.region());
boundsRect.moveBy(adjustedLocation);
- if (visibleToHitTesting() && action == HitTestForeground && pointInContainer.intersects(boundsRect)) {
- updateHitTestResult(result, pointInContainer.point() - toLayoutSize(adjustedLocation));
- if (!result.addNodeToRectBasedTestResult(node(), pointInContainer, boundsRect))
+ if (visibleToHitTesting() && action == HitTestForeground && locationInContainer.intersects(boundsRect)) {
+ updateHitTestResult(result, locationInContainer.point() - toLayoutSize(adjustedLocation));
+ if (!result.addNodeToRectBasedTestResult(node(), request, locationInContainer, boundsRect))
return true;
}
@@ -1171,7 +1151,7 @@ LayoutRect RenderBox::clipRect(const LayoutPoint& location, RenderRegion* region
return clipRect;
}
-LayoutUnit RenderBox::shrinkLogicalWidthToAvoidFloats(LayoutUnit childMarginStart, LayoutUnit childMarginEnd, const RenderBlock* cb, RenderRegion* region, LayoutUnit offsetFromLogicalTopOfFirstPage)
+LayoutUnit RenderBox::shrinkLogicalWidthToAvoidFloats(LayoutUnit childMarginStart, LayoutUnit childMarginEnd, const RenderBlock* cb, RenderRegion* region, LayoutUnit offsetFromLogicalTopOfFirstPage) const
{
RenderRegion* containingBlockRegion = 0;
LayoutUnit logicalTopPosition = logicalTop();
@@ -1374,9 +1354,6 @@ const RenderObject* RenderBox::pushMappingToContainer(const RenderBoxModelObject
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());
-
bool isFixedPos = style()->position() == FixedPosition;
bool hasTransform = hasLayer() && layer()->transform();
if (hasTransform) {
@@ -1577,7 +1554,7 @@ void RenderBox::computeRectForRepaint(RenderBoxModelObject* repaintContainer, La
if (position == AbsolutePosition && o->isInFlowPositioned() && o->isRenderInline())
topLeft += toRenderInline(o)->offsetForInFlowPositionedInline(this);
- else if ((position == RelativePosition) && layer()) {
+ else if ((position == RelativePosition || position == StickyPosition) && 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
@@ -1640,15 +1617,26 @@ void RenderBox::repaintDuringLayoutIfMoved(const LayoutRect& oldRect)
void RenderBox::computeLogicalWidth()
{
- computeLogicalWidthInRegion();
+ LogicalExtentComputedValues computedValues;
+ computeLogicalWidthInRegion(computedValues);
+
+ setLogicalWidth(computedValues.m_extent);
+ setLogicalLeft(computedValues.m_position);
+ setMarginStart(computedValues.m_margins.m_start);
+ setMarginEnd(computedValues.m_margins.m_end);
}
-void RenderBox::computeLogicalWidthInRegion(RenderRegion* region, LayoutUnit offsetFromLogicalTopOfFirstPage)
+void RenderBox::computeLogicalWidthInRegion(LogicalExtentComputedValues& computedValues, RenderRegion* region, LayoutUnit offsetFromLogicalTopOfFirstPage) const
{
+ computedValues.m_extent = logicalWidth();
+ computedValues.m_position = logicalLeft();
+ computedValues.m_margins.m_start = marginStart();
+ computedValues.m_margins.m_end = marginEnd();
+
if (isOutOfFlowPositioned()) {
// FIXME: This calculation is not patched for block-flow yet.
// https://bugs.webkit.org/show_bug.cgi?id=46500
- computePositionedLogicalWidth(region, offsetFromLogicalTopOfFirstPage);
+ computePositionedLogicalWidth(computedValues, region, offsetFromLogicalTopOfFirstPage);
return;
}
@@ -1661,7 +1649,7 @@ void RenderBox::computeLogicalWidthInRegion(RenderRegion* region, LayoutUnit off
// FIXME: Account for block-flow in flexible boxes.
// https://bugs.webkit.org/show_bug.cgi?id=46418
if (hasOverrideWidth() && parent()->isFlexibleBoxIncludingDeprecated()) {
- setLogicalWidth(overrideLogicalContentWidth() + borderAndPaddingLogicalWidth());
+ computedValues.m_extent = overrideLogicalContentWidth() + borderAndPaddingLogicalWidth();
return;
}
@@ -1672,7 +1660,7 @@ void RenderBox::computeLogicalWidthInRegion(RenderRegion* region, LayoutUnit off
bool treatAsReplaced = shouldComputeSizeAsReplaced() && (!inVerticalBox || !stretching);
RenderStyle* styleToUse = style();
- Length logicalWidthLength = (treatAsReplaced) ? Length(computeReplacedLogicalWidth(), Fixed) : styleToUse->logicalWidth();
+ Length logicalWidthLength = treatAsReplaced ? Length(computeReplacedLogicalWidth(), Fixed) : styleToUse->logicalWidth();
RenderBlock* cb = containingBlock();
LayoutUnit containerLogicalWidth = max<LayoutUnit>(0, containingBlockLogicalWidthForContentInRegion(region, offsetFromLogicalTopOfFirstPage));
@@ -1684,44 +1672,53 @@ void RenderBox::computeLogicalWidthInRegion(RenderRegion* region, LayoutUnit off
if (isInline() && !isInlineBlockOrInlineTable()) {
// just calculate margins
RenderView* renderView = view();
- setMarginStart(minimumValueForLength(styleToUse->marginStart(), containerLogicalWidth, renderView));
- setMarginEnd(minimumValueForLength(styleToUse->marginEnd(), containerLogicalWidth, renderView));
+ computedValues.m_margins.m_start = minimumValueForLength(styleToUse->marginStart(), containerLogicalWidth, renderView);
+ computedValues.m_margins.m_end = minimumValueForLength(styleToUse->marginEnd(), containerLogicalWidth, renderView);
if (treatAsReplaced)
- setLogicalWidth(max<LayoutUnit>(floatValueForLength(logicalWidthLength, 0) + borderAndPaddingLogicalWidth(), minPreferredLogicalWidth()));
+ computedValues.m_extent = max<LayoutUnit>(floatValueForLength(logicalWidthLength, 0) + borderAndPaddingLogicalWidth(), minPreferredLogicalWidth());
return;
}
// Width calculations
if (treatAsReplaced)
- setLogicalWidth(logicalWidthLength.value() + borderAndPaddingLogicalWidth());
+ computedValues.m_extent = logicalWidthLength.value() + borderAndPaddingLogicalWidth();
else {
LayoutUnit preferredWidth = computeLogicalWidthInRegionUsing(MainOrPreferredSize, containerWidthInInlineDirection, cb, region, offsetFromLogicalTopOfFirstPage);
- setLogicalWidth(constrainLogicalWidthInRegionByMinMax(preferredWidth, containerWidthInInlineDirection, cb, region, offsetFromLogicalTopOfFirstPage));
+ computedValues.m_extent = constrainLogicalWidthInRegionByMinMax(preferredWidth, containerWidthInInlineDirection, cb, region, offsetFromLogicalTopOfFirstPage);
}
// Fieldsets are currently the only objects that stretch to their minimum width.
if (stretchesToMinIntrinsicLogicalWidth())
- setLogicalWidth(max(logicalWidth(), minPreferredLogicalWidth()));
+ computedValues.m_extent = max(computedValues.m_extent, minPreferredLogicalWidth());
// Margin calculations.
if (hasPerpendicularContainingBlock || isFloating() || isInline()) {
RenderView* renderView = view();
- setMarginStart(minimumValueForLength(styleToUse->marginStart(), containerLogicalWidth, renderView));
- setMarginEnd(minimumValueForLength(styleToUse->marginEnd(), containerLogicalWidth, renderView));
+ computedValues.m_margins.m_start = minimumValueForLength(styleToUse->marginStart(), containerLogicalWidth, renderView);
+ computedValues.m_margins.m_end = minimumValueForLength(styleToUse->marginEnd(), containerLogicalWidth, renderView);
} else {
LayoutUnit containerLogicalWidthForAutoMargins = containerLogicalWidth;
if (avoidsFloats() && cb->containsFloats())
containerLogicalWidthForAutoMargins = containingBlockAvailableLineWidthInRegion(region, offsetFromLogicalTopOfFirstPage);
- computeInlineDirectionMargins(cb, containerLogicalWidthForAutoMargins, logicalWidth());
+ bool hasInvertedDirection = cb->style()->isLeftToRightDirection() != style()->isLeftToRightDirection();
+ computeInlineDirectionMargins(cb, containerLogicalWidthForAutoMargins, computedValues.m_extent,
+ hasInvertedDirection ? computedValues.m_margins.m_end : computedValues.m_margins.m_start,
+ hasInvertedDirection ? computedValues.m_margins.m_start : computedValues.m_margins.m_end);
}
- if (!hasPerpendicularContainingBlock && containerLogicalWidth && containerLogicalWidth != (logicalWidth() + marginStart() + marginEnd())
- && !isFloating() && !isInline() && !cb->isFlexibleBoxIncludingDeprecated())
- cb->setMarginEndForChild(this, containerLogicalWidth - logicalWidth() - cb->marginStartForChild(this));
+ if (!hasPerpendicularContainingBlock && containerLogicalWidth && containerLogicalWidth != (computedValues.m_extent + computedValues.m_margins.m_start + computedValues.m_margins.m_end)
+ && !isFloating() && !isInline() && !cb->isFlexibleBoxIncludingDeprecated()) {
+ LayoutUnit newMargin = containerLogicalWidth - computedValues.m_extent - cb->marginStartForChild(this);
+ bool hasInvertedDirection = cb->style()->isLeftToRightDirection() != style()->isLeftToRightDirection();
+ if (hasInvertedDirection)
+ computedValues.m_margins.m_start = newMargin;
+ else
+ computedValues.m_margins.m_end = newMargin;
+ }
}
LayoutUnit RenderBox::computeLogicalWidthInRegionUsing(SizeType widthType, LayoutUnit availableLogicalWidth,
- const RenderBlock* cb, RenderRegion* region, LayoutUnit offsetFromLogicalTopOfFirstPage)
+ const RenderBlock* cb, RenderRegion* region, LayoutUnit offsetFromLogicalTopOfFirstPage) const
{
RenderStyle* styleToUse = style();
Length logicalWidth;
@@ -1820,7 +1817,7 @@ bool RenderBox::sizesLogicalWidthToFitContent(SizeType widthType) const
return false;
}
-void RenderBox::computeInlineDirectionMargins(RenderBlock* containingBlock, LayoutUnit containerWidth, LayoutUnit childWidth)
+void RenderBox::computeInlineDirectionMargins(RenderBlock* containingBlock, LayoutUnit containerWidth, LayoutUnit childWidth, LayoutUnit& marginStart, LayoutUnit& marginEnd) const
{
const RenderStyle* containingBlockStyle = containingBlock->style();
Length marginStartLength = style()->marginStartUsing(containingBlockStyle);
@@ -1829,8 +1826,8 @@ void RenderBox::computeInlineDirectionMargins(RenderBlock* containingBlock, Layo
if (isFloating() || isInline()) {
// Inline blocks/tables and floats don't have their margins increased.
- containingBlock->setMarginStartForChild(this, minimumValueForLength(marginStartLength, containerWidth, renderView));
- containingBlock->setMarginEndForChild(this, minimumValueForLength(marginEndLength, containerWidth, renderView));
+ marginStart = minimumValueForLength(marginStartLength, containerWidth, renderView);
+ marginEnd = minimumValueForLength(marginEndLength, containerWidth, renderView);
return;
}
@@ -1841,15 +1838,15 @@ void RenderBox::computeInlineDirectionMargins(RenderBlock* containingBlock, Layo
LayoutUnit marginStartWidth = minimumValueForLength(marginStartLength, containerWidth, renderView);
LayoutUnit marginEndWidth = minimumValueForLength(marginEndLength, containerWidth, renderView);
LayoutUnit centeredMarginBoxStart = max<LayoutUnit>(0, (containerWidth - childWidth - marginStartWidth - marginEndWidth) / 2);
- containingBlock->setMarginStartForChild(this, centeredMarginBoxStart + marginStartWidth);
- containingBlock->setMarginEndForChild(this, containerWidth - childWidth - containingBlock->marginStartForChild(this) + marginEndWidth);
+ marginStart = centeredMarginBoxStart + marginStartWidth;
+ marginEnd = containerWidth - childWidth - marginStart + marginEndWidth;
return;
}
// 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, valueForLength(marginStartLength, containerWidth, renderView));
- containingBlock->setMarginEndForChild(this, containerWidth - childWidth - containingBlock->marginStartForChild(this));
+ marginStart = valueForLength(marginStartLength, containerWidth, renderView);
+ marginEnd = containerWidth - childWidth - marginStart;
return;
}
@@ -1857,15 +1854,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, valueForLength(marginEndLength, containerWidth, renderView));
- containingBlock->setMarginStartForChild(this, containerWidth - childWidth - containingBlock->marginEndForChild(this));
+ marginEnd = valueForLength(marginEndLength, containerWidth, renderView);
+ marginStart = containerWidth - childWidth - marginEnd;
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, minimumValueForLength(marginStartLength, containerWidth, renderView));
- containingBlock->setMarginEndForChild(this, minimumValueForLength(marginEndLength, containerWidth, renderView));
+ marginStart = minimumValueForLength(marginStartLength, containerWidth, renderView);
+ marginEnd = minimumValueForLength(marginEndLength, containerWidth, renderView);
}
RenderBoxRegionInfo* RenderBox::renderBoxRegionInfo(RenderRegion* region, LayoutUnit offsetFromLogicalTopOfFirstPage, RenderBoxRegionInfoFlags cacheFlag) const
@@ -1887,21 +1884,12 @@ RenderBoxRegionInfo* RenderBox::renderBoxRegionInfo(RenderRegion* region, Layout
|| isTableCell() || !isBlockFlow() || isRenderFlowThread())
return 0;
- // FIXME: It's gross to cast away the const, but it would be a huge refactoring to
- // change all width computation to avoid updating any member variables, and it would be pretty lame to
- // make all the variables mutable as well.
RenderFlowThread* flowThread = enclosingRenderFlowThread();
if (flowThread->style()->writingMode() != style()->writingMode())
return 0;
- LayoutUnit oldLogicalWidth = logicalWidth();
- LayoutUnit oldLogicalLeft = logicalLeft();
- LayoutUnit oldMarginStart = marginStart();
- LayoutUnit oldMarginEnd = marginEnd();
-
- RenderBox* mutableBox = const_cast<RenderBox*>(this);
-
- mutableBox->computeLogicalWidthInRegion(region, offsetFromLogicalTopOfFirstPage);
+ LogicalExtentComputedValues computedValues;
+ computeLogicalWidthInRegion(computedValues, region, offsetFromLogicalTopOfFirstPage);
// Now determine the insets based off where this object is supposed to be positioned.
RenderBlock* cb = containingBlock();
@@ -1911,22 +1899,16 @@ RenderBoxRegionInfo* RenderBox::renderBoxRegionInfo(RenderRegion* region, Layout
LayoutUnit containingBlockLogicalWidth = cb->logicalWidth();
LayoutUnit containingBlockLogicalWidthInRegion = containingBlockInfo ? containingBlockInfo->logicalWidth() : containingBlockLogicalWidth;
- LayoutUnit marginStartInRegion = marginStart();
- LayoutUnit startMarginDelta = marginStartInRegion - oldMarginStart;
- LayoutUnit logicalWidthInRegion = logicalWidth();
- LayoutUnit logicalLeftInRegion = logicalLeft();
- LayoutUnit widthDelta = logicalWidthInRegion - oldLogicalWidth;
- LayoutUnit logicalLeftDelta = isOutOfFlowPositioned() ? logicalLeftInRegion - oldLogicalLeft : startMarginDelta;
+ LayoutUnit marginStartInRegion = computedValues.m_margins.m_start;
+ LayoutUnit startMarginDelta = marginStartInRegion - marginStart();
+ LayoutUnit logicalWidthInRegion = computedValues.m_extent;
+ LayoutUnit logicalLeftInRegion = computedValues.m_position;
+ LayoutUnit widthDelta = logicalWidthInRegion - logicalWidth();
+ LayoutUnit logicalLeftDelta = isOutOfFlowPositioned() ? logicalLeftInRegion - logicalLeft() : startMarginDelta;
LayoutUnit logicalRightInRegion = containingBlockLogicalWidthInRegion - (logicalLeftInRegion + logicalWidthInRegion);
- LayoutUnit oldLogicalRight = containingBlockLogicalWidth - (oldLogicalLeft + oldLogicalWidth);
+ LayoutUnit oldLogicalRight = containingBlockLogicalWidth - (logicalLeft() + logicalWidth());
LayoutUnit logicalRightDelta = isOutOfFlowPositioned() ? logicalRightInRegion - oldLogicalRight : startMarginDelta;
- // Set our values back.
- mutableBox->setLogicalWidth(oldLogicalWidth);
- mutableBox->setLogicalLeft(oldLogicalLeft);
- mutableBox->setMarginStart(oldMarginStart);
- mutableBox->setMarginEnd(oldMarginEnd);
-
LayoutUnit logicalLeftOffset = 0;
if (!isOutOfFlowPositioned() && avoidsFloats() && cb->containsFloats()) {
@@ -1953,26 +1935,74 @@ RenderBoxRegionInfo* RenderBox::renderBoxRegionInfo(RenderRegion* region, Layout
return new RenderBoxRegionInfo(logicalLeftOffset, logicalWidthInRegion, isShifted);
}
+static bool shouldFlipBeforeAfterMargins(const RenderStyle* containingBlockStyle, const RenderStyle* childStyle)
+{
+ ASSERT(containingBlockStyle->isHorizontalWritingMode() != childStyle->isHorizontalWritingMode());
+ WritingMode childWritingMode = childStyle->writingMode();
+ bool shouldFlip = false;
+ switch (containingBlockStyle->writingMode()) {
+ case TopToBottomWritingMode:
+ shouldFlip = (childWritingMode == RightToLeftWritingMode);
+ break;
+ case BottomToTopWritingMode:
+ shouldFlip = (childWritingMode == RightToLeftWritingMode);
+ break;
+ case RightToLeftWritingMode:
+ shouldFlip = (childWritingMode == BottomToTopWritingMode);
+ break;
+ case LeftToRightWritingMode:
+ shouldFlip = (childWritingMode == BottomToTopWritingMode);
+ break;
+ }
+
+ if (!containingBlockStyle->isLeftToRightDirection())
+ shouldFlip = !shouldFlip;
+
+ return shouldFlip;
+}
+
void RenderBox::computeLogicalHeight()
{
+ LogicalExtentComputedValues computedValues;
+ computeLogicalHeight(computedValues);
+
+ setLogicalHeight(computedValues.m_extent);
+ setLogicalTop(computedValues.m_position);
+ setMarginBefore(computedValues.m_margins.m_before);
+ setMarginAfter(computedValues.m_margins.m_after);
+}
+
+void RenderBox::computeLogicalHeight(LogicalExtentComputedValues& computedValues) const
+{
+ computedValues.m_extent = logicalHeight();
+ computedValues.m_position = logicalTop();
+
// Cell height is managed by the table and inline non-replaced elements do not support a height property.
if (isTableCell() || (isInline() && !isReplaced()))
return;
Length h;
if (isOutOfFlowPositioned())
- computePositionedLogicalHeight();
+ computePositionedLogicalHeight(computedValues);
else {
RenderBlock* cb = containingBlock();
bool hasPerpendicularContainingBlock = cb->isHorizontalWritingMode() != isHorizontalWritingMode();
- if (!hasPerpendicularContainingBlock)
- computeBlockDirectionMargins(cb);
+ if (!hasPerpendicularContainingBlock) {
+ bool shouldFlipBeforeAfter = cb->style()->writingMode() != style()->writingMode();
+ computeBlockDirectionMargins(cb,
+ shouldFlipBeforeAfter ? computedValues.m_margins.m_after : computedValues.m_margins.m_before,
+ shouldFlipBeforeAfter ? computedValues.m_margins.m_before : computedValues.m_margins.m_after);
+ }
// For tables, calculate margins only.
if (isTable()) {
- if (hasPerpendicularContainingBlock)
- computeInlineDirectionMargins(cb, containingBlockLogicalWidthForContent(), logicalHeight());
+ if (hasPerpendicularContainingBlock) {
+ bool shouldFlipBeforeAfter = shouldFlipBeforeAfterMargins(cb->style(), style());
+ computeInlineDirectionMargins(cb, containingBlockLogicalWidthForContent(), logicalHeight(),
+ shouldFlipBeforeAfter ? computedValues.m_margins.m_after : computedValues.m_margins.m_before,
+ shouldFlipBeforeAfter ? computedValues.m_margins.m_before : computedValues.m_margins.m_after);
+ }
return;
}
@@ -2018,10 +2048,14 @@ void RenderBox::computeLogicalHeight()
heightResult = h.value() + borderAndPaddingLogicalHeight();
}
- setLogicalHeight(heightResult);
+ computedValues.m_extent = heightResult;
- if (hasPerpendicularContainingBlock)
- computeInlineDirectionMargins(cb, containingBlockLogicalWidthForContent(), heightResult);
+ if (hasPerpendicularContainingBlock) {
+ bool shouldFlipBeforeAfter = shouldFlipBeforeAfterMargins(cb->style(), style());
+ computeInlineDirectionMargins(cb, containingBlockLogicalWidthForContent(), heightResult,
+ shouldFlipBeforeAfter ? computedValues.m_margins.m_after : computedValues.m_margins.m_before,
+ shouldFlipBeforeAfter ? computedValues.m_margins.m_before : computedValues.m_margins.m_after);
+ }
}
// WinIE quirk: The <html> block always fills the entire canvas in quirks mode. The <body> always fills the
@@ -2045,15 +2079,15 @@ void RenderBox::computeLogicalHeight()
visHeight = view()->viewWidth();
}
if (isRoot())
- setLogicalHeight(max(logicalHeight(), visHeight - margins));
+ computedValues.m_extent = max(computedValues.m_extent, visHeight - margins);
else {
LayoutUnit marginsBordersPadding = margins + parentBox()->marginBefore() + parentBox()->marginAfter() + parentBox()->borderAndPaddingLogicalHeight();
- setLogicalHeight(max(logicalHeight(), visHeight - marginsBordersPadding));
+ computedValues.m_extent = max(computedValues.m_extent, visHeight - marginsBordersPadding);
}
}
}
-LayoutUnit RenderBox::computeLogicalHeightUsing(SizeType heightType, const Length& height)
+LayoutUnit RenderBox::computeLogicalHeightUsing(SizeType heightType, const Length& height) const
{
LayoutUnit logicalHeight = computeContentLogicalHeightUsing(heightType, height);
if (logicalHeight != -1)
@@ -2066,10 +2100,10 @@ LayoutUnit RenderBox::computeLogicalClientHeight(SizeType heightType, const Leng
LayoutUnit heightIncludingScrollbar = computeContentLogicalHeightUsing(heightType, height);
if (heightIncludingScrollbar == -1)
return -1;
- return std::max(LayoutUnit(0), computeContentBoxLogicalHeight(heightIncludingScrollbar) - scrollbarLogicalHeight());
+ return std::max<LayoutUnit>(0, computeContentBoxLogicalHeight(heightIncludingScrollbar) - scrollbarLogicalHeight());
}
-LayoutUnit RenderBox::computeContentLogicalHeightUsing(SizeType heightType, const Length& height)
+LayoutUnit RenderBox::computeContentLogicalHeightUsing(SizeType heightType, const Length& height) const
{
if (height.isAuto())
return heightType == MinSize ? 0 : -1;
@@ -2082,7 +2116,7 @@ LayoutUnit RenderBox::computeContentLogicalHeightUsing(SizeType heightType, cons
return -1;
}
-LayoutUnit RenderBox::computePercentageLogicalHeight(const Length& height)
+LayoutUnit RenderBox::computePercentageLogicalHeight(const Length& height) const
{
LayoutUnit result = -1;
@@ -2098,7 +2132,7 @@ LayoutUnit RenderBox::computePercentageLogicalHeight(const Length& height)
break;
skippedAutoHeightContainingBlock = true;
cb = cb->containingBlock();
- cb->addPercentHeightDescendant(this);
+ cb->addPercentHeightDescendant(const_cast<RenderBox*>(this));
}
RenderStyle* cbstyle = cb->style();
@@ -2138,9 +2172,11 @@ LayoutUnit RenderBox::computePercentageLogicalHeight(const Length& height)
result = max<LayoutUnit>(0, contentBoxHeightWithScrollbar - cb->scrollbarLogicalHeight());
} else if (cbstyle->logicalHeight().isPercent() && !isOutOfFlowPositionedWithSpecifiedHeight) {
// We need to recur and compute the percentage height for our containing block.
- result = cb->computePercentageLogicalHeight(cbstyle->logicalHeight());
- if (result != -1)
- result = cb->computeContentBoxLogicalHeight(result);
+ LayoutUnit heightWithScrollbar = cb->computePercentageLogicalHeight(cbstyle->logicalHeight());
+ if (heightWithScrollbar != -1) {
+ LayoutUnit contentBoxHeightWithScrollbar = cb->computeContentBoxLogicalHeight(heightWithScrollbar);
+ result = max<LayoutUnit>(0, contentBoxHeightWithScrollbar - cb->scrollbarLogicalHeight());
+ }
} else if (cb->isRenderView() || (cb->isBody() && document()->inQuirksMode()) || isOutOfFlowPositionedWithSpecifiedHeight) {
// Don't allow this to affect the block' height() member variable, since this
// can get called while the block is still laying out its kids.
@@ -2270,10 +2306,7 @@ LayoutUnit RenderBox::computeReplacedLogicalHeightUsing(SizeType sizeType, Lengt
cb = cb->containingBlock();
}
}
- availableHeight = computeContentBoxLogicalHeight(valueForLength(logicalHeight, availableHeight));
- if (cb->isBox() && cb->style()->logicalHeight().isFixed())
- availableHeight = max<LayoutUnit>(0, availableHeight - toRenderBox(cb)->scrollbarLogicalHeight());
- return availableHeight;
+ return computeContentBoxLogicalHeight(valueForLength(logicalHeight, availableHeight));
}
case ViewportPercentageWidth:
case ViewportPercentageHeight:
@@ -2291,9 +2324,6 @@ LayoutUnit RenderBox::availableLogicalHeight() const
LayoutUnit RenderBox::availableLogicalHeightUsing(const Length& h) const
{
- if (h.isFixed())
- return computeContentBoxLogicalHeight(h.value());
-
if (isRenderView())
return isHorizontalWritingMode() ? toRenderView(this)->frameView()->visibleHeight() : toRenderView(this)->frameView()->visibleWidth();
@@ -2303,19 +2333,16 @@ LayoutUnit RenderBox::availableLogicalHeightUsing(const Length& h) const
if (isTableCell() && (h.isAuto() || h.isPercent()))
return overrideLogicalContentHeight();
- if (h.isPercent()) {
- LayoutUnit availableHeight;
- // https://bugs.webkit.org/show_bug.cgi?id=64046
- // For absolutely positioned elements whose containing block is based on a block-level element,
- // the percentage is calculated with respect to the height of the padding box of that element
- if (isOutOfFlowPositioned())
- availableHeight = containingBlockLogicalHeightForPositioned(containingBlock());
- else
- availableHeight = containingBlock()->availableLogicalHeight();
+ if (h.isPercent() && isOutOfFlowPositioned()) {
+ LayoutUnit availableHeight = containingBlockLogicalHeightForPositioned(containingBlock());
return computeContentBoxLogicalHeight(valueForLength(h, availableHeight));
}
- // FIXME: We can't just check top/bottom here.
+ LayoutUnit heightIncludingScrollbar = computeContentLogicalHeightUsing(MainOrPreferredSize, h);
+ if (heightIncludingScrollbar != -1)
+ return std::max<LayoutUnit>(0, computeContentBoxLogicalHeight(heightIncludingScrollbar) - scrollbarLogicalHeight());
+
+ // FIXME: Check logicalTop/logicalBottom here to correctly handle vertical writing-mode.
// https://bugs.webkit.org/show_bug.cgi?id=46500
if (isRenderBlock() && isOutOfFlowPositioned() && style()->height().isAuto() && !(style()->top().isAuto() || style()->bottom().isAuto())) {
RenderBlock* block = const_cast<RenderBlock*>(toRenderBlock(this));
@@ -2329,13 +2356,13 @@ LayoutUnit RenderBox::availableLogicalHeightUsing(const Length& h) const
return containingBlock()->availableLogicalHeight();
}
-void RenderBox::computeBlockDirectionMargins(const RenderBlock* containingBlock)
+void RenderBox::computeBlockDirectionMargins(const RenderBlock* containingBlock, LayoutUnit& marginBefore, LayoutUnit& marginAfter) const
{
if (isTableCell()) {
// FIXME: Not right if we allow cells to have different directionality than the table. If we do allow this, though,
// we may just do it with an extra anonymous block inside the cell.
- setMarginBefore(0);
- setMarginAfter(0);
+ marginBefore = 0;
+ marginAfter = 0;
return;
}
@@ -2344,8 +2371,17 @@ void RenderBox::computeBlockDirectionMargins(const RenderBlock* containingBlock)
LayoutUnit cw = containingBlockLogicalWidthForContent();
RenderView* renderView = view();
RenderStyle* containingBlockStyle = containingBlock->style();
- containingBlock->setMarginBeforeForChild(this, minimumValueForLength(style()->marginBeforeUsing(containingBlockStyle), cw, renderView));
- containingBlock->setMarginAfterForChild(this, minimumValueForLength(style()->marginAfterUsing(containingBlockStyle), cw, renderView));
+ marginBefore = minimumValueForLength(style()->marginBeforeUsing(containingBlockStyle), cw, renderView);
+ marginAfter = minimumValueForLength(style()->marginAfterUsing(containingBlockStyle), cw, renderView);
+}
+
+void RenderBox::computeAndSetBlockDirectionMargins(const RenderBlock* containingBlock)
+{
+ LayoutUnit marginBefore;
+ LayoutUnit marginAfter;
+ computeBlockDirectionMargins(containingBlock, marginBefore, marginAfter);
+ containingBlock->setMarginBeforeForChild(this, marginBefore);
+ containingBlock->setMarginAfterForChild(this, marginAfter);
}
LayoutUnit RenderBox::containingBlockLogicalWidthForPositioned(const RenderBoxModelObject* containingBlock, RenderRegion* region,
@@ -2496,10 +2532,10 @@ static void computeInlineStaticDistance(Length& logicalLeft, Length& logicalRigh
}
}
-void RenderBox::computePositionedLogicalWidth(RenderRegion* region, LayoutUnit offsetFromLogicalTopOfFirstPage)
+void RenderBox::computePositionedLogicalWidth(LogicalExtentComputedValues& computedValues, RenderRegion* region, LayoutUnit offsetFromLogicalTopOfFirstPage) const
{
if (isReplaced()) {
- computePositionedLogicalWidthReplaced(); // FIXME: Patch for regions when we add replaced element support.
+ computePositionedLogicalWidthReplaced(computedValues); // FIXME: Patch for regions when we add replaced element support.
return;
}
@@ -2534,8 +2570,6 @@ void RenderBox::computePositionedLogicalWidth(RenderRegion* region, LayoutUnit o
const LayoutUnit bordersPlusPadding = borderAndPaddingLogicalWidth();
const Length marginLogicalLeft = isHorizontal ? style()->marginLeft() : style()->marginTop();
const Length marginLogicalRight = isHorizontal ? style()->marginRight() : style()->marginBottom();
- LayoutUnit& marginLogicalLeftAlias = m_marginBox.mutableLogicalLeft(style()->writingMode());
- LayoutUnit& marginLogicalRightAlias = m_marginBox.mutableLogicalRight(style()->writingMode());
Length logicalLeftLength = style()->logicalLeft();
Length logicalRightLength = style()->logicalRight();
@@ -2569,70 +2603,57 @@ void RenderBox::computePositionedLogicalWidth(RenderRegion* region, LayoutUnit o
computeInlineStaticDistance(logicalLeftLength, logicalRightLength, this, containerBlock, containerLogicalWidth, region);
// Calculate constraint equation values for 'width' case.
- LayoutUnit logicalWidthResult;
- LayoutUnit logicalLeftResult;
computePositionedLogicalWidthUsing(MainOrPreferredSize, style()->logicalWidth(), containerBlock, containerDirection,
containerLogicalWidth, bordersPlusPadding,
logicalLeftLength, logicalRightLength, marginLogicalLeft, marginLogicalRight,
- logicalWidthResult, marginLogicalLeftAlias, marginLogicalRightAlias, logicalLeftResult);
- setLogicalWidth(logicalWidthResult);
- setLogicalLeft(logicalLeftResult);
+ computedValues);
// Calculate constraint equation values for 'max-width' case.
if (!style()->logicalMaxWidth().isUndefined()) {
- LayoutUnit maxLogicalWidth;
- LayoutUnit maxMarginLogicalLeft;
- LayoutUnit maxMarginLogicalRight;
- LayoutUnit maxLogicalLeftPos;
+ LogicalExtentComputedValues maxValues;
computePositionedLogicalWidthUsing(MaxSize, style()->logicalMaxWidth(), containerBlock, containerDirection,
containerLogicalWidth, bordersPlusPadding,
logicalLeftLength, logicalRightLength, marginLogicalLeft, marginLogicalRight,
- maxLogicalWidth, maxMarginLogicalLeft, maxMarginLogicalRight, maxLogicalLeftPos);
+ maxValues);
- if (logicalWidth() > maxLogicalWidth) {
- setLogicalWidth(maxLogicalWidth);
- marginLogicalLeftAlias = maxMarginLogicalLeft;
- marginLogicalRightAlias = maxMarginLogicalRight;
- setLogicalLeft(maxLogicalLeftPos);
+ if (computedValues.m_extent > maxValues.m_extent) {
+ computedValues.m_extent = maxValues.m_extent;
+ computedValues.m_position = maxValues.m_position;
+ computedValues.m_margins.m_start = maxValues.m_margins.m_start;
+ computedValues.m_margins.m_end = maxValues.m_margins.m_end;
}
}
// Calculate constraint equation values for 'min-width' case.
if (!style()->logicalMinWidth().isZero()) {
- LayoutUnit minLogicalWidth;
- LayoutUnit minMarginLogicalLeft;
- LayoutUnit minMarginLogicalRight;
- LayoutUnit minLogicalLeftPos;
+ LogicalExtentComputedValues minValues;
computePositionedLogicalWidthUsing(MinSize, style()->logicalMinWidth(), containerBlock, containerDirection,
containerLogicalWidth, bordersPlusPadding,
logicalLeftLength, logicalRightLength, marginLogicalLeft, marginLogicalRight,
- minLogicalWidth, minMarginLogicalLeft, minMarginLogicalRight, minLogicalLeftPos);
+ minValues);
- if (logicalWidth() < minLogicalWidth) {
- setLogicalWidth(minLogicalWidth);
- marginLogicalLeftAlias = minMarginLogicalLeft;
- marginLogicalRightAlias = minMarginLogicalRight;
- setLogicalLeft(minLogicalLeftPos);
+ if (computedValues.m_extent < minValues.m_extent) {
+ computedValues.m_extent = minValues.m_extent;
+ computedValues.m_position = minValues.m_position;
+ computedValues.m_margins.m_start = minValues.m_margins.m_start;
+ computedValues.m_margins.m_end = minValues.m_margins.m_end;
}
}
- if (stretchesToMinIntrinsicLogicalWidth() && logicalWidth() < minPreferredLogicalWidth() - bordersPlusPadding) {
+ if (stretchesToMinIntrinsicLogicalWidth() && computedValues.m_extent < minPreferredLogicalWidth() - bordersPlusPadding) {
computePositionedLogicalWidthUsing(MainOrPreferredSize, Length(minPreferredLogicalWidth() - bordersPlusPadding, Fixed), containerBlock, containerDirection,
containerLogicalWidth, bordersPlusPadding,
logicalLeftLength, logicalRightLength, marginLogicalLeft, marginLogicalRight,
- logicalWidthResult, marginLogicalLeftAlias, marginLogicalRightAlias, logicalLeftResult);
- setLogicalWidth(logicalWidthResult);
- setLogicalLeft(logicalLeftResult);
+ computedValues);
}
- // Put logicalWidth() into correct form.
- setLogicalWidth(logicalWidth() + bordersPlusPadding);
+ computedValues.m_extent += bordersPlusPadding;
// Adjust logicalLeft if we need to for the flipped version of our writing mode in regions.
if (inRenderFlowThread() && !region && isWritingModeRoot() && isHorizontalWritingMode() == containerBlock->isHorizontalWritingMode()) {
- LayoutUnit logicalLeftPos = logicalLeft();
+ LayoutUnit logicalLeftPos = computedValues.m_position;
const RenderBlock* cb = toRenderBlock(containerBlock);
LayoutUnit cbPageOffset = offsetFromLogicalTopOfFirstPage - logicalTop();
RenderRegion* cbRegion = cb->regionAtBlockOffset(cbPageOffset);
@@ -2641,7 +2662,7 @@ void RenderBox::computePositionedLogicalWidth(RenderRegion* region, LayoutUnit o
RenderBoxRegionInfo* boxInfo = cb->renderBoxRegionInfo(cbRegion, cbPageOffset);
if (boxInfo) {
logicalLeftPos += boxInfo->logicalLeft();
- setLogicalLeft(logicalLeftPos);
+ computedValues.m_position = logicalLeftPos;
}
}
}
@@ -2661,7 +2682,7 @@ static void computeLogicalLeftPositionedOffset(LayoutUnit& logicalLeftPos, const
void RenderBox::computePositionedLogicalWidthUsing(SizeType widthSizeType, Length logicalWidth, const RenderBoxModelObject* containerBlock, TextDirection containerDirection,
LayoutUnit containerLogicalWidth, LayoutUnit bordersPlusPadding,
Length logicalLeft, Length logicalRight, Length marginLogicalLeft, Length marginLogicalRight,
- LayoutUnit& logicalWidthValue, LayoutUnit& marginLogicalLeftValue, LayoutUnit& marginLogicalRightValue, LayoutUnit& logicalLeftPos)
+ LogicalExtentComputedValues& computedValues) const
{
if (widthSizeType == MinSize && logicalWidth.isAuto())
logicalWidth = Length(0, Fixed);
@@ -2676,6 +2697,8 @@ void RenderBox::computePositionedLogicalWidthUsing(SizeType widthSizeType, Lengt
bool logicalLeftIsAuto = logicalLeft.isAuto();
bool logicalRightIsAuto = logicalRight.isAuto();
RenderView* renderView = view();
+ LayoutUnit& marginLogicalLeftValue = style()->isLeftToRightDirection() ? computedValues.m_margins.m_start : computedValues.m_margins.m_end;
+ LayoutUnit& marginLogicalRightValue = style()->isLeftToRightDirection() ? computedValues.m_margins.m_end : computedValues.m_margins.m_start;
if (!logicalLeftIsAuto && !logicalWidthIsAuto && !logicalRightIsAuto) {
/*-----------------------------------------------------------------------*\
@@ -2694,9 +2717,9 @@ void RenderBox::computePositionedLogicalWidthUsing(SizeType widthSizeType, Lengt
// case because the value is not used for any further calculations.
logicalLeftValue = valueForLength(logicalLeft, containerLogicalWidth, renderView);
- logicalWidthValue = computeContentBoxLogicalWidth(valueForLength(logicalWidth, containerLogicalWidth, renderView));
+ computedValues.m_extent = computeContentBoxLogicalWidth(valueForLength(logicalWidth, containerLogicalWidth, renderView));
- const LayoutUnit availableSpace = containerLogicalWidth - (logicalLeftValue + logicalWidthValue + valueForLength(logicalRight, containerLogicalWidth, renderView) + bordersPlusPadding);
+ const LayoutUnit availableSpace = containerLogicalWidth - (logicalLeftValue + computedValues.m_extent + valueForLength(logicalRight, containerLogicalWidth, renderView) + bordersPlusPadding);
// Margins are now the only unknown
if (marginLogicalLeft.isAuto() && marginLogicalRight.isAuto()) {
@@ -2791,8 +2814,8 @@ void RenderBox::computePositionedLogicalWidthUsing(SizeType widthSizeType, Lengt
LayoutUnit preferredWidth = maxPreferredLogicalWidth() - bordersPlusPadding;
LayoutUnit preferredMinWidth = minPreferredLogicalWidth() - bordersPlusPadding;
LayoutUnit availableWidth = availableSpace - logicalRightValue;
- logicalWidthValue = min(max(preferredMinWidth, availableWidth), preferredWidth);
- logicalLeftValue = availableSpace - (logicalWidthValue + logicalRightValue);
+ computedValues.m_extent = min(max(preferredMinWidth, availableWidth), preferredWidth);
+ logicalLeftValue = availableSpace - (computedValues.m_extent + logicalRightValue);
} else if (!logicalLeftIsAuto && logicalWidthIsAuto && logicalRightIsAuto) {
// RULE 3: (use shrink-to-fit for width, and no need solve of right)
logicalLeftValue = valueForLength(logicalLeft, containerLogicalWidth, renderView);
@@ -2801,19 +2824,19 @@ void RenderBox::computePositionedLogicalWidthUsing(SizeType widthSizeType, Lengt
LayoutUnit preferredWidth = maxPreferredLogicalWidth() - bordersPlusPadding;
LayoutUnit preferredMinWidth = minPreferredLogicalWidth() - bordersPlusPadding;
LayoutUnit availableWidth = availableSpace - logicalLeftValue;
- logicalWidthValue = min(max(preferredMinWidth, availableWidth), preferredWidth);
+ computedValues.m_extent = min(max(preferredMinWidth, availableWidth), preferredWidth);
} else if (logicalLeftIsAuto && !logicalWidthIsAuto && !logicalRightIsAuto) {
// RULE 4: (solve for left)
- logicalWidthValue = computeContentBoxLogicalWidth(valueForLength(logicalWidth, containerLogicalWidth, renderView));
- logicalLeftValue = availableSpace - (logicalWidthValue + valueForLength(logicalRight, containerLogicalWidth, renderView));
+ computedValues.m_extent = computeContentBoxLogicalWidth(valueForLength(logicalWidth, containerLogicalWidth, renderView));
+ logicalLeftValue = availableSpace - (computedValues.m_extent + valueForLength(logicalRight, containerLogicalWidth, renderView));
} else if (!logicalLeftIsAuto && logicalWidthIsAuto && !logicalRightIsAuto) {
// RULE 5: (solve for width)
logicalLeftValue = valueForLength(logicalLeft, containerLogicalWidth, renderView);
- logicalWidthValue = availableSpace - (logicalLeftValue + valueForLength(logicalRight, containerLogicalWidth, renderView));
+ computedValues.m_extent = availableSpace - (logicalLeftValue + valueForLength(logicalRight, containerLogicalWidth, renderView));
} else if (!logicalLeftIsAuto && !logicalWidthIsAuto && logicalRightIsAuto) {
// RULE 6: (no need solve for right)
logicalLeftValue = valueForLength(logicalLeft, containerLogicalWidth, renderView);
- logicalWidthValue = computeContentBoxLogicalWidth(valueForLength(logicalWidth, containerLogicalWidth, renderView));
+ computedValues.m_extent = computeContentBoxLogicalWidth(valueForLength(logicalWidth, containerLogicalWidth, renderView));
}
}
@@ -2828,13 +2851,13 @@ void RenderBox::computePositionedLogicalWidthUsing(SizeType widthSizeType, Lengt
InlineFlowBox* firstLine = flow->firstLineBox();
InlineFlowBox* lastLine = flow->lastLineBox();
if (firstLine && lastLine && firstLine != lastLine) {
- logicalLeftPos = logicalLeftValue + marginLogicalLeftValue + lastLine->borderLogicalLeft() + (lastLine->logicalLeft() - firstLine->logicalLeft());
+ computedValues.m_position = logicalLeftValue + marginLogicalLeftValue + lastLine->borderLogicalLeft() + (lastLine->logicalLeft() - firstLine->logicalLeft());
return;
}
}
- logicalLeftPos = logicalLeftValue + marginLogicalLeftValue;
- computeLogicalLeftPositionedOffset(logicalLeftPos, this, logicalWidthValue, containerBlock, containerLogicalWidth);
+ computedValues.m_position = logicalLeftValue + marginLogicalLeftValue;
+ computeLogicalLeftPositionedOffset(computedValues.m_position, this, computedValues.m_extent, containerBlock, containerLogicalWidth);
}
static void computeBlockStaticDistance(Length& logicalTop, Length& logicalBottom, const RenderBox* child, const RenderBoxModelObject* containerBlock)
@@ -2851,10 +2874,10 @@ static void computeBlockStaticDistance(Length& logicalTop, Length& logicalBottom
logicalTop.setValue(Fixed, staticLogicalTop);
}
-void RenderBox::computePositionedLogicalHeight()
+void RenderBox::computePositionedLogicalHeight(LogicalExtentComputedValues& computedValues) const
{
if (isReplaced()) {
- computePositionedLogicalHeightReplaced();
+ computePositionedLogicalHeightReplaced(computedValues);
return;
}
@@ -2874,9 +2897,6 @@ void RenderBox::computePositionedLogicalHeight()
const LayoutUnit bordersPlusPadding = borderAndPaddingLogicalHeight();
const Length marginBefore = styleToUse->marginBefore();
const Length marginAfter = styleToUse->marginAfter();
- LayoutUnit& marginBeforeAlias = m_marginBox.mutableBefore(styleToUse->writingMode());
- LayoutUnit& marginAfterAlias = m_marginBox.mutableAfter(styleToUse->writingMode());
-
Length logicalTopLength = styleToUse->logicalTop();
Length logicalBottomLength = styleToUse->logicalBottom();
@@ -2901,62 +2921,52 @@ void RenderBox::computePositionedLogicalHeight()
// Calculate the static distance if needed.
computeBlockStaticDistance(logicalTopLength, logicalBottomLength, this, containerBlock);
- LayoutUnit logicalHeightResult; // Needed to compute overflow.
- LayoutUnit logicalTopPos;
-
// Calculate constraint equation values for 'height' case.
computePositionedLogicalHeightUsing(MainOrPreferredSize, styleToUse->logicalHeight(), containerBlock, containerLogicalHeight, bordersPlusPadding,
logicalTopLength, logicalBottomLength, marginBefore, marginAfter,
- logicalHeightResult, marginBeforeAlias, marginAfterAlias, logicalTopPos);
- setLogicalTop(logicalTopPos);
+ computedValues);
// Avoid doing any work in the common case (where the values of min-height and max-height are their defaults).
// see FIXME 2
// Calculate constraint equation values for 'max-height' case.
if (!styleToUse->logicalMaxHeight().isUndefined()) {
- LayoutUnit maxLogicalHeight;
- LayoutUnit maxMarginBefore;
- LayoutUnit maxMarginAfter;
- LayoutUnit maxLogicalTopPos;
+ LogicalExtentComputedValues maxValues;
computePositionedLogicalHeightUsing(MaxSize, styleToUse->logicalMaxHeight(), containerBlock, containerLogicalHeight, bordersPlusPadding,
logicalTopLength, logicalBottomLength, marginBefore, marginAfter,
- maxLogicalHeight, maxMarginBefore, maxMarginAfter, maxLogicalTopPos);
+ maxValues);
- if (logicalHeightResult > maxLogicalHeight) {
- logicalHeightResult = maxLogicalHeight;
- marginBeforeAlias = maxMarginBefore;
- marginAfterAlias = maxMarginAfter;
- setLogicalTop(maxLogicalTopPos);
+ if (computedValues.m_extent > maxValues.m_extent) {
+ computedValues.m_extent = maxValues.m_extent;
+ computedValues.m_position = maxValues.m_position;
+ computedValues.m_margins.m_before = maxValues.m_margins.m_before;
+ computedValues.m_margins.m_after = maxValues.m_margins.m_after;
}
}
// Calculate constraint equation values for 'min-height' case.
if (!styleToUse->logicalMinHeight().isZero()) {
- LayoutUnit minLogicalHeight;
- LayoutUnit minMarginBefore;
- LayoutUnit minMarginAfter;
- LayoutUnit minLogicalTopPos;
+ LogicalExtentComputedValues minValues;
computePositionedLogicalHeightUsing(MinSize, styleToUse->logicalMinHeight(), containerBlock, containerLogicalHeight, bordersPlusPadding,
logicalTopLength, logicalBottomLength, marginBefore, marginAfter,
- minLogicalHeight, minMarginBefore, minMarginAfter, minLogicalTopPos);
+ minValues);
- if (logicalHeightResult < minLogicalHeight) {
- logicalHeightResult = minLogicalHeight;
- marginBeforeAlias = minMarginBefore;
- marginAfterAlias = minMarginAfter;
- setLogicalTop(minLogicalTopPos);
+ if (computedValues.m_extent < minValues.m_extent) {
+ computedValues.m_extent = minValues.m_extent;
+ computedValues.m_position = minValues.m_position;
+ computedValues.m_margins.m_before = minValues.m_margins.m_before;
+ computedValues.m_margins.m_after = minValues.m_margins.m_after;
}
}
// Set final height value.
- setLogicalHeight(logicalHeightResult + bordersPlusPadding);
+ computedValues.m_extent += bordersPlusPadding;
// Adjust logicalTop if we need to for perpendicular writing modes in regions.
if (inRenderFlowThread() && isHorizontalWritingMode() != containerBlock->isHorizontalWritingMode()) {
- LayoutUnit logicalTopPos = logicalTop();
+ LayoutUnit logicalTopPos = computedValues.m_position;
const RenderBlock* cb = toRenderBlock(containerBlock);
LayoutUnit cbPageOffset = cb->offsetFromLogicalTopOfFirstPage() - logicalLeft();
RenderRegion* cbRegion = cb->regionAtBlockOffset(cbPageOffset);
@@ -2965,7 +2975,7 @@ void RenderBox::computePositionedLogicalHeight()
RenderBoxRegionInfo* boxInfo = cb->renderBoxRegionInfo(cbRegion, cbPageOffset);
if (boxInfo) {
logicalTopPos += boxInfo->logicalLeft();
- setLogicalTop(logicalTopPos);
+ computedValues.m_position = logicalTopPos;
}
}
}
@@ -2996,7 +3006,7 @@ static void computeLogicalTopPositionedOffset(LayoutUnit& logicalTopPos, const R
void RenderBox::computePositionedLogicalHeightUsing(SizeType heightSizeType, Length logicalHeightLength, const RenderBoxModelObject* containerBlock,
LayoutUnit containerLogicalHeight, LayoutUnit bordersPlusPadding,
Length logicalTop, Length logicalBottom, Length marginBefore, Length marginAfter,
- LayoutUnit& logicalHeightValue, LayoutUnit& marginBeforeValue, LayoutUnit& marginAfterValue, LayoutUnit& logicalTopPos)
+ LogicalExtentComputedValues& computedValues) const
{
if (heightSizeType == MinSize && logicalHeightLength.isAuto())
logicalHeightLength = Length(0, Fixed);
@@ -3005,6 +3015,7 @@ void RenderBox::computePositionedLogicalHeightUsing(SizeType heightSizeType, Len
// converted to the static position in computePositionedLogicalHeight()
ASSERT(!(logicalTop.isAuto() && logicalBottom.isAuto()));
+ LayoutUnit logicalHeightValue;
LayoutUnit contentLogicalHeight = logicalHeight() - bordersPlusPadding;
LayoutUnit logicalTopValue = 0;
@@ -3041,20 +3052,20 @@ void RenderBox::computePositionedLogicalHeightUsing(SizeType heightSizeType, Len
if (marginBefore.isAuto() && marginAfter.isAuto()) {
// Both margins auto, solve for equality
// NOTE: This may result in negative values.
- marginBeforeValue = availableSpace / 2; // split the difference
- marginAfterValue = availableSpace - marginBeforeValue; // account for odd valued differences
+ computedValues.m_margins.m_before = availableSpace / 2; // split the difference
+ computedValues.m_margins.m_after = availableSpace - computedValues.m_margins.m_before; // account for odd valued differences
} else if (marginBefore.isAuto()) {
// Solve for top margin
- marginAfterValue = valueForLength(marginAfter, containerLogicalHeight, renderView);
- marginBeforeValue = availableSpace - marginAfterValue;
+ computedValues.m_margins.m_after = valueForLength(marginAfter, containerLogicalHeight, renderView);
+ computedValues.m_margins.m_before = availableSpace - computedValues.m_margins.m_after;
} else if (marginAfter.isAuto()) {
// Solve for bottom margin
- marginBeforeValue = valueForLength(marginBefore, containerLogicalHeight, renderView);
- marginAfterValue = availableSpace - marginBeforeValue;
+ computedValues.m_margins.m_before = valueForLength(marginBefore, containerLogicalHeight, renderView);
+ computedValues.m_margins.m_after = availableSpace - computedValues.m_margins.m_before;
} else {
// Over-constrained, (no need solve for bottom)
- marginBeforeValue = valueForLength(marginBefore, containerLogicalHeight, renderView);
- marginAfterValue = valueForLength(marginAfter, containerLogicalHeight, renderView);
+ computedValues.m_margins.m_before = valueForLength(marginBefore, containerLogicalHeight, renderView);
+ computedValues.m_margins.m_after = valueForLength(marginAfter, containerLogicalHeight, renderView);
}
} else {
/*--------------------------------------------------------------------*\
@@ -3083,10 +3094,10 @@ void RenderBox::computePositionedLogicalHeightUsing(SizeType heightSizeType, Len
// because the value is not used for any further calculations.
// Calculate margins, 'auto' margins are ignored.
- marginBeforeValue = minimumValueForLength(marginBefore, containerLogicalHeight, renderView);
- marginAfterValue = minimumValueForLength(marginAfter, containerLogicalHeight, renderView);
+ computedValues.m_margins.m_before = minimumValueForLength(marginBefore, containerLogicalHeight, renderView);
+ computedValues.m_margins.m_after = minimumValueForLength(marginAfter, containerLogicalHeight, renderView);
- const LayoutUnit availableSpace = containerLogicalHeight - (marginBeforeValue + marginAfterValue + bordersPlusPadding);
+ const LayoutUnit availableSpace = containerLogicalHeight - (computedValues.m_margins.m_before + computedValues.m_margins.m_after + bordersPlusPadding);
// Use rule/case that applies.
if (logicalTopIsAuto && logicalHeightIsAuto && !logicalBottomIsAuto) {
@@ -3111,13 +3122,14 @@ void RenderBox::computePositionedLogicalHeightUsing(SizeType heightSizeType, Len
logicalTopValue = valueForLength(logicalTop, containerLogicalHeight, renderView);
}
}
+ computedValues.m_extent = logicalHeightValue;
// Use computed values to calculate the vertical position.
- logicalTopPos = logicalTopValue + marginBeforeValue;
- computeLogicalTopPositionedOffset(logicalTopPos, this, logicalHeightValue, containerBlock, containerLogicalHeight);
+ computedValues.m_position = logicalTopValue + computedValues.m_margins.m_before;
+ computeLogicalTopPositionedOffset(computedValues.m_position, this, logicalHeightValue, containerBlock, containerLogicalHeight);
}
-void RenderBox::computePositionedLogicalWidthReplaced()
+void RenderBox::computePositionedLogicalWidthReplaced(LogicalExtentComputedValues& computedValues) const
{
// The following is based off of the W3C Working Draft from April 11, 2006 of
// CSS 2.1: Section 10.3.8 "Absolutely positioned, replaced elements"
@@ -3141,8 +3153,8 @@ void RenderBox::computePositionedLogicalWidthReplaced()
Length logicalRight = style()->logicalRight();
Length marginLogicalLeft = isHorizontal ? style()->marginLeft() : style()->marginTop();
Length marginLogicalRight = isHorizontal ? style()->marginRight() : style()->marginBottom();
- LayoutUnit& marginLogicalLeftAlias = m_marginBox.mutableLogicalLeft(style()->writingMode());
- LayoutUnit& marginLogicalRightAlias = m_marginBox.mutableLogicalRight(style()->writingMode());
+ LayoutUnit& marginLogicalLeftAlias = style()->isLeftToRightDirection() ? computedValues.m_margins.m_start : computedValues.m_margins.m_end;
+ LayoutUnit& marginLogicalRightAlias = style()->isLeftToRightDirection() ? computedValues.m_margins.m_end : computedValues.m_margins.m_start;
/*-----------------------------------------------------------------------*\
* 1. The used value of 'width' is determined as for inline replaced
@@ -3151,9 +3163,9 @@ void RenderBox::computePositionedLogicalWidthReplaced()
// NOTE: This value of width is FINAL in that the min/max width calculations
// are dealt with in computeReplacedWidth(). This means that the steps to produce
// correct max/min in the non-replaced version, are not necessary.
- setLogicalWidth(computeReplacedLogicalWidth() + borderAndPaddingLogicalWidth());
+ computedValues.m_extent = computeReplacedLogicalWidth() + borderAndPaddingLogicalWidth();
- const LayoutUnit availableSpace = containerLogicalWidth - logicalWidth();
+ const LayoutUnit availableSpace = containerLogicalWidth - computedValues.m_extent;
/*-----------------------------------------------------------------------*\
* 2. If both 'left' and 'right' have the value 'auto', then if 'direction'
@@ -3249,7 +3261,7 @@ void RenderBox::computePositionedLogicalWidthReplaced()
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;
+ int totalLogicalWidth = computedValues.m_extent + logicalLeftValue + logicalRightValue + marginLogicalLeftAlias + marginLogicalRightAlias;
logicalLeftValue = containerLogicalWidth - (totalLogicalWidth - logicalLeftValue);
}
}
@@ -3276,17 +3288,17 @@ void RenderBox::computePositionedLogicalWidthReplaced()
InlineFlowBox* firstLine = flow->firstLineBox();
InlineFlowBox* lastLine = flow->lastLineBox();
if (firstLine && lastLine && firstLine != lastLine) {
- setLogicalLeft(logicalLeftValue + marginLogicalLeftAlias + lastLine->borderLogicalLeft() + (lastLine->logicalLeft() - firstLine->logicalLeft()));
+ computedValues.m_position = logicalLeftValue + marginLogicalLeftAlias + lastLine->borderLogicalLeft() + (lastLine->logicalLeft() - firstLine->logicalLeft());
return;
}
}
LayoutUnit logicalLeftPos = logicalLeftValue + marginLogicalLeftAlias;
- computeLogicalLeftPositionedOffset(logicalLeftPos, this, logicalWidth(), containerBlock, containerLogicalWidth);
- setLogicalLeft(logicalLeftPos.round());
+ computeLogicalLeftPositionedOffset(logicalLeftPos, this, computedValues.m_extent, containerBlock, containerLogicalWidth);
+ computedValues.m_position = logicalLeftPos.round();
}
-void RenderBox::computePositionedLogicalHeightReplaced()
+void RenderBox::computePositionedLogicalHeightReplaced(LogicalExtentComputedValues& computedValues) const
{
// The following is based off of the W3C Working Draft from April 11, 2006 of
// CSS 2.1: Section 10.6.5 "Absolutely positioned, replaced elements"
@@ -3302,8 +3314,8 @@ void RenderBox::computePositionedLogicalHeightReplaced()
// Variables to solve.
Length marginBefore = style()->marginBefore();
Length marginAfter = style()->marginAfter();
- LayoutUnit& marginBeforeAlias = m_marginBox.mutableBefore(style()->writingMode());
- LayoutUnit& marginAfterAlias = m_marginBox.mutableAfter(style()->writingMode());
+ LayoutUnit& marginBeforeAlias = computedValues.m_margins.m_before;
+ LayoutUnit& marginAfterAlias = computedValues.m_margins.m_after;
Length logicalTop = style()->logicalTop();
Length logicalBottom = style()->logicalBottom();
@@ -3316,8 +3328,8 @@ void RenderBox::computePositionedLogicalHeightReplaced()
// NOTE: This value of height is FINAL in that the min/max height calculations
// are dealt with in computeReplacedHeight(). This means that the steps to produce
// correct max/min in the non-replaced version, are not necessary.
- setLogicalHeight(computeReplacedLogicalHeight() + borderAndPaddingLogicalHeight());
- const LayoutUnit availableSpace = containerLogicalHeight - logicalHeight();
+ computedValues.m_extent = computeReplacedLogicalHeight() + borderAndPaddingLogicalHeight();
+ const LayoutUnit availableSpace = containerLogicalHeight - computedValues.m_extent;
/*-----------------------------------------------------------------------*\
* 2. If both 'top' and 'bottom' have the value 'auto', replace 'top'
@@ -3411,8 +3423,8 @@ void RenderBox::computePositionedLogicalHeightReplaced()
// Use computed values to calculate the vertical position.
LayoutUnit logicalTopPos = logicalTopValue + marginBeforeAlias;
- computeLogicalTopPositionedOffset(logicalTopPos, this, logicalHeight(), containerBlock, containerLogicalHeight);
- setLogicalTop(logicalTopPos.round());
+ computeLogicalTopPositionedOffset(logicalTopPos, this, computedValues.m_extent, containerBlock, containerLogicalHeight);
+ computedValues.m_position = logicalTopPos.round();
}
LayoutRect RenderBox::localCaretRect(InlineBox* box, int caretOffset, LayoutUnit* extraWidthToEndOfLine)