diff --git a/engine/core/core.gni b/engine/core/core.gni index 72f5f25213fdb35aac7ebf3dbf460f1c198408e2..536494015d263b94a2a18b9ec3f85f86b62a5793 100644 --- a/engine/core/core.gni +++ b/engine/core/core.gni @@ -813,6 +813,8 @@ sky_core_files = [ "loader/MojoLoader.cpp", "loader/MojoLoader.h", "loader/NavigationPolicy.h", + "loader/NewImageLoader.cpp", + "loader/NewImageLoader.h", "loader/UniqueIdentifier.cpp", "loader/UniqueIdentifier.h", "page/ChromeClient.h", @@ -835,6 +837,8 @@ sky_core_files = [ "page/SpellCheckerClient.h", "painting/Canvas.cpp", "painting/Canvas.h", + "painting/CanvasImage.cpp", + "painting/CanvasImage.h", "painting/CanvasPath.cpp", "painting/CanvasPath.h", "painting/ColorFilter.cpp", @@ -1128,6 +1132,7 @@ core_idl_files = get_path_info([ "painting/DrawLooper.idl", "painting/DrawLooperAddLayerCallback.idl", "painting/DrawLooperLayerInfo.idl", + "painting/Image.idl", "painting/LayerDrawLooperBuilder.idl", "painting/LayoutRoot.idl", "painting/Paint.idl", diff --git a/engine/core/loader/NewImageLoader.cpp b/engine/core/loader/NewImageLoader.cpp new file mode 100644 index 0000000000000000000000000000000000000000..7906c8dd9fa20d98b535baae57b1507d033880ed --- /dev/null +++ b/engine/core/loader/NewImageLoader.cpp @@ -0,0 +1,53 @@ +// Copyright 2015 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "sky/engine/config.h" +#include "sky/engine/core/loader/NewImageLoader.h" +#include "sky/engine/platform/image-decoders/ImageDecoder.h" +#include "sky/engine/platform/SharedBuffer.h" + +namespace blink { + +NewImageLoader::NewImageLoader(NewImageLoaderClient* client) : client_(client) { +} + +NewImageLoader::~NewImageLoader() { +} + +void NewImageLoader::Load(const KURL& src) { + fetcher_ = adoptPtr(new MojoFetcher(this, src)); +} + +void NewImageLoader::OnReceivedResponse(mojo::URLResponsePtr response) { + if (response->status_code != 200) { + client_->OnLoadFinished(SkBitmap()); + return; + } + buffer_ = SharedBuffer::create(); + drainer_ = + adoptPtr(new mojo::common::DataPipeDrainer(this, response->body.Pass())); +} + +void NewImageLoader::OnDataAvailable(const void* data, size_t num_bytes) { + buffer_->append(static_cast(data), num_bytes); +} + +void NewImageLoader::OnDataComplete() { + SkBitmap bitmap; + OwnPtr decoder = + ImageDecoder::create(*buffer_.get(), ImageSource::AlphaPremultiplied, + ImageSource::GammaAndColorProfileIgnored); + decoder->setData(buffer_.get(), true); + + if (decoder->failed()) { + client_->OnLoadFinished(bitmap); + } else { + if (decoder->frameCount() > 0) { + bitmap = decoder->frameBufferAtIndex(0)->getSkBitmap(); + } + client_->OnLoadFinished(bitmap); + } +} + +} // namespace blink \ No newline at end of file diff --git a/engine/core/loader/NewImageLoader.h b/engine/core/loader/NewImageLoader.h new file mode 100644 index 0000000000000000000000000000000000000000..d2bacca69badaeba8d92b0abd37efbce3106aafa --- /dev/null +++ b/engine/core/loader/NewImageLoader.h @@ -0,0 +1,49 @@ +// Copyright 2015 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef SKY_ENGINE_CORE_LOADER_NEWIMAGELOADER_H_ +#define SKY_ENGINE_CORE_LOADER_NEWIMAGELOADER_H_ + +#include "mojo/common/data_pipe_drainer.h" +#include "sky/engine/platform/SharedBuffer.h" +#include "sky/engine/platform/fetcher/MojoFetcher.h" +#include "sky/engine/wtf/OwnPtr.h" +#include "sky/engine/wtf/text/AtomicString.h" +#include "third_party/skia/include/core/SkBitmap.h" + +namespace blink { + +class NewImageLoaderClient { + public: + virtual void OnLoadFinished(const SkBitmap& result) = 0; + + protected: + NewImageLoaderClient() {} +}; + +class NewImageLoader : public MojoFetcher::Client, + public mojo::common::DataPipeDrainer::Client { + public: + explicit NewImageLoader(NewImageLoaderClient* client); + virtual ~NewImageLoader(); + + void Load(const KURL& src); + + // MojoFetcher::Client + void OnReceivedResponse(mojo::URLResponsePtr) override; + + // mojo::common::DataPipeDrainer::Client + void OnDataAvailable(const void*, size_t) override; + void OnDataComplete() override; + + private: + NewImageLoaderClient* client_; + OwnPtr fetcher_; + OwnPtr drainer_; + RefPtr buffer_; +}; + +} // namespace blink + +#endif // SKY_ENGINE_CORE_LOADER_NEWIMAGELOADER_H_ diff --git a/engine/core/painting/Canvas.cpp b/engine/core/painting/Canvas.cpp index 4bf9d3473e064ec92fb040f9140ea4f25139b520..1fa585569f7064fcb3a07ecd2a2d8101a3604345 100644 --- a/engine/core/painting/Canvas.cpp +++ b/engine/core/painting/Canvas.cpp @@ -7,9 +7,11 @@ #include "sky/engine/core/dom/Document.h" #include "sky/engine/core/dom/Element.h" +#include "sky/engine/core/painting/CanvasImage.h" #include "sky/engine/core/painting/PaintingTasks.h" #include "sky/engine/platform/geometry/IntRect.h" #include "third_party/skia/include/core/SkCanvas.h" +#include "third_party/skia/include/core/SkBitmap.h" namespace blink { @@ -155,6 +157,17 @@ void Canvas::drawPath(const CanvasPath* path, const Paint* paint) m_canvas->drawPath(path->path(), paint->paint()); } +void Canvas::drawImage(const CanvasImage* image, + float x, + float y, + const Paint* paint) { + if (!m_canvas) + return; + ASSERT(image); + ASSERT(m_displayList->isRecording()); + m_canvas->drawBitmap(image->bitmap(), x, y, &paint->paint()); +} + PassRefPtr Canvas::finishRecording() { if (!isRecording()) diff --git a/engine/core/painting/Canvas.h b/engine/core/painting/Canvas.h index 46f1426411edb89c7e55d6695ad09edb1d807a8f..ad5691b79ecdd173633e623b4893a8eb7dc90870 100644 --- a/engine/core/painting/Canvas.h +++ b/engine/core/painting/Canvas.h @@ -16,6 +16,7 @@ namespace blink { class Element; +class CanvasImage; class Canvas : public RefCounted, public DartWrappable { DEFINE_WRAPPERTYPEINFO(); @@ -46,6 +47,10 @@ public: void drawOval(const Rect& rect, const Paint* paint); void drawCircle(float x, float y, float radius, const Paint* paint); void drawPath(const CanvasPath* path, const Paint* paint); + void drawImage(const CanvasImage* image, + float x, + float y, + const Paint* paint); SkCanvas* skCanvas() { return m_canvas; } diff --git a/engine/core/painting/Canvas.idl b/engine/core/painting/Canvas.idl index b3358ce2277fd679a60f5f533e4fbe810cffd083..074bdff96836323b62bc800e791b522f97b4eef2 100644 --- a/engine/core/painting/Canvas.idl +++ b/engine/core/painting/Canvas.idl @@ -28,4 +28,5 @@ interface Canvas { void drawOval(Rect rect, Paint paint); void drawCircle(float x, float y, float radius, Paint paint); void drawPath(Path path, Paint paint); + void drawImage(Image image, float x, float y, Paint paint); }; diff --git a/engine/core/painting/CanvasImage.cpp b/engine/core/painting/CanvasImage.cpp new file mode 100644 index 0000000000000000000000000000000000000000..b9bed98dc15f82e33836b8cda0f7e0ab203ccc4b --- /dev/null +++ b/engine/core/painting/CanvasImage.cpp @@ -0,0 +1,39 @@ +// Copyright 2013 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "sky/engine/config.h" +#include "sky/engine/core/painting/CanvasImage.h" + +namespace blink { + +CanvasImage::CanvasImage() : imageLoader_(adoptPtr(new NewImageLoader(this))) { +} + +CanvasImage::~CanvasImage() { +} + +int CanvasImage::width() const { + return bitmap_.width(); +} + +int CanvasImage::height() const { + return bitmap_.height(); +} + +void CanvasImage::setSrc(const String& url) { + // TODO(jackson): Figure out how to determine the proper base URL here + KURL newSrcURL = KURL(KURL(), url); + if (srcURL_ != newSrcURL) { + srcURL_ = newSrcURL; + imageLoader_->Load(srcURL_); + } +} + +void CanvasImage::OnLoadFinished(const SkBitmap& result) { + // TODO(jackson): We'll eventually need a notification pathway for + // when the image load is complete so that we know to repaint, etc. + bitmap_ = result; +} + +} // namespace blink \ No newline at end of file diff --git a/engine/core/painting/CanvasImage.h b/engine/core/painting/CanvasImage.h new file mode 100644 index 0000000000000000000000000000000000000000..1f40d7bab83124db57b22bf2cb5aa7663c0f828f --- /dev/null +++ b/engine/core/painting/CanvasImage.h @@ -0,0 +1,47 @@ +// Copyright 2013 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef SKY_ENGINE_CORE_PAINTING_CANVASIMAGE_H_ +#define SKY_ENGINE_CORE_PAINTING_CANVASIMAGE_H_ + +#include "sky/engine/core/loader/NewImageLoader.h" +#include "sky/engine/platform/weborigin/KURL.h" +#include "sky/engine/tonic/dart_wrappable.h" +#include "sky/engine/wtf/PassRefPtr.h" +#include "sky/engine/wtf/text/AtomicString.h" +#include "third_party/skia/include/core/SkBitmap.h" + +namespace blink { + +class CanvasImage final : public RefCounted, + public DartWrappable, + public NewImageLoaderClient { + DEFINE_WRAPPERTYPEINFO(); + public: + ~CanvasImage() override; + static PassRefPtr create() { return adoptRef(new CanvasImage); } + + int width() const; + int height() const; + + KURL src() const { return srcURL_; } + void setSrc(const String&); + + const SkBitmap& bitmap() const { return bitmap_; } + void setBitmap(const SkBitmap& bitmap) { bitmap_ = bitmap; } + + private: + CanvasImage(); + + // NewImageLoaderClient + void OnLoadFinished(const SkBitmap& result) override; + + KURL srcURL_; + SkBitmap bitmap_; + OwnPtr imageLoader_; +}; + +} // namespace blink + +#endif // SKY_ENGINE_CORE_PAINTING_CANVASIMAGE_H_ diff --git a/engine/core/painting/Image.idl b/engine/core/painting/Image.idl new file mode 100644 index 0000000000000000000000000000000000000000..3d24b9aa40a1a3abc7218af9ebcb579e006686b1 --- /dev/null +++ b/engine/core/painting/Image.idl @@ -0,0 +1,12 @@ +// Copyright 2013 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +[ + Constructor(), + ImplementedAs=CanvasImage, +] interface Image { + readonly attribute long width; + readonly attribute long height; + attribute DOMString src; +}; diff --git a/examples/raw/spinning_image.dart b/examples/raw/spinning_image.dart new file mode 100644 index 0000000000000000000000000000000000000000..53fe140460f3b4dbc19e556d937e50c582b77596 --- /dev/null +++ b/examples/raw/spinning_image.dart @@ -0,0 +1,29 @@ +// Copyright 2015 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +import 'dart:sky'; + +double timeBase = null; + +Image image; + +void beginFrame(double timeStamp) { + if (timeBase == null) timeBase = timeStamp; + double delta = timeStamp - timeBase; + PictureRecorder canvas = new PictureRecorder(view.width, view.height); + canvas.translate(view.width / 2.0, view.height / 2.0); + canvas.rotateDegrees(delta / 10); + canvas.scale(0.2, 0.2); + Paint paint = new Paint()..setARGB(255, 0, 255, 0); + canvas.drawImage(image, -image.width / 2.0, -image.height / 2.0, paint); + view.picture = canvas.endRecording(); + view.scheduleFrame(); +} + +void main() { + image = new Image(); + image.src = "https://www.dartlang.org/logos/dart-logo.png"; + view.setBeginFrameCallback(beginFrame); + view.scheduleFrame(); +}