15c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)/* 25c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * Copyright (C) 2006 Eric Seidel <eric@webkit.org> 35c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * Copyright (C) 2008, 2009 Apple Inc. All rights reserved. 45c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * Copyright (C) Research In Motion Limited 2011. All rights reserved. 55c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * 65c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * Redistribution and use in source and binary forms, with or without 75c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * modification, are permitted provided that the following conditions 85c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * are met: 95c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * 1. Redistributions of source code must retain the above copyright 105c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * notice, this list of conditions and the following disclaimer. 115c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * 2. Redistributions in binary form must reproduce the above copyright 125c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * notice, this list of conditions and the following disclaimer in the 135c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * documentation and/or other materials provided with the distribution. 145c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * 155c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY 165c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 175c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 185c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR 195c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 205c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 215c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR 225c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY 235c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 245c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 2502772c6a72f1ee0b226341a4f4439970c29fc861Ben Murdoch * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 265c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) */ 275c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 285c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)#include "config.h" 295c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 3053e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)#include "core/svg/graphics/SVGImage.h" 3153e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles) 32d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles)#include "core/animation/AnimationTimeline.h" 33e1f1df5f01594c0e62e751e4b46e779b85c2faa5Torne (Richard Coles)#include "core/dom/NodeTraversal.h" 34c0e19a689c8ac22cdc96b291a8d33a5d3b0b34a4Torne (Richard Coles)#include "core/dom/shadow/ComposedTreeWalker.h" 351e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)#include "core/frame/FrameView.h" 36d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)#include "core/frame/LocalFrame.h" 3709380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)#include "core/frame/Settings.h" 38d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)#include "core/loader/FrameLoadRequest.h" 39d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)#include "core/page/Chrome.h" 4053e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)#include "core/rendering/style/RenderStyle.h" 4153e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)#include "core/rendering/svg/RenderSVGRoot.h" 42323480423219ecd77329f8326dc5e0e3b50926d4Torne (Richard Coles)#include "core/svg/SVGDocumentExtensions.h" 438abfc5808a4e34d6e03867af8bc440dee641886fTorne (Richard Coles)#include "core/svg/SVGFEImageElement.h" 44e1f1df5f01594c0e62e751e4b46e779b85c2faa5Torne (Richard Coles)#include "core/svg/SVGImageElement.h" 4553e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)#include "core/svg/SVGSVGElement.h" 46d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)#include "core/svg/animation/SMILTimeContainer.h" 4753e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)#include "core/svg/graphics/SVGImageChromeClient.h" 48e38fbeeb576b5094e34e038ab88d9d6a5c5c2214Torne (Richard Coles)#include "platform/EventDispatchForbiddenScope.h" 49bfe3590b1806e3ff18f46ee3af5d4b83078f305aTorne (Richard Coles)#include "platform/LengthFunctions.h" 505d92fedcae5e801a8b224de090094f2d9df0b54aTorne (Richard Coles)#include "platform/TraceEvent.h" 511e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)#include "platform/geometry/IntRect.h" 52a854de003a23bf3c7f95ec0f8154ada64092ff5cTorne (Richard Coles)#include "platform/graphics/GraphicsContextStateSaver.h" 53a854de003a23bf3c7f95ec0f8154ada64092ff5cTorne (Richard Coles)#include "platform/graphics/ImageBuffer.h" 5451b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)#include "platform/graphics/ImageObserver.h" 55591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch#include "wtf/PassRefPtr.h" 565c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 57c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)namespace blink { 585c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 595c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)SVGImage::SVGImage(ImageObserver* observer) 605c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) : Image(observer) 615c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){ 625c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} 635c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 645c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)SVGImage::~SVGImage() 655c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){ 665c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (m_page) { 675c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) // Store m_page in a local variable, clearing m_page, so that SVGImageChromeClient knows we're destructed. 686f543c786fc42989f552b4daa774ca5ff32fa697Ben Murdoch OwnPtrWillBeRawPtr<Page> currentPage = m_page.release(); 695d92fedcae5e801a8b224de090094f2d9df0b54aTorne (Richard Coles) // Break both the loader and view references to the frame 706f543c786fc42989f552b4daa774ca5ff32fa697Ben Murdoch currentPage->willBeDestroyed(); 715c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 725c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 735c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) // Verify that page teardown destroyed the Chrome 745c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) ASSERT(!m_chromeClient || !m_chromeClient->image()); 755c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} 765c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 77f91f5fa1608c2cdd9af1842fb5dadbe78275be2aBo Liubool SVGImage::isInSVGImage(const Node* node) 78e1f1df5f01594c0e62e751e4b46e779b85c2faa5Torne (Richard Coles){ 79f91f5fa1608c2cdd9af1842fb5dadbe78275be2aBo Liu ASSERT(node); 80e1f1df5f01594c0e62e751e4b46e779b85c2faa5Torne (Richard Coles) 81f91f5fa1608c2cdd9af1842fb5dadbe78275be2aBo Liu Page* page = node->document().page(); 82e1f1df5f01594c0e62e751e4b46e779b85c2faa5Torne (Richard Coles) if (!page) 83e1f1df5f01594c0e62e751e4b46e779b85c2faa5Torne (Richard Coles) return false; 84e1f1df5f01594c0e62e751e4b46e779b85c2faa5Torne (Richard Coles) 85e1f1df5f01594c0e62e751e4b46e779b85c2faa5Torne (Richard Coles) return page->chrome().client().isSVGImageChromeClient(); 86e1f1df5f01594c0e62e751e4b46e779b85c2faa5Torne (Richard Coles)} 87e1f1df5f01594c0e62e751e4b46e779b85c2faa5Torne (Richard Coles) 888abfc5808a4e34d6e03867af8bc440dee641886fTorne (Richard Coles)bool SVGImage::currentFrameHasSingleSecurityOrigin() const 89e1f1df5f01594c0e62e751e4b46e779b85c2faa5Torne (Richard Coles){ 90e1f1df5f01594c0e62e751e4b46e779b85c2faa5Torne (Richard Coles) if (!m_page) 91e1f1df5f01594c0e62e751e4b46e779b85c2faa5Torne (Richard Coles) return true; 92e1f1df5f01594c0e62e751e4b46e779b85c2faa5Torne (Richard Coles) 935d92fedcae5e801a8b224de090094f2d9df0b54aTorne (Richard Coles) LocalFrame* frame = toLocalFrame(m_page->mainFrame()); 948abfc5808a4e34d6e03867af8bc440dee641886fTorne (Richard Coles) 958abfc5808a4e34d6e03867af8bc440dee641886fTorne (Richard Coles) RELEASE_ASSERT(frame->document()->loadEventFinished()); 968abfc5808a4e34d6e03867af8bc440dee641886fTorne (Richard Coles) 97323480423219ecd77329f8326dc5e0e3b50926d4Torne (Richard Coles) SVGSVGElement* rootElement = frame->document()->accessSVGExtensions().rootElement(); 98e1f1df5f01594c0e62e751e4b46e779b85c2faa5Torne (Richard Coles) if (!rootElement) 99e1f1df5f01594c0e62e751e4b46e779b85c2faa5Torne (Richard Coles) return true; 100e1f1df5f01594c0e62e751e4b46e779b85c2faa5Torne (Richard Coles) 101e1f1df5f01594c0e62e751e4b46e779b85c2faa5Torne (Richard Coles) // Don't allow foreignObject elements or images that are not known to be 102e1f1df5f01594c0e62e751e4b46e779b85c2faa5Torne (Richard Coles) // single-origin since these can leak cross-origin information. 103c0e19a689c8ac22cdc96b291a8d33a5d3b0b34a4Torne (Richard Coles) ComposedTreeWalker walker(rootElement); 104e1f1df5f01594c0e62e751e4b46e779b85c2faa5Torne (Richard Coles) while (Node* node = walker.get()) { 105d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles) if (isSVGForeignObjectElement(*node)) 106e1f1df5f01594c0e62e751e4b46e779b85c2faa5Torne (Richard Coles) return false; 107d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles) if (isSVGImageElement(*node)) { 108d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles) if (!toSVGImageElement(*node).currentFrameHasSingleSecurityOrigin()) 10909380295ba73501a205346becac22c6978e4671dTorne (Richard Coles) return false; 110d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles) } else if (isSVGFEImageElement(*node)) { 111d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles) if (!toSVGFEImageElement(*node).currentFrameHasSingleSecurityOrigin()) 11209380295ba73501a205346becac22c6978e4671dTorne (Richard Coles) return false; 11309380295ba73501a205346becac22c6978e4671dTorne (Richard Coles) } 114e1f1df5f01594c0e62e751e4b46e779b85c2faa5Torne (Richard Coles) walker.next(); 115e1f1df5f01594c0e62e751e4b46e779b85c2faa5Torne (Richard Coles) } 116e1f1df5f01594c0e62e751e4b46e779b85c2faa5Torne (Richard Coles) 117e1f1df5f01594c0e62e751e4b46e779b85c2faa5Torne (Richard Coles) // Because SVG image rendering disallows external resources and links, these 118e1f1df5f01594c0e62e751e4b46e779b85c2faa5Torne (Richard Coles) // images effectively are restricted to a single security origin. 119e1f1df5f01594c0e62e751e4b46e779b85c2faa5Torne (Richard Coles) return true; 120e1f1df5f01594c0e62e751e4b46e779b85c2faa5Torne (Richard Coles)} 121e1f1df5f01594c0e62e751e4b46e779b85c2faa5Torne (Richard Coles) 12207a852d8c1953036774d8f3b65d18dcfea3bb4a2Ben Murdochstatic SVGSVGElement* svgRootElement(Page* page) 12307a852d8c1953036774d8f3b65d18dcfea3bb4a2Ben Murdoch{ 12407a852d8c1953036774d8f3b65d18dcfea3bb4a2Ben Murdoch if (!page) 12507a852d8c1953036774d8f3b65d18dcfea3bb4a2Ben Murdoch return 0; 1265d92fedcae5e801a8b224de090094f2d9df0b54aTorne (Richard Coles) LocalFrame* frame = toLocalFrame(page->mainFrame()); 127323480423219ecd77329f8326dc5e0e3b50926d4Torne (Richard Coles) return frame->document()->accessSVGExtensions().rootElement(); 12807a852d8c1953036774d8f3b65d18dcfea3bb4a2Ben Murdoch} 12907a852d8c1953036774d8f3b65d18dcfea3bb4a2Ben Murdoch 130926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)void SVGImage::setContainerSize(const IntSize& size) 1315c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){ 13207a852d8c1953036774d8f3b65d18dcfea3bb4a2Ben Murdoch if (!usesContainerSize()) 133926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) return; 134926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) 13507a852d8c1953036774d8f3b65d18dcfea3bb4a2Ben Murdoch SVGSVGElement* rootElement = svgRootElement(m_page.get()); 136926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) if (!rootElement) 137926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) return; 138926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) 139926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) FrameView* view = frameView(); 140926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) view->resize(this->containerSize()); 141926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) 142d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles) RenderSVGRoot* renderer = toRenderSVGRoot(rootElement->renderer()); 143d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles) if (!renderer) 144d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles) return; 145926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) renderer->setContainerSize(size); 1465c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} 1475c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 148926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)IntSize SVGImage::containerSize() const 1495c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){ 15007a852d8c1953036774d8f3b65d18dcfea3bb4a2Ben Murdoch SVGSVGElement* rootElement = svgRootElement(m_page.get()); 1515c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (!rootElement) 1525c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return IntSize(); 1535c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 1545c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) RenderSVGRoot* renderer = toRenderSVGRoot(rootElement->renderer()); 1555c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (!renderer) 1565c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return IntSize(); 1575c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 1585c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) // If a container size is available it has precedence. 1595c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) IntSize containerSize = renderer->containerSize(); 1605c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (!containerSize.isEmpty()) 1615c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return containerSize; 1625c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 1635c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) // Assure that a container size is always given for a non-identity zoom level. 1645c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) ASSERT(renderer->style()->effectiveZoom() == 1); 1655c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 1665d92fedcae5e801a8b224de090094f2d9df0b54aTorne (Richard Coles) FloatSize intrinsicSize; 1675d92fedcae5e801a8b224de090094f2d9df0b54aTorne (Richard Coles) double intrinsicRatio = 0; 1685d92fedcae5e801a8b224de090094f2d9df0b54aTorne (Richard Coles) renderer->computeIntrinsicRatioInformation(intrinsicSize, intrinsicRatio); 1695c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 1705d92fedcae5e801a8b224de090094f2d9df0b54aTorne (Richard Coles) if (intrinsicSize.isEmpty() && intrinsicRatio) { 1715d92fedcae5e801a8b224de090094f2d9df0b54aTorne (Richard Coles) if (!intrinsicSize.width() && intrinsicSize.height()) 1725d92fedcae5e801a8b224de090094f2d9df0b54aTorne (Richard Coles) intrinsicSize.setWidth(intrinsicSize.height() * intrinsicRatio); 1735d92fedcae5e801a8b224de090094f2d9df0b54aTorne (Richard Coles) else if (intrinsicSize.width() && !intrinsicSize.height()) 1745d92fedcae5e801a8b224de090094f2d9df0b54aTorne (Richard Coles) intrinsicSize.setHeight(intrinsicSize.width() / intrinsicRatio); 1755d92fedcae5e801a8b224de090094f2d9df0b54aTorne (Richard Coles) } 1765d92fedcae5e801a8b224de090094f2d9df0b54aTorne (Richard Coles) 1775d92fedcae5e801a8b224de090094f2d9df0b54aTorne (Richard Coles) if (!intrinsicSize.isEmpty()) 1785d92fedcae5e801a8b224de090094f2d9df0b54aTorne (Richard Coles) return expandedIntSize(intrinsicSize); 1795c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 1805d92fedcae5e801a8b224de090094f2d9df0b54aTorne (Richard Coles) // As last resort, use CSS replaced element fallback size. 1815c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return IntSize(300, 150); 1825c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} 1835c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 184926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)void SVGImage::drawForContainer(GraphicsContext* context, const FloatSize containerSize, float zoom, const FloatRect& dstRect, 185a854de003a23bf3c7f95ec0f8154ada64092ff5cTorne (Richard Coles) const FloatRect& srcRect, CompositeOperator compositeOp, blink::WebBlendMode blendMode) 1865c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){ 1875c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (!m_page) 1885c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return; 1895c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 1908abfc5808a4e34d6e03867af8bc440dee641886fTorne (Richard Coles) // Temporarily disable the image observer to prevent changeInRect() calls due re-laying out the image. 1918abfc5808a4e34d6e03867af8bc440dee641886fTorne (Richard Coles) ImageObserverDisabler imageObserverDisabler(this); 1925c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 193926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) IntSize roundedContainerSize = roundedIntSize(containerSize); 194926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) setContainerSize(roundedContainerSize); 1955c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 196926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) FloatRect scaledSrc = srcRect; 197926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) scaledSrc.scale(1 / zoom); 1985c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 199926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) // Compensate for the container size rounding by adjusting the source rect. 200926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) FloatSize adjustedSrcSize = scaledSrc.size(); 201926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) adjustedSrcSize.scale(roundedContainerSize.width() / containerSize.width(), roundedContainerSize.height() / containerSize.height()); 202926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) scaledSrc.setSize(adjustedSrcSize); 2035c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 2045267f701546148b83dfbe1d151cb184385bb5c22Torne (Richard Coles) draw(context, dstRect, scaledSrc, compositeOp, blendMode); 205926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)} 2065c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 207591b958dee2cf159d33a0b931e6231072eaf38d5Ben MurdochPassRefPtr<NativeImageSkia> SVGImage::nativeImageForCurrentFrame() 20853e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles){ 20953e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles) if (!m_page) 210d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles) return nullptr; 21153e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles) 212a854de003a23bf3c7f95ec0f8154ada64092ff5cTorne (Richard Coles) OwnPtr<ImageBuffer> buffer = ImageBuffer::create(size()); 213a854de003a23bf3c7f95ec0f8154ada64092ff5cTorne (Richard Coles) if (!buffer) 214d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles) return nullptr; 21553e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles) 216a854de003a23bf3c7f95ec0f8154ada64092ff5cTorne (Richard Coles) drawForContainer(buffer->context(), size(), 1, rect(), rect(), CompositeSourceOver, blink::WebBlendModeNormal); 21753e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles) 21853e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles) // FIXME: WK(Bug 113657): We should use DontCopyBackingStore here. 21953e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles) return buffer->copyImage(CopyBackingStore)->nativeImageForCurrentFrame(); 22053e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)} 22153e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles) 222926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)void SVGImage::drawPatternForContainer(GraphicsContext* context, const FloatSize containerSize, float zoom, const FloatRect& srcRect, 223a854de003a23bf3c7f95ec0f8154ada64092ff5cTorne (Richard Coles) const FloatSize& scale, const FloatPoint& phase, CompositeOperator compositeOp, const FloatRect& dstRect, blink::WebBlendMode blendMode, const IntSize& repeatSpacing) 224926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles){ 225926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) FloatRect zoomedContainerRect = FloatRect(FloatPoint(), containerSize); 226926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) zoomedContainerRect.scale(zoom); 2275c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 228926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) // The ImageBuffer size needs to be scaled to match the final resolution. 229521d96ec04ace82590870fb04353ec4f82bb150fTorne (Richard Coles) // FIXME: No need to get the full CTM here, we just need the scale. 2305d92fedcae5e801a8b224de090094f2d9df0b54aTorne (Richard Coles) // FIXME: See crbug.com/382491. This scale does not reflect compositor applied 2315d92fedcae5e801a8b224de090094f2d9df0b54aTorne (Richard Coles) // scale factors, such a High DPI or device zoom. 232926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) AffineTransform transform = context->getCTM(); 233926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) FloatSize imageBufferScale = FloatSize(transform.xScale(), transform.yScale()); 234926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) ASSERT(imageBufferScale.width()); 235926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) ASSERT(imageBufferScale.height()); 2365c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 237521d96ec04ace82590870fb04353ec4f82bb150fTorne (Richard Coles) FloatSize scaleWithoutCTM(scale.width() / imageBufferScale.width(), scale.height() / imageBufferScale.height()); 238521d96ec04ace82590870fb04353ec4f82bb150fTorne (Richard Coles) 239926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) FloatRect imageBufferSize = zoomedContainerRect; 240926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) imageBufferSize.scale(imageBufferScale.width(), imageBufferScale.height()); 2415c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 242a854de003a23bf3c7f95ec0f8154ada64092ff5cTorne (Richard Coles) OwnPtr<ImageBuffer> buffer = ImageBuffer::create(expandedIntSize(imageBufferSize.size())); 243521d96ec04ace82590870fb04353ec4f82bb150fTorne (Richard Coles) if (!buffer) // Failed to allocate buffer. 244521d96ec04ace82590870fb04353ec4f82bb150fTorne (Richard Coles) return; 245a854de003a23bf3c7f95ec0f8154ada64092ff5cTorne (Richard Coles) 246a854de003a23bf3c7f95ec0f8154ada64092ff5cTorne (Richard Coles) drawForContainer(buffer->context(), containerSize, zoom, imageBufferSize, zoomedContainerRect, CompositeSourceOver, blink::WebBlendModeNormal); 247926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) RefPtr<Image> image = buffer->copyImage(DontCopyBackingStore, Unscaled); 2485c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 249926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) // Adjust the source rect and transform due to the image buffer's scaling. 250926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) FloatRect scaledSrcRect = srcRect; 251926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) scaledSrcRect.scale(imageBufferScale.width(), imageBufferScale.height()); 2525c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 2531e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles) image->drawPattern(context, scaledSrcRect, scaleWithoutCTM, phase, compositeOp, dstRect, blendMode, repeatSpacing); 2545c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} 2555c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 256a854de003a23bf3c7f95ec0f8154ada64092ff5cTorne (Richard Coles)void SVGImage::draw(GraphicsContext* context, const FloatRect& dstRect, const FloatRect& srcRect, CompositeOperator compositeOp, blink::WebBlendMode blendMode) 2575c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){ 2585c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (!m_page) 2595c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return; 2605c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 2615c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) GraphicsContextStateSaver stateSaver(*context); 262591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch context->setCompositeOperation(compositeOp, blendMode); 2635c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) context->clip(enclosingIntRect(dstRect)); 26409380295ba73501a205346becac22c6978e4671dTorne (Richard Coles) 26509380295ba73501a205346becac22c6978e4671dTorne (Richard Coles) bool compositingRequiresTransparencyLayer = compositeOp != CompositeSourceOver || blendMode != blink::WebBlendModeNormal; 266d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles) float opacity = context->getNormalizedAlpha() / 255.f; 267d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles) bool requiresTransparencyLayer = compositingRequiresTransparencyLayer || opacity < 1; 268d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles) if (requiresTransparencyLayer) { 269d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles) context->beginTransparencyLayer(opacity); 270d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles) if (compositingRequiresTransparencyLayer) 271d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles) context->setCompositeOperation(CompositeSourceOver, blink::WebBlendModeNormal); 27209380295ba73501a205346becac22c6978e4671dTorne (Richard Coles) } 2735c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 2745c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) FloatSize scale(dstRect.width() / srcRect.width(), dstRect.height() / srcRect.height()); 2755267f701546148b83dfbe1d151cb184385bb5c22Torne (Richard Coles) 2765c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) // We can only draw the entire frame, clipped to the rect we want. So compute where the top left 2775c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) // of the image would be if we were drawing without clipping, and translate accordingly. 2785c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) FloatSize topLeftOffset(srcRect.location().x() * scale.width(), srcRect.location().y() * scale.height()); 2795c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) FloatPoint destOffset = dstRect.location() - topLeftOffset; 2805c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 2815c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) context->translate(destOffset.x(), destOffset.y()); 2825d92fedcae5e801a8b224de090094f2d9df0b54aTorne (Richard Coles) context->scale(scale.width(), scale.height()); 2835c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 2848abfc5808a4e34d6e03867af8bc440dee641886fTorne (Richard Coles) FrameView* view = frameView(); 285926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) view->resize(containerSize()); 2865c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 287323480423219ecd77329f8326dc5e0e3b50926d4Torne (Richard Coles) if (!m_url.isEmpty()) 288323480423219ecd77329f8326dc5e0e3b50926d4Torne (Richard Coles) view->scrollToFragment(m_url); 289323480423219ecd77329f8326dc5e0e3b50926d4Torne (Richard Coles) 290e38fbeeb576b5094e34e038ab88d9d6a5c5c2214Torne (Richard Coles) view->updateLayoutAndStyleForPainting(); 291591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch view->paint(context, enclosingIntRect(srcRect)); 292aafa69cb17c9d6606c07663ade5f81388a2c5986Ben Murdoch ASSERT(!view->needsLayout()); 2935c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 294d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles) if (requiresTransparencyLayer) 295c0e19a689c8ac22cdc96b291a8d33a5d3b0b34a4Torne (Richard Coles) context->endLayer(); 2965c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 2975c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) stateSaver.restore(); 2985c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 2995c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (imageObserver()) 3005c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) imageObserver()->didDraw(this); 30107a852d8c1953036774d8f3b65d18dcfea3bb4a2Ben Murdoch 30207a852d8c1953036774d8f3b65d18dcfea3bb4a2Ben Murdoch // Start any (SMIL) animations if needed. This will restart or continue 30307a852d8c1953036774d8f3b65d18dcfea3bb4a2Ben Murdoch // animations if preceded by calls to resetAnimation or stopAnimation 30407a852d8c1953036774d8f3b65d18dcfea3bb4a2Ben Murdoch // respectively. 30507a852d8c1953036774d8f3b65d18dcfea3bb4a2Ben Murdoch startAnimation(); 3065c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} 3075c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 3085c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)RenderBox* SVGImage::embeddedContentBox() const 3095c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){ 31007a852d8c1953036774d8f3b65d18dcfea3bb4a2Ben Murdoch SVGSVGElement* rootElement = svgRootElement(m_page.get()); 3115c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (!rootElement) 3125c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return 0; 3135c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return toRenderBox(rootElement->renderer()); 3145c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} 3155c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 3165c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)FrameView* SVGImage::frameView() const 3175c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){ 3185c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (!m_page) 3195c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return 0; 3205c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 3215d92fedcae5e801a8b224de090094f2d9df0b54aTorne (Richard Coles) return toLocalFrame(m_page->mainFrame())->view(); 3225c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} 3235c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 3245c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)void SVGImage::computeIntrinsicDimensions(Length& intrinsicWidth, Length& intrinsicHeight, FloatSize& intrinsicRatio) 3255c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){ 32607a852d8c1953036774d8f3b65d18dcfea3bb4a2Ben Murdoch SVGSVGElement* rootElement = svgRootElement(m_page.get()); 3275c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (!rootElement) 3285c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return; 3295c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 3305c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) intrinsicWidth = rootElement->intrinsicWidth(); 3315c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) intrinsicHeight = rootElement->intrinsicHeight(); 33209380295ba73501a205346becac22c6978e4671dTorne (Richard Coles) if (rootElement->preserveAspectRatio()->currentValue()->align() == SVGPreserveAspectRatio::SVG_PRESERVEASPECTRATIO_NONE) 3335c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return; 3345c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 33509380295ba73501a205346becac22c6978e4671dTorne (Richard Coles) intrinsicRatio = rootElement->viewBox()->currentValue()->value().size(); 3365c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (intrinsicRatio.isEmpty() && intrinsicWidth.isFixed() && intrinsicHeight.isFixed()) 3375c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) intrinsicRatio = FloatSize(floatValueForLength(intrinsicWidth, 0), floatValueForLength(intrinsicHeight, 0)); 3385c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} 3395c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 34010f88d5669dbd969c059d61ba09fa37dd72ac559Ben Murdoch// FIXME: support CatchUpAnimation = CatchUp. 34110f88d5669dbd969c059d61ba09fa37dd72ac559Ben Murdochvoid SVGImage::startAnimation(CatchUpAnimation) 3425c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){ 34307a852d8c1953036774d8f3b65d18dcfea3bb4a2Ben Murdoch SVGSVGElement* rootElement = svgRootElement(m_page.get()); 34407a852d8c1953036774d8f3b65d18dcfea3bb4a2Ben Murdoch if (!rootElement || !rootElement->animationsPaused()) 345926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) return; 346926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) rootElement->unpauseAnimations(); 347926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)} 348926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) 349926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)void SVGImage::stopAnimation() 350926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles){ 35107a852d8c1953036774d8f3b65d18dcfea3bb4a2Ben Murdoch SVGSVGElement* rootElement = svgRootElement(m_page.get()); 352926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) if (!rootElement) 353926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) return; 354926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) rootElement->pauseAnimations(); 355926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)} 356926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) 357926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)void SVGImage::resetAnimation() 358926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles){ 35907a852d8c1953036774d8f3b65d18dcfea3bb4a2Ben Murdoch SVGSVGElement* rootElement = svgRootElement(m_page.get()); 36007a852d8c1953036774d8f3b65d18dcfea3bb4a2Ben Murdoch if (!rootElement) 36107a852d8c1953036774d8f3b65d18dcfea3bb4a2Ben Murdoch return; 36207a852d8c1953036774d8f3b65d18dcfea3bb4a2Ben Murdoch rootElement->pauseAnimations(); 36307a852d8c1953036774d8f3b65d18dcfea3bb4a2Ben Murdoch rootElement->setCurrentTime(0); 3645c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} 3655c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 366d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)bool SVGImage::hasAnimations() const 367d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles){ 36807a852d8c1953036774d8f3b65d18dcfea3bb4a2Ben Murdoch SVGSVGElement* rootElement = svgRootElement(m_page.get()); 369d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles) if (!rootElement) 370d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles) return false; 3715d92fedcae5e801a8b224de090094f2d9df0b54aTorne (Richard Coles) return rootElement->timeContainer()->hasAnimations() || toLocalFrame(m_page->mainFrame())->document()->timeline().hasPendingUpdates(); 372d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)} 373d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles) 3745c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)bool SVGImage::dataChanged(bool allDataReceived) 3755c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){ 376197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch TRACE_EVENT0("blink", "SVGImage::dataChanged"); 3771e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles) 3785c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) // Don't do anything if is an empty image. 3795c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (!data()->size()) 3805c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return true; 3815c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 3825c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (allDataReceived) { 383d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles) // SVGImage will fire events (and the default C++ handlers run) but doesn't 384d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles) // actually allow script to run so it's fine to call into it. We allow this 385d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles) // since it means an SVG data url can synchronously load like other image 386d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles) // types. 387e38fbeeb576b5094e34e038ab88d9d6a5c5c2214Torne (Richard Coles) EventDispatchForbiddenScope::AllowUserAgentEvents allowUserAgentEvents; 388d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles) 38909380295ba73501a205346becac22c6978e4671dTorne (Richard Coles) static FrameLoaderClient* dummyFrameLoaderClient = new EmptyFrameLoaderClient; 3905c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 3915c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) Page::PageClients pageClients; 3925c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) fillWithEmptyClients(pageClients); 3935c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) m_chromeClient = adoptPtr(new SVGImageChromeClient(this)); 3945c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) pageClients.chromeClient = m_chromeClient.get(); 3955c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 3965c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) // FIXME: If this SVG ends up loading itself, we might leak the world. 3973c9e4aeaee9f9b0a9a814da07bcb33319c7ea363Ben Murdoch // The Cache code does not know about ImageResources holding Frames and 3985c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) // won't know to break the cycle. 3995c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) // This will become an issue when SVGImage will be able to load other 4005c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) // SVGImage objects, but we're safe now, because SVGImage can only be 4015c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) // loaded by a top-level document. 402197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch OwnPtrWillBeRawPtr<Page> page; 403197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch { 404197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch TRACE_EVENT0("blink", "SVGImage::dataChanged::createPage"); 405197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch page = adoptPtrWillBeNoop(new Page(pageClients)); 406197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch page->settings().setScriptEnabled(false); 407197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch page->settings().setPluginsEnabled(false); 408197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch page->settings().setAcceleratedCompositingEnabled(false); 409197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch } 410197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch 4117242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci RefPtrWillBeRawPtr<LocalFrame> frame = nullptr; 412197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch { 413197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch TRACE_EVENT0("blink", "SVGImage::dataChanged::createFrame"); 414197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch frame = LocalFrame::create(dummyFrameLoaderClient, &page->frameHost(), 0); 415197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch frame->setView(FrameView::create(frame.get())); 416197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch frame->init(); 417197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch } 418197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch 419f79f16f17ddc4f842d7b7a38603e280e94be826aTorne (Richard Coles) FrameLoader& loader = frame->loader(); 420f79f16f17ddc4f842d7b7a38603e280e94be826aTorne (Richard Coles) loader.forceSandboxFlags(SandboxAll); 4215c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 42281a5157921f1d2a7ff6aae115bfe3c139b38a5c8Torne (Richard Coles) frame->view()->setScrollbarsSuppressed(true); 4235c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) frame->view()->setCanHaveScrollbars(false); // SVG Images will always synthesize a viewBox, if it's not available, and thus never see scrollbars. 4245c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) frame->view()->setTransparent(true); // SVG Images are transparent. 4255c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 426d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles) m_page = page.release(); 427d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles) 428197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch TRACE_EVENT0("blink", "SVGImage::dataChanged::load"); 4297242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci loader.load(FrameLoadRequest(0, blankURL(), SubstituteData(data(), AtomicString("image/svg+xml", AtomicString::ConstructFromLiteral), 4307242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci AtomicString("UTF-8", AtomicString::ConstructFromLiteral), KURL(), ForceSynchronousLoad))); 431926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) // Set the intrinsic size before a container size is available. 432926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) m_intrinsicSize = containerSize(); 4335c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 4345c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 4355c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return m_page; 4365c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} 4375c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 4385c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)String SVGImage::filenameExtension() const 4395c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){ 4405c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return "svg"; 4415c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} 4425c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 4435c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} 444