Skip to content
Permalink
Browse files
feComposite filter does not clip the paint rect to its effect rect wh…
…en the operator is 'in' or 'atop'

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

Patch by Said Abou-Hallawa <sabouhallawa@apple.com> on 2015-06-09
Reviewed by Darin Adler.

Source/WebCore:

There was bug in calculating the absolutePaintRect of the feComposite filter
when the operator is equal to 'in' or 'atop'. The absolutePaintRect was set
to the absolutePaintRect of the background FilterEffect which is correct.
What was missing is clipping this rectangle to the maxEffectRect of the
filter which we do for other operators.

Tests: svg/filters/feComposite-background-rect-control-operators.svg

* platform/graphics/IntRect.h:
(WebCore::operator-=):
(WebCore::operator-): Add new operators to IntRect.

* platform/graphics/filters/FEComposite.cpp:
(WebCore::FEComposite::determineAbsolutePaintRect): Make sure the filter
absolutePaintRect is clipped to maxEffectRect for all operators.

(WebCore::FEComposite::platformApplySoftware): Code clean-up.

* platform/graphics/filters/FilterEffect.cpp:
(WebCore::FilterEffect::determineAbsolutePaintRect): Move the clipping
part to a separate function.

(WebCore::FilterEffect::clipAbsolutePaintRect): Clip the absolutePaintRect
to the maxEffectRect of the filter.

* platform/graphics/filters/FilterEffect.h:

LayoutTests:

* svg/filters/feComposite-background-rect-control-operators-expected.svg: Added.
* svg/filters/feComposite-background-rect-control-operators.svg: Added.
Ensure the painting rect of the feComposite filter with operator 'in' or
'atop' is clipped to its bounding rectangle

Canonical link: https://commits.webkit.org/163864@main
git-svn-id: https://svn.webkit.org/repository/webkit/trunk@185392 268f45cc-cd09-0410-ab3c-d52691b4dbfc
  • Loading branch information
Said Abou-Hallawa authored and webkit-commit-queue committed Jun 9, 2015
1 parent 5bbe6a2 commit c0f504d0844464c9eb672a3bd870b57e16879728
Showing 8 changed files with 91 additions and 12 deletions.
@@ -1,3 +1,15 @@
2015-06-09 Said Abou-Hallawa <sabouhallawa@apple.com>

feComposite filter does not clip the paint rect to its effect rect when the operator is 'in' or 'atop'
https://bugs.webkit.org/show_bug.cgi?id=137856

Reviewed by Darin Adler.

* svg/filters/feComposite-background-rect-control-operators-expected.svg: Added.
* svg/filters/feComposite-background-rect-control-operators.svg: Added.
Ensure the painting rect of the feComposite filter with operator 'in' or
'atop' is clipped to its bounding rectangle

2015-06-09 Yusuke Suzuki <utatane.tea@gmail.com>

Introduce getter definition into static hash tables and use it for getters in RegExp.prototype.
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
@@ -1,3 +1,37 @@
2015-06-09 Said Abou-Hallawa <sabouhallawa@apple.com>

feComposite filter does not clip the paint rect to its effect rect when the operator is 'in' or 'atop'
https://bugs.webkit.org/show_bug.cgi?id=137856

Reviewed by Darin Adler.

There was bug in calculating the absolutePaintRect of the feComposite filter
when the operator is equal to 'in' or 'atop'. The absolutePaintRect was set
to the absolutePaintRect of the background FilterEffect which is correct.
What was missing is clipping this rectangle to the maxEffectRect of the
filter which we do for other operators.

Tests: svg/filters/feComposite-background-rect-control-operators.svg

* platform/graphics/IntRect.h:
(WebCore::operator-=):
(WebCore::operator-): Add new operators to IntRect.

* platform/graphics/filters/FEComposite.cpp:
(WebCore::FEComposite::determineAbsolutePaintRect): Make sure the filter
absolutePaintRect is clipped to maxEffectRect for all operators.

(WebCore::FEComposite::platformApplySoftware): Code clean-up.

* platform/graphics/filters/FilterEffect.cpp:
(WebCore::FilterEffect::determineAbsolutePaintRect): Move the clipping
part to a separate function.

(WebCore::FilterEffect::clipAbsolutePaintRect): Clip the absolutePaintRect
to the maxEffectRect of the filter.

