summaryrefslogtreecommitdiff
path: root/Source/WebCore/rendering/RenderBoxModelObject.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'Source/WebCore/rendering/RenderBoxModelObject.cpp')
-rw-r--r--Source/WebCore/rendering/RenderBoxModelObject.cpp467
1 files changed, 299 insertions, 168 deletions
diff --git a/Source/WebCore/rendering/RenderBoxModelObject.cpp b/Source/WebCore/rendering/RenderBoxModelObject.cpp
index c709705bc..eed3577a3 100644
--- a/Source/WebCore/rendering/RenderBoxModelObject.cpp
+++ b/Source/WebCore/rendering/RenderBoxModelObject.cpp
@@ -26,6 +26,7 @@
#include "config.h"
#include "RenderBoxModelObject.h"
+#include "FilterOperations.h"
#include "GraphicsContext.h"
#include "HTMLFrameOwnerElement.h"
#include "HTMLNames.h"
@@ -40,6 +41,11 @@
#include "TransformState.h"
#include <wtf/CurrentTime.h>
+#if USE(ACCELERATED_COMPOSITING)
+#include "RenderLayerBacking.h"
+#include "RenderLayerCompositor.h"
+#endif
+
using namespace std;
namespace WebCore {
@@ -240,6 +246,70 @@ void RenderBoxModelObject::setSelectionState(SelectionState state)
containingBlock->setSelectionState(state);
}
+#if USE(ACCELERATED_COMPOSITING)
+void RenderBoxModelObject::contentChanged(ContentChangeType changeType)
+{
+ if (!hasLayer())
+ return;
+
+ layer()->contentChanged(changeType);
+}
+
+bool RenderBoxModelObject::hasAcceleratedCompositing() const
+{
+ return view()->compositor()->hasAcceleratedCompositing();
+}
+
+bool RenderBoxModelObject::startTransition(double timeOffset, CSSPropertyID propertyId, const RenderStyle* fromStyle, const RenderStyle* toStyle)
+{
+ ASSERT(hasLayer());
+ ASSERT(isComposited());
+ return layer()->backing()->startTransition(timeOffset, propertyId, fromStyle, toStyle);
+}
+
+void RenderBoxModelObject::transitionPaused(double timeOffset, CSSPropertyID propertyId)
+{
+ ASSERT(hasLayer());
+ ASSERT(isComposited());
+ layer()->backing()->transitionPaused(timeOffset, propertyId);
+}
+
+void RenderBoxModelObject::transitionFinished(CSSPropertyID propertyId)
+{
+ ASSERT(hasLayer());
+ ASSERT(isComposited());
+ layer()->backing()->transitionFinished(propertyId);
+}
+
+bool RenderBoxModelObject::startAnimation(double timeOffset, const Animation* animation, const KeyframeList& keyframes)
+{
+ ASSERT(hasLayer());
+ ASSERT(isComposited());
+ return layer()->backing()->startAnimation(timeOffset, animation, keyframes);
+}
+
+void RenderBoxModelObject::animationPaused(double timeOffset, const String& name)
+{
+ ASSERT(hasLayer());
+ ASSERT(isComposited());
+ layer()->backing()->animationPaused(timeOffset, name);
+}
+
+void RenderBoxModelObject::animationFinished(const String& name)
+{
+ ASSERT(hasLayer());
+ ASSERT(isComposited());
+ layer()->backing()->animationFinished(name);
+}
+
+void RenderBoxModelObject::suspendAnimations(double time)
+{
+ ASSERT(hasLayer());
+ ASSERT(isComposited());
+ layer()->backing()->suspendAnimations(time);
+}
+#endif
+
bool RenderBoxModelObject::shouldPaintAtLowQuality(GraphicsContext* context, Image* image, const void* layer, const LayoutSize& size)
{
return imageQualityController()->shouldPaintAtLowQuality(context, this, image, layer, size);
@@ -329,9 +399,13 @@ void RenderBoxModelObject::styleWillChange(StyleDifference diff, const RenderSty
|| !(oldStyle->clip() == newStyle->clip())
|| oldStyle->hasClip() != newStyle->hasClip()
|| oldStyle->opacity() != newStyle->opacity()
- || oldStyle->transform() != newStyle->transform())
+ || oldStyle->transform() != newStyle->transform()
+#if ENABLE(CSS_FILTERS)
+ || oldStyle->filter() != newStyle->filter()
+#endif
+ )
layer()->repaintIncludingDescendants();
- } else if (newStyle->hasTransform() || newStyle->opacity() < 1) {
+ } else if (newStyle->hasTransform() || newStyle->opacity() < 1 || newStyle->hasFilter()) {
// If we don't have a layer yet, but we are going to get one because of transform or opacity,
// then we need to repaint the old position of the object.
repaint();
@@ -351,28 +425,18 @@ void RenderBoxModelObject::styleWillChange(StyleDifference diff, const RenderSty
RenderObject::styleWillChange(diff, newStyle);
}
-void RenderBoxModelObject::ensureLayer()
-{
- if (m_layer)
- return;
-
- m_layer = new (renderArena()) RenderLayer(this);
- setHasLayer(true);
- m_layer->insertOnlyThisLayer();
-}
-
void RenderBoxModelObject::styleDidChange(StyleDifference diff, const RenderStyle* oldStyle)
{
RenderObject::styleDidChange(diff, oldStyle);
updateBoxModelInfoFromStyle();
-
+
if (requiresLayer()) {
if (!layer() && layerCreationAllowedForSubtree()) {
if (s_wasFloating && isFloating())
setChildNeedsLayout(true);
-
- ensureLayer();
-
+ m_layer = new (renderArena()) RenderLayer(this);
+ setHasLayer(true);
+ m_layer->insertOnlyThisLayer();
if (parent() && !needsLayout() && containingBlock()) {
m_layer->setRepaintStatus(NeedsFullRepaint);
// There is only one layer to update, it is not worth using |cachedOffset| since
@@ -388,8 +452,6 @@ void RenderBoxModelObject::styleDidChange(StyleDifference diff, const RenderStyl
setChildNeedsLayout(true);
if (s_hadTransform)
setNeedsLayoutAndPrefWidthsRecalc();
- if (hasOverflowClip())
- toRenderBox(this)->updateCachedSizeForOverflowClip();
}
if (layer()) {
@@ -437,12 +499,12 @@ LayoutUnit RenderBoxModelObject::relativePositionOffsetX() const
if (!style()->left().isAuto()) {
RenderBlock* cb = containingBlock();
if (!style()->right().isAuto() && !cb->style()->isLeftToRightDirection())
- return -style()->right().calcValue(cb->availableWidth());
- return offset + style()->left().calcValue(cb->availableWidth());
+ return -valueForLength(style()->right(), cb->availableWidth(), view());
+ return offset + valueForLength(style()->left(), cb->availableWidth(), view());
}
if (!style()->right().isAuto()) {
RenderBlock* cb = containingBlock();
- return offset + -style()->right().calcValue(cb->availableWidth());
+ return offset + -valueForLength(style()->right(), cb->availableWidth(), view());
}
return offset;
}
@@ -462,13 +524,13 @@ LayoutUnit RenderBoxModelObject::relativePositionOffsetY() const
&& (!containingBlock->style()->height().isAuto()
|| !style()->top().isPercent()
|| containingBlock->stretchesToViewport()))
- return offset + style()->top().calcValue(containingBlock->availableHeight());
+ return offset + valueForLength(style()->top(), containingBlock->availableHeight(), view());
if (!style()->bottom().isAuto()
&& (!containingBlock->style()->height().isAuto()
|| !style()->bottom().isPercent()
|| containingBlock->stretchesToViewport()))
- return offset + -style()->bottom().calcValue(containingBlock->availableHeight());
+ return offset + -valueForLength(style()->bottom(), containingBlock->availableHeight(), view());
return offset;
}
@@ -481,7 +543,7 @@ LayoutUnit RenderBoxModelObject::offsetLeft() const
return 0;
RenderBoxModelObject* offsetPar = offsetParent();
- LayoutUnit xPos = (isBox() ? toRenderBox(this)->left() : zeroLayoutUnit);
+ LayoutUnit xPos = (isBox() ? toRenderBox(this)->left() : ZERO_LAYOUT_UNIT);
// If the offsetParent of the element is null, or is the HTML body element,
// return the distance between the canvas origin and the left border edge
@@ -515,7 +577,7 @@ LayoutUnit RenderBoxModelObject::offsetTop() const
return 0;
RenderBoxModelObject* offsetPar = offsetParent();
- LayoutUnit yPos = (isBox() ? toRenderBox(this)->top() : zeroLayoutUnit);
+ LayoutUnit yPos = (isBox() ? toRenderBox(this)->top() : ZERO_LAYOUT_UNIT);
// If the offsetParent of the element is null, or is the HTML body element,
// return the distance between the canvas origin and the top border edge
@@ -542,92 +604,117 @@ LayoutUnit RenderBoxModelObject::offsetTop() const
int RenderBoxModelObject::pixelSnappedOffsetWidth() const
{
- return offsetWidth();
+ return snapSizeToPixel(offsetWidth(), offsetLeft());
}
int RenderBoxModelObject::pixelSnappedOffsetHeight() const
{
- return offsetHeight();
+ return snapSizeToPixel(offsetHeight(), offsetTop());
}
-LayoutUnit RenderBoxModelObject::paddingTop(PaddingOptions) const
+LayoutUnit RenderBoxModelObject::computedCSSPaddingTop() const
{
LayoutUnit w = 0;
+ RenderView* renderView = 0;
Length padding = style()->paddingTop();
if (padding.isPercent())
w = containingBlock()->availableLogicalWidth();
- return padding.calcMinValue(w);
+ else if (padding.isViewportPercentage())
+ renderView = view();
+ return minimumValueForLength(padding, w, renderView);
}
-LayoutUnit RenderBoxModelObject::paddingBottom(PaddingOptions) const
+LayoutUnit RenderBoxModelObject::computedCSSPaddingBottom() const
{
LayoutUnit w = 0;
+ RenderView* renderView = 0;
Length padding = style()->paddingBottom();
if (padding.isPercent())
w = containingBlock()->availableLogicalWidth();
- return padding.calcMinValue(w);
+ else if (padding.isViewportPercentage())
+ renderView = view();
+ return minimumValueForLength(padding, w, renderView);
}
-LayoutUnit RenderBoxModelObject::paddingLeft(PaddingOptions) const
+LayoutUnit RenderBoxModelObject::computedCSSPaddingLeft() const
{
LayoutUnit w = 0;
+ RenderView* renderView = 0;
Length padding = style()->paddingLeft();
if (padding.isPercent())
w = containingBlock()->availableLogicalWidth();
- return padding.calcMinValue(w);
+ else if (padding.isViewportPercentage())
+ renderView = view();
+ return minimumValueForLength(padding, w, renderView);
}
-LayoutUnit RenderBoxModelObject::paddingRight(PaddingOptions) const
+LayoutUnit RenderBoxModelObject::computedCSSPaddingRight() const
{
LayoutUnit w = 0;
+ RenderView* renderView = 0;
Length padding = style()->paddingRight();
if (padding.isPercent())
w = containingBlock()->availableLogicalWidth();
- return padding.calcMinValue(w);
+ else if (padding.isViewportPercentage())
+ renderView = view();
+ return minimumValueForLength(padding, w, renderView);
}
-LayoutUnit RenderBoxModelObject::paddingBefore(PaddingOptions) const
+LayoutUnit RenderBoxModelObject::computedCSSPaddingBefore() const
{
LayoutUnit w = 0;
+ RenderView* renderView = 0;
Length padding = style()->paddingBefore();
if (padding.isPercent())
w = containingBlock()->availableLogicalWidth();
- return padding.calcMinValue(w);
+ else if (padding.isViewportPercentage())
+ renderView = view();
+ return minimumValueForLength(padding, w, renderView);
}
-LayoutUnit RenderBoxModelObject::paddingAfter(PaddingOptions) const
+LayoutUnit RenderBoxModelObject::computedCSSPaddingAfter() const
{
LayoutUnit w = 0;
+ RenderView* renderView = 0;
Length padding = style()->paddingAfter();
if (padding.isPercent())
w = containingBlock()->availableLogicalWidth();
- return padding.calcMinValue(w);
+ else if (padding.isViewportPercentage())
+ renderView = view();
+ return minimumValueForLength(padding, w, renderView);
}
-LayoutUnit RenderBoxModelObject::paddingStart(PaddingOptions) const
+LayoutUnit RenderBoxModelObject::computedCSSPaddingStart() const
{
LayoutUnit w = 0;
+ RenderView* renderView = 0;
Length padding = style()->paddingStart();
if (padding.isPercent())
w = containingBlock()->availableLogicalWidth();
- return padding.calcMinValue(w);
+ else if (padding.isViewportPercentage())
+ renderView = view();
+ return minimumValueForLength(padding, w, renderView);
}
-LayoutUnit RenderBoxModelObject::paddingEnd(PaddingOptions) const
+LayoutUnit RenderBoxModelObject::computedCSSPaddingEnd() const
{
LayoutUnit w = 0;
+ RenderView* renderView = 0;
Length padding = style()->paddingEnd();
if (padding.isPercent())
w = containingBlock()->availableLogicalWidth();
- return padding.calcMinValue(w);
+ else if (padding.isViewportPercentage())
+ renderView = view();
+ return minimumValueForLength(padding, w, renderView);
}
RoundedRect RenderBoxModelObject::getBackgroundRoundedRect(const LayoutRect& borderRect, InlineFlowBox* box, LayoutUnit inlineBoxWidth, LayoutUnit inlineBoxHeight,
bool includeLogicalLeftEdge, bool includeLogicalRightEdge)
{
- RoundedRect border = style()->getRoundedBorderFor(borderRect, includeLogicalLeftEdge, includeLogicalRightEdge);
+ RenderView* renderView = view();
+ RoundedRect border = style()->getRoundedBorderFor(borderRect, renderView, includeLogicalLeftEdge, includeLogicalRightEdge);
if (box && (box->nextLineBox() || box->prevLineBox())) {
- RoundedRect segmentBorder = style()->getRoundedBorderFor(LayoutRect(0, 0, inlineBoxWidth, inlineBoxHeight), includeLogicalLeftEdge, includeLogicalRightEdge);
+ RoundedRect segmentBorder = style()->getRoundedBorderFor(LayoutRect(0, 0, inlineBoxWidth, inlineBoxHeight), renderView, includeLogicalLeftEdge, includeLogicalRightEdge);
border.setRadii(segmentBorder.radii());
}
@@ -731,10 +818,10 @@ void RenderBoxModelObject::paintFillLayerExtended(const PaintInfo& paintInfo, co
context->addRoundedRectClip(border);
}
- LayoutUnit bLeft = includeLeftEdge ? borderLeft() : zeroLayoutUnit;
- LayoutUnit bRight = includeRightEdge ? borderRight() : zeroLayoutUnit;
- LayoutUnit pLeft = includeLeftEdge ? paddingLeft() : zeroLayoutUnit;
- LayoutUnit pRight = includeRightEdge ? paddingRight() : zeroLayoutUnit;
+ int bLeft = includeLeftEdge ? borderLeft() : 0;
+ int bRight = includeRightEdge ? borderRight() : 0;
+ LayoutUnit pLeft = includeLeftEdge ? paddingLeft() : ZERO_LAYOUT_UNIT;
+ LayoutUnit pRight = includeRightEdge ? paddingRight() : ZERO_LAYOUT_UNIT;
GraphicsContextStateSaver clipWithScrollingStateSaver(*context, clippedWithLocalScrolling);
LayoutRect scrolledPaintRect = rect;
@@ -757,10 +844,10 @@ void RenderBoxModelObject::paintFillLayerExtended(const PaintInfo& paintInfo, co
if (bgLayer->clip() == PaddingFillBox || bgLayer->clip() == ContentFillBox) {
// Clip to the padding or content boxes as necessary.
bool includePadding = bgLayer->clip() == ContentFillBox;
- LayoutRect clipRect = LayoutRect(scrolledPaintRect.x() + bLeft + (includePadding ? pLeft : zeroLayoutUnit),
- scrolledPaintRect.y() + borderTop() + (includePadding ? paddingTop() : zeroLayoutUnit),
- scrolledPaintRect.width() - bLeft - bRight - (includePadding ? pLeft + pRight : zeroLayoutUnit),
- scrolledPaintRect.height() - borderTop() - borderBottom() - (includePadding ? paddingTop() + paddingBottom() : zeroLayoutUnit));
+ LayoutRect clipRect = LayoutRect(scrolledPaintRect.x() + bLeft + (includePadding ? pLeft : ZERO_LAYOUT_UNIT),
+ scrolledPaintRect.y() + borderTop() + (includePadding ? paddingTop() : ZERO_LAYOUT_UNIT),
+ scrolledPaintRect.width() - bLeft - bRight - (includePadding ? pLeft + pRight : ZERO_LAYOUT_UNIT),
+ scrolledPaintRect.height() - borderTop() - borderBottom() - (includePadding ? paddingTop() + paddingBottom() : ZERO_LAYOUT_UNIT));
backgroundClipStateSaver.save();
context->clip(clipRect);
} else if (bgLayer->clip() == TextFillBox) {
@@ -879,102 +966,96 @@ void RenderBoxModelObject::paintFillLayerExtended(const PaintInfo& paintInfo, co
}
}
-static inline LayoutUnit resolveWidthForRatio(LayoutUnit height, const FloatSize& intrinsicRatio)
+static inline int resolveWidthForRatio(int height, const FloatSize& intrinsicRatio)
{
- // FIXME: Remove unnecessary rounding when layout is off ints: webkit.org/b/63656
- return static_cast<LayoutUnit>(ceilf(height * intrinsicRatio.width() / intrinsicRatio.height()));
+ return ceilf(height * intrinsicRatio.width() / intrinsicRatio.height());
}
-static inline LayoutUnit resolveHeightForRatio(LayoutUnit width, const FloatSize& intrinsicRatio)
+static inline int resolveHeightForRatio(int width, const FloatSize& intrinsicRatio)
{
- // FIXME: Remove unnecessary rounding when layout is off ints: webkit.org/b/63656
- return static_cast<LayoutUnit>(ceilf(width * intrinsicRatio.height() / intrinsicRatio.width()));
+ return ceilf(width * intrinsicRatio.height() / intrinsicRatio.width());
}
-static inline LayoutSize resolveAgainstIntrinsicWidthOrHeightAndRatio(const LayoutSize& size, const FloatSize& intrinsicRatio, LayoutUnit useWidth, LayoutUnit useHeight)
+static inline IntSize resolveAgainstIntrinsicWidthOrHeightAndRatio(const IntSize& size, const FloatSize& intrinsicRatio, int useWidth, int useHeight)
{
if (intrinsicRatio.isEmpty()) {
if (useWidth)
- return LayoutSize(useWidth, size.height());
- return LayoutSize(size.width(), useHeight);
+ return IntSize(useWidth, size.height());
+ return IntSize(size.width(), useHeight);
}
if (useWidth)
- return LayoutSize(useWidth, resolveHeightForRatio(useWidth, intrinsicRatio));
- return LayoutSize(resolveWidthForRatio(useHeight, intrinsicRatio), useHeight);
+ return IntSize(useWidth, resolveHeightForRatio(useWidth, intrinsicRatio));
+ return IntSize(resolveWidthForRatio(useHeight, intrinsicRatio), useHeight);
}
-static inline LayoutSize resolveAgainstIntrinsicRatio(const LayoutSize& size, const FloatSize& intrinsicRatio)
+static inline IntSize resolveAgainstIntrinsicRatio(const IntSize& size, const FloatSize& intrinsicRatio)
{
// Two possible solutions: (size.width(), solutionHeight) or (solutionWidth, size.height())
// "... must be assumed to be the largest dimensions..." = easiest answer: the rect with the largest surface area.
- LayoutUnit solutionWidth = resolveWidthForRatio(size.height(), intrinsicRatio);
- LayoutUnit solutionHeight = resolveHeightForRatio(size.width(), intrinsicRatio);
+ int solutionWidth = resolveWidthForRatio(size.height(), intrinsicRatio);
+ int solutionHeight = resolveHeightForRatio(size.width(), intrinsicRatio);
if (solutionWidth <= size.width()) {
if (solutionHeight <= size.height()) {
// If both solutions fit, choose the one covering the larger area.
- LayoutUnit areaOne = solutionWidth * size.height();
- LayoutUnit areaTwo = size.width() * solutionHeight;
+ int areaOne = solutionWidth * size.height();
+ int areaTwo = size.width() * solutionHeight;
if (areaOne < areaTwo)
- return LayoutSize(size.width(), solutionHeight);
- return LayoutSize(solutionWidth, size.height());
+ return IntSize(size.width(), solutionHeight);
+ return IntSize(solutionWidth, size.height());
}
// Only the first solution fits.
- return LayoutSize(solutionWidth, size.height());
+ return IntSize(solutionWidth, size.height());
}
// Only the second solution fits, assert that.
ASSERT(solutionHeight <= size.height());
- return LayoutSize(size.width(), solutionHeight);
+ return IntSize(size.width(), solutionHeight);
}
IntSize RenderBoxModelObject::calculateImageIntrinsicDimensions(StyleImage* image, const IntSize& positioningAreaSize) const
{
- int resolvedWidth = 0;
- int resolvedHeight = 0;
+ // A generated image without a fixed size, will always return the container size as intrinsic size.
+ if (image->isGeneratedImage() && image->usesImageContainerSize())
+ return IntSize(positioningAreaSize.width(), positioningAreaSize.height());
+
+ Length intrinsicWidth;
+ Length intrinsicHeight;
FloatSize intrinsicRatio;
+ image->computeIntrinsicDimensions(this, intrinsicWidth, intrinsicHeight, intrinsicRatio);
- // A generated image without a fixed size, will always return the container size as intrinsic size.
- if (image->isGeneratedImage() && image->usesImageContainerSize()) {
- resolvedWidth = positioningAreaSize.width();
- resolvedHeight = positioningAreaSize.height();
- } else {
- Length intrinsicWidth;
- Length intrinsicHeight;
- image->computeIntrinsicDimensions(this, intrinsicWidth, intrinsicHeight, intrinsicRatio);
-
- // Intrinsic dimensions expressed as percentages must be resolved relative to the dimensions of the rectangle
- // that establishes the coordinate system for the 'background-position' property.
-
- // FIXME: Remove unnecessary rounding when layout is off ints: webkit.org/b/63656
- if (intrinsicWidth.isPercent() && intrinsicHeight.isPercent() && intrinsicRatio.isEmpty()) {
- // Resolve width/height percentages against positioningAreaSize, only if no intrinsic ratio is provided.
- resolvedWidth = static_cast<int>(round(positioningAreaSize.width() * intrinsicWidth.percent() / 100));
- resolvedHeight = static_cast<int>(round(positioningAreaSize.height() * intrinsicHeight.percent() / 100));
- } else {
- if (intrinsicWidth.isFixed())
- resolvedWidth = static_cast<int>(intrinsicWidth.value() * style()->effectiveZoom());
- if (intrinsicHeight.isFixed())
- resolvedHeight = static_cast<int>(intrinsicHeight.value() * style()->effectiveZoom());
- }
+ // Intrinsic dimensions expressed as percentages must be resolved relative to the dimensions of the rectangle
+ // that establishes the coordinate system for the 'background-position' property.
+
+ // FIXME: Remove unnecessary rounding when layout is off ints: webkit.org/b/63656
+ if (intrinsicWidth.isPercent() && intrinsicHeight.isPercent() && intrinsicRatio.isEmpty()) {
+ // Resolve width/height percentages against positioningAreaSize, only if no intrinsic ratio is provided.
+ int resolvedWidth = static_cast<int>(round(positioningAreaSize.width() * intrinsicWidth.percent() / 100));
+ int resolvedHeight = static_cast<int>(round(positioningAreaSize.height() * intrinsicHeight.percent() / 100));
+ return IntSize(resolvedWidth, resolvedHeight);
}
- if (resolvedWidth > 0 && resolvedHeight > 0)
- return IntSize(resolvedWidth, resolvedHeight);
+ IntSize resolvedSize(intrinsicWidth.isFixed() ? intrinsicWidth.value() : 0, intrinsicHeight.isFixed() ? intrinsicHeight.value() : 0);
+ IntSize minimumSize(resolvedSize.width() > 0 ? 1 : 0, resolvedSize.height() > 0 ? 1 : 0);
+ resolvedSize.scale(style()->effectiveZoom());
+ resolvedSize.clampToMinimumSize(minimumSize);
+
+ if (!resolvedSize.isEmpty())
+ return resolvedSize;
// If the image has one of either an intrinsic width or an intrinsic height:
// * and an intrinsic aspect ratio, then the missing dimension is calculated from the given dimension and the ratio.
// * and no intrinsic aspect ratio, then the missing dimension is assumed to be the size of the rectangle that
// establishes the coordinate system for the 'background-position' property.
- if ((resolvedWidth && !resolvedHeight) || (!resolvedWidth && resolvedHeight))
- return resolveAgainstIntrinsicWidthOrHeightAndRatio(positioningAreaSize, intrinsicRatio, resolvedWidth, resolvedHeight);
+ if (resolvedSize.width() > 0 || resolvedSize.height() > 0)
+ return resolveAgainstIntrinsicWidthOrHeightAndRatio(positioningAreaSize, intrinsicRatio, resolvedSize.width(), resolvedSize.height());
// If the image has no intrinsic dimensions and has an intrinsic ratio the dimensions must be assumed to be the
// largest dimensions at that ratio such that neither dimension exceeds the dimensions of the rectangle that
// establishes the coordinate system for the 'background-position' property.
- if (!resolvedWidth && !resolvedHeight && !intrinsicRatio.isEmpty())
+ if (!intrinsicRatio.isEmpty())
return resolveAgainstIntrinsicRatio(positioningAreaSize, intrinsicRatio);
// If the image has no intrinsic ratio either, then the dimensions must be assumed to be the rectangle that
@@ -988,7 +1069,8 @@ IntSize RenderBoxModelObject::calculateFillTileSize(const FillLayer* fillLayer,
EFillSizeType type = fillLayer->size().type;
IntSize imageIntrinsicSize = calculateImageIntrinsicDimensions(image, positioningAreaSize);
-
+ imageIntrinsicSize.scale(1 / image->imageScaleFactor(), 1 / image->imageScaleFactor());
+ RenderView* renderView = view();
switch (type) {
case SizeLength: {
int w = positioningAreaSize.width();
@@ -999,13 +1081,13 @@ IntSize RenderBoxModelObject::calculateFillTileSize(const FillLayer* fillLayer,
if (layerWidth.isFixed())
w = layerWidth.value();
- else if (layerWidth.isPercent())
- w = layerWidth.calcValue(positioningAreaSize.width());
+ else if (layerWidth.isPercent() || layerHeight.isViewportPercentage())
+ w = valueForLength(layerWidth, positioningAreaSize.width(), renderView);
if (layerHeight.isFixed())
h = layerHeight.value();
- else if (layerHeight.isPercent())
- h = layerHeight.calcValue(positioningAreaSize.height());
+ else if (layerHeight.isPercent() || layerHeight.isViewportPercentage())
+ h = valueForLength(layerHeight, positioningAreaSize.height(), renderView);
// If one of the values is auto we have to use the appropriate
// scale to maintain our aspect ratio.
@@ -1083,6 +1165,7 @@ void RenderBoxModelObject::calculateBackgroundImageGeometry(const FillLayer* fil
LayoutUnit left = 0;
LayoutUnit top = 0;
IntSize positioningAreaSize;
+ IntRect snappedPaintRect = pixelSnappedIntRect(paintRect);
// Determine the background positioning area and set destRect to the background painting area.
// destRect will be adjusted later if the background is non-repeating.
@@ -1099,7 +1182,7 @@ void RenderBoxModelObject::calculateBackgroundImageGeometry(const FillLayer* fil
#endif
if (!fixedAttachment) {
- geometry.setDestRect(paintRect);
+ geometry.setDestRect(snappedPaintRect);
LayoutUnit right = 0;
LayoutUnit bottom = 0;
@@ -1121,11 +1204,13 @@ void RenderBoxModelObject::calculateBackgroundImageGeometry(const FillLayer* fil
// its margins. Since those were added in already, we have to factor them out when computing
// the background positioning area.
if (isRoot()) {
- positioningAreaSize = LayoutSize(toRenderBox(this)->width() - left - right, toRenderBox(this)->height() - top - bottom);
+ positioningAreaSize = IntSize(snapSizeToPixel(toRenderBox(this)->width() - left - right, toRenderBox(this)->x()),
+ snapSizeToPixel(toRenderBox(this)->height() - top - bottom, toRenderBox(this)->y()));
left += marginLeft();
top += marginTop();
} else
- positioningAreaSize = LayoutSize(paintRect.width() - left - right, paintRect.height() - top - bottom);
+ positioningAreaSize = IntSize(snapSizeToPixel(paintRect.width() - left - right, paintRect.x()),
+ snapSizeToPixel(paintRect.height() - top - bottom, paintRect.y()));
} else {
geometry.setDestRect(pixelSnappedIntRect(viewRect()));
positioningAreaSize = geometry.destRect().size();
@@ -1137,33 +1222,34 @@ void RenderBoxModelObject::calculateBackgroundImageGeometry(const FillLayer* fil
EFillRepeat backgroundRepeatX = fillLayer->repeatX();
EFillRepeat backgroundRepeatY = fillLayer->repeatY();
+ RenderView* renderView = view();
- LayoutUnit xPosition = fillLayer->xPosition().calcMinValue(positioningAreaSize.width() - geometry.tileSize().width(), true);
+ LayoutUnit xPosition = minimumValueForLength(fillLayer->xPosition(), positioningAreaSize.width() - geometry.tileSize().width(), renderView, true);
if (backgroundRepeatX == RepeatFill)
- geometry.setPhaseX(geometry.tileSize().width() ? layoutMod(geometry.tileSize().width() - (xPosition + left), geometry.tileSize().width()) : LayoutUnit(0));
+ geometry.setPhaseX(geometry.tileSize().width() ? geometry.tileSize().width() - roundToInt(xPosition + left) % geometry.tileSize().width() : 0);
else
geometry.setNoRepeatX(xPosition + left);
- LayoutUnit yPosition = fillLayer->yPosition().calcMinValue(positioningAreaSize.height() - geometry.tileSize().height(), true);
+ LayoutUnit yPosition = minimumValueForLength(fillLayer->yPosition(), positioningAreaSize.height() - geometry.tileSize().height(), renderView, true);
if (backgroundRepeatY == RepeatFill)
- geometry.setPhaseY(geometry.tileSize().height() ? layoutMod(geometry.tileSize().height() - (yPosition + top), geometry.tileSize().height()) : LayoutUnit(0));
+ geometry.setPhaseY(geometry.tileSize().height() ? geometry.tileSize().height() - roundToInt(yPosition + top) % geometry.tileSize().height() : 0);
else
geometry.setNoRepeatY(yPosition + top);
if (fixedAttachment)
- geometry.useFixedAttachment(paintRect.location());
+ geometry.useFixedAttachment(snappedPaintRect.location());
- geometry.clip(paintRect);
+ geometry.clip(snappedPaintRect);
geometry.setDestOrigin(geometry.destRect().location());
}
-static LayoutUnit computeBorderImageSide(Length borderSlice, LayoutUnit borderSide, LayoutUnit imageSide, LayoutUnit boxExtent)
+static LayoutUnit computeBorderImageSide(Length borderSlice, LayoutUnit borderSide, LayoutUnit imageSide, LayoutUnit boxExtent, RenderView* renderView)
{
if (borderSlice.isRelative())
return borderSlice.value() * borderSide;
if (borderSlice.isAuto())
return imageSide;
- return borderSlice.calcValue(boxExtent);
+ return valueForLength(borderSlice, boxExtent, renderView);
}
bool RenderBoxModelObject::paintNinePieceImage(GraphicsContext* graphicsContext, const LayoutRect& rect, const RenderStyle* style,
@@ -1191,7 +1277,7 @@ bool RenderBoxModelObject::paintNinePieceImage(GraphicsContext* graphicsContext,
LayoutUnit bottomWithOutset = rect.maxY() + bottomOutset;
LayoutUnit leftWithOutset = rect.x() - leftOutset;
LayoutUnit rightWithOutset = rect.maxX() + rightOutset;
- LayoutRect borderImageRect = LayoutRect(leftWithOutset, topWithOutset, rightWithOutset - leftWithOutset, bottomWithOutset - topWithOutset);
+ IntRect borderImageRect = pixelSnappedIntRect(leftWithOutset, topWithOutset, rightWithOutset - leftWithOutset, bottomWithOutset - topWithOutset);
IntSize imageSize = calculateImageIntrinsicDimensions(styleImage, borderImageRect.size());
@@ -1200,19 +1286,21 @@ bool RenderBoxModelObject::paintNinePieceImage(GraphicsContext* graphicsContext,
int imageWidth = imageSize.width() / style->effectiveZoom();
int imageHeight = imageSize.height() / style->effectiveZoom();
+ RenderView* renderView = view();
- int topSlice = min<int>(imageHeight, ninePieceImage.imageSlices().top().calcValue(imageHeight));
- int rightSlice = min<int>(imageWidth, ninePieceImage.imageSlices().right().calcValue(imageWidth));
- int bottomSlice = min<int>(imageHeight, ninePieceImage.imageSlices().bottom().calcValue(imageHeight));
- int leftSlice = min<int>(imageWidth, ninePieceImage.imageSlices().left().calcValue(imageWidth));
+ float imageScaleFactor = styleImage->imageScaleFactor();
+ int topSlice = min<int>(imageHeight, valueForLength(ninePieceImage.imageSlices().top(), imageHeight, renderView)) * imageScaleFactor;
+ int rightSlice = min<int>(imageWidth, valueForLength(ninePieceImage.imageSlices().right(), imageWidth, renderView)) * imageScaleFactor;
+ int bottomSlice = min<int>(imageHeight, valueForLength(ninePieceImage.imageSlices().bottom(), imageHeight, renderView)) * imageScaleFactor;
+ int leftSlice = min<int>(imageWidth, valueForLength(ninePieceImage.imageSlices().left(), imageWidth, renderView)) * imageScaleFactor;
ENinePieceImageRule hRule = ninePieceImage.horizontalRule();
ENinePieceImageRule vRule = ninePieceImage.verticalRule();
-
- LayoutUnit topWidth = computeBorderImageSide(ninePieceImage.borderSlices().top(), style->borderTopWidth(), topSlice, borderImageRect.height());
- LayoutUnit rightWidth = computeBorderImageSide(ninePieceImage.borderSlices().right(), style->borderRightWidth(), rightSlice, borderImageRect.width());
- LayoutUnit bottomWidth = computeBorderImageSide(ninePieceImage.borderSlices().bottom(), style->borderBottomWidth(), bottomSlice, borderImageRect.height());
- LayoutUnit leftWidth = computeBorderImageSide(ninePieceImage.borderSlices().left(), style->borderLeftWidth(), leftSlice, borderImageRect.width());
+
+ LayoutUnit topWidth = computeBorderImageSide(ninePieceImage.borderSlices().top(), style->borderTopWidth(), topSlice, borderImageRect.height(), renderView);
+ LayoutUnit rightWidth = computeBorderImageSide(ninePieceImage.borderSlices().right(), style->borderRightWidth(), rightSlice, borderImageRect.width(), renderView);
+ LayoutUnit bottomWidth = computeBorderImageSide(ninePieceImage.borderSlices().bottom(), style->borderBottomWidth(), bottomSlice, borderImageRect.height(), renderView);
+ LayoutUnit leftWidth = computeBorderImageSide(ninePieceImage.borderSlices().left(), style->borderLeftWidth(), leftSlice, borderImageRect.width(), renderView);
// Reduce the widths if they're too large.
// The spec says: Given Lwidth as the width of the border image area, Lheight as its height, and Wside as the border image width
@@ -1755,27 +1843,27 @@ void RenderBoxModelObject::paintBorder(const PaintInfo& info, const LayoutRect&
return;
BorderEdge edges[4];
- getBorderEdgeInfo(edges, includeLogicalLeftEdge, includeLogicalRightEdge);
-
- RoundedRect outerBorder = style->getRoundedBorderFor(rect, includeLogicalLeftEdge, includeLogicalRightEdge);
+ getBorderEdgeInfo(edges, style, includeLogicalLeftEdge, includeLogicalRightEdge);
+ RoundedRect outerBorder = style->getRoundedBorderFor(rect, view(), includeLogicalLeftEdge, includeLogicalRightEdge);
RoundedRect innerBorder = style->getRoundedInnerBorderFor(rect, includeLogicalLeftEdge, includeLogicalRightEdge);
bool haveAlphaColor = false;
bool haveAllSolidEdges = true;
- bool allEdgesVisible = true;
+ bool haveAllDoubleEdges = true;
+ int numEdgesVisible = 4;
bool allEdgesShareColor = true;
int firstVisibleEdge = -1;
for (int i = BSTop; i <= BSLeft; ++i) {
const BorderEdge& currEdge = edges[i];
if (currEdge.presentButInvisible()) {
- allEdgesVisible = false;
+ --numEdgesVisible;
allEdgesShareColor = false;
continue;
}
if (!currEdge.width) {
- allEdgesVisible = false;
+ --numEdgesVisible;
continue;
}
@@ -1789,6 +1877,9 @@ void RenderBoxModelObject::paintBorder(const PaintInfo& info, const LayoutRect&
if (currEdge.style != SOLID)
haveAllSolidEdges = false;
+
+ if (currEdge.style != DOUBLE)
+ haveAllDoubleEdges = false;
}
// If no corner intersects the clip region, we can pretend outerBorder is
@@ -1797,9 +1888,10 @@ void RenderBoxModelObject::paintBorder(const PaintInfo& info, const LayoutRect&
outerBorder.setRadii(RoundedRect::Radii());
// isRenderable() check avoids issue described in https://bugs.webkit.org/show_bug.cgi?id=38787
- if (haveAllSolidEdges && allEdgesShareColor && innerBorder.isRenderable()) {
- // Fast path for drawing all solid edges.
- if (allEdgesVisible && (outerBorder.isRounded() || haveAlphaColor)) {
+ if ((haveAllSolidEdges || haveAllDoubleEdges) && allEdgesShareColor && innerBorder.isRenderable()) {
+ // Fast path for drawing all solid edges and all unrounded double edges
+ if (numEdgesVisible == 4 && (outerBorder.isRounded() || haveAlphaColor)
+ && (haveAllSolidEdges || (!outerBorder.isRounded() && !innerBorder.isRounded()))) {
Path path;
if (outerBorder.isRounded() && bleedAvoidance != BackgroundBleedUseTransparencyLayer)
@@ -1807,6 +1899,45 @@ void RenderBoxModelObject::paintBorder(const PaintInfo& info, const LayoutRect&
else
path.addRect(outerBorder.rect());
+ if (haveAllDoubleEdges) {
+ IntRect innerThirdRect = outerBorder.rect();
+ IntRect outerThirdRect = outerBorder.rect();
+ for (int side = BSTop; side <= BSLeft; ++side) {
+ int outerWidth;
+ int innerWidth;
+ edges[side].getDoubleBorderStripeWidths(outerWidth, innerWidth);
+
+ if (side == BSTop) {
+ innerThirdRect.shiftYEdgeTo(innerThirdRect.y() + innerWidth);
+ outerThirdRect.shiftYEdgeTo(outerThirdRect.y() + outerWidth);
+ } else if (side == BSBottom) {
+ innerThirdRect.setHeight(innerThirdRect.height() - innerWidth);
+ outerThirdRect.setHeight(outerThirdRect.height() - outerWidth);
+ } else if (side == BSLeft) {
+ innerThirdRect.shiftXEdgeTo(innerThirdRect.x() + innerWidth);
+ outerThirdRect.shiftXEdgeTo(outerThirdRect.x() + outerWidth);
+ } else {
+ innerThirdRect.setWidth(innerThirdRect.width() - innerWidth);
+ outerThirdRect.setWidth(outerThirdRect.width() - outerWidth);
+ }
+ }
+
+ RoundedRect outerThird = outerBorder;
+ RoundedRect innerThird = innerBorder;
+ innerThird.setRect(innerThirdRect);
+ outerThird.setRect(outerThirdRect);
+
+ if (outerThird.isRounded() && bleedAvoidance != BackgroundBleedUseTransparencyLayer)
+ path.addRoundedRect(outerThird);
+ else
+ path.addRect(outerThird.rect());
+
+ if (innerThird.isRounded() && bleedAvoidance != BackgroundBleedUseTransparencyLayer)
+ path.addRoundedRect(innerThird);
+ else
+ path.addRect(innerThird.rect());
+ }
+
if (innerBorder.isRounded())
path.addRoundedRect(innerBorder);
else
@@ -1818,7 +1949,7 @@ void RenderBoxModelObject::paintBorder(const PaintInfo& info, const LayoutRect&
return;
}
// Avoid creating transparent layers
- if (!allEdgesVisible && !outerBorder.isRounded() && haveAlphaColor) {
+ if (haveAllSolidEdges && numEdgesVisible != 4 && !outerBorder.isRounded() && haveAlphaColor) {
Path path;
for (int i = BSTop; i <= BSLeft; ++i) {
@@ -1848,7 +1979,8 @@ void RenderBoxModelObject::paintBorder(const PaintInfo& info, const LayoutRect&
graphicsContext->clipOutRoundedRect(innerBorder);
}
- bool antialias = shouldAntialiasLines(graphicsContext);
+ // If only one edge visible antialiasing doesn't create seams
+ bool antialias = shouldAntialiasLines(graphicsContext) || numEdgesVisible == 1;
if (haveAlphaColor)
paintTranslucentBorderSides(graphicsContext, style, outerBorder, innerBorder, edges, bleedAvoidance, includeLogicalLeftEdge, includeLogicalRightEdge, antialias);
else
@@ -2042,7 +2174,7 @@ void RenderBoxModelObject::paintBorder(const PaintInfo& info, const IntRect& rec
GraphicsContextStateSaver stateSaver(*graphicsContext, false);
if (style->hasBorderRadius()) {
- border.includeLogicalEdges(style->getRoundedBorderFor(border.rect()).radii(),
+ border.includeLogicalEdges(style->getRoundedBorderFor(border.rect(), view()).radii(),
horizontal, includeLogicalLeftEdge, includeLogicalRightEdge);
if (border.isRounded()) {
stateSaver.save();
@@ -2560,9 +2692,8 @@ void RenderBoxModelObject::clipBorderSideForComplexInnerPath(GraphicsContext* gr
graphicsContext->clipOutRoundedRect(calculateAdjustedInnerBorder(innerBorder, side));
}
-void RenderBoxModelObject::getBorderEdgeInfo(BorderEdge edges[], bool includeLogicalLeftEdge, bool includeLogicalRightEdge) const
+void RenderBoxModelObject::getBorderEdgeInfo(BorderEdge edges[], const RenderStyle* style, bool includeLogicalLeftEdge, bool includeLogicalRightEdge) const
{
- const RenderStyle* style = this->style();
bool horizontal = style->isHorizontalWritingMode();
edges[BSTop] = BorderEdge(style->borderTopWidth(),
@@ -2593,7 +2724,7 @@ void RenderBoxModelObject::getBorderEdgeInfo(BorderEdge edges[], bool includeLog
bool RenderBoxModelObject::borderObscuresBackgroundEdge(const FloatSize& contextScale) const
{
BorderEdge edges[4];
- getBorderEdgeInfo(edges);
+ getBorderEdgeInfo(edges, style());
for (int i = BSTop; i <= BSLeft; ++i) {
const BorderEdge& currEdge = edges[i];
@@ -2616,7 +2747,7 @@ bool RenderBoxModelObject::borderObscuresBackground() const
return false;
BorderEdge edges[4];
- getBorderEdgeInfo(edges);
+ getBorderEdgeInfo(edges, style());
for (int i = BSTop; i <= BSLeft; ++i) {
const BorderEdge& currEdge = edges[i];
@@ -2674,16 +2805,16 @@ bool RenderBoxModelObject::boxShadowShouldBeAppliedToBackground(BackgroundBleedA
return true;
}
-static inline LayoutRect areaCastingShadowInHole(const LayoutRect& holeRect, int shadowBlur, int shadowSpread, const LayoutSize& shadowOffset)
+static inline IntRect areaCastingShadowInHole(const IntRect& holeRect, int shadowBlur, int shadowSpread, const IntSize& shadowOffset)
{
- LayoutRect bounds(holeRect);
+ IntRect bounds(holeRect);
bounds.inflate(shadowBlur);
if (shadowSpread < 0)
bounds.inflate(-shadowSpread);
- LayoutRect offsetBounds = bounds;
+ IntRect offsetBounds = bounds;
offsetBounds.move(-shadowOffset);
return unionRect(bounds, offsetBounds);
}
@@ -2696,7 +2827,7 @@ void RenderBoxModelObject::paintBoxShadow(const PaintInfo& info, const LayoutRec
return;
RoundedRect border = (shadowStyle == Inset) ? s->getRoundedInnerBorderFor(paintRect, includeLogicalLeftEdge, includeLogicalRightEdge)
- : s->getRoundedBorderFor(paintRect, includeLogicalLeftEdge, includeLogicalRightEdge);
+ : s->getRoundedBorderFor(paintRect, view(), includeLogicalLeftEdge, includeLogicalRightEdge);
bool hasBorderRadius = s->hasBorderRadius();
bool isHorizontal = s->isHorizontalWritingMode();
@@ -2706,9 +2837,9 @@ void RenderBoxModelObject::paintBoxShadow(const PaintInfo& info, const LayoutRec
if (shadow->style() != shadowStyle)
continue;
- LayoutSize shadowOffset(shadow->x(), shadow->y());
- LayoutUnit shadowBlur = shadow->blur();
- LayoutUnit shadowSpread = shadow->spread();
+ IntSize shadowOffset(shadow->x(), shadow->y());
+ int shadowBlur = shadow->blur();
+ int shadowSpread = shadow->spread();
if (shadowOffset.isZero() && !shadowBlur && !shadowSpread)
continue;
@@ -2721,7 +2852,7 @@ void RenderBoxModelObject::paintBoxShadow(const PaintInfo& info, const LayoutRec
if (fillRect.isEmpty())
continue;
- LayoutRect shadowRect(border.rect());
+ IntRect shadowRect(border.rect());
shadowRect.inflate(shadowBlur + shadowSpread);
shadowRect.move(shadowOffset);
@@ -2730,7 +2861,7 @@ void RenderBoxModelObject::paintBoxShadow(const PaintInfo& info, const LayoutRec
// Move the fill just outside the clip, adding 1 pixel separation so that the fill does not
// bleed in (due to antialiasing) if the context is transformed.
- LayoutSize extraOffset(paintRect.width() + max<LayoutUnit>(0, shadowOffset.width()) + shadowBlur + 2 * shadowSpread + 1, 0);
+ IntSize extraOffset(paintRect.pixelSnappedWidth() + max(0, shadowOffset.width()) + shadowBlur + 2 * shadowSpread + 1, 0);
shadowOffset -= extraOffset;
fillRect.move(extraOffset);
@@ -2752,7 +2883,7 @@ void RenderBoxModelObject::paintBoxShadow(const PaintInfo& info, const LayoutRec
if (!rectToClipOut.isEmpty())
context->clipOutRoundedRect(rectToClipOut);
- RoundedRect influenceRect(pixelSnappedIntRect(shadowRect), border.radii());
+ RoundedRect influenceRect(shadowRect, border.radii());
influenceRect.expandRadii(2 * shadowBlur + shadowSpread);
if (allCornersClippedOut(influenceRect, info.rect))
context->fillRect(fillRect.rect(), Color::black, s->colorSpace());
@@ -2761,7 +2892,7 @@ void RenderBoxModelObject::paintBoxShadow(const PaintInfo& info, const LayoutRec
context->fillRoundedRect(fillRect, Color::black, s->colorSpace());
}
} else {
- LayoutRect rectToClipOut = border.rect();
+ IntRect rectToClipOut = border.rect();
// If the box is opaque, it is unnecessary to clip it out. However, doing so saves time
// when painting the shadow. On the other hand, it introduces subpixel gaps along the
@@ -2776,12 +2907,12 @@ void RenderBoxModelObject::paintBoxShadow(const PaintInfo& info, const LayoutRec
}
if (!rectToClipOut.isEmpty())
- context->clipOut(pixelSnappedIntRect(rectToClipOut));
+ context->clipOut(rectToClipOut);
context->fillRect(fillRect.rect(), Color::black, s->colorSpace());
}
} else {
// Inset shadow.
- LayoutRect holeRect(border.rect());
+ IntRect holeRect(border.rect());
holeRect.inflate(-shadowSpread);
if (holeRect.isEmpty()) {
@@ -2794,24 +2925,24 @@ void RenderBoxModelObject::paintBoxShadow(const PaintInfo& info, const LayoutRec
if (!includeLogicalLeftEdge) {
if (isHorizontal) {
- holeRect.move(-max<LayoutUnit>(shadowOffset.width(), 0) - shadowBlur, 0);
- holeRect.setWidth(holeRect.width() + max<LayoutUnit>(shadowOffset.width(), 0) + shadowBlur);
+ holeRect.move(-max(shadowOffset.width(), 0) - shadowBlur, 0);
+ holeRect.setWidth(holeRect.width() + max(shadowOffset.width(), 0) + shadowBlur);
} else {
- holeRect.move(0, -max<LayoutUnit>(shadowOffset.height(), 0) - shadowBlur);
- holeRect.setHeight(holeRect.height() + max<LayoutUnit>(shadowOffset.height(), 0) + shadowBlur);
+ holeRect.move(0, -max(shadowOffset.height(), 0) - shadowBlur);
+ holeRect.setHeight(holeRect.height() + max(shadowOffset.height(), 0) + shadowBlur);
}
}
if (!includeLogicalRightEdge) {
if (isHorizontal)
- holeRect.setWidth(holeRect.width() - min<LayoutUnit>(shadowOffset.width(), 0) + shadowBlur);
+ holeRect.setWidth(holeRect.width() - min(shadowOffset.width(), 0) + shadowBlur);
else
- holeRect.setHeight(holeRect.height() - min<LayoutUnit>(shadowOffset.height(), 0) + shadowBlur);
+ holeRect.setHeight(holeRect.height() - min(shadowOffset.height(), 0) + shadowBlur);
}
Color fillColor(shadowColor.red(), shadowColor.green(), shadowColor.blue(), 255);
- LayoutRect outerRect = areaCastingShadowInHole(border.rect(), shadowBlur, shadowSpread, shadowOffset);
- RoundedRect roundedHole(pixelSnappedIntRect(holeRect), border.radii());
+ IntRect outerRect = areaCastingShadowInHole(border.rect(), shadowBlur, shadowSpread, shadowOffset);
+ RoundedRect roundedHole(holeRect, border.radii());
GraphicsContextStateSaver stateSaver(*context);
if (hasBorderRadius) {
@@ -2822,7 +2953,7 @@ void RenderBoxModelObject::paintBoxShadow(const PaintInfo& info, const LayoutRec
} else
context->clip(border.rect());
- LayoutSize extraOffset(2 * paintRect.width() + max<LayoutUnit>(0, shadowOffset.width()) + shadowBlur - 2 * shadowSpread + 1, 0);
+ IntSize extraOffset(2 * paintRect.pixelSnappedWidth() + max(0, shadowOffset.width()) + shadowBlur - 2 * shadowSpread + 1, 0);
context->translate(extraOffset.width(), extraOffset.height());
shadowOffset -= extraOffset;
@@ -2831,7 +2962,7 @@ void RenderBoxModelObject::paintBoxShadow(const PaintInfo& info, const LayoutRec
else
context->setShadow(shadowOffset, shadowBlur, shadowColor, s->colorSpace());
- context->fillRectWithRoundedHole(pixelSnappedIntRect(outerRect), roundedHole, fillColor, s->colorSpace());
+ context->fillRectWithRoundedHole(outerRect, roundedHole, fillColor, s->colorSpace());
}
}
}