Commit 07d7fc6a authored by mvujovic@adobe.com's avatar mvujovic@adobe.com

[CSS Filters] CSS opacity property clips filter outsets

https://bugs.webkit.org/show_bug.cgi?id=106549

Reviewed by Dirk Schulze.

Source/WebCore:

Expand the transparencyClipBox for filter outsets and pass the filter output rect instead of
the input rect to beginTransparencyLayers for clipping. Details below.

Test: css3/filters/css-opacity-with-drop-shadow.html

* rendering/RenderLayer.cpp:
(WebCore):
(WebCore::RenderLayer::setFilterBackendNeedsRepaintingInRect):
    Replace filter outset calcuation with a call to expandRectForFilterOutsets.
(WebCore::expandRectForFilterOutsets):
    New method to factor out repeated filter outset calculation code.
(WebCore::transparencyClipBox):
    After expanding the clip rect for descendants and reflection, expand it for filter
    outsets, so they don't get clipped when we begin a transparency layer.
(WebCore::RenderLayer::paintLayerContents):
    Pass paintingInfo.paintDirtyRect instead of localPaintingInfo.paintDirtyRect to
    beginTransparencyLayers for clipping. localPaintingInfo.paintDirtyRect (aka the filter
    input rect) does not contain filter outsets, so they would get clipped. Now, we pass
    paintingInfo.paintDirtyRect (the filter output rect), which includes the filter outsets.
(WebCore::RenderLayer::calculateLayerBounds):
    Replace filter outset calcuation with a call to expandRectForFilterOutsets.
* rendering/RenderLayer.h:
(RenderLayer):

LayoutTests:

Add a reftest to verify that an element's drop shadow filter is not clipped when a CSS
opacity property is not applied.

* css3/filters/css-opacity-with-drop-shadow-expected.html: Added.
* css3/filters/css-opacity-with-drop-shadow.html: Added.