* platform/graphics/filters/FilterEffect.h:

2015-06-09 Matt Rajca <mrajca@apple.com>

Implement MediaSessionManager to keep track of all MediaSessions.
@@ -216,6 +216,18 @@ inline bool operator!=(const IntRect& a, const IntRect& b)
return a.location() != b.location() || a.size() != b.size();
}

inline IntRect& operator-=(IntRect& r, const IntPoint& offset)
{
r.move(-offset.x(), -offset.y());
return r;
}

inline IntRect operator-(const IntRect& r, const IntPoint& offset)
{
IntRect t = r;
return t -= offset;
}

#if USE(CG)
WEBCORE_EXPORT IntRect enclosingIntRect(const CGRect&);
#endif
@@ -235,6 +235,7 @@ void FEComposite::determineAbsolutePaintRect()
// For In and Atop the first effect just influences the result of
// the second effect. So just use the absolute paint rect of the second effect here.
setAbsolutePaintRect(inputEffect(1)->absolutePaintRect());
clipAbsolutePaintRect();
return;
case FECOMPOSITE_OPERATOR_ARITHMETIC:
// Arithmetic may influnce the compele filter primitive region. So we can't
@@ -290,13 +291,11 @@ void FEComposite::platformApplySoftware()
destinationRect.intersect(absolutePaintRect());
if (destinationRect.isEmpty())
break;
IntPoint destinationPoint(destinationRect.x() - absolutePaintRect().x(), destinationRect.y() - absolutePaintRect().y());
IntRect sourceRect(IntPoint(destinationRect.x() - in->absolutePaintRect().x(),
destinationRect.y() - in->absolutePaintRect().y()), destinationRect.size());
IntRect source2Rect(IntPoint(destinationRect.x() - in2->absolutePaintRect().x(),
destinationRect.y() - in2->absolutePaintRect().y()), destinationRect.size());
filterContext->drawImageBuffer(imageBuffer2, ColorSpaceDeviceRGB, IntRect(destinationPoint, source2Rect.size()), source2Rect);
filterContext->drawImageBuffer(imageBuffer, ColorSpaceDeviceRGB, IntRect(destinationPoint, sourceRect.size()), sourceRect, CompositeSourceIn);
IntRect adjustedDestinationRect = destinationRect - absolutePaintRect().location();
IntRect sourceRect = destinationRect - in->absolutePaintRect().location();
IntRect source2Rect = destinationRect - in2->absolutePaintRect().location();
filterContext->drawImageBuffer(imageBuffer2, ColorSpaceDeviceRGB, adjustedDestinationRect, source2Rect);
filterContext->drawImageBuffer(imageBuffer, ColorSpaceDeviceRGB, adjustedDestinationRect, sourceRect, CompositeSourceIn);
break;
}
case FECOMPOSITE_OPERATOR_OUT:
@@ -56,16 +56,18 @@ FilterEffect::~FilterEffect()
void FilterEffect::determineAbsolutePaintRect()
{
m_absolutePaintRect = IntRect();
unsigned size = m_inputEffects.size();
for (unsigned i = 0; i < size; ++i)
m_absolutePaintRect.unite(m_inputEffects.at(i)->absolutePaintRect());

for (auto& effect : m_inputEffects)
m_absolutePaintRect.unite(effect->absolutePaintRect());
clipAbsolutePaintRect();
}

void FilterEffect::clipAbsolutePaintRect()
{
// Filters in SVG clip to primitive subregion, while CSS doesn't.
if (m_clipsToBounds)
m_absolutePaintRect.intersect(enclosingIntRect(m_maxEffectRect));
else
m_absolutePaintRect.unite(enclosingIntRect(m_maxEffectRect));

}

IntRect FilterEffect::requestedRegionOfInputImageData(const IntRect& effectRect) const
@@ -177,6 +177,8 @@ class FilterEffect : public RefCounted<FilterEffect> {
// If a pre-multiplied image, check every pixel for validity and correct if necessary.
void forceValidPreMultipliedPixels();

void clipAbsolutePaintRect();

private:
std::unique_ptr<ImageBuffer> m_imageBufferResult;
RefPtr<Uint8ClampedArray> m_unmultipliedImageResult;

0 comments on commit c0f504d

Please sign in to comment.