diff options
| author | Simon Hausmann <simon.hausmann@nokia.com> | 2012-02-03 09:55:33 +0100 |
|---|---|---|
| committer | Simon Hausmann <simon.hausmann@nokia.com> | 2012-02-03 09:55:33 +0100 |
| commit | cd44dc59cdfc39534aef4d417e9f3c412e3be139 (patch) | |
| tree | 8d89889ba95ed6ec9322e733846cc9cce9d7dff1 /Source/WebCore/rendering/RenderBox.cpp | |
| parent | d11f84f5b5cdc0d92a08af01b13472fdd5f9acb9 (diff) | |
| download | qtwebkit-cd44dc59cdfc39534aef4d417e9f3c412e3be139.tar.gz | |
Imported WebKit commit fce473cb4d55aa9fe9d0b0322a2fffecb731b961 (http://svn.webkit.org/repository/webkit/trunk@106560)
Diffstat (limited to 'Source/WebCore/rendering/RenderBox.cpp')
| -rw-r--r-- | Source/WebCore/rendering/RenderBox.cpp | 213 |
1 files changed, 104 insertions, 109 deletions
diff --git a/Source/WebCore/rendering/RenderBox.cpp b/Source/WebCore/rendering/RenderBox.cpp index 506105636..63fd6f807 100644 --- a/Source/WebCore/rendering/RenderBox.cpp +++ b/Source/WebCore/rendering/RenderBox.cpp @@ -42,6 +42,7 @@ #include "PaintInfo.h" #include "RenderArena.h" #include "RenderBoxRegionInfo.h" +#include "RenderFlexibleBox.h" #include "RenderFlowThread.h" #include "RenderInline.h" #include "RenderLayer.h" @@ -248,12 +249,13 @@ void RenderBox::willBeDestroyed() { clearOverrideSize(); - if (style() && (style()->logicalHeight().isPercent() || style()->logicalMinHeight().isPercent() || style()->logicalMaxHeight().isPercent())) + RenderStyle* styleToUse = style(); + 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 (style() && style()->hasPseudoStyle(SCROLLBAR) && frame() && frame()->view()) + if (styleToUse && styleToUse->hasPseudoStyle(SCROLLBAR) && frame() && frame()->view()) frame()->view()->clearOwningRendererForCustomScrollbars(this); // If the following assertion fails, logicalHeight()/logicalMinHeight()/ @@ -286,6 +288,7 @@ void RenderBox::removeFloatingOrPositionedChildFromBlockLists() if (parent && parent->isDeprecatedFlexibleBox()) parentBlock = toRenderBlock(parent); + parentBlock->markSiblingsWithFloatsForLayout(this); parentBlock->markAllDescendantsWithFloatsForLayout(this, false); } } @@ -302,7 +305,8 @@ void RenderBox::styleWillChange(StyleDifference diff, const RenderStyle* newStyl { s_hadOverflowClip = hasOverflowClip(); - if (style()) { + RenderStyle* oldStyle = style(); + if (oldStyle) { // The background of the root element or the body element could propagate up to // the canvas. Just dirty the entire canvas when our style changes substantially. if (diff >= StyleDifferenceRepaint && node() && @@ -311,13 +315,13 @@ void RenderBox::styleWillChange(StyleDifference diff, const RenderStyle* newStyl // When a layout hint happens and an object's position style changes, we have to do a layout // to dirty the render tree using the old position value now. - if (diff == StyleDifferenceLayout && parent() && style()->position() != newStyle->position()) { + if (diff == StyleDifferenceLayout && parent() && oldStyle->position() != newStyle->position()) { markContainingBlocksForLayout(); - if (style()->position() == StaticPosition) + if (oldStyle->position() == StaticPosition) repaint(); - else if (newStyle->position() == AbsolutePosition || newStyle->position() == FixedPosition) + else if (newStyle->isPositioned()) parent()->setChildNeedsLayout(true); - if (isFloating() && !isPositioned() && (newStyle->position() == AbsolutePosition || newStyle->position() == FixedPosition)) + if (isFloating() && !isPositioned() && newStyle->isPositioned()) removeFloatingOrPositionedChildFromBlockLists(); } } else if (newStyle && isBody()) @@ -325,7 +329,7 @@ void RenderBox::styleWillChange(StyleDifference diff, const RenderStyle* newStyl if (FrameView *frameView = view()->frameView()) { bool newStyleIsFixed = newStyle && newStyle->position() == FixedPosition; - bool oldStyleIsFixed = style() && style()->position() == FixedPosition; + bool oldStyleIsFixed = oldStyle && oldStyle->position() == FixedPosition; if (newStyleIsFixed != oldStyleIsFixed) { if (newStyleIsFixed) frameView->addFixedObject(); @@ -341,6 +345,7 @@ void RenderBox::styleDidChange(StyleDifference diff, const RenderStyle* oldStyle { RenderBoxModelObject::styleDidChange(diff, oldStyle); + RenderStyle* newStyle = style(); if (needsLayout() && oldStyle) { if (oldStyle && (oldStyle->logicalHeight().isPercent() || oldStyle->logicalMinHeight().isPercent() || oldStyle->logicalMaxHeight().isPercent())) RenderBlock::removePercentHeightDescendant(this); @@ -348,20 +353,20 @@ void RenderBox::styleDidChange(StyleDifference diff, const RenderStyle* oldStyle // Normally we can do optimized positioning layout for absolute/fixed positioned objects. There is one special case, however, which is // when the positioned object's margin-before is changed. In this case the parent has to get a layout in order to run margin collapsing // to determine the new static position. - if (isPositioned() && style()->hasStaticBlockPosition(isHorizontalWritingMode()) && oldStyle->marginBefore() != style()->marginBefore() + if (isPositioned() && newStyle->hasStaticBlockPosition(isHorizontalWritingMode()) && oldStyle->marginBefore() != newStyle->marginBefore() && parent() && !parent()->normalChildNeedsLayout()) parent()->setChildNeedsLayout(true); } // If our zoom factor changes and we have a defined scrollLeft/Top, we need to adjust that value into the // new zoomed coordinate space. - if (hasOverflowClip() && oldStyle && style() && oldStyle->effectiveZoom() != style()->effectiveZoom()) { + if (hasOverflowClip() && oldStyle && newStyle && oldStyle->effectiveZoom() != newStyle->effectiveZoom()) { if (int left = layer()->scrollXOffset()) { - left = (left / oldStyle->effectiveZoom()) * style()->effectiveZoom(); + left = (left / oldStyle->effectiveZoom()) * newStyle->effectiveZoom(); layer()->scrollToXOffset(left); } if (int top = layer()->scrollYOffset()) { - top = (top / oldStyle->effectiveZoom()) * style()->effectiveZoom(); + top = (top / oldStyle->effectiveZoom()) * newStyle->effectiveZoom(); layer()->scrollToYOffset(top); } } @@ -371,25 +376,25 @@ void RenderBox::styleDidChange(StyleDifference diff, const RenderStyle* oldStyle // Set the text color if we're the body. if (isBodyRenderer) - document()->setTextColor(style()->visitedDependentColor(CSSPropertyColor)); + document()->setTextColor(newStyle->visitedDependentColor(CSSPropertyColor)); if (isRootRenderer || isBodyRenderer) { // Propagate the new writing mode and direction up to the RenderView. RenderView* viewRenderer = view(); RenderStyle* viewStyle = viewRenderer->style(); - if (viewStyle->direction() != style()->direction() && (isRootRenderer || !document()->directionSetOnDocumentElement())) { - viewStyle->setDirection(style()->direction()); + if (viewStyle->direction() != newStyle->direction() && (isRootRenderer || !document()->directionSetOnDocumentElement())) { + viewStyle->setDirection(newStyle->direction()); if (isBodyRenderer) - document()->documentElement()->renderer()->style()->setDirection(style()->direction()); + document()->documentElement()->renderer()->style()->setDirection(newStyle->direction()); setNeedsLayoutAndPrefWidthsRecalc(); } - if (viewStyle->writingMode() != style()->writingMode() && (isRootRenderer || !document()->writingModeSetOnDocumentElement())) { - viewStyle->setWritingMode(style()->writingMode()); - viewRenderer->setHorizontalWritingMode(style()->isHorizontalWritingMode()); + if (viewStyle->writingMode() != newStyle->writingMode() && (isRootRenderer || !document()->writingModeSetOnDocumentElement())) { + viewStyle->setWritingMode(newStyle->writingMode()); + viewRenderer->setHorizontalWritingMode(newStyle->isHorizontalWritingMode()); if (isBodyRenderer) { - document()->documentElement()->renderer()->style()->setWritingMode(style()->writingMode()); - document()->documentElement()->renderer()->setHorizontalWritingMode(style()->isHorizontalWritingMode()); + document()->documentElement()->renderer()->style()->setWritingMode(newStyle->writingMode()); + document()->documentElement()->renderer()->setHorizontalWritingMode(newStyle->isHorizontalWritingMode()); } setNeedsLayoutAndPrefWidthsRecalc(); } @@ -402,6 +407,7 @@ void RenderBox::updateBoxModelInfoFromStyle() { RenderBoxModelObject::updateBoxModelInfoFromStyle(); + RenderStyle* styleToUse = style(); bool isRootObject = isRoot(); bool isViewObject = isRenderView(); @@ -409,11 +415,11 @@ void RenderBox::updateBoxModelInfoFromStyle() if (isRootObject || isViewObject) setHasBoxDecorations(true); - setPositioned(style()->position() == AbsolutePosition || style()->position() == FixedPosition); - setFloating(style()->isFloating() && (!isPositioned() || style()->floating() == PositionedFloat)); + setPositioned(styleToUse->isPositioned()); + setFloating(styleToUse->isFloating() && (!isPositioned() || styleToUse->floating() == PositionedFloat)); // We also handle <body> and <html>, whose overflow applies to the viewport. - if (style()->overflowX() != OVISIBLE && !isRootObject && (isRenderBlock() || isTableRow() || isTableSection())) { + if (styleToUse->overflowX() != OVISIBLE && !isRootObject && (isRenderBlock() || isTableRow() || isTableSection())) { bool boxHasOverflowClip = true; if (isBody()) { // Overflow on the body can propagate to the viewport under the following conditions. @@ -436,8 +442,8 @@ void RenderBox::updateBoxModelInfoFromStyle() } } - setHasTransform(style()->hasTransformRelatedProperty()); - setHasReflection(style()->boxReflect()); + setHasTransform(styleToUse->hasTransformRelatedProperty()); + setHasReflection(styleToUse->boxReflect()); } void RenderBox::layout() @@ -628,9 +634,9 @@ LayoutRect RenderBox::reflectedRect(const LayoutRect& r) const return result; } -bool RenderBox::shouldLayoutFixedElementRelativeToFrame(Frame* frame, FrameView* frameView) const +bool RenderBox::fixedElementLaysOutRelativeToFrame(Frame* frame, FrameView* frameView) const { - return style() && style()->position() == FixedPosition && container()->isRenderView() && frame && frameView && frameView->shouldLayoutFixedElementsRelativeToFrame(); + return style() && style()->position() == FixedPosition && container()->isRenderView() && frame && frameView && frameView->fixedElementsLayoutRelativeToFrame(); } bool RenderBox::includeVerticalScrollbarSize() const @@ -941,9 +947,11 @@ void RenderBox::paintBackground(const PaintInfo& paintInfo, const LayoutRect& pa { if (isRoot()) paintRootBoxFillLayers(paintInfo); - else if (!isBody() || (document()->documentElement()->renderer() && document()->documentElement()->renderer()->hasBackground())) { - // The <body> only paints its background if the root element has defined a background - // independent of the body. + else if (!isBody() + || (document()->documentElement()->renderer() && document()->documentElement()->renderer()->hasBackground()) + || (document()->documentElement()->renderer() != parent())) { + // The <body> only paints its background if the root element has defined a background independent of the body, + // or if the <body>'s parent is not the document element's renderer (e.g. inside SVG foreignObject). if (!backgroundIsObscured()) paintFillLayers(paintInfo, style()->visitedDependentColor(CSSPropertyBackgroundColor), style()->backgroundLayers(), paintRect, bleedAvoidance); } @@ -973,11 +981,7 @@ void RenderBox::paintMaskImages(const PaintInfo& paintInfo, const LayoutRect& pa bool allMaskImagesLoaded = true; if (!compositedMask) { - // If the context has a rotation, scale or skew, then use a transparency layer to avoid - // pixel cruft around the edge of the mask. - const AffineTransform& currentCTM = paintInfo.context->getCTM(); - pushTransparencyLayer = !currentCTM.isIdentityOrTranslationOrFlipped(); - + pushTransparencyLayer = true; StyleImage* maskBoxImage = style()->maskBoxImage().image(); const FillLayer* maskLayers = style()->maskLayers(); @@ -988,37 +992,9 @@ void RenderBox::paintMaskImages(const PaintInfo& paintInfo, const LayoutRect& pa if (maskLayers) allMaskImagesLoaded &= maskLayers->imagesAreLoaded(); - // Before all images have loaded, just use an empty transparency layer as the mask. - if (!allMaskImagesLoaded) - pushTransparencyLayer = true; - - bool hasMaskLayerWithImage = maskLayers->hasImage(); - if (maskBoxImage && hasMaskLayerWithImage) { - // We have a mask-box-image and mask-image, so need to composite them together before using the result as a mask. - pushTransparencyLayer = true; - } else if (hasMaskLayerWithImage) { - // We have to use an extra image buffer to hold the mask. Multiple mask images need - // to composite together using source-over so that they can then combine into a single unified mask that - // can be composited with the content using destination-in. SVG images need to be able to set compositing modes - // as they draw images contained inside their sub-document, so we paint all our images into a separate buffer - // and composite that buffer as the mask. - // We have to check that the mask images to be rendered contain at least one image that can be actually used in rendering - // before pushing the transparency layer. - for (const FillLayer* fillLayer = maskLayers->next(); fillLayer; fillLayer = fillLayer->next()) { - if (fillLayer->image() && fillLayer->image()->canRender(this, style()->effectiveZoom())) { - pushTransparencyLayer = true; - // We found one image that can be used in rendering, exit the loop - break; - } - } - } - - compositeOp = CompositeDestinationIn; - if (pushTransparencyLayer) { - paintInfo.context->setCompositeOperation(CompositeDestinationIn); - paintInfo.context->beginTransparencyLayer(1.0f); - compositeOp = CompositeSourceOver; - } + paintInfo.context->setCompositeOperation(CompositeDestinationIn); + paintInfo.context->beginTransparencyLayer(1); + compositeOp = CompositeSourceOver; } if (allMaskImagesLoaded) { @@ -1397,7 +1373,7 @@ LayoutSize RenderBox::offsetFromContainer(RenderObject* o, const LayoutPoint& po offset += relativePositionOffset(); if (!isInline() || isReplaced()) { - if (style()->position() != AbsolutePosition && style()->position() != FixedPosition && o->hasColumns()) { + if (!style()->isPositioned() && o->hasColumns()) { RenderBlock* block = toRenderBlock(o); LayoutRect columnRect(frameRect()); block->adjustStartEdgeForWritingModeIncludingColumns(columnRect); @@ -1518,15 +1494,16 @@ void RenderBox::computeRectForRepaint(RenderBoxModelObject* repaintContainer, La // RenderView::computeRectForRepaint then converts the rect to physical coordinates. We also convert to // physical when we hit a repaintContainer boundary. Therefore the final rect returned is always in the // physical coordinate space of the repaintContainer. + RenderStyle* styleToUse = style(); if (RenderView* v = view()) { // LayoutState is only valid for root-relative, non-fixed position repainting - if (v->layoutStateEnabled() && !repaintContainer && style()->position() != FixedPosition) { + if (v->layoutStateEnabled() && !repaintContainer && styleToUse->position() != FixedPosition) { LayoutState* layoutState = v->layoutState(); if (layer() && layer()->transform()) rect = layer()->transform()->mapRect(rect); - if (style()->position() == RelativePosition && layer()) + if (styleToUse->position() == RelativePosition && layer()) rect.move(layer()->relativePositionOffset()); rect.moveBy(location()); @@ -1555,12 +1532,12 @@ void RenderBox::computeRectForRepaint(RenderBoxModelObject* repaintContainer, La flipForWritingMode(rect); #if ENABLE(CSS_FILTERS) - if (style()->hasFilterOutsets()) { + if (styleToUse->hasFilterOutsets()) { LayoutUnit topOutset; LayoutUnit rightOutset; LayoutUnit bottomOutset; LayoutUnit leftOutset; - style()->filter().getOutsets(topOutset, rightOutset, bottomOutset, leftOutset); + styleToUse->filter().getOutsets(topOutset, rightOutset, bottomOutset, leftOutset); rect.move(-leftOutset, -topOutset); rect.expand(leftOutset + rightOutset, topOutset + bottomOutset); } @@ -1569,7 +1546,7 @@ void RenderBox::computeRectForRepaint(RenderBoxModelObject* repaintContainer, La LayoutPoint topLeft = rect.location(); topLeft.move(x(), y()); - EPosition position = style()->position(); + EPosition position = styleToUse->position(); // We are now in our parent container's coordinate space. Apply our transform to obtain a bounding box // in the parent's coordinate space that encloses us. @@ -1680,7 +1657,8 @@ void RenderBox::computeLogicalWidthInRegion(RenderRegion* region, LayoutUnit off bool stretching = (parent()->style()->boxAlign() == BSTRETCH); bool treatAsReplaced = shouldComputeSizeAsReplaced() && (!inVerticalBox || !stretching); - Length logicalWidthLength = (treatAsReplaced) ? Length(computeReplacedLogicalWidth(), Fixed) : style()->logicalWidth(); + RenderStyle* styleToUse = style(); + Length logicalWidthLength = (treatAsReplaced) ? Length(computeReplacedLogicalWidth(), Fixed) : styleToUse->logicalWidth(); RenderBlock* cb = containingBlock(); LayoutUnit containerLogicalWidth = max<LayoutUnit>(0, containingBlockLogicalWidthForContentInRegion(region, offsetFromLogicalTopOfFirstPage)); @@ -1691,8 +1669,8 @@ void RenderBox::computeLogicalWidthInRegion(RenderRegion* region, LayoutUnit off if (isInline() && !isInlineBlockOrInlineTable()) { // just calculate margins - setMarginStart(style()->marginStart().calcMinValue(containerLogicalWidth)); - setMarginEnd(style()->marginEnd().calcMinValue(containerLogicalWidth)); + setMarginStart(styleToUse->marginStart().calcMinValue(containerLogicalWidth)); + setMarginEnd(styleToUse->marginEnd().calcMinValue(containerLogicalWidth)); if (treatAsReplaced) setLogicalWidth(max<LayoutUnit>(logicalWidthLength.calcFloatValue(0) + borderAndPaddingLogicalWidth(), minPreferredLogicalWidth())); return; @@ -1706,11 +1684,11 @@ void RenderBox::computeLogicalWidthInRegion(RenderRegion* region, LayoutUnit off setLogicalWidth(computeLogicalWidthUsing(LogicalWidth, containerWidthInInlineDirection)); // Calculate MaxLogicalWidth - if (!style()->logicalMaxWidth().isUndefined()) { + if (!styleToUse->logicalMaxWidth().isUndefined()) { LayoutUnit maxLogicalWidth = computeLogicalWidthUsing(MaxLogicalWidth, containerWidthInInlineDirection); if (logicalWidth() > maxLogicalWidth) { setLogicalWidth(maxLogicalWidth); - logicalWidthLength = style()->logicalMaxWidth(); + logicalWidthLength = styleToUse->logicalMaxWidth(); } } @@ -1718,7 +1696,7 @@ void RenderBox::computeLogicalWidthInRegion(RenderRegion* region, LayoutUnit off LayoutUnit minLogicalWidth = computeLogicalWidthUsing(MinLogicalWidth, containerWidthInInlineDirection); if (logicalWidth() < minLogicalWidth) { setLogicalWidth(minLogicalWidth); - logicalWidthLength = style()->logicalMinWidth(); + logicalWidthLength = styleToUse->logicalMinWidth(); } } @@ -1730,8 +1708,8 @@ void RenderBox::computeLogicalWidthInRegion(RenderRegion* region, LayoutUnit off // Margin calculations. if (logicalWidthLength.isAuto() || hasPerpendicularContainingBlock) { - setMarginStart(style()->marginStart().calcMinValue(containerLogicalWidth)); - setMarginEnd(style()->marginEnd().calcMinValue(containerLogicalWidth)); + setMarginStart(styleToUse->marginStart().calcMinValue(containerLogicalWidth)); + setMarginEnd(styleToUse->marginEnd().calcMinValue(containerLogicalWidth)); } else computeInlineDirectionMargins(cb, containerLogicalWidth, logicalWidth()); @@ -1743,17 +1721,18 @@ void RenderBox::computeLogicalWidthInRegion(RenderRegion* region, LayoutUnit off LayoutUnit RenderBox::computeLogicalWidthUsing(LogicalWidthType widthType, LayoutUnit availableLogicalWidth) { LayoutUnit logicalWidthResult = logicalWidth(); + RenderStyle* styleToUse = style(); Length logicalWidth; if (widthType == LogicalWidth) - logicalWidth = style()->logicalWidth(); + logicalWidth = styleToUse->logicalWidth(); else if (widthType == MinLogicalWidth) - logicalWidth = style()->logicalMinWidth(); + logicalWidth = styleToUse->logicalMinWidth(); else - logicalWidth = style()->logicalMaxWidth(); + logicalWidth = styleToUse->logicalMaxWidth(); if (logicalWidth.isIntrinsicOrAuto()) { - LayoutUnit marginStart = style()->marginStart().calcMinValue(availableLogicalWidth); - LayoutUnit marginEnd = style()->marginEnd().calcMinValue(availableLogicalWidth); + LayoutUnit marginStart = styleToUse->marginStart().calcMinValue(availableLogicalWidth); + LayoutUnit marginEnd = styleToUse->marginEnd().calcMinValue(availableLogicalWidth); logicalWidthResult = availableLogicalWidth - marginStart - marginEnd; if (sizesToIntrinsicLogicalWidth(widthType)) { @@ -1793,8 +1772,13 @@ bool RenderBox::sizesToIntrinsicLogicalWidth(LogicalWidthType widthType) const // Flexible box items should shrink wrap, so we lay them out at their intrinsic widths. // In the case of columns that have a stretch alignment, we go ahead and layout at the // stretched size to avoid an extra layout when applying alignment. - if (parent()->isFlexibleBox() && (!parent()->style()->isColumnFlexDirection() || style()->flexItemAlign() != AlignStretch)) - return true; + if (parent()->isFlexibleBox()) { + if (!parent()->style()->isColumnFlexDirection()) + return true; + EFlexAlign itemAlign = style()->flexItemAlign(); + if (itemAlign != AlignStretch && (itemAlign != AlignAuto || parent()->style()->flexAlign() != AlignStretch)) + return true; + } // Flexible horizontal boxes lay out children at their intrinsic widths. Also vertical boxes // that don't stretch their kids lay out their children at their intrinsic widths. @@ -1981,12 +1965,13 @@ void RenderBox::computeLogicalHeight() // grab our cached flexible height. // FIXME: Account for block-flow in flexible boxes. // https://bugs.webkit.org/show_bug.cgi?id=46418 + RenderStyle* styleToUse = style(); if (hasOverrideHeight() && parent()->isFlexibleBoxIncludingDeprecated()) h = Length(overrideHeight() - borderAndPaddingLogicalHeight(), Fixed); else if (treatAsReplaced) h = Length(computeReplacedLogicalHeight(), Fixed); else { - h = style()->logicalHeight(); + h = styleToUse->logicalHeight(); checkMinMaxHeight = true; } @@ -2001,12 +1986,12 @@ void RenderBox::computeLogicalHeight() LayoutUnit heightResult; if (checkMinMaxHeight) { - heightResult = computeLogicalHeightUsing(style()->logicalHeight()); + heightResult = computeLogicalHeightUsing(styleToUse->logicalHeight()); // FIXME: Use < 0 or roughlyEquals when we move to float, see https://bugs.webkit.org/show_bug.cgi?id=66148 if (heightResult == -1) heightResult = logicalHeight(); - LayoutUnit minH = computeLogicalHeightUsing(style()->logicalMinHeight()); // Leave as -1 if unset. - LayoutUnit maxH = style()->logicalMaxHeight().isUndefined() ? heightResult : computeLogicalHeightUsing(style()->logicalMaxHeight()); + LayoutUnit minH = computeLogicalHeightUsing(styleToUse->logicalMinHeight()); // Leave as -1 if unset. + LayoutUnit maxH = styleToUse->logicalMaxHeight().isUndefined() ? heightResult : computeLogicalHeightUsing(styleToUse->logicalMaxHeight()); if (maxH == -1) maxH = heightResult; heightResult = min(maxH, heightResult); @@ -2089,11 +2074,13 @@ LayoutUnit RenderBox::computePercentageLogicalHeight(const Length& height) cb->addPercentHeightDescendant(this); } + RenderStyle* cbstyle = cb->style(); + // A positioned element that specified both top/bottom or that specifies height should be treated as though it has a height // explicitly specified that can be used for any percentage computations. // FIXME: We can't just check top/bottom here. // https://bugs.webkit.org/show_bug.cgi?id=46500 - bool isPositionedWithSpecifiedHeight = cb->isPositioned() && (!cb->style()->logicalHeight().isAuto() || (!cb->style()->top().isAuto() && !cb->style()->bottom().isAuto())); + bool isPositionedWithSpecifiedHeight = cb->isPositioned() && (!cbstyle->logicalHeight().isAuto() || (!cbstyle->top().isAuto() && !cbstyle->bottom().isAuto())); bool includeBorderPadding = isTable(); @@ -2121,11 +2108,11 @@ LayoutUnit RenderBox::computePercentageLogicalHeight(const Length& height) } // Otherwise we only use our percentage height if our containing block had a specified // height. - else if (cb->style()->logicalHeight().isFixed()) - result = cb->computeContentBoxLogicalHeight(cb->style()->logicalHeight().value()); - else if (cb->style()->logicalHeight().isPercent() && !isPositionedWithSpecifiedHeight) { + else if (cbstyle->logicalHeight().isFixed()) + result = cb->computeContentBoxLogicalHeight(cbstyle->logicalHeight().value()); + else if (cbstyle->logicalHeight().isPercent() && !isPositionedWithSpecifiedHeight) { // We need to recur and compute the percentage height for our containing block. - result = cb->computePercentageLogicalHeight(cb->style()->logicalHeight()); + result = cb->computePercentageLogicalHeight(cbstyle->logicalHeight()); // FIXME: Use < 0 or roughlyEquals when we move to float, see https://bugs.webkit.org/show_bug.cgi?id=66148 if (result != -1) result = cb->computeContentBoxLogicalHeight(result); @@ -2323,7 +2310,7 @@ LayoutUnit RenderBox::containingBlockLogicalWidthForPositioned(const RenderBoxMo // Container for position:fixed is the frame. Frame* frame = view() ? view()->frame(): 0; FrameView* frameView = view() ? view()->frameView() : 0; - if (shouldLayoutFixedElementRelativeToFrame(frame, frameView)) + if (fixedElementLaysOutRelativeToFrame(frame, frameView)) return (view()->isHorizontalWritingMode() ? frameView->visibleWidth() : frameView->visibleHeight()) / frame->frameScaleFactor(); if (checkForPerpendicularWritingMode && containingBlock->isHorizontalWritingMode() != isHorizontalWritingMode()) @@ -2380,7 +2367,7 @@ LayoutUnit RenderBox::containingBlockLogicalHeightForPositioned(const RenderBoxM { Frame* frame = view() ? view()->frame(): 0; FrameView* frameView = view() ? view()->frameView() : 0; - if (shouldLayoutFixedElementRelativeToFrame(frame, frameView)) + if (fixedElementLaysOutRelativeToFrame(frame, frameView)) return (view()->isHorizontalWritingMode() ? frameView->visibleHeight() : frameView->visibleWidth()) / frame->frameScaleFactor(); if (checkForPerpendicularWritingMode && containingBlock->isHorizontalWritingMode() != isHorizontalWritingMode()) @@ -2832,15 +2819,16 @@ void RenderBox::computePositionedLogicalHeight() const LayoutUnit containerLogicalHeight = containingBlockLogicalHeightForPositioned(containerBlock); bool isHorizontal = isHorizontalWritingMode(); - bool isFlipped = style()->isFlippedBlocksWritingMode(); + RenderStyle* styleToUse = style(); + bool isFlipped = styleToUse->isFlippedBlocksWritingMode(); const LayoutUnit bordersPlusPadding = borderAndPaddingLogicalHeight(); - const Length marginBefore = style()->marginBefore(); - const Length marginAfter = style()->marginAfter(); + const Length marginBefore = styleToUse->marginBefore(); + const Length marginAfter = styleToUse->marginAfter(); LayoutUnit& marginBeforeAlias = isHorizontal ? (isFlipped ? m_marginBottom : m_marginTop) : (isFlipped ? m_marginRight: m_marginLeft); LayoutUnit& marginAfterAlias = isHorizontal ? (isFlipped ? m_marginTop : m_marginBottom) : (isFlipped ? m_marginLeft: m_marginRight); - Length logicalTopLength = style()->logicalTop(); - Length logicalBottomLength = style()->logicalBottom(); + Length logicalTopLength = styleToUse->logicalTop(); + Length logicalBottomLength = styleToUse->logicalBottom(); /*---------------------------------------------------------------------------*\ * For the purposes of this section and the next, the term "static position" @@ -2867,7 +2855,7 @@ void RenderBox::computePositionedLogicalHeight() LayoutUnit logicalTopPos; // Calculate constraint equation values for 'height' case. - computePositionedLogicalHeightUsing(style()->logicalHeight(), containerBlock, containerLogicalHeight, bordersPlusPadding, + computePositionedLogicalHeightUsing(styleToUse->logicalHeight(), containerBlock, containerLogicalHeight, bordersPlusPadding, logicalTopLength, logicalBottomLength, marginBefore, marginAfter, logicalHeightResult, marginBeforeAlias, marginAfterAlias, logicalTopPos); setLogicalTop(logicalTopPos); @@ -2876,13 +2864,13 @@ void RenderBox::computePositionedLogicalHeight() // see FIXME 2 // Calculate constraint equation values for 'max-height' case. - if (!style()->logicalMaxHeight().isUndefined()) { + if (!styleToUse->logicalMaxHeight().isUndefined()) { LayoutUnit maxLogicalHeight; LayoutUnit maxMarginBefore; LayoutUnit maxMarginAfter; LayoutUnit maxLogicalTopPos; - computePositionedLogicalHeightUsing(style()->logicalMaxHeight(), containerBlock, containerLogicalHeight, bordersPlusPadding, + computePositionedLogicalHeightUsing(styleToUse->logicalMaxHeight(), containerBlock, containerLogicalHeight, bordersPlusPadding, logicalTopLength, logicalBottomLength, marginBefore, marginAfter, maxLogicalHeight, maxMarginBefore, maxMarginAfter, maxLogicalTopPos); @@ -2895,13 +2883,13 @@ void RenderBox::computePositionedLogicalHeight() } // Calculate constraint equation values for 'min-height' case. - if (!style()->logicalMinHeight().isZero()) { + if (!styleToUse->logicalMinHeight().isZero()) { LayoutUnit minLogicalHeight; LayoutUnit minMarginBefore; LayoutUnit minMarginAfter; LayoutUnit minLogicalTopPos; - computePositionedLogicalHeightUsing(style()->logicalMinHeight(), containerBlock, containerLogicalHeight, bordersPlusPadding, + computePositionedLogicalHeightUsing(styleToUse->logicalMinHeight(), containerBlock, containerLogicalHeight, bordersPlusPadding, logicalTopLength, logicalBottomLength, marginBefore, marginAfter, minLogicalHeight, minMarginBefore, minMarginAfter, minLogicalTopPos); @@ -3608,6 +3596,13 @@ void RenderBox::addLayoutOverflow(const LayoutRect& rect) // and vertical-lr/rl as the same. bool hasTopOverflow = !style()->isLeftToRightDirection() && !isHorizontalWritingMode(); bool hasLeftOverflow = !style()->isLeftToRightDirection() && isHorizontalWritingMode(); + if (isFlexibleBox() && style()->isReverseFlexDirection()) { + RenderFlexibleBox* flexibleBox = static_cast<RenderFlexibleBox*>(this); + if (flexibleBox->isHorizontalFlow()) + hasLeftOverflow = true; + else + hasTopOverflow = true; + } if (!hasTopOverflow) overflowRect.shiftYEdgeTo(max(overflowRect.y(), clientBox.y())); |
