This source file includes following definitions.
- documentResourceReference
- setDocumentResourceReference
- clearDocumentResourceReference
- getSVGElementColorSpace
- build
#include "config.h"
#include "core/rendering/svg/ReferenceFilterBuilder.h"
#include "SVGNames.h"
#include "core/css/CSSPrimitiveValue.h"
#include "core/css/CSSPrimitiveValueMappings.h"
#include "core/css/StylePropertySet.h"
#include "core/dom/Element.h"
#include "core/fetch/DocumentResource.h"
#include "core/rendering/svg/RenderSVGResourceFilter.h"
#include "core/svg/SVGDocumentExtensions.h"
#include "core/svg/SVGFilterPrimitiveStandardAttributes.h"
#include "core/svg/graphics/filters/SVGFilterBuilder.h"
#include "platform/graphics/filters/SourceAlpha.h"
namespace WebCore {
HashMap<const FilterOperation*, OwnPtr<DocumentResourceReference> >* ReferenceFilterBuilder::documentResourceReferences = 0;
DocumentResourceReference* ReferenceFilterBuilder::documentResourceReference(const FilterOperation* filterOperation)
{
if (!documentResourceReferences)
return 0;
return documentResourceReferences->get(filterOperation);
}
void ReferenceFilterBuilder::setDocumentResourceReference(const FilterOperation* filterOperation, PassOwnPtr<DocumentResourceReference> documentResourceReference)
{
if (!documentResourceReferences)
documentResourceReferences = new HashMap<const FilterOperation*, OwnPtr<DocumentResourceReference> >;
documentResourceReferences->add(filterOperation, documentResourceReference);
}
void ReferenceFilterBuilder::clearDocumentResourceReference(const FilterOperation* filterOperation)
{
if (!documentResourceReferences)
return;
documentResourceReferences->remove(filterOperation);
}
static bool getSVGElementColorSpace(SVGElement* svgElement, ColorSpace& cs)
{
if (!svgElement)
return false;
const RenderObject* renderer = svgElement->renderer();
const RenderStyle* style = renderer ? renderer->style() : 0;
const SVGRenderStyle* svgStyle = style ? style->svgStyle() : 0;
EColorInterpolation eColorInterpolation = CI_AUTO;
if (svgStyle) {
eColorInterpolation = svgStyle->colorInterpolationFilters();
} else if (!svgElement->presentationAttributeStyle()) {
return false;
} else {
RefPtrWillBeRawPtr<CSSValue> cssValue = svgElement->presentationAttributeStyle()->getPropertyCSSValue(CSSPropertyColorInterpolationFilters);
if (cssValue.get() && cssValue->isPrimitiveValue()) {
const CSSPrimitiveValue& primitiveValue = *((CSSPrimitiveValue*)cssValue.get());
eColorInterpolation = (EColorInterpolation)primitiveValue;
} else {
return false;
}
}
switch (eColorInterpolation) {
case CI_AUTO:
case CI_SRGB:
cs = ColorSpaceDeviceRGB;
break;
case CI_LINEARRGB:
cs = ColorSpaceLinearRGB;
break;
default:
return false;
}
return true;
}
PassRefPtr<FilterEffect> ReferenceFilterBuilder::build(Filter* parentFilter, RenderObject* renderer, FilterEffect* previousEffect, const ReferenceFilterOperation* filterOperation)
{
if (!renderer)
return nullptr;
Document* document = &renderer->document();
if (DocumentResourceReference* documentResourceRef = documentResourceReference(filterOperation)) {
DocumentResource* cachedSVGDocument = documentResourceRef->document();
if (cachedSVGDocument)
document = cachedSVGDocument->document();
}
if (!document)
return nullptr;
Element* filter = document->getElementById(filterOperation->fragment());
if (!filter) {
document->accessSVGExtensions().addPendingResource(filterOperation->fragment(), toElement(renderer->node()));
return nullptr;
}
if (!isSVGFilterElement(*filter))
return nullptr;
SVGFilterElement& filterElement = toSVGFilterElement(*filter);
RefPtr<SVGFilterBuilder> builder = SVGFilterBuilder::create(previousEffect, SourceAlpha::create(parentFilter));
ColorSpace filterColorSpace = ColorSpaceDeviceRGB;
bool useFilterColorSpace = getSVGElementColorSpace(&filterElement, filterColorSpace);
for (SVGElement* element = Traversal<SVGElement>::firstChild(filterElement); element; element = Traversal<SVGElement>::nextSibling(*element)) {
if (!element->isFilterEffect())
continue;
SVGFilterPrimitiveStandardAttributes* effectElement = static_cast<SVGFilterPrimitiveStandardAttributes*>(element);
RefPtr<FilterEffect> effect = effectElement->build(builder.get(), parentFilter);
if (!effect)
continue;
effectElement->setStandardAttributes(effect.get());
effect->setEffectBoundaries(SVGLengthContext::resolveRectangle<SVGFilterPrimitiveStandardAttributes>(effectElement, filterElement.primitiveUnits()->currentValue()->enumValue(), parentFilter->sourceImageRect()));
ColorSpace colorSpace = filterColorSpace;
if (useFilterColorSpace || getSVGElementColorSpace(effectElement, colorSpace))
effect->setOperatingColorSpace(colorSpace);
builder->add(AtomicString(effectElement->result()->currentValue()->value()), effect);
}
return builder->lastEffect();
}
}