Commit 17e31b89 authored by mstensho's avatar mstensho Committed by Commit bot

Display -webkit-filter objects in any column (instead of only in the first one).

Most of our painting-related operations take place after fragmentation, i.e.
via PaintLayerPainter::paintFragmentWithPhase(). All such operations can just
sit back and relax and not worry about fragmentation, since translation and
clipping for a given fragmentainer (column) has already taken place.

This is not the case for filters, though. They are set up before fragmentation.
Therefore, we need to make the bounding box of the layer visual (convert out of
the flow thread coordinate space) on our own. We now do this specifically for
filters, or we'd upset other parts of the code, such as clip path.

BUG=530074
R=wangxianzhu@chromium.org

Review URL: https://codereview.chromium.org/1645583002

Cr-Commit-Position: refs/heads/master@{#371808}
parent 86654512
<!DOCTYPE html>
<p>The word "PASS" should be seen below.</p>
<div style="margin-left:5em; -webkit-filter:grayscale(90%);">PASS</div>
<!DOCTYPE html>
<p>The word "PASS" should be seen below.</p>
<div style="-webkit-columns:2; -webkit-column-gap:0; width:10em;">
<br>
<div style="-webkit-filter:grayscale(90%);">PASS</div>
</div>
...@@ -69,7 +69,13 @@ FilterPainter::FilterPainter(PaintLayer& layer, GraphicsContext& context, const ...@@ -69,7 +69,13 @@ FilterPainter::FilterPainter(PaintLayer& layer, GraphicsContext& context, const
// the layer's filter. See crbug.com/502026. // the layer's filter. See crbug.com/502026.
if (webFilterOperations->isEmpty()) if (webFilterOperations->isEmpty())
return; return;
context.paintController().createAndAppend<BeginFilterDisplayItem>(*m_layoutObject, imageFilter, FloatRect(rootRelativeBounds), webFilterOperations.release()); LayoutRect visualBounds(rootRelativeBounds);
if (layer.enclosingPaginationLayer()) {
// Filters are set up before pagination, so we need to make the bounding box visual on our own.
visualBounds.moveBy(-offsetFromRoot);
layer.convertFromFlowThreadToVisualBoundingBoxInAncestor(paintingInfo.rootLayer, visualBounds);
}
context.paintController().createAndAppend<BeginFilterDisplayItem>(*m_layoutObject, imageFilter, FloatRect(visualBounds), webFilterOperations.release());
} }
m_filterInProgress = true; m_filterInProgress = true;
......
...@@ -436,17 +436,15 @@ TransformationMatrix PaintLayer::renderableTransform(GlobalPaintFlags globalPain ...@@ -436,17 +436,15 @@ TransformationMatrix PaintLayer::renderableTransform(GlobalPaintFlags globalPain
return *m_transform; return *m_transform;
} }
// Convert a bounding box from flow thread coordinates, relative to |layer|, to visual coordinates, relative to |ancestorLayer|. void PaintLayer::convertFromFlowThreadToVisualBoundingBoxInAncestor(const PaintLayer* ancestorLayer, LayoutRect& rect) const
// See http://www.chromium.org/developers/design-documents/multi-column-layout for more info on these coordinate types.
static void convertFromFlowThreadToVisualBoundingBoxInAncestor(const PaintLayer* layer, const PaintLayer* ancestorLayer, LayoutRect& rect)
{ {
PaintLayer* paginationLayer = layer->enclosingPaginationLayer(); PaintLayer* paginationLayer = enclosingPaginationLayer();
ASSERT(paginationLayer); ASSERT(paginationLayer);
LayoutFlowThread* flowThread = toLayoutFlowThread(paginationLayer->layoutObject()); LayoutFlowThread* flowThread = toLayoutFlowThread(paginationLayer->layoutObject());
// First make the flow thread rectangle relative to the flow thread, not to |layer|. // First make the flow thread rectangle relative to the flow thread, not to |layer|.
LayoutPoint offsetWithinPaginationLayer; LayoutPoint offsetWithinPaginationLayer;
layer->convertToLayerCoords(paginationLayer, offsetWithinPaginationLayer); convertToLayerCoords(paginationLayer, offsetWithinPaginationLayer);
rect.moveBy(offsetWithinPaginationLayer); rect.moveBy(offsetWithinPaginationLayer);
// Then make the rectangle visual, relative to the fragmentation context. Split our box up into // Then make the rectangle visual, relative to the fragmentation context. Split our box up into
...@@ -2155,7 +2153,7 @@ LayoutRect PaintLayer::fragmentsBoundingBox(const PaintLayer* ancestorLayer) con ...@@ -2155,7 +2153,7 @@ LayoutRect PaintLayer::fragmentsBoundingBox(const PaintLayer* ancestorLayer) con
return physicalBoundingBox(ancestorLayer); return physicalBoundingBox(ancestorLayer);
LayoutRect result = flippedLogicalBoundingBox(logicalBoundingBox(), layoutObject()); LayoutRect result = flippedLogicalBoundingBox(logicalBoundingBox(), layoutObject());
convertFromFlowThreadToVisualBoundingBoxInAncestor(this, ancestorLayer, result); convertFromFlowThreadToVisualBoundingBoxInAncestor(ancestorLayer, result);
return result; return result;
} }
...@@ -2255,7 +2253,7 @@ LayoutRect PaintLayer::boundingBoxForCompositing(const PaintLayer* ancestorLayer ...@@ -2255,7 +2253,7 @@ LayoutRect PaintLayer::boundingBoxForCompositing(const PaintLayer* ancestorLayer
result = transform()->mapRect(result); result = transform()->mapRect(result);
if (enclosingPaginationLayer()) { if (enclosingPaginationLayer()) {
convertFromFlowThreadToVisualBoundingBoxInAncestor(this, ancestorLayer, result); convertFromFlowThreadToVisualBoundingBoxInAncestor(ancestorLayer, result);
return result; return result;
} }
LayoutPoint delta; LayoutPoint delta;
......
...@@ -300,6 +300,11 @@ public: ...@@ -300,6 +300,11 @@ public:
// http://www.chromium.org/developers/design-documents/multi-column-layout for more info. // http://www.chromium.org/developers/design-documents/multi-column-layout for more info.
LayoutPoint visualOffsetFromAncestor(const PaintLayer* ancestorLayer) const; LayoutPoint visualOffsetFromAncestor(const PaintLayer* ancestorLayer) const;
// Convert a bounding box from flow thread coordinates, relative to |this|, to visual coordinates, relative to |ancestorLayer|.
// See http://www.chromium.org/developers/design-documents/multi-column-layout for more info on these coordinate types.
// This method requires this layer to be paginated; i.e. it must have an enclosingPaginationLayer().
void convertFromFlowThreadToVisualBoundingBoxInAncestor(const PaintLayer* ancestorLayer, LayoutRect&) const;
// The hitTest() method looks for mouse events by walking layers that intersect the point from front to back. // The hitTest() method looks for mouse events by walking layers that intersect the point from front to back.
bool hitTest(HitTestResult&); bool hitTest(HitTestResult&);
......
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