Title: [185392] trunk
Revision
185392
Author
[email protected]
Date
2015-06-09 16:24:12 -0700 (Tue, 09 Jun 2015)

Log Message

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

Patch by Said Abou-Hallawa <[email protected]> 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

Modified Paths

Added Paths

Diff

Modified: trunk/LayoutTests/ChangeLog (185391 => 185392)


--- trunk/LayoutTests/ChangeLog	2015-06-09 23:22:19 UTC (rev 185391)
+++ trunk/LayoutTests/ChangeLog	2015-06-09 23:24:12 UTC (rev 185392)
@@ -1,3 +1,15 @@
+2015-06-09  Said Abou-Hallawa  <[email protected]>
+
+        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  <[email protected]>
 
         Introduce getter definition into static hash tables and use it for getters in RegExp.prototype.

Added: trunk/LayoutTests/svg/filters/feComposite-background-rect-control-operators-expected.svg (0 => 185392)


--- trunk/LayoutTests/svg/filters/feComposite-background-rect-control-operators-expected.svg	                        (rev 0)
+++ trunk/LayoutTests/svg/filters/feComposite-background-rect-control-operators-expected.svg	2015-06-09 23:24:12 UTC (rev 185392)
@@ -0,0 +1,4 @@
+<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="200" height="100">
+  <rect x="20" y="20" width="60" height="60" fill="green"/>
+  <rect x="120" y="20" width="60" height="60" fill="green"/>
+</svg>
\ No newline at end of file

Added: trunk/LayoutTests/svg/filters/feComposite-background-rect-control-operators.svg (0 => 185392)


--- trunk/LayoutTests/svg/filters/feComposite-background-rect-control-operators.svg	                        (rev 0)
+++ trunk/LayoutTests/svg/filters/feComposite-background-rect-control-operators.svg	2015-06-09 23:24:12 UTC (rev 185392)
@@ -0,0 +1,14 @@
+<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="200" height="100">
+  <filter id="filter-in" filterUnits="objectBoundingBox" primitiveUnits="objectBoundingBox" x="0" y="0" width="1" height="1">
+    <feFlood flood-color="orange" x="0" y="0" width="0.9" height="0.9" result="flood-orange"/>
+    <feFlood flood-color="green" x="0.1" y="0.1" width="0.9" height="0.9" result="flood-green"/>
+    <feComposite x="0.2" y="0.2" width="0.6" height="0.6" operator="in" in="flood-green" in2="flood-orange"/>
+  </filter>
+  <filter id="filter-atop" filterUnits="objectBoundingBox" primitiveUnits="objectBoundingBox" x="0" y="0" width="1" height="1">
+    <feFlood flood-color="orange" x="0" y="0" width="0.8" height="0.8" result="flood-orange"/>
+    <feFlood flood-color="green" x="0.2" y="0.2" width="0.8" height="0.8" result="flood-green"/>
+    <feComposite x="0.2" y="0.2" width="0.8" height="0.8" operator="atop" in="flood-green" in2="flood-orange"/>
+  </filter>
+  <rect x=  "0" y="0" width="100" height="100" fill="red" filter="url(#filter-in)"/>
+  <rect x="100" y="0" width="100" height="100" fill="red" filter="url(#filter-atop)"/>
+</svg>
\ No newline at end of file

Modified: trunk/Source/WebCore/ChangeLog (185391 => 185392)


--- trunk/Source/WebCore/ChangeLog	2015-06-09 23:22:19 UTC (rev 185391)
+++ trunk/Source/WebCore/ChangeLog	2015-06-09 23:24:12 UTC (rev 185392)
@@ -1,3 +1,37 @@
+2015-06-09  Said Abou-Hallawa  <[email protected]>
+
+        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  <[email protected]>
 
         Implement MediaSessionManager to keep track of all MediaSessions.

Modified: trunk/Source/WebCore/platform/graphics/IntRect.h (185391 => 185392)


--- trunk/Source/WebCore/platform/graphics/IntRect.h	2015-06-09 23:22:19 UTC (rev 185391)
+++ trunk/Source/WebCore/platform/graphics/IntRect.h	2015-06-09 23:24:12 UTC (rev 185392)
@@ -216,6 +216,18 @@
     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

Modified: trunk/Source/WebCore/platform/graphics/filters/FEComposite.cpp (185391 => 185392)


--- trunk/Source/WebCore/platform/graphics/filters/FEComposite.cpp	2015-06-09 23:22:19 UTC (rev 185391)
+++ trunk/Source/WebCore/platform/graphics/filters/FEComposite.cpp	2015-06-09 23:24:12 UTC (rev 185392)
@@ -235,6 +235,7 @@
         // 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 @@
         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:

Modified: trunk/Source/WebCore/platform/graphics/filters/FilterEffect.cpp (185391 => 185392)


--- trunk/Source/WebCore/platform/graphics/filters/FilterEffect.cpp	2015-06-09 23:22:19 UTC (rev 185391)
+++ trunk/Source/WebCore/platform/graphics/filters/FilterEffect.cpp	2015-06-09 23:24:12 UTC (rev 185392)
@@ -56,16 +56,18 @@
 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

Modified: trunk/Source/WebCore/platform/graphics/filters/FilterEffect.h (185391 => 185392)


--- trunk/Source/WebCore/platform/graphics/filters/FilterEffect.h	2015-06-09 23:22:19 UTC (rev 185391)
+++ trunk/Source/WebCore/platform/graphics/filters/FilterEffect.h	2015-06-09 23:24:12 UTC (rev 185392)
@@ -177,6 +177,8 @@
     // 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;
_______________________________________________
webkit-changes mailing list
[email protected]
https://lists.webkit.org/mailman/listinfo/webkit-changes

Reply via email to