bool SVGFilterPrimitiveStandardAttributes::rendererIsNeeded(const RenderStyle& style) { if (isSVGFilterElement(parentNode())) return SVGElement::rendererIsNeeded(style); return false; }
void RenderLayerFilterInfo::updateReferenceFilterClients(const FilterOperations& operations) { removeReferenceFilterClients(); for (size_t i = 0; i < operations.size(); ++i) { RefPtr<FilterOperation> filterOperation = operations.operations().at(i); if (filterOperation->type() != FilterOperation::REFERENCE) continue; ReferenceFilterOperation* referenceFilterOperation = toReferenceFilterOperation(filterOperation.get()); DocumentResourceReference* documentReference = ReferenceFilterBuilder::documentResourceReference(referenceFilterOperation); DocumentResource* cachedSVGDocument = documentReference ? documentReference->document() : 0; if (cachedSVGDocument) { // Reference is external; wait for notifyFinished(). cachedSVGDocument->addClient(this); m_externalSVGReferences.append(cachedSVGDocument); } else { // Reference is internal; add layer as a client so we can trigger // filter paint invalidation on SVG attribute change. Element* filter = m_layer->renderer()->node()->document().getElementById(referenceFilterOperation->fragment()); if (!isSVGFilterElement(filter)) continue; if (filter->renderer()) toRenderSVGResourceContainer(filter->renderer())->addClientRenderLayer(m_layer); else toSVGFilterElement(filter)->addClient(m_layer->renderer()->node()); m_internalSVGReferences.append(filter); } } }
bool SVGFilterPrimitiveStandardAttributes::layoutObjectIsNeeded(const ComputedStyle& style) { if (isSVGFilterElement(parentNode())) return SVGElement::layoutObjectIsNeeded(style); return false; }
void SVGFEImageElement::notifyFinished(Resource*) { if (!isConnected()) return; Element* parent = parentElement(); if (!parent || !isSVGFilterElement(parent) || !parent->layoutObject()) return; if (LayoutObject* layoutObject = this->layoutObject()) markForLayoutAndParentResourceInvalidation(layoutObject); }
PassRefPtr<FilterEffect> ReferenceFilterBuilder::build(Filter* parentFilter, RenderObject* renderer, FilterEffect* previousEffect, const ReferenceFilterOperation* filterOperation) { if (!renderer) return nullptr; TreeScope* treeScope = &renderer->node()->treeScope(); if (DocumentResourceReference* documentResourceRef = documentResourceReference(filterOperation)) { DocumentResource* cachedSVGDocument = documentResourceRef->document(); // If we have an SVG document, this is an external reference. Otherwise // we look up the referenced node in the current document. if (cachedSVGDocument) treeScope = cachedSVGDocument->document(); } if (!treeScope) return nullptr; Element* filter = treeScope->getElementById(filterOperation->fragment()); if (!filter) { // Although we did not find the referenced filter, it might exist later // in the document. treeScope->document().accessSVGExtensions().addPendingResource(filterOperation->fragment(), toElement(renderer->node())); return nullptr; } if (!isSVGFilterElement(*filter)) return nullptr; SVGFilterElement& filterElement = toSVGFilterElement(*filter); // FIXME: Figure out what to do with SourceAlpha. Right now, we're // using the alpha of the original input layer, which is obviously // wrong. We should probably be extracting the alpha from the // previousEffect, but this requires some more processing. // This may need a spec clarification. 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(); }