git-svn-id: http://svn.webkit.org/repository/webkit/trunk@140702 268f45cc-cd09-0410-ab3c-d52691b4dbfc
parent f0e3c45f
2013-01-24 Max Vujovic <mvujovic@adobe.com>
[CSS Filters] CSS opacity property clips filter outsets
https://bugs.webkit.org/show_bug.cgi?id=106549
Reviewed by Dirk Schulze.
Add a reftest to verify that an element's drop shadow filter is not clipped when a CSS
opacity property is not applied.
* css3/filters/css-opacity-with-drop-shadow-expected.html: Added.
* css3/filters/css-opacity-with-drop-shadow.html: Added.
2013-01-24 Christophe Dumez <christophe.dumez@intel.com>
Unreviewed EFL rebaseline.
<!DOCTYPE html>
<html>
<head>
<title>This test verifies that an element's drop shadow filter is not clipped when a CSS opacity property is applied.</title>
<!--
This is the reference file for the the test.
If the associated test passes, you should see a gray square and a light green square.
-->
<style>
body {
margin: 0;
}
#filtered {
background-color: black;
opacity: 0.5;
width: 100px;
height: 100px;
}
#drop-shadow {
background-color: #0f0;
opacity: 0.5;
position: absolute;
top: 110px;
left: 110px;
width: 100px;
height: 100px;
}
</style>
</head>
<body>
<div id="filtered"></div>
<div id="drop-shadow"></div>
</body>
<!DOCTYPE html>
<html>
<head>
<title>This test verifies that an element's drop shadow filter is not clipped when a CSS opacity property is applied.</title>
<!-- If the test passes, you should see a gray square and a light green square. -->
<style>
body {
margin: 0;
}
#filtered {
background-color: black;
opacity: 0.5;
-webkit-filter: drop-shadow(110px 110px 0 #0f0);
width: 100px;
height: 100px;
}
</style>
</head>
<body>
<div id="filtered"></div>
</body>
2013-01-24 Max Vujovic <mvujovic@adobe.com>
[CSS Filters] CSS opacity property clips filter outsets
https://bugs.webkit.org/show_bug.cgi?id=106549
Reviewed by Dirk Schulze.
Expand the transparencyClipBox for filter outsets and pass the filter output rect instead of
the input rect to beginTransparencyLayers for clipping. Details below.
Test: css3/filters/css-opacity-with-drop-shadow.html
* rendering/RenderLayer.cpp:
(WebCore):
(WebCore::RenderLayer::setFilterBackendNeedsRepaintingInRect):
Replace filter outset calcuation with a call to expandRectForFilterOutsets.
(WebCore::expandRectForFilterOutsets):
New method to factor out repeated filter outset calculation code.
(WebCore::transparencyClipBox):
After expanding the clip rect for descendants and reflection, expand it for filter
outsets, so they don't get clipped when we begin a transparency layer.
(WebCore::RenderLayer::paintLayerContents):
Pass paintingInfo.paintDirtyRect instead of localPaintingInfo.paintDirtyRect to
beginTransparencyLayers for clipping. localPaintingInfo.paintDirtyRect (aka the filter
input rect) does not contain filter outsets, so they would get clipped. Now, we pass
paintingInfo.paintDirtyRect (the filter output rect), which includes the filter outsets.
(WebCore::RenderLayer::calculateLayerBounds):
Replace filter outset calcuation with a call to expandRectForFilterOutsets.
* rendering/RenderLayer.h:
(RenderLayer):
2013-01-24 Ryosuke Niwa <rniwa@webkit.org>
Fix a typo after r139838.
......@@ -1362,24 +1362,28 @@ RenderLayer* RenderLayer::enclosingFilterRepaintLayer() const
return 0;
}
static inline void expandRectForFilterOutsets(LayoutRect& rect, const RenderLayerModelObject* renderer)
{
ASSERT(renderer);
if (!renderer->style()->hasFilterOutsets())
return;
int topOutset;
int rightOutset;
int bottomOutset;
int leftOutset;
renderer->style()->getFilterOutsets(topOutset, rightOutset, bottomOutset, leftOutset);
rect.move(-leftOutset, -topOutset);
rect.expand(leftOutset + rightOutset, topOutset + bottomOutset);
}
void RenderLayer::setFilterBackendNeedsRepaintingInRect(const LayoutRect& rect, bool immediate)
{
if (rect.isEmpty())
return;
LayoutRect rectForRepaint = rect;
#if ENABLE(CSS_FILTERS)
if (renderer()->style()->hasFilterOutsets()) {
int topOutset;
int rightOutset;
int bottomOutset;
int leftOutset;
renderer()->style()->getFilterOutsets(topOutset, rightOutset, bottomOutset, leftOutset);
rectForRepaint.move(-leftOutset, -topOutset);
rectForRepaint.expand(leftOutset + rightOutset, topOutset + bottomOutset);
}
#endif
expandRectForFilterOutsets(rectForRepaint, renderer());
RenderLayerFilterInfo* filterInfo = this->filterInfo();
ASSERT(filterInfo);
......@@ -1547,11 +1551,17 @@ static LayoutRect transparencyClipBox(const RenderLayer* layer, const RenderLaye
LayoutRect clipRect = layer->boundingBox(layer);
expandClipRectForDescendantsAndReflection(clipRect, layer, layer, paintBehavior);
#if ENABLE(CSS_FILTERS)
expandRectForFilterOutsets(clipRect, layer->renderer());
#endif
return transform.mapRect(clipRect);
}
LayoutRect clipRect = layer->boundingBox(rootLayer);
expandClipRectForDescendantsAndReflection(clipRect, layer, rootLayer, paintBehavior);
#if ENABLE(CSS_FILTERS)
expandRectForFilterOutsets(clipRect, layer->renderer());
#endif
return clipRect;
}
......@@ -3701,7 +3711,7 @@ void RenderLayer::paintLayerContents(GraphicsContext* context, const LayerPainti
if (shouldPaintContent && !selectionOnly) {
// Begin transparency layers lazily now that we know we have to paint something.
if (haveTransparency)
beginTransparencyLayers(transparencyLayerContext, localPaintingInfo.rootLayer, localPaintingInfo.paintDirtyRect, localPaintingInfo.paintBehavior);
beginTransparencyLayers(transparencyLayerContext, localPaintingInfo.rootLayer, paintingInfo.paintDirtyRect, localPaintingInfo.paintBehavior);
if (useClipRect) {
// Paint our background first, before painting any child layers.
......@@ -3728,7 +3738,7 @@ void RenderLayer::paintLayerContents(GraphicsContext* context, const LayerPainti
if (shouldPaintContent && !clipRectToApply.isEmpty()) {
// Begin transparency layers lazily now that we know we have to paint something.
if (haveTransparency)
beginTransparencyLayers(transparencyLayerContext, localPaintingInfo.rootLayer, localPaintingInfo.paintDirtyRect, localPaintingInfo.paintBehavior);
beginTransparencyLayers(transparencyLayerContext, localPaintingInfo.rootLayer, paintingInfo.paintDirtyRect, localPaintingInfo.paintBehavior);
if (useClipRect) {
// Set up the clip used when painting our children.
......@@ -4961,15 +4971,8 @@ IntRect RenderLayer::calculateLayerBounds(const RenderLayer* ancestorLayer, cons
// FIXME: We can optimize the size of the composited layers, by not enlarging
// filtered areas with the outsets if we know that the filter is going to render in hardware.
// https://bugs.webkit.org/show_bug.cgi?id=81239
if ((flags & IncludeLayerFilterOutsets) && renderer->style()->hasFilterOutsets()) {
int topOutset;
int rightOutset;
int bottomOutset;
int leftOutset;
renderer->style()->getFilterOutsets(topOutset, rightOutset, bottomOutset, leftOutset);
unionBounds.move(-leftOutset, -topOutset);
unionBounds.expand(leftOutset + rightOutset, topOutset + bottomOutset);
}
if (flags & IncludeLayerFilterOutsets)
expandRectForFilterOutsets(unionBounds, renderer);
#endif
if ((flags & IncludeSelfTransform) && paintsWithTransform(PaintBehaviorNormal)) {
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment