Filters aren't applied to elements in columns after the first
authordino@apple.com <dino@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Tue, 13 Jan 2015 23:22:21 +0000 (23:22 +0000)
committerdino@apple.com <dino@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Tue, 13 Jan 2015 23:22:21 +0000 (23:22 +0000)
https://bugs.webkit.org/show_bug.cgi?id=140331
Source/WebCore:

Reviewed by Simon Fraser.

The important bits of this change came from Simon.

Filters and clipping were not taking columns into
account when using their offset rectangles. The fix
is to recalculate the rects if you're in such a
situation.

Tests: fast/multicol/clip-in-columns.html
       fast/multicol/filter-in-columns.html

* rendering/RenderLayer.cpp:
(WebCore::RenderLayer::hasFilterThatIsPainting): New method used
to check if we're about to paint a filter.
(WebCore::RenderLayer::setupFilters): Use the new helper if possible.
(WebCore::RenderLayer::paintLayerContents): If we're in columns,
and we either have a clip or a filter, recalculate the offset rectangles.
* rendering/RenderLayer.h:

LayoutTests:

<rdar://problem/19313858>

Reviewed by Simon Fraser.

Tests for filters and clipping on a column other
than the first.

* fast/multicol/clip-in-columns-expected.html: Added.
* fast/multicol/clip-in-columns.html: Added.
* fast/multicol/filter-in-columns-expected.html: Added.
* fast/multicol/filter-in-columns.html: Added.

git-svn-id: https://svn.webkit.org/repository/webkit/trunk@178380 268f45cc-cd09-0410-ab3c-d52691b4dbfc

LayoutTests/ChangeLog
LayoutTests/fast/multicol/clip-in-columns-expected.html [new file with mode: 0644]
LayoutTests/fast/multicol/clip-in-columns.html [new file with mode: 0644]
LayoutTests/fast/multicol/filter-in-columns-expected.html [new file with mode: 0644]
LayoutTests/fast/multicol/filter-in-columns.html [new file with mode: 0644]
Source/WebCore/ChangeLog
Source/WebCore/rendering/RenderLayer.cpp
Source/WebCore/rendering/RenderLayer.h

index 0be16e5..f861f47 100644 (file)
@@ -1,3 +1,19 @@
+2015-01-13  Dean Jackson  <dino@apple.com>
+
+        Filters aren't applied to elements in columns after the first
+        https://bugs.webkit.org/show_bug.cgi?id=140331
+        <rdar://problem/19313858>
+
+        Reviewed by Simon Fraser.
+
+        Tests for filters and clipping on a column other
+        than the first.
+
+        * fast/multicol/clip-in-columns-expected.html: Added.
+        * fast/multicol/clip-in-columns.html: Added.
+        * fast/multicol/filter-in-columns-expected.html: Added.
+        * fast/multicol/filter-in-columns.html: Added.
+
 2015-01-13  Yusuke Suzuki  <utatane.tea@gmail.com>
 
         DFG can call PutByValDirect for generic arrays
diff --git a/LayoutTests/fast/multicol/clip-in-columns-expected.html b/LayoutTests/fast/multicol/clip-in-columns-expected.html
new file mode 100644 (file)
index 0000000..c533ccb
--- /dev/null
@@ -0,0 +1,30 @@
+<style>
+section {
+    height: 200px;
+    width: 300px;
+    position: relative;
+}
+
+p {
+    padding: 0;
+    margin: 0;
+}
+
+.break-after {
+    page-break-after: always;
+}
+
+.clipped {
+    position: absolute;
+    left: 150px;
+    top: 0;
+    width: 150px;
+    background: blue;
+    color: white;
+    -webkit-clip-path: polygon(5px 5px, 60px 5px, 60px 20px, 5px 20px);
+}
+</style>
+<section>
+<p class="break-after">Hello</p>
+<p class="clipped">World</p>
+</section>
\ No newline at end of file
diff --git a/LayoutTests/fast/multicol/clip-in-columns.html b/LayoutTests/fast/multicol/clip-in-columns.html
new file mode 100644 (file)
index 0000000..b0b60e0
--- /dev/null
@@ -0,0 +1,27 @@
+<style>
+section {
+    columns: 2;
+    column-gap: 0;
+    height: 200px;
+    width: 300px;
+}
+
+p {
+    padding: 0;
+    margin: 0;
+}
+
+.break-after {
+    page-break-after: always;
+}
+
+.clipped {
+    background: blue;
+    color: white;
+    -webkit-clip-path: polygon(5px 5px, 60px 5px, 60px 20px, 5px 20px);
+}
+</style>
+<section>
+<p class="break-after">Hello</p>
+<p class="clipped">World</p>
+</section>
\ No newline at end of file
diff --git a/LayoutTests/fast/multicol/filter-in-columns-expected.html b/LayoutTests/fast/multicol/filter-in-columns-expected.html
new file mode 100644 (file)
index 0000000..99afb2f
--- /dev/null
@@ -0,0 +1,29 @@
+<style>
+section {
+    height: 200px;
+    width: 300px;
+    position: relative;
+}
+
+p {
+    padding: 0;
+    margin: 0;
+}
+
+.break-after {
+    page-break-after: always;
+}
+
+.filtered {
+    position: absolute;
+    left: 150px;
+    top: 0;
+    width: 150px;
+    background: white;
+    -webkit-filter: invert();
+}
+</style>
+<section>
+<p class="break-after">Hello</p>
+<p class="filtered">World</p>
+</section>
\ No newline at end of file
diff --git a/LayoutTests/fast/multicol/filter-in-columns.html b/LayoutTests/fast/multicol/filter-in-columns.html
new file mode 100644 (file)
index 0000000..2ba8fd9
--- /dev/null
@@ -0,0 +1,26 @@
+<style>
+section {
+    columns: 2;
+    column-gap: 0;
+    height: 200px;
+    width: 300px;
+}
+
+p {
+    padding: 0;
+    margin: 0;
+}
+
+.break-after {
+    page-break-after: always;
+}
+
+.filtered {
+    background: white;
+    -webkit-filter: invert();
+}
+</style>
+<section>
+<p class="break-after">Hello</p>
+<p class="filtered">World</p>
+</section>
\ No newline at end of file
index ab2f62e..cb43c5d 100644 (file)
@@ -1,3 +1,28 @@
+2015-01-13  Dean Jackson  <dino@apple.com>
+
+        Filters aren't applied to elements in columns after the first
+        https://bugs.webkit.org/show_bug.cgi?id=140331
+
+        Reviewed by Simon Fraser.
+
+        The important bits of this change came from Simon.
+
+        Filters and clipping were not taking columns into
+        account when using their offset rectangles. The fix
+        is to recalculate the rects if you're in such a
+        situation.
+
+        Tests: fast/multicol/clip-in-columns.html
+               fast/multicol/filter-in-columns.html
+
+        * rendering/RenderLayer.cpp:
+        (WebCore::RenderLayer::hasFilterThatIsPainting): New method used
+        to check if we're about to paint a filter.
+        (WebCore::RenderLayer::setupFilters): Use the new helper if possible.
+        (WebCore::RenderLayer::paintLayerContents): If we're in columns,
+        and we either have a clip or a filter, recalculate the offset rectangles.
+        * rendering/RenderLayer.h:
+
 2015-01-13  Beth Dakin  <bdakin@apple.com>
 
         Should disable immediate actions for iTunes
index b583c90..64dc7b4 100644 (file)
@@ -3959,23 +3959,35 @@ bool RenderLayer::setupClipPath(GraphicsContext* context, const LayerPaintingInf
     return false;
 }
 
