OLD | NEW |
1 /* | 1 /* |
2 Copyright (C) 1998 Lars Knoll (knoll@mpi-hd.mpg.de) | 2 Copyright (C) 1998 Lars Knoll (knoll@mpi-hd.mpg.de) |
3 Copyright (C) 2001 Dirk Mueller (mueller@kde.org) | 3 Copyright (C) 2001 Dirk Mueller (mueller@kde.org) |
4 Copyright (C) 2002 Waldo Bastian (bastian@kde.org) | 4 Copyright (C) 2002 Waldo Bastian (bastian@kde.org) |
5 Copyright (C) 2006 Samuel Weinig (sam.weinig@gmail.com) | 5 Copyright (C) 2006 Samuel Weinig (sam.weinig@gmail.com) |
6 Copyright (C) 2004, 2005, 2006, 2007 Apple Inc. All rights reserved. | 6 Copyright (C) 2004, 2005, 2006, 2007 Apple Inc. All rights reserved. |
7 | 7 |
8 This library is free software; you can redistribute it and/or | 8 This library is free software; you can redistribute it and/or |
9 modify it under the terms of the GNU Library General Public | 9 modify it under the terms of the GNU Library General Public |
10 License as published by the Free Software Foundation; either | 10 License as published by the Free Software Foundation; either |
(...skipping 12 matching lines...) Expand all Loading... |
23 | 23 |
24 #include "config.h" | 24 #include "config.h" |
25 #include "core/fetch/ImageResource.h" | 25 #include "core/fetch/ImageResource.h" |
26 | 26 |
27 #include "core/fetch/ImageResourceClient.h" | 27 #include "core/fetch/ImageResourceClient.h" |
28 #include "core/fetch/MemoryCache.h" | 28 #include "core/fetch/MemoryCache.h" |
29 #include "core/fetch/ResourceClient.h" | 29 #include "core/fetch/ResourceClient.h" |
30 #include "core/fetch/ResourceClientWalker.h" | 30 #include "core/fetch/ResourceClientWalker.h" |
31 #include "core/fetch/ResourceFetcher.h" | 31 #include "core/fetch/ResourceFetcher.h" |
32 #include "core/fetch/ResourceLoader.h" | 32 #include "core/fetch/ResourceLoader.h" |
33 #include "core/html/HTMLImageElement.h" | |
34 #include "core/layout/LayoutObject.h" | 33 #include "core/layout/LayoutObject.h" |
35 #include "core/svg/graphics/SVGImage.h" | 34 #include "core/svg/graphics/SVGImage.h" |
36 #include "core/svg/graphics/SVGImageForContainer.h" | |
37 #include "platform/Logging.h" | 35 #include "platform/Logging.h" |
38 #include "platform/RuntimeEnabledFeatures.h" | 36 #include "platform/RuntimeEnabledFeatures.h" |
39 #include "platform/SharedBuffer.h" | 37 #include "platform/SharedBuffer.h" |
40 #include "platform/TraceEvent.h" | 38 #include "platform/TraceEvent.h" |
41 #include "platform/graphics/BitmapImage.h" | 39 #include "platform/graphics/BitmapImage.h" |
42 #include "public/platform/Platform.h" | 40 #include "public/platform/Platform.h" |
43 #include "wtf/CurrentTime.h" | 41 #include "wtf/CurrentTime.h" |
44 #include "wtf/StdLibExtras.h" | 42 #include "wtf/StdLibExtras.h" |
45 | 43 |
46 namespace blink { | 44 namespace blink { |
(...skipping 73 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
120 if (m_image && !m_image->isNull()) | 118 if (m_image && !m_image->isNull()) |
121 static_cast<ImageResourceClient*>(c)->imageChanged(this); | 119 static_cast<ImageResourceClient*>(c)->imageChanged(this); |
122 | 120 |
123 Resource::didAddClient(c); | 121 Resource::didAddClient(c); |
124 } | 122 } |
125 | 123 |
126 void ImageResource::didRemoveClient(ResourceClient* c) | 124 void ImageResource::didRemoveClient(ResourceClient* c) |
127 { | 125 { |
128 ASSERT(c); | 126 ASSERT(c); |
129 ASSERT(c->resourceClientType() == ImageResourceClient::expectedType()); | 127 ASSERT(c->resourceClientType() == ImageResourceClient::expectedType()); |
130 if (m_imageForContainerMap) | |
131 m_imageForContainerMap->remove(static_cast<ImageResourceClient*>(c)); | |
132 | 128 |
133 Resource::didRemoveClient(c); | 129 Resource::didRemoveClient(c); |
134 } | 130 } |
135 | 131 |
136 bool ImageResource::isSafeToUnlock() const | 132 bool ImageResource::isSafeToUnlock() const |
137 { | 133 { |
138 // Note that |m_image| holds a reference to |m_data| in addition to the one
held by the Resource parent class. | 134 // Note that |m_image| holds a reference to |m_data| in addition to the one
held by the Resource parent class. |
139 return !m_image || (m_image->hasOneRef() && m_data->refCount() == 2); | 135 return !m_image || (m_image->hasOneRef() && m_data->refCount() == 2); |
140 } | 136 } |
141 | 137 |
(...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
188 // when they need the real, deviceScaleFactor-appropriate broken image i
con. | 184 // when they need the real, deviceScaleFactor-appropriate broken image i
con. |
189 return brokenImage(1).first; | 185 return brokenImage(1).first; |
190 } | 186 } |
191 | 187 |
192 if (m_image) | 188 if (m_image) |
193 return m_image.get(); | 189 return m_image.get(); |
194 | 190 |
195 return blink::Image::nullImage(); | 191 return blink::Image::nullImage(); |
196 } | 192 } |
197 | 193 |
198 blink::Image* ImageResource::imageForLayoutObject(const LayoutObject* layoutObje
ct) | |
199 { | |
200 ASSERT(!isPurgeable()); | |
201 | |
202 if (errorOccurred()) { | |
203 // Returning the 1x broken image is non-ideal, but we cannot reliably ac
cess the appropriate | |
204 // deviceScaleFactor from here. It is critical that callers use ImageRes
ource::brokenImage() | |
205 // when they need the real, deviceScaleFactor-appropriate broken image i
con. | |
206 return brokenImage(1).first; | |
207 } | |
208 | |
209 if (!m_image) | |
210 return blink::Image::nullImage(); | |
211 | |
212 if (m_image->isSVGImage()) { | |
213 blink::Image* image = svgImageForLayoutObject(layoutObject); | |
214 if (image != blink::Image::nullImage()) | |
215 return image; | |
216 } | |
217 | |
218 return m_image.get(); | |
219 } | |
220 | |
221 void ImageResource::setContainerSizeForLayoutObject(const ImageResourceClient* l
ayoutObject, const IntSize& containerSize, float containerZoom) | |
222 { | |
223 if (containerSize.isEmpty()) | |
224 return; | |
225 ASSERT(layoutObject); | |
226 ASSERT(containerZoom); | |
227 if (!m_image) | |
228 return; | |
229 if (!m_image->isSVGImage()) { | |
230 m_image->setContainerSize(containerSize); | |
231 return; | |
232 } | |
233 | |
234 FloatSize containerSizeWithoutZoom(containerSize); | |
235 containerSizeWithoutZoom.scale(1 / containerZoom); | |
236 m_imageForContainerMap->set(layoutObject, SVGImageForContainer::create(toSVG
Image(m_image.get()), containerSizeWithoutZoom, containerZoom)); | |
237 } | |
238 | |
239 bool ImageResource::usesImageContainerSize() const | 194 bool ImageResource::usesImageContainerSize() const |
240 { | 195 { |
241 if (m_image) | 196 if (m_image) |
242 return m_image->usesContainerSize(); | 197 return m_image->usesContainerSize(); |
243 | 198 |
244 return false; | 199 return false; |
245 } | 200 } |
246 | 201 |
247 bool ImageResource::imageHasRelativeWidth() const | 202 bool ImageResource::imageHasRelativeWidth() const |
248 { | 203 { |
(...skipping 15 matching lines...) Expand all Loading... |
264 { | 219 { |
265 ASSERT(!isPurgeable()); | 220 ASSERT(!isPurgeable()); |
266 | 221 |
267 if (!m_image) | 222 if (!m_image) |
268 return LayoutSize(); | 223 return LayoutSize(); |
269 | 224 |
270 LayoutSize imageSize; | 225 LayoutSize imageSize; |
271 | 226 |
272 if (m_image->isBitmapImage() && (layoutObject && layoutObject->shouldRespect
ImageOrientation() == RespectImageOrientation)) | 227 if (m_image->isBitmapImage() && (layoutObject && layoutObject->shouldRespect
ImageOrientation() == RespectImageOrientation)) |
273 imageSize = LayoutSize(toBitmapImage(m_image.get())->sizeRespectingOrien
tation()); | 228 imageSize = LayoutSize(toBitmapImage(m_image.get())->sizeRespectingOrien
tation()); |
274 else if (m_image->isSVGImage() && sizeType == NormalSize) | |
275 imageSize = LayoutSize(svgImageSizeForLayoutObject(layoutObject)); | |
276 else | 229 else |
277 imageSize = LayoutSize(m_image->size()); | 230 imageSize = LayoutSize(m_image->size()); |
278 | 231 |
279 if (sizeType == IntrinsicCorrectedToDPR && m_hasDevicePixelRatioHeaderValue
&& m_devicePixelRatioHeaderValue > 0) | 232 if (sizeType == IntrinsicCorrectedToDPR && m_hasDevicePixelRatioHeaderValue
&& m_devicePixelRatioHeaderValue > 0) |
280 multiplier = 1.0 / m_devicePixelRatioHeaderValue; | 233 multiplier = 1.0 / m_devicePixelRatioHeaderValue; |
281 | 234 |
282 if (multiplier == 1.0f) | 235 if (multiplier == 1.0f) |
283 return imageSize; | 236 return imageSize; |
284 | 237 |
285 // Don't let images that have a width/height >= 1 shrink below 1 when zoomed
. | 238 // Don't let images that have a width/height >= 1 shrink below 1 when zoomed
. |
(...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
323 } | 276 } |
324 | 277 |
325 inline void ImageResource::createImage() | 278 inline void ImageResource::createImage() |
326 { | 279 { |
327 // Create the image if it doesn't yet exist. | 280 // Create the image if it doesn't yet exist. |
328 if (m_image) | 281 if (m_image) |
329 return; | 282 return; |
330 | 283 |
331 if (m_response.mimeType() == "image/svg+xml") { | 284 if (m_response.mimeType() == "image/svg+xml") { |
332 m_image = SVGImage::create(this); | 285 m_image = SVGImage::create(this); |
333 m_imageForContainerMap = adoptPtr(new ImageForContainerMap); | |
334 } else { | 286 } else { |
335 m_image = BitmapImage::create(this); | 287 m_image = BitmapImage::create(this); |
336 } | 288 } |
337 } | 289 } |
338 | 290 |
339 inline void ImageResource::clearImage() | 291 inline void ImageResource::clearImage() |
340 { | 292 { |
341 // If our Image has an observer, it's always us so we need to clear the back
pointer | 293 // If our Image has an observer, it's always us so we need to clear the back
pointer |
342 // before dropping our reference. | 294 // before dropping our reference. |
343 if (m_image) | 295 if (m_image) |
(...skipping 145 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
489 | 441 |
490 void ImageResource::changedInRect(const blink::Image* image, const IntRect& rect
) | 442 void ImageResource::changedInRect(const blink::Image* image, const IntRect& rect
) |
491 { | 443 { |
492 if (!image || image != m_image) | 444 if (!image || image != m_image) |
493 return; | 445 return; |
494 notifyObservers(&rect); | 446 notifyObservers(&rect); |
495 } | 447 } |
496 | 448 |
497 bool ImageResource::currentFrameKnownToBeOpaque(const LayoutObject* layoutObject
) | 449 bool ImageResource::currentFrameKnownToBeOpaque(const LayoutObject* layoutObject
) |
498 { | 450 { |
499 blink::Image* image = imageForLayoutObject(layoutObject); | 451 blink::Image* image = this->image(); |
500 if (image->isBitmapImage()) { | 452 if (image->isBitmapImage()) { |
501 TRACE_EVENT1(TRACE_DISABLED_BY_DEFAULT("devtools.timeline"), "PaintImage
", "data", InspectorPaintImageEvent::data(layoutObject, *this)); | 453 TRACE_EVENT1(TRACE_DISABLED_BY_DEFAULT("devtools.timeline"), "PaintImage
", "data", InspectorPaintImageEvent::data(layoutObject, *this)); |
502 // BitmapImage::currentFrameKnownToBeOpaque() conservatively returns tru
e for uncached | 454 // BitmapImage::currentFrameKnownToBeOpaque() conservatively returns tru
e for uncached |
503 // frames. To get an accurate answer, we pre-cache the current frame met
adata. | 455 // frames. To get an accurate answer, we pre-cache the current frame met
adata. |
504 image->imageForCurrentFrame(); | 456 image->imageForCurrentFrame(); |
505 } | 457 } |
506 return image->currentFrameKnownToBeOpaque(); | 458 return image->currentFrameKnownToBeOpaque(); |
507 } | 459 } |
508 | 460 |
509 bool ImageResource::isAccessAllowed(SecurityOrigin* securityOrigin) | 461 bool ImageResource::isAccessAllowed(SecurityOrigin* securityOrigin) |
510 { | 462 { |
511 if (response().wasFetchedViaServiceWorker()) | 463 if (response().wasFetchedViaServiceWorker()) |
512 return response().serviceWorkerResponseType() != WebServiceWorkerRespons
eTypeOpaque; | 464 return response().serviceWorkerResponseType() != WebServiceWorkerRespons
eTypeOpaque; |
513 if (!image()->currentFrameHasSingleSecurityOrigin()) | 465 if (!image()->currentFrameHasSingleSecurityOrigin()) |
514 return false; | 466 return false; |
515 if (passesAccessControlCheck(securityOrigin)) | 467 if (passesAccessControlCheck(securityOrigin)) |
516 return true; | 468 return true; |
517 return !securityOrigin->taintsCanvas(response().url()); | 469 return !securityOrigin->taintsCanvas(response().url()); |
518 } | 470 } |
519 | 471 |
520 IntSize ImageResource::svgImageSizeForLayoutObject(const LayoutObject* layoutObj
ect) const | |
521 { | |
522 IntSize imageSize = m_image->size(); | |
523 if (!layoutObject) | |
524 return imageSize; | |
525 | |
526 ImageForContainerMap::const_iterator it = m_imageForContainerMap->find(layou
tObject); | |
527 if (it == m_imageForContainerMap->end()) | |
528 return imageSize; | |
529 | |
530 RefPtr<SVGImageForContainer> imageForContainer = it->value; | |
531 ASSERT(!imageForContainer->size().isEmpty()); | |
532 return imageForContainer->size(); | |
533 } | |
534 | |
535 // FIXME: This doesn't take into account the animation timeline so animations wi
ll not | |
536 // restart on page load, nor will two animations in different pages have differe
nt timelines. | |
537 Image* ImageResource::svgImageForLayoutObject(const LayoutObject* layoutObject) | |
538 { | |
539 if (!layoutObject) | |
540 return Image::nullImage(); | |
541 | |
542 ImageForContainerMap::iterator it = m_imageForContainerMap->find(layoutObjec
t); | |
543 if (it == m_imageForContainerMap->end()) | |
544 return Image::nullImage(); | |
545 | |
546 RefPtr<SVGImageForContainer> imageForContainer = it->value; | |
547 ASSERT(!imageForContainer->size().isEmpty()); | |
548 | |
549 Node* node = layoutObject->node(); | |
550 if (node && isHTMLImageElement(node)) { | |
551 const AtomicString& urlString = toHTMLImageElement(node)->imageSourceURL
(); | |
552 KURL url = node->document().completeURL(urlString); | |
553 imageForContainer->setURL(url); | |
554 } | |
555 | |
556 return imageForContainer.get(); | |
557 } | |
558 | |
559 bool ImageResource::loadingMultipartContent() const | 472 bool ImageResource::loadingMultipartContent() const |
560 { | 473 { |
561 return m_loader && m_loader->loadingMultipartContent(); | 474 return m_loader && m_loader->loadingMultipartContent(); |
562 } | 475 } |
563 | 476 |
564 } // namespace blink | 477 } // namespace blink |
OLD | NEW |