| 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..c00cffa87dc32d3a7ad32dd58c7cfefa6b132328 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* zoomedReferenceBoxSize, float zoom)
|
| +{
|
| + FloatSize size;
|
| + if (zoomedReferenceBoxSize) {
|
| + size = *zoomedReferenceBoxSize;
|
| + } 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()
|
| @@ -131,7 +147,7 @@ DEFINE_TRACE(FilterEffectBuilder)
|
| visitor->trace(m_lastEffect);
|
| }
|
|
|
| -bool FilterEffectBuilder::build(Element* element, const FilterOperations& operations, float zoom, const FloatSize* referenceBoxSize, const SkPaint* fillPaint, const SkPaint* strokePaint)
|
| +bool FilterEffectBuilder::build(Element* element, const FilterOperations& operations, float zoom, const FloatSize* zoomedReferenceBoxSize, const SkPaint* fillPaint, const SkPaint* strokePaint)
|
| {
|
| // Create a parent filter for shorthand filters. These have already been scaled by the CSS code for page zoom, so scale is 1.0 here.
|
| Filter* parentFilter = Filter::create(1.0f);
|
| @@ -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), zoomedReferenceBoxSize, 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* zoomedReferenceBoxSize,
|
| + 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, zoomedReferenceBoxSize, 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())
|
| + 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
|
|
|
|
|