Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(274)

Unified Diff: third_party/WebKit/Source/core/paint/PaintLayer.cpp

Issue 1775013003: Implement -webkit-box-reflect as a filter. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: rebase master Created 4 years, 9 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
Index: third_party/WebKit/Source/core/paint/PaintLayer.cpp
diff --git a/third_party/WebKit/Source/core/paint/PaintLayer.cpp b/third_party/WebKit/Source/core/paint/PaintLayer.cpp
index c96f42c49d496e00d9ca3538e287babc7d8d072d..9b8b3eba036c0686d453148e2df3c6c4a7751b4b 100644
--- a/third_party/WebKit/Source/core/paint/PaintLayer.cpp
+++ b/third_party/WebKit/Source/core/paint/PaintLayer.cpp
@@ -254,7 +254,7 @@ void PaintLayer::contentChanged(ContentChangeType changeType)
bool PaintLayer::paintsWithFilters() const
{
- if (!layoutObject()->hasFilter())
+ if (!layoutObject()->hasFilterInducingProperty())
return false;
// https://code.google.com/p/chromium/issues/detail?id=343759
@@ -1066,8 +1066,7 @@ void PaintLayer::setShouldIsolateCompositedDescendants(bool shouldIsolateComposi
bool PaintLayer::hasAncestorWithFilterOutsets() const
{
for (const PaintLayer* curr = this; curr; curr = curr->parent()) {
- LayoutBoxModelObject* layoutObject = curr->layoutObject();
- if (layoutObject->style()->hasFilterOutsets())
+ if (curr->hasFilterOutsets())
return true;
}
return false;
@@ -2134,9 +2133,18 @@ LayoutRect PaintLayer::boundingBoxForCompositingOverlapTest() const
return overlapBoundsIncludeChildren() ? boundingBoxForCompositing(this, NeverIncludeTransformForAncestorLayer) : fragmentsBoundingBox(this);
}
+bool PaintLayer::overlapBoundsIncludeChildren() const
+{
+ if (hasFilter() && layoutObject()->style()->filter().hasFilterThatMovesPixels())
+ return true;
+ if (RuntimeEnabledFeatures::cssBoxReflectFilterEnabled() && layoutObject()->hasReflection())
+ return true;
+ return false;
+}
+
static void expandRectForReflectionAndStackingChildren(const PaintLayer* ancestorLayer, LayoutRect& result)
{
- if (ancestorLayer->reflectionInfo() && !ancestorLayer->reflectionInfo()->reflectionLayer()->hasCompositedLayerMapping())
+ if (ancestorLayer->reflectionInfo() && !ancestorLayer->reflectionInfo()->reflectionLayer()->hasCompositedLayerMapping() && !RuntimeEnabledFeatures::cssBoxReflectFilterEnabled())
result.unite(ancestorLayer->reflectionInfo()->reflectionLayer()->boundingBoxForCompositing(ancestorLayer));
ASSERT(ancestorLayer->stackingNode()->isStackingContext() || !ancestorLayer->stackingNode()->hasPositiveZOrderList());
@@ -2473,7 +2481,7 @@ bool PaintLayer::hasVisibleBoxDecorations() const
void PaintLayer::updateFilters(const ComputedStyle* oldStyle, const ComputedStyle& newStyle)
{
- if (!newStyle.hasFilter() && (!oldStyle || !oldStyle->hasFilter()))
+ if (!newStyle.hasFilterInducingProperty() && (!oldStyle || !oldStyle->hasFilterInducingProperty()))
return;
updateOrRemoveFilterClients();
@@ -2606,7 +2614,43 @@ FilterOperations computeFilterOperationsHandleReferenceFilters(const FilterOpera
FilterOperations PaintLayer::computeFilterOperations(const ComputedStyle& style) const
{
- return computeFilterOperationsHandleReferenceFilters(style.filter(), style.effectiveZoom(), enclosingNode());
+ FilterOperations filterOperations = style.filter();
+ if (RuntimeEnabledFeatures::cssBoxReflectFilterEnabled() && layoutObject()->hasReflection() && layoutObject()->isBox()) {
+ // TODO(jbroman): Incorporate the mask image.
+ const auto* reflectStyle = style.boxReflect();
+ FloatRect frameRect(toLayoutBox(layoutObject())->frameRect());
+ ReflectionDirection direction = VerticalReflection;
+ float offset = 0;
+ switch (reflectStyle->direction()) {
+ case ReflectionAbove:
+ direction = VerticalReflection;
+ offset = -floatValueForLength(reflectStyle->offset(), frameRect.height());
+ break;
+ case ReflectionBelow:
+ direction = VerticalReflection;
+ offset = 2 * frameRect.height() + floatValueForLength(reflectStyle->offset(), frameRect.height());
+ break;
+ case ReflectionLeft:
+ direction = HorizontalReflection;
+ offset = -floatValueForLength(reflectStyle->offset(), frameRect.width());
+ break;
+ case ReflectionRight:
+ direction = HorizontalReflection;
+ offset = 2 * frameRect.width() + floatValueForLength(reflectStyle->offset(), frameRect.width());
+ break;
+ }
+
+ // Since the filter origin is the corner of the input bounds, which may
+ // include visual overflow (e.g. due to box-shadow), we must adjust the
+ // offset to also account for this offset (this is equivalent to using
+ // SkLocalMatrixImageFilter, but simpler).
+ // The rect used here should match the one used in FilterPainter.
+ LayoutRect filterInputBounds = physicalBoundingBoxIncludingReflectionAndStackingChildren(LayoutPoint());
+ offset -= 2 * (direction == VerticalReflection ? filterInputBounds.y() : filterInputBounds.x()).toFloat();
+
+ filterOperations.operations().append(BoxReflectFilterOperation::create(direction, offset));
+ }
+ return computeFilterOperationsHandleReferenceFilters(filterOperations, style.effectiveZoom(), enclosingNode());
}
FilterOperations PaintLayer::computeBackdropFilterOperations(const ComputedStyle& style) const
@@ -2659,13 +2703,26 @@ FilterEffect* PaintLayer::lastFilterEffect() const
return builder->lastEffect().get();
}
+bool PaintLayer::hasFilterOutsets() const
+{
+ if (!layoutObject()->hasFilterInducingProperty())
+ return false;
+ const ComputedStyle& style = layoutObject()->styleRef();
+ if (style.hasFilter() && style.filter().hasOutsets())
+ return true;
+ if (RuntimeEnabledFeatures::cssBoxReflectFilterEnabled() && style.hasBoxReflect())
+ return true;
+ return false;
+}
+
FilterOutsets PaintLayer::filterOutsets() const
{
- if (!layoutObject()->hasFilter())
+ if (!layoutObject()->hasFilterInducingProperty())
return FilterOutsets();
// Ensure the filter-chain is refreshed wrt reference filters.
updateFilterEffectBuilder();
+
return layoutObject()->style()->filter().outsets();
}

Powered by Google App Engine
This is Rietveld 408576698