summaryrefslogtreecommitdiff
path: root/Source/WebCore/rendering/RenderReplaced.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'Source/WebCore/rendering/RenderReplaced.cpp')
-rw-r--r--Source/WebCore/rendering/RenderReplaced.cpp113
1 files changed, 47 insertions, 66 deletions
diff --git a/Source/WebCore/rendering/RenderReplaced.cpp b/Source/WebCore/rendering/RenderReplaced.cpp
index 47c239ab5..1df9e19c5 100644
--- a/Source/WebCore/rendering/RenderReplaced.cpp
+++ b/Source/WebCore/rendering/RenderReplaced.cpp
@@ -33,6 +33,7 @@
#include "RenderTheme.h"
#include "RenderView.h"
#include "VisiblePosition.h"
+#include <wtf/StackStats.h>
using namespace std;
@@ -41,15 +42,15 @@ namespace WebCore {
const int cDefaultWidth = 300;
const int cDefaultHeight = 150;
-RenderReplaced::RenderReplaced(Node* node)
- : RenderBox(node)
+RenderReplaced::RenderReplaced(Element* element)
+ : RenderBox(element)
, m_intrinsicSize(cDefaultWidth, cDefaultHeight)
{
setReplaced(true);
}
-RenderReplaced::RenderReplaced(Node* node, const LayoutSize& intrinsicSize)
- : RenderBox(node)
+RenderReplaced::RenderReplaced(Element* element, const LayoutSize& intrinsicSize)
+ : RenderBox(element)
, m_intrinsicSize(intrinsicSize)
{
setReplaced(true);
@@ -92,11 +93,12 @@ void RenderReplaced::layout()
m_overflow.clear();
addVisualEffectOverflow();
updateLayerTransform();
-
+ invalidateBackgroundObscurationStatus();
+
repainter.repaintAfterLayout();
setNeedsLayout(false);
}
-
+
void RenderReplaced::intrinsicSizeChanged()
{
int scaledWidth = static_cast<int>(cDefaultWidth * style()->effectiveZoom());
@@ -122,7 +124,7 @@ void RenderReplaced::paint(PaintInfo& paintInfo, const LayoutPoint& paintOffset)
LayoutRect paintRect = LayoutRect(adjustedPaintOffset, size());
if ((paintInfo.phase == PaintPhaseOutline || paintInfo.phase == PaintPhaseSelfOutline) && style()->outlineWidth())
- paintOutline(paintInfo.context, paintRect);
+ paintOutline(paintInfo, paintRect);
if (paintInfo.phase != PaintPhaseForeground && paintInfo.phase != PaintPhaseSelection && !canHaveChildren())
return;
@@ -232,33 +234,13 @@ bool RenderReplaced::hasReplacedLogicalWidth() const
return firstContainingBlockWithLogicalWidth(this);
}
-static inline bool hasAutoHeightOrContainingBlockWithAutoHeight(const RenderReplaced* replaced)
-{
- Length logicalHeightLength = replaced->style()->logicalHeight();
- if (logicalHeightLength.isAuto())
- return true;
-
- // For percentage heights: The percentage is calculated with respect to the height of the generated box's
- // containing block. If the height of the containing block is not specified explicitly (i.e., it depends
- // on content height), and this element is not absolutely positioned, the value computes to 'auto'.
- if (!logicalHeightLength.isPercent() || replaced->isOutOfFlowPositioned() || replaced->document()->inQuirksMode())
- return false;
-
- for (RenderBlock* cb = replaced->containingBlock(); !cb->isRenderView(); cb = cb->containingBlock()) {
- if (cb->isTableCell() || (!cb->style()->logicalHeight().isAuto() || (!cb->style()->top().isAuto() && !cb->style()->bottom().isAuto())))
- return false;
- }
-
- return true;
-}
-
bool RenderReplaced::hasReplacedLogicalHeight() const
{
if (style()->logicalHeight().isAuto())
return false;
if (style()->logicalHeight().isSpecified()) {
- if (hasAutoHeightOrContainingBlockWithAutoHeight(this))
+ if (hasAutoHeightOrContainingBlockWithAutoHeight())
return false;
return true;
}
@@ -266,12 +248,6 @@ bool RenderReplaced::hasReplacedLogicalHeight() const
return false;
}
-static inline bool rendererHasAspectRatio(const RenderObject* renderer)
-{
- ASSERT(renderer);
- return renderer->isImage() || renderer->isCanvas() || renderer->isVideo();
-}
-
void RenderReplaced::computeAspectRatioInformationForRenderBox(RenderBox* contentRenderer, FloatSize& constrainedSize, double& intrinsicRatio, bool& isPercentageIntrinsicSize) const
{
FloatSize intrinsicSize;
@@ -284,7 +260,7 @@ void RenderReplaced::computeAspectRatioInformationForRenderBox(RenderBox* conten
if (!isPercentageIntrinsicSize)
intrinsicSize.scale(style()->effectiveZoom());
- if (rendererHasAspectRatio(this) && isPercentageIntrinsicSize)
+ if (hasAspectRatio() && isPercentageIntrinsicSize)
intrinsicRatio = 1;
// Update our intrinsic size to match what the content renderer has computed, so that when we
@@ -330,16 +306,16 @@ void RenderReplaced::computeIntrinsicRatioInformation(FloatSize& intrinsicSize,
intrinsicSize = FloatSize(intrinsicLogicalWidth(), intrinsicLogicalHeight());
// Figure out if we need to compute an intrinsic ratio.
- if (intrinsicSize.isEmpty() || !rendererHasAspectRatio(this))
+ if (intrinsicSize.isEmpty() || !hasAspectRatio())
return;
intrinsicRatio = intrinsicSize.width() / intrinsicSize.height();
}
-LayoutUnit RenderReplaced::computeReplacedLogicalWidth(bool includeMaxWidth) const
+LayoutUnit RenderReplaced::computeReplacedLogicalWidth(ShouldComputePreferred shouldComputePreferred) const
{
- if (style()->logicalWidth().isSpecified())
- return computeReplacedLogicalWidthRespectingMinMaxWidth(computeReplacedLogicalWidthUsing(MainOrPreferredSize, style()->logicalWidth()), includeMaxWidth);
+ if (style()->logicalWidth().isSpecified() || style()->logicalWidth().isIntrinsic())
+ return computeReplacedLogicalWidthRespectingMinMaxWidth(computeReplacedLogicalWidthUsing(style()->logicalWidth()), shouldComputePreferred);
RenderBox* contentRenderer = embeddedContentBox();
@@ -355,7 +331,7 @@ LayoutUnit RenderReplaced::computeReplacedLogicalWidth(bool includeMaxWidth) con
// 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)
- return computeReplacedLogicalWidthRespectingMinMaxWidth(constrainedSize.width(), includeMaxWidth);
+ return computeReplacedLogicalWidthRespectingMinMaxWidth(constrainedSize.width(), shouldComputePreferred);
bool hasIntrinsicHeight = !isPercentageIntrinsicSize && constrainedSize.height() > 0;
if (intrinsicRatio || isPercentageIntrinsicSize) {
@@ -363,8 +339,8 @@ LayoutUnit RenderReplaced::computeReplacedLogicalWidth(bool includeMaxWidth) con
// 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 = computeReplacedLogicalHeightUsing(MainOrPreferredSize, style()->logicalHeight());
- return computeReplacedLogicalWidthRespectingMinMaxWidth(roundToInt(round(logicalHeight * intrinsicRatio)));
+ LayoutUnit logicalHeight = computeReplacedLogicalHeight();
+ 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
@@ -375,7 +351,7 @@ LayoutUnit RenderReplaced::computeReplacedLogicalWidth(bool includeMaxWidth) con
// '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(MainOrPreferredSize, blockWithWidth->style()->logicalWidth()), false);
+ logicalWidth = blockWithWidth->computeReplacedLogicalWidthRespectingMinMaxWidth(blockWithWidth->computeReplacedLogicalWidthUsing(blockWithWidth->style()->logicalWidth()), shouldComputePreferred);
else
logicalWidth = containingBlock()->availableLogicalWidth();
@@ -385,13 +361,13 @@ LayoutUnit RenderReplaced::computeReplacedLogicalWidth(bool includeMaxWidth) con
logicalWidth = max<LayoutUnit>(0, logicalWidth - (marginStart + marginEnd + (width() - clientWidth())));
if (isPercentageIntrinsicSize)
logicalWidth = logicalWidth * constrainedSize.width() / 100;
- return computeReplacedLogicalWidthRespectingMinMaxWidth(logicalWidth, includeMaxWidth);
+ return computeReplacedLogicalWidthRespectingMinMaxWidth(logicalWidth, 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'.
if (hasIntrinsicWidth)
- return computeReplacedLogicalWidthRespectingMinMaxWidth(constrainedSize.width(), includeMaxWidth);
+ return computeReplacedLogicalWidthRespectingMinMaxWidth(constrainedSize.width(), shouldComputePreferred);
// Otherwise, if 'width' has a computed value of 'auto', but none of the conditions above are met, then the used value of 'width' becomes 300px. If 300px is too
// wide to fit the device, UAs should use the width of the largest rectangle that has a 2:1 ratio and fits the device instead.
@@ -400,14 +376,14 @@ LayoutUnit RenderReplaced::computeReplacedLogicalWidth(bool includeMaxWidth) con
// has no intrinsic size, which is wrong per CSS 2.1, but matches our behavior since a long time.
}
- return computeReplacedLogicalWidthRespectingMinMaxWidth(intrinsicLogicalWidth(), includeMaxWidth);
+ return computeReplacedLogicalWidthRespectingMinMaxWidth(intrinsicLogicalWidth(), shouldComputePreferred);
}
LayoutUnit RenderReplaced::computeReplacedLogicalHeight() const
{
// 10.5 Content height: the 'height' property: http://www.w3.org/TR/CSS21/visudet.html#propdef-height
if (hasReplacedLogicalHeight())
- return computeReplacedLogicalHeightRespectingMinMaxHeight(computeReplacedLogicalHeightUsing(MainOrPreferredSize, style()->logicalHeight()));
+ return computeReplacedLogicalHeightRespectingMinMaxHeight(computeReplacedLogicalHeightUsing(style()->logicalHeight()));
RenderBox* contentRenderer = embeddedContentBox();
@@ -438,34 +414,39 @@ LayoutUnit RenderReplaced::computeReplacedLogicalHeight() const
return computeReplacedLogicalHeightRespectingMinMaxHeight(intrinsicLogicalHeight());
}
-LayoutUnit RenderReplaced::computeMaxPreferredLogicalWidth() const
+void RenderReplaced::computeIntrinsicLogicalWidths(LayoutUnit& minLogicalWidth, LayoutUnit& maxLogicalWidth) const
{
- Length logicalWidth = style()->logicalWidth();
-
- // We cannot resolve any percent logical width here as the available logical
- // width may not be set on our containing block.
- if (logicalWidth.isPercent())
- return intrinsicLogicalWidth();
-
- // FIXME: We shouldn't be calling a logical width computing function in preferred
- // logical widths computation as the layout information is probably invalid.
- return computeReplacedLogicalWidth(false);
+ minLogicalWidth = maxLogicalWidth = intrinsicLogicalWidth();
}
void RenderReplaced::computePreferredLogicalWidths()
{
ASSERT(preferredLogicalWidthsDirty());
- LayoutUnit borderAndPadding = borderAndPaddingLogicalWidth();
- m_maxPreferredLogicalWidth = computeMaxPreferredLogicalWidth() + borderAndPadding;
-
- if (style()->maxWidth().isFixed())
- m_maxPreferredLogicalWidth = min<LayoutUnit>(m_maxPreferredLogicalWidth, style()->maxWidth().value() + (style()->boxSizing() == CONTENT_BOX ? borderAndPadding : LayoutUnit()));
+ // 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())
+ computeIntrinsicLogicalWidths(m_minPreferredLogicalWidth, m_maxPreferredLogicalWidth);
+ else
+ m_minPreferredLogicalWidth = m_maxPreferredLogicalWidth = computeReplacedLogicalWidth(ComputePreferred);
- if (hasRelativeDimensions())
+ RenderStyle* styleToUse = style();
+ if (styleToUse->logicalWidth().isPercent() || styleToUse->logicalMaxWidth().isPercent() || hasRelativeIntrinsicLogicalWidth())
m_minPreferredLogicalWidth = 0;
- else
- m_minPreferredLogicalWidth = m_maxPreferredLogicalWidth;
+
+ if (styleToUse->logicalMinWidth().isFixed() && styleToUse->logicalMinWidth().value() > 0) {
+ m_maxPreferredLogicalWidth = max(m_maxPreferredLogicalWidth, adjustContentBoxLogicalWidthForBoxSizing(styleToUse->logicalMinWidth().value()));
+ m_minPreferredLogicalWidth = max(m_minPreferredLogicalWidth, adjustContentBoxLogicalWidthForBoxSizing(styleToUse->logicalMinWidth().value()));
+ }
+
+ if (styleToUse->logicalMaxWidth().isFixed()) {
+ m_maxPreferredLogicalWidth = min(m_maxPreferredLogicalWidth, adjustContentBoxLogicalWidthForBoxSizing(styleToUse->logicalMaxWidth().value()));
+ m_minPreferredLogicalWidth = min(m_minPreferredLogicalWidth, adjustContentBoxLogicalWidthForBoxSizing(styleToUse->logicalMaxWidth().value()));
+ }
+
+ LayoutUnit borderAndPadding = borderAndPaddingLogicalWidth();
+ m_minPreferredLogicalWidth += borderAndPadding;
+ m_maxPreferredLogicalWidth += borderAndPadding;
setPreferredLogicalWidthsDirty(false);
}