diff options
Diffstat (limited to 'Source/WebCore/svg/graphics')
-rw-r--r-- | Source/WebCore/svg/graphics/SVGImage.cpp | 251 | ||||
-rw-r--r-- | Source/WebCore/svg/graphics/SVGImage.h | 72 | ||||
-rw-r--r-- | Source/WebCore/svg/graphics/SVGImageCache.cpp | 40 | ||||
-rw-r--r-- | Source/WebCore/svg/graphics/SVGImageCache.h | 16 | ||||
-rw-r--r-- | Source/WebCore/svg/graphics/SVGImageClients.h (renamed from Source/WebCore/svg/graphics/SVGImageChromeClient.h) | 32 | ||||
-rw-r--r-- | Source/WebCore/svg/graphics/SVGImageForContainer.cpp | 25 | ||||
-rw-r--r-- | Source/WebCore/svg/graphics/SVGImageForContainer.h | 38 | ||||
-rw-r--r-- | Source/WebCore/svg/graphics/filters/SVGFEImage.cpp | 43 | ||||
-rw-r--r-- | Source/WebCore/svg/graphics/filters/SVGFEImage.h | 35 | ||||
-rw-r--r-- | Source/WebCore/svg/graphics/filters/SVGFilter.cpp | 8 | ||||
-rw-r--r-- | Source/WebCore/svg/graphics/filters/SVGFilter.h | 29 | ||||
-rw-r--r-- | Source/WebCore/svg/graphics/filters/SVGFilterBuilder.cpp | 33 | ||||
-rw-r--r-- | Source/WebCore/svg/graphics/filters/SVGFilterBuilder.h | 20 |
13 files changed, 329 insertions, 313 deletions
diff --git a/Source/WebCore/svg/graphics/SVGImage.cpp b/Source/WebCore/svg/graphics/SVGImage.cpp index 8ebf0444e..27cec3db7 100644 --- a/Source/WebCore/svg/graphics/SVGImage.cpp +++ b/Source/WebCore/svg/graphics/SVGImage.cpp @@ -1,6 +1,6 @@ /* * Copyright (C) 2006 Eric Seidel <eric@webkit.org> - * Copyright (C) 2008, 2009 Apple Inc. All rights reserved. + * Copyright (C) 2008-2009, 2015-2016 Apple Inc. All rights reserved. * Copyright (C) Research In Motion Limited 2011. All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -26,30 +26,48 @@ */ #include "config.h" - -#if ENABLE(SVG) #include "SVGImage.h" #include "Chrome.h" +#include "CommonVM.h" +#include "DOMWindow.h" #include "DocumentLoader.h" +#include "EditorClient.h" #include "ElementIterator.h" +#include "FrameLoader.h" #include "FrameView.h" #include "ImageBuffer.h" #include "ImageObserver.h" #include "IntRect.h" +#include "JSDOMWindowBase.h" +#include "LibWebRTCProvider.h" #include "MainFrame.h" +#include "Page.h" +#include "PageConfiguration.h" #include "RenderSVGRoot.h" #include "RenderStyle.h" #include "SVGDocument.h" +#include "SVGFEImageElement.h" #include "SVGForeignObjectElement.h" -#include "SVGImageChromeClient.h" +#include "SVGImageClients.h" +#include "SVGImageElement.h" #include "SVGSVGElement.h" #include "Settings.h" +#include "SocketProvider.h" +#include "TextStream.h" +#include <runtime/JSCInlines.h> +#include <runtime/JSLock.h> + +#if USE(DIRECT2D) +#include "COMPtr.h" +#include <d2d1.h> +#endif namespace WebCore { -SVGImage::SVGImage(ImageObserver* observer) - : Image(observer) +SVGImage::SVGImage(ImageObserver& observer, const URL& url) + : Image(&observer) + , m_url(url) { } @@ -57,7 +75,7 @@ SVGImage::~SVGImage() { if (m_page) { // Store m_page in a local variable, clearing m_page, so that SVGImageChromeClient knows we're destructed. - std::unique_ptr<Page> currentPage = std::move(m_page); + std::unique_ptr<Page> currentPage = WTFMove(m_page); currentPage->mainFrame().loader().frameDetached(); // Break both the loader and view references to the frame } @@ -65,51 +83,64 @@ SVGImage::~SVGImage() ASSERT(!m_chromeClient || !m_chromeClient->image()); } -bool SVGImage::hasSingleSecurityOrigin() const +inline SVGSVGElement* SVGImage::rootElement() const { if (!m_page) - return true; + return nullptr; + return SVGDocument::rootElement(*m_page->mainFrame().document()); +} - SVGSVGElement* rootElement = toSVGDocument(m_page->mainFrame().document())->rootElement(); +bool SVGImage::hasSingleSecurityOrigin() const +{ + SVGSVGElement* rootElement = this->rootElement(); if (!rootElement) return true; - // Don't allow foreignObject elements since they can leak information with arbitrary HTML (like spellcheck or control theme). - if (descendantsOfType<SVGForeignObjectElement>(*rootElement).first()) - return false; + // FIXME: Once foreignObject elements within SVG images are updated to not leak cross-origin data + // (e.g., visited links, spellcheck) we can remove the SVGForeignObjectElement check here and + // research if we can remove the Image::hasSingleSecurityOrigin mechanism entirely. + for (auto& element : descendantsOfType<SVGElement>(*rootElement)) { + if (is<SVGForeignObjectElement>(element)) + return false; + if (is<SVGImageElement>(element)) { + if (!downcast<SVGImageElement>(element).hasSingleSecurityOrigin()) + return false; + } else if (is<SVGFEImageElement>(element)) { + if (!downcast<SVGFEImageElement>(element).hasSingleSecurityOrigin()) + return false; + } + } // Because SVG image rendering disallows external resources and links, // these images effectively are restricted to a single security origin. return true; } -void SVGImage::setContainerSize(const IntSize& size) +void SVGImage::setContainerSize(const FloatSize& size) { - if (!m_page || !usesContainerSize()) + if (!usesContainerSize()) return; - SVGSVGElement* rootElement = toSVGDocument(m_page->mainFrame().document())->rootElement(); + SVGSVGElement* rootElement = this->rootElement(); if (!rootElement) return; - RenderSVGRoot* renderer = toRenderSVGRoot(rootElement->renderer()); + auto* renderer = downcast<RenderSVGRoot>(rootElement->renderer()); if (!renderer) return; FrameView* view = frameView(); view->resize(this->containerSize()); - renderer->setContainerSize(size); + renderer->setContainerSize(IntSize(size)); } IntSize SVGImage::containerSize() const { - if (!m_page) - return IntSize(); - SVGSVGElement* rootElement = toSVGDocument(m_page->mainFrame().document())->rootElement(); + SVGSVGElement* rootElement = this->rootElement(); if (!rootElement) return IntSize(); - RenderSVGRoot* renderer = toRenderSVGRoot(rootElement->renderer()); + auto* renderer = downcast<RenderSVGRoot>(rootElement->renderer()); if (!renderer) return IntSize(); @@ -122,7 +153,7 @@ IntSize SVGImage::containerSize() const ASSERT(renderer->style().effectiveZoom() == 1); FloatSize currentSize; - if (rootElement->intrinsicWidth().isFixed() && rootElement->intrinsicHeight().isFixed()) + if (rootElement->hasIntrinsicWidth() && rootElement->hasIntrinsicHeight()) currentSize = rootElement->currentViewportSize(); else currentSize = rootElement->currentViewBoxRect().size(); @@ -134,8 +165,8 @@ IntSize SVGImage::containerSize() const return IntSize(300, 150); } -void SVGImage::drawForContainer(GraphicsContext* context, const FloatSize containerSize, float zoom, const FloatRect& dstRect, - const FloatRect& srcRect, ColorSpace colorSpace, CompositeOperator compositeOp, BlendMode blendMode) +void SVGImage::drawForContainer(GraphicsContext& context, const FloatSize containerSize, float zoom, const FloatRect& dstRect, + const FloatRect& srcRect, CompositeOperator compositeOp, BlendMode blendMode) { if (!m_page) return; @@ -144,7 +175,7 @@ void SVGImage::drawForContainer(GraphicsContext* context, const FloatSize contai ASSERT(observer); // Temporarily reset image observer, we don't want to receive any changeInRect() calls due to this relayout. - setImageObserver(0); + setImageObserver(nullptr); IntSize roundedContainerSize = roundedIntSize(containerSize); setContainerSize(roundedContainerSize); @@ -157,38 +188,66 @@ void SVGImage::drawForContainer(GraphicsContext* context, const FloatSize contai adjustedSrcSize.scale(roundedContainerSize.width() / containerSize.width(), roundedContainerSize.height() / containerSize.height()); scaledSrc.setSize(adjustedSrcSize); - draw(context, dstRect, scaledSrc, colorSpace, compositeOp, blendMode, ImageOrientationDescription()); + draw(context, dstRect, scaledSrc, compositeOp, blendMode, ImageOrientationDescription()); setImageObserver(observer); } #if USE(CAIRO) -// Passes ownership of the native image to the caller so PassNativeImagePtr needs +// Passes ownership of the native image to the caller so NativeImagePtr needs // to be a smart pointer type. -PassNativeImagePtr SVGImage::nativeImageForCurrentFrame() +NativeImagePtr SVGImage::nativeImageForCurrentFrame(const GraphicsContext*) { if (!m_page) - return 0; + return nullptr; - std::unique_ptr<ImageBuffer> buffer = ImageBuffer::create(size(), 1); + // Cairo does not use the accelerated drawing flag, so it's OK to make an unconditionally unaccelerated buffer. + std::unique_ptr<ImageBuffer> buffer = ImageBuffer::create(size(), Unaccelerated); if (!buffer) // failed to allocate image - return 0; + return nullptr; - draw(buffer->context(), rect(), rect(), ColorSpaceDeviceRGB, CompositeSourceOver, BlendModeNormal, ImageOrientationDescription()); + draw(buffer->context(), rect(), rect(), CompositeSourceOver, BlendModeNormal, ImageOrientationDescription()); // FIXME: WK(Bug 113657): We should use DontCopyBackingStore here. return buffer->copyImage(CopyBackingStore)->nativeImageForCurrentFrame(); } #endif -void SVGImage::drawPatternForContainer(GraphicsContext* context, const FloatSize containerSize, float zoom, const FloatRect& srcRect, - const AffineTransform& patternTransform, const FloatPoint& phase, ColorSpace colorSpace, CompositeOperator compositeOp, const FloatRect& dstRect, BlendMode blendMode) +#if USE(DIRECT2D) +NativeImagePtr SVGImage::nativeImage(const GraphicsContext* targetContext) +{ + ASSERT(targetContext); + if (!m_page || !targetContext) + return nullptr; + + auto platformContext = targetContext->platformContext(); + ASSERT(platformContext); + + // Draw the SVG into a bitmap. + COMPtr<ID2D1BitmapRenderTarget> nativeImageTarget; + HRESULT hr = platformContext->CreateCompatibleRenderTarget(IntSize(rect().size()), &nativeImageTarget); + ASSERT(SUCCEEDED(hr)); + + GraphicsContext localContext(nativeImageTarget.get()); + + draw(localContext, rect(), rect(), CompositeSourceOver, BlendModeNormal, ImageOrientationDescription()); + + COMPtr<ID2D1Bitmap> nativeImage; + hr = nativeImageTarget->GetBitmap(&nativeImage); + ASSERT(SUCCEEDED(hr)); + + return nativeImage; +} +#endif + +void SVGImage::drawPatternForContainer(GraphicsContext& context, const FloatSize& containerSize, float zoom, const FloatRect& srcRect, + const AffineTransform& patternTransform, const FloatPoint& phase, const FloatSize& spacing, CompositeOperator compositeOp, const FloatRect& dstRect, BlendMode blendMode) { FloatRect zoomedContainerRect = FloatRect(FloatPoint(), containerSize); zoomedContainerRect.scale(zoom); // The ImageBuffer size needs to be scaled to match the final resolution. - AffineTransform transform = context->getCTM(); + AffineTransform transform = context.getCTM(); FloatSize imageBufferScale = FloatSize(transform.xScale(), transform.yScale()); ASSERT(imageBufferScale.width()); ASSERT(imageBufferScale.height()); @@ -196,15 +255,16 @@ void SVGImage::drawPatternForContainer(GraphicsContext* context, const FloatSize FloatRect imageBufferSize = zoomedContainerRect; imageBufferSize.scale(imageBufferScale.width(), imageBufferScale.height()); - std::unique_ptr<ImageBuffer> buffer = ImageBuffer::create(expandedIntSize(imageBufferSize.size()), 1); + std::unique_ptr<ImageBuffer> buffer = ImageBuffer::createCompatibleBuffer(expandedIntSize(imageBufferSize.size()), 1, ColorSpaceSRGB, context); if (!buffer) // Failed to allocate buffer. return; - drawForContainer(buffer->context(), containerSize, zoom, imageBufferSize, zoomedContainerRect, ColorSpaceDeviceRGB, CompositeSourceOver, BlendModeNormal); - if (context->drawLuminanceMask()) + drawForContainer(buffer->context(), containerSize, zoom, imageBufferSize, zoomedContainerRect, CompositeSourceOver, BlendModeNormal); + if (context.drawLuminanceMask()) buffer->convertToLuminanceMask(); - RefPtr<Image> image = buffer->copyImage(DontCopyBackingStore, Unscaled); - image->setSpaceSize(spaceSize()); + RefPtr<Image> image = ImageBuffer::sinkIntoImage(WTFMove(buffer), Unscaled); + if (!image) + return; // Adjust the source rect and transform due to the image buffer's scaling. FloatRect scaledSrcRect = srcRect; @@ -212,24 +272,27 @@ void SVGImage::drawPatternForContainer(GraphicsContext* context, const FloatSize AffineTransform unscaledPatternTransform(patternTransform); unscaledPatternTransform.scale(1 / imageBufferScale.width(), 1 / imageBufferScale.height()); - context->setDrawLuminanceMask(false); - image->drawPattern(context, scaledSrcRect, unscaledPatternTransform, phase, colorSpace, compositeOp, dstRect, blendMode); + context.setDrawLuminanceMask(false); + image->drawPattern(context, dstRect, scaledSrcRect, unscaledPatternTransform, phase, spacing, compositeOp, blendMode); } -void SVGImage::draw(GraphicsContext* context, const FloatRect& dstRect, const FloatRect& srcRect, ColorSpace, CompositeOperator compositeOp, BlendMode blendMode, ImageOrientationDescription) +void SVGImage::draw(GraphicsContext& context, const FloatRect& dstRect, const FloatRect& srcRect, CompositeOperator compositeOp, BlendMode blendMode, ImageOrientationDescription) { if (!m_page) return; FrameView* view = frameView(); + ASSERT(view); - GraphicsContextStateSaver stateSaver(*context); - context->setCompositeOperation(compositeOp, blendMode); - context->clip(enclosingIntRect(dstRect)); - bool compositingRequiresTransparencyLayer = compositeOp != CompositeSourceOver || blendMode != BlendModeNormal; + GraphicsContextStateSaver stateSaver(context); + context.setCompositeOperation(compositeOp, blendMode); + context.clip(enclosingIntRect(dstRect)); + + float alpha = context.alpha(); + bool compositingRequiresTransparencyLayer = compositeOp != CompositeSourceOver || blendMode != BlendModeNormal || alpha < 1; if (compositingRequiresTransparencyLayer) { - context->beginTransparencyLayer(1); - context->setCompositeOperation(CompositeSourceOver, BlendModeNormal); + context.beginTransparencyLayer(alpha); + context.setCompositeOperation(CompositeSourceOver, BlendModeNormal); } FloatSize scale(dstRect.width() / srcRect.width(), dstRect.height() / srcRect.height()); @@ -239,18 +302,21 @@ void SVGImage::draw(GraphicsContext* context, const FloatRect& dstRect, const Fl FloatSize topLeftOffset(srcRect.location().x() * scale.width(), srcRect.location().y() * scale.height()); FloatPoint destOffset = dstRect.location() - topLeftOffset; - context->translate(destOffset.x(), destOffset.y()); - context->scale(scale); + context.translate(destOffset.x(), destOffset.y()); + context.scale(scale); view->resize(containerSize()); + if (!m_url.isEmpty()) + view->scrollToFragment(m_url); + if (view->needsLayout()) view->layout(); - view->paint(context, enclosingIntRect(srcRect)); + view->paint(context, intersection(context.clipBounds(), enclosingIntRect(srcRect))); if (compositingRequiresTransparencyLayer) - context->endTransparencyLayer(); + context.endTransparencyLayer(); stateSaver.restore(); @@ -260,52 +326,44 @@ void SVGImage::draw(GraphicsContext* context, const FloatRect& dstRect, const Fl RenderBox* SVGImage::embeddedContentBox() const { - if (!m_page) - return 0; - SVGSVGElement* rootElement = toSVGDocument(m_page->mainFrame().document())->rootElement(); + SVGSVGElement* rootElement = this->rootElement(); if (!rootElement) - return 0; - return toRenderBox(rootElement->renderer()); + return nullptr; + return downcast<RenderBox>(rootElement->renderer()); } FrameView* SVGImage::frameView() const { if (!m_page) - return 0; + return nullptr; return m_page->mainFrame().view(); } bool SVGImage::hasRelativeWidth() const { - if (!m_page) - return false; - SVGSVGElement* rootElement = toSVGDocument(m_page->mainFrame().document())->rootElement(); + SVGSVGElement* rootElement = this->rootElement(); if (!rootElement) return false; - return rootElement->intrinsicWidth().isPercent(); + return rootElement->intrinsicWidth().isPercentOrCalculated(); } bool SVGImage::hasRelativeHeight() const { - if (!m_page) - return false; - SVGSVGElement* rootElement = toSVGDocument(m_page->mainFrame().document())->rootElement(); + SVGSVGElement* rootElement = this->rootElement(); if (!rootElement) return false; - return rootElement->intrinsicHeight().isPercent(); + return rootElement->intrinsicHeight().isPercentOrCalculated(); } void SVGImage::computeIntrinsicDimensions(Length& intrinsicWidth, Length& intrinsicHeight, FloatSize& intrinsicRatio) { - if (!m_page) - return; - SVGSVGElement* rootElement = toSVGDocument(m_page->mainFrame().document())->rootElement(); + SVGSVGElement* rootElement = this->rootElement(); if (!rootElement) return; intrinsicWidth = rootElement->intrinsicWidth(); intrinsicHeight = rootElement->intrinsicHeight(); - if (rootElement->preserveAspectRatio().align() == SVGPreserveAspectRatio::SVG_PRESERVEASPECTRATIO_NONE) + if (rootElement->preserveAspectRatio().align() == SVGPreserveAspectRatioValue::SVG_PRESERVEASPECTRATIO_NONE) return; intrinsicRatio = rootElement->viewBox().size(); @@ -313,12 +371,9 @@ void SVGImage::computeIntrinsicDimensions(Length& intrinsicWidth, Length& intrin intrinsicRatio = FloatSize(floatValueForLength(intrinsicWidth, 0), floatValueForLength(intrinsicHeight, 0)); } -// FIXME: support catchUpIfNecessary. -void SVGImage::startAnimation(bool /* catchUpIfNecessary */) +void SVGImage::startAnimation() { - if (!m_page) - return; - SVGSVGElement* rootElement = toSVGDocument(m_page->mainFrame().document())->rootElement(); + SVGSVGElement* rootElement = this->rootElement(); if (!rootElement) return; rootElement->unpauseAnimations(); @@ -327,9 +382,7 @@ void SVGImage::startAnimation(bool /* catchUpIfNecessary */) void SVGImage::stopAnimation() { - if (!m_page) - return; - SVGSVGElement* rootElement = toSVGDocument(m_page->mainFrame().document())->rootElement(); + SVGSVGElement* rootElement = this->rootElement(); if (!rootElement) return; rootElement->pauseAnimations(); @@ -340,6 +393,21 @@ void SVGImage::resetAnimation() stopAnimation(); } +void SVGImage::reportApproximateMemoryCost() const +{ + Document* document = m_page->mainFrame().document(); + size_t decodedImageMemoryCost = 0; + + for (Node* node = document; node; node = NodeTraversal::next(*node)) + decodedImageMemoryCost += node->approximateMemoryCost(); + + JSC::VM& vm = commonVM(); + JSC::JSLockHolder lock(vm); + // FIXME: Adopt reportExtraMemoryVisited, and switch to reportExtraMemoryAllocated. + // https://bugs.webkit.org/show_bug.cgi?id=142595 + vm.heap.deprecatedReportExtraMemory(decodedImageMemoryCost + data()->size()); +} + bool SVGImage::dataChanged(bool allDataReceived) { // Don't do anything if is an empty image. @@ -347,10 +415,14 @@ bool SVGImage::dataChanged(bool allDataReceived) return true; if (allDataReceived) { - Page::PageClients pageClients; - fillWithEmptyClients(pageClients); + PageConfiguration pageConfiguration( + createEmptyEditorClient(), + SocketProvider::create(), + makeUniqueRef<LibWebRTCProvider>() + ); + fillWithEmptyClients(pageConfiguration); m_chromeClient = std::make_unique<SVGImageChromeClient>(this); - pageClients.chromeClient = m_chromeClient.get(); + pageConfiguration.chromeClient = m_chromeClient.get(); // FIXME: If this SVG ends up loading itself, we might leak the world. // The Cache code does not know about CachedImages holding Frames and @@ -358,10 +430,11 @@ bool SVGImage::dataChanged(bool allDataReceived) // This will become an issue when SVGImage will be able to load other // SVGImage objects, but we're safe now, because SVGImage can only be // loaded by a top-level document. - m_page = std::make_unique<Page>(pageClients); + m_page = std::make_unique<Page>(WTFMove(pageConfiguration)); m_page->settings().setMediaEnabled(false); m_page->settings().setScriptEnabled(false); m_page->settings().setPluginsEnabled(false); + m_page->settings().setAcceleratedCompositingEnabled(false); Frame& frame = m_page->mainFrame(); frame.setView(FrameView::create(frame)); @@ -380,6 +453,7 @@ bool SVGImage::dataChanged(bool allDataReceived) // Set the intrinsic size before a container size is available. m_intrinsicSize = containerSize(); + reportApproximateMemoryCost(); } return m_page != nullptr; @@ -387,7 +461,7 @@ bool SVGImage::dataChanged(bool allDataReceived) String SVGImage::filenameExtension() const { - return "svg"; + return ASCIILiteral("svg"); } bool isInSVGImage(const Element* element) @@ -401,6 +475,11 @@ bool isInSVGImage(const Element* element) return page->chrome().client().isSVGImageChromeClient(); } +void SVGImage::dump(TextStream& ts) const +{ + Image::dump(ts); + ts.dumpProperty("url", m_url.string()); } -#endif // ENABLE(SVG) + +} diff --git a/Source/WebCore/svg/graphics/SVGImage.h b/Source/WebCore/svg/graphics/SVGImage.h index 62f9f1d6a..13f9ed87e 100644 --- a/Source/WebCore/svg/graphics/SVGImage.h +++ b/Source/WebCore/svg/graphics/SVGImage.h @@ -24,12 +24,10 @@ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -#ifndef SVGImage_h -#define SVGImage_h - -#if ENABLE(SVG) +#pragma once #include "Image.h" +#include "URL.h" namespace WebCore { @@ -38,33 +36,39 @@ class FrameView; class ImageBuffer; class Page; class RenderBox; +class SVGSVGElement; class SVGImageChromeClient; class SVGImageForContainer; class SVGImage final : public Image { public: - static PassRefPtr<SVGImage> create(ImageObserver* observer) + static Ref<SVGImage> create(ImageObserver& observer, const URL& url) { - return adoptRef(new SVGImage(observer)); + return adoptRef(*new SVGImage(observer, url)); } RenderBox* embeddedContentBox() const; FrameView* frameView() const; - virtual bool isSVGImage() const override { return true; } - virtual IntSize size() const override { return m_intrinsicSize; } + bool isSVGImage() const final { return true; } + FloatSize size() const final { return m_intrinsicSize; } + + void setURL(const URL& url) { m_url = url; } - virtual bool hasSingleSecurityOrigin() const override; + bool hasSingleSecurityOrigin() const final; - virtual bool hasRelativeWidth() const override; - virtual bool hasRelativeHeight() const override; + bool hasRelativeWidth() const final; + bool hasRelativeHeight() const final; - virtual void startAnimation(bool /*catchUpIfNecessary*/ = true) override; - virtual void stopAnimation() override; - virtual void resetAnimation() override; + void startAnimation() final; + void stopAnimation() final; + void resetAnimation() final; #if USE(CAIRO) - virtual PassNativeImagePtr nativeImageForCurrentFrame() override; + NativeImagePtr nativeImageForCurrentFrame(const GraphicsContext* = nullptr) final; +#endif +#if USE(DIRECT2D) + NativeImagePtr nativeImage(const GraphicsContext* = nullptr) final; #endif private: @@ -73,38 +77,40 @@ private: virtual ~SVGImage(); - virtual String filenameExtension() const override; + String filenameExtension() const final; - virtual void setContainerSize(const IntSize&) override; + void setContainerSize(const FloatSize&) final; IntSize containerSize() const; - virtual bool usesContainerSize() const override { return true; } - virtual void computeIntrinsicDimensions(Length& intrinsicWidth, Length& intrinsicHeight, FloatSize& intrinsicRatio) override; + bool usesContainerSize() const final { return true; } + void computeIntrinsicDimensions(Length& intrinsicWidth, Length& intrinsicHeight, FloatSize& intrinsicRatio) final; - virtual bool dataChanged(bool allDataReceived) override; + void reportApproximateMemoryCost() const; + bool dataChanged(bool allDataReceived) final; // FIXME: SVGImages will be unable to prune because this function is not implemented yet. - virtual void destroyDecodedData(bool) override { } + void destroyDecodedData(bool) final { } // FIXME: Implement this to be less conservative. - virtual bool currentFrameKnownToBeOpaque() override { return false; } + bool currentFrameKnownToBeOpaque() const final { return false; } + + void dump(TextStream&) const final; - SVGImage(ImageObserver*); - virtual void draw(GraphicsContext*, const FloatRect& fromRect, const FloatRect& toRect, ColorSpace styleColorSpace, CompositeOperator, BlendMode, ImageOrientationDescription) override; - void drawForContainer(GraphicsContext*, const FloatSize, float, const FloatRect&, const FloatRect&, ColorSpace, CompositeOperator, BlendMode); - void drawPatternForContainer(GraphicsContext*, const FloatSize, float, const FloatRect&, const AffineTransform&, const FloatPoint&, ColorSpace, + SVGImage(ImageObserver&, const URL&); + void draw(GraphicsContext&, const FloatRect& fromRect, const FloatRect& toRect, CompositeOperator, BlendMode, ImageOrientationDescription) final; + void drawForContainer(GraphicsContext&, const FloatSize, float, const FloatRect&, const FloatRect&, CompositeOperator, BlendMode); + void drawPatternForContainer(GraphicsContext&, const FloatSize& containerSize, float zoom, const FloatRect& srcRect, const AffineTransform&, const FloatPoint& phase, const FloatSize& spacing, CompositeOperator, const FloatRect&, BlendMode); + SVGSVGElement* rootElement() const; + std::unique_ptr<SVGImageChromeClient> m_chromeClient; std::unique_ptr<Page> m_page; - IntSize m_intrinsicSize; + FloatSize m_intrinsicSize; + URL m_url; }; bool isInSVGImage(const Element*); -IMAGE_TYPE_CASTS(SVGImage) - -} - +} // namespace WebCore -#endif // ENABLE(SVG) -#endif // SVGImage_h +SPECIALIZE_TYPE_TRAITS_IMAGE(SVGImage) diff --git a/Source/WebCore/svg/graphics/SVGImageCache.cpp b/Source/WebCore/svg/graphics/SVGImageCache.cpp index e3a89fd3b..399d6bae5 100644 --- a/Source/WebCore/svg/graphics/SVGImageCache.cpp +++ b/Source/WebCore/svg/graphics/SVGImageCache.cpp @@ -21,11 +21,10 @@ #include "config.h" #include "SVGImageCache.h" -#if ENABLE(SVG) #include "FrameView.h" #include "GraphicsContext.h" #include "ImageBuffer.h" -#include "Page.h" +#include "LayoutSize.h" #include "RenderSVGRoot.h" #include "SVGImage.h" #include "SVGImageForContainer.h" @@ -50,7 +49,7 @@ void SVGImageCache::removeClientFromCache(const CachedImageClient* client) m_imageForContainerMap.remove(client); } -void SVGImageCache::setContainerSizeForRenderer(const CachedImageClient* client, const IntSize& containerSize, float containerZoom) +void SVGImageCache::setContainerSizeForRenderer(const CachedImageClient* client, const LayoutSize& containerSize, float containerZoom) { ASSERT(client); ASSERT(!containerSize.isEmpty()); @@ -62,37 +61,26 @@ void SVGImageCache::setContainerSizeForRenderer(const CachedImageClient* client, m_imageForContainerMap.set(client, SVGImageForContainer::create(m_svgImage, containerSizeWithoutZoom, containerZoom)); } -IntSize SVGImageCache::imageSizeForRenderer(const RenderObject* renderer) const +Image* SVGImageCache::findImageForRenderer(const RenderObject* renderer) const { - IntSize imageSize = m_svgImage->size(); - if (!renderer) - return imageSize; - - ImageForContainerMap::const_iterator it = m_imageForContainerMap.find(renderer); - if (it == m_imageForContainerMap.end()) - return imageSize; + return renderer ? m_imageForContainerMap.get(renderer) : nullptr; +} - RefPtr<SVGImageForContainer> imageForContainer = it->value; - ASSERT(!imageForContainer->size().isEmpty()); - return imageForContainer->size(); +FloatSize SVGImageCache::imageSizeForRenderer(const RenderObject* renderer) const +{ + auto* image = findImageForRenderer(renderer); + return image ? image->size() : m_svgImage->size(); } // FIXME: This doesn't take into account the animation timeline so animations will not // restart on page load, nor will two animations in different pages have different timelines. -Image* SVGImageCache::imageForRenderer(const RenderObject* renderer) +Image* SVGImageCache::imageForRenderer(const RenderObject* renderer) const { - if (!renderer) + auto* image = findImageForRenderer(renderer); + if (!image) return Image::nullImage(); - - ImageForContainerMap::iterator it = m_imageForContainerMap.find(renderer); - if (it == m_imageForContainerMap.end()) - return Image::nullImage(); - - RefPtr<SVGImageForContainer> imageForContainer = it->value; - ASSERT(!imageForContainer->size().isEmpty()); - return imageForContainer.get(); + ASSERT(!image->size().isEmpty()); + return image; } } // namespace WebCore - -#endif // ENABLE(SVG) diff --git a/Source/WebCore/svg/graphics/SVGImageCache.h b/Source/WebCore/svg/graphics/SVGImageCache.h index 3e000d3ac..bd8ce4f55 100644 --- a/Source/WebCore/svg/graphics/SVGImageCache.h +++ b/Source/WebCore/svg/graphics/SVGImageCache.h @@ -17,10 +17,8 @@ * Boston, MA 02110-1301, USA. */ -#ifndef SVGImageCache_h -#define SVGImageCache_h +#pragma once -#if ENABLE(SVG) #include "FloatSize.h" #include "Image.h" #include "IntSize.h" @@ -32,6 +30,7 @@ namespace WebCore { class CachedImage; class CachedImageClient; class ImageBuffer; +class LayoutSize; class SVGImage; class SVGImageForContainer; class RenderObject; @@ -44,12 +43,14 @@ public: void removeClientFromCache(const CachedImageClient*); - void setContainerSizeForRenderer(const CachedImageClient*, const IntSize&, float); - IntSize imageSizeForRenderer(const RenderObject*) const; + void setContainerSizeForRenderer(const CachedImageClient*, const LayoutSize&, float); + FloatSize imageSizeForRenderer(const RenderObject*) const; - Image* imageForRenderer(const RenderObject*); + Image* imageForRenderer(const RenderObject*) const; private: + Image* findImageForRenderer(const RenderObject*) const; + typedef HashMap<const CachedImageClient*, RefPtr<SVGImageForContainer>> ImageForContainerMap; SVGImage* m_svgImage; @@ -57,6 +58,3 @@ private: }; } // namespace WebCore - -#endif // ENABLE(SVG) -#endif // SVGImageCache_h diff --git a/Source/WebCore/svg/graphics/SVGImageChromeClient.h b/Source/WebCore/svg/graphics/SVGImageClients.h index af64e463d..bee03d506 100644 --- a/Source/WebCore/svg/graphics/SVGImageChromeClient.h +++ b/Source/WebCore/svg/graphics/SVGImageClients.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2012 Apple Inc. All rights reserved. + * Copyright (C) 2015 Apple Inc. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions @@ -10,7 +10,7 @@ * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. - * 3. Neither the name of Apple Computer, Inc. ("Apple") nor the names of + * 3. Neither the name of Apple Inc. ("Apple") nor the names of * its contributors may be used to endorse or promote products derived * from this software without specific prior written permission. * @@ -26,16 +26,13 @@ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -#ifndef SVGImageChromeClient_h -#define SVGImageChromeClient_h - -#if ENABLE(SVG) +#pragma once #include "EmptyClients.h" namespace WebCore { -class SVGImageChromeClient : public EmptyChromeClient { +class SVGImageChromeClient final : public EmptyChromeClient { WTF_MAKE_NONCOPYABLE(SVGImageChromeClient); WTF_MAKE_FAST_ALLOCATED; public: SVGImageChromeClient(SVGImage* image) @@ -43,32 +40,23 @@ public: { } - virtual bool isSVGImageChromeClient() const override { return true; } + bool isSVGImageChromeClient() const final { return true; } SVGImage* image() const { return m_image; } private: - virtual void chromeDestroyed() override + void chromeDestroyed() final { - m_image = 0; + m_image = nullptr; } - virtual void invalidateContentsAndRootView(const IntRect& r, bool) override + void invalidateContentsAndRootView(const IntRect& r) final { // If m_image->m_page is null, we're being destructed, don't fire changedInRect() in that case. if (m_image && m_image->imageObserver() && m_image->m_page) - m_image->imageObserver()->changedInRect(m_image, r); + m_image->imageObserver()->changedInRect(m_image, &r); } SVGImage* m_image; }; -inline SVGImageChromeClient* toSVGImageChromeClient(ChromeClient* client) -{ - ASSERT_WITH_SECURITY_IMPLICATION(!client || client->isSVGImageChromeClient()); - return static_cast<SVGImageChromeClient*>(client); -} - -} - -#endif // ENABLE(SVG) -#endif // SVGImageChromeClient_h +} // namespace WebCore diff --git a/Source/WebCore/svg/graphics/SVGImageForContainer.cpp b/Source/WebCore/svg/graphics/SVGImageForContainer.cpp index 33d78778c..482c39415 100644 --- a/Source/WebCore/svg/graphics/SVGImageForContainer.cpp +++ b/Source/WebCore/svg/graphics/SVGImageForContainer.cpp @@ -20,40 +20,35 @@ #include "config.h" #include "SVGImageForContainer.h" -#if ENABLE(SVG) #include "AffineTransform.h" #include "FloatRect.h" #include "FloatSize.h" #include "Image.h" -#include "SVGImage.h" namespace WebCore { -IntSize SVGImageForContainer::size() const +FloatSize SVGImageForContainer::size() const { FloatSize scaledContainerSize(m_containerSize); scaledContainerSize.scale(m_zoom); - return roundedIntSize(scaledContainerSize); + return FloatSize(roundedIntSize(scaledContainerSize)); } -void SVGImageForContainer::draw(GraphicsContext* context, const FloatRect& dstRect, - const FloatRect& srcRect, ColorSpace colorSpace, CompositeOperator compositeOp, BlendMode blendMode, ImageOrientationDescription) +void SVGImageForContainer::draw(GraphicsContext& context, const FloatRect& dstRect, + const FloatRect& srcRect, CompositeOperator compositeOp, BlendMode blendMode, ImageOrientationDescription) { - m_image->drawForContainer(context, m_containerSize, m_zoom, dstRect, srcRect, colorSpace, compositeOp, blendMode); + m_image->drawForContainer(context, m_containerSize, m_zoom, dstRect, srcRect, compositeOp, blendMode); } -void SVGImageForContainer::drawPattern(GraphicsContext* context, const FloatRect& srcRect, const AffineTransform& patternTransform, - const FloatPoint& phase, ColorSpace colorSpace, CompositeOperator compositeOp, const FloatRect& dstRect, BlendMode blendMode) +void SVGImageForContainer::drawPattern(GraphicsContext& context, const FloatRect& dstRect, const FloatRect& srcRect, const AffineTransform& patternTransform, + const FloatPoint& phase, const FloatSize& spacing, CompositeOperator compositeOp, BlendMode blendMode) { - m_image->setSpaceSize(spaceSize()); - m_image->drawPatternForContainer(context, m_containerSize, m_zoom, srcRect, patternTransform, phase, colorSpace, compositeOp, dstRect, blendMode); + m_image->drawPatternForContainer(context, m_containerSize, m_zoom, srcRect, patternTransform, phase, spacing, compositeOp, dstRect, blendMode); } -PassNativeImagePtr SVGImageForContainer::nativeImageForCurrentFrame() +NativeImagePtr SVGImageForContainer::nativeImageForCurrentFrame(const GraphicsContext* targetContext) { - return m_image->nativeImageForCurrentFrame(); + return m_image->nativeImageForCurrentFrame(targetContext); } } // namespace WebCore - -#endif // ENABLE(SVG) diff --git a/Source/WebCore/svg/graphics/SVGImageForContainer.h b/Source/WebCore/svg/graphics/SVGImageForContainer.h index b0c9bea96..aa1988a00 100644 --- a/Source/WebCore/svg/graphics/SVGImageForContainer.h +++ b/Source/WebCore/svg/graphics/SVGImageForContainer.h @@ -23,46 +23,46 @@ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -#ifndef SVGImageForContainer_h -#define SVGImageForContainer_h - -#if ENABLE(SVG) +#pragma once #include "AffineTransform.h" #include "FloatRect.h" #include "FloatSize.h" #include "Image.h" #include "SVGImage.h" +#include "URL.h" namespace WebCore { class SVGImageForContainer final : public Image { public: - static PassRefPtr<SVGImageForContainer> create(SVGImage* image, const FloatSize& containerSize, float zoom) + static Ref<SVGImageForContainer> create(SVGImage* image, const FloatSize& containerSize, float zoom) { - return adoptRef(new SVGImageForContainer(image, containerSize, zoom)); + return adoptRef(*new SVGImageForContainer(image, containerSize, zoom)); } - virtual bool isSVGImage() const override { return true; } + bool isSVGImage() const final { return true; } + + FloatSize size() const final; - virtual IntSize size() const override; + void setURL(const URL& url) { m_image->setURL(url); } - virtual bool usesContainerSize() const override { return m_image->usesContainerSize(); } - virtual bool hasRelativeWidth() const override { return m_image->hasRelativeWidth(); } - virtual bool hasRelativeHeight() const override { return m_image->hasRelativeHeight(); } - virtual void computeIntrinsicDimensions(Length& intrinsicWidth, Length& intrinsicHeight, FloatSize& intrinsicRatio) override + bool usesContainerSize() const final { return m_image->usesContainerSize(); } + bool hasRelativeWidth() const final { return m_image->hasRelativeWidth(); } + bool hasRelativeHeight() const final { return m_image->hasRelativeHeight(); } + void computeIntrinsicDimensions(Length& intrinsicWidth, Length& intrinsicHeight, FloatSize& intrinsicRatio) final { m_image->computeIntrinsicDimensions(intrinsicWidth, intrinsicHeight, intrinsicRatio); } - virtual void draw(GraphicsContext*, const FloatRect&, const FloatRect&, ColorSpace, CompositeOperator, BlendMode, ImageOrientationDescription) override; + void draw(GraphicsContext&, const FloatRect&, const FloatRect&, CompositeOperator, BlendMode, ImageOrientationDescription) final; - virtual void drawPattern(GraphicsContext*, const FloatRect&, const AffineTransform&, const FloatPoint&, ColorSpace, CompositeOperator, const FloatRect&, BlendMode) override; + void drawPattern(GraphicsContext&, const FloatRect&, const FloatRect&, const AffineTransform&, const FloatPoint&, const FloatSize&, CompositeOperator, BlendMode) final; // FIXME: Implement this to be less conservative. - virtual bool currentFrameKnownToBeOpaque() override { return false; } + bool currentFrameKnownToBeOpaque() const final { return false; } - virtual PassNativeImagePtr nativeImageForCurrentFrame() override; + NativeImagePtr nativeImageForCurrentFrame(const GraphicsContext* = nullptr) final; private: SVGImageForContainer(SVGImage* image, const FloatSize& containerSize, float zoom) @@ -72,13 +72,11 @@ private: { } - virtual void destroyDecodedData(bool /*destroyAll*/ = true) override { } + void destroyDecodedData(bool /*destroyAll*/ = true) final { } SVGImage* m_image; const FloatSize m_containerSize; const float m_zoom; }; -} -#endif // ENABLE(SVG) -#endif // SVGImageForContainer_h +} // namespace WebCore diff --git a/Source/WebCore/svg/graphics/filters/SVGFEImage.cpp b/Source/WebCore/svg/graphics/filters/SVGFEImage.cpp index 87be6e85e..d25893e2a 100644 --- a/Source/WebCore/svg/graphics/filters/SVGFEImage.cpp +++ b/Source/WebCore/svg/graphics/filters/SVGFEImage.cpp @@ -21,8 +21,6 @@ */ #include "config.h" - -#if ENABLE(SVG) && ENABLE(FILTERS) #include "SVGFEImage.h" #include "AffineTransform.h" @@ -31,22 +29,21 @@ #include "RenderElement.h" #include "RenderTreeAsText.h" #include "SVGElement.h" -#include "SVGPreserveAspectRatio.h" #include "SVGRenderingContext.h" #include "SVGURIReference.h" #include "TextStream.h" namespace WebCore { -FEImage::FEImage(Filter* filter, PassRefPtr<Image> image, const SVGPreserveAspectRatio& preserveAspectRatio) +FEImage::FEImage(Filter& filter, RefPtr<Image> image, const SVGPreserveAspectRatioValue& preserveAspectRatio) : FilterEffect(filter) , m_image(image) - , m_document(0) + , m_document(nullptr) , m_preserveAspectRatio(preserveAspectRatio) { } -FEImage::FEImage(Filter* filter, Document& document, const String& href, const SVGPreserveAspectRatio& preserveAspectRatio) +FEImage::FEImage(Filter& filter, Document& document, const String& href, const SVGPreserveAspectRatioValue& preserveAspectRatio) : FilterEffect(filter) , m_document(&document) , m_href(href) @@ -54,25 +51,25 @@ FEImage::FEImage(Filter* filter, Document& document, const String& href, const S { } -PassRefPtr<FEImage> FEImage::createWithImage(Filter* filter, PassRefPtr<Image> image, const SVGPreserveAspectRatio& preserveAspectRatio) +Ref<FEImage> FEImage::createWithImage(Filter& filter, RefPtr<Image> image, const SVGPreserveAspectRatioValue& preserveAspectRatio) { - return adoptRef(new FEImage(filter, image, preserveAspectRatio)); + return adoptRef(*new FEImage(filter, image, preserveAspectRatio)); } -PassRefPtr<FEImage> FEImage::createWithIRIReference(Filter* filter, Document& document, const String& href, const SVGPreserveAspectRatio& preserveAspectRatio) +Ref<FEImage> FEImage::createWithIRIReference(Filter& filter, Document& document, const String& href, const SVGPreserveAspectRatioValue& preserveAspectRatio) { - return adoptRef(new FEImage(filter, document, href, preserveAspectRatio)); + return adoptRef(*new FEImage(filter, document, href, preserveAspectRatio)); } void FEImage::determineAbsolutePaintRect() { - FloatRect paintRect = filter()->absoluteTransform().mapRect(filterPrimitiveSubregion()); + FloatRect paintRect = filter().absoluteTransform().mapRect(filterPrimitiveSubregion()); FloatRect srcRect; if (m_image) { srcRect.setSize(m_image->size()); m_preserveAspectRatio.transformRect(paintRect, srcRect); } else if (RenderElement* renderer = referencedRenderer()) - srcRect = filter()->absoluteTransform().mapRect(renderer->repaintRectInLocalCoordinates()); + srcRect = filter().absoluteTransform().mapRect(renderer->repaintRectInLocalCoordinates()); if (clipsToBounds()) paintRect.intersect(maxEffectRect()); @@ -101,11 +98,11 @@ void FEImage::platformApplySoftware() if (!resultImage) return; - FloatRect destRect = filter()->absoluteTransform().mapRect(filterPrimitiveSubregion()); + FloatRect destRect = filter().absoluteTransform().mapRect(filterPrimitiveSubregion()); FloatRect srcRect; if (renderer) - srcRect = filter()->absoluteTransform().mapRect(renderer->repaintRectInLocalCoordinates()); + srcRect = filter().absoluteTransform().mapRect(renderer->repaintRectInLocalCoordinates()); else { srcRect = FloatRect(FloatPoint(), m_image->size()); m_preserveAspectRatio.transformRect(destRect, srcRect); @@ -114,14 +111,14 @@ void FEImage::platformApplySoftware() IntPoint paintLocation = absolutePaintRect().location(); destRect.move(-paintLocation.x(), -paintLocation.y()); - // FEImage results are always in ColorSpaceDeviceRGB - setResultColorSpace(ColorSpaceDeviceRGB); + // FEImage results are always in ColorSpaceSRGB + setResultColorSpace(ColorSpaceSRGB); if (renderer) { - const AffineTransform& absoluteTransform = filter()->absoluteTransform(); - resultImage->context()->concatCTM(absoluteTransform); + const AffineTransform& absoluteTransform = filter().absoluteTransform(); + resultImage->context().concatCTM(absoluteTransform); - SVGElement* contextNode = toSVGElement(renderer->element()); + SVGElement* contextNode = downcast<SVGElement>(renderer->element()); if (contextNode->hasRelativeLengths()) { SVGLengthContext lengthContext(contextNode); FloatSize viewportSize; @@ -129,7 +126,7 @@ void FEImage::platformApplySoftware() // If we're referencing an element with percentage units, eg. <rect with="30%"> those values were resolved against the viewport. // Build up a transformation that maps from the viewport space to the filter primitive subregion. if (lengthContext.determineViewport(viewportSize)) - resultImage->context()->concatCTM(makeMapBetweenRects(FloatRect(FloatPoint(), viewportSize), destRect)); + resultImage->context().concatCTM(makeMapBetweenRects(FloatRect(FloatPoint(), viewportSize), destRect)); } AffineTransform contentTransformation; @@ -137,7 +134,7 @@ void FEImage::platformApplySoftware() return; } - resultImage->context()->drawImage(m_image.get(), ColorSpaceDeviceRGB, destRect, srcRect); + resultImage->context().drawImage(*m_image, destRect, srcRect); } void FEImage::dump() @@ -146,7 +143,7 @@ void FEImage::dump() TextStream& FEImage::externalRepresentation(TextStream& ts, int indent) const { - IntSize imageSize; + FloatSize imageSize; if (m_image) imageSize = m_image->size(); else if (RenderObject* renderer = referencedRenderer()) @@ -160,5 +157,3 @@ TextStream& FEImage::externalRepresentation(TextStream& ts, int indent) const } } // namespace WebCore - -#endif // ENABLE(SVG) && ENABLE(FILTERS) diff --git a/Source/WebCore/svg/graphics/filters/SVGFEImage.h b/Source/WebCore/svg/graphics/filters/SVGFEImage.h index 83c886da9..45d8a1be9 100644 --- a/Source/WebCore/svg/graphics/filters/SVGFEImage.h +++ b/Source/WebCore/svg/graphics/filters/SVGFEImage.h @@ -20,12 +20,10 @@ * Boston, MA 02110-1301, USA. */ -#ifndef SVGFEImage_h -#define SVGFEImage_h +#pragma once -#if ENABLE(SVG) && ENABLE(FILTERS) #include "FilterEffect.h" -#include "SVGPreserveAspectRatio.h" +#include "SVGPreserveAspectRatioValue.h" namespace WebCore { @@ -33,27 +31,24 @@ class Document; class Image; class RenderElement; -class FEImage : public FilterEffect { +class FEImage final : public FilterEffect { public: - static PassRefPtr<FEImage> createWithImage(Filter*, PassRefPtr<Image>, const SVGPreserveAspectRatio&); - static PassRefPtr<FEImage> createWithIRIReference(Filter*, Document&, const String&, const SVGPreserveAspectRatio&); + static Ref<FEImage> createWithImage(Filter&, RefPtr<Image>, const SVGPreserveAspectRatioValue&); + static Ref<FEImage> createWithIRIReference(Filter&, Document&, const String&, const SVGPreserveAspectRatioValue&); - virtual void platformApplySoftware() override; -#if ENABLE(OPENCL) - virtual bool platformApplyOpenCL(); -#endif - virtual void dump() override; + void platformApplySoftware() final; + void dump() final; - virtual void determineAbsolutePaintRect() override; + void determineAbsolutePaintRect() final; - virtual FilterEffectType filterEffectType() const override { return FilterEffectTypeImage; } + FilterEffectType filterEffectType() const final { return FilterEffectTypeImage; } - virtual TextStream& externalRepresentation(TextStream&, int indention) const override; + TextStream& externalRepresentation(TextStream&, int indention) const final; private: virtual ~FEImage() { } - FEImage(Filter*, PassRefPtr<Image>, const SVGPreserveAspectRatio&); - FEImage(Filter*, Document&, const String&, const SVGPreserveAspectRatio&); + FEImage(Filter&, RefPtr<Image>, const SVGPreserveAspectRatioValue&); + FEImage(Filter&, Document&, const String&, const SVGPreserveAspectRatioValue&); RenderElement* referencedRenderer() const; RefPtr<Image> m_image; @@ -61,11 +56,7 @@ private: // m_document will never be a dangling reference. See https://bugs.webkit.org/show_bug.cgi?id=99243 Document* m_document; String m_href; - SVGPreserveAspectRatio m_preserveAspectRatio; + SVGPreserveAspectRatioValue m_preserveAspectRatio; }; } // namespace WebCore - -#endif // ENABLE(SVG) && ENABLE(FILTERS) - -#endif // SVGFEImage_h diff --git a/Source/WebCore/svg/graphics/filters/SVGFilter.cpp b/Source/WebCore/svg/graphics/filters/SVGFilter.cpp index e5b27662f..2d85ae550 100644 --- a/Source/WebCore/svg/graphics/filters/SVGFilter.cpp +++ b/Source/WebCore/svg/graphics/filters/SVGFilter.cpp @@ -20,8 +20,6 @@ */ #include "config.h" - -#if ENABLE(SVG) && ENABLE(FILTERS) #include "SVGFilter.h" namespace WebCore { @@ -50,11 +48,9 @@ float SVGFilter::applyVerticalScale(float value) const return Filter::applyVerticalScale(value) * m_absoluteFilterRegion.height() / m_filterRegion.height(); } -PassRefPtr<SVGFilter> SVGFilter::create(const AffineTransform& absoluteTransform, const FloatRect& absoluteSourceDrawingRegion, const FloatRect& targetBoundingBox, const FloatRect& filterRegion, bool effectBBoxMode) +Ref<SVGFilter> SVGFilter::create(const AffineTransform& absoluteTransform, const FloatRect& absoluteSourceDrawingRegion, const FloatRect& targetBoundingBox, const FloatRect& filterRegion, bool effectBBoxMode) { - return adoptRef(new SVGFilter(absoluteTransform, absoluteSourceDrawingRegion, targetBoundingBox, filterRegion, effectBBoxMode)); + return adoptRef(*new SVGFilter(absoluteTransform, absoluteSourceDrawingRegion, targetBoundingBox, filterRegion, effectBBoxMode)); } } // namespace WebCore - -#endif // ENABLE(SVG) && ENABLE(FILTERS) diff --git a/Source/WebCore/svg/graphics/filters/SVGFilter.h b/Source/WebCore/svg/graphics/filters/SVGFilter.h index e4811ded4..a01509eb3 100644 --- a/Source/WebCore/svg/graphics/filters/SVGFilter.h +++ b/Source/WebCore/svg/graphics/filters/SVGFilter.h @@ -18,36 +18,33 @@ * Boston, MA 02110-1301, USA. */ -#ifndef SVGFilter_h -#define SVGFilter_h +#pragma once -#if ENABLE(SVG) && ENABLE(FILTERS) #include "AffineTransform.h" #include "Filter.h" #include "FilterEffect.h" #include "FloatRect.h" #include "FloatSize.h" - -#include <wtf/PassRefPtr.h> #include <wtf/RefCounted.h> #include <wtf/RefPtr.h> +#include <wtf/TypeCasts.h> namespace WebCore { -class SVGFilter : public Filter { +class SVGFilter final : public Filter { public: - static PassRefPtr<SVGFilter> create(const AffineTransform&, const FloatRect&, const FloatRect&, const FloatRect&, bool); + static Ref<SVGFilter> create(const AffineTransform&, const FloatRect&, const FloatRect&, const FloatRect&, bool); FloatRect filterRegionInUserSpace() const { return m_filterRegion; } - virtual FloatRect filterRegion() const override { return m_absoluteFilterRegion; } + FloatRect filterRegion() const final { return m_absoluteFilterRegion; } - virtual float applyHorizontalScale(float value) const override; - virtual float applyVerticalScale(float value) const override; + float applyHorizontalScale(float value) const final; + float applyVerticalScale(float value) const final; - virtual FloatRect sourceImageRect() const override { return m_absoluteSourceDrawingRegion; } + FloatRect sourceImageRect() const final { return m_absoluteSourceDrawingRegion; } FloatRect targetBoundingBox() const { return m_targetBoundingBox; } - virtual bool isSVGFilter() const override final { return true; } + bool isSVGFilter() const final { return true; } private: SVGFilter(const AffineTransform& absoluteTransform, const FloatRect& absoluteSourceDrawingRegion, const FloatRect& targetBoundingBox, const FloatRect& filterRegion, bool effectBBoxMode); @@ -59,10 +56,8 @@ private: bool m_effectBBoxMode; }; -FILTER_TYPE_CASTS(SVGFilter, isSVGFilter()) - } // namespace WebCore -#endif // ENABLE(SVG) && ENABLE(FILTERS) - -#endif // SVGFilter_h +SPECIALIZE_TYPE_TRAITS_BEGIN(WebCore::SVGFilter) + static bool isType(const WebCore::Filter& filter) { return filter.isSVGFilter(); } +SPECIALIZE_TYPE_TRAITS_END() diff --git a/Source/WebCore/svg/graphics/filters/SVGFilterBuilder.cpp b/Source/WebCore/svg/graphics/filters/SVGFilterBuilder.cpp index 31102c9c9..4f6a82771 100644 --- a/Source/WebCore/svg/graphics/filters/SVGFilterBuilder.cpp +++ b/Source/WebCore/svg/graphics/filters/SVGFilterBuilder.cpp @@ -18,26 +18,22 @@ */ #include "config.h" - -#if ENABLE(SVG) && ENABLE(FILTERS) #include "SVGFilterBuilder.h" #include "FilterEffect.h" #include "SourceAlpha.h" #include "SourceGraphic.h" -#include <wtf/PassRefPtr.h> -#include <wtf/text/WTFString.h> namespace WebCore { -SVGFilterBuilder::SVGFilterBuilder(PassRefPtr<FilterEffect> sourceGraphic, PassRefPtr<FilterEffect> sourceAlpha) +SVGFilterBuilder::SVGFilterBuilder(RefPtr<FilterEffect> sourceGraphic) { m_builtinEffects.add(SourceGraphic::effectName(), sourceGraphic); - m_builtinEffects.add(SourceAlpha::effectName(), sourceAlpha); + m_builtinEffects.add(SourceAlpha::effectName(), SourceAlpha::create(*sourceGraphic)); addBuiltinEffects(); } -void SVGFilterBuilder::add(const AtomicString& id, PassRefPtr<FilterEffect> effect) +void SVGFilterBuilder::add(const AtomicString& id, RefPtr<FilterEffect> effect) { if (id.isEmpty()) { m_lastEffect = effect; @@ -66,13 +62,11 @@ FilterEffect* SVGFilterBuilder::getEffectById(const AtomicString& id) const return m_namedEffects.get(id); } -void SVGFilterBuilder::appendEffectToEffectReferences(PassRefPtr<FilterEffect> prpEffect, RenderObject* object) +void SVGFilterBuilder::appendEffectToEffectReferences(RefPtr<FilterEffect>&& effect, RenderObject* object) { - RefPtr<FilterEffect> effect = prpEffect; - // The effect must be a newly created filter effect. ASSERT(!m_effectReferences.contains(effect)); - ASSERT(object && !m_effectRenderer.contains(object)); + ASSERT(!object || !m_effectRenderer.contains(object)); m_effectReferences.add(effect, FilterEffectSet()); unsigned numberOfInputEffects = effect->inputEffects().size(); @@ -80,12 +74,17 @@ void SVGFilterBuilder::appendEffectToEffectReferences(PassRefPtr<FilterEffect> p // It is not possible to add the same value to a set twice. for (unsigned i = 0; i < numberOfInputEffects; ++i) effectReferences(effect->inputEffect(i)).add(effect.get()); - m_effectRenderer.add(object, effect.get()); + + // If object is null, that means the element isn't attached for some + // reason, which in turn mean that certain types of invalidation will not + // work (the LayoutObject -> FilterEffect mapping will not be defined). + if (object) + m_effectRenderer.add(object, effect.get()); } void SVGFilterBuilder::clearEffects() { - m_lastEffect = 0; + m_lastEffect = nullptr; m_namedEffects.clear(); m_effectReferences.clear(); m_effectRenderer.clear(); @@ -99,12 +98,8 @@ void SVGFilterBuilder::clearResultsRecursive(FilterEffect* effect) effect->clearResult(); - HashSet<FilterEffect*>& effectReferences = this->effectReferences(effect); - HashSet<FilterEffect*>::iterator end = effectReferences.end(); - for (HashSet<FilterEffect*>::iterator it = effectReferences.begin(); it != end; ++it) - clearResultsRecursive(*it); + for (auto& reference : effectReferences(effect)) + clearResultsRecursive(reference); } } // namespace WebCore - -#endif // ENABLE(SVG) && ENABLE(FILTERS) diff --git a/Source/WebCore/svg/graphics/filters/SVGFilterBuilder.h b/Source/WebCore/svg/graphics/filters/SVGFilterBuilder.h index d789b7cb6..c5e40a808 100644 --- a/Source/WebCore/svg/graphics/filters/SVGFilterBuilder.h +++ b/Source/WebCore/svg/graphics/filters/SVGFilterBuilder.h @@ -18,15 +18,11 @@ * Boston, MA 02110-1301, USA. */ -#ifndef SVGFilterBuilder_h -#define SVGFilterBuilder_h +#pragma once -#if ENABLE(SVG) && ENABLE(FILTERS) #include "FilterEffect.h" - #include <wtf/HashMap.h> #include <wtf/HashSet.h> -#include <wtf/PassRefPtr.h> #include <wtf/text/AtomicStringHash.h> #include <wtf/text/WTFString.h> @@ -38,14 +34,14 @@ class SVGFilterBuilder { public: typedef HashSet<FilterEffect*> FilterEffectSet; - SVGFilterBuilder(PassRefPtr<FilterEffect> sourceGraphic, PassRefPtr<FilterEffect> sourceAlpha); + SVGFilterBuilder(RefPtr<FilterEffect> sourceGraphic); - void add(const AtomicString& id, PassRefPtr<FilterEffect>); + void add(const AtomicString& id, RefPtr<FilterEffect>); FilterEffect* getEffectById(const AtomicString& id) const; FilterEffect* lastEffect() const { return m_lastEffect.get(); } - void appendEffectToEffectReferences(PassRefPtr<FilterEffect>, RenderObject*); + void appendEffectToEffectReferences(RefPtr<FilterEffect>&&, RenderObject*); inline FilterEffectSet& effectReferences(FilterEffect* effect) { @@ -63,9 +59,8 @@ public: private: inline void addBuiltinEffects() { - HashMap<AtomicString, RefPtr<FilterEffect>>::iterator end = m_builtinEffects.end(); - for (HashMap<AtomicString, RefPtr<FilterEffect>>::iterator iterator = m_builtinEffects.begin(); iterator != end; ++iterator) - m_effectReferences.add(iterator->value, FilterEffectSet()); + for (auto& effect : m_builtinEffects.values()) + m_effectReferences.add(effect, FilterEffectSet()); } HashMap<AtomicString, RefPtr<FilterEffect>> m_builtinEffects; @@ -79,6 +74,3 @@ private: }; } // namespace WebCore - -#endif // ENABLE(SVG) && ENABLE(FILTERS) -#endif // SVGFilterBuilder_h |