Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(203)

Side by Side Diff: Source/WebCore/svg/graphics/SVGImage.cpp

Issue 12319101: Merge 142765 (Closed) Base URL: http://svn.webkit.org/repository/webkit/branches/chromium/1410/
Patch Set: Created 7 years, 10 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « Source/WebCore/svg/graphics/SVGImage.h ('k') | Source/WebCore/svg/graphics/SVGImageCache.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 /* 1 /*
2 * Copyright (C) 2006 Eric Seidel <eric@webkit.org> 2 * Copyright (C) 2006 Eric Seidel <eric@webkit.org>
3 * Copyright (C) 2008, 2009 Apple Inc. All rights reserved. 3 * Copyright (C) 2008, 2009 Apple Inc. All rights reserved.
4 * Copyright (C) Research In Motion Limited 2011. All rights reserved. 4 * Copyright (C) Research In Motion Limited 2011. All rights reserved.
5 * 5 *
6 * Redistribution and use in source and binary forms, with or without 6 * Redistribution and use in source and binary forms, with or without
7 * modification, are permitted provided that the following conditions 7 * modification, are permitted provided that the following conditions
8 * are met: 8 * are met:
9 * 1. Redistributions of source code must retain the above copyright 9 * 1. Redistributions of source code must retain the above copyright
10 * notice, this list of conditions and the following disclaimer. 10 * notice, this list of conditions and the following disclaimer.
(...skipping 16 matching lines...) Expand all
27 27
28 #include "config.h" 28 #include "config.h"
29 29
30 #if ENABLE(SVG) 30 #if ENABLE(SVG)
31 #include "SVGImage.h" 31 #include "SVGImage.h"
32 32
33 #include "DocumentLoader.h" 33 #include "DocumentLoader.h"
34 #include "FrameView.h" 34 #include "FrameView.h"
35 #include "ImageBuffer.h" 35 #include "ImageBuffer.h"
36 #include "ImageObserver.h" 36 #include "ImageObserver.h"
37 #include "IntRect.h"
37 #include "RenderSVGRoot.h" 38 #include "RenderSVGRoot.h"
38 #include "SVGDocument.h" 39 #include "SVGDocument.h"
39 #include "SVGImageChromeClient.h" 40 #include "SVGImageChromeClient.h"
40 #include "SVGSVGElement.h" 41 #include "SVGSVGElement.h"
41 #include "Settings.h" 42 #include "Settings.h"
42 43
43 namespace WebCore { 44 namespace WebCore {
44 45
45 SVGImage::SVGImage(ImageObserver* observer) 46 SVGImage::SVGImage(ImageObserver* observer)
46 : Image(observer) 47 : Image(observer)
47 { 48 {
48 } 49 }
49 50
50 SVGImage::~SVGImage() 51 SVGImage::~SVGImage()
51 { 52 {
52 if (m_page) { 53 if (m_page) {
53 // Store m_page in a local variable, clearing m_page, so that SVGImageCh romeClient knows we're destructed. 54 // Store m_page in a local variable, clearing m_page, so that SVGImageCh romeClient knows we're destructed.
54 OwnPtr<Page> currentPage = m_page.release(); 55 OwnPtr<Page> currentPage = m_page.release();
55 currentPage->mainFrame()->loader()->frameDetached(); // Break both the l oader and view references to the frame 56 currentPage->mainFrame()->loader()->frameDetached(); // Break both the l oader and view references to the frame
56 } 57 }
57 58
58 // Verify that page teardown destroyed the Chrome 59 // Verify that page teardown destroyed the Chrome
59 ASSERT(!m_chromeClient || !m_chromeClient->image()); 60 ASSERT(!m_chromeClient || !m_chromeClient->image());
60 } 61 }
61 62
62 void SVGImage::setContainerSize(const IntSize&) 63 void SVGImage::setContainerSize(const IntSize& size)
63 { 64 {
64 // SVGImageCache already intercepted this call, as it stores & caches the de sired container sizes & zoom levels. 65 if (!m_page || !usesContainerSize())
65 ASSERT_NOT_REACHED(); 66 return;
67
68 Frame* frame = m_page->mainFrame();
69 SVGSVGElement* rootElement = static_cast<SVGDocument*>(frame->document())->r ootElement();
70 if (!rootElement)
71 return;
72 RenderSVGRoot* renderer = toRenderSVGRoot(rootElement->renderer());
73 if (!renderer)
74 return;
75
76 FrameView* view = frameView();
77 view->resize(this->size());
78
79 renderer->setContainerSize(size);
66 } 80 }
67 81
68 IntSize SVGImage::size() const 82 IntSize SVGImage::size() const
69 { 83 {
70 if (!m_page) 84 if (!m_page)
71 return IntSize(); 85 return IntSize();
72 Frame* frame = m_page->mainFrame(); 86 Frame* frame = m_page->mainFrame();
73 SVGSVGElement* rootElement = static_cast<SVGDocument*>(frame->document())->r ootElement(); 87 SVGSVGElement* rootElement = static_cast<SVGDocument*>(frame->document())->r ootElement();
74 if (!rootElement) 88 if (!rootElement)
75 return IntSize(); 89 return IntSize();
(...skipping 16 matching lines...) Expand all
92 else 106 else
93 currentSize = rootElement->currentViewBoxRect().size(); 107 currentSize = rootElement->currentViewBoxRect().size();
94 108
95 if (!currentSize.isEmpty()) 109 if (!currentSize.isEmpty())
96 return IntSize(static_cast<int>(ceilf(currentSize.width())), static_cast <int>(ceilf(currentSize.height()))); 110 return IntSize(static_cast<int>(ceilf(currentSize.width())), static_cast <int>(ceilf(currentSize.height())));
97 111
98 // As last resort, use CSS default intrinsic size. 112 // As last resort, use CSS default intrinsic size.
99 return IntSize(300, 150); 113 return IntSize(300, 150);
100 } 114 }
101 115
102 void SVGImage::drawSVGToImageBuffer(ImageBuffer* buffer, const FloatSize& size, float zoomAndScale, ShouldClearBuffer shouldClear) 116 void SVGImage::drawForContainer(GraphicsContext* context, const FloatSize contai nerSize, float zoom, const FloatRect& dstRect,
117 const FloatRect& srcRect, ColorSpace colorSpace, CompositeOperator composite Op, BlendMode blendMode)
103 { 118 {
104 // FIXME: This doesn't work correctly with animations. If an image contains animations, that say run for 2 seconds,
105 // and we currently have one <img> that displays us. If we open another docu ment referencing the same SVGImage it
106 // will display the document at a time where animations already ran - even t hough it has its own ImageBuffer.
107 // We currently don't implement SVGSVGElement::setCurrentTime, and can NOT g o back in time, once animations started.
108 // There's no way to fix this besides avoiding style/attribute mutations fro m SVGAnimationElement.
109 ASSERT(buffer);
110 ASSERT(!size.isEmpty());
111
112 if (!m_page) 119 if (!m_page)
113 return; 120 return;
114 121
115 Frame* frame = m_page->mainFrame();
116 SVGSVGElement* rootElement = static_cast<SVGDocument*>(frame->document())->r ootElement();
117 if (!rootElement)
118 return;
119 RenderSVGRoot* renderer = toRenderSVGRoot(rootElement->renderer());
120 if (!renderer)
121 return;
122
123 // Draw image at requested size.
124 ImageObserver* observer = imageObserver(); 122 ImageObserver* observer = imageObserver();
125 ASSERT(observer); 123 ASSERT(observer);
126 124
127 // Temporarily reset image observer, we don't want to receive any changeInRe ct() calls due to this relayout. 125 // Temporarily reset image observer, we don't want to receive any changeInRe ct() calls due to this relayout.
128 setImageObserver(0); 126 setImageObserver(0);
129 127
130 // Disable repainting; we don't want deferred repaints to schedule any timer s due to this relayout. 128 IntSize roundedContainerSize = roundedIntSize(containerSize);
131 frame->view()->beginDisableRepaints(); 129 setContainerSize(roundedContainerSize);
132 130
133 IntSize containerSize = roundedIntSize(size); 131 FloatRect scaledSrc = srcRect;
134 renderer->setContainerSize(containerSize); 132 scaledSrc.scale(1 / zoom);
135 frame->view()->resize(this->size());
136 133
137 FloatSize scaledContainerSize(size); 134 // Compensate for the container size rounding by adjusting the source rect.
138 scaledContainerSize.scale(zoomAndScale); 135 FloatSize adjustedSrcSize = scaledSrc.size();
139 IntRect destRect = IntRect(IntPoint(), expandedIntSize(scaledContainerSize)) ; 136 adjustedSrcSize.scale(roundedContainerSize.width() / containerSize.width(), roundedContainerSize.height() / containerSize.height());
140 if (shouldClear == ClearImageBuffer) 137 scaledSrc.setSize(adjustedSrcSize);
141 buffer->context()->clearRect(destRect);
142 138
143 // Draw SVG on top of ImageBuffer. 139 draw(context, dstRect, scaledSrc, colorSpace, compositeOp, blendMode);
144 draw(buffer->context(), destRect, IntRect(IntPoint(), containerSize), ColorS paceDeviceRGB, CompositeSourceOver, BlendModeNormal);
145
146 if (frame->view()->needsLayout())
147 frame->view()->layout();
148 140
149 setImageObserver(observer); 141 setImageObserver(observer);
142 }
150 143
151 frame->view()->endDisableRepaints(); 144 void SVGImage::drawPatternForContainer(GraphicsContext* context, const FloatSize containerSize, float pageScale, float zoom, const FloatRect& srcRect,
145 const AffineTransform& patternTransform, const FloatPoint& phase, ColorSpace colorSpace, CompositeOperator compositeOp, const FloatRect& dstRect)
146 {
147 FloatSize zoomedContainerSize(containerSize);
148 zoomedContainerSize.scale(zoom);
149 FloatRect zoomedContainerRect = FloatRect(FloatPoint(), zoomedContainerSize) ;
150
151 OwnPtr<ImageBuffer> buffer = ImageBuffer::create(expandedIntSize(zoomedConta inerSize), pageScale);
152 drawForContainer(buffer->context(), containerSize, zoom, zoomedContainerRect , zoomedContainerRect, ColorSpaceDeviceRGB, CompositeSourceOver, BlendModeNormal );
153
154 RefPtr<Image> image = buffer->copyImage(CopyBackingStore);
155 image->drawPattern(context, srcRect, patternTransform, phase, colorSpace, co mpositeOp, dstRect);
152 } 156 }
153 157
154 void SVGImage::draw(GraphicsContext* context, const FloatRect& dstRect, const Fl oatRect& srcRect, ColorSpace, CompositeOperator compositeOp, BlendMode) 158 void SVGImage::draw(GraphicsContext* context, const FloatRect& dstRect, const Fl oatRect& srcRect, ColorSpace, CompositeOperator compositeOp, BlendMode)
155 { 159 {
156 if (!m_page) 160 if (!m_page)
157 return; 161 return;
158 162
159 FrameView* view = frameView(); 163 FrameView* view = frameView();
160 164
161 GraphicsContextStateSaver stateSaver(*context); 165 GraphicsContextStateSaver stateSaver(*context);
(...skipping 81 matching lines...) Expand 10 before | Expand all | Expand 10 after
243 intrinsicWidth = rootElement->intrinsicWidth(); 247 intrinsicWidth = rootElement->intrinsicWidth();
244 intrinsicHeight = rootElement->intrinsicHeight(); 248 intrinsicHeight = rootElement->intrinsicHeight();
245 if (rootElement->preserveAspectRatio().align() == SVGPreserveAspectRatio::SV G_PRESERVEASPECTRATIO_NONE) 249 if (rootElement->preserveAspectRatio().align() == SVGPreserveAspectRatio::SV G_PRESERVEASPECTRATIO_NONE)
246 return; 250 return;
247 251
248 intrinsicRatio = rootElement->viewBox().size(); 252 intrinsicRatio = rootElement->viewBox().size();
249 if (intrinsicRatio.isEmpty() && intrinsicWidth.isFixed() && intrinsicHeight. isFixed()) 253 if (intrinsicRatio.isEmpty() && intrinsicWidth.isFixed() && intrinsicHeight. isFixed())
250 intrinsicRatio = FloatSize(floatValueForLength(intrinsicWidth, 0), float ValueForLength(intrinsicHeight, 0)); 254 intrinsicRatio = FloatSize(floatValueForLength(intrinsicWidth, 0), float ValueForLength(intrinsicHeight, 0));
251 } 255 }
252 256
253 NativeImagePtr SVGImage::nativeImageForCurrentFrame() 257 // FIXME: support catchUpIfNecessary.
258 void SVGImage::startAnimation(bool /* catchUpIfNecessary */)
254 { 259 {
255 // FIXME: In order to support dynamic SVGs we need to have a way to invalida te this 260 if (!m_page)
256 // frame cache, or better yet, not use a cache for tiled drawing at all, ins tead 261 return;
257 // having a tiled drawing callback (hopefully non-virtual). 262 Frame* frame = m_page->mainFrame();
258 if (!m_frameCache) { 263 SVGSVGElement* rootElement = static_cast<SVGDocument*>(frame->document())->r ootElement();
259 if (!m_page) 264 if (!rootElement)
260 return 0; 265 return;
261 OwnPtr<ImageBuffer> buffer = ImageBuffer::create(size(), 1); 266 rootElement->unpauseAnimations();
262 if (!buffer) // failed to allocate image 267 rootElement->setCurrentTime(0);
263 return 0; 268 }
264 draw(buffer->context(), rect(), rect(), ColorSpaceDeviceRGB, CompositeSo urceOver, BlendModeNormal); 269
265 m_frameCache = buffer->copyImage(CopyBackingStore); 270 void SVGImage::stopAnimation()
266 } 271 {
267 return m_frameCache->nativeImageForCurrentFrame(); 272 if (!m_page)
273 return;
274 Frame* frame = m_page->mainFrame();
275 SVGSVGElement* rootElement = static_cast<SVGDocument*>(frame->document())->r ootElement();
276 if (!rootElement)
277 return;
278 rootElement->pauseAnimations();
279 }
280
281 void SVGImage::resetAnimation()
282 {
283 stopAnimation();
284 startAnimation();
268 } 285 }
269 286
270 bool SVGImage::dataChanged(bool allDataReceived) 287 bool SVGImage::dataChanged(bool allDataReceived)
271 { 288 {
272 // Don't do anything if is an empty image. 289 // Don't do anything if is an empty image.
273 if (!data()->size()) 290 if (!data()->size())
274 return true; 291 return true;
275 292
276 if (allDataReceived) { 293 if (allDataReceived) {
277 static FrameLoaderClient* dummyFrameLoaderClient = new EmptyFrameLoader Client; 294 static FrameLoaderClient* dummyFrameLoaderClient = new EmptyFrameLoader Client;
(...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after
315 { 332 {
316 return "svg"; 333 return "svg";
317 } 334 }
318 335
319 void SVGImage::reportMemoryUsage(MemoryObjectInfo* memoryObjectInfo) const 336 void SVGImage::reportMemoryUsage(MemoryObjectInfo* memoryObjectInfo) const
320 { 337 {
321 MemoryClassInfo info(memoryObjectInfo, this, WebCoreMemoryTypes::CachedResou rceImage); 338 MemoryClassInfo info(memoryObjectInfo, this, WebCoreMemoryTypes::CachedResou rceImage);
322 Image::reportMemoryUsage(memoryObjectInfo); 339 Image::reportMemoryUsage(memoryObjectInfo);
323 info.addMember(m_chromeClient, "chromeClient"); 340 info.addMember(m_chromeClient, "chromeClient");
324 info.addMember(m_page, "page"); 341 info.addMember(m_page, "page");
325 info.addMember(m_frameCache, "frameCache");
326 } 342 }
327 343
328 } 344 }
329 345
330 #endif // ENABLE(SVG) 346 #endif // ENABLE(SVG)
OLDNEW
« no previous file with comments | « Source/WebCore/svg/graphics/SVGImage.h ('k') | Source/WebCore/svg/graphics/SVGImageCache.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698