Chromium Code Reviews| 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); |
| +} |
| + |
| } |