Index: Source/core/page/ImageBitmap.cpp |
diff --git a/Source/core/page/ImageBitmap.cpp b/Source/core/page/ImageBitmap.cpp |
index fabe6847b5aabfeb1a3482cb5754b9cbb20caddd..189bb9c8442e8de7cab80b7bce588d2193e9889e 100644 |
--- a/Source/core/page/ImageBitmap.cpp |
+++ b/Source/core/page/ImageBitmap.cpp |
@@ -5,11 +5,13 @@ |
#include "config.h" |
#include "core/page/ImageBitmap.h" |
+#include "core/fileapi/Blob.h" |
#include "core/html/HTMLCanvasElement.h" |
#include "core/html/HTMLImageElement.h" |
#include "core/html/HTMLVideoElement.h" |
#include "core/html/ImageData.h" |
-#include "core/page/ImageBitmapCallback.h" |
+#include "core/loader/cache/FetchRequest.h" |
+#include "core/loader/cache/ResourceFetcher.h" |
#include "core/platform/graphics/GraphicsContext.h" |
#include "wtf/RefPtr.h" |
@@ -34,7 +36,8 @@ static inline PassRefPtr<BitmapImage> cropImage(Image* image, IntRect cropRect) |
ImageBitmap::ImageBitmap(HTMLImageElement* image, IntRect cropRect) |
: m_bitmapOffset(max(0, -cropRect.x()), max(0, -cropRect.y())) |
- , m_size(cropRect.size()) |
+ , m_cropRect(cropRect) |
+ , m_window(0) |
{ |
Image* bitmapImage = image->cachedImage()->image(); |
m_bitmap = cropImage(bitmapImage, cropRect).get(); |
@@ -44,7 +47,8 @@ ImageBitmap::ImageBitmap(HTMLImageElement* image, IntRect cropRect) |
ImageBitmap::ImageBitmap(HTMLVideoElement* video, IntRect cropRect) |
: m_bitmapOffset(max(0, -cropRect.x()), max(0, -cropRect.y())) |
- , m_size(cropRect.size()) |
+ , m_cropRect(cropRect) |
+ , m_window(0) |
{ |
IntRect videoRect = IntRect(IntPoint(), video->player()->naturalSize()); |
IntRect srcRect = intersection(cropRect, videoRect); |
@@ -55,14 +59,15 @@ ImageBitmap::ImageBitmap(HTMLVideoElement* video, IntRect cropRect) |
c->clip(dstRect); |
c->translate(-srcRect.x(), -srcRect.y()); |
video->paintCurrentFrameInContext(c, videoRect); |
- m_bitmap = static_cast<BitmapImage*>(m_buffer->copyImage(DontCopyBackingStore).get()); |
+ m_bitmap = m_buffer->copyImage(DontCopyBackingStore).get(); |
ScriptWrappable::init(this); |
} |
ImageBitmap::ImageBitmap(HTMLCanvasElement* canvas, IntRect cropRect) |
: m_bitmapOffset(max(0, -cropRect.x()), max(0, -cropRect.y())) |
- , m_size(cropRect.size()) |
+ , m_cropRect(cropRect) |
+ , m_window(0) |
{ |
IntSize canvasSize = canvas->size(); |
IntRect srcRect = intersection(cropRect, IntRect(IntPoint(), canvasSize)); |
@@ -70,14 +75,28 @@ ImageBitmap::ImageBitmap(HTMLCanvasElement* canvas, IntRect cropRect) |
m_buffer = ImageBuffer::create(canvasSize); |
m_buffer->context()->drawImageBuffer(canvas->buffer(), dstRect, srcRect); |
- m_bitmap = static_cast<BitmapImage*>(m_buffer->copyImage(DontCopyBackingStore).get()); |
+ m_bitmap = m_buffer->copyImage(DontCopyBackingStore).get(); |
ScriptWrappable::init(this); |
} |
+ImageBitmap::ImageBitmap(DOMWindow* window, PassRefPtr<ImageBitmapCallback> callback, Blob* blob, IntRect cropRect) |
+ : m_bitmapOffset(max(0, -cropRect.x()), max(0, -cropRect.y())) |
+ , m_cropRect(cropRect) |
+ , m_bitmap(0) |
+ , m_window(window) |
+ , m_callback(callback) |
+{ |
+ m_loader = adoptPtr(new FileReaderLoader(FileReaderLoader::ReadAsDataURL, this)); |
Justin Novosad
2013/07/26 18:15:58
This loading functionality should not live in Imag
|
+ m_loader->setDataType(blob->type()); |
+ m_loader->start(m_window->document()->scriptExecutionContext(), *blob); |
+ ScriptWrappable::init(this); |
+} |
+ |
ImageBitmap::ImageBitmap(ImageData* data, IntRect cropRect) |
: m_bitmapOffset(max(0, -cropRect.x()), max(0, -cropRect.y())) |
- , m_size(cropRect.size()) |
+ , m_cropRect(cropRect) |
+ , m_window(0) |
{ |
IntRect srcRect = intersection(cropRect, IntRect(IntPoint(), data->size())); |
@@ -85,14 +104,15 @@ ImageBitmap::ImageBitmap(ImageData* data, IntRect cropRect) |
if (srcRect.width() > 0 && srcRect.height() > 0) |
m_buffer->putByteArray(Unmultiplied, data->data(), data->size(), srcRect, IntPoint(min(0, -cropRect.x()), min(0, -cropRect.y()))); |
- m_bitmap = static_cast<BitmapImage*>(m_buffer->copyImage(DontCopyBackingStore).get()); |
+ m_bitmap = m_buffer->copyImage(DontCopyBackingStore).get(); |
ScriptWrappable::init(this); |
} |
ImageBitmap::ImageBitmap(ImageBitmap* bitmap, IntRect cropRect) |
: m_bitmapOffset(max(0, bitmap->bitmapOffset().x() - cropRect.x()), max(0, bitmap->bitmapOffset().y() - cropRect.y())) |
- , m_size(cropRect.size()) |
+ , m_cropRect(cropRect) |
+ , m_window(0) |
{ |
Image* bitmapImage = bitmap->bitmapImage(); |
cropRect.moveBy(IntPoint(-bitmap->bitmapOffset().x(), -bitmap->bitmapOffset().y())); |
@@ -101,6 +121,13 @@ ImageBitmap::ImageBitmap(ImageBitmap* bitmap, IntRect cropRect) |
ScriptWrappable::init(this); |
} |
+ImageBitmap::~ImageBitmap() |
+{ |
+ // If the ImageBitmap was destroyed before the bitmap has resolved from a blob. |
+ if (m_window && !m_bitmap) |
+ m_window->imageBitmapFinishedLoading(this); |
+} |
+ |
PassRefPtr<ImageBitmap> ImageBitmap::create(HTMLImageElement* image, IntRect cropRect) |
{ |
IntRect normalizedCropRect = normalizeRect(cropRect); |
@@ -122,6 +149,13 @@ PassRefPtr<ImageBitmap> ImageBitmap::create(HTMLCanvasElement* canvas, IntRect c |
return imageBitmap.release(); |
} |
+PassRefPtr<ImageBitmap> ImageBitmap::create(DOMWindow* window, PassRefPtr<ImageBitmapCallback> callback, Blob* blob, IntRect cropRect) |
+{ |
+ IntRect normalizedCropRect = normalizeRect(cropRect); |
+ RefPtr<ImageBitmap> imageBitmap(adoptRef(new ImageBitmap(window, callback, blob, normalizedCropRect))); |
+ return imageBitmap.release(); |
+} |
+ |
PassRefPtr<ImageBitmap> ImageBitmap::create(ImageData* data, IntRect cropRect) |
{ |
IntRect normalizedCropRect = normalizeRect(cropRect); |
@@ -136,4 +170,37 @@ PassRefPtr<ImageBitmap> ImageBitmap::create(ImageBitmap* bitmap, IntRect cropRec |
return imageBitmap.release(); |
} |
+// FileReaderLoaderClient |
+void ImageBitmap::didFinishLoading() |
+{ |
+ FetchRequest request(ResourceRequest(m_window->document()->completeURL(m_loader->stringResult())), ""); |
+ m_pendingCachedImage = m_window->document()->fetcher()->requestImage(request); |
+ m_pendingCachedImage->addClient(this); |
+} |
+ |
+void ImageBitmap::didFail(FileError::ErrorCode errorCode) |
+{ |
+ // Read the Blob object's data. If an error occurs during reading of the object, then reject the |
+ // Promise's associated resolver, with null as the value, and abort these steps. |
+ |
+ // If the image data is not in a supported file format (e.g. it's not actually an image at all), |
+ // or if the image data is corrupted in some fatal way such that the image dimensions cannot be obtained, |
+ // then reject the Promise's associated resolver, with null as the value, and abort these steps. |
+} |
+ |
+// CachedImageClient |
+void ImageBitmap::notifyFinished(CachedResource* resource) |
+{ |
+ Image* image = static_cast<CachedImage*>(resource)->image(); |
+ if (!m_cropRect.width() && !m_cropRect.height()) { |
+ // No crop rect was specified |
+ m_cropRect = IntRect(IntPoint(), image->size()); |
+ m_bitmap = image; |
+ } else { |
+ m_bitmap = cropImage(image, m_cropRect); |
+ } |
+ m_window->scriptExecutionContext()->postTask(ImageBitmapCallback::CallbackTask::create(this, m_callback)); |
+ m_window->imageBitmapFinishedLoading(this); |
+} |
+ |
} |