Chromium Code Reviews| Index: third_party/WebKit/Source/core/paint/FilterEffectBuilder.cpp |
| diff --git a/third_party/WebKit/Source/core/paint/FilterEffectBuilder.cpp b/third_party/WebKit/Source/core/paint/FilterEffectBuilder.cpp |
| index 9241542c378224c90dbe0c2cd471410271bf0f9e..c58eebbf6b38b8bd3a27ecbb0c22aa6837b4d609 100644 |
| --- a/third_party/WebKit/Source/core/paint/FilterEffectBuilder.cpp |
| +++ b/third_party/WebKit/Source/core/paint/FilterEffectBuilder.cpp |
| @@ -27,6 +27,10 @@ |
| #include "core/paint/FilterEffectBuilder.h" |
| #include "core/layout/svg/ReferenceFilterBuilder.h" |
| +#include "core/paint/PaintLayer.h" |
| +#include "core/svg/SVGFilterElement.h" |
| +#include "core/svg/SVGLengthContext.h" |
| +#include "core/svg/graphics/filters/SVGFilterBuilder.h" |
| #include "platform/FloatConversion.h" |
| #include "platform/LengthFunctions.h" |
| #include "platform/graphics/ColorSpace.h" |
| @@ -116,6 +120,18 @@ Vector<float> sepiaMatrix(double amount) |
| return matrix; |
| } |
| +FloatRect computeReferenceBox(const Element& element, const FloatSize* referenceBoxSize, float zoom) |
| +{ |
| + FloatSize size; |
| + if (referenceBoxSize) { |
| + size = *referenceBoxSize; |
| + } else if (element.inShadowIncludingDocument() && element.layoutObject() && element.layoutObject()->enclosingLayer()) { |
| + size = FloatSize(element.layoutObject()->enclosingLayer()->physicalBoundingBoxIncludingReflectionAndStackingChildren(LayoutPoint()).size()); |
| + } |
| + size.scale(1.0f / zoom); |
| + return FloatRect(FloatPoint(), size); |
| +} |
| + |
| } // namespace |
| FilterEffectBuilder::FilterEffectBuilder() |
| @@ -141,7 +157,7 @@ bool FilterEffectBuilder::build(Element* element, const FilterOperations& operat |
| FilterOperation* filterOperation = operations.operations().at(i).get(); |
| switch (filterOperation->type()) { |
| case FilterOperation::REFERENCE: { |
| - Filter* referenceFilter = ReferenceFilterBuilder::build(zoom, element, previousEffect, toReferenceFilterOperation(*filterOperation), referenceBoxSize, fillPaint, strokePaint); |
| + Filter* referenceFilter = buildReferenceFilter(toReferenceFilterOperation(*filterOperation), referenceBoxSize, fillPaint, strokePaint, *element, previousEffect, zoom); |
| if (referenceFilter) |
| effect = referenceFilter->lastEffect(); |
| break; |
| @@ -260,5 +276,49 @@ bool FilterEffectBuilder::build(Element* element, const FilterOperations& operat |
| return true; |
| } |
| +Filter* FilterEffectBuilder::buildReferenceFilter( |
| + const ReferenceFilterOperation& referenceOperation, |
| + const FloatSize* referenceBoxSize, |
| + const SkPaint* fillPaint, |
| + const SkPaint* strokePaint, |
| + Element& element, |
| + FilterEffect* previousEffect, |
| + float zoom) |
| +{ |
| + SVGFilterElement* filterElement = ReferenceFilterBuilder::resolveFilterReference(referenceOperation, element); |
| + if (!filterElement) |
| + return nullptr; |
| + |
| + const FloatRect referenceBox = computeReferenceBox(element, referenceBoxSize, zoom); |
| + return buildReferenceFilter(*filterElement, referenceBox, fillPaint, strokePaint, previousEffect, zoom); |
| +} |
| + |
| +Filter* FilterEffectBuilder::buildReferenceFilter( |
| + SVGFilterElement& filterElement, |
| + const FloatRect& referenceBox, |
| + const SkPaint* fillPaint, |
| + const SkPaint* strokePaint, |
| + FilterEffect* previousEffect, |
| + float zoom, |
| + SVGFilterGraphNodeMap* nodeMap) |
| +{ |
| + FloatRect filterRegion = SVGLengthContext::resolveRectangle<SVGFilterElement>(&filterElement, filterElement.filterUnits()->currentValue()->enumValue(), referenceBox); |
| + // TODO(fs): We rely on the presence of a node map here to opt-in to the |
| + // check for an empty filter region. The reason for this is that we lack a |
| + // viewport to resolve against for HTML content. This is crbug.com/512453. |
| + if (nodeMap && filterRegion.isEmpty()) |
|
fs
2016/06/08 10:51:36
This is a bit ugly, and could also be achieved usi
|
| + return nullptr; |
| + |
| + bool primitiveBoundingBoxMode = filterElement.primitiveUnits()->currentValue()->enumValue() == SVGUnitTypes::SVG_UNIT_TYPE_OBJECTBOUNDINGBOX; |
| + Filter::UnitScaling unitScaling = primitiveBoundingBoxMode ? Filter::BoundingBox : Filter::UserSpace; |
| + Filter* result = Filter::create(referenceBox, filterRegion, zoom, unitScaling); |
| + if (!previousEffect) |
| + previousEffect = result->getSourceGraphic(); |
| + SVGFilterBuilder builder(previousEffect, nodeMap, fillPaint, strokePaint); |
| + builder.buildGraph(result, filterElement, referenceBox); |
| + result->setLastEffect(builder.lastEffect()); |
| + return result; |
| +} |
| + |
| } // namespace blink |