Log Message
[New Multicolumn] Transformed objects inside fragmented transparent objects don't render https://bugs.webkit.org/show_bug.cgi?id=111221.
Reviewed by Simon Fraser.
Source/WebCore:
Improve transparencyClipBox so that it understands when moving into descendants
that it does in fact have to break up the transformed clip rect across the
fragments.
Make sure when handling fragmented transforms using multiple paints that
the test that determines the extent of the transform within the fragments
uses transparencyClipBox. This gives us an accurate set of columns that the
final transformed result will paint across.
Tests: fast/multicol/mixed-opacity-fixed-test.html
fast/multicol/mixed-opacity-test.html
fast/multicol/transform-inside-opacity.html
* rendering/RenderLayer.cpp:
(WebCore::transparencyClipBox):
(WebCore::expandClipRectForDescendantsAndReflection):
Break transformed boxes up into fragments when they are
being requested by an ancestor.
(WebCore::RenderLayer::collectFragments):
(WebCore::RenderLayer::paintTransformedLayerIntoFragments):
(WebCore::RenderLayer::hitTestTransformedLayerInFragments):
* rendering/RenderLayer.h:
(RenderLayer):
Modify collectFragments so that we pass in the correct range
within the columns that can possibly cover the fragmented
transformed box.
LayoutTests:
* fast/multicol/mixed-opacity-fixed-test-expected.html: Added.
* fast/multicol/mixed-opacity-fixed-test.html: Added.
* fast/multicol/mixed-opacity-test-expected.html: Added.
* fast/multicol/mixed-opacity-test.html: Added.
* fast/multicol/transform-inside-opacity-expected.html: Added.
* fast/multicol/transform-inside-opacity.html: Added.
Modified Paths
- trunk/LayoutTests/ChangeLog
- trunk/Source/WebCore/ChangeLog
- trunk/Source/WebCore/rendering/RenderLayer.cpp
- trunk/Source/WebCore/rendering/RenderLayer.h
Added Paths
- trunk/LayoutTests/fast/multicol/mixed-opacity-fixed-test-expected.html
- trunk/LayoutTests/fast/multicol/mixed-opacity-fixed-test.html
- trunk/LayoutTests/fast/multicol/mixed-opacity-test-expected.html
- trunk/LayoutTests/fast/multicol/mixed-opacity-test.html
- trunk/LayoutTests/fast/multicol/transform-inside-opacity-expected.html
- trunk/LayoutTests/fast/multicol/transform-inside-opacity.html
Diff
Modified: trunk/LayoutTests/ChangeLog (144528 => 144529)
--- trunk/LayoutTests/ChangeLog 2013-03-02 05:53:00 UTC (rev 144528)
+++ trunk/LayoutTests/ChangeLog 2013-03-02 06:14:28 UTC (rev 144529)
@@ -1,3 +1,17 @@
+2013-03-01 David Hyatt <[email protected]>
+
+ [New Multicolumn] Transformed objects inside fragmented transparent objects don't render
+ https://bugs.webkit.org/show_bug.cgi?id=111221.
+
+ Reviewed by Simon Fraser.
+
+ * fast/multicol/mixed-opacity-fixed-test-expected.html: Added.
+ * fast/multicol/mixed-opacity-fixed-test.html: Added.
+ * fast/multicol/mixed-opacity-test-expected.html: Added.
+ * fast/multicol/mixed-opacity-test.html: Added.
+ * fast/multicol/transform-inside-opacity-expected.html: Added.
+ * fast/multicol/transform-inside-opacity.html: Added.
+
2013-03-01 Kentaro Hara <[email protected]>
Style recalculation takes too long when adding whitespace text nodes
Added: trunk/LayoutTests/fast/multicol/mixed-opacity-fixed-test-expected.html (0 => 144529)
--- trunk/LayoutTests/fast/multicol/mixed-opacity-fixed-test-expected.html (rev 0)
+++ trunk/LayoutTests/fast/multicol/mixed-opacity-fixed-test-expected.html 2013-03-02 06:14:28 UTC (rev 144529)
@@ -0,0 +1,9 @@
+<div style="position:relative; width:420px; border:2px solid black; height:200px">
+<div style="opacity:0.5;position:relative">
+<div style="height:200px;background-color:green;position:absolute;width:200px;left:0;top:0"></div>
+<div style="height:200px;background-color:green;position:absolute;width:200px;right:0;top:0"></div>
+<div style="position:fixed;height:98px;width:98px;background-color:lightgray; left:170px; top:220px;background-color:green;border:1px solid lime">
+</div>
+</div>
+</div>
+</div>
Added: trunk/LayoutTests/fast/multicol/mixed-opacity-fixed-test.html (0 => 144529)
--- trunk/LayoutTests/fast/multicol/mixed-opacity-fixed-test.html (rev 0)
+++ trunk/LayoutTests/fast/multicol/mixed-opacity-fixed-test.html 2013-03-02 06:14:28 UTC (rev 144529)
@@ -0,0 +1,11 @@
+<script>
+internals.settings.setRegionBasedColumnsEnabled(true)
+</script>
+<div style="position:relative; -webkit-column-count:2; -webkit-column-width:200px; width:420px; -webkit-column-gap:20px; border:2px solid black; height:200px">
+<div style="opacity:0.5">
+<div style="height:400px;background-color:green"></div>
+<div style="position:fixed;height:98px;width:98px;background-color:lightgray; left:170px; top:220px;background-color:green;border:1px solid lime">
+</div>
+</div>
+</div>
+</div>
Added: trunk/LayoutTests/fast/multicol/mixed-opacity-test-expected.html (0 => 144529)
--- trunk/LayoutTests/fast/multicol/mixed-opacity-test-expected.html (rev 0)
+++ trunk/LayoutTests/fast/multicol/mixed-opacity-test-expected.html 2013-03-02 06:14:28 UTC (rev 144529)
@@ -0,0 +1,9 @@
+<div style="position:relative; width:420px; border:2px solid black; height:200px">
+<div style="opacity:0.5;position:relative">
+<div style="height:200px;background-color:green;position:absolute;width:200px;left:0;top:0"></div>
+<div style="height:200px;background-color:green;position:absolute;width:200px;right:0;top:0"></div>
+<div style="position:absolute;height:98px;width:98px;background-color:lightgray; left:160px; top:50px;background-color:green;border:1px solid lime">
+</div>
+</div>
+</div>
+</div>
Added: trunk/LayoutTests/fast/multicol/mixed-opacity-test.html (0 => 144529)
--- trunk/LayoutTests/fast/multicol/mixed-opacity-test.html (rev 0)
+++ trunk/LayoutTests/fast/multicol/mixed-opacity-test.html 2013-03-02 06:14:28 UTC (rev 144529)
@@ -0,0 +1,11 @@
+<script>
+internals.settings.setRegionBasedColumnsEnabled(true)
+</script>
+<div style="position:relative; -webkit-column-count:2; -webkit-column-width:200px; width:420px; -webkit-column-gap:20px; border:2px solid black; height:200px">
+<div style="opacity:0.5">
+<div style="height:400px;background-color:green"></div>
+<div style="position:absolute;height:98px;width:98px;background-color:lightgray; left:160px; top:50px;background-color:green;border:1px solid lime">
+</div>
+</div>
+</div>
+</div>
Added: trunk/LayoutTests/fast/multicol/transform-inside-opacity-expected.html (0 => 144529)
--- trunk/LayoutTests/fast/multicol/transform-inside-opacity-expected.html (rev 0)
+++ trunk/LayoutTests/fast/multicol/transform-inside-opacity-expected.html 2013-03-02 06:14:28 UTC (rev 144529)
@@ -0,0 +1,4 @@
+<div style="position:relative; width:420px;border:2px solid black; height:200px">
+<div style="opacity:0.5; position:absolute;width:200px;height:100px;background-color:green;right:0;top:0"></div>
+</div>
+</div>
Added: trunk/LayoutTests/fast/multicol/transform-inside-opacity.html (0 => 144529)
--- trunk/LayoutTests/fast/multicol/transform-inside-opacity.html (rev 0)
+++ trunk/LayoutTests/fast/multicol/transform-inside-opacity.html 2013-03-02 06:14:28 UTC (rev 144529)
@@ -0,0 +1,15 @@
+<head>
+<script>
+internals.settings.setRegionBasedColumnsEnabled(true)
+</script>
+<style>
+.transformed { background-color:green }
+.transformed:hover { background-color:maroon }
+</style>
+</head>
+<div style="position:relative; -webkit-column-count:2; -webkit-column-width:200px; width:420px; -webkit-column-gap:20px; border:2px solid black; height:200px">
+<div style="height:100px"></div>
+<div style="opacity:0.5">
+<div class="transformed" style="float:left;width:200px;height:100px;-webkit-transform:translate(0, 100px)"></div>
+</div>
+</div>
Modified: trunk/Source/WebCore/ChangeLog (144528 => 144529)
--- trunk/Source/WebCore/ChangeLog 2013-03-02 05:53:00 UTC (rev 144528)
+++ trunk/Source/WebCore/ChangeLog 2013-03-02 06:14:28 UTC (rev 144529)
@@ -1,3 +1,38 @@
+2013-03-01 David Hyatt <[email protected]>
+
+ [New Multicolumn] Transformed objects inside fragmented transparent objects don't render
+ https://bugs.webkit.org/show_bug.cgi?id=111221.
+
+ Reviewed by Simon Fraser.
+
+ Improve transparencyClipBox so that it understands when moving into descendants
+ that it does in fact have to break up the transformed clip rect across the
+ fragments.
+
+ Make sure when handling fragmented transforms using multiple paints that
+ the test that determines the extent of the transform within the fragments
+ uses transparencyClipBox. This gives us an accurate set of columns that the
+ final transformed result will paint across.
+
+ Tests: fast/multicol/mixed-opacity-fixed-test.html
+ fast/multicol/mixed-opacity-test.html
+ fast/multicol/transform-inside-opacity.html
+
+ * rendering/RenderLayer.cpp:
+ (WebCore::transparencyClipBox):
+ (WebCore::expandClipRectForDescendantsAndReflection):
+ Break transformed boxes up into fragments when they are
+ being requested by an ancestor.
+
+ (WebCore::RenderLayer::collectFragments):
+ (WebCore::RenderLayer::paintTransformedLayerIntoFragments):
+ (WebCore::RenderLayer::hitTestTransformedLayerInFragments):
+ * rendering/RenderLayer.h:
+ (RenderLayer):
+ Modify collectFragments so that we pass in the correct range
+ within the columns that can possibly cover the fragmented
+ transformed box.
+
2013-03-01 Ilya Tikhonovsky <[email protected]>
Web Inspector: Native Memory Instrumentation: do not visit raw pointers by default.
Modified: trunk/Source/WebCore/rendering/RenderLayer.cpp (144528 => 144529)
--- trunk/Source/WebCore/rendering/RenderLayer.cpp 2013-03-02 05:53:00 UTC (rev 144528)
+++ trunk/Source/WebCore/rendering/RenderLayer.cpp 2013-03-02 06:14:28 UTC (rev 144529)
@@ -1560,9 +1560,20 @@
return 0;
}
-static LayoutRect transparencyClipBox(const RenderLayer*, const RenderLayer* rootLayer, PaintBehavior);
+enum TransparencyClipBoxBehavior {
+ PaintingTransparencyClipBox,
+ HitTestingTransparencyClipBox
+};
-static void expandClipRectForDescendantsAndReflection(LayoutRect& clipRect, const RenderLayer* layer, const RenderLayer* rootLayer, PaintBehavior paintBehavior)
+enum TransparencyClipBoxMode {
+ DescendantsOfTransparencyClipBox,
+ RootOfTransparencyClipBox
+};
+
+static LayoutRect transparencyClipBox(const RenderLayer*, const RenderLayer* rootLayer, TransparencyClipBoxBehavior, TransparencyClipBoxMode, PaintBehavior = 0);
+
+static void expandClipRectForDescendantsAndReflection(LayoutRect& clipRect, const RenderLayer* layer, const RenderLayer* rootLayer,
+ TransparencyClipBoxBehavior transparencyBehavior, PaintBehavior paintBehavior)
{
// If we have a mask, then the clip is limited to the border box area (and there is
// no need to examine child layers).
@@ -1571,7 +1582,7 @@
// a stacking container. This means we can just walk the layer tree directly.
for (RenderLayer* curr = layer->firstChild(); curr; curr = curr->nextSibling()) {
if (!layer->reflection() || layer->reflectionLayer() != curr)
- clipRect.unite(transparencyClipBox(curr, rootLayer, paintBehavior));
+ clipRect.unite(transparencyClipBox(curr, rootLayer, transparencyBehavior, DescendantsOfTransparencyClipBox, paintBehavior));
}
}
@@ -1588,32 +1599,51 @@
}
}
-static LayoutRect transparencyClipBox(const RenderLayer* layer, const RenderLayer* rootLayer, PaintBehavior paintBehavior)
+static LayoutRect transparencyClipBox(const RenderLayer* layer, const RenderLayer* rootLayer, TransparencyClipBoxBehavior transparencyBehavior,
+ TransparencyClipBoxMode transparencyMode, PaintBehavior paintBehavior)
{
// FIXME: Although this function completely ignores CSS-imposed clipping, we did already intersect with the
// paintDirtyRect, and that should cut down on the amount we have to paint. Still it
// would be better to respect clips.
- if (rootLayer != layer && layer->paintsWithTransform(paintBehavior)) {
+ if (rootLayer != layer && ((transparencyBehavior == PaintingTransparencyClipBox && layer->paintsWithTransform(paintBehavior))
+ || (transparencyBehavior == HitTestingTransparencyClipBox && layer->hasTransform()))) {
// The best we can do here is to use enclosed bounding boxes to establish a "fuzzy" enough clip to encompass
// the transformed layer and all of its children.
+ const RenderLayer* paginationLayer = transparencyMode == DescendantsOfTransparencyClipBox ? layer->enclosingPaginationLayer() : 0;
+ const RenderLayer* rootLayerForTransform = paginationLayer ? paginationLayer : rootLayer;
LayoutPoint delta;
- layer->convertToLayerCoords(rootLayer, delta);
+ layer->convertToLayerCoords(rootLayerForTransform, delta);
TransformationMatrix transform;
transform.translate(delta.x(), delta.y());
transform = transform * *layer->transform();
- LayoutRect clipRect = layer->boundingBox(layer, RenderLayer::UseFragmentBoxes);
- expandClipRectForDescendantsAndReflection(clipRect, layer, layer, paintBehavior);
+ // We don't use fragment boxes when collecting a transformed layer's bounding box, since it always
+ // paints unfragmented.
+ LayoutRect clipRect = layer->boundingBox(layer);
+ expandClipRectForDescendantsAndReflection(clipRect, layer, layer, transparencyBehavior, paintBehavior);
#if ENABLE(CSS_FILTERS)
layer->renderer()->style()->filterOutsets().expandRect(clipRect);
#endif
- return transform.mapRect(clipRect);
+ LayoutRect result = transform.mapRect(clipRect);
+ if (!paginationLayer)
+ return result;
+
+ // We have to break up the transformed extent across our columns.
+ // Split our box up into the actual fragment boxes that render in the columns/pages and unite those together to
+ // get our true bounding box.
+ RenderFlowThread* enclosingFlowThread = toRenderFlowThread(paginationLayer->renderer());
+ result = enclosingFlowThread->fragmentsBoundingBox(result);
+
+ LayoutPoint rootLayerDelta;
+ paginationLayer->convertToLayerCoords(rootLayer, rootLayerDelta);
+ result.moveBy(rootLayerDelta);
+ return result;
}
LayoutRect clipRect = layer->boundingBox(rootLayer, RenderLayer::UseFragmentBoxes);
- expandClipRectForDescendantsAndReflection(clipRect, layer, rootLayer, paintBehavior);
+ expandClipRectForDescendantsAndReflection(clipRect, layer, rootLayer, transparencyBehavior, paintBehavior);
#if ENABLE(CSS_FILTERS)
layer->renderer()->style()->filterOutsets().expandRect(clipRect);
#endif
@@ -1622,7 +1652,7 @@
LayoutRect RenderLayer::paintingExtent(const RenderLayer* rootLayer, const LayoutRect& paintDirtyRect, PaintBehavior paintBehavior)
{
- return intersection(transparencyClipBox(this, rootLayer, paintBehavior), paintDirtyRect);
+ return intersection(transparencyClipBox(this, rootLayer, PaintingTransparencyClipBox, RootOfTransparencyClipBox, paintBehavior), paintDirtyRect);
}
void RenderLayer::beginTransparencyLayers(GraphicsContext* context, const RenderLayer* rootLayer, const LayoutRect& paintDirtyRect, PaintBehavior paintBehavior)
@@ -3888,7 +3918,8 @@
}
void RenderLayer::collectFragments(LayerFragments& fragments, const RenderLayer* rootLayer, RenderRegion* region, const LayoutRect& dirtyRect,
- ClipRectsType clipRectsType, OverlayScrollbarSizeRelevancy inOverlayScrollbarSizeRelevancy, ShouldRespectOverflowClip respectOverflowClip, const LayoutPoint* offsetFromRoot)
+ ClipRectsType clipRectsType, OverlayScrollbarSizeRelevancy inOverlayScrollbarSizeRelevancy, ShouldRespectOverflowClip respectOverflowClip, const LayoutPoint* offsetFromRoot,
+ const LayoutRect* layerBoundingBox)
{
if (!enclosingPaginationLayer() || hasTransform()) {
// For unpaginated layers, there is only one fragment.
@@ -3914,7 +3945,7 @@
outlineRectInFlowThread, &offsetWithinPaginatedLayer);
// Take our bounding box within the flow thread and clip it.
- LayoutRect layerBoundingBoxInFlowThread = boundingBox(enclosingPaginationLayer(), 0, &offsetWithinPaginatedLayer);
+ LayoutRect layerBoundingBoxInFlowThread = layerBoundingBox ? *layerBoundingBox : boundingBox(enclosingPaginationLayer(), 0, &offsetWithinPaginatedLayer);
layerBoundingBoxInFlowThread.intersect(backgroundRectInFlowThread.rect());
// Shift the dirty rect into flow thread coordinates.
@@ -3976,9 +4007,10 @@
{
LayerFragments enclosingPaginationFragments;
LayoutPoint offsetOfPaginationLayerFromRoot;
+ LayoutRect transformedExtent = transparencyClipBox(this, enclosingPaginationLayer(), PaintingTransparencyClipBox, RootOfTransparencyClipBox, paintingInfo.paintBehavior);
enclosingPaginationLayer()->collectFragments(enclosingPaginationFragments, paintingInfo.rootLayer, paintingInfo.region, paintingInfo.paintDirtyRect,
(paintFlags & PaintLayerTemporaryClipRects) ? TemporaryClipRects : PaintingClipRects, IgnoreOverlayScrollbarSize,
- (paintFlags & PaintLayerPaintingOverflowContents) ? IgnoreOverflowClip : RespectOverflowClip, &offsetOfPaginationLayerFromRoot);
+ (paintFlags & PaintLayerPaintingOverflowContents) ? IgnoreOverflowClip : RespectOverflowClip, &offsetOfPaginationLayerFromRoot, &transformedExtent);
for (size_t i = 0; i < enclosingPaginationFragments.size(); ++i) {
const LayerFragment& fragment = enclosingPaginationFragments.at(i);
@@ -4609,8 +4641,9 @@
{
LayerFragments enclosingPaginationFragments;
LayoutPoint offsetOfPaginationLayerFromRoot;
+ LayoutRect transformedExtent = transparencyClipBox(this, enclosingPaginationLayer(), HitTestingTransparencyClipBox, RootOfTransparencyClipBox);
enclosingPaginationLayer()->collectFragments(enclosingPaginationFragments, rootLayer, hitTestLocation.region(), hitTestRect,
- RootRelativeClipRects, IncludeOverlayScrollbarSize, RespectOverflowClip, &offsetOfPaginationLayerFromRoot);
+ RootRelativeClipRects, IncludeOverlayScrollbarSize, RespectOverflowClip, &offsetOfPaginationLayerFromRoot, &transformedExtent);
for (int i = enclosingPaginationFragments.size() - 1; i >= 0; --i) {
const LayerFragment& fragment = enclosingPaginationFragments.at(i);
Modified: trunk/Source/WebCore/rendering/RenderLayer.h (144528 => 144529)
--- trunk/Source/WebCore/rendering/RenderLayer.h 2013-03-02 05:53:00 UTC (rev 144528)
+++ trunk/Source/WebCore/rendering/RenderLayer.h 2013-03-02 06:14:28 UTC (rev 144529)
@@ -946,7 +946,7 @@
void collectFragments(LayerFragments&, const RenderLayer* rootLayer, RenderRegion*, const LayoutRect& dirtyRect,
ClipRectsType, OverlayScrollbarSizeRelevancy inOverlayScrollbarSizeRelevancy = IgnoreOverlayScrollbarSize,
- ShouldRespectOverflowClip = RespectOverflowClip, const LayoutPoint* offsetFromRoot = 0);
+ ShouldRespectOverflowClip = RespectOverflowClip, const LayoutPoint* offsetFromRoot = 0, const LayoutRect* layerBoundingBox = 0);
void updatePaintingInfoForFragments(LayerFragments&, const LayerPaintingInfo&, PaintLayerFlags, bool shouldPaintContent, const LayoutPoint* offsetFromRoot);
void paintBackgroundForFragments(const LayerFragments&, GraphicsContext*, GraphicsContext* transparencyLayerContext,
const LayoutRect& transparencyPaintDirtyRect, bool haveTransparency, const LayerPaintingInfo&, PaintBehavior, RenderObject* paintingRootForRenderer);
_______________________________________________ webkit-changes mailing list [email protected] https://lists.webkit.org/mailman/listinfo/webkit-changes
