diff options
Diffstat (limited to 'Source/WebCore/rendering/RenderReplaced.cpp')
-rw-r--r-- | Source/WebCore/rendering/RenderReplaced.cpp | 265 |
1 files changed, 156 insertions, 109 deletions
diff --git a/Source/WebCore/rendering/RenderReplaced.cpp b/Source/WebCore/rendering/RenderReplaced.cpp index 8481bd84f..2ce1b0960 100644 --- a/Source/WebCore/rendering/RenderReplaced.cpp +++ b/Source/WebCore/rendering/RenderReplaced.cpp @@ -24,15 +24,17 @@ #include "config.h" #include "RenderReplaced.h" +#include "FloatRoundedRect.h" #include "Frame.h" #include "GraphicsContext.h" +#include "HTMLElement.h" #include "InlineElementBox.h" #include "LayoutRepainter.h" -#include "Page.h" #include "RenderBlock.h" #include "RenderFlowThread.h" +#include "RenderImage.h" #include "RenderLayer.h" -#include "RenderRegion.h" +#include "RenderNamedFlowFragment.h" #include "RenderTheme.h" #include "RenderView.h" #include "VisiblePosition.h" @@ -43,22 +45,22 @@ namespace WebCore { const int cDefaultWidth = 300; const int cDefaultHeight = 150; -RenderReplaced::RenderReplaced(Element& element, PassRef<RenderStyle> style) - : RenderBox(element, std::move(style), RenderReplacedFlag) +RenderReplaced::RenderReplaced(Element& element, RenderStyle&& style) + : RenderBox(element, WTFMove(style), RenderReplacedFlag) , m_intrinsicSize(cDefaultWidth, cDefaultHeight) { setReplaced(true); } -RenderReplaced::RenderReplaced(Element& element, PassRef<RenderStyle> style, const LayoutSize& intrinsicSize) - : RenderBox(element, std::move(style), RenderReplacedFlag) +RenderReplaced::RenderReplaced(Element& element, RenderStyle&& style, const LayoutSize& intrinsicSize) + : RenderBox(element, WTFMove(style), RenderReplacedFlag) , m_intrinsicSize(intrinsicSize) { setReplaced(true); } -RenderReplaced::RenderReplaced(Document& document, PassRef<RenderStyle> style, const LayoutSize& intrinsicSize) - : RenderBox(document, std::move(style), RenderReplacedFlag) +RenderReplaced::RenderReplaced(Document& document, RenderStyle&& style, const LayoutSize& intrinsicSize) + : RenderBox(document, WTFMove(style), RenderReplacedFlag) , m_intrinsicSize(intrinsicSize) { setReplaced(true); @@ -70,8 +72,8 @@ RenderReplaced::~RenderReplaced() void RenderReplaced::willBeDestroyed() { - if (!documentBeingDestroyed() && parent()) - parent()->dirtyLinesFromChangedChild(this); + if (!renderTreeBeingDestroyed() && parent()) + parent()->dirtyLinesFromChangedChild(*this); RenderBox::willBeDestroyed(); } @@ -98,6 +100,18 @@ void RenderReplaced::layout() updateLogicalWidth(); updateLogicalHeight(); + // Now that we've calculated our preferred layout, we check to see + // if we should further constrain sizing to the intrinsic aspect ratio. + if (style().aspectRatioType() == AspectRatioFromIntrinsic && !m_intrinsicSize.isEmpty()) { + float aspectRatio = m_intrinsicSize.aspectRatio(); + LayoutSize frameSize = size(); + float frameAspectRatio = frameSize.aspectRatio(); + if (frameAspectRatio < aspectRatio) + setHeight(computeReplacedLogicalHeightRespectingMinMaxHeight(frameSize.height() * frameAspectRatio / aspectRatio)); + else if (frameAspectRatio > aspectRatio) + setWidth(computeReplacedLogicalWidthRespectingMinMaxWidth(frameSize.width() * aspectRatio / frameAspectRatio, ComputePreferred)); + } + clearOverflow(); addVisualEffectOverflow(); updateLayerTransform(); @@ -115,14 +129,22 @@ void RenderReplaced::intrinsicSizeChanged() setNeedsLayoutAndPrefWidthsRecalc(); } +bool RenderReplaced::shouldDrawSelectionTint() const +{ + return selectionState() != SelectionNone && !document().printing(); +} + void RenderReplaced::paint(PaintInfo& paintInfo, const LayoutPoint& paintOffset) { if (!shouldPaint(paintInfo, paintOffset)) return; - + +#ifndef NDEBUG + SetLayoutNeededForbiddenScope scope(this); +#endif LayoutPoint adjustedPaintOffset = paintOffset + location(); - if (hasBoxDecorations() && (paintInfo.phase == PaintPhaseForeground || paintInfo.phase == PaintPhaseSelection)) + if (hasVisibleBoxDecorations() && paintInfo.phase == PaintPhaseForeground) paintBoxDecorations(paintInfo, adjustedPaintOffset); if (paintInfo.phase == PaintPhaseMask) { @@ -131,16 +153,19 @@ void RenderReplaced::paint(PaintInfo& paintInfo, const LayoutPoint& paintOffset) } LayoutRect paintRect = LayoutRect(adjustedPaintOffset, size()); - if ((paintInfo.phase == PaintPhaseOutline || paintInfo.phase == PaintPhaseSelfOutline) && style().outlineWidth()) - paintOutline(paintInfo, paintRect); - - if (paintInfo.phase != PaintPhaseForeground && paintInfo.phase != PaintPhaseSelection && !canHaveChildren()) + if (paintInfo.phase == PaintPhaseOutline || paintInfo.phase == PaintPhaseSelfOutline) { + if (style().outlineWidth()) + paintOutline(paintInfo, paintRect); + return; + } + + if (paintInfo.phase != PaintPhaseForeground && paintInfo.phase != PaintPhaseSelection) return; if (!paintInfo.shouldPaintWithinRoot(*this)) return; - bool drawSelectionTint = selectionState() != SelectionNone && !document().printing(); + bool drawSelectionTint = shouldDrawSelectionTint(); if (paintInfo.phase == PaintPhaseSelection) { if (selectionState() == SelectionNone) return; @@ -155,10 +180,10 @@ void RenderReplaced::paint(PaintInfo& paintInfo, const LayoutPoint& paintOffset) completelyClippedOut = true; else { // Push a clip if we have a border radius, since we want to round the foreground content that gets painted. - paintInfo.context->save(); - RoundedRect roundedInnerRect = style().getRoundedInnerBorderFor(paintRect, - paddingTop() + borderTop(), paddingBottom() + borderBottom(), paddingLeft() + borderLeft(), paddingRight() + borderRight(), true, true); - clipRoundedInnerRect(paintInfo.context, paintRect, roundedInnerRect); + paintInfo.context().save(); + FloatRoundedRect roundedInnerRect = FloatRoundedRect(style().getRoundedInnerBorderFor(paintRect, + paddingTop() + borderTop(), paddingBottom() + borderBottom(), paddingLeft() + borderLeft(), paddingRight() + borderRight(), true, true)); + clipRoundedInnerRect(paintInfo.context(), paintRect, roundedInnerRect); } } @@ -166,7 +191,7 @@ void RenderReplaced::paint(PaintInfo& paintInfo, const LayoutPoint& paintOffset) paintReplaced(paintInfo, adjustedPaintOffset); if (style().hasBorderRadius()) - paintInfo.context->restore(); + paintInfo.context().restore(); } // The selection tint never gets clipped by border-radius rounding, since we want it to run right up to the edges of @@ -174,7 +199,7 @@ void RenderReplaced::paint(PaintInfo& paintInfo, const LayoutPoint& paintOffset) if (drawSelectionTint) { LayoutRect selectionPaintingRect = localSelectionRect(); selectionPaintingRect.moveBy(adjustedPaintOffset); - paintInfo.context->fillRect(pixelSnappedIntRect(selectionPaintingRect), selectionBackgroundColor(), style().colorSpace()); + paintInfo.context().fillRect(snappedIntRect(selectionPaintingRect), selectionBackgroundColor()); } } @@ -191,8 +216,9 @@ bool RenderReplaced::shouldPaint(PaintInfo& paintInfo, const LayoutPoint& paintO if (style().visibility() != VISIBLE) return false; + RenderNamedFlowFragment* namedFlowFragment = currentRenderNamedFlowFragment(); // Check our region range to make sure we need to be painting in this region. - if (paintInfo.renderRegion && !paintInfo.renderRegion->flowThread()->objectShouldPaintInFlowRegion(this, paintInfo.renderRegion)) + if (namedFlowFragment && !namedFlowFragment->flowThread()->objectShouldFragmentInFlowRegion(this, namedFlowFragment)) return false; LayoutPoint adjustedPaintOffset = paintOffset + location(); @@ -209,7 +235,6 @@ bool RenderReplaced::shouldPaint(PaintInfo& paintInfo, const LayoutPoint& paintO } LayoutRect localRepaintRect = paintInfo.rect; - localRepaintRect.inflate(maximalOutlineSize(paintInfo.phase)); if (adjustedPaintOffset.x() + visualOverflowRect().x() >= localRepaintRect.maxX() || adjustedPaintOffset.x() + visualOverflowRect().maxX() <= localRepaintRect.x()) return false; @@ -228,7 +253,7 @@ static inline RenderBlock* firstContainingBlockWithLogicalWidth(const RenderRepl if (!containingBlock) return 0; - for (; !containingBlock->isRenderView() && !containingBlock->isBody(); containingBlock = containingBlock->containingBlock()) { + for (; containingBlock && !is<RenderView>(*containingBlock) && !containingBlock->isBody(); containingBlock = containingBlock->containingBlock()) { if (containingBlock->style().logicalWidth().isSpecified()) return containingBlock; } @@ -258,28 +283,53 @@ bool RenderReplaced::hasReplacedLogicalHeight() const return true; } + if (style().logicalHeight().isIntrinsic()) + return true; + return false; } -void RenderReplaced::computeAspectRatioInformationForRenderBox(RenderBox* contentRenderer, FloatSize& constrainedSize, double& intrinsicRatio, bool& isPercentageIntrinsicSize) const +bool RenderReplaced::setNeedsLayoutIfNeededAfterIntrinsicSizeChange() +{ + setPreferredLogicalWidthsDirty(true); + + // If the actual area occupied by the image has changed and it is not constrained by style then a layout is required. + bool imageSizeIsConstrained = style().logicalWidth().isSpecified() && style().logicalHeight().isSpecified(); + + // FIXME: We only need to recompute the containing block's preferred size + // if the containing block's size depends on the image's size (i.e., the container uses shrink-to-fit sizing). + // There's no easy way to detect that shrink-to-fit is needed, always force a layout. + bool containingBlockNeedsToRecomputePreferredSize = + style().logicalWidth().isPercentOrCalculated() + || style().logicalMaxWidth().isPercentOrCalculated() + || style().logicalMinWidth().isPercentOrCalculated(); + + bool layoutSizeDependsOnIntrinsicSize = style().aspectRatioType() == AspectRatioFromIntrinsic; + + if (!imageSizeIsConstrained || containingBlockNeedsToRecomputePreferredSize || layoutSizeDependsOnIntrinsicSize) { + setNeedsLayout(); + return true; + } + + return false; +} + +void RenderReplaced::computeAspectRatioInformationForRenderBox(RenderBox* contentRenderer, FloatSize& constrainedSize, double& intrinsicRatio) const { FloatSize intrinsicSize; if (contentRenderer) { - contentRenderer->computeIntrinsicRatioInformation(intrinsicSize, intrinsicRatio, isPercentageIntrinsicSize); - if (intrinsicRatio) - ASSERT(!isPercentageIntrinsicSize); + contentRenderer->computeIntrinsicRatioInformation(intrinsicSize, intrinsicRatio); // Handle zoom & vertical writing modes here, as the embedded document doesn't know about them. - if (!isPercentageIntrinsicSize) - intrinsicSize.scale(style().effectiveZoom()); + intrinsicSize.scale(style().effectiveZoom()); + + if (is<RenderImage>(*this)) + intrinsicSize.scale(downcast<RenderImage>(*this).imageDevicePixelRatio()); - if (hasAspectRatio() && isPercentageIntrinsicSize) - intrinsicRatio = 1; - // Update our intrinsic size to match what the content renderer has computed, so that when we // constrain the size below, the correct intrinsic size will be obtained for comparison against // min and max widths. - if (intrinsicRatio && !isPercentageIntrinsicSize && !intrinsicSize.isEmpty()) + if (intrinsicRatio && !intrinsicSize.isEmpty()) m_intrinsicSize = LayoutSize(intrinsicSize); if (!isHorizontalWritingMode()) { @@ -288,12 +338,9 @@ void RenderReplaced::computeAspectRatioInformationForRenderBox(RenderBox* conten intrinsicSize = intrinsicSize.transposedSize(); } } else { - computeIntrinsicRatioInformation(intrinsicSize, intrinsicRatio, isPercentageIntrinsicSize); - if (intrinsicRatio) { - ASSERT(!isPercentageIntrinsicSize); - if (!intrinsicSize.isEmpty()) - m_intrinsicSize = LayoutSize(isHorizontalWritingMode() ? intrinsicSize : intrinsicSize.transposedSize()); - } + computeIntrinsicRatioInformation(intrinsicSize, intrinsicRatio); + if (intrinsicRatio && !intrinsicSize.isEmpty()) + m_intrinsicSize = LayoutSize(isHorizontalWritingMode() ? intrinsicSize : intrinsicSize.transposedSize()); } // Now constrain the intrinsic size along each axis according to minimum and maximum width/heights along the @@ -303,7 +350,7 @@ void RenderReplaced::computeAspectRatioInformationForRenderBox(RenderBox* conten // FIXME: In the long term, it might be better to just return this code more to the way it used to be before this // function was added, since all it has done is make the code more unclear. constrainedSize = intrinsicSize; - if (intrinsicRatio && !isPercentageIntrinsicSize && !intrinsicSize.isEmpty() && style().logicalWidth().isAuto() && style().logicalHeight().isAuto()) { + if (intrinsicRatio && !intrinsicSize.isEmpty() && style().logicalWidth().isAuto() && style().logicalHeight().isAuto()) { // We can't multiply or divide by 'intrinsicRatio' here, it breaks tests, like fast/images/zoomed-img-size.html, which // can only be fixed once subpixel precision is available for things like intrinsicWidth/Height - which include zoom! constrainedSize.setWidth(RenderBox::computeReplacedLogicalHeight() * intrinsicSize.width() / intrinsicSize.height()); @@ -314,12 +361,10 @@ void RenderReplaced::computeAspectRatioInformationForRenderBox(RenderBox* conten LayoutRect RenderReplaced::replacedContentRect(const LayoutSize& intrinsicSize) const { LayoutRect contentRect = contentBoxRect(); - ObjectFit objectFit = style().objectFit(); - if (objectFit == ObjectFitFill) + if (intrinsicSize.isEmpty()) return contentRect; - if (!intrinsicSize.width() || !intrinsicSize.height()) - return contentRect; + ObjectFit objectFit = style().objectFit(); LayoutRect finalRect = contentRect; switch (objectFit) { @@ -334,23 +379,23 @@ LayoutRect RenderReplaced::replacedContentRect(const LayoutSize& intrinsicSize) finalRect.setSize(intrinsicSize); break; case ObjectFitFill: - ASSERT_NOT_REACHED(); + break; } - // FIXME: This is where object-position should be taken into account, but since it's not - // implemented yet, assume the initial value of "50% 50%". - LayoutUnit xOffset = (contentRect.width() - finalRect.width()) / 2; - LayoutUnit yOffset = (contentRect.height() - finalRect.height()) / 2; + LengthPoint objectPosition = style().objectPosition(); + + LayoutUnit xOffset = minimumValueForLength(objectPosition.x(), contentRect.width() - finalRect.width()); + LayoutUnit yOffset = minimumValueForLength(objectPosition.y(), contentRect.height() - finalRect.height()); + finalRect.move(xOffset, yOffset); return finalRect; } -void RenderReplaced::computeIntrinsicRatioInformation(FloatSize& intrinsicSize, double& intrinsicRatio, bool& isPercentageIntrinsicSize) const +void RenderReplaced::computeIntrinsicRatioInformation(FloatSize& intrinsicSize, double& intrinsicRatio) const { // If there's an embeddedContentBox() of a remote, referenced document available, this code-path should never be used. ASSERT(!embeddedContentBox()); - isPercentageIntrinsicSize = false; intrinsicSize = FloatSize(intrinsicLogicalWidth(), intrinsicLogicalHeight()); // Figure out if we need to compute an intrinsic ratio. @@ -360,57 +405,66 @@ void RenderReplaced::computeIntrinsicRatioInformation(FloatSize& intrinsicSize, intrinsicRatio = intrinsicSize.width() / intrinsicSize.height(); } +LayoutUnit RenderReplaced::computeConstrainedLogicalWidth(ShouldComputePreferred shouldComputePreferred) const +{ + if (shouldComputePreferred == ComputePreferred) + return computeReplacedLogicalWidthRespectingMinMaxWidth(LayoutUnit(), ComputePreferred); + + // The aforementioned 'constraint equation' used for block-level, non-replaced + // elements in normal flow: + // 'margin-left' + 'border-left-width' + 'padding-left' + 'width' + + // 'padding-right' + 'border-right-width' + 'margin-right' = width of + // containing block + LayoutUnit logicalWidth = containingBlock()->availableLogicalWidth(); + + // This solves above equation for 'width' (== logicalWidth). + LayoutUnit marginStart = minimumValueForLength(style().marginStart(), logicalWidth); + LayoutUnit marginEnd = minimumValueForLength(style().marginEnd(), logicalWidth); + logicalWidth = std::max(LayoutUnit(), (logicalWidth - (marginStart + marginEnd + (size().width() - clientWidth())))); + return computeReplacedLogicalWidthRespectingMinMaxWidth(logicalWidth, shouldComputePreferred); +} + LayoutUnit RenderReplaced::computeReplacedLogicalWidth(ShouldComputePreferred shouldComputePreferred) const { if (style().logicalWidth().isSpecified() || style().logicalWidth().isIntrinsic()) - return computeReplacedLogicalWidthRespectingMinMaxWidth(computeReplacedLogicalWidthUsing(style().logicalWidth()), shouldComputePreferred); + return computeReplacedLogicalWidthRespectingMinMaxWidth(computeReplacedLogicalWidthUsing(MainOrPreferredSize, style().logicalWidth()), shouldComputePreferred); RenderBox* contentRenderer = embeddedContentBox(); // 10.3.2 Inline, replaced elements: http://www.w3.org/TR/CSS21/visudet.html#inline-replaced-width - bool isPercentageIntrinsicSize = false; double intrinsicRatio = 0; FloatSize constrainedSize; - computeAspectRatioInformationForRenderBox(contentRenderer, constrainedSize, intrinsicRatio, isPercentageIntrinsicSize); + computeAspectRatioInformationForRenderBox(contentRenderer, constrainedSize, intrinsicRatio); if (style().logicalWidth().isAuto()) { - bool heightIsAuto = style().logicalHeight().isAuto(); - bool hasIntrinsicWidth = !isPercentageIntrinsicSize && constrainedSize.width() > 0; + bool computedHeightIsAuto = style().logicalHeight().isAuto(); + bool hasIntrinsicWidth = constrainedSize.width() > 0; // If 'height' and 'width' both have computed values of 'auto' and the element also has an intrinsic width, then that intrinsic width is the used value of 'width'. - if (heightIsAuto && hasIntrinsicWidth) + if (computedHeightIsAuto && hasIntrinsicWidth) return computeReplacedLogicalWidthRespectingMinMaxWidth(constrainedSize.width(), shouldComputePreferred); - bool hasIntrinsicHeight = !isPercentageIntrinsicSize && constrainedSize.height() > 0; - if (intrinsicRatio || isPercentageIntrinsicSize) { + bool hasIntrinsicHeight = constrainedSize.height() > 0; + if (intrinsicRatio) { // If 'height' and 'width' both have computed values of 'auto' and the element has no intrinsic width, but does have an intrinsic height and intrinsic ratio; // or if 'width' has a computed value of 'auto', 'height' has some other computed value, and the element does have an intrinsic ratio; then the used value // of 'width' is: (used height) * (intrinsic ratio) - if (intrinsicRatio && ((heightIsAuto && !hasIntrinsicWidth && hasIntrinsicHeight) || !heightIsAuto)) { - LayoutUnit logicalHeight = computeReplacedLogicalHeight(); + if (intrinsicRatio && ((computedHeightIsAuto && !hasIntrinsicWidth && hasIntrinsicHeight) || !computedHeightIsAuto)) { + LayoutUnit estimatedUsedWidth = hasIntrinsicWidth ? LayoutUnit(constrainedSize.width()) : computeConstrainedLogicalWidth(shouldComputePreferred); + LayoutUnit logicalHeight = computeReplacedLogicalHeight(std::optional<LayoutUnit>(estimatedUsedWidth)); return computeReplacedLogicalWidthRespectingMinMaxWidth(roundToInt(round(logicalHeight * intrinsicRatio)), shouldComputePreferred); } - // If 'height' and 'width' both have computed values of 'auto' and the element has an intrinsic ratio but no intrinsic height or width, then the used value of - // 'width' is undefined in CSS 2.1. However, it is suggested that, if the containing block's width does not itself depend on the replaced element's width, then - // the used value of 'width' is calculated from the constraint equation used for block-level, non-replaced elements in normal flow. - if (heightIsAuto && !hasIntrinsicWidth && !hasIntrinsicHeight) { - // The aforementioned 'constraint equation' used for block-level, non-replaced elements in normal flow: - // 'margin-left' + 'border-left-width' + 'padding-left' + 'width' + 'padding-right' + 'border-right-width' + 'margin-right' = width of containing block - LayoutUnit logicalWidth; - if (RenderBlock* blockWithWidth = firstContainingBlockWithLogicalWidth(this)) - logicalWidth = blockWithWidth->computeReplacedLogicalWidthRespectingMinMaxWidth(blockWithWidth->computeReplacedLogicalWidthUsing(blockWithWidth->style().logicalWidth()), shouldComputePreferred); - else - logicalWidth = containingBlock()->availableLogicalWidth(); - - // This solves above equation for 'width' (== logicalWidth). - LayoutUnit marginStart = minimumValueForLength(style().marginStart(), logicalWidth); - LayoutUnit marginEnd = minimumValueForLength(style().marginEnd(), logicalWidth); - logicalWidth = std::max<LayoutUnit>(0, logicalWidth - (marginStart + marginEnd + (width() - clientWidth()))); - if (isPercentageIntrinsicSize) - logicalWidth = logicalWidth * constrainedSize.width() / 100; - return computeReplacedLogicalWidthRespectingMinMaxWidth(logicalWidth, shouldComputePreferred); - } + + // If 'height' and 'width' both have computed values of 'auto' and the + // element has an intrinsic ratio but no intrinsic height or width, then + // the used value of 'width' is undefined in CSS 2.1. However, it is + // suggested that, if the containing block's width does not itself depend + // on the replaced element's width, then the used value of 'width' is + // calculated from the constraint equation used for block-level, + // non-replaced elements in normal flow. + if (computedHeightIsAuto && !hasIntrinsicWidth && !hasIntrinsicHeight) + return computeConstrainedLogicalWidth(shouldComputePreferred); } // Otherwise, if 'width' has a computed value of 'auto', and the element has an intrinsic width, then that intrinsic width is the used value of 'width'. @@ -427,22 +481,21 @@ LayoutUnit RenderReplaced::computeReplacedLogicalWidth(ShouldComputePreferred sh return computeReplacedLogicalWidthRespectingMinMaxWidth(intrinsicLogicalWidth(), shouldComputePreferred); } -LayoutUnit RenderReplaced::computeReplacedLogicalHeight() const +LayoutUnit RenderReplaced::computeReplacedLogicalHeight(std::optional<LayoutUnit> estimatedUsedWidth) const { // 10.5 Content height: the 'height' property: http://www.w3.org/TR/CSS21/visudet.html#propdef-height if (hasReplacedLogicalHeight()) - return computeReplacedLogicalHeightRespectingMinMaxHeight(computeReplacedLogicalHeightUsing(style().logicalHeight())); + return computeReplacedLogicalHeightRespectingMinMaxHeight(computeReplacedLogicalHeightUsing(MainOrPreferredSize, style().logicalHeight())); RenderBox* contentRenderer = embeddedContentBox(); // 10.6.2 Inline, replaced elements: http://www.w3.org/TR/CSS21/visudet.html#inline-replaced-height - bool isPercentageIntrinsicSize = false; double intrinsicRatio = 0; FloatSize constrainedSize; - computeAspectRatioInformationForRenderBox(contentRenderer, constrainedSize, intrinsicRatio, isPercentageIntrinsicSize); + computeAspectRatioInformationForRenderBox(contentRenderer, constrainedSize, intrinsicRatio); bool widthIsAuto = style().logicalWidth().isAuto(); - bool hasIntrinsicHeight = !isPercentageIntrinsicSize && constrainedSize.height() > 0; + bool hasIntrinsicHeight = constrainedSize.height() > 0; // If 'height' and 'width' both have computed values of 'auto' and the element also has an intrinsic height, then that intrinsic height is the used value of 'height'. if (widthIsAuto && hasIntrinsicHeight) @@ -450,8 +503,10 @@ LayoutUnit RenderReplaced::computeReplacedLogicalHeight() const // Otherwise, if 'height' has a computed value of 'auto', and the element has an intrinsic ratio then the used value of 'height' is: // (used width) / (intrinsic ratio) - if (intrinsicRatio) - return computeReplacedLogicalHeightRespectingMinMaxHeight(roundToInt(round(availableLogicalWidth() / intrinsicRatio))); + if (intrinsicRatio) { + LayoutUnit usedWidth = estimatedUsedWidth ? estimatedUsedWidth.value() : availableLogicalWidth(); + return computeReplacedLogicalHeightRespectingMinMaxHeight(roundToInt(round(usedWidth / intrinsicRatio))); + } // Otherwise, if 'height' has a computed value of 'auto', and the element has an intrinsic height, then that intrinsic height is the used value of 'height'. if (hasIntrinsicHeight) @@ -473,13 +528,13 @@ void RenderReplaced::computePreferredLogicalWidths() // We cannot resolve any percent logical width here as the available logical // width may not be set on our containing block. - if (style().logicalWidth().isPercent()) + if (style().logicalWidth().isPercentOrCalculated()) computeIntrinsicLogicalWidths(m_minPreferredLogicalWidth, m_maxPreferredLogicalWidth); else m_minPreferredLogicalWidth = m_maxPreferredLogicalWidth = computeReplacedLogicalWidth(ComputePreferred); const RenderStyle& styleToUse = style(); - if (styleToUse.logicalWidth().isPercent() || styleToUse.logicalMaxWidth().isPercent() || hasRelativeIntrinsicLogicalWidth()) + if (styleToUse.logicalWidth().isPercentOrCalculated() || styleToUse.logicalMaxWidth().isPercentOrCalculated()) m_minPreferredLogicalWidth = 0; if (styleToUse.logicalMinWidth().isFixed() && styleToUse.logicalMinWidth().value() > 0) { @@ -499,7 +554,7 @@ void RenderReplaced::computePreferredLogicalWidths() setPreferredLogicalWidthsDirty(false); } -VisiblePosition RenderReplaced::positionForPoint(const LayoutPoint& point) +VisiblePosition RenderReplaced::positionForPoint(const LayoutPoint& point, const RenderRegion* region) { // FIXME: This code is buggy if the replaced element is relative positioned. InlineBox* box = inlineBoxWrapper(); @@ -523,7 +578,7 @@ VisiblePosition RenderReplaced::positionForPoint(const LayoutPoint& point) return createVisiblePosition(1, DOWNSTREAM); } - return RenderBox::positionForPoint(point); + return RenderBox::positionForPoint(point, region); } LayoutRect RenderReplaced::selectionRectForRepaint(const RenderLayerModelObject* repaintContainer, bool clipToVisibleContent) @@ -535,11 +590,8 @@ LayoutRect RenderReplaced::selectionRectForRepaint(const RenderLayerModelObject* LayoutRect rect = localSelectionRect(); if (clipToVisibleContent) - computeRectForRepaint(repaintContainer, rect); - else - rect = localToContainerQuad(FloatRect(rect), repaintContainer).enclosingBoundingBox(); - - return rect; + return computeRectForRepaint(rect, repaintContainer); + return localToContainerQuad(FloatRect(rect), repaintContainer).enclosingBoundingBox(); } LayoutRect RenderReplaced::localSelectionRect(bool checkWhetherSelected) const @@ -575,18 +627,18 @@ bool RenderReplaced::isSelected() const if (s == SelectionInside) return true; - int selectionStart, selectionEnd; + unsigned selectionStart, selectionEnd; selectionStartEnd(selectionStart, selectionEnd); if (s == SelectionStart) return selectionStart == 0; - int end = element()->hasChildNodes() ? element()->childNodeCount() : 1; + unsigned end = element()->hasChildNodes() ? element()->countChildNodes() : 1; if (s == SelectionEnd) return selectionEnd == end; if (s == SelectionBoth) return selectionStart == 0 && selectionEnd == end; - ASSERT(0); + ASSERT_NOT_REACHED(); return false; } @@ -598,15 +650,10 @@ LayoutRect RenderReplaced::clippedOverflowRectForRepaint(const RenderLayerModelO // The selectionRect can project outside of the overflowRect, so take their union // for repainting to avoid selection painting glitches. LayoutRect r = unionRect(localSelectionRect(false), visualOverflowRect()); - // FIXME: layoutDelta needs to be applied in parts before/after transforms and // repaint containers. https://bugs.webkit.org/show_bug.cgi?id=23308 r.move(view().layoutDelta()); - - r.inflate(style().outlineSize()); - - computeRectForRepaint(repaintContainer, r); - return r; + return computeRectForRepaint(r, repaintContainer); } } |