-std::unique_ptr<FilterEffectRendererHelper> RenderLayer::setupFilters(GraphicsContext* context, LayerPaintingInfo& paintingInfo, PaintLayerFlags paintFlags, const LayoutSize& offsetFromRoot, LayoutRect& rootRelativeBounds, bool& rootRelativeBoundsComputed)
+bool RenderLayer::hasFilterThatIsPainting(GraphicsContext* context, PaintLayerFlags paintFlags) const
 {
     if (context->paintingDisabled())
-        return nullptr;
+        return false;
 
     if (paintFlags & PaintLayerPaintingOverlayScrollbars)
-        return nullptr;
+        return false;
 
     FilterInfo* filterInfo = FilterInfo::getIfExists(*this);
     bool hasPaintedFilter = filterInfo && filterInfo->renderer() && paintsWithFilters();
     if (!hasPaintedFilter)
-        return nullptr;
+        return false;
 
     auto filterPainter = std::make_unique<FilterEffectRendererHelper>(hasPaintedFilter);
     if (!filterPainter->haveFilterEffect())
+        return false;
+
+    return true;
+}
+
+std::unique_ptr<FilterEffectRendererHelper> RenderLayer::setupFilters(GraphicsContext* context, LayerPaintingInfo& paintingInfo, PaintLayerFlags paintFlags, const LayoutSize& offsetFromRoot, LayoutRect& rootRelativeBounds, bool& rootRelativeBoundsComputed)
+{
+    if (!hasFilterThatIsPainting(context, paintFlags))
         return nullptr;
-    
+
+    FilterInfo* filterInfo = FilterInfo::getIfExists(*this);
+    bool hasPaintedFilter = filterInfo && filterInfo->renderer() && paintsWithFilters();
+    auto filterPainter = std::make_unique<FilterEffectRendererHelper>(hasPaintedFilter);
+
     LayoutRect filterRepaintRect = filterInfo->dirtySourceRect();
     filterRepaintRect.move(offsetFromRoot);
 
@@ -4094,12 +4106,15 @@ void RenderLayer::paintLayerContents(GraphicsContext* context, const LayerPainti
     bool needToAdjustSubpixelQuantization = setupFontSubpixelQuantization(context, didQuantizeFonts);
 
     // Apply clip-path to context.
-    bool hasClipPath = setupClipPath(context, paintingInfo, offsetFromRoot, rootRelativeBounds, rootRelativeBoundsComputed);
+    LayoutSize columnAwareOffsetFromRoot = offsetFromRoot;
+    if (renderer().flowThreadContainingBlock() && (renderer().hasClipPath() || hasFilterThatIsPainting(context, paintFlags)))
+        columnAwareOffsetFromRoot = toLayoutSize(convertToLayerCoords(paintingInfo.rootLayer, LayoutPoint(), AdjustForColumns));
+    bool hasClipPath = setupClipPath(context, paintingInfo, columnAwareOffsetFromRoot, rootRelativeBounds, rootRelativeBoundsComputed);
 
     LayerPaintingInfo localPaintingInfo(paintingInfo);
 
     GraphicsContext* transparencyLayerContext = context;
-    std::unique_ptr<FilterEffectRendererHelper> filterPainter = setupFilters(context, localPaintingInfo, paintFlags, offsetFromRoot, rootRelativeBounds, rootRelativeBoundsComputed);
+    std::unique_ptr<FilterEffectRendererHelper> filterPainter = setupFilters(context, localPaintingInfo, paintFlags, columnAwareOffsetFromRoot, rootRelativeBounds, rootRelativeBoundsComputed);
     if (filterPainter) {
         context = filterPainter->filterContext();
         if (context != transparencyLayerContext && haveTransparency) {
index e09df91..0275288 100644 (file)
@@ -986,6 +986,7 @@ private:
     bool setupFontSubpixelQuantization(GraphicsContext*, bool& didQuantizeFonts);
     bool setupClipPath(GraphicsContext*, const LayerPaintingInfo&, const LayoutSize& offsetFromRoot, LayoutRect& rootRelativeBounds, bool& rootRelativeBoundsComputed);
 
+    bool hasFilterThatIsPainting(GraphicsContext*, PaintLayerFlags) const;
     std::unique_ptr<FilterEffectRendererHelper> setupFilters(GraphicsContext*, LayerPaintingInfo&, PaintLayerFlags, const LayoutSize& offsetFromRoot, LayoutRect& rootRelativeBounds, bool& rootRelativeBoundsComputed);
     GraphicsContext* applyFilters(FilterEffectRendererHelper*, GraphicsContext* originalContext, LayerPaintingInfo&, LayerFragments&);