Respect SVG fragment identifiers in <img> src attribute
[WebKit-https.git] / Source / WebCore / svg / graphics / SVGImageCache.cpp
1 /*
2  * Copyright (C) 2011 Research In Motion Limited. All rights reserved.
3  * Copyright (C) 2013 Apple Inc. All rights reserved.
4  *
5  * This library is free software; you can redistribute it and/or
6  * modify it under the terms of the GNU Library General Public
7  * License as published by the Free Software Foundation; either
8  * version 2 of the License, or (at your option) any later version.
9  *
10  * This library is distributed in the hope that it will be useful,
11  * but WITHOUT ANY WARRANTY; without even the implied warranty of
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
13  * Library General Public License for more details.
14  *
15  * You should have received a copy of the GNU Library General Public License
16  * along with this library; see the file COPYING.LIB.  If not, write to
17  * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
18  * Boston, MA 02110-1301, USA.
19  */
20
21 #include "config.h"
22 #include "SVGImageCache.h"
23
24 #include "FrameView.h"
25 #include "GraphicsContext.h"
26 #include "HTMLImageElement.h"
27 #include "ImageBuffer.h"
28 #include "Page.h"
29 #include "RenderSVGRoot.h"
30 #include "SVGImage.h"
31 #include "SVGImageForContainer.h"
32
33 namespace WebCore {
34
35 SVGImageCache::SVGImageCache(SVGImage* svgImage)
36     : m_svgImage(svgImage)
37 {
38     ASSERT(m_svgImage);
39 }
40
41 SVGImageCache::~SVGImageCache()
42 {
43     m_imageForContainerMap.clear();
44 }
45
46 void SVGImageCache::removeClientFromCache(const CachedImageClient* client)
47 {
48     ASSERT(client);
49
50     m_imageForContainerMap.remove(client);
51 }
52
53 void SVGImageCache::setContainerSizeForRenderer(const CachedImageClient* client, const IntSize& containerSize, float containerZoom)
54 {
55     ASSERT(client);
56     ASSERT(!containerSize.isEmpty());
57     ASSERT(containerZoom);
58
59     FloatSize containerSizeWithoutZoom(containerSize);
60     containerSizeWithoutZoom.scale(1 / containerZoom);
61
62     m_imageForContainerMap.set(client, SVGImageForContainer::create(m_svgImage, containerSizeWithoutZoom, containerZoom));
63 }
64
65 IntSize SVGImageCache::imageSizeForRenderer(const RenderObject* renderer) const
66 {
67     IntSize imageSize = m_svgImage->size();
68     if (!renderer)
69         return imageSize;
70
71     ImageForContainerMap::const_iterator it = m_imageForContainerMap.find(renderer);
72     if (it == m_imageForContainerMap.end())
73         return imageSize;
74
75     RefPtr<SVGImageForContainer> imageForContainer = it->value;
76     ASSERT(!imageForContainer->size().isEmpty());
77     return imageForContainer->size();
78 }
79
80 // FIXME: This doesn't take into account the animation timeline so animations will not
81 // restart on page load, nor will two animations in different pages have different timelines.
82 Image* SVGImageCache::imageForRenderer(const RenderObject* renderer)
83 {
84     if (!renderer)
85         return Image::nullImage();
86
87     ImageForContainerMap::iterator it = m_imageForContainerMap.find(renderer);
88     if (it == m_imageForContainerMap.end())
89         return Image::nullImage();
90
91     RefPtr<SVGImageForContainer> imageForContainer = it->value;
92     
93     Node* node = renderer->node();
94     if (node && isHTMLImageElement(node)) {
95         const AtomicString& urlString = toHTMLImageElement(node)->imageSourceURL();
96         URL url = node->document().completeURL(urlString);
97         imageForContainer->setURL(url);
98     }
99         
100     ASSERT(!imageForContainer->size().isEmpty());
101     return imageForContainer.get();
102 }
103
104 } // namespace WebCore