TextStream& FEImage::externalRepresentation(TextStream& ts, int indent) const { IntSize imageSize; if (m_image) imageSize = m_image->size(); else if (LayoutObject* layoutObject = referencedLayoutObject()) imageSize = enclosingIntRect(getLayoutObjectRepaintRect(layoutObject)).size(); writeIndent(ts, indent); ts << "[feImage"; FilterEffect::externalRepresentation(ts); ts << " image-size=\"" << imageSize.width() << "x" << imageSize.height() << "\"]\n"; // FIXME: should this dump also object returned by SVGFEImage::image() ? return ts; }
sk_sp<SkImageFilter> FEImage::createImageFilter() { if (auto* layoutObject = referencedLayoutObject()) return createImageFilterForLayoutObject(*layoutObject); sk_sp<SkImage> image = m_image ? toSkSp(m_image->imageForCurrentFrame()) : nullptr; if (!image) { // "A href reference that is an empty image (zero width or zero height), that fails // to download, is non-existent, or that cannot be displayed (e.g. because it is // not in a supported image format) fills the filter primitive subregion with // transparent black." return createTransparentBlack(); } FloatRect srcRect = FloatRect(FloatPoint(), FloatSize(m_image->size())); FloatRect dstRect = filterPrimitiveSubregion(); m_preserveAspectRatio->transformRect(dstRect, srcRect); return SkImageSource::Make(std::move(image), srcRect, dstRect, kHigh_SkFilterQuality); }
PassRefPtr<SkImageFilter> FEImage::createImageFilter(SkiaImageFilterBuilder* builder) { if (auto* layoutObject = referencedLayoutObject()) return createImageFilterForLayoutObject(*layoutObject, builder); FloatRect dstRect = filterPrimitiveSubregion(); RefPtr<SkImage> image = m_image ? m_image->imageForCurrentFrame() : nullptr; if (!image) { // "A href reference that is an empty image (zero width or zero height), that fails // to download, is non-existent, or that cannot be displayed (e.g. because it is // not in a supported image format) fills the filter primitive subregion with // transparent black." return adoptRef(SkPictureImageFilter::Create(nullptr, dstRect)); } FloatRect srcRect = FloatRect(FloatPoint(), m_image->size()); m_preserveAspectRatio->transformRect(dstRect, srcRect); return adoptRef(SkImageSource::Create(image.get(), srcRect, dstRect, kHigh_SkFilterQuality)); }
FloatRect FEImage::determineAbsolutePaintRect(const FloatRect& originalRequestedRect) { LayoutObject* layoutObject = referencedLayoutObject(); if (!m_image && !layoutObject) return FloatRect(); FloatRect requestedRect = originalRequestedRect; if (clipsToBounds()) requestedRect.intersect(maxEffectRect()); FloatRect destRect = getFilter()->mapLocalRectToAbsoluteRect(filterPrimitiveSubregion()); FloatRect srcRect; if (layoutObject) { srcRect = getLayoutObjectRepaintRect(layoutObject); SVGElement* contextNode = toSVGElement(layoutObject->node()); if (contextNode->hasRelativeLengths()) { // FIXME: This fixes relative lengths but breaks non-relative ones (see crbug/260709). SVGLengthContext lengthContext(contextNode); FloatSize viewportSize; if (lengthContext.determineViewport(viewportSize)) { srcRect = makeMapBetweenRects(FloatRect(FloatPoint(), viewportSize), destRect).mapRect(srcRect); } } else { srcRect = getFilter()->mapLocalRectToAbsoluteRect(srcRect); srcRect.move(destRect.x(), destRect.y()); } destRect.intersect(srcRect); } else { srcRect = FloatRect(FloatPoint(), FloatSize(m_image->size())); m_preserveAspectRatio->transformRect(destRect, srcRect); } destRect.intersect(requestedRect); addAbsolutePaintRect(destRect); return destRect; }